From c9ef240fe5a18911837f1dcf4d45cbd802a0a318 Mon Sep 17 00:00:00 2001 From: Rick Wierenga Date: Thu, 18 Aug 2022 23:08:21 -0400 Subject: [PATCH 01/18] Trigger Build From a0015777a2e2dbe10c53bf43aacaeef8ea2eea6a Mon Sep 17 00:00:00 2001 From: Rick Wierenga Date: Wed, 5 Oct 2022 12:55:57 -0400 Subject: [PATCH 02/18] Trigger Build From b8a1edcef93a004a7d5eb7c7daf768ffdc56727d Mon Sep 17 00:00:00 2001 From: Lenni Justen <65619456+lennijusten@users.noreply.github.com> Date: Fri, 26 Apr 2024 15:09:24 -0400 Subject: [PATCH 03/18] fix doc string; fix parent temp module dimensions (#111) From c7700251dc10683ed0c4537aeddc315989ada3b1 Mon Sep 17 00:00:00 2001 From: Rick Wierenga Date: Tue, 1 Oct 2024 16:51:34 -0700 Subject: [PATCH 04/18] re-add parameterset --- .../parameter_sets/__init__.py | 2 + .../parameter_sets/parameter_set.py | 13 +++ .../liquid_handling/parameter_sets/star.py | 110 ++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 pylabrobot/liquid_handling/parameter_sets/__init__.py create mode 100644 pylabrobot/liquid_handling/parameter_sets/parameter_set.py create mode 100644 pylabrobot/liquid_handling/parameter_sets/star.py diff --git a/pylabrobot/liquid_handling/parameter_sets/__init__.py b/pylabrobot/liquid_handling/parameter_sets/__init__.py new file mode 100644 index 0000000000..b1944dce91 --- /dev/null +++ b/pylabrobot/liquid_handling/parameter_sets/__init__.py @@ -0,0 +1,2 @@ +from .parameter_set import ParameterSet +from .star import STARParameterSet diff --git a/pylabrobot/liquid_handling/parameter_sets/parameter_set.py b/pylabrobot/liquid_handling/parameter_sets/parameter_set.py new file mode 100644 index 0000000000..ecb50f8649 --- /dev/null +++ b/pylabrobot/liquid_handling/parameter_sets/parameter_set.py @@ -0,0 +1,13 @@ +import abc +import dataclasses + + +@dataclasses.dataclass +class ParameterSet(abc.ABC): + @abc.abstractmethod + def make_asp_kwargs(self) -> dict: + pass + + @abc.abstractmethod + def make_disp_kwargs(self) -> dict: + pass diff --git a/pylabrobot/liquid_handling/parameter_sets/star.py b/pylabrobot/liquid_handling/parameter_sets/star.py new file mode 100644 index 0000000000..02b38b08d9 --- /dev/null +++ b/pylabrobot/liquid_handling/parameter_sets/star.py @@ -0,0 +1,110 @@ +import dataclasses +from typing import Optional +import warnings + +from pylabrobot.liquid_handling.parameter_sets.parameter_set import ParameterSet +from pylabrobot.liquid_handling.backends.hamilton.STAR import STAR +from pylabrobot.liquid_handling.liquid_classes.hamilton.base import HamiltonLiquidClass + + +@dataclasses.dataclass +class STARParameterSet(ParameterSet): + """ A collection of parameters for a liquid transfer on a Hamilton STAR. + + A rough adoption of HamiltonLiquidClass. + - This includes blow_out and jet configuration + - Parameters are lists to allow channel-specific values. + - `blow_out_air_volumes` is shared between aspiration and dispense. + """ + + blow_out_air_volumes: Optional[list[float]] + transport_air_volumes: Optional[list[float]] + + aspiration_flow_rates: Optional[list[float]] + aspiration_mix_flow_rates: Optional[list[float]] + aspiration_swap_speeds: Optional[list[float]] + aspiration_settling_times: Optional[list[float]] + aspiration_clot_retract_heights: Optional[list[float]] + aspiration_lld_modes: Optional[list[STAR.LLDMode]] + + dispense_blow_out: Optional[list[bool]] + dispense_jet: Optional[list[bool]] + dispense_flow_rates: Optional[list[float]] + dispense_mix_speeds: Optional[list[float]] + dispense_swap_speeds: Optional[list[float]] + dispense_settling_times: Optional[list[float]] + dispense_stop_back_volumes: Optional[list[float]] + dispense_lld_modes: Optional[list[STAR.LLDMode]] + + def make_asp_kwargs(self) -> dict[str, list[float]]: + return { + "flow_rates": self.aspiration_flow_rates, + "mix_speed": self.aspiration_mix_flow_rates, + "transport_air_volume": self.transport_air_volumes, + "swap_speed": self.aspiration_swap_speeds, + "settling_time": self.aspiration_settling_times, + "clot_detection_height": self.aspiration_clot_retract_heights, + "blow_out_air_volume": self.blow_out_air_volumes, + "lld_mode": self.aspiration_lld_modes, + } + + def make_disp_kwargs(self) -> dict[str, list[float]]: + return { + "jet": self.dispense_jet, + "blow_out": self.dispense_blow_out, + "flow_rates": self.dispense_flow_rates, + "mix_speed": self.dispense_mix_speeds, + "transport_air_volume": self.transport_air_volumes, + "swap_speed": self.dispense_swap_speeds, + "settling_time": self.dispense_settling_times, + "stop_back_volume": self.dispense_stop_back_volumes, + "blow_out_air_volume": self.blow_out_air_volumes, + "lld_mode": self.dispense_lld_modes, + } + + @classmethod + def from_hamilton_liquid_class( + cls, + hlc: HamiltonLiquidClass, + jet: Optional[list[bool]] = None, + blow_out: Optional[list[bool]] = None, + aspiration_lld_modes: Optional[list[STAR.LLDMode]] = None, + dispense_lld_modes: Optional[list[STAR.LLDMode]] = None, + num_channels: int = 8, + ): + warnings.warn("This method is deprecated. Hamilton liquid classes will be removed soon.", + DeprecationWarning) + + if jet is not None and len(jet) != num_channels: + raise ValueError(f"jet must have length {num_channels}") + if blow_out is not None and len(blow_out) != num_channels: + raise ValueError(f"blow_out must have length {num_channels}") + if aspiration_lld_modes is not None and len(aspiration_lld_modes) != num_channels: + raise ValueError(f"aspiration_lld_modes must have length {num_channels}") + if dispense_lld_modes is not None and len(dispense_lld_modes) != num_channels: + raise ValueError(f"dispense_lld_modes must have length {num_channels}") + if not hlc.aspiration_air_transport_volume == hlc.dispense_air_transport_volume: + raise ValueError("Different transport air volumes not supported.") + if not hlc.aspiration_blow_out_volume == hlc.dispense_blow_out_volume: + raise ValueError("Different blow out volumes not supported.") + + return cls( + blow_out_air_volumes=[hlc.aspiration_blow_out_volume] * num_channels, + transport_air_volumes=[hlc.aspiration_air_transport_volume] * num_channels, + aspiration_blow_out=[blow_out] * num_channels, + aspiration_jet=[jet] * num_channels, + aspiration_flow_rates=[hlc.aspiration_flow_rate] * num_channels, + aspiration_mix_flow_rates=[hlc.aspiration_mix_flow_rate] * num_channels, + aspiration_swap_speeds=[hlc.aspiration_swap_speed] * num_channels, + aspiration_settling_times=[hlc.aspiration_settling_time] * num_channels, + aspiration_clot_retract_heights=[hlc.aspiration_clot_retract_height] * num_channels, + aspiration_lld_modes=aspiration_lld_modes, + dispense_blow_out=[blow_out] * num_channels, + dispense_jet=[jet] * num_channels, + dispense_flow_rates=[hlc.dispense_flow_rate] * num_channels, + dispense_mix_speeds=[hlc.dispense_mix_flow_rate] * num_channels, + dispense_swap_speeds=[hlc.dispense_swap_speed] * num_channels, + dispense_settling_times=[hlc.dispense_settling_time] * num_channels, + dispense_stop_back_volumes=[hlc.dispense_stop_back_volume] * num_channels, + dispense_lld_modes=dispense_lld_modes, + ) From 2539a6f9a447505169c60e52fff190c625ec0496 Mon Sep 17 00:00:00 2001 From: Rick Wierenga Date: Mon, 16 Sep 2024 20:47:42 -0700 Subject: [PATCH 05/18] add ParameterSet and STARParameterSet --- .../liquid_handling/parameter_sets/star.py | 71 ++++--------------- 1 file changed, 13 insertions(+), 58 deletions(-) diff --git a/pylabrobot/liquid_handling/parameter_sets/star.py b/pylabrobot/liquid_handling/parameter_sets/star.py index 02b38b08d9..4604df71e7 100644 --- a/pylabrobot/liquid_handling/parameter_sets/star.py +++ b/pylabrobot/liquid_handling/parameter_sets/star.py @@ -1,16 +1,13 @@ import dataclasses from typing import Optional -import warnings - from pylabrobot.liquid_handling.parameter_sets.parameter_set import ParameterSet from pylabrobot.liquid_handling.backends.hamilton.STAR import STAR -from pylabrobot.liquid_handling.liquid_classes.hamilton.base import HamiltonLiquidClass @dataclasses.dataclass class STARParameterSet(ParameterSet): """ A collection of parameters for a liquid transfer on a Hamilton STAR. - + A rough adoption of HamiltonLiquidClass. - This includes blow_out and jet configuration - Parameters are lists to allow channel-specific values. @@ -18,10 +15,12 @@ class STARParameterSet(ParameterSet): """ blow_out_air_volumes: Optional[list[float]] - transport_air_volumes: Optional[list[float]] + aspiration_blow_out: Optional[list[bool]] + aspiration_jet: Optional[list[bool]] aspiration_flow_rates: Optional[list[float]] aspiration_mix_flow_rates: Optional[list[float]] + aspiration_transport_air_volumes: Optional[list[float]] aspiration_swap_speeds: Optional[list[float]] aspiration_settling_times: Optional[list[float]] aspiration_clot_retract_heights: Optional[list[float]] @@ -31,16 +30,19 @@ class STARParameterSet(ParameterSet): dispense_jet: Optional[list[bool]] dispense_flow_rates: Optional[list[float]] dispense_mix_speeds: Optional[list[float]] + dispense_transport_air_volumes: Optional[list[float]] dispense_swap_speeds: Optional[list[float]] dispense_settling_times: Optional[list[float]] dispense_stop_back_volumes: Optional[list[float]] dispense_lld_modes: Optional[list[STAR.LLDMode]] - def make_asp_kwargs(self) -> dict[str, list[float]]: + def make_asp_kwargs(self) -> dict[str, float]: return { + "jet": self.aspiration_jet, + "blow_out": self.aspiration_blow_out, "flow_rates": self.aspiration_flow_rates, - "mix_speed": self.aspiration_mix_flow_rates, - "transport_air_volume": self.transport_air_volumes, + "mix_flow_rate": self.aspiration_mix_flow_rates, + "transport_air_volume": self.aspiration_transport_air_volumes, "swap_speed": self.aspiration_swap_speeds, "settling_time": self.aspiration_settling_times, "clot_detection_height": self.aspiration_clot_retract_heights, @@ -48,63 +50,16 @@ def make_asp_kwargs(self) -> dict[str, list[float]]: "lld_mode": self.aspiration_lld_modes, } - def make_disp_kwargs(self) -> dict[str, list[float]]: + def make_disp_kwargs(self) -> dict[str, float]: return { "jet": self.dispense_jet, "blow_out": self.dispense_blow_out, - "flow_rates": self.dispense_flow_rates, + "flow_rate": self.dispense_flow_rates, "mix_speed": self.dispense_mix_speeds, - "transport_air_volume": self.transport_air_volumes, + "transport_air_volume": self.dispense_transport_air_volumes, "swap_speed": self.dispense_swap_speeds, "settling_time": self.dispense_settling_times, "stop_back_volume": self.dispense_stop_back_volumes, "blow_out_air_volume": self.blow_out_air_volumes, "lld_mode": self.dispense_lld_modes, } - - @classmethod - def from_hamilton_liquid_class( - cls, - hlc: HamiltonLiquidClass, - jet: Optional[list[bool]] = None, - blow_out: Optional[list[bool]] = None, - aspiration_lld_modes: Optional[list[STAR.LLDMode]] = None, - dispense_lld_modes: Optional[list[STAR.LLDMode]] = None, - num_channels: int = 8, - ): - warnings.warn("This method is deprecated. Hamilton liquid classes will be removed soon.", - DeprecationWarning) - - if jet is not None and len(jet) != num_channels: - raise ValueError(f"jet must have length {num_channels}") - if blow_out is not None and len(blow_out) != num_channels: - raise ValueError(f"blow_out must have length {num_channels}") - if aspiration_lld_modes is not None and len(aspiration_lld_modes) != num_channels: - raise ValueError(f"aspiration_lld_modes must have length {num_channels}") - if dispense_lld_modes is not None and len(dispense_lld_modes) != num_channels: - raise ValueError(f"dispense_lld_modes must have length {num_channels}") - if not hlc.aspiration_air_transport_volume == hlc.dispense_air_transport_volume: - raise ValueError("Different transport air volumes not supported.") - if not hlc.aspiration_blow_out_volume == hlc.dispense_blow_out_volume: - raise ValueError("Different blow out volumes not supported.") - - return cls( - blow_out_air_volumes=[hlc.aspiration_blow_out_volume] * num_channels, - transport_air_volumes=[hlc.aspiration_air_transport_volume] * num_channels, - aspiration_blow_out=[blow_out] * num_channels, - aspiration_jet=[jet] * num_channels, - aspiration_flow_rates=[hlc.aspiration_flow_rate] * num_channels, - aspiration_mix_flow_rates=[hlc.aspiration_mix_flow_rate] * num_channels, - aspiration_swap_speeds=[hlc.aspiration_swap_speed] * num_channels, - aspiration_settling_times=[hlc.aspiration_settling_time] * num_channels, - aspiration_clot_retract_heights=[hlc.aspiration_clot_retract_height] * num_channels, - aspiration_lld_modes=aspiration_lld_modes, - dispense_blow_out=[blow_out] * num_channels, - dispense_jet=[jet] * num_channels, - dispense_flow_rates=[hlc.dispense_flow_rate] * num_channels, - dispense_mix_speeds=[hlc.dispense_mix_flow_rate] * num_channels, - dispense_swap_speeds=[hlc.dispense_swap_speed] * num_channels, - dispense_settling_times=[hlc.dispense_settling_time] * num_channels, - dispense_stop_back_volumes=[hlc.dispense_stop_back_volume] * num_channels, - dispense_lld_modes=dispense_lld_modes, - ) From 89eeb8b0c009464871b77db4d83596d6d285ae13 Mon Sep 17 00:00:00 2001 From: Rick Wierenga Date: Wed, 18 Sep 2024 12:00:54 -0700 Subject: [PATCH 06/18] share transport air volume --- pylabrobot/liquid_handling/parameter_sets/star.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pylabrobot/liquid_handling/parameter_sets/star.py b/pylabrobot/liquid_handling/parameter_sets/star.py index 4604df71e7..e30f363ec9 100644 --- a/pylabrobot/liquid_handling/parameter_sets/star.py +++ b/pylabrobot/liquid_handling/parameter_sets/star.py @@ -7,7 +7,7 @@ @dataclasses.dataclass class STARParameterSet(ParameterSet): """ A collection of parameters for a liquid transfer on a Hamilton STAR. - + A rough adoption of HamiltonLiquidClass. - This includes blow_out and jet configuration - Parameters are lists to allow channel-specific values. @@ -15,12 +15,12 @@ class STARParameterSet(ParameterSet): """ blow_out_air_volumes: Optional[list[float]] + transport_air_volumes: Optional[list[float]] aspiration_blow_out: Optional[list[bool]] aspiration_jet: Optional[list[bool]] aspiration_flow_rates: Optional[list[float]] aspiration_mix_flow_rates: Optional[list[float]] - aspiration_transport_air_volumes: Optional[list[float]] aspiration_swap_speeds: Optional[list[float]] aspiration_settling_times: Optional[list[float]] aspiration_clot_retract_heights: Optional[list[float]] @@ -30,7 +30,6 @@ class STARParameterSet(ParameterSet): dispense_jet: Optional[list[bool]] dispense_flow_rates: Optional[list[float]] dispense_mix_speeds: Optional[list[float]] - dispense_transport_air_volumes: Optional[list[float]] dispense_swap_speeds: Optional[list[float]] dispense_settling_times: Optional[list[float]] dispense_stop_back_volumes: Optional[list[float]] @@ -42,7 +41,7 @@ def make_asp_kwargs(self) -> dict[str, float]: "blow_out": self.aspiration_blow_out, "flow_rates": self.aspiration_flow_rates, "mix_flow_rate": self.aspiration_mix_flow_rates, - "transport_air_volume": self.aspiration_transport_air_volumes, + "transport_air_volume": self.transport_air_volumes, "swap_speed": self.aspiration_swap_speeds, "settling_time": self.aspiration_settling_times, "clot_detection_height": self.aspiration_clot_retract_heights, @@ -56,7 +55,7 @@ def make_disp_kwargs(self) -> dict[str, float]: "blow_out": self.dispense_blow_out, "flow_rate": self.dispense_flow_rates, "mix_speed": self.dispense_mix_speeds, - "transport_air_volume": self.dispense_transport_air_volumes, + "transport_air_volume": self.transport_air_volumes, "swap_speed": self.dispense_swap_speeds, "settling_time": self.dispense_settling_times, "stop_back_volume": self.dispense_stop_back_volumes, From 5bcdfdb70530aa071bc4b721e37cfc8bc9e259d0 Mon Sep 17 00:00:00 2001 From: Rick Wierenga Date: Thu, 19 Sep 2024 14:46:11 -0700 Subject: [PATCH 07/18] remove hamilton liquid classes --- .../liquid_handling/backends/hamilton/STAR.py | 4193 ++++------ .../backends/hamilton/vantage.py | 1427 ++-- .../liquid_classes/hamilton/star.py | 7203 +++++------------ .../liquid_classes/hamilton/vantage.py | 7035 +++++----------- 4 files changed, 6025 insertions(+), 13833 deletions(-) diff --git a/pylabrobot/liquid_handling/backends/hamilton/STAR.py b/pylabrobot/liquid_handling/backends/hamilton/STAR.py index 0c8e403a5e..0369c5729c 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/STAR.py +++ b/pylabrobot/liquid_handling/backends/hamilton/STAR.py @@ -1,79 +1,45 @@ +""" +This file defines interfaces for all supported Hamilton liquid handling robots. +""" +# pylint: disable=invalid-sequence-index, dangerous-default-value + +from abc import ABCMeta import datetime import enum import functools import logging import re -from abc import ABCMeta -from contextlib import asynccontextmanager, contextmanager -from typing import ( - Callable, - Dict, - List, - Literal, - Optional, - Sequence, - Type, - TypeVar, - Union, - cast, -) +from typing import Callable, Dict, List, Literal, Optional, Sequence, Type, TypeVar, Union, cast from pylabrobot import audio -from pylabrobot.liquid_handling.backends.hamilton.base import ( - HamiltonLiquidHandler, -) +from pylabrobot.liquid_handling.backends.hamilton.base import HamiltonLiquidHandler from pylabrobot.liquid_handling.errors import ChannelizedError -from pylabrobot.liquid_handling.liquid_classes.hamilton import ( - HamiltonLiquidClass, - get_star_liquid_class, -) +from pylabrobot.liquid_handling.liquid_classes.hamilton import HamiltonLiquidClass from pylabrobot.liquid_handling.standard import ( + Pickup, + PickupTipRack, Drop, DropTipRack, + Aspiration, + AspirationPlate, + AspirationContainer, + Dispense, + DispensePlate, + DispenseContainer, GripDirection, - MultiHeadAspirationContainer, - MultiHeadAspirationPlate, - MultiHeadDispenseContainer, - MultiHeadDispensePlate, - Pickup, - PickupTipRack, - ResourceDrop, - ResourceMove, - ResourcePickup, - SingleChannelAspiration, - SingleChannelDispense, -) -from pylabrobot.liquid_handling.utils import ( - get_tight_single_resource_liquid_op_offsets, - get_wide_single_resource_liquid_op_offsets, -) -from pylabrobot.resources import ( - Carrier, - Coordinate, - Resource, - TipRack, - TipSpot, - Well, + Move ) +from pylabrobot.resources import Carrier, Coordinate, Resource, TipRack, TipSpot, Well from pylabrobot.resources.errors import ( - HasTipError, - NoTipError, - TooLittleLiquidError, TooLittleVolumeError, + TooLittleLiquidError, + HasTipError, + NoTipError ) -from pylabrobot.resources.hamilton import ( - HamiltonTip, - TipDropMethod, - TipPickupMethod, - TipSize, -) -from pylabrobot.resources.hamilton.hamilton_decks import ( - STAR_SIZE_X, - STARLET_SIZE_X, -) -from pylabrobot.resources.liquid import Liquid -from pylabrobot.resources.rotation import Rotation -from pylabrobot.resources.trash import Trash +from pylabrobot.resources.hamilton.hamilton_decks import STAR_SIZE_X, STARLET_SIZE_X +from pylabrobot.resources.ml_star import HamiltonTip, TipDropMethod, TipPickupMethod, TipSize +from pylabrobot.resources.utils import get_child_location +from pylabrobot.utils.linalg import matrix_vector_multiply_3x3 T = TypeVar("T") @@ -90,19 +56,17 @@ def need_iswap_parked(method: Callable): @functools.wraps(method) async def wrapper(self: "STAR", *args, **kwargs): if self.iswap_installed and not self.iswap_parked: - await self.park_iswap( - minimum_traverse_height_at_beginning_of_a_command=int(self._iswap_traversal_height * 10) - ) + await self.park_iswap(minimum_traverse_height_at_beginning_of_a_command= + int(self._traversal_height * 10)) # pylint: disable=protected-access - result = await method(self, *args, **kwargs) + result = await method(self, *args, **kwargs) # pylint: disable=not-callable return result - return wrapper def _fill_in_defaults(val: Optional[List[T]], default: List[T]) -> List[T]: - """Util for converting an argument to the appropriate format for low level star methods.""" + """ Util for converting an argument to the appropriate format for low level star methods. """ t = type(default[0]) # if the val is None, use the default. if val is None: @@ -117,7 +81,7 @@ def _fill_in_defaults(val: Optional[List[T]], default: List[T]) -> List[T]: val = [v if v is not None else d for v, d in zip(val, default)] # the values must be of the right type. automatically handle int and float. if t in [int, float]: - return [t(v) for v in val] # type: ignore + return [t(v) for v in val] # type: ignore if not all(isinstance(v, t) for v in val): raise ValueError(f"Value must be a list of {t}, but is {val}") # the value is ready to be used. @@ -125,7 +89,7 @@ def _fill_in_defaults(val: Optional[List[T]], default: List[T]) -> List[T]: def parse_star_fw_string(resp: str, fmt: str = "") -> dict: - """Parse a machine command or response string according to a format string. + """ Parse a machine command or response string according to a format string. The format contains names of parameters (always length 2), followed by an arbitrary number of the following, but always @@ -178,7 +142,11 @@ def parse_star_fw_string(resp: str, fmt: str = "") -> dict: def find_param(param): name, data = param[0:2], param[2:] - type_ = {"#": "int", "*": "hex", "&": "str"}[data[0]] + type_ = { + "#": "int", + "*": "hex", + "&": "str" + }[data[0]] # Build a regex to match this parameter. exp = { @@ -186,7 +154,7 @@ def find_param(param): "hex": r"[\da-fA-F ]", "str": ".", }[type_] - len_ = len(data.split(" ")[0]) # Get length of first block. + len_ = len(data.split(" ")[0]) # Get length of first block. regex = f"{name}((?:{exp}{ {len_} }" if param.endswith(" (n)"): @@ -234,7 +202,7 @@ def find_param(param): param += char prevchar = char if param != "": - find_param(param) # last parameter is not closed by loop. + find_param(param) # last parameter is not closed by loop. # If id not in fmt, add it. if "id" not in info: @@ -244,7 +212,7 @@ def find_param(param): class STARModuleError(Exception, metaclass=ABCMeta): - """Base class for all Hamilton backend errors, raised by a single module.""" + """ Base class for all Hamilton backend errors, raised by a single module. """ def __init__( self, @@ -263,14 +231,14 @@ def __repr__(self) -> str: class CommandSyntaxError(STARModuleError): - """Command syntax error + """ Command syntax error Code: 01 """ class HardwareError(STARModuleError): - """Hardware error + """ Hardware error Possible cause(s): drive blocked, low power etc. @@ -280,7 +248,7 @@ class HardwareError(STARModuleError): class CommandNotCompletedError(STARModuleError): - """Command not completed + """ Command not completed Possible cause(s): error in previous sequence (not executed) @@ -290,7 +258,7 @@ class CommandNotCompletedError(STARModuleError): class ClotDetectedError(STARModuleError): - """Clot detected + """ Clot detected Possible cause(s): LLD not interrupted @@ -300,7 +268,7 @@ class ClotDetectedError(STARModuleError): class BarcodeUnreadableError(STARModuleError): - """Barcode unreadable + """ Barcode unreadable Possible cause(s): bad or missing barcode @@ -310,7 +278,7 @@ class BarcodeUnreadableError(STARModuleError): class TipTooLittleVolumeError(STARModuleError): - """Too little liquid + """ Too little liquid Possible cause(s): 1. liquid surface is not detected, @@ -321,7 +289,7 @@ class TipTooLittleVolumeError(STARModuleError): class TipAlreadyFittedError(STARModuleError): - """Tip already fitted + """ Tip already fitted Possible cause(s): Repeated attempts to fit a tip or iSwap movement with tips @@ -331,7 +299,7 @@ class TipAlreadyFittedError(STARModuleError): class HamiltonNoTipError(STARModuleError): - """No tips + """ No tips Possible cause(s): command was started without fitting tip (tip was not fitted or fell off again) @@ -341,7 +309,7 @@ class HamiltonNoTipError(STARModuleError): class NoCarrierError(STARModuleError): - """No carrier + """ No carrier Possible cause(s): load command without carrier @@ -351,7 +319,7 @@ class NoCarrierError(STARModuleError): class NotCompletedError(STARModuleError): - """Not completed + """ Not completed Possible cause(s): Command in command buffer was aborted due to an error in a previous command, or command stack @@ -362,7 +330,7 @@ class NotCompletedError(STARModuleError): class DispenseWithPressureLLDError(STARModuleError): - """Dispense with pressure LLD + """ Dispense with pressure LLD Possible cause(s): dispense with pressure LLD is not permitted @@ -372,7 +340,7 @@ class DispenseWithPressureLLDError(STARModuleError): class NoTeachInSignalError(STARModuleError): - """No Teach In Signal + """ No Teach In Signal Possible cause(s): X-Movement to LLD reached maximum allowable position with- out detecting Teach in signal @@ -382,7 +350,7 @@ class NoTeachInSignalError(STARModuleError): class LoadingTrayError(STARModuleError): - """Loading Tray error + """ Loading Tray error Possible cause(s): position already occupied @@ -392,7 +360,7 @@ class LoadingTrayError(STARModuleError): class SequencedAspirationWithPressureLLDError(STARModuleError): - """Sequenced aspiration with pressure LLD + """ Sequenced aspiration with pressure LLD Possible cause(s): sequenced aspiration with pressure LLD is not permitted @@ -402,7 +370,7 @@ class SequencedAspirationWithPressureLLDError(STARModuleError): class NotAllowedParameterCombinationError(STARModuleError): - """Not allowed parameter combination + """ Not allowed parameter combination Possible cause(s): i.e. PLLD and dispense or wrong X-drive assignment @@ -422,7 +390,7 @@ class CoverCloseError(STARModuleError): class AspirationError(STARModuleError): - """Aspiration error + """ Aspiration error Possible cause(s): aspiration liquid stream error detected @@ -443,7 +411,7 @@ class WashFluidOrWasteError(STARModuleError): class IncubationError(STARModuleError): - """Incubation error + """ Incubation error Possible cause(s): incubator temperature out of limit @@ -463,7 +431,7 @@ class TADMMeasurementError(STARModuleError): class NoElementError(STARModuleError): - """No element + """ No element Possible cause(s): expected element not detected @@ -483,7 +451,7 @@ class ElementStillHoldingError(STARModuleError): class ElementLostError(STARModuleError): - """Element lost + """ Element lost Possible cause(s): expected element is missing (lost) @@ -524,7 +492,7 @@ class PositionNotReachableError(STARModuleError): class UnexpectedLLDError(STARModuleError): - """unexpected LLD + """ unexpected LLD Possible cause(s): liquid level is reached before LLD scanning is started (using PIP or XL channels) @@ -534,7 +502,7 @@ class UnexpectedLLDError(STARModuleError): class AreaAlreadyOccupiedError(STARModuleError): - """area already occupied + """ area already occupied Possible cause(s): Its impossible to occupy area because this area is already in use @@ -544,7 +512,7 @@ class AreaAlreadyOccupiedError(STARModuleError): class ImpossibleToOccupyAreaError(STARModuleError): - """impossible to occupy area + """ impossible to occupy area Possible cause(s): Area cant be occupied because is no solution for arm prepositioning @@ -586,7 +554,7 @@ class StopError(STARModuleError): class SlaveError(STARModuleError): - """Slave error + """ Slave error Possible cause(s): This error code indicates an error in one of slaves. (for error handling purpose using service @@ -724,11 +692,11 @@ class DelimiterError(STARModuleError): class UnknownHamiltonError(STARModuleError): - """Unknown error""" + """ Unknown error """ def _module_id_to_module_name(id_): - """Convert a module ID to a module name.""" + """ Convert a module ID to a module name. """ return { "C0": "Master", "X0": "X-drives", @@ -761,12 +729,12 @@ def _module_id_to_module_name(id_): "N0": "Nano dispenser", "D0": "384 dispensing head", "NP": "Nano disp. pressure controller", - "M1": "Reserved for module 1", + "M1": "Reserved for module 1" }.get(id_, "Unknown Module") def error_code_to_exception(code: int) -> Type[STARModuleError]: - """Convert an error code to an exception.""" + """ Convert an error code to an exception. """ codes = { 1: CommandSyntaxError, 2: HardwareError, @@ -815,7 +783,7 @@ def error_code_to_exception(code: int) -> Type[STARModuleError]: 110: BarcodeNotUniqueError, 111: BarcodeAlreadyUsedError, 112: KitLotExpiredError, - 113: DelimiterError, + 113: DelimiterError } if code in codes: return codes[code] @@ -823,10 +791,10 @@ def error_code_to_exception(code: int) -> Type[STARModuleError]: def trace_information_to_string(module_identifier: str, trace_information: int) -> str: - """Convert a trace identifier to an error message.""" + """ Convert a trace identifier to an error message. """ table = None - if module_identifier == "C0": # master + if module_identifier == "C0": # master table = { 10: "CAN error", 11: "Slave command time out", @@ -853,29 +821,14 @@ def trace_information_to_string(module_identifier: str, trace_information: int) 50: "XL channel task busy", 51: "Tube gripper task busy", 52: "Imaging channel task busy", - 53: "Robotic channel task busy", + 53: "Robotic channel task busy" + } + elif module_identifier == "I0": # autoload + table = { + 36: "Hamilton will not run while the hood is open" } - elif module_identifier == "I0": # autoload - table = {36: "Hamilton will not run while the hood is open"} - elif module_identifier in [ - "PX", - "P1", - "P2", - "P3", - "P4", - "P5", - "P6", - "P7", - "P8", - "P9", - "PA", - "PB", - "PC", - "PD", - "PE", - "PF", - "PG", - ]: + elif module_identifier in ["PX", "P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9", "PA", + "PB", "PC", "PD", "PE", "PF", "PG"]: table = { 0: "No error", 20: "No communication to EEPROM", @@ -886,7 +839,7 @@ def trace_information_to_string(module_identifier: str, trace_information: int) 36: "Stop during execution of command", 37: "Stop during execution of command", 40: "No parallel processes permitted (Two or more commands sent for the same control" - "process)", + "process)", 50: "Dispensing drive init. position not found", 51: "Dispensing drive not initialized", 52: "Dispensing drive movement error", @@ -901,7 +854,7 @@ def trace_information_to_string(module_identifier: str, trace_information: int) 63: "Z-drive limit stop not found", 70: "No liquid level found (possibly because no liquid was present)", 71: "Not enough liquid present (Immersion depth or surface following position possiby" - "below minimal access range)", + "below minimal access range)", 72: "Auto calibration at pressure (Sensor not possible)", 73: "No liquid level found with dual LLD", 74: "Liquid at a not allowed position detected", @@ -918,16 +871,16 @@ def trace_information_to_string(module_identifier: str, trace_information: int) 86: "ADC algorithm error", 87: "2nd phase of liquid nt found", 88: "Not enough liquid present (Immersion depth or surface following position possiby" - "below minimal access range)", + "below minimal access range)", 90: "Limit curve not resetable", 91: "Limit curve not programmable", 92: "Limit curve not found", 93: "Limit curve data incorrect", 94: "Not enough memory for limit curve", 95: "Invalid limit curve index", - 96: "Limit curve already stored", + 96: "Limit curve already stored" } - elif module_identifier == "H0": # Core 96 head + elif module_identifier == "H0": # Core 96 head table = { 20: "No communication to EEPROM", 30: "Unknown command", @@ -960,7 +913,7 @@ def trace_information_to_string(module_identifier: str, trace_information: int) 76: "Tip already picked up", 81: "Clot detected", } - elif module_identifier == "R0": # iswap + elif module_identifier == "R0": # iswap table = { 20: "No communication to EEPROM", 30: "Unknown command", @@ -991,14 +944,15 @@ def trace_information_to_string(module_identifier: str, trace_information: int) 83: "Wrist twist drive movement error: position counter over/underflow", 85: "Gripper drive: communication error to gripper DMS digital potentiometer", 86: "Gripper drive: Auto adjustment of DMS digital potentiometer not possible", - 89: "Gripper drive movement error: drive locked or incremental sensor fault during gripping", + 89: + "Gripper drive movement error: drive locked or incremental sensor fault during gripping", 90: "Gripper drive initialized failed", 91: "iSWAP not initialized. Call star.initialize_iswap().", 92: "Gripper drive movement error: drive locked or incremental sensor fault during release", 93: "Gripper drive movement error: position counter over/underflow", 94: "Plate not found", 96: "Plate not available", - 97: "Unexpected object found", + 97: "Unexpected object found" } if table is not None and trace_information in table: @@ -1018,7 +972,7 @@ def star_firmware_string_to_error( error_code_dict: Dict[str, str], raw_response: str, ) -> STARFirmwareError: - """Convert a firmware string to a STARFirmwareError.""" + """ Convert a firmware string to a STARFirmwareError. """ errors = {} @@ -1027,11 +981,8 @@ def star_firmware_string_to_error( if "/" in error: # C0 module: error code / trace information error_code_str, trace_information_str = error.split("/") - error_code, trace_information = ( - int(error_code_str), - int(trace_information_str), - ) - if error_code == 0: # No error + error_code, trace_information = int(error_code_str), int(trace_information_str) + if error_code == 0: # No error continue error_class = error_code_to_exception(error_code) elif module_id == "I0" and error == "36": @@ -1042,14 +993,11 @@ def star_firmware_string_to_error( error_class = UnknownHamiltonError trace_information = int(error) error_description = trace_information_to_string( - module_identifier=module_id, trace_information=trace_information - ) - errors[module_name] = error_class( - message=error_description, - trace_information=trace_information, - raw_response=error, - raw_module=module_id, - ) + module_identifier=module_id, trace_information=trace_information) + errors[module_name] = error_class(message=error_description, + trace_information=trace_information, + raw_response=error, + raw_module=module_id) # If the master error is a SlaveError, remove it from the errors dict. if isinstance(errors.get("Master"), SlaveError): @@ -1058,10 +1006,8 @@ def star_firmware_string_to_error( return STARFirmwareError(errors=errors, raw_response=raw_response) -def convert_star_module_error_to_plr_error( - error: STARModuleError, -) -> Optional[Exception]: - """Convert an error returned by a specific STAR module to a Hamilton error.""" +def convert_star_module_error_to_plr_error(error: STARModuleError) -> Optional[Exception]: + """ Convert an error returned by a specific STAR module to a Hamilton error. """ # TipAlreadyFittedError -> HasTipError if isinstance(error, TipAlreadyFittedError): return HasTipError() @@ -1082,18 +1028,14 @@ def convert_star_module_error_to_plr_error( return None -def convert_star_firmware_error_to_plr_error( - error: STARFirmwareError, -) -> Optional[Exception]: - """Check if a STARFirmwareError can be converted to a native PLR error. If so, return it, else - return `None`.""" +def convert_star_firmware_error_to_plr_error(error: STARFirmwareError) -> Optional[Exception]: + """ Check if a STARFirmwareError can be converted to a native PLR error. If so, return it, else + return `None`. """ # if all errors are channel errors, return a ChannelizedError if all(e.startswith("Pipetting channel ") for e in error.errors): - def _channel_to_int(channel: str) -> int: - return int(channel.split(" ")[-1]) - 1 # star is 1-indexed, plr is 0-indexed - + return int(channel.split(" ")[-1]) - 1 # star is 1-indexed, plr is 0-indexed errors = { _channel_to_int(module_name): convert_star_module_error_to_plr_error(error) or error for module_name, error in error.errors.items() @@ -1104,7 +1046,7 @@ def _channel_to_int(channel: str) -> int: def _dispensing_mode_for_op(empty: bool, jet: bool, blow_out: bool) -> int: - """from docs: + """ from docs: 0 = Partial volume in jet mode 1 = Blow out in jet mode, called "empty" in the VENUS liquid editor 2 = Partial volume at surface @@ -1133,7 +1075,7 @@ def __init__( read_timeout: int = 30, write_timeout: int = 30, ): - """Create a new STAR interface. + """ Create a new STAR interface. Args: device_address: the USB device address of the Hamilton STAR. Only useful if using more than @@ -1151,7 +1093,7 @@ def __init__( read_timeout=read_timeout, write_timeout=write_timeout, id_product=0x8000, - serial_number=serial_number, + serial_number=serial_number ) self.iswap_installed: Optional[bool] = None @@ -1162,33 +1104,24 @@ def __init__( self._num_channels: Optional[int] = None self._core_parked: Optional[bool] = None self._extended_conf: Optional[dict] = None - self._channel_traversal_height: float = 245.0 - self._iswap_traversal_height: float = 284.0 + self._traversal_height: float = 245.0 self.core_adjustment = Coordinate.zero() self._unsafe = UnSafe(self) - self._iswap_version: Optional[str] = None # loaded lazily - @property def unsafe(self) -> "UnSafe": - """Actions that have a higher risk of damaging the robot. Use with care!""" + """ Actions that have a higher risk of damaging the robot. Use with care! """ return self._unsafe @property def num_channels(self) -> int: - """The number of pipette channels present on the robot.""" + """ The number of pipette channels present on the robot. """ if self._num_channels is None: raise RuntimeError("has not loaded num_channels, forgot to call `setup`?") return self._num_channels def set_minimum_traversal_height(self, traversal_height: float): - raise NotImplementedError( - "set_minimum_traversal_height is depricated. use set_minimum_channel_traversal_height or " - "set_minimum_iswap_traversal_height instead." - ) - - def set_minimum_channel_traversal_height(self, traversal_height: float): - """Set the minimum traversal height for the pip channels. + """ Set the minimum traversal height for the robot. This refers to the bottom of the pipetting channel when no tip is present, or the bottom of the tip when a tip is present. This value will be used as the default value for the @@ -1198,24 +1131,7 @@ def set_minimum_channel_traversal_height(self, traversal_height: float): assert 0 < traversal_height < 285, "Traversal height must be between 0 and 285 mm" - self._channel_traversal_height = traversal_height - - def set_minimum_iswap_traversal_height(self, traversal_height: float): - """Set the minimum traversal height for the iswap.""" - - assert 0 < traversal_height < 285, "Traversal height must be between 0 and 285 mm" - - self._iswap_traversal_height = traversal_height - - @contextmanager - def iswap_minimum_traversal_height(self, traversal_height: float): - orig = self._iswap_traversal_height - self._iswap_traversal_height = traversal_height - try: - yield - except Exception as e: - self._iswap_traversal_height = orig - raise e + self._traversal_height = traversal_height @property def module_id_length(self): @@ -1223,7 +1139,7 @@ def module_id_length(self): @property def extended_conf(self) -> dict: - """Extended configuration.""" + """ Extended configuration. """ if self._extended_conf is None: raise RuntimeError("has not loaded extended_conf, forgot to call `setup`?") return self._extended_conf @@ -1236,26 +1152,15 @@ def iswap_parked(self) -> bool: def core_parked(self) -> bool: return self._core_parked is True - async def get_iswap_version(self) -> str: - """Lazily load the iSWAP version. Use cached value if available.""" - if self._iswap_version is None: - self._iswap_version = await self.request_iswap_version() - return self._iswap_version - - async def request_pip_channel_version(self, channel: int) -> str: - return cast( - str, (await self.send_command(STAR.channel_id(channel), "RF", fmt="rf" + "&" * 17))["rf"] - ) - def get_id_from_fw_response(self, resp: str) -> Optional[int]: - """Get the id from a firmware response.""" + """ Get the id from a firmware response. """ parsed = parse_star_fw_string(resp, "id####") if "id" in parsed and parsed["id"] is not None: return int(parsed["id"]) return None def check_fw_string_error(self, resp: str): - """Raise an error if the firmware response is an error response. + """ Raise an error if the firmware response is an error response. Raises: ValueError: if the format string is incompatible with the response. @@ -1272,39 +1177,9 @@ def check_fw_string_error(self, resp: str): # named capturing groups to the regex. exp = r"er(?P[0-9]{2}/[0-9]{2})" - for module in [ - "X0", - "I0", - "W1", - "W2", - "T1", - "T2", - "R0", - "P1", - "P2", - "P3", - "P4", - "P5", - "P6", - "P7", - "P8", - "P9", - "PA", - "PB", - "PC", - "PD", - "PE", - "PF", - "PG", - "H0", - "HW", - "HU", - "HV", - "N0", - "D0", - "NP", - "M1", - ]: + for module in ["X0", "I0", "W1", "W2", "T1", "T2", "R0", "P1", "P2", "P3", "P4", "P5", "P6", + "P7", "P8", "P9", "PA", "PB", "PC", "PD", "PE", "PF", "PG", "H0", "HW", "HU", + "HV", "N0", "D0", "NP", "M1"]: exp += f" ?(?:{module}(?P<{module}>[0-9]{{2}}/[0-9]{{2}}))?" errors = re.search(exp, resp) else: @@ -1314,9 +1189,9 @@ def check_fw_string_error(self, resp: str): if errors is not None: # filter None elements - errors_dict = {k: v for k, v in errors.groupdict().items() if v is not None} + errors_dict = {k:v for k,v in errors.groupdict().items() if v is not None} # filter 00 and 00/00 elements, which mean no error. - errors_dict = {k: v for k, v in errors_dict.items() if v not in ["00", "00/00"]} + errors_dict = {k:v for k,v in errors_dict.items() if v not in ["00", "00/00"]} has_error = not (errors is None or len(errors_dict) == 0) if has_error: @@ -1328,36 +1203,26 @@ def check_fw_string_error(self, resp: str): # temp. disabled until we figure out how to handle async in parse response (the # background thread does not have an event loop, and I'm not sure if it should.) # vp = await self.send_command(module=error.raw_module, command="VP", fmt="vp&&")["vp"] - # he[module_name].message += f" ({vp})" + # he[module_name].message += f" ({vp})" # pylint: disable=unnecessary-dict-index-lookup - he.errors[ - module_name - ].message += " (call lh.backend.request_name_of_last_faulty_parameter)" + # pylint: disable=unnecessary-dict-index-lookup + he.errors[module_name].message += \ + " (call lh.backend.request_name_of_last_faulty_parameter)" raise he def _parse_response(self, resp: str, fmt: str) -> dict: - """Parse a response from the machine.""" + """ Parse a response from the machine. """ return parse_star_fw_string(resp, fmt) - async def setup( - self, - skip_autoload=False, - skip_iswap=False, - skip_core96_head=False, - ): - """Creates a USB connection and finds read/write interfaces. + async def setup(self): + """ setup - Args: - skip_autoload: if True, skip initializing the autoload module, if applicable. - skip_iswap: if True, skip initializing the iSWAP module, if applicable. - skip_core96_head: if True, skip initializing the CoRe 96 head module, if applicable. + Creates a USB connection and finds read/write interfaces. """ await super().setup() - self.id_ = 0 - tip_presences = await self.request_tip_presence() self._num_channels = len(tip_presences) @@ -1366,12 +1231,11 @@ async def setup( self._extended_conf = await self.request_extended_configuration() left_x_drive_configuration_byte_1 = bin(self.extended_conf["xl"]) - left_x_drive_configuration_byte_1 = left_x_drive_configuration_byte_1 + "0" * ( - 16 - len(left_x_drive_configuration_byte_1) - ) + left_x_drive_configuration_byte_1 = left_x_drive_configuration_byte_1 + \ + "0" * (16 - len(left_x_drive_configuration_byte_1)) left_x_drive_configuration_byte_1 = left_x_drive_configuration_byte_1[2:] configuration_data1 = bin(conf["kb"]).split("b")[-1].zfill(8) - autoload_configuration_byte = configuration_data1[-4] + autoload_configuration_byte = configuration_data1[-3] # Identify installations self.autoload_installed = autoload_configuration_byte == "1" self.core96_head_installed = left_x_drive_configuration_byte_1[2] == "1" @@ -1391,37 +1255,34 @@ async def setup( await self.initialize_pipetting_channels( x_positions=[self.extended_conf["xw"]], # Tip eject waste X position. y_positions=y_positions, - begin_of_tip_deposit_process=int(self._channel_traversal_height * 10), + begin_of_tip_deposit_process=int(self._traversal_height * 10), end_of_tip_deposit_process=1220, z_position_at_end_of_a_command=3600, tip_pattern=[True] * self.num_channels, - tip_type=4, # TODO: get from tip types - discarding_method=0, + tip_type=4, # TODO: get from tip types + discarding_method=0 ) - if self.autoload_installed and not skip_autoload: + if self.autoload_installed: autoload_initialized = await self.request_autoload_initialization_status() if not autoload_initialized: await self.initialize_autoload() await self.park_autoload() - if self.iswap_installed and not skip_iswap: + if self.iswap_installed: iswap_initialized = await self.request_iswap_initialization_status() if not iswap_initialized: await self.initialize_iswap() - await self.park_iswap( - minimum_traverse_height_at_beginning_of_a_command=int(self._iswap_traversal_height * 10) - ) + await self.park_iswap(minimum_traverse_height_at_beginning_of_a_command= + int(self._traversal_height * 10)) - if self.core96_head_installed and not skip_core96_head: + if self.core96_head_installed: core96_head_initialized = await self.request_core_96_head_initialization_status() if not core96_head_initialized: await self.initialize_core_96_head( - trash96=self.deck.get_trash_area96(), - z_position_at_the_command_end=self._channel_traversal_height, - ) + z_position_at_the_command_end=int(self._traversal_height*10)) # After setup, STAR will have thrown out anything mounted on the pipetting channels, including # the core grippers. @@ -1438,9 +1299,10 @@ async def pick_up_tips( minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, pickup_method: Optional[TipPickupMethod] = None, ): - """Pick up tips from a resource.""" + """ Pick up tips from a resource. """ - x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) + x_positions, y_positions, channels_involved = \ + self._ops_to_fw_positions(ops, use_channels) tip_spots = [op.resource for op in ops] tips = set(cast(HamiltonTip, tip_spot.get_tip()) for tip_spot in tip_spots) @@ -1450,7 +1312,7 @@ async def pick_up_tips( max_z = max(op.resource.get_absolute_location().z + op.offset.z for op in ops) max_total_tip_length = max(op.tip.total_tip_length for op in ops) - max_tip_length = max((op.tip.total_tip_length - op.tip.fitting_depth) for op in ops) + max_tip_length = max((op.tip.total_tip_length-op.tip.fitting_depth) for op in ops) # not sure why this is necessary, but it is according to log files and experiments if self._get_hamilton_tip([op.resource for op in ops]).tip_size == TipSize.LOW_VOLUME: @@ -1462,21 +1324,13 @@ async def pick_up_tips( if not isinstance(tip, HamiltonTip): raise TypeError("Tip type must be HamiltonTip.") - begin_tip_pick_up_process = ( - round((max_z + max_total_tip_length) * 10) - if begin_tip_pick_up_process is None - else int(begin_tip_pick_up_process * 10) - ) - end_tip_pick_up_process = ( - round((max_z + max_tip_length) * 10) - if end_tip_pick_up_process is None - else round(end_tip_pick_up_process * 10) - ) - minimum_traverse_height_at_beginning_of_a_command = ( - round(self._channel_traversal_height * 10) - if minimum_traverse_height_at_beginning_of_a_command is None + begin_tip_pick_up_process = round((max_z + max_total_tip_length)*10) \ + if begin_tip_pick_up_process is None else int(begin_tip_pick_up_process*10) + end_tip_pick_up_process = round((max_z + max_tip_length)*10) \ + if end_tip_pick_up_process is None else round(end_tip_pick_up_process*10) + minimum_traverse_height_at_beginning_of_a_command = round(self._traversal_height * 10) \ + if minimum_traverse_height_at_beginning_of_a_command is None \ else round(minimum_traverse_height_at_beginning_of_a_command * 10) - ) pickup_method = pickup_method or tip.pickup_method try: @@ -1487,7 +1341,8 @@ async def pick_up_tips( tip_type_idx=ttti, begin_tip_pick_up_process=begin_tip_pick_up_process, end_tip_pick_up_process=end_tip_pick_up_process, - minimum_traverse_height_at_beginning_of_a_command=minimum_traverse_height_at_beginning_of_a_command, + minimum_traverse_height_at_beginning_of_a_command=\ + minimum_traverse_height_at_beginning_of_a_command, pickup_method=pickup_method, ) except STARFirmwareError as e: @@ -1505,7 +1360,7 @@ async def drop_tips( minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, z_position_at_end_of_a_command: Optional[float] = None, ): - """Drop tips to a resource. + """ Drop tips to a resource. Args: drop_method: The method to use for dropping tips. If None, the default method for dropping to @@ -1519,46 +1374,30 @@ async def drop_tips( else: drop_method = TipDropMethod.DROP - x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) + x_positions, y_positions, channels_involved = \ + self._ops_to_fw_positions(ops, use_channels) # get highest z position max_z = max(op.resource.get_absolute_location().z + op.offset.z for op in ops) if drop_method == TipDropMethod.PLACE_SHIFT: # magic values empirically found in https://github.com/PyLabRobot/pylabrobot/pull/63 - begin_tip_deposit_process = ( - round((max_z + 59.9) * 10) - if begin_tip_deposit_process is None - else round(begin_tip_deposit_process * 10) - ) - end_tip_deposit_process = ( - round((max_z + 49.9) * 10) - if end_tip_deposit_process is None - else round(end_tip_deposit_process * 10) - ) + begin_tip_deposit_process = round((max_z+59.9)*10) \ + if begin_tip_deposit_process is None else round(begin_tip_deposit_process*10) + end_tip_deposit_process = round((max_z+49.9)*10) \ + if end_tip_deposit_process is None else round(end_tip_deposit_process*10) else: max_total_tip_length = max(op.tip.total_tip_length for op in ops) - max_tip_length = max((op.tip.total_tip_length - op.tip.fitting_depth) for op in ops) - begin_tip_deposit_process = ( - round((max_z + max_total_tip_length) * 10) - if begin_tip_deposit_process is None - else round(begin_tip_deposit_process * 10) - ) - end_tip_deposit_process = ( - round((max_z + max_tip_length) * 10) - if end_tip_deposit_process is None - else round(end_tip_deposit_process * 10) - ) - - minimum_traverse_height_at_beginning_of_a_command = ( - round(self._channel_traversal_height * 10) - if minimum_traverse_height_at_beginning_of_a_command is None + max_tip_length = max((op.tip.total_tip_length-op.tip.fitting_depth) for op in ops) + begin_tip_deposit_process=round((max_z + max_total_tip_length)*10) \ + if begin_tip_deposit_process is None else round(begin_tip_deposit_process*10) + end_tip_deposit_process=round((max_z + max_tip_length)*10) \ + if end_tip_deposit_process is None else round(end_tip_deposit_process*10) + + minimum_traverse_height_at_beginning_of_a_command = round(self._traversal_height * 10) \ + if minimum_traverse_height_at_beginning_of_a_command is None \ else round(minimum_traverse_height_at_beginning_of_a_command * 10) - ) - z_position_at_end_of_a_command = ( - round(self._channel_traversal_height * 10) - if z_position_at_end_of_a_command is None - else round(z_position_at_end_of_a_command * 10) - ) + z_position_at_end_of_a_command = round(self._traversal_height * 10) \ + if z_position_at_end_of_a_command is None else round(z_position_at_end_of_a_command * 10) try: return await self.discard_tip( @@ -1567,9 +1406,10 @@ async def drop_tips( tip_pattern=channels_involved, begin_tip_deposit_process=begin_tip_deposit_process, end_tip_deposit_process=end_tip_deposit_process, - minimum_traverse_height_at_beginning_of_a_command=minimum_traverse_height_at_beginning_of_a_command, + minimum_traverse_height_at_beginning_of_a_command=\ + minimum_traverse_height_at_beginning_of_a_command, z_position_at_end_of_a_command=z_position_at_end_of_a_command, - discarding_method=drop_method, + discarding_method=drop_method ) except STARFirmwareError as e: if plr_e := convert_star_firmware_error_to_plr_error(e): @@ -1577,15 +1417,14 @@ async def drop_tips( raise e def _assert_valid_resources(self, resources: Sequence[Resource]) -> None: - """Assert that resources are in a valid location for pipetting.""" + """ Assert that resources are in a valid location for pipetting. """ for resource in resources: if resource.get_absolute_location().z < 100: raise ValueError( - f"Resource {resource} is too low: {resource.get_absolute_location().z} < 100" - ) + f"Resource {resource} is too low: {resource.get_absolute_location().z} < 100") class LLDMode(enum.Enum): - """Liquid level detection mode.""" + """ Liquid level detection mode. """ OFF = 0 GAMMA = 1 @@ -1595,7 +1434,7 @@ class LLDMode(enum.Enum): async def aspirate( self, - ops: List[SingleChannelAspiration], + ops: List[Aspiration], use_channels: List[int], jet: Optional[List[bool]] = None, blow_out: Optional[List[bool]] = None, @@ -1617,12 +1456,13 @@ async def aspirate( detection_height_difference_for_dual_lld: Optional[List[float]] = None, swap_speed: Optional[List[float]] = None, settling_time: Optional[List[float]] = None, - mix_volume: Optional[List[float]] = None, - mix_cycles: Optional[List[int]] = None, - mix_position_from_liquid_surface: Optional[List[float]] = None, - mix_speed: Optional[List[float]] = None, - mix_surface_following_distance: Optional[List[float]] = None, + homogenization_volume: Optional[List[float]] = None, + homogenization_cycles: Optional[List[int]] = None, + homogenization_position_from_liquid_surface: Optional[List[float]] = None, + homogenization_speed: Optional[List[float]] = None, + homogenization_surface_following_distance: Optional[List[float]] = None, limit_curve_index: Optional[List[int]] = None, + use_2nd_section_aspiration: Optional[List[bool]] = None, retract_height_over_2nd_section_to_empty_tip: Optional[List[float]] = None, dispensation_speed_during_emptying_tip: Optional[List[float]] = None, @@ -1631,12 +1471,14 @@ async def aspirate( cup_upper_edge: Optional[List[float]] = None, ratio_liquid_rise_to_tip_deep_in: Optional[List[float]] = None, immersion_depth_2nd_section: Optional[List[float]] = None, + minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, min_z_endpos: Optional[float] = None, + hamilton_liquid_classes: Optional[List[Optional[HamiltonLiquidClass]]] = None, liquid_surfaces_no_lld: Optional[List[float]] = None, ): - """Aspirate liquid from the specified channels. + """ Aspirate liquid from the specified channels. For all parameters where `None` is the default value, STAR will use the default value, based on the aspirations. For all list parameters, the length of the list must be equal to the number of @@ -1672,14 +1514,14 @@ async def aspirate( detection_height_difference_for_dual_lld: Difference between the gamma and DP LLD heights if the LLD mode is DUAL. swap_speed: Swap speed (on leaving liquid) [1mm/s]. Must be between 3 and 1600. Default 100. - settling_time: The time to wait after mix. - mix_volume: The volume to aspirate for mix. - mix_cycles: The number of cycles to perform for mix. - mix_position_from_liquid_surface: The height to aspirate from for mix + settling_time: The time to wait after homogenization. + homogenization_volume: The volume to aspirate for homogenization. + homogenization_cycles: The number of cycles to perform for homogenization. + homogenization_position_from_liquid_surface: The height to aspirate from for homogenization (LLD or absolute terms). - mix_speed: The speed to aspirate at for mix. - mix_surface_following_distance: The distance to follow the liquid surface for - mix. + homogenization_speed: The speed to aspirate at for homogenization. + homogenization_surface_following_distance: The distance to follow the liquid surface for + homogenization. limit_curve_index: The index of the limit curve to use. use_2nd_section_aspiration: Whether to use the second section of aspiration. @@ -1696,13 +1538,15 @@ async def aspirate( starting an aspiration. min_z_endpos: The minimum height to move to, this is the end of aspiration. - hamilton_liquid_classes: Override the default liquid classes. See - pylabrobot/liquid_handling/liquid_classes/hamilton/star.py liquid_surface_no_lld: Liquid surface at function without LLD [mm]. Must be between 0 and 360. Defaults to well bottom + liquid height. Should use absolute z. """ - x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) + if hamilton_liquid_classes is not None: + raise NotImplementedError("Hamilton liquid classes are deprecated.") + + x_positions, y_positions, channels_involved = \ + self._ops_to_fw_positions(ops, use_channels) n = len(ops) @@ -1711,130 +1555,62 @@ async def aspirate( if blow_out is None: blow_out = [False] * n - if hamilton_liquid_classes is None: - hamilton_liquid_classes = [] - for i, op in enumerate(ops): - liquid = Liquid.WATER # default to WATER - # [-1][0]: get last liquid in well, [0] is indexing into the tuple - if len(op.liquids) > 0 and op.liquids[-1][0] is not None: - liquid = op.liquids[-1][0] - - hamilton_liquid_classes.append( - get_star_liquid_class( - tip_volume=op.tip.maximal_volume, - is_core=False, - is_tip=True, - has_filter=op.tip.has_filter, - liquid=liquid, - jet=jet[i], - blow_out=blow_out[i], - ) - ) - self._assert_valid_resources([op.resource for op in ops]) - # correct volumes using the liquid class - volumes = [ - hlc.compute_corrected_volume(op.volume) if hlc is not None else op.volume - for op, hlc in zip(ops, hamilton_liquid_classes) - ] - - well_bottoms = [ - op.resource.get_absolute_location().z + op.offset.z + op.resource.material_z_thickness - for op in ops - ] - liquid_surfaces_no_lld = liquid_surfaces_no_lld or [ - wb + (op.liquid_height or 0) for wb, op in zip(well_bottoms, ops) - ] + well_bottoms = [op.resource.get_absolute_location().z + op.offset.z + \ + op.resource.material_z_thickness for op in ops] + liquid_surfaces_no_lld = liquid_surfaces_no_lld or [wb + (op.liquid_height or 0) + for wb, op in zip(well_bottoms, ops)] if lld_search_height is None: lld_search_height = [ - ( - wb + op.resource.get_absolute_size_z() + (2.7 if isinstance(op.resource, Well) else 5) - ) # ? + (wb + op.resource.get_absolute_size_z() + (2.7 if isinstance(op.resource, Well) else 5)) # ? for wb, op in zip(well_bottoms, ops) ] else: lld_search_height = [(wb + sh) for wb, sh in zip(well_bottoms, lld_search_height)] - clot_detection_height = _fill_in_defaults( - clot_detection_height, - default=[ - hlc.aspiration_clot_retract_height if hlc is not None else 0 - for hlc in hamilton_liquid_classes - ], - ) - pull_out_distance_transport_air = _fill_in_defaults(pull_out_distance_transport_air, [10] * n) - second_section_height = _fill_in_defaults(second_section_height, [3.2] * n) - second_section_ratio = _fill_in_defaults(second_section_ratio, [618.0] * n) + clot_detection_height = _fill_in_defaults(clot_detection_height, default=[0]) + pull_out_distance_transport_air = _fill_in_defaults(pull_out_distance_transport_air, [10]*n) + second_section_height = _fill_in_defaults(second_section_height, [3.2]*n) + second_section_ratio = _fill_in_defaults(second_section_ratio, [618.0]*n) minimum_height = _fill_in_defaults(minimum_height, well_bottoms) # TODO: I think minimum height should be the minimum height of the well - immersion_depth = _fill_in_defaults(immersion_depth, [0] * n) - immersion_depth_direction = _fill_in_defaults(immersion_depth_direction, [0] * n) - surface_following_distance = _fill_in_defaults(surface_following_distance, [0] * n) - flow_rates = [ - op.flow_rate or (hlc.aspiration_flow_rate if hlc is not None else 100) - for op, hlc in zip(ops, hamilton_liquid_classes) - ] - transport_air_volume = _fill_in_defaults( - transport_air_volume, - default=[ - hlc.aspiration_air_transport_volume if hlc is not None else 0 - for hlc in hamilton_liquid_classes - ], - ) - blow_out_air_volumes = [ - (op.blow_out_air_volume or (hlc.aspiration_blow_out_volume if hlc is not None else 0)) - for op, hlc in zip(ops, hamilton_liquid_classes) - ] - pre_wetting_volume = _fill_in_defaults(pre_wetting_volume, [0] * n) - lld_mode = _fill_in_defaults(lld_mode, [self.__class__.LLDMode.OFF] * n) - gamma_lld_sensitivity = _fill_in_defaults(gamma_lld_sensitivity, [1] * n) - dp_lld_sensitivity = _fill_in_defaults(dp_lld_sensitivity, [1] * n) - aspirate_position_above_z_touch_off = _fill_in_defaults( - aspirate_position_above_z_touch_off, [0] * n - ) - detection_height_difference_for_dual_lld = _fill_in_defaults( - detection_height_difference_for_dual_lld, [0] * n - ) - swap_speed = _fill_in_defaults( - swap_speed, - default=[ - hlc.aspiration_swap_speed if hlc is not None else 100 for hlc in hamilton_liquid_classes - ], - ) - settling_time = _fill_in_defaults( - settling_time, - default=[ - hlc.aspiration_settling_time if hlc is not None else 0 for hlc in hamilton_liquid_classes - ], - ) - mix_volume = _fill_in_defaults(mix_volume, [0] * n) - mix_cycles = _fill_in_defaults(mix_cycles, [0] * n) - mix_position_from_liquid_surface = _fill_in_defaults(mix_position_from_liquid_surface, [0] * n) - mix_speed = _fill_in_defaults( - mix_speed, - default=[ - hlc.aspiration_mix_flow_rate if hlc is not None else 50.0 for hlc in hamilton_liquid_classes - ], - ) - mix_surface_following_distance = _fill_in_defaults(mix_surface_following_distance, [0] * n) - limit_curve_index = _fill_in_defaults(limit_curve_index, [0] * n) - - use_2nd_section_aspiration = _fill_in_defaults(use_2nd_section_aspiration, [False] * n) - retract_height_over_2nd_section_to_empty_tip = _fill_in_defaults( - retract_height_over_2nd_section_to_empty_tip, [0] * n - ) - dispensation_speed_during_emptying_tip = _fill_in_defaults( - dispensation_speed_during_emptying_tip, [50.0] * n - ) - dosing_drive_speed_during_2nd_section_search = _fill_in_defaults( - dosing_drive_speed_during_2nd_section_search, [50.0] * n - ) - z_drive_speed_during_2nd_section_search = _fill_in_defaults( - z_drive_speed_during_2nd_section_search, [30.0] * n - ) - cup_upper_edge = _fill_in_defaults(cup_upper_edge, [0] * n) - ratio_liquid_rise_to_tip_deep_in = _fill_in_defaults(ratio_liquid_rise_to_tip_deep_in, [0] * n) - immersion_depth_2nd_section = _fill_in_defaults(immersion_depth_2nd_section, [0] * n) + immersion_depth = _fill_in_defaults(immersion_depth, [0]*n) + immersion_depth_direction = _fill_in_defaults(immersion_depth_direction, [0]*n) + surface_following_distance = _fill_in_defaults(surface_following_distance, [0]*n) + flow_rates = [op.flow_rate or 100 for op in ops] + transport_air_volume = _fill_in_defaults(transport_air_volume, default=[0]*n) + blow_out_air_volumes = [op.blow_out_air_volume or 0 for op in ops] + pre_wetting_volume = _fill_in_defaults(pre_wetting_volume, [0]*n) + lld_mode = _fill_in_defaults(lld_mode, [self.__class__.LLDMode.OFF]*n) + gamma_lld_sensitivity = _fill_in_defaults(gamma_lld_sensitivity, [1]*n) + dp_lld_sensitivity = _fill_in_defaults(dp_lld_sensitivity, [1]*n) + aspirate_position_above_z_touch_off = \ + _fill_in_defaults(aspirate_position_above_z_touch_off, [0]*n) + detection_height_difference_for_dual_lld = \ + _fill_in_defaults(detection_height_difference_for_dual_lld, [0]*n) + swap_speed = _fill_in_defaults(swap_speed, default=[100]*n) + settling_time = _fill_in_defaults(settling_time, default=[0]*n) + homogenization_volume = _fill_in_defaults(homogenization_volume, [0]*n) + homogenization_cycles = _fill_in_defaults(homogenization_cycles, [0]*n) + homogenization_position_from_liquid_surface = \ + _fill_in_defaults(homogenization_position_from_liquid_surface, [0]*n) + homogenization_speed = _fill_in_defaults(homogenization_speed, [50]*n) + homogenization_surface_following_distance = \ + _fill_in_defaults(homogenization_surface_following_distance, [0]*n) + limit_curve_index = _fill_in_defaults(limit_curve_index, [0]*n) + + use_2nd_section_aspiration = _fill_in_defaults(use_2nd_section_aspiration, [False]*n) + retract_height_over_2nd_section_to_empty_tip = \ + _fill_in_defaults(retract_height_over_2nd_section_to_empty_tip, [0]*n) + dispensation_speed_during_emptying_tip = \ + _fill_in_defaults(dispensation_speed_during_emptying_tip, [50.0]*n) + dosing_drive_speed_during_2nd_section_search = \ + _fill_in_defaults(dosing_drive_speed_during_2nd_section_search, [50.0]*n) + z_drive_speed_during_2nd_section_search = \ + _fill_in_defaults(z_drive_speed_during_2nd_section_search, [30.0]*n) + cup_upper_edge = _fill_in_defaults(cup_upper_edge, [0]*n) + ratio_liquid_rise_to_tip_deep_in = _fill_in_defaults(ratio_liquid_rise_to_tip_deep_in, [0]*n) + immersion_depth_2nd_section = _fill_in_defaults(immersion_depth_2nd_section, [0]*n) try: return await self.aspirate_pip( @@ -1842,7 +1618,8 @@ async def aspirate( tip_pattern=channels_involved, x_positions=x_positions, y_positions=y_positions, - aspiration_volumes=[round(vol * 10) for vol in volumes], + + aspiration_volumes=[round(op.volume * 10) for op in ops], lld_search_height=[round(lsh * 10) for lsh in lld_search_height], clot_detection_height=[round(cd * 10) for cd in clot_detection_height], liquid_surface_no_lld=[round(ls * 10) for ls in liquid_surfaces_no_lld], @@ -1860,42 +1637,37 @@ async def aspirate( lld_mode=[mode.value for mode in lld_mode], gamma_lld_sensitivity=gamma_lld_sensitivity, dp_lld_sensitivity=dp_lld_sensitivity, - aspirate_position_above_z_touch_off=[ - round(ap * 10) for ap in aspirate_position_above_z_touch_off - ], - detection_height_difference_for_dual_lld=[ - round(dh * 10) for dh in detection_height_difference_for_dual_lld - ], + aspirate_position_above_z_touch_off=[round(ap * 10) + for ap in aspirate_position_above_z_touch_off], + detection_height_difference_for_dual_lld=[round(dh * 10) + for dh in detection_height_difference_for_dual_lld], swap_speed=[round(ss * 10) for ss in swap_speed], settling_time=[round(st * 10) for st in settling_time], - mix_volume=[round(hv * 10) for hv in mix_volume], - mix_cycles=mix_cycles, - mix_position_from_liquid_surface=[ - round(hp * 10) for hp in mix_position_from_liquid_surface - ], - mix_speed=[round(hs * 10) for hs in mix_speed], - mix_surface_following_distance=[round(hsd * 10) for hsd in mix_surface_following_distance], + homogenization_volume=[round(hv * 10) for hv in homogenization_volume], + homogenization_cycles=homogenization_cycles, + homogenization_position_from_liquid_surface=[round(hp * 10) + for hp in homogenization_position_from_liquid_surface], + homogenization_speed=[round(hs * 10) for hs in homogenization_speed], + homogenization_surface_following_distance=[round(hsd * 10) + for hsd in homogenization_surface_following_distance], limit_curve_index=limit_curve_index, + use_2nd_section_aspiration=use_2nd_section_aspiration, - retract_height_over_2nd_section_to_empty_tip=[ - round(rh * 10) for rh in retract_height_over_2nd_section_to_empty_tip - ], - dispensation_speed_during_emptying_tip=[ - round(ds * 10) for ds in dispensation_speed_during_emptying_tip - ], - dosing_drive_speed_during_2nd_section_search=[ - round(ds * 10) for ds in dosing_drive_speed_during_2nd_section_search - ], - z_drive_speed_during_2nd_section_search=[ - round(zs * 10) for zs in z_drive_speed_during_2nd_section_search - ], + retract_height_over_2nd_section_to_empty_tip=[round(rh * 10) + for rh in retract_height_over_2nd_section_to_empty_tip], + dispensation_speed_during_emptying_tip=[round(ds * 10) + for ds in dispensation_speed_during_emptying_tip], + dosing_drive_speed_during_2nd_section_search=[round(ds * 10) + for ds in dosing_drive_speed_during_2nd_section_search], + z_drive_speed_during_2nd_section_search=[round(zs * 10) + for zs in z_drive_speed_during_2nd_section_search], cup_upper_edge=[round(cue * 10) for cue in cup_upper_edge], ratio_liquid_rise_to_tip_deep_in=ratio_liquid_rise_to_tip_deep_in, - immersion_depth_2nd_section=[round(id_ * 10) for id_ in immersion_depth_2nd_section], - minimum_traverse_height_at_beginning_of_a_command=round( - (minimum_traverse_height_at_beginning_of_a_command or self._channel_traversal_height) * 10 - ), - min_z_endpos=round((min_z_endpos or self._channel_traversal_height) * 10), + immersion_depth_2nd_section=[round(id_*10) for id_ in immersion_depth_2nd_section], + + minimum_traverse_height_at_beginning_of_a_command= + round((minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10), + min_z_endpos=round((min_z_endpos or self._traversal_height) * 10), ) except STARFirmwareError as e: if plr_e := convert_star_firmware_error_to_plr_error(e): @@ -1904,8 +1676,9 @@ async def aspirate( async def dispense( self, - ops: List[SingleChannelDispense], + ops: List[Dispense], use_channels: List[int], + lld_search_height: Optional[List[float]] = None, liquid_surface_no_lld: Optional[List[float]] = None, dispensing_mode: Optional[List[int]] = None, @@ -1931,15 +1704,17 @@ async def dispense( mix_speed: Optional[List[float]] = None, mix_surface_following_distance: Optional[List[float]] = None, limit_curve_index: Optional[List[int]] = None, + minimum_traverse_height_at_beginning_of_a_command: Optional[int] = None, min_z_endpos: Optional[float] = None, side_touch_off_distance: float = 0, + hamilton_liquid_classes: Optional[List[Optional[HamiltonLiquidClass]]] = None, jet: Optional[List[bool]] = None, - blow_out: Optional[List[bool]] = None, # "empty" in the VENUS liquid editor - empty: Optional[List[bool]] = None, # truly "empty", does not exist in liquid editor, dm4 + blow_out: Optional[List[bool]] = None, # "empty" in the VENUS liquid editor + empty: Optional[List[bool]] = None, # truly "empty", does not exist in liquid editor, dm4 ): - """Dispense liquid from the specified channels. + """ Dispense liquid from the specified channels. For all parameters where `None` is the default value, STAR will use the default value, based on the dispenses. For all list parameters, the length of the list must be equal to the number of @@ -1970,12 +1745,12 @@ async def dispense( dp_lld_sensitivity: The dp LLD sensitivity. (1 = high, 4 = low) swap_speed: Swap speed (on leaving liquid) [0.1mm/s]. Must be between 3 and 1600. Default 100. settling_time: The settling time. - mix_volume: The volume to use for mix. - mix_cycles: The number of mix cycles. + mix_volume: The volume to use for homogenization. + mix_cycles: The number of homogenization cycles. mix_position_from_liquid_surface: The height to move above the liquid surface for - mix. - mix_speed: The mix speed. - mix_surface_following_distance: The distance to follow the liquid surface for mix. + homogenization. + mix_speed: The homogenization speed. + mix_surface_following_distance: The distance to follow the liquid surface for homogenization. limit_curve_index: The limit curve to use for the dispense. minimum_traverse_height_at_beginning_of_a_command: The minimum height to move to before starting a dispense. @@ -1995,7 +1770,11 @@ async def dispense( documentation. Dispense mode 4. """ - x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) + if hamilton_liquid_classes is not None: + raise NotImplementedError("Hamilton liquid classes are deprecated.") + + x_positions, y_positions, channels_involved = \ + self._ops_to_fw_positions(ops, use_channels) n = len(ops) @@ -2006,156 +1785,88 @@ async def dispense( if blow_out is None: blow_out = [False] * n - if hamilton_liquid_classes is None: - hamilton_liquid_classes = [] - for i, op in enumerate(ops): - liquid = Liquid.WATER # default to WATER - # [-1][0]: get last liquid in tip, [0] is indexing into the tuple - if len(op.liquids) > 0 and op.liquids[-1][0] is not None: - liquid = op.liquids[-1][0] - - hamilton_liquid_classes.append( - get_star_liquid_class( - tip_volume=op.tip.maximal_volume, - is_core=False, - is_tip=True, - has_filter=op.tip.has_filter, - liquid=liquid, - jet=jet[i], - blow_out=blow_out[i], - ) - ) - - # correct volumes using the liquid class - volumes = [ - hlc.compute_corrected_volume(op.volume) if hlc is not None else op.volume - for op, hlc in zip(ops, hamilton_liquid_classes) - ] - - well_bottoms = [ - op.resource.get_absolute_location().z + op.offset.z + op.resource.material_z_thickness - for op in ops - ] - liquid_surfaces_no_lld = liquid_surface_no_lld or [ - ls + (op.liquid_height or 0) for ls, op in zip(well_bottoms, ops) - ] + well_bottoms = [op.resource.get_absolute_location().z + op.offset.z + \ + op.resource.material_z_thickness for op in ops] + liquid_surfaces_no_lld = liquid_surface_no_lld or \ + [ls + (op.liquid_height or 0) for ls, op in zip(well_bottoms, ops)] if lld_search_height is None: lld_search_height = [ - ( - wb + op.resource.get_absolute_size_z() + (2.7 if isinstance(op.resource, Well) else 5) - ) # ? + (wb + op.resource.get_absolute_size_z() + (2.7 if isinstance(op.resource, Well) else 5)) #? for wb, op in zip(well_bottoms, ops) ] else: lld_search_height = [wb + sh for wb, sh in zip(well_bottoms, lld_search_height)] - dispensing_modes = dispensing_mode or [ - _dispensing_mode_for_op(empty=empty[i], jet=jet[i], blow_out=blow_out[i]) - for i in range(len(ops)) - ] + dispensing_modes = dispensing_mode or \ + [_dispensing_mode_for_op(empty=empty[i], jet=jet[i], blow_out=blow_out[i]) + for i in range(len(ops))] - pull_out_distance_transport_air = _fill_in_defaults(pull_out_distance_transport_air, [10.0] * n) - second_section_height = _fill_in_defaults(second_section_height, [3.2] * n) - second_section_ratio = _fill_in_defaults(second_section_ratio, [618.0] * n) + dispense_volumes = [op.volume for op in ops] + pull_out_distance_transport_air = _fill_in_defaults(pull_out_distance_transport_air, [10.0]*n) + second_section_height = _fill_in_defaults(second_section_height, [3.2]*n) + second_section_ratio = _fill_in_defaults(second_section_ratio, [618.0]*n) minimum_height = _fill_in_defaults(minimum_height, well_bottoms) - immersion_depth = _fill_in_defaults(immersion_depth, [0] * n) - immersion_depth_direction = _fill_in_defaults(immersion_depth_direction, [0] * n) - surface_following_distance = _fill_in_defaults(surface_following_distance, [0] * n) - flow_rates = [ - op.flow_rate or (hlc.dispense_flow_rate if hlc is not None else 120) - for op, hlc in zip(ops, hamilton_liquid_classes) - ] - cut_off_speed = _fill_in_defaults(cut_off_speed, [5.0] * n) - stop_back_volume = _fill_in_defaults( - stop_back_volume, - default=[ - hlc.dispense_stop_back_volume if hlc is not None else 0 for hlc in hamilton_liquid_classes - ], - ) - transport_air_volume = _fill_in_defaults( - transport_air_volume, - default=[ - hlc.dispense_air_transport_volume if hlc is not None else 0 - for hlc in hamilton_liquid_classes - ], - ) - blow_out_air_volumes = [ - (op.blow_out_air_volume or (hlc.dispense_blow_out_volume if hlc is not None else 0)) - for op, hlc in zip(ops, hamilton_liquid_classes) - ] - lld_mode = _fill_in_defaults(lld_mode, [self.__class__.LLDMode.OFF] * n) - dispense_position_above_z_touch_off = _fill_in_defaults( - dispense_position_above_z_touch_off, default=[0] * n - ) - gamma_lld_sensitivity = _fill_in_defaults(gamma_lld_sensitivity, [1] * n) - dp_lld_sensitivity = _fill_in_defaults(dp_lld_sensitivity, [1] * n) - swap_speed = _fill_in_defaults( - swap_speed, - default=[ - hlc.dispense_swap_speed if hlc is not None else 10.0 for hlc in hamilton_liquid_classes - ], - ) - settling_time = _fill_in_defaults( - settling_time, - default=[ - hlc.dispense_settling_time if hlc is not None else 0 for hlc in hamilton_liquid_classes - ], - ) - mix_volume = _fill_in_defaults(mix_volume, [0] * n) - mix_cycles = _fill_in_defaults(mix_cycles, [0] * n) - mix_position_from_liquid_surface = _fill_in_defaults(mix_position_from_liquid_surface, [0] * n) - mix_speed = _fill_in_defaults( - mix_speed, - default=[ - hlc.dispense_mix_flow_rate if hlc is not None else 50.0 for hlc in hamilton_liquid_classes - ], - ) - mix_surface_following_distance = _fill_in_defaults(mix_surface_following_distance, [0] * n) - limit_curve_index = _fill_in_defaults(limit_curve_index, [0] * n) + immersion_depth = _fill_in_defaults(immersion_depth, [0]*n) + immersion_depth_direction = _fill_in_defaults(immersion_depth_direction, [0]*n) + surface_following_distance = _fill_in_defaults(surface_following_distance, [0]*n) + flow_rates = [op.flow_rate or 120 for op in ops] + cut_off_speed = _fill_in_defaults(cut_off_speed, [5.0]*n) + stop_back_volume = _fill_in_defaults(stop_back_volume, default=[0]*n) + transport_air_volume = _fill_in_defaults(transport_air_volume, [0]*n) + blow_out_air_volumes = [op.blow_out_air_volume or 0 for op in ops] + lld_mode = _fill_in_defaults(lld_mode, [self.__class__.LLDMode.OFF]*n) + dispense_position_above_z_touch_off = _fill_in_defaults(dispense_position_above_z_touch_off, + default=[0]*n) + gamma_lld_sensitivity = _fill_in_defaults(gamma_lld_sensitivity, [1]*n) + dp_lld_sensitivity = _fill_in_defaults(dp_lld_sensitivity, [1]*n) + swap_speed = _fill_in_defaults(swap_speed, [10.0]*n) + settling_time = _fill_in_defaults(settling_time, [0]*n) + mix_volume = _fill_in_defaults(mix_volume, [0]*n) + mix_cycles = _fill_in_defaults(mix_cycles, [0]*n) + mix_position_from_liquid_surface = _fill_in_defaults(mix_position_from_liquid_surface, [0]*n) + mix_speed = _fill_in_defaults(mix_speed, [50.0]*n) + mix_surface_following_distance = _fill_in_defaults(mix_surface_following_distance, [0]*n) + limit_curve_index = _fill_in_defaults(limit_curve_index, [0]*n) try: ret = await self.dispense_pip( tip_pattern=channels_involved, x_positions=x_positions, y_positions=y_positions, + dispensing_mode=dispensing_modes, - dispense_volumes=[round(vol * 10) for vol in volumes], - lld_search_height=[round(lsh * 10) for lsh in lld_search_height], - liquid_surface_no_lld=[round(ls * 10) for ls in liquid_surfaces_no_lld], - pull_out_distance_transport_air=[round(po * 10) for po in pull_out_distance_transport_air], - second_section_height=[round(sh * 10) for sh in second_section_height], - second_section_ratio=[round(sr * 10) for sr in second_section_ratio], - minimum_height=[round(mh * 10) for mh in minimum_height], - immersion_depth=[round(id_ * 10) for id_ in immersion_depth], # [0, 0] + dispense_volumes=[round(op.volume*10) for op in ops], + lld_search_height=[round(lsh*10) for lsh in lld_search_height], + liquid_surface_no_lld=[round(ls*10) for ls in liquid_surfaces_no_lld], + pull_out_distance_transport_air=[round(po*10) for po in pull_out_distance_transport_air], + second_section_height=[round(sh*10) for sh in second_section_height], + second_section_ratio=[round(sr*10) for sr in second_section_ratio], + minimum_height=[round(mh*10) for mh in minimum_height], + immersion_depth=[round(id_*10) for id_ in immersion_depth], # [0, 0] immersion_depth_direction=immersion_depth_direction, - surface_following_distance=[round(sfd * 10) for sfd in surface_following_distance], - dispense_speed=[round(fr * 10) for fr in flow_rates], - cut_off_speed=[round(cs * 10) for cs in cut_off_speed], - stop_back_volume=[round(sbv * 10) for sbv in stop_back_volume], - transport_air_volume=[round(tav * 10) for tav in transport_air_volume], - blow_out_air_volume=[round(boa * 10) for boa in blow_out_air_volumes], + surface_following_distance=[round(sfd*10) for sfd in surface_following_distance], + dispense_speed=[round(fr*10) for fr in flow_rates], + cut_off_speed=[round(cs*10) for cs in cut_off_speed], + stop_back_volume=[round(sbv*10) for sbv in stop_back_volume], + transport_air_volume=[round(tav*10) for tav in transport_air_volume], + blow_out_air_volume=[round(boa*10) for boa in blow_out_air_volumes], lld_mode=[mode.value for mode in lld_mode], - dispense_position_above_z_touch_off=[ - round(dp * 10) for dp in dispense_position_above_z_touch_off - ], + dispense_position_above_z_touch_off=[round(dp*10) + for dp in dispense_position_above_z_touch_off], gamma_lld_sensitivity=gamma_lld_sensitivity, dp_lld_sensitivity=dp_lld_sensitivity, - swap_speed=[round(ss * 10) for ss in swap_speed], - settling_time=[round(st * 10) for st in settling_time], - mix_volume=[round(mv * 10) for mv in mix_volume], + swap_speed=[round(ss*10) for ss in swap_speed], + settling_time=[round(st*10) for st in settling_time], + mix_volume=[round(mv*10) for mv in mix_volume], mix_cycles=mix_cycles, - mix_position_from_liquid_surface=[ - round(mp * 10) for mp in mix_position_from_liquid_surface - ], - mix_speed=[round(ms * 10) for ms in mix_speed], - mix_surface_following_distance=[ - round(msfd * 10) for msfd in mix_surface_following_distance - ], + mix_position_from_liquid_surface=[round(mp*10) for mp in mix_position_from_liquid_surface], + mix_speed=[round(ms*10) for ms in mix_speed], + mix_surface_following_distance=[round(msfd*10) for msfd in mix_surface_following_distance], limit_curve_index=limit_curve_index, - minimum_traverse_height_at_beginning_of_a_command=round( - (minimum_traverse_height_at_beginning_of_a_command or self._channel_traversal_height) * 10 - ), - min_z_endpos=round((min_z_endpos or self._channel_traversal_height) * 10), + + minimum_traverse_height_at_beginning_of_a_command= + round((minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10), + min_z_endpos=round((min_z_endpos or self._traversal_height) * 10), side_touch_off_distance=side_touch_off_distance, ) except STARFirmwareError as e: @@ -2173,14 +1884,14 @@ async def pick_up_tips96( minimum_height_command_end: Optional[float] = None, minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, ): - """Pick up tips using the 96 head.""" + """ Pick up tips using the 96 head. """ assert self.core96_head_installed, "96 head must be installed" tip_spot_a1 = pickup.resource.get_item("A1") tip_a1 = tip_spot_a1.get_tip() assert isinstance(tip_a1, HamiltonTip), "Tip type must be HamiltonTip." ttti = await self.get_or_assign_tip_type_index(tip_a1) position = tip_spot_a1.get_absolute_location() + tip_spot_a1.center() + pickup.offset - z_deposit_position += round(pickup.offset.z * 10) + z_deposit_position += round(pickup.offset.z*10) x_direction = 0 if position.x > 0 else 1 return await self.pick_up_tips_core96( @@ -2189,13 +1900,10 @@ async def pick_up_tips96( y_position=round(position.y * 10), tip_type_idx=ttti, tip_pickup_method=tip_pickup_method, - z_deposit_position=round(z_deposit_position * 10), - minimum_traverse_height_at_beginning_of_a_command=round( - (minimum_traverse_height_at_beginning_of_a_command or self._channel_traversal_height) * 10 - ), - minimum_height_command_end=round( - (minimum_height_command_end or self._channel_traversal_height) * 10 - ), + z_deposit_position=round(z_deposit_position*10), + minimum_traverse_height_at_beginning_of_a_command= + round((minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10), + minimum_height_command_end=round((minimum_height_command_end or self._traversal_height) * 10), ) async def drop_tips96( @@ -2205,37 +1913,36 @@ async def drop_tips96( minimum_height_command_end: Optional[float] = None, minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, ): - """Drop tips from the 96 head.""" + """ Drop tips from the 96 head. """ assert self.core96_head_installed, "96 head must be installed" if isinstance(drop.resource, TipRack): tip_a1 = drop.resource.get_item("A1") position = tip_a1.get_absolute_location() + tip_a1.center() + drop.offset else: - position = self._position_96_head_in_resource(drop.resource) + drop.offset + position = drop.resource.get_absolute_location() + drop.offset x_direction = 0 if position.x > 0 else 1 return await self.discard_tips_core96( x_position=abs(round(position.x * 10)), x_direction=x_direction, y_position=round(position.y * 10), - z_deposit_position=round(z_deposit_position * 10), - minimum_traverse_height_at_beginning_of_a_command=round( - (minimum_traverse_height_at_beginning_of_a_command or self._channel_traversal_height) * 10 - ), - minimum_height_command_end=round( - (minimum_height_command_end or self._channel_traversal_height) * 10 - ), + z_deposit_position=round(z_deposit_position*10), + minimum_traverse_height_at_beginning_of_a_command= + round((minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10), + minimum_height_command_end=round((minimum_height_command_end or self._traversal_height) * 10), ) async def aspirate96( self, - aspiration: Union[MultiHeadAspirationPlate, MultiHeadAspirationContainer], + aspiration: Union[AspirationPlate, AspirationContainer], jet: bool = False, blow_out: bool = False, + use_lld: bool = False, liquid_height: float = 0, air_transport_retract_dist: float = 10, hlc: Optional[HamiltonLiquidClass] = None, + aspiration_type: int = 0, minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, minimal_end_height: Optional[float] = None, @@ -2251,14 +1958,14 @@ async def aspirate96( gamma_lld_sensitivity: int = 1, swap_speed: float = 2.0, settling_time: float = 1.0, - mix_volume: float = 0, - mix_cycles: int = 0, - mix_position_from_liquid_surface: float = 0, - surface_following_distance_during_mix: float = 0, - speed_of_mix: float = 120.0, + homogenization_volume: float = 0, + homogenization_cycles: int = 0, + homogenization_position_from_liquid_surface: float = 0, + surface_following_distance_during_homogenization: float = 0, + speed_of_homogenization: float = 120.0, limit_curve_index: int = 0, ): - """Aspirate using the Core96 head. + """ Aspirate using the Core96 head. Args: aspiration: The aspiration to perform. @@ -2267,8 +1974,6 @@ async def aspirate96( blow_out: Whether to use "blow out" dispense mode. Only used on dispense. Note that this is labelled as "empty" in the VENUS liquid editor, but "blow out" in the firmware documentation. - hlc: The Hamiltonian liquid class to use. If `None`, the liquid class will be determined - automatically. use_lld: If True, use gamma liquid level detection. If False, use liquid height. liquid_height: The height of the liquid above the bottom of the well, in millimeters. @@ -2292,67 +1997,42 @@ async def aspirate96( gamma_lld_sensitivity: The sensitivity of the gamma liquid level detection. swap_speed: Swap speed (on leaving liquid) [1mm/s]. Must be between 0.3 and 160. Default 2. settling_time: The time to wait after aspirating. - mix_volume: The volume of liquid to aspirate for mix. - mix_cycles: The number of cycles to perform for mix. - mix_position_from_liquid_surface: The position of the mix from the + homogenization_volume: The volume of liquid to aspirate for homogenization. + homogenization_cycles: The number of cycles to perform for homogenization. + homogenization_position_from_liquid_surface: The position of the homogenization from the liquid surface. - surface_following_distance_during_mix: The distance to follow the liquid surface - during mix. - speed_of_mix: The speed of mix. + surface_following_distance_during_homogenization: The distance to follow the liquid surface + during homogenization. + speed_of_homogenization: The speed of homogenization. limit_curve_index: The index of the limit curve to use. """ + if hlc is not None: + raise NotImplementedError("Hamilton liquid classes are deprecated.") + assert self.core96_head_installed, "96 head must be installed" + if jet is not None or blow_out is not None: + raise NotImplementedError("jet and blow out are not implemented for aspirate96 yet") + # get the first well and tip as representatives - if isinstance(aspiration, MultiHeadAspirationPlate): + if isinstance(aspiration, AspirationPlate): top_left_well = aspiration.wells[0] - position = ( - top_left_well.get_absolute_location() - + top_left_well.center() - + Coordinate(z=top_left_well.material_z_thickness) - + aspiration.offset - ) + position = top_left_well.get_absolute_location() + top_left_well.center() + \ + Coordinate(z=top_left_well.material_z_thickness) + aspiration.offset else: position = aspiration.container.get_absolute_location(y="b") + aspiration.offset - tip = aspiration.tips[0] - liquid_height = position.z + liquid_height - liquid_to_be_aspirated = Liquid.WATER - if len(aspiration.liquids[0]) > 0 and aspiration.liquids[0][0][0] is not None: - # [channel][liquid][PyLabRobot.resources.liquid.Liquid] - liquid_to_be_aspirated = aspiration.liquids[0][0][0] - hlc = hlc or get_star_liquid_class( - tip_volume=tip.maximal_volume, - is_core=True, - is_tip=True, - has_filter=tip.has_filter, - # get last liquid in pipette, first to be dispensed - liquid=liquid_to_be_aspirated, - jet=jet, - blow_out=blow_out, # see comment in method docstring - ) - - if hlc is not None: - volume = hlc.compute_corrected_volume(aspiration.volume) - else: - volume = aspiration.volume - - # Get better default values from the HLC if available - transport_air_volume = transport_air_volume or ( - hlc.aspiration_air_transport_volume if hlc is not None else 0 - ) - blow_out_air_volume = aspiration.blow_out_air_volume or ( - hlc.aspiration_blow_out_volume if hlc is not None else 0 - ) - flow_rate = aspiration.flow_rate or (hlc.aspiration_flow_rate if hlc is not None else 250) - swap_speed = swap_speed or (hlc.aspiration_swap_speed if hlc is not None else 100) - settling_time = settling_time or (hlc.aspiration_settling_time if hlc is not None else 0.5) - speed_of_mix = speed_of_mix or (hlc.aspiration_mix_flow_rate if hlc is not None else 10.0) + transport_air_volume = transport_air_volume or 0 + blow_out_air_volume = aspiration.blow_out_air_volume or 0 + flow_rate = aspiration.flow_rate or 250 + swap_speed = swap_speed or 100 + settling_time = settling_time or 0.5 + speed_of_homogenization = speed_of_homogenization or 10.0 - channel_pattern = [True] * 12 * 8 + channel_pattern = [True]*12*8 # Was this ever true? Just copied it over from pyhamilton. Could have something to do with # the liquid classes and whether blow_out mode is enabled. @@ -2372,37 +2052,37 @@ async def aspirate96( x_direction=0, y_positions=round(position.y * 10), aspiration_type=aspiration_type, - minimum_traverse_height_at_beginning_of_a_command=round( - (minimum_traverse_height_at_beginning_of_a_command or self._channel_traversal_height) * 10 - ), - minimal_end_height=round((minimal_end_height or self._channel_traversal_height) * 10), - lld_search_height=round(lld_search_height * 10), + + minimum_traverse_height_at_beginning_of_a_command= + round((minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10), + minimal_end_height=round((minimal_end_height or self._traversal_height) * 10), + lld_search_height=round(lld_search_height*10), liquid_surface_at_function_without_lld=round(liquid_height * 10), - pull_out_distance_to_take_transport_air_in_function_without_lld=round( - air_transport_retract_dist * 10 - ), - maximum_immersion_depth=round((maximum_immersion_depth or position.z) * 10), + pull_out_distance_to_take_transport_air_in_function_without_lld= + round(air_transport_retract_dist * 10), + maximum_immersion_depth=round((maximum_immersion_depth or position.z)*10), tube_2nd_section_height_measured_from_zm=round(tube_2nd_section_height_measured_from_zm * 10), tube_2nd_section_ratio=round(tube_2nd_section_ratio * 10), immersion_depth=round(immersion_depth * 10), immersion_depth_direction=immersion_depth_direction, - liquid_surface_sink_distance_at_the_end_of_aspiration=round( - liquid_surface_sink_distance_at_the_end_of_aspiration * 10 - ), - aspiration_volumes=round(volume * 10), + liquid_surface_sink_distance_at_the_end_of_aspiration= + round(liquid_surface_sink_distance_at_the_end_of_aspiration*10), + aspiration_volumes=round(aspiration.volume * 10), aspiration_speed=round(flow_rate * 10), transport_air_volume=round(transport_air_volume * 10), blow_out_air_volume=round(blow_out_air_volume * 10), pre_wetting_volume=round(pre_wetting_volume * 10), lld_mode=int(use_lld), gamma_lld_sensitivity=gamma_lld_sensitivity, - swap_speed=round(swap_speed * 10), + swap_speed=round(swap_speed*10), settling_time=round(settling_time * 10), - mix_volume=round(mix_volume * 10), - mix_cycles=mix_cycles, - mix_position_from_liquid_surface=round(mix_position_from_liquid_surface * 10), - surface_following_distance_during_mix=round(surface_following_distance_during_mix * 10), - speed_of_mix=round(speed_of_mix * 10), + homogenization_volume=round(homogenization_volume * 10), + homogenization_cycles=homogenization_cycles, + homogenization_position_from_liquid_surface= + round(homogenization_position_from_liquid_surface * 10), + surface_following_distance_during_homogenization= + round(surface_following_distance_during_homogenization * 10), + speed_of_homogenization=round(speed_of_homogenization * 10), channel_pattern=channel_pattern, limit_curve_index=limit_curve_index, tadm_algorithm=False, @@ -2411,15 +2091,17 @@ async def aspirate96( async def dispense96( self, - dispense: Union[MultiHeadDispensePlate, MultiHeadDispenseContainer], + dispense: Union[DispensePlate, DispenseContainer], jet: bool = False, empty: bool = False, blow_out: bool = False, hlc: Optional[HamiltonLiquidClass] = None, + liquid_height: float = 0, dispense_mode: Optional[int] = None, air_transport_retract_dist=10, use_lld: bool = False, + minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, minimal_end_height: Optional[float] = None, lld_search_height: float = 199.9, @@ -2442,7 +2124,7 @@ async def dispense96( cut_off_speed: float = 5.0, stop_back_volume: float = 0, ): - """Dispense using the Core96 head. + """ Dispense using the Core96 head. Args: dispense: The Dispense command to execute. @@ -2479,99 +2161,74 @@ async def dispense96( stop_back_volume: Unknown. """ + if hlc is not None: + raise NotImplementedError("Hamilton liquid classes are deprecated.") + + if jet is not None or blow_out is not None: + raise NotImplementedError("jet and blow out are not implemented for aspirate96 yet") + assert self.core96_head_installed, "96 head must be installed" # get the first well and tip as representatives - if isinstance(dispense, MultiHeadDispensePlate): + if isinstance(dispense, DispensePlate): top_left_well = dispense.wells[0] - position = ( - top_left_well.get_absolute_location() - + top_left_well.center() - + Coordinate(z=top_left_well.material_z_thickness) - + dispense.offset - ) + position = top_left_well.get_absolute_location() + top_left_well.center() + \ + Coordinate(z=top_left_well.material_z_thickness) + dispense.offset else: position = dispense.container.get_absolute_location(y="b") + dispense.offset - tip = dispense.tips[0] liquid_height = position.z + liquid_height dispense_mode = _dispensing_mode_for_op(empty=empty, jet=jet, blow_out=blow_out) - liquid_to_be_dispensed = Liquid.WATER # default to water. - if len(dispense.liquids[0]) > 0 and dispense.liquids[0][-1][0] is not None: - # [channel][liquid][PyLabRobot.resources.liquid.Liquid] - liquid_to_be_dispensed = dispense.liquids[0][-1][0] - hlc = hlc or get_star_liquid_class( - tip_volume=tip.maximal_volume, - is_core=True, - is_tip=True, - has_filter=tip.has_filter, - # get last liquid in pipette, first to be dispensed - liquid=liquid_to_be_dispensed, - jet=jet, - blow_out=blow_out, # see comment in method docstring - ) + transport_air_volume = transport_air_volume or 0 + blow_out_air_volume = dispense.blow_out_air_volume or 0 + flow_rate = dispense.flow_rate or 120 + swap_speed = swap_speed or 100 + settling_time = settling_time or 5 + speed_of_mixing = speed_of_mixing or 100 - if hlc is not None: - volume = hlc.compute_corrected_volume(dispense.volume) - else: - volume = dispense.volume - - transport_air_volume = transport_air_volume or ( - hlc.dispense_air_transport_volume if hlc is not None else 0 - ) - blow_out_air_volume = dispense.blow_out_air_volume or ( - hlc.dispense_blow_out_volume if hlc is not None else 0 - ) - flow_rate = dispense.flow_rate or (hlc.dispense_flow_rate if hlc is not None else 120) - swap_speed = swap_speed or (hlc.dispense_swap_speed if hlc is not None else 100) - settling_time = settling_time or (hlc.dispense_settling_time if hlc is not None else 5) - speed_of_mixing = speed_of_mixing or (hlc.dispense_mix_flow_rate if hlc is not None else 100) - - channel_pattern = [True] * 12 * 8 + channel_pattern = [True]*12*8 ret = await self.dispense_core_96( dispensing_mode=dispense_mode, x_position=round(position.x * 10), x_direction=0, y_position=round(position.y * 10), - minimum_traverse_height_at_beginning_of_a_command=round( - (minimum_traverse_height_at_beginning_of_a_command or self._channel_traversal_height) * 10 - ), - minimal_end_height=round((minimal_end_height or self._channel_traversal_height) * 10), - lld_search_height=round(lld_search_height * 10), - liquid_surface_at_function_without_lld=round(liquid_height * 10), - pull_out_distance_to_take_transport_air_in_function_without_lld=round( - air_transport_retract_dist * 10 - ), - maximum_immersion_depth=maximum_immersion_depth or round(position.z * 10), - tube_2nd_section_height_measured_from_zm=round(tube_2nd_section_height_measured_from_zm * 10), - tube_2nd_section_ratio=round(tube_2nd_section_ratio * 10), - immersion_depth=round(immersion_depth * 10), + + minimum_traverse_height_at_beginning_of_a_command= + round((minimum_traverse_height_at_beginning_of_a_command or self._traversal_height)*10), + minimal_end_height=round((minimal_end_height or self._traversal_height)*10), + lld_search_height=round(lld_search_height*10), + liquid_surface_at_function_without_lld=round(liquid_height*10), + pull_out_distance_to_take_transport_air_in_function_without_lld= + round(air_transport_retract_dist*10), + maximum_immersion_depth=maximum_immersion_depth or round(position.z*10), + tube_2nd_section_height_measured_from_zm=round(tube_2nd_section_height_measured_from_zm*10), + tube_2nd_section_ratio=round(tube_2nd_section_ratio*10), + immersion_depth=round(immersion_depth*10), immersion_depth_direction=immersion_depth_direction, - liquid_surface_sink_distance_at_the_end_of_dispense=round( - liquid_surface_sink_distance_at_the_end_of_dispense * 10 - ), - dispense_volume=round(volume * 10), - dispense_speed=round(flow_rate * 10), - transport_air_volume=round(transport_air_volume * 10), - blow_out_air_volume=round(blow_out_air_volume * 10), + liquid_surface_sink_distance_at_the_end_of_dispense= + round(liquid_surface_sink_distance_at_the_end_of_dispense*10), + dispense_volume=round(dispense.volume*10), + dispense_speed=round(flow_rate*10), + transport_air_volume=round(transport_air_volume*10), + blow_out_air_volume=round(blow_out_air_volume*10), lld_mode=int(use_lld), gamma_lld_sensitivity=gamma_lld_sensitivity, - swap_speed=round(swap_speed * 10), - settling_time=round(settling_time * 10), - mixing_volume=round(mixing_volume * 10), + swap_speed=round(swap_speed*10), + settling_time=round(settling_time*10), + mixing_volume=round(mixing_volume*10), mixing_cycles=mixing_cycles, - mixing_position_from_liquid_surface=round(mixing_position_from_liquid_surface * 10), - surface_following_distance_during_mixing=round(surface_following_distance_during_mixing * 10), - speed_of_mixing=round(speed_of_mixing * 10), + mixing_position_from_liquid_surface=round(mixing_position_from_liquid_surface*10), + surface_following_distance_during_mixing=round(surface_following_distance_during_mixing*10), + speed_of_mixing=round(speed_of_mixing*10), channel_pattern=channel_pattern, limit_curve_index=limit_curve_index, tadm_algorithm=False, recording_mode=0, - cut_off_speed=round(cut_off_speed * 10), - stop_back_volume=round(stop_back_volume * 10), + cut_off_speed=round(cut_off_speed*10), + stop_back_volume=round(stop_back_volume*10), ) # Was this ever true? Just copied it over from pyhamilton. Could have something to do with @@ -2589,6 +2246,63 @@ async def dispense96( return ret + async def iswap_pick_up_resource( + self, + resource: Resource, + grip_direction: GripDirection, + pickup_distance_from_top: float, + offset: Coordinate = Coordinate.zero(), + minimum_traverse_height_at_beginning_of_a_command: float = 284.0, + z_position_at_the_command_end: float = 284.0, + grip_strength: int = 4, + plate_width_tolerance: float = 2.0, + collision_control_level: int = 0, + acceleration_index_high_acc: int = 4, + acceleration_index_low_acc: int = 1, + fold_up_sequence_at_the_end_of_process: bool = True + ): + """ Pick up a resource using iSWAP. + Low level component of :meth:`move_resource` + """ + + assert self.iswap_installed, "iswap must be installed" + + # Get center of source plate. Also gripping height and plate width. + center = resource.get_absolute_location(x="c", y="c", z="b") + offset + grip_height = center.z + resource.get_absolute_size_z() - pickup_distance_from_top + if grip_direction in (GripDirection.FRONT, GripDirection.BACK): + plate_width = resource.get_absolute_size_x() + elif grip_direction in (GripDirection.RIGHT, GripDirection.LEFT): + plate_width = resource.get_absolute_size_y() + else: + raise ValueError("Invalid grip direction") + + await self.iswap_get_plate( + x_position=round(center.x * 10), + x_direction=0, + y_position=round(center.y * 10), + y_direction=0, + z_position=round(grip_height * 10), + z_direction=0, + grip_direction={ + GripDirection.FRONT: 1, + GripDirection.RIGHT: 2, + GripDirection.BACK: 3, + GripDirection.LEFT: 4, + }[grip_direction], + minimum_traverse_height_at_beginning_of_a_command= + round(minimum_traverse_height_at_beginning_of_a_command*10), + z_position_at_the_command_end=round(z_position_at_the_command_end*10), + grip_strength=grip_strength, + open_gripper_position=round(plate_width*10) + 30, + plate_width=round(plate_width*10) - 33, + plate_width_tolerance=round(plate_width_tolerance*10), + collision_control_level=collision_control_level, + acceleration_index_high_acc=acceleration_index_high_acc, + acceleration_index_low_acc=acceleration_index_low_acc, + fold_up_sequence_at_the_end_of_process=fold_up_sequence_at_the_end_of_process + ) + async def iswap_move_picked_up_resource( self, location: Coordinate, @@ -2597,9 +2311,9 @@ async def iswap_move_picked_up_resource( minimum_traverse_height_at_beginning_of_a_command: float = 284.0, collision_control_level: int = 1, acceleration_index_high_acc: int = 4, - acceleration_index_low_acc: int = 1, + acceleration_index_low_acc: int = 1 ): - """After a resource is picked up, move it to a new location but don't release it yet. + """ After a resource is picked up, move it to a new location but don't release it yet. Low level component of :meth:`move_resource` """ @@ -2620,12 +2334,78 @@ async def iswap_move_picked_up_resource( GripDirection.BACK: 3, GripDirection.LEFT: 4, }[grip_direction], - minimum_traverse_height_at_beginning_of_a_command=round( - minimum_traverse_height_at_beginning_of_a_command * 10 - ), + minimum_traverse_height_at_beginning_of_a_command= + round(minimum_traverse_height_at_beginning_of_a_command*10), collision_control_level=collision_control_level, acceleration_index_high_acc=acceleration_index_high_acc, - acceleration_index_low_acc=acceleration_index_low_acc, + acceleration_index_low_acc=acceleration_index_low_acc + ) + + async def iswap_release_picked_up_resource( + self, + location: Coordinate, + resource: Resource, + rotation: int, + offset: Coordinate, + grip_direction: GripDirection, + pickup_distance_from_top: float, + minimum_traverse_height_at_beginning_of_a_command: float = 284.0, + z_position_at_the_command_end: float = 284.0, + collision_control_level: int = 0, + ): + """ After a resource is picked up, release it at the specified location. + Low level component of :meth:`move_resource` + + Args: + location: The location to release the resource (bottom front left corner). + resource: The resource to release. + rotation: The rotation of the resource's final orientation wrt the pickup orientation. + offset: offset for location + grip_direction: The direction of the iswap arm on release. + pickup_distance_from_top: How far from the top the resource was picked up. + """ + + assert self.iswap_installed, "iswap must be installed" + + # Get center of source plate in absolute space. + # The computation of the center has to be rotated so that the offset is in absolute space. + center_in_absolute_space = Coordinate(*matrix_vector_multiply_3x3( + resource.rotated(z=rotation).get_absolute_rotation().get_rotation_matrix(), + resource.center().vector() + )) + # This is when the resource is rotated (around its origin), but we also need to translate + # so that the left front bottom corner of the plate is lfb in absolute space, not local. + center_in_absolute_space += get_child_location(resource.rotated(z=rotation)) + + center = location + center_in_absolute_space + offset + grip_height = center.z + resource.get_absolute_size_z() - pickup_distance_from_top + # grip_direction here is the put_direction. We use `rotation` to cancel it out and get the + # original grip direction. Hack. + if grip_direction in (GripDirection.FRONT, GripDirection.BACK): + plate_width = resource.rotated(z=rotation).get_absolute_size_x() + elif grip_direction in (GripDirection.RIGHT, GripDirection.LEFT): + plate_width = resource.rotated(z=rotation).get_absolute_size_y() + else: + raise ValueError("Invalid grip direction") + + await self.iswap_put_plate( + x_position=round(center.x * 10), + x_direction=0, + y_position=round(center.y * 10), + y_direction=0, + z_position=round(grip_height * 10), + z_direction=0, + grip_direction={ + GripDirection.FRONT: 1, + GripDirection.RIGHT: 2, + GripDirection.BACK: 3, + GripDirection.LEFT: 4, + }[grip_direction], + minimum_traverse_height_at_beginning_of_a_command= + round(minimum_traverse_height_at_beginning_of_a_command*10), + z_position_at_the_command_end=round(z_position_at_the_command_end*10), + open_gripper_position=round(plate_width*10) + 30, + collision_control_level=collision_control_level, ) async def core_pick_up_resource( @@ -2641,7 +2421,7 @@ async def core_pick_up_resource( channel_1: int = 7, channel_2: int = 8, ): - """Pick up resource with CoRe gripper tool + """ Pick up resource with CoRe gripper tool Low level component of :meth:`move_resource` Args: @@ -2661,7 +2441,7 @@ async def core_pick_up_resource( # Get center of source plate. Also gripping height and plate width. center = resource.get_absolute_location(x="c", y="c", z="b") + offset grip_height = center.z + resource.get_absolute_size_z() - pickup_distance_from_top - grip_width = resource.get_absolute_size_y() # grip width is y size of resource + grip_width = resource.get_absolute_size_y() #grip width is y size of resource if self.core_parked: await self.get_core(p1=channel_1, p2=channel_2) @@ -2670,18 +2450,16 @@ async def core_pick_up_resource( x_position=round(center.x * 10), x_direction=0, y_position=round(center.y * 10), - y_gripping_speed=round(y_gripping_speed * 10), + y_gripping_speed=round(y_gripping_speed*10), z_position=round(grip_height * 10), - z_speed=round(z_speed * 10), - open_gripper_position=round(grip_width * 10) + 30, - plate_width=round(grip_width * 10) - 30, + z_speed=round(z_speed*10), + open_gripper_position=round(grip_width*10) + 30, + plate_width=round(grip_width*10) - 30, grip_strength=grip_strength, - minimum_traverse_height_at_beginning_of_a_command=round( - (minimum_traverse_height_at_beginning_of_a_command or self._iswap_traversal_height) * 10 - ), - minimum_z_position_at_the_command_end=round( - (minimum_z_position_at_the_command_end or self._iswap_traversal_height) * 10 - ), + minimum_traverse_height_at_beginning_of_a_command= + round((minimum_traverse_height_at_beginning_of_a_command or self._traversal_height)*10), + minimum_z_position_at_the_command_end= + round((minimum_z_position_at_the_command_end or self._traversal_height)*10), ) async def core_move_picked_up_resource( @@ -2692,7 +2470,7 @@ async def core_move_picked_up_resource( acceleration_index: int = 4, z_speed: float = 50.0, ): - """After a ressource is picked up, move it to a new location but don't release it yet. + """ After a ressource is picked up, move it to a new location but don't release it yet. Low level component of :meth:`move_resource` Args: @@ -2715,10 +2493,9 @@ async def core_move_picked_up_resource( x_acceleration_index=acceleration_index, y_position=round(center.y * 10), z_position=round(center.z * 10), - z_speed=round(z_speed * 10), - minimum_traverse_height_at_beginning_of_a_command=round( - (minimum_traverse_height_at_beginning_of_a_command or self._iswap_traversal_height) * 10 - ), + z_speed=round(z_speed*10), + minimum_traverse_height_at_beginning_of_a_command= + round((minimum_traverse_height_at_beginning_of_a_command or self._traversal_height)*10), ) async def core_release_picked_up_resource( @@ -2726,11 +2503,12 @@ async def core_release_picked_up_resource( location: Coordinate, resource: Resource, pickup_distance_from_top: float, + offset: Coordinate = Coordinate.zero(), minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, z_position_at_the_command_end: Optional[float] = None, - return_tool: bool = True, + return_tool: bool = True ): - """Place resource with CoRe gripper tool + """ Place resource with CoRe gripper tool Low level component of :meth:`move_resource` Args: @@ -2746,332 +2524,138 @@ async def core_release_picked_up_resource( """ # Get center of destination location. Also gripping height and plate width. - grip_height = location.z + resource.get_absolute_size_z() - pickup_distance_from_top + center = location + resource.center() + offset + grip_height = center.z + resource.get_absolute_size_z() - pickup_distance_from_top grip_width = resource.get_absolute_size_y() await self.core_put_plate( - x_position=round(location.x * 10), + x_position=round(center.x * 10), x_direction=0, - y_position=round(location.y * 10), + y_position=round(center.y * 10), z_position=round(grip_height * 10), z_press_on_distance=0, z_speed=500, - open_gripper_position=round(grip_width * 10) + 30, - minimum_traverse_height_at_beginning_of_a_command=round( - (minimum_traverse_height_at_beginning_of_a_command or self._iswap_traversal_height) * 10 - ), - z_position_at_the_command_end=round( - (z_position_at_the_command_end or self._iswap_traversal_height) * 10 - ), - return_tool=return_tool, + open_gripper_position=round(grip_width*10) + 30, + minimum_traverse_height_at_beginning_of_a_command= + round((minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10), + z_position_at_the_command_end= + round((z_position_at_the_command_end or self._traversal_height)*10), + return_tool=return_tool ) - async def pick_up_resource( + async def move_resource( self, - pickup: ResourcePickup, + move: Move, use_arm: Literal["iswap", "core"] = "iswap", channel_1: int = 7, channel_2: int = 8, - iswap_grip_strength: int = 4, core_grip_strength: int = 15, - minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, - z_position_at_the_command_end: Optional[float] = None, - plate_width_tolerance: float = 2.0, - open_gripper_position: Optional[float] = None, - hotel_depth=160.0, - hotel_clearance_height=7.5, - high_speed=False, - plate_width: Optional[float] = None, - use_unsafe_hotel: bool = False, - iswap_collision_control_level: int = 0, - iswap_fold_up_sequence_at_the_end_of_process: bool = True, + return_core_gripper: bool = True, ): - if use_arm == "iswap": - assert ( - pickup.resource.get_absolute_rotation().x == 0 - and pickup.resource.get_absolute_rotation().y == 0 - ) - assert pickup.resource.get_absolute_rotation().z % 90 == 0 - if plate_width is None: - if pickup.direction in (GripDirection.FRONT, GripDirection.BACK): - plate_width = pickup.resource.get_absolute_size_x() - else: - plate_width = pickup.resource.get_absolute_size_y() - - center_in_absolute_space = pickup.resource.center().rotated( - pickup.resource.get_absolute_rotation() - ) - x, y, z = ( - pickup.resource.get_absolute_location("l", "f", "t") - + center_in_absolute_space - + pickup.offset - ) - z -= pickup.pickup_distance_from_top + """ Move a resource. - traverse_height_at_beginning = ( - minimum_traverse_height_at_beginning_of_a_command or self._iswap_traversal_height - ) - z_position_at_the_command_end = z_position_at_the_command_end or self._iswap_traversal_height - - if open_gripper_position is None: - if use_unsafe_hotel: - open_gripper_position = plate_width + 5 - else: - open_gripper_position = plate_width + 3 - - if use_unsafe_hotel: - await self.unsafe.get_from_hotel( - hotel_center_x_coord=round(abs(x) * 10), - hotel_center_y_coord=round(abs(y) * 10), - # hotel_center_z_coord=int((z * 10)+0.5), # use sensible rounding (.5 goes up) - hotel_center_z_coord=round(abs(z) * 10), - hotel_center_x_direction=0 if x >= 0 else 1, - hotel_center_y_direction=0 if y >= 0 else 1, - hotel_center_z_direction=0 if z >= 0 else 1, - clearance_height=round(hotel_clearance_height * 10), - hotel_depth=round(hotel_depth * 10), - grip_direction=pickup.direction, - open_gripper_position=round(open_gripper_position * 10), - traverse_height_at_beginning=round(traverse_height_at_beginning * 10), - z_position_at_end=round(z_position_at_the_command_end * 10), - high_acceleration_index=4 if high_speed else 1, - low_acceleration_index=1, - plate_width=round(plate_width * 10), - plate_width_tolerance=round(plate_width_tolerance * 10), - ) - else: - await self.iswap_get_plate( - x_position=round(x * 10), - y_position=round(y * 10), - z_position=round(z * 10), - x_direction=0 if x >= 0 else 1, - y_direction=0 if y >= 0 else 1, - z_direction=0 if z >= 0 else 1, - grip_direction={ - GripDirection.FRONT: 1, - GripDirection.RIGHT: 2, - GripDirection.BACK: 3, - GripDirection.LEFT: 4, - }[pickup.direction], - minimum_traverse_height_at_beginning_of_a_command=round( - traverse_height_at_beginning * 10 - ), - z_position_at_the_command_end=round(z_position_at_the_command_end * 10), - grip_strength=iswap_grip_strength, - open_gripper_position=round(open_gripper_position * 10), - plate_width=round(plate_width * 10) - 33, - plate_width_tolerance=round(plate_width_tolerance * 10), - collision_control_level=iswap_collision_control_level, - acceleration_index_high_acc=4 if high_speed else 1, - acceleration_index_low_acc=1, - fold_up_sequence_at_the_end_of_process=iswap_fold_up_sequence_at_the_end_of_process, - ) - elif use_arm == "core": - if use_unsafe_hotel: - raise ValueError("Cannot use iswap hotel mode with core grippers") + Args: + move: The move to perform. + use_arm: Which arm to use. Either "iswap" or "core". + channel_1: The first channel to use with the core arm. Only used if `use_arm` is "core". + channel_2: The second channel to use with the core arm. Only used if `use_arm` is "core". + core_grip_strength: The grip strength to use with the core arm. Only used if `use_arm` is + "core". + return_core_gripper: Whether to return the core gripper to the home position after the move. + Only used if `use_arm` is "core". + """ - await self.core_pick_up_resource( - resource=pickup.resource, - pickup_distance_from_top=pickup.pickup_distance_from_top, - offset=pickup.offset, - minimum_traverse_height_at_beginning_of_a_command=self._iswap_traversal_height, - minimum_z_position_at_the_command_end=self._iswap_traversal_height, - channel_1=channel_1, - channel_2=channel_2, - grip_strength=core_grip_strength, - ) - else: + if not use_arm in {"iswap", "core"}: raise ValueError(f"use_arm must be either 'iswap' or 'core', not {use_arm}") - async def move_picked_up_resource( - self, move: ResourceMove, use_arm: Literal["iswap", "core"] = "iswap" - ): if use_arm == "iswap": - await self.iswap_move_picked_up_resource( - location=move.location, + await self.iswap_pick_up_resource( resource=move.resource, - grip_direction=move.gripped_direction, - minimum_traverse_height_at_beginning_of_a_command=self._iswap_traversal_height, - collision_control_level=1, - acceleration_index_high_acc=4, - acceleration_index_low_acc=1, + grip_direction=move.get_direction, + pickup_distance_from_top=move.pickup_distance_from_top, + offset=move.resource_offset, + minimum_traverse_height_at_beginning_of_a_command=self._traversal_height, + z_position_at_the_command_end=self._traversal_height, ) else: - await self.core_move_picked_up_resource( - location=move.location, + await self.core_pick_up_resource( resource=move.resource, - minimum_traverse_height_at_beginning_of_a_command=self._iswap_traversal_height, - acceleration_index=4, - ) - - async def drop_resource( - self, - drop: ResourceDrop, - use_arm: Literal["iswap", "core"] = "iswap", - return_core_gripper: bool = True, - minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, - z_position_at_the_command_end: Optional[float] = None, - open_gripper_position: Optional[float] = None, - hotel_depth=160.0, - hotel_clearance_height=7.5, - hotel_high_speed=False, - use_unsafe_hotel: bool = False, - iswap_collision_control_level: int = 0, - ): - # Get center of source plate in absolute space. - # The computation of the center has to be rotated so that the offset is in absolute space. - # center_in_absolute_space will be the vector pointing from the destination origin to the - # center of the moved the resource after drop. - # This means that the center vector has to be rotated from the child local space by the - # new child absolute rotation. The moved resource's rotation will be the original child - # rotation plus the rotation applied by the movement. - # The resource is moved by drop.rotation - # The new resource absolute location is - # drop.resource.get_absolute_rotation().z + drop.rotation - center_in_absolute_space = drop.resource.center().rotated( - Rotation(z=drop.resource.get_absolute_rotation().z + drop.rotation) - ) - x, y, z = drop.destination + center_in_absolute_space + drop.offset - - if use_arm == "iswap": - traversal_height_start = ( - minimum_traverse_height_at_beginning_of_a_command or self._iswap_traversal_height - ) - z_position_at_the_command_end = z_position_at_the_command_end or self._iswap_traversal_height - assert ( - drop.resource.get_absolute_rotation().x == 0 - and drop.resource.get_absolute_rotation().y == 0 + pickup_distance_from_top=move.pickup_distance_from_top, + offset=move.resource_offset, + minimum_traverse_height_at_beginning_of_a_command=self._traversal_height, + minimum_z_position_at_the_command_end=self._traversal_height, + channel_1=channel_1, + channel_2=channel_2, + grip_strength=core_grip_strength, ) - assert drop.resource.get_absolute_rotation().z % 90 == 0 - - # Use the pickup direction to determine how wide the plate is gripped. - # Note that the plate is still in the original orientation at this point, - # so get_absolute_size_{x,y}() will return the size of the plate in the original orientation. - if ( - drop.pickup_direction == GripDirection.FRONT or drop.pickup_direction == GripDirection.BACK - ): - plate_width = drop.resource.get_absolute_size_x() - elif ( - drop.pickup_direction == GripDirection.RIGHT or drop.pickup_direction == GripDirection.LEFT - ): - plate_width = drop.resource.get_absolute_size_y() - else: - raise ValueError("Invalid grip direction") - z = z + drop.resource.get_absolute_size_z() - drop.pickup_distance_from_top - - if open_gripper_position is None: - if use_unsafe_hotel: - open_gripper_position = plate_width + 5 - else: - open_gripper_position = plate_width + 3 - - if use_unsafe_hotel: - # hotel: down forward down. - # down to level of the destination + the clearance height (so clearance height can be subtracted) - # hotel_depth is forward. - # clearance height is second down. - - await self.unsafe.put_in_hotel( - hotel_center_x_coord=round(abs(x) * 10), - hotel_center_y_coord=round(abs(y) * 10), - hotel_center_z_coord=round(abs(z) * 10), - hotel_center_x_direction=0 if x >= 0 else 1, - hotel_center_y_direction=0 if y >= 0 else 1, - hotel_center_z_direction=0 if z >= 0 else 1, - clearance_height=round(hotel_clearance_height * 10), - hotel_depth=round(hotel_depth * 10), - grip_direction=drop.drop_direction, - open_gripper_position=round(open_gripper_position * 10), - traverse_height_at_beginning=round(traversal_height_start * 10), - z_position_at_end=round(z_position_at_the_command_end * 10), - high_acceleration_index=4 if hotel_high_speed else 1, - low_acceleration_index=1, - ) + previous_location = move.resource.get_absolute_location() + move.resource_offset + minimum_traverse_height = 284.0 + previous_location.z = minimum_traverse_height - move.resource.get_absolute_size_z() / 2 + + for location in move.intermediate_locations: + if use_arm == "iswap": + await self.iswap_move_picked_up_resource( + location=location, + resource=move.resource, + grip_direction=move.get_direction, + minimum_traverse_height_at_beginning_of_a_command=self._traversal_height, + # int(previous_location.z + move.resource.get_size_z() / 2) * 10, # "minimum" is a scam. + collision_control_level=1, + acceleration_index_high_acc=4, + acceleration_index_low_acc=1) else: - await self.iswap_put_plate( - x_position=round(abs(x) * 10), - y_position=round(abs(y) * 10), - z_position=round(abs(z) * 10), - x_direction=0 if x >= 0 else 1, - y_direction=0 if y >= 0 else 1, - z_direction=0 if z >= 0 else 1, - grip_direction={ - GripDirection.FRONT: 1, - GripDirection.RIGHT: 2, - GripDirection.BACK: 3, - GripDirection.LEFT: 4, - }[drop.drop_direction], - minimum_traverse_height_at_beginning_of_a_command=round(traversal_height_start * 10), - z_position_at_the_command_end=round(z_position_at_the_command_end * 10), - open_gripper_position=round(open_gripper_position * 10), - collision_control_level=iswap_collision_control_level, + await self.core_move_picked_up_resource( + location=location, + resource=move.resource, + minimum_traverse_height_at_beginning_of_a_command=self._traversal_height, + # int(previous_location.z + move.resource.get_size_z() / 2) * 10, + acceleration_index=4 ) - elif use_arm == "core": - if use_unsafe_hotel: - raise ValueError("Cannot use iswap hotel mode with core grippers") + previous_location = location - await self.core_release_picked_up_resource( - location=Coordinate(x, y, z), - resource=drop.resource, - pickup_distance_from_top=drop.pickup_distance_from_top, - minimum_traverse_height_at_beginning_of_a_command=self._iswap_traversal_height, - z_position_at_the_command_end=self._iswap_traversal_height, - # int(previous_location.z + move.resource.get_size_z() / 2) * 10, - return_tool=return_core_gripper, + if use_arm == "iswap": + await self.iswap_release_picked_up_resource( + location=move.destination, + resource=move.resource, + rotation=move.rotation, + offset=move.destination_offset, + grip_direction=move.put_direction, + pickup_distance_from_top=move.pickup_distance_from_top, + minimum_traverse_height_at_beginning_of_a_command=self._traversal_height, + # int(previous_location.z + move.resource.get_size_z() / 2) * 10, # "minimum" is a scam. + z_position_at_the_command_end=self._traversal_height, ) else: - raise ValueError(f"use_arm must be either 'iswap' or 'core', not {use_arm}") + await self.core_release_picked_up_resource( + location=move.destination, + resource=move.resource, + offset=move.destination_offset, + pickup_distance_from_top=move.pickup_distance_from_top, + minimum_traverse_height_at_beginning_of_a_command=self._traversal_height, + z_position_at_the_command_end=self._traversal_height, + # int(previous_location.z + move.resource.get_size_z() / 2) * 10, + return_tool=return_core_gripper + ) async def prepare_for_manual_channel_operation(self, channel: int): - """Prepare for manual operation.""" + """ Prepare for manual operation. """ - await self.position_max_free_y_for_n(pipetting_channel_index=channel) + await self.position_max_free_y_for_n(pipetting_channel_index=channel + 1) - async def move_channel_x(self, channel: int, x: float): - """Move a channel in the x direction.""" + async def move_channel_x(self, channel: int, x: float): # pylint: disable=unused-argument + """ Move a channel in the x direction. """ await self.position_left_x_arm_(round(x * 10)) - @need_iswap_parked async def move_channel_y(self, channel: int, y: float): - """Move a channel safely in the y direction.""" - - # Anti-channel-crash feature - if channel > 0: - max_y_pos = await self.request_y_pos_channel_n(channel - 1) - if y > max_y_pos: - raise ValueError( - f"channel {channel} y-target must be <= {max_y_pos} mm " - f"(channel {channel - 1} y-position is {round(y, 2)} mm)" - ) - else: - # STAR machines appear to lose connection to a channel if y > 635 mm - max_y_pos = 635 - if y > max_y_pos: - raise ValueError(f"channel {channel} y-target must be <= {max_y_pos} mm (machine limit)") - - if channel < (self.num_channels - 1): - min_y_pos = await self.request_y_pos_channel_n(channel + 1) - if y < min_y_pos: - raise ValueError( - f"channel {channel} y-target must be >= {min_y_pos} mm " - f"(channel {channel + 1} y-position is {round(y, 2)} mm)" - ) - else: - # STAR machines appear to lose connection to a channel if y < 6 mm - min_y_pos = 6 - if y < min_y_pos: - raise ValueError(f"channel {channel} y-target must be >= {min_y_pos} mm (machine limit)") - + """ Move a channel in the y direction. """ await self.position_single_pipetting_channel_in_y_direction( - pipetting_channel_index=channel + 1, y_position=round(y * 10) - ) + pipetting_channel_index=channel + 1, y_position=round(y * 10)) async def move_channel_z(self, channel: int, z: float): - """Move a channel in the z direction.""" + """ Move a channel in the z direction. """ await self.position_single_pipetting_channel_in_z_direction( - pipetting_channel_index=channel + 1, z_position=round(z * 10) - ) + pipetting_channel_index=channel + 1, z_position=round(z*10)) async def core_check_resource_exists_at_location_center( self, @@ -3082,38 +2666,37 @@ async def core_check_resource_exists_at_location_center( minimum_traverse_height_at_beginning_of_a_command: float = 275.0, z_position_at_the_command_end: float = 275.0, enable_recovery: bool = True, - audio_feedback: bool = True, + audio_feedback: bool = True ) -> bool: - """Check existence of resource with CoRe gripper tool - a "Get plate using CO-RE gripper" + error handling - Which channels are used for resource check is dependent on which channels have been used for - `STAR.get_core(p1: int, p2: int)` which is a prerequisite for this check function. - - Args: - location: Location to check for resource - resource: Resource to check for. - gripper_y_margin = Distance between the front / back wall of the resource - and the grippers during "bumping" / checking - offset: Offset from resource position in mm. - minimum_traverse_height_at_beginning_of_a_command: Minimum traverse height at beginning of - a command [mm] (refers to all channels independent of tip pattern parameter 'tm'). - Must be between 0 and 360.0. - z_position_at_the_command_end: Minimum z-Position at end of a command [mm] (refers to - all channels independent of tip pattern parameter 'tm'). Must be between 0 and 360.0. - enable_recovery: if True will ask for user input if resource was not found - audio_feedback: enable controlling computer to emit different sounds when - finding/not finding the resource - - Returns: - True if resource was found, False if resource was not found - """ + """ Check existence of resource with CoRe gripper tool + a "Get plate using CO-RE gripper" + error handling + Which channels are used for resource check is dependent on which channels have been used for + `STAR.get_core(p1: int, p2: int)` which is a prerequisite for this check function. + + Args: + location: Location to check for resource + resource: Resource to check for. + gripper_y_margin = Distance between the front / back wall of the resource + and the grippers during "bumping" / checking + offset: Offset from resource position in mm. + minimum_traverse_height_at_beginning_of_a_command: Minimum traverse height at beginning of + a command [mm] (refers to all channels independent of tip pattern parameter 'tm'). + Must be between 0 and 360.0. + z_position_at_the_command_end: Minimum z-Position at end of a command [mm] (refers to + all channels independent of tip pattern parameter 'tm'). Must be between 0 and 360.0. + enable_recovery: if True will ask for user input if resource was not found + audio_feedback: enable controlling computer to emit different sounds when + finding/not finding the resource + + Returns: + True if resource was found, False if resource was not found + """ center = location + resource.centers()[0] + offset - y_width_to_gripper_bump = resource.get_absolute_size_y() - gripper_y_margin * 2 - assert 9 <= y_width_to_gripper_bump <= round(resource.get_absolute_size_y()), ( - f"width between channels must be between 9 and {resource.get_absolute_size_y()} mm" + y_width_to_gripper_bump = resource.get_absolute_size_y() - gripper_y_margin*2 + assert 9 <= y_width_to_gripper_bump <= round(resource.get_absolute_size_y()), \ + f"width between channels must be between 9 and {resource.get_absolute_size_y()} mm" \ " (i.e. the minimal distance between channels and the max y size of the resource" - ) # Check if CoRe gripper currently in use cores_used = not self._core_parked @@ -3135,12 +2718,11 @@ async def core_check_resource_exists_at_location_center( y_gripping_speed=50, x_direction=0, z_speed=600, - grip_strength=20, + grip_strength = 20, # Enable mods of channel z position for check acceleration - minimum_traverse_height_at_beginning_of_a_command=round( - minimum_traverse_height_at_beginning_of_a_command * 10 - ), - minimum_z_position_at_the_command_end=round(z_position_at_the_command_end * 10), + minimum_traverse_height_at_beginning_of_a_command= + round(minimum_traverse_height_at_beginning_of_a_command*10), + minimum_z_position_at_the_command_end=round(z_position_at_the_command_end*10), ) except STARFirmwareError as exc: for module_error in exc.errors.values(): @@ -3152,23 +2734,18 @@ async def core_check_resource_exists_at_location_center( if audio_feedback: audio.play_not_found() if enable_recovery: - print( - f"\nWARNING: Resource '{resource.name}' not found at center" - f" location {(center.x, center.y, center.z)} during check no {try_counter}." - ) - user_prompt = input( - "Have you checked resource is present?" - "\n [ yes ] -> machine will check location again" - "\n [ abort ] -> machine will abort run\n Answer:" - ) + print(f"\nWARNING: Resource '{resource.name}' not found at center" \ + f" location {(center.x, center.y, center.z)} during check no {try_counter}.") + user_prompt = input("Have you checked resource is present?" \ + "\n [ yes ] -> machine will check location again" \ + "\n [ abort ] -> machine will abort run\n Answer:" + ) if user_prompt == "yes": try_counter += 1 elif user_prompt == "abort": - raise ValueError( - f"Resource '{resource.name}' not found at center" - f" location {(center.x,center.y,center.z)}" - " & error not resolved -> aborted resource movement." - ) + raise ValueError(f"Resource '{resource.name}' not found at center" \ + f" location {(center.x,center.y,center.z)}" \ + " & error not resolved -> aborted resource movement.") else: # Resource was not found return False @@ -3178,23 +2755,12 @@ async def core_check_resource_exists_at_location_center( audio.play_got_item() return True - def _position_96_head_in_resource(self, resource: Resource) -> Coordinate: - """The firmware command expects location of tip A1 of the head. We center the head in the given - resource.""" - head_size_x = 9 * 11 # 12 channels, 9mm spacing in between - head_size_y = 9 * 7 # 8 channels, 9mm spacing in between - channel_size = 9 - loc = resource.get_absolute_location() - loc.x += (resource.get_size_x() - head_size_x) / 2 + channel_size / 2 - loc.y += (resource.get_size_y() - head_size_y) / 2 + channel_size / 2 - return loc - # ============== Firmware Commands ============== # -------------- 3.2 System general commands -------------- async def pre_initialize_instrument(self): - """Pre-initialize instrument""" + """ Pre-initialize instrument """ return await self.send_command(module="C0", command="VI") async def define_tip_needle( @@ -3204,9 +2770,9 @@ async def define_tip_needle( tip_length: int, maximum_tip_volume: int, tip_size: TipSize, - pickup_method: TipPickupMethod, + pickup_method: TipPickupMethod ): - """Tip/needle definition. + """ Tip/needle definition. Args: tip_type_table_index: tip_table_index @@ -3220,6 +2786,8 @@ async def define_tip_needle( power OFF or RESET. After power ON the default values apply. (see Table 3) """ + # pylint: disable=redefined-builtin + assert 0 <= tip_type_table_index <= 99, "tip_type_table_index must be between 0 and 99" assert 0 <= tip_type_table_index <= 99, "tip_type_table_index must be between 0 and 99" assert 1 <= tip_length <= 1999, "tip_length must be between 1 and 1999" @@ -3233,13 +2801,13 @@ async def define_tip_needle( tl=f"{tip_length:04}", tv=f"{maximum_tip_volume:05}", tg=tip_size.value, - tu=pickup_method.value, + tu=pickup_method.value ) # -------------- 3.2.1 System query -------------- async def request_error_code(self): - """Request error code + """ Request error code Here the last saved error messages can be retrieved. The error buffer is automatically voided when a new command is started. All configured nodes are displayed. @@ -3253,7 +2821,7 @@ async def request_error_code(self): return await self.send_command(module="C0", command="RE") async def request_firmware_version(self): - """Request firmware version + """ Request firmware version Returns: TODO: Rfid0001rf1.0S 2009-06-24 A """ @@ -3261,7 +2829,7 @@ async def request_firmware_version(self): return await self.send_command(module="C0", command="RF") async def request_parameter_value(self): - """Request parameter value + """ Request parameter value Returns: TODO: Raid1111er00/00yg1200 """ @@ -3276,12 +2844,14 @@ class BoardType(enum.Enum): UNKNOWN = -1 async def request_electronic_board_type(self): - """Request electronic board type + """ Request electronic board type Returns: The board type. """ + # pylint: disable=undefined-variable + resp = await self.send_command(module="C0", command="QB") try: return STAR.BoardType(resp["qb"]) @@ -3290,7 +2860,7 @@ async def request_electronic_board_type(self): # TODO: parse response. async def request_supply_voltage(self): - """Request supply voltage + """ Request supply voltage Request supply voltage (for LDPB only) """ @@ -3298,19 +2868,19 @@ async def request_supply_voltage(self): return await self.send_command(module="C0", command="MU") async def request_instrument_initialization_status(self) -> bool: - """Request instrument initialization status""" + """ Request instrument initialization status """ resp = await self.send_command(module="C0", command="QW", fmt="qw#") return resp is not None and resp["qw"] == 1 async def request_autoload_initialization_status(self) -> bool: - """Request autoload initialization status""" + """ Request autoload initialization status """ resp = await self.send_command(module="I0", command="QW", fmt="qw#") return resp is not None and resp["qw"] == 1 async def request_name_of_last_faulty_parameter(self): - """Request name of last faulty parameter + """ Request name of last faulty parameter Returns: TODO: Name of last parameter with syntax error @@ -3323,7 +2893,7 @@ async def request_name_of_last_faulty_parameter(self): return await self.send_command(module="C0", command="VP", fmt="vp&&") async def request_master_status(self): - """Request master status + """ Request master status Returns: TODO: see page 19 (SFCO.0036) """ @@ -3331,7 +2901,7 @@ async def request_master_status(self): return await self.send_command(module="C0", command="RQ") async def request_number_of_presence_sensors_installed(self): - """Request number of presence sensors installed + """ Request number of presence sensors installed Returns: number of sensors installed (1...103) @@ -3341,7 +2911,7 @@ async def request_number_of_presence_sensors_installed(self): return resp["sr"] async def request_eeprom_data_correctness(self): - """Request EEPROM data correctness + """ Request EEPROM data correctness Returns: TODO: (SFCO.0149) """ @@ -3352,8 +2922,12 @@ async def request_eeprom_data_correctness(self): # -------------- 3.3.1 Volatile Settings -------------- - async def set_single_step_mode(self, single_step_mode: bool = False): - """Set Single step mode + + async def set_single_step_mode( + self, + single_step_mode: bool = False + ): + """ Set Single step mode Args: single_step_mode: Single Step Mode. Default False. @@ -3366,13 +2940,13 @@ async def set_single_step_mode(self, single_step_mode: bool = False): ) async def trigger_next_step(self): - """Trigger next step (Single step mode)""" + """ Trigger next step (Single step mode) """ # TODO: this command has no reply!!!! return await self.send_command(module="C0", command="NS") async def halt(self): - """Halt + """ Halt Intermediate sequences not yet carried out and the commands in the command stack are discarded. Sequence already in process is @@ -3382,7 +2956,7 @@ async def halt(self): return await self.send_command(module="C0", command="HD") async def save_all_cycle_counters(self): - """Save all cycle counters + """ Save all cycle counters Save all cycle counters of the instrument """ @@ -3390,7 +2964,7 @@ async def save_all_cycle_counters(self): return await self.send_command(module="C0", command="AZ") async def set_not_stop(self, non_stop): - """Set not stop mode + """ Set not stop mode Args: non_stop: True if non stop mode should be turned on after command is sent. @@ -3407,9 +2981,9 @@ async def set_not_stop(self, non_stop): async def store_installation_data( self, date: datetime.datetime = datetime.datetime.now(), - serial_number: str = "0000", + serial_number: str = "0000" ): - """Store installation data + """ Store installation data Args: date: installation date. @@ -3417,15 +2991,20 @@ async def store_installation_data( assert len(serial_number) == 4, "serial number must be 4 chars long" - return await self.send_command(module="C0", command="SI", si=date, sn=serial_number) + return await self.send_command( + module="C0", + command="SI", + si=date, + sn=serial_number + ) async def store_verification_data( self, verification_subject: int = 0, date: datetime.datetime = datetime.datetime.now(), - verification_status: bool = False, + verification_status: bool = False ): - """Store verification data + """ Store verification data Args: verification_subject: verification subject. Default 0. Must be between 0 and 24. @@ -3444,39 +3023,54 @@ async def store_verification_data( ) async def additional_time_stamp(self): - """Additional time stamp""" + """ Additional time stamp """ return await self.send_command(module="C0", command="AT") async def set_x_offset_x_axis_iswap(self, x_offset: int): - """Set X-offset X-axis <-> iSWAP + """ Set X-offset X-axis <-> iSWAP Args: x_offset: X-offset [0.1mm] """ - return await self.send_command(module="C0", command="AG", x_offset=x_offset) + return await self.send_command( + module="C0", + command="AG", + x_offset=x_offset + ) async def set_x_offset_x_axis_core_96_head(self, x_offset: int): - """Set X-offset X-axis <-> CoRe 96 head + """ Set X-offset X-axis <-> CoRe 96 head Args: x_offset: X-offset [0.1mm] """ - return await self.send_command(module="C0", command="AF", x_offset=x_offset) + return await self.send_command( + module="C0", + command="AF", + x_offset=x_offset + ) async def set_x_offset_x_axis_core_nano_pipettor_head(self, x_offset: int): - """Set X-offset X-axis <-> CoRe 96 head + """ Set X-offset X-axis <-> CoRe 96 head Args: x_offset: X-offset [0.1mm] """ - return await self.send_command(module="C0", command="AF", x_offset=x_offset) + return await self.send_command( + module="C0", + command="AF", + x_offset=x_offset + ) - async def save_download_date(self, date: datetime.datetime = datetime.datetime.now()): - """Save Download date + async def save_download_date( + self, + date: datetime.datetime = datetime.datetime.now() + ): + """ Save Download date Args: date: download date. Default now. @@ -3488,8 +3082,12 @@ async def save_download_date(self, date: datetime.datetime = datetime.datetime.n ao=date, ) - async def save_technical_status_of_assemblies(self, processor_board: str, power_supply: str): - """Save technical status of assemblies + async def save_technical_status_of_assemblies( + self, + processor_board: str, + power_supply: str + ): + """ Save technical status of assemblies Args: processor_board: Processor board. Art.Nr./Rev./Ser.No. (000000/00/0000) @@ -3504,9 +3102,9 @@ async def save_technical_status_of_assemblies(self, processor_board: str, power_ async def set_instrument_configuration( self, - configuration_data_1: Optional[str] = None, # TODO: configuration byte - configuration_data_2: Optional[str] = None, # TODO: configuration byte - configuration_data_3: Optional[str] = None, # TODO: configuration byte + configuration_data_1: Optional[str] = None, # TODO: configuration byte + configuration_data_2: Optional[str] = None, # TODO: configuration byte + configuration_data_3: Optional[str] = None, # TODO: configuration byte instrument_size_in_slots_x_range: int = 54, auto_load_size_in_slots: int = 54, tip_waste_x_position: int = 13400, @@ -3524,9 +3122,9 @@ async def set_instrument_configuration( minimal_raster_pitch_of_robotic_channels: int = 360, pip_maximal_y_position: int = 6065, left_arm_minimal_y_position: int = 60, - right_arm_minimal_y_position: int = 60, + right_arm_minimal_y_position: int = 60 ): - """Set instrument configuration + """ Set instrument configuration Args: configuration_data_1: configuration data 1. @@ -3567,44 +3165,35 @@ async def set_instrument_configuration( and 9999. Default 60. """ - assert ( - 1 <= instrument_size_in_slots_x_range <= 9 - ), "instrument_size_in_slots_x_range must be between 1 and 99" + assert 1 <= instrument_size_in_slots_x_range <= 9, \ + "instrument_size_in_slots_x_range must be between 1 and 99" assert 1 <= auto_load_size_in_slots <= 54, "auto_load_size_in_slots must be between 1 and 54" assert 1000 <= tip_waste_x_position <= 25000, "tip_waste_x_position must be between 1 and 25000" - assert ( - 0 <= right_x_drive_configuration_byte_1 <= 1 - ), "right_x_drive_configuration_byte_1 must be between 0 and 1" - assert ( - 0 <= right_x_drive_configuration_byte_2 <= 1 - ), "right_x_drive_configuration_byte_2 must be between 0 and must1" - assert ( - 0 <= minimal_iswap_collision_free_position <= 30000 - ), "minimal_iswap_collision_free_position must be between 0 and 30000" - assert ( - 0 <= maximal_iswap_collision_free_position <= 30000 - ), "maximal_iswap_collision_free_position must be between 0 and 30000" + assert 0 <= right_x_drive_configuration_byte_1 <= 1, \ + "right_x_drive_configuration_byte_1 must be between 0 and 1" + assert 0 <= right_x_drive_configuration_byte_2 <= 1, \ + "right_x_drive_configuration_byte_2 must be between 0 and must1" + assert 0 <= minimal_iswap_collision_free_position <= 30000, \ + "minimal_iswap_collision_free_position must be between 0 and 30000" + assert 0 <= maximal_iswap_collision_free_position <= 30000, \ + "maximal_iswap_collision_free_position must be between 0 and 30000" assert 0 <= left_x_arm_width <= 9999, "left_x_arm_width must be between 0 and 9999" assert 0 <= right_x_arm_width <= 9999, "right_x_arm_width must be between 0 and 9999" assert 0 <= num_pip_channels <= 16, "num_pip_channels must be between 0 and 16" assert 0 <= num_xl_channels <= 8, "num_xl_channels must be between 0 and 8" assert 0 <= num_robotic_channels <= 8, "num_robotic_channels must be between 0 and 8" - assert ( - 0 <= minimal_raster_pitch_of_pip_channels <= 999 - ), "minimal_raster_pitch_of_pip_channels must be between 0 and 999" - assert ( - 0 <= minimal_raster_pitch_of_xl_channels <= 999 - ), "minimal_raster_pitch_of_xl_channels must be between 0 and 999" - assert ( - 0 <= minimal_raster_pitch_of_robotic_channels <= 999 - ), "minimal_raster_pitch_of_robotic_channels must be between 0 and 999" - assert 0 <= pip_maximal_y_position <= 9999, "pip_maximal_y_position must be between 0 and 9999" - assert ( - 0 <= left_arm_minimal_y_position <= 9999 - ), "left_arm_minimal_y_position must be between 0 and 9999" - assert ( - 0 <= right_arm_minimal_y_position <= 9999 - ), "right_arm_minimal_y_position must be between 0 and 9999" + assert 0 <= minimal_raster_pitch_of_pip_channels <= 999, \ + "minimal_raster_pitch_of_pip_channels must be between 0 and 999" + assert 0 <= minimal_raster_pitch_of_xl_channels <= 999, \ + "minimal_raster_pitch_of_xl_channels must be between 0 and 999" + assert 0 <= minimal_raster_pitch_of_robotic_channels <= 999, \ + "minimal_raster_pitch_of_robotic_channels must be between 0 and 999" + assert 0 <= pip_maximal_y_position <= 9999, \ + "pip_maximal_y_position must be between 0 and 9999" + assert 0 <= left_arm_minimal_y_position <= 9999, \ + "left_arm_minimal_y_position must be between 0 and 9999" + assert 0 <= right_arm_minimal_y_position <= 9999, \ + "right_arm_minimal_y_position must be between 0 and 9999" return await self.send_command( module="C0", @@ -3632,8 +3221,11 @@ async def set_instrument_configuration( yx=right_arm_minimal_y_position, ) - async def save_pip_channel_validation_status(self, validation_status: bool = False): - """Save PIP channel validation status + async def save_pip_channel_validation_status( + self, + validation_status: bool = False + ): + """ Save PIP channel validation status Args: validation_status: PIP channel validation status. Default False. @@ -3645,8 +3237,11 @@ async def save_pip_channel_validation_status(self, validation_status: bool = Fal tq=validation_status, ) - async def save_xl_channel_validation_status(self, validation_status: bool = False): - """Save XL channel validation status + async def save_xl_channel_validation_status( + self, + validation_status: bool = False + ): + """ Save XL channel validation status Args: validation_status: XL channel validation status. Default False. @@ -3660,12 +3255,16 @@ async def save_xl_channel_validation_status(self, validation_status: bool = Fals # TODO: response async def configure_node_names(self): - """Configure node names""" + """ Configure node names """ return await self.send_command(module="C0", command="AJ") - async def set_deck_data(self, data_index: int = 0, data_stream: str = "0"): - """set deck data + async def set_deck_data( + self, + data_index: int = 0, + data_stream: str = "0" + ): + """ set deck data Args: data_index: data index. Must be between 0 and 9. Default 0. @@ -3685,25 +3284,28 @@ async def set_deck_data(self, data_index: int = 0, data_stream: str = "0"): # -------------- 3.3.3 Settings query (stored in EEPROM) -------------- async def request_technical_status_of_assemblies(self): - """Request Technical status of assemblies""" + """ Request Technical status of assemblies """ # TODO: parse res return await self.send_command(module="C0", command="QT") async def request_installation_data(self): - """Request installation data""" + """ Request installation data """ # TODO: parse res return await self.send_command(module="C0", command="RI") async def request_download_date(self): - """Request download date""" + """ Request download date """ # TODO: parse res return await self.send_command(module="C0", command="RO") - async def request_verification_data(self, verification_subject: int = 0): - """Request download date + async def request_verification_data( + self, + verification_subject: int = 0 + ): + """ Request download date Args: verification_subject: verification subject. Must be between 0 and 24. Default 0. @@ -3712,50 +3314,51 @@ async def request_verification_data(self, verification_subject: int = 0): assert 0 <= verification_subject <= 24, "verification_subject must be between 0 and 24" # TODO: parse results. - return await self.send_command(module="C0", command="RO", vo=verification_subject) + return await self.send_command( + module="C0", + command="RO", + vo = verification_subject + ) async def request_additional_timestamp_data(self): - """Request additional timestamp data""" + """ Request additional timestamp data """ # TODO: parse res return await self.send_command(module="C0", command="RS") async def request_pip_channel_validation_status(self): - """Request PIP channel validation status""" + """ Request PIP channel validation status """ # TODO: parse res return await self.send_command(module="C0", command="RJ") async def request_xl_channel_validation_status(self): - """Request XL channel validation status""" + """ Request XL channel validation status """ # TODO: parse res return await self.send_command(module="C0", command="UJ") async def request_machine_configuration(self): - """Request machine configuration""" + """ Request machine configuration """ # TODO: parse res return await self.send_command(module="C0", command="RM", fmt="kb**kp**") async def request_extended_configuration(self): - """Request extended configuration""" + """ Request extended configuration """ - return await self.send_command( - module="C0", - command="QM", - fmt="ka******ke********xt##xa##xw#####xl**xn**xr**xo**xm#####xx#####xu####xv####kc#kr#ys###" - + "kl###km###ym####yu####yx####", - ) + return await self.send_command(module="C0", command="QM", + fmt="ka******ke********xt##xa##xw#####xl**xn**xr**xo**xm#####xx#####xu####xv####kc#kr#ys###"+\ + "kl###km###ym####yu####yx####") async def request_node_names(self): - """Request node names""" + """ Request node names """ # TODO: parse res return await self.send_command(module="C0", command="RK") async def request_deck_data(self): - """Request deck data""" + """ Request deck data """ # TODO: parse res return await self.send_command(module="C0", command="VD") @@ -3764,8 +3367,11 @@ async def request_deck_data(self): # -------------- 3.4.1 Movements -------------- - async def position_left_x_arm_(self, x_position: int = 0): - """Position left X-Arm + async def position_left_x_arm_( + self, + x_position: int = 0 + ): + """ Position left X-Arm Collision risk! @@ -3781,8 +3387,11 @@ async def position_left_x_arm_(self, x_position: int = 0): xs=f"{x_position:05}", ) - async def position_right_x_arm_(self, x_position: int = 0): - """Position right X-Arm + async def position_right_x_arm_( + self, + x_position: int = 0 + ): + """ Position right X-Arm Collision risk! @@ -3799,9 +3408,10 @@ async def position_right_x_arm_(self, x_position: int = 0): ) async def move_left_x_arm_to_position_with_all_attached_components_in_z_safety_position( - self, x_position: int = 0 + self, + x_position: int = 0 ): - """Move left X-arm to position with all attached components in Z-safety position + """ Move left X-arm to position with all attached components in Z-safety position Args: x_position: X-Position [0.1mm]. Must be between 0 and 30000. Default 0. @@ -3816,9 +3426,10 @@ async def move_left_x_arm_to_position_with_all_attached_components_in_z_safety_p ) async def move_right_x_arm_to_position_with_all_attached_components_in_z_safety_position( - self, x_position: int = 0 + self, + x_position: int = 0 ): - """Move right X-arm to position with all attached components in Z-safety position + """ Move right X-arm to position with all attached components in Z-safety position Args: x_position: X-Position [0.1mm]. Must be between 0 and 30000. Default 0. @@ -3840,9 +3451,9 @@ async def occupy_and_provide_area_for_external_access( taken_area_left_margin: int = 0, taken_area_left_margin_direction: int = 0, taken_area_size: int = 0, - arm_preposition_mode_related_to_taken_areas: int = 0, + arm_preposition_mode_related_to_taken_areas: int = 0 ): - """Occupy and provide area for external access + """ Occupy and provide area for external access Args: taken_area_identification_number: taken area identification number. Must be between 0 and @@ -3855,17 +3466,14 @@ async def occupy_and_provide_area_for_external_access( 1) all arms left. 2) all arms right. """ - assert ( - 0 <= taken_area_identification_number <= 9999 - ), "taken_area_identification_number must be between 0 and 9999" + assert 0 <= taken_area_identification_number <= 9999, \ + "taken_area_identification_number must be between 0 and 9999" assert 0 <= taken_area_left_margin <= 99, "taken_area_left_margin must be between 0 and 99" - assert ( - 0 <= taken_area_left_margin_direction <= 1 - ), "taken_area_left_margin_direction must be between 0 and 1" + assert 0 <= taken_area_left_margin_direction <= 1, \ + "taken_area_left_margin_direction must be between 0 and 1" assert 0 <= taken_area_size <= 50000, "taken_area_size must be between 0 and 50000" - assert ( - 0 <= arm_preposition_mode_related_to_taken_areas <= 2 - ), "arm_preposition_mode_related_to_taken_areas must be between 0 and 2" + assert 0 <= arm_preposition_mode_related_to_taken_areas <= 2, \ + "arm_preposition_mode_related_to_taken_areas must be between 0 and 2" return await self.send_command( module="C0", @@ -3877,17 +3485,19 @@ async def occupy_and_provide_area_for_external_access( ap=arm_preposition_mode_related_to_taken_areas, ) - async def release_occupied_area(self, taken_area_identification_number: int = 0): - """Release occupied area + async def release_occupied_area( + self, + taken_area_identification_number: int = 0 + ): + """ Release occupied area Args: taken_area_identification_number: taken area identification number. Must be between 0 and 9999. Default 0. """ - assert ( - 0 <= taken_area_identification_number <= 999 - ), "taken_area_identification_number must be between 0 and 9999" + assert 0 <= taken_area_identification_number <= 999, \ + "taken_area_identification_number must be between 0 and 9999" return await self.send_command( module="C0", @@ -3896,34 +3506,34 @@ async def release_occupied_area(self, taken_area_identification_number: int = 0) ) async def release_all_occupied_areas(self): - """Release all occupied areas""" + """ Release all occupied areas """ return await self.send_command(module="C0", command="BC") # -------------- 3.4.3 X-query -------------- async def request_left_x_arm_position(self): - """Request left X-Arm position""" + """ Request left X-Arm position """ return await self.send_command(module="C0", command="RX", fmt="rx#####") async def request_right_x_arm_position(self): - """Request right X-Arm position""" + """ Request right X-Arm position """ return await self.send_command(module="C0", command="QX", fmt="rx#####") async def request_maximal_ranges_of_x_drives(self): - """Request maximal ranges of X drives""" + """ Request maximal ranges of X drives """ return await self.send_command(module="C0", command="RU") async def request_present_wrap_size_of_installed_arms(self): - """Request present wrap size of installed arms""" + """ Request present wrap size of installed arms """ return await self.send_command(module="C0", command="UA") async def request_left_x_arm_last_collision_type(self): - """Request left X-Arm last collision type (after error 27) + """ Request left X-Arm last collision type (after error 27) Returns: False if present positions collide (not reachable), @@ -3934,7 +3544,7 @@ async def request_left_x_arm_last_collision_type(self): return resp["xq"] == 1 async def request_right_x_arm_last_collision_type(self) -> bool: - """Request right X-Arm last collision type (after error 27) + """ Request right X-Arm last collision type (after error 27) Returns: False if present positions collide (not reachable), @@ -3957,9 +3567,9 @@ async def initialize_pipetting_channels( z_position_at_end_of_a_command: int = 3600, tip_pattern: List[bool] = [True], tip_type: int = 16, - discarding_method: int = 1, + discarding_method: int = 1 ): - """Initialize pipetting channels + """ Initialize pipetting channels Initialize pipetting channels (discard tips) @@ -3981,15 +3591,12 @@ async def initialize_pipetting_channels( assert all(0 <= xp <= 25000 for xp in x_positions), "x_positions must be between 0 and 25000" assert all(0 <= yp <= 6500 for yp in y_positions), "y_positions must be between 0 and 6500" - assert ( - 0 <= begin_of_tip_deposit_process <= 3600 - ), "begin_of_tip_deposit_process must be between 0 and 3600" - assert ( - 0 <= end_of_tip_deposit_process <= 3600 - ), "end_of_tip_deposit_process must be between 0 and 3600" - assert ( - 0 <= z_position_at_end_of_a_command <= 3600 - ), "z_position_at_end_of_a_command must be between 0 and 3600" + assert 0 <= begin_of_tip_deposit_process <= 3600, \ + "begin_of_tip_deposit_process must be between 0 and 3600" + assert 0 <= end_of_tip_deposit_process <= 3600, \ + "end_of_tip_deposit_process must be between 0 and 3600" + assert 0 <= z_position_at_end_of_a_command <= 3600, \ + "z_position_at_end_of_a_command must be between 0 and 3600" assert 0 <= tip_type <= 99, "tip must be between 0 and 99" assert 0 <= discarding_method <= 1, "discarding_method must be between 0 and 1" @@ -4019,9 +3626,9 @@ async def pick_up_tip( begin_tip_pick_up_process: int = 0, end_tip_pick_up_process: int = 0, minimum_traverse_height_at_beginning_of_a_command: int = 3600, - pickup_method: TipPickupMethod = TipPickupMethod.OUT_OF_RACK, + pickup_method: TipPickupMethod = TipPickupMethod.OUT_OF_RACK ): - """Tip Pick-up + """ Tip Pick-up Args: x_positions: x positions [0.1mm]. Must be between 0 and 25000. Default 0. @@ -4040,21 +3647,18 @@ async def pick_up_tip( assert all(0 <= xp <= 25000 for xp in x_positions), "x_positions must be between 0 and 25000" assert all(0 <= yp <= 6500 for yp in y_positions), "y_positions must be between 0 and 6500" - assert ( - 0 <= begin_tip_pick_up_process <= 3600 - ), "begin_tip_pick_up_process must be between 0 and 3600" - assert ( - 0 <= end_tip_pick_up_process <= 3600 - ), "end_tip_pick_up_process must be between 0 and 3600" - assert ( - 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 - ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert 0 <= begin_tip_pick_up_process <= 3600, \ + "begin_tip_pick_up_process must be between 0 and 3600" + assert 0 <= end_tip_pick_up_process <= 3600, \ + "end_tip_pick_up_process must be between 0 and 3600" + assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ + "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" return await self.send_command( module="C0", command="TP", tip_pattern=tip_pattern, - read_timeout=max(120, self.read_timeout), + read_timeout=60, xp=[f"{x:05}" for x in x_positions], yp=[f"{y:04}" for y in y_positions], tm=tip_pattern, @@ -4075,9 +3679,9 @@ async def discard_tip( end_tip_deposit_process: int = 0, minimum_traverse_height_at_beginning_of_a_command: int = 3600, z_position_at_end_of_a_command: int = 3600, - discarding_method: TipDropMethod = TipDropMethod.DROP, + discarding_method: TipDropMethod = TipDropMethod.DROP ): - """discard tip + """ discard tip Args: x_positions: x positions [0.1mm]. Must be between 0 and 25000. Default 0. @@ -4102,24 +3706,19 @@ async def discard_tip( assert all(0 <= xp <= 25000 for xp in x_positions), "x_positions must be between 0 and 25000" assert all(0 <= yp <= 6500 for yp in y_positions), "y_positions must be between 0 and 6500" - assert ( - 0 <= begin_tip_deposit_process <= 3600 - ), "begin_tip_deposit_process must be between 0 and 3600" - assert ( - 0 <= end_tip_deposit_process <= 3600 - ), "end_tip_deposit_process must be between 0 and 3600" - assert ( - 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 - ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" - assert ( - 0 <= z_position_at_end_of_a_command <= 3600 - ), "z_position_at_end_of_a_command must be between 0 and 3600" + assert 0 <= begin_tip_deposit_process <= 3600, \ + "begin_tip_deposit_process must be between 0 and 3600" + assert 0 <= end_tip_deposit_process <= 3600, \ + "end_tip_deposit_process must be between 0 and 3600" + assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ + "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert 0 <= z_position_at_end_of_a_command <= 3600, \ + "z_position_at_end_of_a_command must be between 0 and 3600" return await self.send_command( module="C0", command="TR", tip_pattern=tip_pattern, - read_timeout=max(120, self.read_timeout), fmt="kz### (n)vz### (n)", xp=[f"{x:05}" for x in x_positions], yp=[f"{y:04}" for y in y_positions], @@ -4168,14 +3767,15 @@ async def aspirate_pip( detection_height_difference_for_dual_lld: List[int] = [0], swap_speed: List[int] = [100], settling_time: List[int] = [5], - mix_volume: List[int] = [0], - mix_cycles: List[int] = [0], - mix_position_from_liquid_surface: List[int] = [250], - mix_speed: List[int] = [500], - mix_surface_following_distance: List[int] = [0], + homogenization_volume: List[int] = [0], + homogenization_cycles: List[int] = [0], + homogenization_position_from_liquid_surface: List[int] = [250], + homogenization_speed: List[int] = [500], + homogenization_surface_following_distance: List[int] = [0], limit_curve_index: List[int] = [0], tadm_algorithm: bool = False, recording_mode: int = 0, + # For second section aspiration only use_2nd_section_aspiration: List[bool] = [False], retract_height_over_2nd_section_to_empty_tip: List[int] = [60], @@ -4184,9 +3784,9 @@ async def aspirate_pip( z_drive_speed_during_2nd_section_search: List[int] = [215], cup_upper_edge: List[int] = [3600], ratio_liquid_rise_to_tip_deep_in: List[int] = [16246], - immersion_depth_2nd_section: List[int] = [30], + immersion_depth_2nd_section: List[int] = [30] ): - """aspirate pip + """ aspirate pip Aspiration of liquid using PIP. @@ -4245,14 +3845,14 @@ async def aspirate_pip( swap_speed: Swap speed (on leaving liquid) [0.1mm/s]. Must be between 3 and 1600. Default 100. settling_time: Settling time [0.1s]. Must be between 0 and 99. Default 5. - mix_volume: mix volume [0.1ul]. Must be between 0 and 12500. Default 0 - mix_cycles: Number of mix cycles. Must be between 0 and 99. Default 0. - mix_position_from_liquid_surface: mix position in Z- direction from + homogenization_volume: Homogenization volume [0.1ul]. Must be between 0 and 12500. Default 0 + homogenization_cycles: Number of homogenization cycles. Must be between 0 and 99. Default 0. + homogenization_position_from_liquid_surface: Homogenization position in Z- direction from liquid surface (LLD or absolute terms) [0.1mm]. Must be between 0 and 900. Default 250. - mix_speed: Speed of mix [0.1ul/s]. Must be between 4 and 5000. + homogenization_speed: Speed of homogenization [0.1ul/s]. Must be between 4 and 5000. Default 500. - mix_surface_following_distance: Surface following distance during - mix [0.1mm]. Must be between 0 and 3600. Default 0. + homogenization_surface_following_distance: Surface following distance during + homogenization [0.1mm]. Must be between 0 and 3600. Default 0. limit_curve_index: limit curve index. Must be between 0 and 999. Default 0. tadm_algorithm: TADM algorithm. Default False. recording_mode: Recording mode 0 : no 1 : TADM errors only 2 : all TADM measurement. Must @@ -4276,106 +3876,81 @@ async def aspirate_pip( assert all(0 <= x <= 2 for x in aspiration_type), "aspiration_type must be between 0 and 2" assert all(0 <= xp <= 25000 for xp in x_positions), "x_positions must be between 0 and 25000" assert all(0 <= yp <= 6500 for yp in y_positions), "y_positions must be between 0 and 6500" - assert ( - 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 - ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ + "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" assert 0 <= min_z_endpos <= 3600, "min_z_endpos must be between 0 and 3600" - assert all( - 0 <= x <= 3600 for x in lld_search_height - ), "lld_search_height must be between 0 and 3600" - assert all( - 0 <= x <= 500 for x in clot_detection_height - ), "clot_detection_height must be between 0 and 500" - assert all( - 0 <= x <= 3600 for x in liquid_surface_no_lld - ), "liquid_surface_no_lld must be between 0 and 3600" - assert all( - 0 <= x <= 3600 for x in pull_out_distance_transport_air - ), "pull_out_distance_transport_air must be between 0 and 3600" - assert all( - 0 <= x <= 3600 for x in second_section_height - ), "second_section_height must be between 0 and 3600" - assert all( - 0 <= x <= 10000 for x in second_section_ratio - ), "second_section_ratio must be between 0 and 10000" + assert all(0 <= x <= 3600 for x in lld_search_height), \ + "lld_search_height must be between 0 and 3600" + assert all(0 <= x <= 500 for x in clot_detection_height), \ + "clot_detection_height must be between 0 and 500" + assert all(0 <= x <= 3600 for x in liquid_surface_no_lld), \ + "liquid_surface_no_lld must be between 0 and 3600" + assert all(0 <= x <= 3600 for x in pull_out_distance_transport_air), \ + "pull_out_distance_transport_air must be between 0 and 3600" + assert all(0 <= x <= 3600 for x in second_section_height), \ + "second_section_height must be between 0 and 3600" + assert all(0 <= x <= 10000 for x in second_section_ratio), \ + "second_section_ratio must be between 0 and 10000" assert all(0 <= x <= 3600 for x in minimum_height), "minimum_height must be between 0 and 3600" - assert all( - 0 <= x <= 3600 for x in immersion_depth - ), "immersion_depth must be between 0 and 3600" - assert all( - 0 <= x <= 1 for x in immersion_depth_direction - ), "immersion_depth_direction must be between 0 and 1" - assert all( - 0 <= x <= 3600 for x in surface_following_distance - ), "surface_following_distance must be between 0 and 3600" - assert all( - 0 <= x <= 12500 for x in aspiration_volumes - ), "aspiration_volumes must be between 0 and 12500" - assert all( - 4 <= x <= 5000 for x in aspiration_speed - ), "aspiration_speed must be between 4 and 5000" - assert all( - 0 <= x <= 500 for x in transport_air_volume - ), "transport_air_volume must be between 0 and 500" - assert all( - 0 <= x <= 9999 for x in blow_out_air_volume - ), "blow_out_air_volume must be between 0 and 9999" - assert all( - 0 <= x <= 999 for x in pre_wetting_volume - ), "pre_wetting_volume must be between 0 and 999" + assert all(0 <= x <= 3600 for x in immersion_depth), \ + "immersion_depth must be between 0 and 3600" + assert all(0 <= x <= 1 for x in immersion_depth_direction), \ + "immersion_depth_direction must be between 0 and 1" + assert all(0 <= x <= 3600 for x in surface_following_distance), \ + "surface_following_distance must be between 0 and 3600" + assert all(0 <= x <= 12500 for x in aspiration_volumes), \ + "aspiration_volumes must be between 0 and 12500" + assert all(4 <= x <= 5000 for x in aspiration_speed), \ + "aspiration_speed must be between 4 and 5000" + assert all(0 <= x <= 500 for x in transport_air_volume), \ + "transport_air_volume must be between 0 and 500" + assert all(0 <= x <= 9999 for x in blow_out_air_volume), \ + "blow_out_air_volume must be between 0 and 9999" + assert all(0 <= x <= 999 for x in pre_wetting_volume), \ + "pre_wetting_volume must be between 0 and 999" assert all(0 <= x <= 4 for x in lld_mode), "lld_mode must be between 0 and 4" - assert all( - 1 <= x <= 4 for x in gamma_lld_sensitivity - ), "gamma_lld_sensitivity must be between 1 and 4" - assert all( - 1 <= x <= 4 for x in dp_lld_sensitivity - ), "dp_lld_sensitivity must be between 1 and 4" - assert all( - 0 <= x <= 100 for x in aspirate_position_above_z_touch_off - ), "aspirate_position_above_z_touch_off must be between 0 and 100" - assert all( - 0 <= x <= 99 for x in detection_height_difference_for_dual_lld - ), "detection_height_difference_for_dual_lld must be between 0 and 99" + assert all(1 <= x <= 4 for x in gamma_lld_sensitivity), \ + "gamma_lld_sensitivity must be between 1 and 4" + assert all(1 <= x <= 4 for x in dp_lld_sensitivity), \ + "dp_lld_sensitivity must be between 1 and 4" + assert all(0 <= x <= 100 for x in aspirate_position_above_z_touch_off), \ + "aspirate_position_above_z_touch_off must be between 0 and 100" + assert all(0 <= x <= 99 for x in detection_height_difference_for_dual_lld), \ + "detection_height_difference_for_dual_lld must be between 0 and 99" assert all(3 <= x <= 1600 for x in swap_speed), "swap_speed must be between 3 and 1600" assert all(0 <= x <= 99 for x in settling_time), "settling_time must be between 0 and 99" - assert all(0 <= x <= 12500 for x in mix_volume), "mix_volume must be between 0 and 12500" - assert all(0 <= x <= 99 for x in mix_cycles), "mix_cycles must be between 0 and 99" - assert all( - 0 <= x <= 900 for x in mix_position_from_liquid_surface - ), "mix_position_from_liquid_surface must be between 0 and 900" - assert all(4 <= x <= 5000 for x in mix_speed), "mix_speed must be between 4 and 5000" - assert all( - 0 <= x <= 3600 for x in mix_surface_following_distance - ), "mix_surface_following_distance must be between 0 and 3600" - assert all( - 0 <= x <= 999 for x in limit_curve_index - ), "limit_curve_index must be between 0 and 999" + assert all(0 <= x <= 12500 for x in homogenization_volume), \ + "homogenization_volume must be between 0 and 12500" + assert all(0 <= x <= 99 for x in homogenization_cycles), \ + "homogenization_cycles must be between 0 and 99" + assert all(0 <= x <= 900 for x in homogenization_position_from_liquid_surface), \ + "homogenization_position_from_liquid_surface must be between 0 and 900" + assert all(4 <= x <= 5000 for x in homogenization_speed), \ + "homogenization_speed must be between 4 and 5000" + assert all(0 <= x <= 3600 for x in homogenization_surface_following_distance), \ + "homogenization_surface_following_distance must be between 0 and 3600" + assert all(0 <= x <= 999 for x in limit_curve_index), \ + "limit_curve_index must be between 0 and 999" assert 0 <= recording_mode <= 2, "recording_mode must be between 0 and 2" - assert all( - 0 <= x <= 3600 for x in retract_height_over_2nd_section_to_empty_tip - ), "retract_height_over_2nd_section_to_empty_tip must be between 0 and 3600" - assert all( - 4 <= x <= 5000 for x in dispensation_speed_during_emptying_tip - ), "dispensation_speed_during_emptying_tip must be between 4 and 5000" - assert all( - 4 <= x <= 5000 for x in dosing_drive_speed_during_2nd_section_search - ), "dosing_drive_speed_during_2nd_section_search must be between 4 and 5000" - assert all( - 3 <= x <= 1600 for x in z_drive_speed_during_2nd_section_search - ), "z_drive_speed_during_2nd_section_search must be between 3 and 1600" + assert all(0 <= x <= 3600 for x in retract_height_over_2nd_section_to_empty_tip), \ + "retract_height_over_2nd_section_to_empty_tip must be between 0 and 3600" + assert all(4 <= x <= 5000 for x in dispensation_speed_during_emptying_tip), \ + "dispensation_speed_during_emptying_tip must be between 4 and 5000" + assert all(4 <= x <= 5000 for x in dosing_drive_speed_during_2nd_section_search), \ + "dosing_drive_speed_during_2nd_section_search must be between 4 and 5000" + assert all(3 <= x <= 1600 for x in z_drive_speed_during_2nd_section_search), \ + "z_drive_speed_during_2nd_section_search must be between 3 and 1600" assert all(0 <= x <= 3600 for x in cup_upper_edge), "cup_upper_edge must be between 0 and 3600" - assert all( - 0 <= x <= 5000 for x in ratio_liquid_rise_to_tip_deep_in - ), "ratio_liquid_rise_to_tip_deep_in must be between 0 and 50000" - assert all( - 0 <= x <= 3600 for x in immersion_depth_2nd_section - ), "immersion_depth_2nd_section must be between 0 and 3600" + assert all(0 <= x <= 5000 for x in ratio_liquid_rise_to_tip_deep_in), \ + "ratio_liquid_rise_to_tip_deep_in must be between 0 and 50000" + assert all(0 <= x <= 3600 for x in immersion_depth_2nd_section), \ + "immersion_depth_2nd_section must be between 0 and 3600" return await self.send_command( module="C0", command="AS", tip_pattern=tip_pattern, - read_timeout=max(120, self.read_timeout), + read_timeout=max(60, self.read_timeout), at=[f"{at:01}" for at in aspiration_type], tm=tip_pattern, xp=[f"{xp:05}" for xp in x_positions], @@ -4390,28 +3965,29 @@ async def aspirate_pip( zr=[f"{zr:05}" for zr in second_section_ratio], zx=[f"{zx:04}" for zx in minimum_height], ip=[f"{ip:04}" for ip in immersion_depth], - it=[f"{it}" for it in immersion_depth_direction], + it=[f"{it}" for it in immersion_depth_direction], fp=[f"{fp:04}" for fp in surface_following_distance], av=[f"{av:05}" for av in aspiration_volumes], as_=[f"{as_:04}" for as_ in aspiration_speed], ta=[f"{ta:03}" for ta in transport_air_volume], ba=[f"{ba:04}" for ba in blow_out_air_volume], oa=[f"{oa:03}" for oa in pre_wetting_volume], - lm=[f"{lm}" for lm in lld_mode], - ll=[f"{ll}" for ll in gamma_lld_sensitivity], - lv=[f"{lv}" for lv in dp_lld_sensitivity], + lm=[f"{lm}" for lm in lld_mode], + ll=[f"{ll}" for ll in gamma_lld_sensitivity], + lv=[f"{lv}" for lv in dp_lld_sensitivity], zo=[f"{zo:03}" for zo in aspirate_position_above_z_touch_off], ld=[f"{ld:02}" for ld in detection_height_difference_for_dual_lld], de=[f"{de:04}" for de in swap_speed], wt=[f"{wt:02}" for wt in settling_time], - mv=[f"{mv:05}" for mv in mix_volume], - mc=[f"{mc:02}" for mc in mix_cycles], - mp=[f"{mp:03}" for mp in mix_position_from_liquid_surface], - ms=[f"{ms:04}" for ms in mix_speed], - mh=[f"{mh:04}" for mh in mix_surface_following_distance], + mv=[f"{mv:05}" for mv in homogenization_volume], + mc=[f"{mc:02}" for mc in homogenization_cycles], + mp=[f"{mp:03}" for mp in homogenization_position_from_liquid_surface], + ms=[f"{ms:04}" for ms in homogenization_speed], + mh=[f"{mh:04}" for mh in homogenization_surface_following_distance], gi=[f"{gi:03}" for gi in limit_curve_index], gj=tadm_algorithm, gk=recording_mode, + lk=[1 if lk else 0 for lk in use_2nd_section_aspiration], ik=[f"{ik:04}" for ik in retract_height_over_2nd_section_to_empty_tip], sd=[f"{sd:04}" for sd in dispensation_speed_during_emptying_tip], @@ -4439,7 +4015,7 @@ async def dispense_pip( second_section_height: List[int] = [0], second_section_ratio: List[int] = [0], minimum_traverse_height_at_beginning_of_a_command: int = 3600, - min_z_endpos: int = 3600, # + min_z_endpos: int = 3600, # dispense_volumes: List[int] = [0], dispense_speed: List[int] = [500], cut_off_speed: List[int] = [250], @@ -4460,9 +4036,9 @@ async def dispense_pip( mix_surface_following_distance: List[int] = [0], limit_curve_index: List[int] = [0], tadm_algorithm: bool = False, - recording_mode: int = 0, + recording_mode: int = 0 ): - """dispense pip + """ dispense pip Dispensing of liquid using PIP. @@ -4535,81 +4111,63 @@ async def dispense_pip( assert all(0 <= x <= 4 for x in dispensing_mode), "dispensing_mode must be between 0 and 4" assert all(0 <= xp <= 25000 for xp in x_positions), "x_positions must be between 0 and 25000" assert all(0 <= yp <= 6500 for yp in y_positions), "y_positions must be between 0 and 6500" - assert any(0 <= x <= 3600 for x in minimum_height), "minimum_height must be between 0 and 3600" - assert any( - 0 <= x <= 3600 for x in lld_search_height - ), "lld_search_height must be between 0 and 3600" - assert any( - 0 <= x <= 3600 for x in liquid_surface_no_lld - ), "liquid_surface_no_lld must be between 0 and 3600" - assert any( - 0 <= x <= 3600 for x in pull_out_distance_transport_air - ), "pull_out_distance_transport_air must be between 0 and 3600" - assert any( - 0 <= x <= 3600 for x in immersion_depth - ), "immersion_depth must be between 0 and 3600" - assert any( - 0 <= x <= 1 for x in immersion_depth_direction - ), "immersion_depth_direction must be between 0 and 1" - assert any( - 0 <= x <= 3600 for x in surface_following_distance - ), "surface_following_distance must be between 0 and 3600" - assert any( - 0 <= x <= 3600 for x in second_section_height - ), "second_section_height must be between 0 and 3600" - assert any( - 0 <= x <= 10000 for x in second_section_ratio - ), "second_section_ratio must be between 0 and 10000" - assert ( - 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 - ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert any(0 <= x <= 3600 for x in minimum_height), \ + "minimum_height must be between 0 and 3600" + assert any(0 <= x <= 3600 for x in lld_search_height), \ + "lld_search_height must be between 0 and 3600" + assert any(0 <= x <= 3600 for x in liquid_surface_no_lld), \ + "liquid_surface_no_lld must be between 0 and 3600" + assert any(0 <= x <= 3600 for x in pull_out_distance_transport_air), \ + "pull_out_distance_transport_air must be between 0 and 3600" + assert any(0 <= x <= 3600 for x in immersion_depth), \ + "immersion_depth must be between 0 and 3600" + assert any(0 <= x <= 1 for x in immersion_depth_direction), \ + "immersion_depth_direction must be between 0 and 1" + assert any(0 <= x <= 3600 for x in surface_following_distance), \ + "surface_following_distance must be between 0 and 3600" + assert any(0 <= x <= 3600 for x in second_section_height), \ + "second_section_height must be between 0 and 3600" + assert any(0 <= x <= 10000 for x in second_section_ratio), \ + "second_section_ratio must be between 0 and 10000" + assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ + "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" assert 0 <= min_z_endpos <= 3600, "min_z_endpos must be between 0 and 3600" - assert any( - 0 <= x <= 12500 for x in dispense_volumes - ), "dispense_volume must be between 0 and 12500" + assert any(0 <= x <= 12500 for x in dispense_volumes), \ + "dispense_volume must be between 0 and 12500" assert any(4 <= x <= 5000 for x in dispense_speed), "dispense_speed must be between 4 and 5000" assert any(4 <= x <= 5000 for x in cut_off_speed), "cut_off_speed must be between 4 and 5000" - assert any( - 0 <= x <= 180 for x in stop_back_volume - ), "stop_back_volume must be between 0 and 180" - assert any( - 0 <= x <= 500 for x in transport_air_volume - ), "transport_air_volume must be between 0 and 500" - assert any( - 0 <= x <= 9999 for x in blow_out_air_volume - ), "blow_out_air_volume must be between 0 and 9999" + assert any(0 <= x <= 180 for x in stop_back_volume), \ + "stop_back_volume must be between 0 and 180" + assert any(0 <= x <= 500 for x in transport_air_volume), \ + "transport_air_volume must be between 0 and 500" + assert any(0 <= x <= 9999 for x in blow_out_air_volume), \ + "blow_out_air_volume must be between 0 and 9999" assert any(0 <= x <= 4 for x in lld_mode), "lld_mode must be between 0 and 4" assert 0 <= side_touch_off_distance <= 45, "side_touch_off_distance must be between 0 and 45" - assert any( - 0 <= x <= 100 for x in dispense_position_above_z_touch_off - ), "dispense_position_above_z_touch_off must be between 0 and 100" - assert any( - 1 <= x <= 4 for x in gamma_lld_sensitivity - ), "gamma_lld_sensitivity must be between 1 and 4" - assert any( - 1 <= x <= 4 for x in dp_lld_sensitivity - ), "dp_lld_sensitivity must be between 1 and 4" + assert any(0 <= x <= 100 for x in dispense_position_above_z_touch_off), \ + "dispense_position_above_z_touch_off must be between 0 and 100" + assert any(1 <= x <= 4 for x in gamma_lld_sensitivity), \ + "gamma_lld_sensitivity must be between 1 and 4" + assert any(1 <= x <= 4 for x in dp_lld_sensitivity), \ + "dp_lld_sensitivity must be between 1 and 4" assert any(3 <= x <= 1600 for x in swap_speed), "swap_speed must be between 3 and 1600" assert any(0 <= x <= 99 for x in settling_time), "settling_time must be between 0 and 99" assert any(0 <= x <= 12500 for x in mix_volume), "mix_volume must be between 0 and 12500" assert any(0 <= x <= 99 for x in mix_cycles), "mix_cycles must be between 0 and 99" - assert any( - 0 <= x <= 900 for x in mix_position_from_liquid_surface - ), "mix_position_from_liquid_surface must be between 0 and 900" + assert any(0 <= x <= 900 for x in mix_position_from_liquid_surface), \ + "mix_position_from_liquid_surface must be between 0 and 900" assert any(4 <= x <= 5000 for x in mix_speed), "mix_speed must be between 4 and 5000" - assert any( - 0 <= x <= 3600 for x in mix_surface_following_distance - ), "mix_surface_following_distance must be between 0 and 3600" - assert any( - 0 <= x <= 999 for x in limit_curve_index - ), "limit_curve_index must be between 0 and 999" + assert any(0 <= x <= 3600 for x in mix_surface_following_distance), \ + "mix_surface_following_distance must be between 0 and 3600" + assert any(0 <= x <= 999 for x in limit_curve_index), \ + "limit_curve_index must be between 0 and 999" assert 0 <= recording_mode <= 2, "recording_mode must be between 0 and 2" return await self.send_command( module="C0", command="DS", tip_pattern=tip_pattern, - read_timeout=max(120, self.read_timeout), + read_timeout=max(60, self.read_timeout), dm=[f"{dm:01}" for dm in dispensing_mode], tm=[f"{tm:01}" for tm in tip_pattern], xp=[f"{xp:05}" for xp in x_positions], @@ -4632,7 +4190,7 @@ async def dispense_pip( ta=[f"{ta:03}" for ta in transport_air_volume], ba=[f"{ba:04}" for ba in blow_out_air_volume], lm=[f"{lm:01}" for lm in lld_mode], - dj=f"{side_touch_off_distance:02}", # + dj=f"{side_touch_off_distance:02}", # zo=[f"{zo:03}" for zo in dispense_position_above_z_touch_off], ll=[f"{ll:01}" for ll in gamma_lld_sensitivity], lv=[f"{lv:01}" for lv in dp_lld_sensitivity], @@ -4644,8 +4202,8 @@ async def dispense_pip( ms=[f"{ms:04}" for ms in mix_speed], mh=[f"{mh:04}" for mh in mix_surface_following_distance], gi=[f"{gi:03}" for gi in limit_curve_index], - gj=tadm_algorithm, # - gk=recording_mode, # + gj=tadm_algorithm, # + gk=recording_mode, # ) # TODO:(command:DA) Simultaneous aspiration & dispensation of liquid @@ -4658,7 +4216,7 @@ async def dispense_pip( @need_iswap_parked async def get_core(self, p1: int, p2: int): - """Get CoRe gripper tool from wasteblock mount.""" + """ Get CoRe gripper tool from wasteblock mount. """ if not 0 <= p1 < self.num_channels: raise ValueError(f"channel_1 must be between 0 and {self.num_channels - 1}") if not 1 <= p2 <= self.num_channels: @@ -4669,9 +4227,9 @@ async def get_core(self, p1: int, p2: int): # a resource on the robot deck and use deck.get_resource().get_absolute_location(). deck_size = self.deck.get_absolute_size_x() if deck_size == STARLET_SIZE_X: - xs = 7975 # 1360-797.5 = 562.5 + xs = 7975 # 1360-797.5 = 562.5 elif deck_size == STAR_SIZE_X: - xs = 13385 # 1900-1337.5 = 562.5, plus a manual adjustment of + 10 + xs = 13385 # 1900-1337.5 = 562.5, plus a manual adjustment of + 10 else: raise ValueError(f"Deck size {deck_size} not supported") @@ -4686,15 +4244,15 @@ async def get_core(self, p1: int, p2: int): pb=f"{p2:02}", tp=f"{2350 + self.core_adjustment.z:04}", tz=f"{2250 + self.core_adjustment.z:04}", - th=round(self._iswap_traversal_height * 10), - tt="14", + th=round(self._traversal_height * 10), + tt="14" ) self._core_parked = False return command_output @need_iswap_parked async def put_core(self): - """Put CoRe gripper tool at wasteblock mount.""" + """ Put CoRe gripper tool at wasteblock mount. """ assert self.deck is not None, "must have deck defined to access CoRe grippers" deck_size = self.deck.get_absolute_size_x() if deck_size == STARLET_SIZE_X: @@ -4712,14 +4270,14 @@ async def put_core(self): yb=f"{1065 + self.core_adjustment.y:04}", tp=f"{2150 + self.core_adjustment.z:04}", tz=f"{2050 + self.core_adjustment.z:04}", - th=round(self._iswap_traversal_height * 10), - te=round(self._iswap_traversal_height * 10), + th=round(self._traversal_height * 10), + te=round(self._traversal_height * 10), ) self._core_parked = True return command_output async def core_open_gripper(self): - """Open CoRe gripper tool.""" + """ Open CoRe gripper tool. """ return await self.send_command(module="C0", command="ZO") @need_iswap_parked @@ -4737,7 +4295,7 @@ async def core_get_plate( minimum_traverse_height_at_beginning_of_a_command: int = 2750, minimum_z_position_at_the_command_end: int = 2750, ): - """Get plate with CoRe gripper tool from wasteblock mount.""" + """ Get plate with CoRe gripper tool from wasteblock mount. """ assert 0 <= x_position <= 30000, "x_position must be between 0 and 30000" assert 0 <= x_direction <= 1, "x_direction must be between 0 and 1" @@ -4748,12 +4306,10 @@ async def core_get_plate( assert 0 <= open_gripper_position <= 9999, "open_gripper_position must be between 0 and 9999" assert 0 <= plate_width <= 9999, "plate_width must be between 0 and 9999" assert 0 <= grip_strength <= 99, "grip_strength must be between 0 and 99" - assert ( - 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 - ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" - assert ( - 0 <= minimum_z_position_at_the_command_end <= 3600 - ), "minimum_z_position_at_the_command_end must be between 0 and 3600" + assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ + "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert 0 <= minimum_z_position_at_the_command_end <= 3600, \ + "minimum_z_position_at_the_command_end must be between 0 and 3600" command_output = await self.send_command( module="C0", @@ -4768,7 +4324,7 @@ async def core_get_plate( yg=f"{plate_width:04}", yw=f"{grip_strength:02}", th=f"{minimum_traverse_height_at_beginning_of_a_command:04}", - te=f"{minimum_z_position_at_the_command_end:04}", + te=f"{minimum_z_position_at_the_command_end:04}" ) return command_output @@ -4785,9 +4341,9 @@ async def core_put_plate( open_gripper_position: int = 0, minimum_traverse_height_at_beginning_of_a_command: int = 2750, z_position_at_the_command_end: int = 2750, - return_tool: bool = True, + return_tool: bool = True ): - """Put plate with CoRe gripper tool and return to wasteblock mount.""" + """ Put plate with CoRe gripper tool and return to wasteblock mount. """ assert 0 <= x_position <= 30000, "x_position must be between 0 and 30000" assert 0 <= x_direction <= 1, "x_direction must be between 0 and 1" @@ -4796,12 +4352,10 @@ async def core_put_plate( assert 0 <= z_press_on_distance <= 50, "z_press_on_distance must be between 0 and 999" assert 0 <= z_speed <= 1600, "z_speed must be between 0 and 1600" assert 0 <= open_gripper_position <= 9999, "open_gripper_position must be between 0 and 9999" - assert ( - 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 - ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" - assert ( - 0 <= z_position_at_the_command_end <= 3600 - ), "z_position_at_the_command_end must be between 0 and 3600" + assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ + "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert 0 <= z_position_at_the_command_end <= 3600, \ + "z_position_at_the_command_end must be between 0 and 3600" command_output = await self.send_command( module="C0", @@ -4814,7 +4368,7 @@ async def core_put_plate( zy=f"{z_speed:04}", yo=f"{open_gripper_position:04}", th=f"{minimum_traverse_height_at_beginning_of_a_command:04}", - te=f"{z_position_at_the_command_end:04}", + te=f"{z_position_at_the_command_end:04}" ) if return_tool: @@ -4833,7 +4387,7 @@ async def core_move_plate_to_position( z_speed: int = 500, minimum_traverse_height_at_beginning_of_a_command: int = 3600, ): - """Move a plate with CoRe gripper tool.""" + """ Move a plate with CoRe gripper tool. """ command_output = await self.send_command( module="C0", @@ -4844,7 +4398,7 @@ async def core_move_plate_to_position( yj=f"{y_position:04}", zj=f"{z_position:04}", zy=f"{z_speed:04}", - th=f"{minimum_traverse_height_at_beginning_of_a_command:04}", + th=f"{minimum_traverse_height_at_beginning_of_a_command:04}" ) return command_output @@ -4853,19 +4407,24 @@ async def core_move_plate_to_position( # -------------- 3.5.6 Adjustment & movement commands -------------- + # TODO:(command:JY) Position all pipetting channels in Y-direction + + # TODO:(command:JZ) Position all pipetting channels in Z-direction + async def position_single_pipetting_channel_in_y_direction( - self, pipetting_channel_index: int, y_position: int + self, + pipetting_channel_index: int, + y_position: int ): - """Position single pipetting channel in Y-direction. + """ Position single pipetting channel in Y-direction. Args: pipetting_channel_index: Index of pipetting channel. Must be between 1 and 16. y_position: y position [0.1mm]. Must be between 0 and 6500. """ - assert ( - 1 <= pipetting_channel_index <= self.num_channels - ), "pipetting_channel_index must be between 1 and self" + assert 1 <= pipetting_channel_index <= self.num_channels, \ + "pipetting_channel_index must be between 1 and self" assert 0 <= y_position <= 6500, "y_position must be between 0 and 6500" return await self.send_command( @@ -4876,9 +4435,11 @@ async def position_single_pipetting_channel_in_y_direction( ) async def position_single_pipetting_channel_in_z_direction( - self, pipetting_channel_index: int, z_position: int + self, + pipetting_channel_index: int, + z_position: int ): - """Position single pipetting channel in Z-direction. + """ Position single pipetting channel in Z-direction. Note that this refers to the point of the tip if a tip is mounted! @@ -4888,9 +4449,8 @@ async def position_single_pipetting_channel_in_z_direction( 3347 is the max. """ - assert ( - 1 <= pipetting_channel_index <= self.num_channels - ), "pipetting_channel_index must be between 1 and self.num_channels" + assert 1 <= pipetting_channel_index <= self.num_channels, \ + "pipetting_channel_index must be between 1 and self.num_channels" # docs say 3600, but empirically 3347 is the max assert 0 <= z_position <= 3347, "z_position must be between 0 and 3347" @@ -4902,18 +4462,19 @@ async def position_single_pipetting_channel_in_z_direction( ) async def search_for_teach_in_signal_using_pipetting_channel_n_in_x_direction( - self, pipetting_channel_index: int, x_position: int + self, + pipetting_channel_index: int, + x_position: int ): - """Search for Teach in signal using pipetting channel n in X-direction. + """ Search for Teach in signal using pipetting channel n in X-direction. Args: pipetting_channel_index: Index of pipetting channel. Must be between 1 and self.num_channels. x_position: x position [0.1mm]. Must be between 0 and 30000. """ - assert ( - 1 <= pipetting_channel_index <= self.num_channels - ), "pipetting_channel_index must be between 1 and self.num_channels" + assert 1 <= pipetting_channel_index <= self.num_channels, \ + "pipetting_channel_index must be between 1 and self.num_channels" assert 0 <= x_position <= 30000, "x_position must be between 0 and 30000" return await self.send_command( @@ -4924,20 +4485,19 @@ async def search_for_teach_in_signal_using_pipetting_channel_n_in_x_direction( ) async def spread_pip_channels(self): - """Spread PIP channels""" + """ Spread PIP channels """ return await self.send_command(module="C0", command="JE") - @need_iswap_parked async def move_all_pipetting_channels_to_defined_position( self, tip_pattern: bool = True, x_positions: int = 0, y_positions: int = 0, minimum_traverse_height_at_beginning_of_command: int = 3600, - z_endpos: int = 0, + z_endpos: int = 0 ): - """Move all pipetting channels to defined position + """ Move all pipetting channels to defined position Args: tip_pattern: Tip pattern (channels involved). Default True. @@ -4952,9 +4512,8 @@ async def move_all_pipetting_channels_to_defined_position( assert 0 <= x_positions <= 25000, "x_positions must be between 0 and 25000" assert 0 <= y_positions <= 6500, "y_positions must be between 0 and 6500" - assert ( - 0 <= minimum_traverse_height_at_beginning_of_command <= 3600 - ), "minimum_traverse_height_at_beginning_of_command must be between 0 and 3600" + assert 0 <= minimum_traverse_height_at_beginning_of_command <= 3600, \ + "minimum_traverse_height_at_beginning_of_command must be between 0 and 3600" assert 0 <= z_endpos <= 3600, "z_endpos must be between 0 and 3600" return await self.send_command( @@ -4969,19 +4528,18 @@ async def move_all_pipetting_channels_to_defined_position( # TODO:(command:JR): teach rack using pipetting channel n - @need_iswap_parked - async def position_max_free_y_for_n(self, pipetting_channel_index: int): - """Position all pipetting channels so that there is maximum free Y range for channel n + async def position_max_free_y_for_n( + self, + pipetting_channel_index: int = 1 + ): + """ Position all pipetting channels so that there is maximum free Y range for channel n Args: - pipetting_channel_index: Index of pipetting channel. Must be between 0 and self.num_channels. + pipetting_channel_index: Index of pipetting channel. Must be between 1 and 16. Default 1. """ - assert ( - 0 <= pipetting_channel_index < self.num_channels - ), "pipetting_channel_index must be between 1 and self.num_channels" - # convert Python's 0-based indexing to Hamilton firmware's 1-based indexing - pipetting_channel_index = pipetting_channel_index + 1 + assert 1 <= pipetting_channel_index <= self.num_channels, \ + "pipetting_channel_index must be between 1 and self.num_channels" return await self.send_command( module="C0", @@ -4990,7 +4548,7 @@ async def position_max_free_y_for_n(self, pipetting_channel_index: int): ) async def move_all_channels_in_z_safety(self): - """Move all pipetting channels in Z-safety position""" + """ Move all pipetting channels in Z-safety position """ return await self.send_command(module="C0", command="ZA") @@ -4998,57 +4556,51 @@ async def move_all_channels_in_z_safety(self): # TODO:(command:RY): Request Y-Positions of all pipetting channels - async def request_y_pos_channel_n(self, pipetting_channel_index: int) -> float: - """Request Y-Position of Pipetting channel n + async def request_y_pos_channel_n( + self, + pipetting_channel_index: int = 1 + ): + """ Request Y-Position of Pipetting channel n Args: - pipetting_channel_index: Index of pipetting channel. Must be between 0 and 15. - 0 is the backmost channel. + pipetting_channel_index: Index of pipetting channel. Must be between 1 and 16. Default 1. """ - assert ( - 0 <= pipetting_channel_index < self.num_channels - ), "pipetting_channel_index must be between 0 and self.num_channels" - # convert Python's 0-based indexing to Hamilton firmware's 1-based indexing - pipetting_channel_index = pipetting_channel_index + 1 + assert 1 <= pipetting_channel_index <= 16, "pipetting_channel_index must be between 1 and 16" - y_pos_query = await self.send_command( + return await self.send_command( module="C0", command="RB", fmt="rb####", pn=f"{pipetting_channel_index:02}", ) - # Extract y-coordinate and convert to mm - return float(y_pos_query["rb"] / 10) # TODO:(command:RZ): Request Z-Positions of all pipetting channels - async def request_z_pos_channel_n(self, pipetting_channel_index: int) -> float: - """Request Z-Position of Pipetting channel n + async def request_z_pos_channel_n( + self, + pipetting_channel_index: int = 1 + ): + """ Request Z-Position of Pipetting channel n Args: - pipetting_channel_index: Index of pipetting channel. Must be between 0 and 15. - 0 is the backmost channel. + pipetting_channel_index: Index of pipetting channel. Must be between 1 and 16. Default 1. Returns: Z-Position of channel n [0.1mm]. Taking into account tip presence and length. """ - assert 0 <= pipetting_channel_index <= 15, "pipetting_channel_index must be between 0 and 15" - # convert Python's 0-based indexing to Hamilton firmware's 1-based indexing - pipetting_channel_index = pipetting_channel_index + 1 + assert 1 <= pipetting_channel_index <= 16, "pipetting_channel_index must be between 1 and 16" - z_pos_query = await self.send_command( + return await self.send_command( module="C0", command="RD", fmt="rd####", pn=f"{pipetting_channel_index:02}", ) - # Extract z-coordinate and convert to mm - return float(z_pos_query["rd"] / 10) async def request_tip_presence(self) -> List[int]: - """Request query tip presence on each channel + """ Request query tip presence on each channel Returns: 0 = no tip, 1 = Tip in gripper (for each channel) @@ -5058,7 +4610,7 @@ async def request_tip_presence(self) -> List[int]: return cast(List[int], resp.get("rt")) async def request_pip_height_last_lld(self): - """Request PIP height of last LLD + """ Request PIP height of last LLD Returns: LLD height of all channels @@ -5067,7 +4619,7 @@ async def request_pip_height_last_lld(self): return await self.send_command(module="C0", command="RL", fmt="lh#### (n)") async def request_tadm_status(self): - """Request PIP height of last LLD + """ Request PIP height of last LLD Returns: TADM channel status 0 = off, 1 = on @@ -5206,39 +4758,55 @@ async def request_tadm_status(self): # -------------- 3.10.1 Initialization -------------- async def initialize_core_96_head( - self, trash96: Trash, z_position_at_the_command_end: float = 245.0 + self, + x_position: int = 2321, + x_direction: int = 1, + y_position: int = 1103, + z_deposit_position: int = 1890, + z_position_at_the_command_end: int = 2450 ): - """Initialize CoRe 96 Head + """ Initialize CoRe 96 Head + + Initialize CoRe 96 Head. Dependent to configuration initialization change. Args: - trash96: Trash object where tips should be disposed. The 96 head will be positioned in the - center of the trash. - z_position_at_the_command_end: Z position at the end of the command [mm]. + x_position: X-Position [0.1mm] (discard position of tip A1). Must be between 0 and 30000. + Default 0. + x_direction: X-direction. 0 = positive 1 = negative. Must be between 0 and 1. Default 0. + y_position: Y-Position [0.1mm] (discard position of tip A1 ). Must be between 1054 and 5743. + Default 5743. + z_deposit_position_[0.1mm]: Z- deposit position [0.1mm] (collar bearing position). Must be + between 0 and 3425. Default 3425. + z_position_at_the_command_end: Z-Position at the command end [0.1mm]. Must be between 0 and + 3425. Default 3425. """ - # The firmware command expects location of tip A1 of the head. - loc = self._position_96_head_in_resource(trash96) + assert 0 <= x_position <= 30000, "x_position must be between 0 and 30000" + assert 0 <= x_direction <= 1, "x_direction must be between 0 and 1" + assert 1054 <= y_position <= 5743, "y_position must be between 1054 and 5743" + assert 0 <= z_deposit_position <= 3425, "z_deposit_position must be between 0 and 3425" + assert 0 <= z_position_at_the_command_end <= 3425, \ + "z_position_at_the_command_end must be between 0 and 3425" return await self.send_command( module="C0", command="EI", - read_timeout=60, - xs=f"{abs(round(loc.x * 10)):05}", - xd=0 if loc.x >= 0 else 1, - yh=f"{abs(round(loc.y * 10)):04}", - za=f"{round(loc.z * 10):04}", - ze=f"{round(z_position_at_the_command_end*10):04}", + xs=f"{x_position:05}", + xd=x_direction, + yh=f"{y_position}", + za=f"{z_deposit_position}", + ze=f"{z_position_at_the_command_end}", ) async def move_core_96_to_safe_position(self): - """Move CoRe 96 Head to Z save position""" + """ Move CoRe 96 Head to Z save position """ return await self.send_command(module="C0", command="EV") async def request_core_96_head_initialization_status(self) -> bool: # not available in the C0 docs, so get from module H0 itself instead response = await self.send_command(module="H0", command="QW", fmt="qw#") - return bool(response.get("qw", 0) == 1) # type? + return bool(response.get("qw", 0) == 1) # type? # -------------- 3.10.2 Tip handling using CoRe 96 Head -------------- @@ -5252,9 +4820,9 @@ async def pick_up_tips_core96( tip_pickup_method: int = 2, z_deposit_position: int = 3425, minimum_traverse_height_at_beginning_of_a_command: int = 3425, - minimum_height_command_end: int = 3425, + minimum_height_command_end: int = 3425 ): - """Pick up tips with CoRe 96 head + """ Pick up tips with CoRe 96 head Args: x_position: x position [0.1mm]. Must be between 0 and 30000. Default 0. @@ -5274,12 +4842,10 @@ async def pick_up_tips_core96( assert 0 <= x_direction <= 1, "x_direction must be between 0 and 1" assert 1080 <= y_position <= 5600, "y_position must be between 1080 and 5600" assert 0 <= z_deposit_position <= 3425, "z_deposit_position must be between 0 and 3425" - assert ( - 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3425 - ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3425" - assert ( - 0 <= minimum_height_command_end <= 3425 - ), "minimum_height_command_end must be between 0 and 3425" + assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3425, \ + "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3425" + assert 0 <= minimum_height_command_end <= 3425, \ + "minimum_height_command_end must be between 0 and 3425" return await self.send_command( module="C0", @@ -5302,9 +4868,9 @@ async def discard_tips_core96( y_position: int, z_deposit_position: int = 3425, minimum_traverse_height_at_beginning_of_a_command: int = 3425, - minimum_height_command_end: int = 3425, + minimum_height_command_end: int = 3425 ): - """Drop tips with CoRe 96 head + """ Drop tips with CoRe 96 head Args: x_position: x position [0.1mm]. Must be between 0 and 30000. Default 0. @@ -5324,12 +4890,10 @@ async def discard_tips_core96( assert 0 <= x_direction <= 1, "x_direction must be between 0 and 1" assert 1080 <= y_position <= 5600, "y_position must be between 1080 and 5600" assert 0 <= z_deposit_position <= 3425, "z_deposit_position must be between 0 and 3425" - assert ( - 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3425 - ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3425" - assert ( - 0 <= minimum_height_command_end <= 3425 - ), "minimum_height_command_end must be between 0 and 3425" + assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3425, \ + "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3425" + assert 0 <= minimum_height_command_end <= 3425, \ + "minimum_height_command_end must be between 0 and 3425" return await self.send_command( module="C0", @@ -5339,7 +4903,7 @@ async def discard_tips_core96( yh=f"{y_position:04}", za=f"{z_deposit_position:04}", zh=f"{minimum_traverse_height_at_beginning_of_a_command:04}", - ze=f"{minimum_height_command_end:04}", + ze=f"{minimum_height_command_end:04}" ) # -------------- 3.10.3 Liquid handling using CoRe 96 Head -------------- @@ -5371,17 +4935,17 @@ async def aspirate_core_96( gamma_lld_sensitivity: int = 1, swap_speed: int = 100, settling_time: int = 5, - mix_volume: int = 0, - mix_cycles: int = 0, - mix_position_from_liquid_surface: int = 250, - surface_following_distance_during_mix: int = 0, - speed_of_mix: int = 1000, + homogenization_volume: int = 0, + homogenization_cycles: int = 0, + homogenization_position_from_liquid_surface: int = 250, + surface_following_distance_during_homogenization: int = 0, + speed_of_homogenization: int = 1000, channel_pattern: List[bool] = [True] * 96, limit_curve_index: int = 0, tadm_algorithm: bool = False, - recording_mode: int = 0, + recording_mode: int = 0 ): - """aspirate CoRe 96 + """ aspirate CoRe 96 Aspiration of liquid using CoRe 96 @@ -5423,13 +4987,13 @@ async def aspirate_core_96( Default 1. swap_speed: Swap speed (on leaving liquid) [0.1mm/s]. Must be between 3 and 1000. Default 100. settling_time: Settling time [0.1s]. Must be between 0 and 99. Default 5. - mix_volume: mix volume [0.1ul]. Must be between 0 and 11500. Default 0. - mix_cycles: Number of mix cycles. Must be between 0 and 99. Default 0. - mix_position_from_liquid_surface: mix position in Z- direction from + homogenization_volume: Homogenization volume [0.1ul]. Must be between 0 and 11500. Default 0. + homogenization_cycles: Number of homogenization cycles. Must be between 0 and 99. Default 0. + homogenization_position_from_liquid_surface: Homogenization position in Z- direction from liquid surface (LLD or absolute terms) [0.1mm]. Must be between 0 and 990. Default 250. - surface_following_distance_during_mix: surface following distance during - mix [0.1mm]. Must be between 0 and 990. Default 0. - speed_of_mix: Speed of mix [0.1ul/s]. Must be between 3 and 5000. + surface_following_distance_during_homogenization: surface following distance during + homogenization [0.1mm]. Must be between 0 and 990. Default 0. + speed_of_homogenization: Speed of homogenization [0.1ul/s]. Must be between 3 and 5000. Default 1000. todo: TODO: 24 hex chars. Must be between 4 and 5000. limit_curve_index: limit curve index. Must be between 0 and 999. Default 0. @@ -5442,31 +5006,24 @@ async def aspirate_core_96( assert 0 <= x_position <= 30000, "x_position must be between 0 and 30000" assert 0 <= x_direction <= 1, "x_direction must be between 0 and 1" assert 1080 <= y_positions <= 5600, "y_positions must be between 1080 and 5600" - assert ( - 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3425 - ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3425" + assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3425, \ + "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3425" assert 0 <= minimal_end_height <= 3425, "minimal_end_height must be between 0 and 3425" assert 0 <= lld_search_height <= 3425, "lld_search_height must be between 0 and 3425" - assert ( - 0 <= liquid_surface_at_function_without_lld <= 3425 - ), "liquid_surface_at_function_without_lld must be between 0 and 3425" - assert ( - 0 <= pull_out_distance_to_take_transport_air_in_function_without_lld <= 3425 - ), "pull_out_distance_to_take_transport_air_in_function_without_lld must be between 0 and 3425" - assert ( - 0 <= maximum_immersion_depth <= 3425 - ), "maximum_immersion_depth must be between 0 and 3425" - assert ( - 0 <= tube_2nd_section_height_measured_from_zm <= 3425 - ), "tube_2nd_section_height_measured_from_zm must be between 0 and 3425" - assert ( - 0 <= tube_2nd_section_ratio <= 10000 - ), "tube_2nd_section_ratio must be between 0 and 10000" + assert 0 <= liquid_surface_at_function_without_lld <= 3425, \ + "liquid_surface_at_function_without_lld must be between 0 and 3425" + assert 0 <= pull_out_distance_to_take_transport_air_in_function_without_lld <= 3425, \ + "pull_out_distance_to_take_transport_air_in_function_without_lld must be between 0 and 3425" + assert 0 <= maximum_immersion_depth <= 3425, \ + "maximum_immersion_depth must be between 0 and 3425" + assert 0 <= tube_2nd_section_height_measured_from_zm <= 3425, \ + "tube_2nd_section_height_measured_from_zm must be between 0 and 3425" + assert 0 <= tube_2nd_section_ratio <= 10000, \ + "tube_2nd_section_ratio must be between 0 and 10000" assert 0 <= immersion_depth <= 3600, "immersion_depth must be between 0 and 3600" assert 0 <= immersion_depth_direction <= 1, "immersion_depth_direction must be between 0 and 1" - assert ( - 0 <= liquid_surface_sink_distance_at_the_end_of_aspiration <= 990 - ), "liquid_surface_sink_distance_at_the_end_of_aspiration must be between 0 and 990" + assert 0 <= liquid_surface_sink_distance_at_the_end_of_aspiration <= 990, \ + "liquid_surface_sink_distance_at_the_end_of_aspiration must be between 0 and 990" assert 0 <= aspiration_volumes <= 11500, "aspiration_volumes must be between 0 and 11500" assert 3 <= aspiration_speed <= 5000, "aspiration_speed must be between 3 and 5000" assert 0 <= transport_air_volume <= 500, "transport_air_volume must be between 0 and 500" @@ -5476,15 +5033,14 @@ async def aspirate_core_96( assert 1 <= gamma_lld_sensitivity <= 4, "gamma_lld_sensitivity must be between 1 and 4" assert 3 <= swap_speed <= 1000, "swap_speed must be between 3 and 1000" assert 0 <= settling_time <= 99, "settling_time must be between 0 and 99" - assert 0 <= mix_volume <= 11500, "mix_volume must be between 0 and 11500" - assert 0 <= mix_cycles <= 99, "mix_cycles must be between 0 and 99" - assert ( - 0 <= mix_position_from_liquid_surface <= 990 - ), "mix_position_from_liquid_surface must be between 0 and 990" - assert ( - 0 <= surface_following_distance_during_mix <= 990 - ), "surface_following_distance_during_mix must be between 0 and 990" - assert 3 <= speed_of_mix <= 5000, "speed_of_mix must be between 3 and 5000" + assert 0 <= homogenization_volume <= 11500, "homogenization_volume must be between 0 and 11500" + assert 0 <= homogenization_cycles <= 99, "homogenization_cycles must be between 0 and 99" + assert 0 <= homogenization_position_from_liquid_surface <= 990, \ + "homogenization_position_from_liquid_surface must be between 0 and 990" + assert 0 <= surface_following_distance_during_homogenization <= 990, \ + "surface_following_distance_during_homogenization must be between 0 and 990" + assert 3 <= speed_of_homogenization <= 5000, \ + "speed_of_homogenization must be between 3 and 5000" assert 0 <= limit_curve_index <= 999, "limit_curve_index must be between 0 and 999" assert 0 <= recording_mode <= 2, "recording_mode must be between 0 and 2" @@ -5521,11 +5077,11 @@ async def aspirate_core_96( cs=gamma_lld_sensitivity, bs=f"{swap_speed:04}", wh=f"{settling_time:02}", - hv=f"{mix_volume:05}", - hc=f"{mix_cycles:02}", - hp=f"{mix_position_from_liquid_surface:03}", - mj=f"{surface_following_distance_during_mix:03}", - hs=f"{speed_of_mix:04}", + hv=f"{homogenization_volume:05}", + hc=f"{homogenization_cycles:02}", + hp=f"{homogenization_position_from_liquid_surface:03}", + mj=f"{surface_following_distance_during_homogenization:03}", + hs=f"{speed_of_homogenization:04}", cw=channel_pattern_hex, cr=f"{limit_curve_index:03}", cj=tadm_algorithm, @@ -5566,12 +5122,12 @@ async def dispense_core_96( mixing_position_from_liquid_surface: int = 250, surface_following_distance_during_mixing: int = 0, speed_of_mixing: int = 1000, - channel_pattern: List[bool] = [True] * 12 * 8, + channel_pattern: List[bool] = [True]*12*8, limit_curve_index: int = 0, tadm_algorithm: bool = False, - recording_mode: int = 0, + recording_mode: int = 0 ): - """dispense CoRe 96 + """ dispense CoRe 96 Dispensing of liquid using CoRe 96 @@ -5616,9 +5172,9 @@ async def dispense_core_96( Must be between 0 and 45. Default 1. swap_speed: Swap speed (on leaving liquid) [0.1mm/s]. Must be between 3 and 1000. Default 100. settling_time: Settling time [0.1s]. Must be between 0 and 99. Default 5. - mixing_volume: mix volume [0.1ul]. Must be between 0 and 11500. Default 0. + mixing_volume: Homogenization volume [0.1ul]. Must be between 0 and 11500. Default 0. mixing_cycles: Number of mixing cycles. Must be between 0 and 99. Default 0. - mixing_position_from_liquid_surface: mix position in Z- direction from liquid + mixing_position_from_liquid_surface: Homogenization position in Z- direction from liquid surface (LLD or absolute terms) [0.1mm]. Must be between 0 and 990. Default 250. surface_following_distance_during_mixing: surface following distance during mixing [0.1mm]. Must be between 0 and 990. Default 0. @@ -5634,30 +5190,23 @@ async def dispense_core_96( assert 0 <= x_position <= 30000, "x_position must be between 0 and 30000" assert 0 <= x_direction <= 1, "x_direction must be between 0 and 1" assert 1080 <= y_position <= 5600, "y_position must be between 1080 and 5600" - assert ( - 0 <= maximum_immersion_depth <= 3425 - ), "maximum_immersion_depth must be between 0 and 3425" - assert ( - 0 <= tube_2nd_section_height_measured_from_zm <= 3425 - ), "tube_2nd_section_height_measured_from_zm must be between 0 and 3425" - assert ( - 0 <= tube_2nd_section_ratio <= 10000 - ), "tube_2nd_section_ratio must be between 0 and 10000" + assert 0 <= maximum_immersion_depth <= 3425, \ + "maximum_immersion_depth must be between 0 and 3425" + assert 0 <= tube_2nd_section_height_measured_from_zm <= 3425, \ + "tube_2nd_section_height_measured_from_zm must be between 0 and 3425" + assert 0 <= tube_2nd_section_ratio <= 10000, \ + "tube_2nd_section_ratio must be between 0 and 10000" assert 0 <= lld_search_height <= 3425, "lld_search_height must be between 0 and 3425" - assert ( - 0 <= liquid_surface_at_function_without_lld <= 3425 - ), "liquid_surface_at_function_without_lld must be between 0 and 3425" - assert ( - 0 <= pull_out_distance_to_take_transport_air_in_function_without_lld <= 3425 - ), "pull_out_distance_to_take_transport_air_in_function_without_lld must be between 0 and 3425" + assert 0 <= liquid_surface_at_function_without_lld <= 3425, \ + "liquid_surface_at_function_without_lld must be between 0 and 3425" + assert 0 <= pull_out_distance_to_take_transport_air_in_function_without_lld <= 3425, \ + "pull_out_distance_to_take_transport_air_in_function_without_lld must be between 0 and 3425" assert 0 <= immersion_depth <= 3600, "immersion_depth must be between 0 and 3600" assert 0 <= immersion_depth_direction <= 1, "immersion_depth_direction must be between 0 and 1" - assert ( - 0 <= liquid_surface_sink_distance_at_the_end_of_dispense <= 990 - ), "liquid_surface_sink_distance_at_the_end_of_dispense must be between 0 and 990" - assert ( - 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3425 - ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3425" + assert 0 <= liquid_surface_sink_distance_at_the_end_of_dispense <= 990, \ + "liquid_surface_sink_distance_at_the_end_of_dispense must be between 0 and 990" + assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3425, \ + "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3425" assert 0 <= minimal_end_height <= 3425, "minimal_end_height must be between 0 and 3425" assert 0 <= dispense_volume <= 11500, "dispense_volume must be between 0 and 11500" assert 3 <= dispense_speed <= 5000, "dispense_speed must be between 3 and 5000" @@ -5672,12 +5221,10 @@ async def dispense_core_96( assert 0 <= settling_time <= 99, "settling_time must be between 0 and 99" assert 0 <= mixing_volume <= 11500, "mixing_volume must be between 0 and 11500" assert 0 <= mixing_cycles <= 99, "mixing_cycles must be between 0 and 99" - assert ( - 0 <= mixing_position_from_liquid_surface <= 990 - ), "mixing_position_from_liquid_surface must be between 0 and 990" - assert ( - 0 <= surface_following_distance_during_mixing <= 990 - ), "surface_following_distance_during_mixing must be between 0 and 990" + assert 0 <= mixing_position_from_liquid_surface <= 990, \ + "mixing_position_from_liquid_surface must be between 0 and 990" + assert 0 <= surface_following_distance_during_mixing <= 990, \ + "surface_following_distance_during_mixing must be between 0 and 990" assert 3 <= speed_of_mixing <= 5000, "speed_of_mixing must be between 3 and 5000" assert 0 <= limit_curve_index <= 999, "limit_curve_index must be between 0 and 999" assert 0 <= recording_mode <= 2, "recording_mode must be between 0 and 2" @@ -5736,9 +5283,9 @@ async def move_core_96_head_to_defined_position( x_direction: int = 0, y_position: int = 0, z_position: int = 0, - minimum_height_at_beginning_of_a_command: int = 3425, + minimum_height_at_beginning_of_a_command: int = 3425 ): - """Move CoRe 96 Head to defined position + """ Move CoRe 96 Head to defined position Args: dispensing_mode: Type of dispensing mode 0 = Partial volume in jet mode 1 = Blow out @@ -5758,9 +5305,8 @@ async def move_core_96_head_to_defined_position( assert 0 <= x_direction <= 1, "x_direction must be between 0 and 1" assert 1080 <= y_position <= 5600, "y_position must be between 1080 and 5600" assert 0 <= y_position <= 5600, "z_position must be between 0 and 5600" - assert ( - 0 <= minimum_height_at_beginning_of_a_command <= 3425 - ), "minimum_height_at_beginning_of_a_command must be between 0 and 3425" + assert 0 <= minimum_height_at_beginning_of_a_command <= 3425, \ + "minimum_height_at_beginning_of_a_command must be between 0 and 3425" return await self.send_command( module="C0", @@ -5781,7 +5327,7 @@ async def move_core_96_head_to_defined_position( # -------------- 3.10.6 Query CoRe 96 Head -------------- async def request_tip_presence_in_core_96_head(self): - """Request Tip presence in CoRe 96 Head + """ Request Tip presence in CoRe 96 Head Returns: qh: 0 = no tips, 1 = TipRack are picked up @@ -5790,7 +5336,7 @@ async def request_tip_presence_in_core_96_head(self): return await self.send_command(module="C0", command="QH", fmt="qh#") async def request_position_of_core_96_head(self): - """Request position of CoRe 96 Head (A1 considered to tip length) + """ Request position of CoRe 96 Head (A1 considered to tip length) Returns: xs: A1 X direction [0.1mm] @@ -5802,7 +5348,7 @@ async def request_position_of_core_96_head(self): return await self.send_command(module="C0", command="QI", fmt="xs#####xd#hy####za####") async def request_core_96_head_channel_tadm_status(self): - """Request CoRe 96 Head channel TADM Status + """ Request CoRe 96 Head channel TADM Status Returns: qx: TADM channel status 0 = off 1 = on @@ -5811,7 +5357,7 @@ async def request_core_96_head_channel_tadm_status(self): return await self.send_command(module="C0", command="VC", fmt="qx#") async def request_core_96_head_channel_tadm_error_status(self): - """Request CoRe 96 Head channel TADM error status + """ Request CoRe 96 Head channel TADM error status Returns: vb: error pattern 0 = no error @@ -5875,12 +5421,12 @@ async def request_core_96_head_channel_tadm_error_status(self): # -------------- 3.13.1 Initialization -------------- async def initialize_auto_load(self): - """Initialize Auto load module""" + """ Initialize Auto load module """ return await self.send_command(module="C0", command="II") async def move_auto_load_to_z_save_position(self): - """Move auto load to Z save position""" + """ Move auto load to Z save position """ return await self.send_command(module="C0", command="IV") @@ -5888,8 +5434,11 @@ async def move_auto_load_to_z_save_position(self): # TODO:(command:CI) Identify carrier (determine carrier type) - async def request_single_carrier_presence(self, carrier_position: int): - """Request single carrier presence + async def request_single_carrier_presence( + self, + carrier_position: int + ): + """ Request single carrier presence Args: carrier_position: Carrier position (slot number) @@ -5911,30 +5460,38 @@ async def request_single_carrier_presence(self, carrier_position: int): # Move autoload/scanner X-drive into slot number async def move_autoload_to_slot(self, slot_number: int): - """Move autoload to specific slot/track position""" + """ Move autoload to specific slot/track position """ assert 1 <= slot_number <= 54, "slot_number must be between 1 and 54" slot_no_as_safe_str = str(slot_number).zfill(2) - return await self.send_command(module="I0", command="XP", xp=slot_no_as_safe_str) + return await self.send_command( + module="I0", + command="XP", + xp=slot_no_as_safe_str + ) # Park autoload async def park_autoload(self): - """Park autoload""" + """ Park autoload """ # Identify max number of x positions for your liquid handler max_x_pos = str(self.extended_conf["xt"]).zfill(2) # Park autoload to max x position available - return await self.send_command(module="I0", command="XP", xp=max_x_pos) + return await self.send_command( + module="I0", + command="XP", + xp=max_x_pos + ) # TODO:(command:CA) Push out carrier to loading tray (after identification CI) async def unload_carrier(self, carrier: Carrier): - """Use autoload to unload carrier.""" + """ Use autoload to unload carrier. """ # Identify carrier end rail track_width = 22.5 - carrier_width = carrier.get_absolute_location().x - 100 + carrier.get_absolute_size_x() + carrier_width = carrier.get_absolute_location().x - 100 + carrier.get_absolute_size_x() carrier_end_rail = int(carrier_width / track_width) assert 1 <= carrier_end_rail <= 54, "carrier loading rail must be between 1 and 54" @@ -5955,18 +5512,19 @@ async def load_carrier( carrier: Carrier, barcode_reading: bool = False, barcode_reading_direction: Literal["horizontal", "vertical"] = "horizontal", - barcode_symbology: Literal[ - "ISBT Standard", - "Code 128 (Subset B and C)", - "Code 39", - "Codebar", - "Code 2of5 Interleaved", - "UPC A/E", - "YESN/EAN 8", - "Code 93", - ] = "Code 128 (Subset B and C)", + barcode_symbology: + Literal[ + "ISBT Standard", + "Code 128 (Subset B and C)", + "Code 39", + "Codebar", + "Code 2of5 Interleaved", + "UPC A/E", + "YESN/EAN 8", + "Code 93" + ] = "Code 128 (Subset B and C)", no_container_per_carrier: int = 5, - park_autoload_after: bool = True, + park_autoload_after: bool = True ): """ Use autoload to load carrier. @@ -5983,7 +5541,7 @@ async def load_carrier( barcode_reading_direction_dict = { "vertical": "0", - "horizontal": "1", + "horizontal": "1" } barcode_symbology_dict = { "ISBT Standard": "70", @@ -5997,7 +5555,7 @@ async def load_carrier( } # Identify carrier end rail track_width = 22.5 - carrier_width = carrier.get_absolute_location().x - 100 + carrier.get_absolute_size_x() + carrier_width = carrier.get_absolute_location().x - 100 + carrier.get_absolute_size_x() carrier_end_rail = int(carrier_width / track_width) assert 1 <= carrier_end_rail <= 54, "carrier loading rail must be between 1 and 54" @@ -6006,10 +5564,8 @@ async def load_carrier( carrier_end_rail_str = str(carrier_end_rail).zfill(2) if presence_check != 1: - raise ValueError( - f"""No carrier found at position {carrier_end_rail}, - have you placed the carrier onto the correct autoload tray position?""" - ) + raise ValueError(f"""No carrier found at position {carrier_end_rail}, + have you placed the carrier onto the correct autoload tray position?""") # Set carrier type for identification purposes await self.send_command(module="C0", command="CI", cp=carrier_end_rail_str) @@ -6021,28 +5577,36 @@ async def load_carrier( await self.send_command( module="C0", command="CB", - bt=barcode_symbology_dict[barcode_symbology], + bt=barcode_symbology_dict[barcode_symbology] ) # Load and read out barcodes resp = await self.send_command( module="C0", command="CL", bd=barcode_reading_direction_dict[barcode_reading_direction], - bp="0616", # Barcode reading direction (0 = vertical 1 = horizontal) - co="0960", # Distance between containers (pattern) [0.1 mm] - cf="380", # Width of reading window [0.1 mm] - cv="1281", # Carrier reading speed [0.1 mm]/s - cn=str(no_container_per_carrier).zfill(2), # No of containers (cups, plates) in a carrier + bp="0616", # Barcode reading direction (0 = vertical 1 = horizontal) + co="0960", # Distance between containers (pattern) [0.1 mm] + cf="380", # Width of reading window [0.1 mm] + cv="1281", # Carrier reading speed [0.1 mm]/s + cn=str(no_container_per_carrier).zfill(2), # No of containers (cups, plates) in a carrier + ) + else: # without barcoding + resp = await self.send_command( + module="C0", + command="CL", + cn="00" ) - else: # without barcoding - resp = await self.send_command(module="C0", command="CL", cn="00") if park_autoload_after: await self.park_autoload() return resp - async def set_loading_indicators(self, bit_pattern: List[bool], blink_pattern: List[bool]): - """Set loading indicators (LEDs) + async def set_loading_indicators( + self, + bit_pattern: List[bool], + blink_pattern: List[bool] + ): + """ Set loading indicators (LEDs) The docs here are a little weird because 2^54 < 7FFFFFFFFFFFFF. @@ -6058,14 +5622,14 @@ def pattern2hex(pattern: List[bool]) -> str: bit_string = "".join(["1" if x else "0" for x in pattern]) return hex(int(bit_string, base=2))[2:].upper().zfill(14) - bit_pattern_hex = pattern2hex(bit_pattern) + bit_pattern_hex = pattern2hex(bit_pattern) blink_pattern_hex = pattern2hex(blink_pattern) return await self.send_command( module="C0", command="CP", cl=bit_pattern_hex, - cb=blink_pattern_hex, + cb=blink_pattern_hex ) # TODO:(command:CS) Check for presence of carriers on loading tray @@ -6078,9 +5642,9 @@ async def set_barcode_type( codebar: bool = True, code2_5: bool = True, UPC_AE: bool = True, - EAN8: bool = True, + EAN8: bool = True ): - """Set bar code type: which types of barcodes will be scanned for. + """ Set bar code type: which types of barcodes will be scanned for. Args: ISBT_Standard: ISBT_Standard. Default True. @@ -6092,29 +5656,29 @@ async def set_barcode_type( EAN8: EAN8. Default True. """ + # pylint: disable=invalid-name + # Encode values into bit pattern. Last bit is always one. bt = "" - for t in [ - ISBT_Standard, - code128, - code39, - codebar, - code2_5, - UPC_AE, - EAN8, - True, - ]: + for t in [ISBT_Standard, code128, code39, codebar, code2_5, UPC_AE, EAN8, True]: bt += "1" if t else "0" # Convert bit pattern to hex. bt_hex = hex(int(bt, base=2)) - return await self.send_command(module="C0", command="CB", bt=bt_hex) + return await self.send_command( + module="C0", + command="CB", + bt=bt_hex + ) # TODO:(command:CW) Unload carrier finally - async def set_carrier_monitoring(self, should_monitor: bool = False): - """Set carrier monitoring + async def set_carrier_monitoring( + self, + should_monitor: bool = False + ): + """ Set carrier monitoring Args: should_monitor: whether carrier should be monitored. @@ -6123,7 +5687,11 @@ async def set_carrier_monitoring(self, should_monitor: bool = False): True if present, False otherwise """ - return await self.send_command(module="C0", command="CU", cu=should_monitor) + return await self.send_command( + module="C0", + command="CU", + cu=should_monitor + ) # TODO:(command:CN) Take out the carrier to identification position @@ -6132,7 +5700,7 @@ async def set_carrier_monitoring(self, should_monitor: bool = False): # TODO:(command:RC) Query presence of carrier on deck async def request_auto_load_slot_position(self): - """Request auto load slot position. + """ Request auto load slot position. Returns: slot position (0..54) @@ -6156,8 +5724,11 @@ async def request_auto_load_slot_position(self): # -------------- 3.15 Pump unit commands -------------- - async def request_pump_settings(self, pump_station: int = 1): - """Set carrier monitoring + async def request_pump_settings( + self, + pump_station: int = 1 + ): + """ Set carrier monitoring Args: carrier_position: pump station number (1..3) @@ -6172,7 +5743,12 @@ async def request_pump_settings(self, pump_station: int = 1): assert 1 <= pump_station <= 3, "pump_station must be between 1 and 3" - return await self.send_command(module="C0", command="ET", fmt="et#", ep=pump_station) + return await self.send_command( + module="C0", + command="ET", + fmt="et#", + ep=pump_station + ) # -------------- 3.15.1 DC Wash commands (only for revision up to 01) -------------- @@ -6192,8 +5768,11 @@ async def request_pump_settings(self, pump_station: int = 1): # -------------- 3.15.3 Dual chamber pump unit only -------------- - async def initialize_dual_pump_station_valves(self, pump_station: int = 1): - """Initialize pump station valves (dual chamber only) + async def initialize_dual_pump_station_valves( + self, + pump_station: int = 1 + ): + """ Initialize pump station valves (dual chamber only) Args: carrier_position: pump station number (1..3) @@ -6201,7 +5780,11 @@ async def initialize_dual_pump_station_valves(self, pump_station: int = 1): assert 1 <= pump_station <= 3, "pump_station must be between 1 and 3" - return await self.send_command(module="C0", command="EJ", ep=pump_station) + return await self.send_command( + module="C0", + command="EJ", + ep=pump_station + ) async def fill_selected_dual_chamber( self, @@ -6209,9 +5792,9 @@ async def fill_selected_dual_chamber( drain_before_refill: bool = False, wash_fluid: int = 1, chamber: int = 2, - waste_chamber_suck_time_after_sensor_change: int = 0, + waste_chamber_suck_time_after_sensor_change: int = 0 ): - """Initialize pump station valves (dual chamber only) + """ Initialize pump station valves (dual chamber only) Args: carrier_position: pump station number (1..3) @@ -6230,7 +5813,12 @@ async def fill_selected_dual_chamber( # 1 = wash fluid 1 <-> chamber 1 # 2 = wash fluid 2 <-> chamber 1 # 3 = wash fluid 2 <-> chamber 2 - connection = {(1, 2): 0, (1, 1): 1, (2, 1): 2, (2, 2): 3}[wash_fluid, chamber] + connection = { + (1, 2): 0, + (1, 1): 1, + (2, 1): 2, + (2, 2): 3 + }[wash_fluid, chamber] return await self.send_command( module="C0", @@ -6239,13 +5827,16 @@ async def fill_selected_dual_chamber( ed=drain_before_refill, ek=connection, eu=f"{waste_chamber_suck_time_after_sensor_change:02}", - wait=False, + wait=False ) # TODO:(command:EK) Drain selected chamber - async def drain_dual_chamber_system(self, pump_station: int = 1): - """Drain system (dual chamber only) + async def drain_dual_chamber_system( + self, + pump_station: int = 1 + ): + """ Drain system (dual chamber only) Args: carrier_position: pump station number (1..3) @@ -6253,7 +5844,11 @@ async def drain_dual_chamber_system(self, pump_station: int = 1): assert 1 <= pump_station <= 3, "pump_station must be between 1 and 3" - return await self.send_command(module="C0", command="EL", ep=pump_station) + return await self.send_command( + module="C0", + command="EL", + ep=pump_station + ) # TODO:(command:QD) Request dual chamber pump station prime status @@ -6270,112 +5865,108 @@ async def drain_dual_chamber_system(self, pump_station: int = 1): # -------------- 3.17.1 Pre & Initialization commands -------------- async def initialize_iswap(self): - """Initialize iSWAP (for standalone configuration only)""" + """ Initialize iSWAP (for standalone configuration only) """ return await self.send_command(module="C0", command="FI") async def initialize_autoload(self): - """Initialize autoload (for standalone configuration only)""" + """ Initialize autoload (for standalone configuration only) """ return await self.send_command(module="C0", command="II") async def position_components_for_free_iswap_y_range(self): - """Position all components so that there is maximum free Y range for iSWAP""" + """ Position all components so that there is maximum free Y range for iSWAP """ return await self.send_command(module="C0", command="FY") - async def move_iswap_x_relative(self, step_size: float, allow_splitting: bool = False): - """ + async def move_iswap_x_direction( + self, + step_size: int = 0, + direction: int = 0 + ): + """ Move iSWAP in X-direction + Args: - step_size: X Step size [1mm] Between -99.9 and 99.9 if allow_splitting is False. - allow_splitting: Allow splitting of the movement into multiple steps. Default False. + step_size: X Step size [0.1mm] Between 0 and 999. Default 0. + direction: X direction. 0 = positive 1 = negative """ - direction = 0 if step_size >= 0 else 1 - max_step_size = 99.9 - if abs(step_size) > max_step_size: - if not allow_splitting: - raise ValueError("step_size must be less than 99.9") - await self.move_iswap_x_relative( - step_size=max_step_size if step_size > 0 else -max_step_size, allow_splitting=True - ) - remaining_steps = step_size - max_step_size if step_size > 0 else step_size + max_step_size - return await self.move_iswap_x_relative(remaining_steps, allow_splitting) - return await self.send_command( - module="C0", command="GX", gx=str(round(abs(step_size) * 10)).zfill(3), xd=direction + module="C0", + command="GX", + gx=step_size, + xd=direction ) - async def move_iswap_y_relative(self, step_size: float, allow_splitting: bool = False): - """ + async def move_iswap_y_direction( + self, + step_size: int = 0, + direction: int = 0 + ): + """ Move iSWAP in Y-direction + Args: - step_size: Y Step size [1mm] Between -99.9 and 99.9 if allow_splitting is False. - allow_splitting: Allow splitting of the movement into multiple steps. Default False. + step_size: Y Step size [0.1mm] Between 0 and 999. Default 0. + direction: Y direction. 0 = positive 1 = negative """ - direction = 0 if step_size >= 0 else 1 - max_step_size = 99.9 - if abs(step_size) > max_step_size: - if not allow_splitting: - raise ValueError("step_size must be less than 99.9") - await self.move_iswap_y_relative( - step_size=max_step_size if step_size > 0 else -max_step_size, allow_splitting=True - ) - remaining_steps = step_size - max_step_size if step_size > 0 else step_size + max_step_size - return await self.move_iswap_y_relative(remaining_steps, allow_splitting) - return await self.send_command( - module="C0", command="GY", gy=str(round(abs(step_size) * 10)).zfill(3), yd=direction + module="C0", + command="GY", + gx=step_size, + xd=direction ) - async def move_iswap_z_relative(self, step_size: float, allow_splitting: bool = False): - """ + async def move_iswap_z_direction( + self, + step_size: int = 0, + direction: int = 0 + ): + """ Move iSWAP in Z-direction + Args: - step_size: Z Step size [1mm] Between -99.9 and 99.9 if allow_splitting is False. - allow_splitting: Allow splitting of the movement into multiple steps. Default False. + step_size: Z Step size [0.1mm] Between 0 and 999. Default 0. + direction: Z direction. 0 = positive 1 = negative """ - direction = 0 if step_size >= 0 else 1 - max_step_size = 99.9 - if abs(step_size) > max_step_size: - if not allow_splitting: - raise ValueError("step_size must be less than 99.9") - await self.move_iswap_z_relative( - step_size=max_step_size if step_size > 0 else -max_step_size, allow_splitting=True - ) - remaining_steps = step_size - max_step_size if step_size > 0 else step_size + max_step_size - return await self.move_iswap_z_relative(remaining_steps, allow_splitting) - return await self.send_command( - module="C0", command="GZ", gz=str(round(abs(step_size) * 10)).zfill(3), zd=direction + module="C0", + command="GZ", + gx=step_size, + xd=direction ) async def open_not_initialized_gripper(self): + """ Open not initialized gripper """ + return await self.send_command(module="C0", command="GI") - async def iswap_open_gripper(self, open_position: Optional[int] = None): - """Open gripper + async def iswap_open_gripper( + self, + open_position: int = 1320 + ): + """ Open gripper Args: open_position: Open position [0.1mm] (0.1 mm = 16 increments) The gripper moves to pos + 20. - Must be between 0 and 9999. Default 1320 for iSWAP 4.0 (landscape). Default to - 910 for iSWAP 3 (portrait). + Must be between 0 and 9999. Default 860. """ - if open_position is None: - open_position = 910 if (await self.get_iswap_version()).startswith("3") else 1320 - assert 0 <= open_position <= 9999, "open_position must be between 0 and 9999" - return await self.send_command(module="C0", command="GF", go=f"{open_position:04}") + return await self.send_command( + module="C0", + command="GF", + go=f"{open_position:04}" + ) async def iswap_close_gripper( self, grip_strength: int = 5, plate_width: int = 0, - plate_width_tolerance: int = 0, + plate_width_tolerance: int = 0 ): - """Close gripper + """ Close gripper The gripper should be at the position gb+gt+20 before sending this command. @@ -6391,16 +5982,16 @@ async def iswap_close_gripper( command="GC", gw=grip_strength, gb=plate_width, - gt=plate_width_tolerance, + gt=plate_width_tolerance ) # -------------- 3.17.2 Stack handling commands CP -------------- async def park_iswap( self, - minimum_traverse_height_at_beginning_of_a_command: int = 2840, + minimum_traverse_height_at_beginning_of_a_command: int = 2840 ): - """Close gripper + """ Close gripper The gripper should be at the position gb+gt+20 before sending this command. @@ -6409,14 +6000,13 @@ async def park_iswap( of a command [0.1mm]. Must be between 0 and 3600. Default 3600. """ - assert ( - 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 - ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ + "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" command_output = await self.send_command( module="C0", command="PG", - th=minimum_traverse_height_at_beginning_of_a_command, + th=minimum_traverse_height_at_beginning_of_a_command ) # Once the command has completed successfully, set _iswap_parked to True @@ -6441,9 +6031,9 @@ async def iswap_get_plate( collision_control_level: int = 1, acceleration_index_high_acc: int = 4, acceleration_index_low_acc: int = 1, - fold_up_sequence_at_the_end_of_process: bool = True, + fold_up_sequence_at_the_end_of_process: bool = True ): - """Get plate using iswap. + """ Get plate using iswap. Args: x_position: Plate center in X direction [0.1mm]. Must be between 0 and 30000. Default 0. @@ -6477,23 +6067,19 @@ async def iswap_get_plate( assert 0 <= z_position <= 3600, "z_position must be between 0 and 3600" assert 0 <= z_direction <= 1, "z_direction must be between 0 and 1" assert 1 <= grip_direction <= 4, "grip_direction must be between 1 and 4" - assert ( - 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 - ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" - assert ( - 0 <= z_position_at_the_command_end <= 3600 - ), "z_position_at_the_command_end must be between 0 and 3600" + assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ + "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert 0 <= z_position_at_the_command_end <= 3600, \ + "z_position_at_the_command_end must be between 0 and 3600" assert 1 <= grip_strength <= 9, "grip_strength must be between 1 and 9" assert 0 <= open_gripper_position <= 9999, "open_gripper_position must be between 0 and 9999" assert 0 <= plate_width <= 9999, "plate_width must be between 0 and 9999" assert 0 <= plate_width_tolerance <= 99, "plate_width_tolerance must be between 0 and 99" assert 0 <= collision_control_level <= 1, "collision_control_level must be between 0 and 1" - assert ( - 0 <= acceleration_index_high_acc <= 4 - ), "acceleration_index_high_acc must be between 0 and 4" - assert ( - 0 <= acceleration_index_low_acc <= 4 - ), "acceleration_index_low_acc must be between 0 and 4" + assert 0 <= acceleration_index_high_acc <= 4, \ + "acceleration_index_high_acc must be between 0 and 4" + assert 0 <= acceleration_index_low_acc <= 4, \ + "acceleration_index_low_acc must be between 0 and 4" command_output = await self.send_command( module="C0", @@ -6534,9 +6120,9 @@ async def iswap_put_plate( open_gripper_position: int = 860, collision_control_level: int = 1, acceleration_index_high_acc: int = 4, - acceleration_index_low_acc: int = 1, + acceleration_index_low_acc: int = 1 ): - """put plate + """ put plate Args: x_position: Plate center in X direction [0.1mm]. Must be between 0 and 30000. Default 0. @@ -6568,20 +6154,16 @@ async def iswap_put_plate( assert 0 <= z_position <= 3600, "z_position must be between 0 and 3600" assert 0 <= z_direction <= 1, "z_direction must be between 0 and 1" assert 1 <= grip_direction <= 4, "grip_direction must be between 1 and 4" - assert ( - 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 - ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" - assert ( - 0 <= z_position_at_the_command_end <= 3600 - ), "z_position_at_the_command_end must be between 0 and 3600" + assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ + "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert 0 <= z_position_at_the_command_end <= 3600, \ + "z_position_at_the_command_end must be between 0 and 3600" assert 0 <= open_gripper_position <= 9999, "open_gripper_position must be between 0 and 9999" assert 0 <= collision_control_level <= 1, "collision_control_level must be between 0 and 1" - assert ( - 0 <= acceleration_index_high_acc <= 4 - ), "acceleration_index_high_acc must be between 0 and 4" - assert ( - 0 <= acceleration_index_low_acc <= 4 - ), "acceleration_index_low_acc must be between 0 and 4" + assert 0 <= acceleration_index_high_acc <= 4, \ + "acceleration_index_high_acc must be between 0 and 4" + assert 0 <= acceleration_index_low_acc <= 4, \ + "acceleration_index_low_acc must be between 0 and 4" command_output = await self.send_command( module="C0", @@ -6609,10 +6191,10 @@ async def iswap_rotate( position: int = 33, gripper_velocity: int = 55_000, gripper_acceleration: int = 170, - gripper_protection: Literal[0, 1, 2, 3, 4, 5, 6, 7] = 5, + gripper_protection: Literal[0,1,2,3,4,5,6,7] = 5, wrist_velocity: int = 48_000, wrist_acceleration: int = 145, - wrist_protection: Literal[0, 1, 2, 3, 4, 5, 6, 7] = 5, + wrist_protection: Literal[0,1,2,3,4,5,6,7] = 5, ): """ Rotate the iswap to a predifined position. @@ -6649,9 +6231,9 @@ async def move_plate_to_position( minimum_traverse_height_at_beginning_of_a_command: int = 3600, collision_control_level: int = 1, acceleration_index_high_acc: int = 4, - acceleration_index_low_acc: int = 1, + acceleration_index_low_acc: int = 1 ): - """Move plate to position. + """ Move plate to position. Args: x_position: Plate center in X direction [0.1mm]. Must be between 0 and 30000. Default 0. @@ -6677,16 +6259,13 @@ async def move_plate_to_position( assert 0 <= z_position <= 3600, "z_position must be between 0 and 3600" assert 0 <= z_direction <= 1, "z_direction must be between 0 and 1" assert 1 <= grip_direction <= 4, "grip_direction must be between 1 and 4" - assert ( - 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 - ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ + "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" assert 0 <= collision_control_level <= 1, "collision_control_level must be between 0 and 1" - assert ( - 0 <= acceleration_index_high_acc <= 4 - ), "acceleration_index_high_acc must be between 0 and 4" - assert ( - 0 <= acceleration_index_low_acc <= 4 - ), "acceleration_index_low_acc must be between 0 and 4" + assert 0 <= acceleration_index_high_acc <= 4, \ + "acceleration_index_high_acc must be between 0 and 4" + assert 0 <= acceleration_index_low_acc <= 4, \ + "acceleration_index_low_acc must be between 0 and 4" command_output = await self.send_command( module="C0", @@ -6700,7 +6279,7 @@ async def move_plate_to_position( gr=grip_direction, th=f"{minimum_traverse_height_at_beginning_of_a_command:04}", ga=collision_control_level, - xe=f"{acceleration_index_high_acc} {acceleration_index_low_acc}", + xe=f"{acceleration_index_high_acc} {acceleration_index_low_acc}" ) # Once the command has completed successfuly, set _iswap_parked to false self._iswap_parked = False @@ -6709,9 +6288,9 @@ async def move_plate_to_position( async def collapse_gripper_arm( self, minimum_traverse_height_at_beginning_of_a_command: int = 3600, - fold_up_sequence_at_the_end_of_process: bool = True, + fold_up_sequence_at_the_end_of_process: bool = True ): - """Collapse gripper arm + """ Collapse gripper arm Args: minimum_traverse_height_at_beginning_of_a_command: Minimum traverse height at beginning of a @@ -6720,9 +6299,8 @@ async def collapse_gripper_arm( fold_up_sequence_at_the_end_of_process: fold up sequence at the end of process. Default True. """ - assert ( - 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 - ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ + "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" return await self.send_command( module="C0", @@ -6755,9 +6333,9 @@ async def prepare_iswap_teaching( minimum_traverse_height_at_beginning_of_a_command: int = 3600, collision_control_level: int = 1, acceleration_index_high_acc: int = 4, - acceleration_index_low_acc: int = 1, + acceleration_index_low_acc: int = 1 ): - """Prepare iSWAP teaching + """ Prepare iSWAP teaching Prepare for teaching with iSWAP @@ -6786,16 +6364,13 @@ async def prepare_iswap_teaching( assert 0 <= z_direction <= 1, "z_direction must be between 0 and 1" assert 0 <= location <= 1, "location must be between 0 and 1" assert 0 <= hotel_depth <= 3000, "hotel_depth must be between 0 and 3000" - assert ( - 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 - ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ + "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" assert 0 <= collision_control_level <= 1, "collision_control_level must be between 0 and 1" - assert ( - 0 <= acceleration_index_high_acc <= 4 - ), "acceleration_index_high_acc must be between 0 and 4" - assert ( - 0 <= acceleration_index_low_acc <= 4 - ), "acceleration_index_low_acc must be between 0 and 4" + assert 0 <= acceleration_index_high_acc <= 4, \ + "acceleration_index_high_acc must be between 0 and 4" + assert 0 <= acceleration_index_low_acc <= 4, \ + "acceleration_index_low_acc must be between 0 and 4" return await self.send_command( module="C0", @@ -6811,7 +6386,7 @@ async def prepare_iswap_teaching( gr=grip_direction, th=f"{minimum_traverse_height_at_beginning_of_a_command:04}", ga=collision_control_level, - xe=f"{acceleration_index_high_acc} {acceleration_index_low_acc}", + xe=f"{acceleration_index_high_acc} {acceleration_index_low_acc}" ) async def get_logic_iswap_position( @@ -6825,9 +6400,9 @@ async def get_logic_iswap_position( location: int = 0, hotel_depth: int = 1300, grip_direction: int = 1, - collision_control_level: int = 1, + collision_control_level: int = 1 ): - """Get logic iSWAP position + """ Get logic iSWAP position Args: x_position: Plate center in X direction [0.1mm]. Must be between 0 and 30000. Default 0. @@ -6873,7 +6448,7 @@ async def get_logic_iswap_position( # -------------- 3.17.6 iSWAP query -------------- async def request_iswap_in_parking_position(self): - """Request iSWAP in parking position + """ Request iSWAP in parking position Returns: 0 = gripper is not in parking position @@ -6883,7 +6458,7 @@ async def request_iswap_in_parking_position(self): return await self.send_command(module="C0", command="RG", fmt="rg#") async def request_plate_in_iswap(self) -> bool: - """Request plate in iSWAP + """ Request plate in iSWAP Returns: True if holding a plate, False otherwise. @@ -6893,25 +6468,21 @@ async def request_plate_in_iswap(self) -> bool: return resp is not None and resp["ph"] == 1 async def request_iswap_position(self): - """Request iSWAP position ( grip center ) + """ Request iSWAP position ( grip center ) Returns: - xs: Hotel center in X direction [1mm] + xs: Hotel center in X direction [0.1mm] xd: X direction 0 = positive 1 = negative - yj: Gripper center in Y direction [1mm] + yj: Gripper center in Y direction [0.1mm] yd: Y direction 0 = positive 1 = negative - zj: Gripper Z height (gripping height) [1mm] + zj: Gripper Z height (gripping height) [0.1mm] zd: Z direction 0 = positive 1 = negative """ - resp = await self.send_command(module="C0", command="QG", fmt="xs#####xd#yj####yd#zj####zd#") - resp["xs"] = resp["xs"] / 10 - resp["yj"] = resp["yj"] / 10 - resp["zj"] = resp["zj"] / 10 - return resp + return await self.send_command(module="C0", command="QG", fmt="xs#####xd#yj####yd#zj####zd#") async def request_iswap_initialization_status(self) -> bool: - """Request iSWAP initialization status + """ Request iSWAP initialization status Returns: True if iSWAP is fully initialized @@ -6920,34 +6491,30 @@ async def request_iswap_initialization_status(self) -> bool: resp = await self.send_command(module="R0", command="QW", fmt="qw#") return cast(int, resp["qw"]) == 1 - async def request_iswap_version(self) -> str: - """Firmware command for getting iswap version""" - return cast(str, (await self.send_command("R0", "RF", fmt="rf" + "&" * 15))["rf"]) - # -------------- 3.18 Cover and port control -------------- async def lock_cover(self): - """Lock cover""" + """ Lock cover """ return await self.send_command(module="C0", command="CO") async def unlock_cover(self): - """Unlock cover""" + """ Unlock cover """ return await self.send_command(module="C0", command="HO") async def disable_cover_control(self): - """Disable cover control""" + """ Disable cover control """ return await self.send_command(module="C0", command="CD") async def enable_cover_control(self): - """Enable cover control""" + """ Enable cover control """ return await self.send_command(module="C0", command="CE") async def set_cover_output(self, output: int = 0): - """Set cover output + """ Set cover output Args: output: 1 = cover lock; 2 = reserve out; 3 = reserve out. @@ -6957,7 +6524,7 @@ async def set_cover_output(self, output: int = 0): return await self.send_command(module="C0", command="OS", on=output) async def reset_output(self, output: int = 0): - """Reset output + """ Reset output Returns: output: 1 = cover lock; 2 = reserve out; 3 = reserve out. @@ -6967,7 +6534,7 @@ async def reset_output(self, output: int = 0): return await self.send_command(module="C0", command="QS", on=output, fmt="#") async def request_cover_open(self) -> bool: - """Request cover open + """ Request cover open Returns: True if the cover is open """ @@ -6975,6 +6542,7 @@ async def request_cover_open(self) -> bool: resp = await self.send_command(module="C0", command="QC", fmt="qc#") return bool(resp["qc"]) + # -------------- 4.0 Direct Device Integration -------------- # Communication occurs directly through STAR "TCC" connections, # i.e. firmware commands. This means devices can be seen as part @@ -6990,14 +6558,12 @@ async def check_type_is_hhs(self, device_number: int): firmware_version = await self.send_command(module=f"T{device_number}", command="RF") if "Heater Shaker" not in firmware_version: - raise ValueError( - f"Device number {device_number} does not connect to a Hamilton" - f" Heater Shaker, found {firmware_version} instead." - f"Have you called the wrong device number?" - ) + raise ValueError(f"Device number {device_number} does not connect to a Hamilton" \ + f" Heater Shaker, found {firmware_version} instead." \ + f"Have you called the wrong device number?") async def initialize_hhs(self, device_number: int) -> str: - """Initialize Hamilton Heater Shaker (HHS) at specified TCC port + """ Initialize Hamilton Heater Shaker (HHS) at specified TCC port Args: device_number: TCC connect number to the HHS @@ -7012,10 +6578,8 @@ async def initialize_hhs(self, device_number: int) -> str: try: await self.send_command(module=module_pointer, command="QU") except TimeoutError as exc: - error_message = ( - f"No Hamilton Heater Shaker found at device_number {device_number}" + error_message = f"No Hamilton Heater Shaker found at device_number {device_number}" \ f", have you checked your connections? Original error: {exc}" - ) raise ValueError(error_message) from exc await self.check_type_is_hhs(device_number) @@ -7035,25 +6599,25 @@ async def initialize_hhs(self, device_number: int) -> str: # -------------- 4.1.1 HHS Plate Lock -------------- async def open_plate_lock(self, device_number: int): - """Open HHS plate lock""" + """ Open HHS plate lock """ await self.check_type_is_hhs(device_number) return await self.send_command( module=f"T{device_number}", command="LP", - lp="0", # => open plate lock + lp="0" # => open plate lock ) async def close_plate_lock(self, device_number: int): - """Close HHS plate lock""" + """ Close HHS plate lock """ await self.check_type_is_hhs(device_number) return await self.send_command( - module=f"T{device_number}", + module = f"T{device_number}", command="LP", - lp="1", # => close plate lock + lp="1" # => close plate lock ) # -------------- 4.1.2 HHS Shaking -------------- @@ -7062,9 +6626,9 @@ async def start_shaking_at_hhs( device_number: int, rpm: int, rotation: int = 0, - plate_locked_during_shaking: bool = True, + plate_locked_during_shaking: bool = True ): - """Start shaking of specified HHS + """ Start shaking of specified HHS Args: rpm: round per minute @@ -7084,11 +6648,11 @@ async def start_shaking_at_hhs( command="SB", st=str(rotation), sv=str(rpm).zfill(4), - sr="00500", # ??? maybe shakingAccRamp rate? + sr="00500" # ??? maybe shakingAccRamp rate? ) async def stop_shaking_at_hhs(self, device_number: int): - """Close HHS plate lock""" + """ Close HHS plate lock """ await self.check_type_is_hhs(device_number) @@ -7101,7 +6665,7 @@ async def start_temperature_control_at_hhs( device_number: int, temp: Union[float, int], ): - """Start temperature regulation of specified HHS""" + """ Start temperature regulation of specified HHS """ await self.check_type_is_hhs(device_number) assert 0 < temp <= 105 @@ -7114,12 +6678,12 @@ async def start_temperature_control_at_hhs( return await self.send_command( module=f"T{device_number}", - command="TA", # temperature adjustment + command="TA", # temperature adjustment ta=safe_temp_str, ) async def get_temperature_at_hhs(self, device_number: int) -> dict: - """Query current temperatures of both sensors of specified HHS + """ Query current temperatures of both sensors of specified HHS Returns: Dictionary with keys "middle_T" and "edge_T" for the middle and edge temperature @@ -7128,15 +6692,12 @@ async def get_temperature_at_hhs(self, device_number: int) -> dict: await self.check_type_is_hhs(device_number) request_temperature = await self.send_command(module=f"T{device_number}", command="RT") - processed_t_info = [int(x) / 10 for x in request_temperature.split("+")[-2:]] + processed_t_info = [int(x)/10 for x in request_temperature.split("+")[-2:]] - return { - "middle_T": processed_t_info[0], - "edge_T": processed_t_info[-1], - } + return {"middle_T": processed_t_info[0],"edge_T": processed_t_info[-1]} async def stop_temperature_control_at_hhs(self, device_number: int): - """Stop temperature regulation of specified HHS""" + """ Stop temperature regulation of specified HHS """ await self.check_type_is_hhs(device_number) @@ -7152,14 +6713,12 @@ async def check_type_is_hhc(self, device_number: int): firmware_version = await self.send_command(module=f"T{device_number}", command="RF") if "Hamilton Heater Cooler" not in firmware_version: - raise ValueError( - f"Device number {device_number} does not connect to a Hamilton" - f" Heater-Cooler, found {firmware_version} instead." - f"Have you called the wrong device number?" - ) + raise ValueError(f"Device number {device_number} does not connect to a Hamilton" \ + f" Heater-Cooler, found {firmware_version} instead." \ + f"Have you called the wrong device number?") async def initialize_hhc(self, device_number: int) -> str: - """Initialize Hamilton Heater Cooler (HHC) at specified TCC port + """ Initialize Hamilton Heater Cooler (HHC) at specified TCC port Args: device_number: TCC connect number to the HHC @@ -7171,10 +6730,8 @@ async def initialize_hhc(self, device_number: int) -> str: try: await self.send_command(module=module_pointer, command="QU") except TimeoutError as exc: - error_message = ( - f"No Hamilton Heater Cooler found at device_number {device_number}" + error_message = f"No Hamilton Heater Cooler found at device_number {device_number}" \ f", have you checked your connections? Original error: {exc}" - ) raise ValueError(error_message) from exc await self.check_type_is_hhc(device_number) @@ -7195,9 +6752,9 @@ async def initialize_hhc(self, device_number: int) -> str: async def start_temperature_control_at_hhc( self, device_number: int, - temp: Union[float, int], + temp: Union[float, int], ): - """Start temperature regulation of specified HHC""" + """ Start temperature regulation of specified HHC """ await self.check_type_is_hhc(device_number) assert 0 < temp <= 105 @@ -7210,27 +6767,24 @@ async def start_temperature_control_at_hhc( return await self.send_command( module=f"T{device_number}", - command="TA", # temperature adjustment + command="TA", # temperature adjustment ta=safe_temp_str, - tb="1800", # TODO: identify precise purpose? - tc="0020", # TODO: identify precise purpose? + tb="1800", # TODO: identify precise purpose? + tc="0020", # TODO: identify precise purpose? ) async def get_temperature_at_hhc(self, device_number: int) -> dict: - """Query current temperatures of both sensors of specified HHC""" + """ Query current temperatures of both sensors of specified HHC """ await self.check_type_is_hhc(device_number) request_temperature = await self.send_command(module=f"T{device_number}", command="RT") - processed_t_info = [int(x) / 10 for x in request_temperature.split("+")[-2:]] + processed_t_info = [int(x)/10 for x in request_temperature.split("+")[-2:]] - return { - "middle_T": processed_t_info[0], - "edge_T": processed_t_info[-1], - } + return {"middle_T": processed_t_info[0],"edge_T": processed_t_info[-1]} async def query_whether_temperature_reached_at_hhc(self, device_number: int): - """Stop temperature regulation of specified HHC""" + """ Stop temperature regulation of specified HHC """ await self.check_type_is_hhc(device_number) query_current_control_status = await self.send_command( @@ -7240,653 +6794,100 @@ async def query_whether_temperature_reached_at_hhc(self, device_number: int): return query_current_control_status["qd"] == 0 async def stop_temperature_control_at_hhc(self, device_number: int): - """Stop temperature regulation of specified HHC""" + """ Stop temperature regulation of specified HHC """ await self.check_type_is_hhc(device_number) return await self.send_command(module=f"T{device_number}", command="TO") - # -------------- Extra - Probing labware with STAR - making STAR into a CMM -------------- +# -------------- Extra - Probing labware with STAR - making STAR into a CMM -------------- - y_drive_mm_per_increment = 0.046302082 - z_drive_mm_per_increment = 0.01072765 - - @staticmethod - def mm_to_y_drive_increment(value_mm: float) -> int: - return round(value_mm / STAR.y_drive_mm_per_increment) - - @staticmethod - def y_drive_increment_to_mm(value_mm: int) -> float: - return round(value_mm * STAR.y_drive_mm_per_increment, 2) - - @staticmethod - def mm_to_z_drive_increment(value_mm: float) -> int: - return round(value_mm / STAR.z_drive_mm_per_increment) - - @staticmethod - def z_drive_increment_to_mm(value_increments: int) -> float: - return round(value_increments * STAR.z_drive_mm_per_increment, 2) - - async def clld_probe_z_height_using_channel( + async def probe_z_height_using_channel( self, - channel_idx: int, # 0-based indexing of channels! - lowest_immers_pos: float = 99.98, # mm - start_pos_search: float = 330.0, # mm - channel_speed: float = 10.0, # mm - channel_acceleration: float = 800.0, # mm/sec**2 + channel_idx: int, + lowest_immers_pos: int = 10000, + start_pos_lld_search: int = 31200, + channel_speed: int = 1000, + channel_acceleration: int = 75, detection_edge: int = 10, detection_drop: int = 2, post_detection_trajectory: Literal[0, 1] = 1, - post_detection_dist: float = 2.0, # mm - move_channels_to_save_pos_after: bool = False, + post_detection_dist: int = 100, + move_channels_to_save_pos_after: bool = False ) -> float: - """Probes the Z-height below the specified channel on a Hamilton STAR liquid handling machine - using the channels 'capacitive Liquid Level Detection' (cLLD) capabilities. - N.B.: this means only conductive materials can be probed! + """ Probes the Z-height using a specified channel on a liquid handling device. + Commands the liquid handler to perform a Liquid Level Detection (LLD) operation using the + specified channel (this means only conductive materials can be probed!). Args: - channel_idx: The index of the channel to use for probing. Backmost channel = 0. - lowest_immers_pos: The lowest immersion position in mm. - start_pos_lld_search: The start position for z-touch search in mm. - channel_speed: The speed of channel movement in mm/sec. - channel_acceleration: The acceleration of the channel in mm/sec**2. + self: The liquid handler. + channel_idx: The index of the channel to use for probing. + lowest_immers_pos: The lowest immersion position in increments. + start_pos_lld_search: The start position for LLD search in increments. + channel_speed: The speed of channel movement. + channel_acceleration: The acceleration of the channel. detection_edge: The edge steepness at capacitive LLD detection. detection_drop: The offset after capacitive LLD edge detection. - post_detection_trajectory (0, 1): Movement of the channel up (1) or down (0) after - contacting the surface. - post_detection_dist: Distance to move into the trajectory after detection in mm. - move_channels_to_save_pos_after: Flag to move channels to a safe position after + post_detection_trajectory: Movement of the channel up (1) or down (0) after contacting the + surface. + post_detection_dist (int): Distance to move up after detection to avoid pressure build-up. + move_channels_to_save_pos_after (bool): Flag to move channels to a safe position after operation. Returns: - The detected Z-height in mm. + float: The detected Z-height in mm. """ - lowest_immers_pos_increments = STAR.mm_to_z_drive_increment(lowest_immers_pos) - start_pos_search_increments = STAR.mm_to_z_drive_increment(start_pos_search) - channel_speed_increments = STAR.mm_to_z_drive_increment(channel_speed) - channel_acceleration_thousand_increments = STAR.mm_to_z_drive_increment( - channel_acceleration / 1000 + assert 9320 <= lowest_immers_pos <= 31200, ( + "Lowest immersion position [increment] must be between 9320 and 31200" ) - post_detection_dist_increments = STAR.mm_to_z_drive_increment(post_detection_dist) - - assert 9_320 <= lowest_immers_pos_increments <= 31_200, ( - f"Lowest immersion position must be between \n{STAR.z_drive_increment_to_mm(9_320)}" - + f" and {STAR.z_drive_increment_to_mm(31_200)} mm, is {lowest_immers_pos} mm" + assert 9320 <= start_pos_lld_search <= 31200, ( + "Start position of LLD search [increment] must be between 9320 and 31200" ) - assert 9_320 <= start_pos_search_increments <= 31_200, ( - f"Start position of LLD search must be between \n{STAR.z_drive_increment_to_mm(9_320)}" - + f" and {STAR.z_drive_increment_to_mm(31_200)} mm, is {start_pos_search} mm" + assert 20 <= channel_speed <= 15000, ( + "LLD search speed [increment/second] must be between 20 and 15000" ) - assert 20 <= channel_speed_increments <= 15_000, ( - f"LLD search speed must be between \n{STAR.z_drive_increment_to_mm(20)}" - + f"and {STAR.z_drive_increment_to_mm(15_000)} mm/sec, is {channel_speed} mm/sec" + assert 5 <= channel_acceleration <= 150, ( + "Channel acceleration [increment] must be between 5 and 150" ) - assert 5 <= channel_acceleration_thousand_increments <= 150, ( - f"Channel acceleration must be between \n{STAR.z_drive_increment_to_mm(5*1_000)} " - + f" and {STAR.z_drive_increment_to_mm(150*1_000)} mm/sec**2, is {channel_acceleration} mm/sec**2" + assert 0 <= detection_edge <= 1023, ( + "Edge steepness at capacitive LLD detection must be between 0 and 1023" ) - assert ( - 0 <= detection_edge <= 1_023 - ), "Edge steepness at capacitive LLD detection must be between 0 and 1023" - assert ( - 0 <= detection_drop <= 1_023 - ), "Offset after capacitive LLD edge detection must be between 0 and 1023" - assert 0 <= post_detection_dist_increments <= 9_999, ( - "Post cLLD-detection movement distance must be between \n0" - + f" and {STAR.z_drive_increment_to_mm(9_999)} mm, is {post_detection_dist} mm" + assert 0 <= detection_drop <= 1023, ( + "Offset after capacitive LLD edge detection must be between 0 and 1023" + ) + assert 0 <= post_detection_dist <= 9999, ( + "Immersion depth after Liquid Level Detection [increment] must be between 0 and 9999" ) - lowest_immers_pos_str = f"{lowest_immers_pos_increments:05}" - start_pos_search_str = f"{start_pos_search_increments:05}" - channel_speed_str = f"{channel_speed_increments:05}" - channel_acc_str = f"{channel_acceleration_thousand_increments:03}" + lowest_immers_pos_str = f"{lowest_immers_pos:05}" + start_pos_lld_search_str = f"{start_pos_lld_search:05}" + channel_speed_str = f"{channel_speed:05}" + channel_acc_str = f"{channel_acceleration:03}" detection_edge_str = f"{detection_edge:04}" detection_drop_str = f"{detection_drop:04}" - post_detection_dist_str = f"{post_detection_dist_increments:04}" + post_detection_dist_str = f"{post_detection_dist:04}" await self.send_command( - module=STAR.channel_id(channel_idx), + module=f"P{channel_idx}", command="ZL", - zh=lowest_immers_pos_str, # Lowest immersion position [increment] - zc=start_pos_search_str, # Start position of LLD search [increment] - zl=channel_speed_str, # Speed of channel movement - zr=channel_acc_str, # Acceleration [1000 increment/second^2] - gt=detection_edge_str, # Edge steepness at capacitive LLD detection - gl=detection_drop_str, # Offset after capacitive LLD edge detection - zj=post_detection_trajectory, # Movement of the channel after contacting surface - zi=post_detection_dist_str, # Distance to move up after detection [increment] + zh=lowest_immers_pos_str, # Lowest immersion position [increment] + zc=start_pos_lld_search_str, # Start position of LLD search [increment] + zl=channel_speed_str, # Speed of channel movement + zr=channel_acc_str, # Acceleration [1000 increment/second^2] + gt=detection_edge_str, # Edge steepness at capacitive LLD detection + gl=detection_drop_str, # Offset after capacitive LLD edge detection + zj=post_detection_trajectory, # Movement of the channel after contacting surface + zi=post_detection_dist_str # Distance to move up after detection ) if move_channels_to_save_pos_after: await self.move_all_channels_in_z_safety() get_llds = await self.request_pip_height_last_lld() - result_in_mm = float(get_llds["lh"][channel_idx] / 10) + result_in_mm = float(get_llds["lh"][channel_idx-1] / 10) return result_in_mm - async def request_tip_len_on_channel( - self, - channel_idx: int, # 0-based indexing of channels! - ) -> float: - """ - Measures the length of the tip attached to the specified pipetting channel. - Checks if a tip is present on the given channel. If present, moves all channels - to THE safe Z position, 334.3 mm, measures the tip bottom Z-coordinate, and calculates - the total tip length. Supports tips of lengths 50.4 mm, 59.9 mm, and 95.1 mm. - Raises an error if the tip length is unsupported or if no tip is present. - Parameters: - channel_idx: Index of the pipetting channel (0-based). - Returns: - The measured tip length in millimeters. - Raises: - ValueError: If no tip is present on the channel or if the tip length is unsupported. - """ - - # Check there is a tip on the channel - all_channel_occupancy = await self.request_tip_presence() - if not all_channel_occupancy[channel_idx]: - raise ValueError(f"No tip present on channel {channel_idx}") - - # Level all channels - await self.move_all_channels_in_z_safety() - known_top_position_channel_head = 334.3 # mm - fitting_depth_of_all_standard_channel_tips = 8 # mm - unknown_offset_for_all_tips = 0.4 # mm - - # Request z-coordinate of channel+tip bottom - tip_bottom_z_coordinate = await self.request_z_pos_channel_n( - pipetting_channel_index=channel_idx - ) - - total_tip_len = round( - known_top_position_channel_head - - ( - tip_bottom_z_coordinate - - fitting_depth_of_all_standard_channel_tips - - unknown_offset_for_all_tips - ), - 1, - ) - - if total_tip_len in [50.4, 59.9, 95.1]: # 50ul, 300ul, 1000ul - return total_tip_len - raise ValueError(f"Tip of length {total_tip_len} not yet supported") - - async def ztouch_probe_z_height_using_channel( - self, - channel_idx: int, # 0-based indexing of channels! - tip_len: Optional[float] = None, # mm - lowest_immers_pos: float = 99.98, # mm - start_pos_search: Optional[float] = None, # mm - channel_speed: float = 10.0, # mm/sec - channel_acceleration: float = 800.0, # mm/sec**2 - channel_speed_upwards: float = 125.0, # mm - detection_limiter_in_PWM: int = 1, - push_down_force_in_PWM: int = 0, - post_detection_dist: float = 2.0, # mm - move_channels_to_save_pos_after: bool = False, - ) -> float: - """Probes the Z-height below the specified channel on a Hamilton STAR liquid handling machine - using the channels 'z-touchoff' capabilities, i.e. a controlled triggering of the z-drive, - aka a controlled 'crash'. - - Args: - channel_idx: The index of the channel to use for probing. Backmost channel = 0. - tip_len: override the tip length (of tip on channel `channel_idx`). Default is the tip length - of the tip that was picked up. - lowest_immers_pos: The lowest immersion position in mm. - start_pos_lld_search: The start position for z-touch search in mm. - channel_speed: The speed of channel movement in mm/sec. - channel_acceleration: The acceleration of the channel in mm/sec**2. - detection_limiter_in_PWM: Offset PWM limiter value for searching - push_down_force_in_PWM: Offset PWM value for push down force. - cf000 = No push down force, drive is switched off. - post_detection_dist: Distance to move into the trajectory after detection in mm. - move_channels_to_save_pos_after: Flag to move channels to a safe position after - operation. - - Returns: - The detected Z-height in mm. - """ - - version = await self.request_pip_channel_version(channel_idx) - year_matches = re.search(r"\b\d{4}\b", version) - if year_matches is not None: - year = int(year_matches.group()) - if year < 2022: - raise ValueError( - "Z-touch probing is not supported for PIP versions predating 2022, " - f"found version '{version}'" - ) - - if tip_len is None: - # currently a bug, will be fixed in the future - # reverted to previous implementation - # tip_len = self.head[channel_idx].get_tip().total_tip_length - tip_len = await self.request_tip_len_on_channel(channel_idx) - - # fitting_depth = 8 mm for 10, 50, 300, 1000 ul Hamilton tips - # fitting_depth = self.head[channel_idx].get_tip().fitting_depth - fitting_depth = 8 # mm, for 10, 50, 300, 1000 ul Hamilton tips - - if start_pos_search is None: - start_pos_search = 334.7 - tip_len + fitting_depth - - tip_len_used_in_increments = (tip_len - fitting_depth) / STAR.z_drive_mm_per_increment - channel_head_start_pos = ( - start_pos_search + tip_len - fitting_depth - ) # start_pos of the head itself! - safe_head_bottom_z_pos = ( - 99.98 + tip_len - fitting_depth - ) # 99.98 == STAR.z_drive_increment_to_mm(9_320) - safe_head_top_z_pos = 334.7 # 334.7 == STAR.z_drive_increment_to_mm(31_200) - - lowest_immers_pos_increments = STAR.mm_to_z_drive_increment(lowest_immers_pos) - start_pos_search_increments = STAR.mm_to_z_drive_increment(channel_head_start_pos) - channel_speed_increments = STAR.mm_to_z_drive_increment(channel_speed) - channel_acceleration_thousand_increments = STAR.mm_to_z_drive_increment( - channel_acceleration / 1000 - ) - channel_speed_upwards_increments = STAR.mm_to_z_drive_increment(channel_speed_upwards) - - assert 0 <= channel_idx <= 15, f"channel_idx must be between 0 and 15, is {channel_idx}" - assert 20 <= tip_len <= 120, "Total tip length must be between 20 and 120" - - assert 9320 <= lowest_immers_pos_increments <= 31_200, ( - "Lowest immersion position must be between \n99.98" - + f" and 334.7 mm, is {lowest_immers_pos} mm" - ) - assert safe_head_bottom_z_pos <= channel_head_start_pos <= safe_head_top_z_pos, ( - f"Start position of LLD search must be between \n{safe_head_bottom_z_pos}" - + f" and {safe_head_top_z_pos} mm, is {channel_head_start_pos} mm" - ) - assert 20 <= channel_speed_increments <= 15_000, ( - f"Z-touch search speed must be between \n{STAR.z_drive_increment_to_mm(20)}" - + f" and {STAR.z_drive_increment_to_mm(15_000)} mm/sec, is {channel_speed} mm/sec" - ) - assert 5 <= channel_acceleration_thousand_increments <= 150, ( - f"Channel acceleration must be between \n{STAR.z_drive_increment_to_mm(5*1_000)}" - + f" and {STAR.z_drive_increment_to_mm(150*1_000)} mm/sec**2, is {channel_speed} mm/sec**2" - ) - assert 20 <= channel_speed_upwards_increments <= 15_000, ( - f"Channel retraction speed must be between \n{STAR.z_drive_increment_to_mm(20)}" - + f" and {STAR.z_drive_increment_to_mm(15_000)} mm/sec, is {channel_speed_upwards} mm/sec" - ) - assert ( - 0 <= detection_limiter_in_PWM <= 125 - ), "Detection limiter value must be between 0 and 125 PWM." - assert 0 <= push_down_force_in_PWM <= 125, "Push down force between 0 and 125 PWM values" - assert ( - 0 <= post_detection_dist <= 245 - ), f"Post detection distance must be between 0 and 245 mm, is {post_detection_dist}" - - lowest_immers_pos_str = f"{lowest_immers_pos_increments:05}" - start_pos_search_str = f"{start_pos_search_increments:05}" - channel_speed_str = f"{channel_speed_increments:05}" - channel_acc_str = f"{channel_acceleration_thousand_increments:03}" - channel_speed_up_str = f"{channel_speed_upwards_increments:05}" - detection_limiter_in_PWM_str = f"{detection_limiter_in_PWM:03}" - push_down_force_in_PWM_str = f"{push_down_force_in_PWM:03}" - - ztouch_probed_z_height = await self.send_command( - module=STAR.channel_id(channel_idx), - command="ZH", - zb=start_pos_search_str, # begin of searching range [increment] - za=lowest_immers_pos_str, # end of searching range [increment] - zv=channel_speed_up_str, # speed z-drive upper section [increment/second] - zr=channel_acc_str, # acceleration z-drive [1000 increment/second] - zu=channel_speed_str, # speed z-drive lower section [increment/second] - cg=detection_limiter_in_PWM_str, # offset PWM limiter value for searching - cf=push_down_force_in_PWM_str, # offset PWM value for push down force - fmt="rz#####", - ) - # Subtract tip_length from measurement in increment, and convert to mm - result_in_mm = STAR.z_drive_increment_to_mm( - ztouch_probed_z_height["rz"] - tip_len_used_in_increments - ) - if post_detection_dist != 0: # Safety first - await self.move_channel_z(z=result_in_mm + post_detection_dist, channel=channel_idx) - if move_channels_to_save_pos_after: - await self.move_all_channels_in_z_safety() - - return float(result_in_mm) - - class RotationDriveOrientation(enum.Enum): - LEFT = 1 - FRONT = 2 - RIGHT = 3 - - async def rotate_iswap_rotation_drive(self, orientation: RotationDriveOrientation): - return await self.send_command( - module="R0", - command="WP", - auto_id=False, - wp=orientation.value, - ) - - class WristOrientation(enum.Enum): - RIGHT = 1 - STRAIGHT = 2 - LEFT = 3 - REVERSE = 4 - - async def rotate_iswap_wrist(self, orientation: WristOrientation): - return await self.send_command( - module="R0", - command="TP", - auto_id=False, - tp=orientation.value, - ) - - @staticmethod - def channel_id(channel_idx: int) -> str: - """channel_idx: plr style, 0-indexed from the back""" - channel_ids = "123456789ABCDEFG" - return "P" + channel_ids[channel_idx] - - async def get_channels_y_positions(self) -> Dict[int, float]: - """Get the Y position of all channels in mm""" - resp = await self.send_command( - module="C0", - command="RY", - fmt="ry#### (n)", - ) - y_positions = [round(y / 10, 2) for y in resp["ry"]] - - # sometimes there is (likely) a floating point error and channels are reported to be - # less than 9mm apart. (When you set channels using position_channels_in_y_direction, - # it will raise an error.) The minimum y is 6mm, so we fix that first (in case that - # values is misreported). Then, we traverse the list in reverse and set the min_diff. - if y_positions[-1] < 5.8: - raise RuntimeError( - "Channels are reported to be too close to the front of the machine. " - "The known minimum is 6, which will be fixed automatically for 5.8=9mm. We start with the channel closest to `back_channel`, and make sure the - # channel behind it is at least 9mm, updating if needed. Iterating from the front (closest - # to `back_channel`) to the back (channel 0), all channels are put at the correct location. - # This order matters because the channel in front of any channel may have been moved in the - # previous iteration. - # Note that if a channel is already spaced at >=9mm, it is not moved. - use_channels = list(ys.keys()) - back_channel = min(use_channels) - for channel_idx in range(back_channel, 0, -1): - if (channel_locations[channel_idx - 1] - channel_locations[channel_idx]) < 9: - channel_locations[channel_idx - 1] = channel_locations[channel_idx] + 9 - - # Similarly for the channels to the front of `front_channel`, make sure they are all - # spaced >=9mm apart. This time, we iterate from back (closest to `front_channel`) - # to the front (lh.backend.num_channels - 1), and put each channel >=9mm before the - # one behind it. - front_channel = max(use_channels) - for channel_idx in range(front_channel, self.num_channels - 1): - if (channel_locations[channel_idx] - channel_locations[channel_idx + 1]) < 9: - channel_locations[channel_idx + 1] = channel_locations[channel_idx] - 9 - - # Quick checks before movement. - if channel_locations[0] > 650: - raise ValueError("Channel 0 would hit the back of the robot") - - if channel_locations[self.num_channels - 1] < 6: - raise ValueError("Channel N would hit the front of the robot") - - if not all( - int((channel_locations[i] - channel_locations[i + 1]) * 1000) >= 8_999 # float fixing - for i in range(len(channel_locations) - 1) - ): - raise ValueError("Channels must be at least 9mm apart and in descending order") - - yp = " ".join([f"{round(y*10):04}" for y in channel_locations.values()]) - return await self.send_command( - module="C0", - command="JY", - yp=yp, - ) - - async def get_channels_z_positions(self) -> Dict[int, float]: - """Get the Y position of all channels in mm""" - resp = await self.send_command( - module="C0", - command="RZ", - fmt="rz#### (n)", - ) - return {channel_idx: round(y / 10, 2) for channel_idx, y in enumerate(resp["rz"])} - - async def position_channels_in_z_direction(self, zs: Dict[int, float]): - channel_locations = await self.get_channels_z_positions() - - for channel_idx, z in zs.items(): - channel_locations[channel_idx] = z - - return await self.send_command( - module="C0", command="JZ", zp=[f"{round(z*10):04}" for z in channel_locations.values()] - ) - - async def pierce_foil( - self, - wells: Union[Well, List[Well]], - piercing_channels: List[int], - hold_down_channels: List[int], - move_inwards: float, - spread: Literal["wide", "tight"] = "wide", - one_by_one: bool = False, - distance_from_bottom: float = 20.0, - ): - """Pierce the foil of the media source plate at the specified column. Throw away the tips - after piercing because there will be a bit of foil stuck to the tips. Use this method - before aspirating from a foil-sealed plate to make sure the tips are clean and the - aspirations are accurate. - - Args: - wells: Well or wells in the plate to pierce the foil. If multiple wells, they must be on one - column. - piercing_channels: The channels to use for piercing the foil. - hold_down_channels: The channels to use for holding down the plate when moving up the - piercing channels. - spread: The spread of the piercing channels in the well. - one_by_one: If True, the channels will pierce the foil one by one. If False, all channels - will pierce the foil simultaneously. - """ - - x: float - ys: List[float] - z: float - - # if only one well is give, but in a list, convert to Well so we fall into single-well logic. - if isinstance(wells, list) and len(wells) == 1: - wells = wells[0] - - if isinstance(wells, Well): - well = wells - x, y, z = well.get_absolute_location("c", "c", "cavity_bottom") - - if spread == "wide": - offsets = get_wide_single_resource_liquid_op_offsets( - well, num_channels=len(piercing_channels) - ) - else: - offsets = get_tight_single_resource_liquid_op_offsets( - well, num_channels=len(piercing_channels) - ) - ys = [y + offset.y for offset in offsets] - else: - assert ( - len(set(w.get_absolute_location().x for w in wells)) == 1 - ), "Wells must be on the same column" - absolute_center = wells[0].get_absolute_location("c", "c", "cavity_bottom") - x = absolute_center.x - ys = [well.get_absolute_location(x="c", y="c").y for well in wells] - z = absolute_center.z - - await self.move_channel_x(0, x=x) - - await self.position_channels_in_y_direction( - {channel: y for channel, y in zip(piercing_channels, ys)} - ) - - zs = [z + distance_from_bottom for _ in range(len(piercing_channels))] - if one_by_one: - for channel in piercing_channels: - await self.move_channel_z(channel, z) - else: - await self.position_channels_in_z_direction( - {channel: z for channel, z in zip(piercing_channels, zs)} - ) - - await self.step_off_foil( - [wells] if isinstance(wells, Well) else wells, - back_channel=hold_down_channels[0], - front_channel=hold_down_channels[1], - move_inwards=move_inwards, - ) - - async def step_off_foil( - self, - wells: Union[Well, List[Well]], - front_channel: int, - back_channel: int, - move_inwards: float = 2, - move_height: float = 15, - ): - """ - Hold down a plate by placing two channels on the edges of a plate that is sealed with foil - while moving up the channels that are still within the foil. This is useful when, for - example, aspirating from a plate that is sealed: without holding it down, the tips might get - stuck in the plate and move it up when retracting. Putting plates on the edge prevents this. - - When aspirating or dispensing in the foil, be sure to set the `min_z_endpos` parameter in - `lh.aspirate` or `lh.dispense` to a value in the foil. You might want to use something like - - .. code-block:: python - - well = plate.get_well("A3") - await wc.lh.aspirate( - [well]*4, vols=[100]*4, use_channels=[7,8,9,10], - min_z_endpos=well.get_absolute_location(z="cavity_bottom").z, - surface_following_distance=0, - pull_out_distance_transport_air=[0] * 4) - await step_off_foil(lh.backend, [well], front_channel=11, back_channel=6, move_inwards=3) - - Args: - wells: Wells in the plate to hold down. (x-coordinate of channels will be at center of wells). - Must be sorted from back to front. - front_channel: The channel to place on the front of the plate. - back_channel: The channel to place on the back of the plate. - move_inwards: mm to move inwards (backward on the front channel; frontward on the back). - move_height: mm to move upwards after piercing the foil. front_channel and back_channel will hold the plate down. - """ - - if front_channel <= back_channel: - raise ValueError( - "front_channel should be in front of back_channel. " "Channels are 0-indexed from the back." - ) - - if isinstance(wells, Well): - wells = [wells] - - plates = set(well.parent for well in wells) - assert len(plates) == 1, "All wells must be in the same plate" - plate = plates.pop() - assert plate is not None - - z_location = plate.get_absolute_location(z="top").z - - if plate.get_absolute_rotation().z % 360 == 0: - back_location = plate.get_absolute_location(y="b") - front_location = plate.get_absolute_location(y="f") - elif plate.get_absolute_rotation().z % 360 == 90: - back_location = plate.get_absolute_location(x="r") - front_location = plate.get_absolute_location(x="l") - elif plate.get_absolute_rotation().z % 360 == 180: - back_location = plate.get_absolute_location(y="f") - front_location = plate.get_absolute_location(y="b") - elif plate.get_absolute_rotation().z % 360 == 270: - back_location = plate.get_absolute_location(x="l") - front_location = plate.get_absolute_location(x="r") - else: - raise ValueError("Plate rotation must be a multiple of 90 degrees") - - try: - # Then move all channels in the y-space simultaneously. - await self.position_channels_in_y_direction( - { - front_channel: front_location.y + move_inwards, - back_channel: back_location.y - move_inwards, - } - ) - - await self.move_channel_z(front_channel, z_location) - await self.move_channel_z(back_channel, z_location) - finally: - # Move channels that are lower than the `front_channel` and `back_channel` to - # the just above the foil, in case the foil pops up. - zs = await self.get_channels_z_positions() - indices = [channel_idx for channel_idx, z in zs.items() if z < z_location] - idx = { - idx: z_location + move_height for idx in indices if idx not in (front_channel, back_channel) - } - await self.position_channels_in_z_direction(idx) - - # After that, all channels are clear to move up. - await self.move_all_channels_in_z_safety() - - async def request_volume_in_tip(self, channel: int) -> float: - resp = await self.send_command(STAR.channel_id(channel), "QC", fmt="qc##### (n)") - _, current_volume = resp["qc"] # first is max volume - return float(current_volume) / 10 - - @asynccontextmanager - async def slow_iswap(self, wrist_velocity: int = 20_000, gripper_velocity: int = 20_000): - """A context manager that sets the iSWAP to slow speed during the context""" - assert 20 <= gripper_velocity <= 75_000 - assert 20 <= wrist_velocity <= 65_000 - - original_wv = (await self.send_command("R0", "RA", ra="wv", fmt="wv#####"))["wv"] - original_tv = (await self.send_command("R0", "RA", ra="tv", fmt="tv#####"))["tv"] - - await self.send_command("R0", "AA", wv=gripper_velocity) # wrist velocity - await self.send_command("R0", "AA", tv=wrist_velocity) # gripper velocity - try: - yield - finally: - await self.send_command("R0", "AA", wv=original_wv) - await self.send_command("R0", "AA", tv=original_tv) - class UnSafe: """ @@ -7902,12 +6903,13 @@ async def put_in_hotel( hotel_center_x_coord: int = 0, hotel_center_y_coord: int = 0, hotel_center_z_coord: int = 0, + # for direction, 0 is positive, 1 is negative hotel_center_x_direction: Literal[0, 1] = 0, hotel_center_y_direction: Literal[0, 1] = 0, hotel_center_z_direction: Literal[0, 1] = 0, clearance_height: int = 50, hotel_depth: int = 1_300, - grip_direction: GripDirection = GripDirection.FRONT, + grip_direction:GripDirection = GripDirection.FRONT, traverse_height_at_beginning: int = 3_600, z_position_at_end: int = 3_600, grip_strength: Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] = 5, @@ -7977,14 +6979,14 @@ async def get_from_hotel( hotel_center_z_direction: Literal[0, 1] = 0, clearance_height: int = 50, hotel_depth: int = 1_300, - grip_direction: GripDirection = GripDirection.FRONT, + grip_direction:GripDirection = GripDirection.FRONT, traverse_height_at_beginning: int = 3_600, z_position_at_end: int = 3_600, grip_strength: Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] = 5, open_gripper_position: int = 860, plate_width: int = 800, plate_width_tolerance: int = 20, - collision_control: Literal[0, 1] = 1, + collision_control: Literal[0, 1]=1, high_acceleration_index: Literal[1, 2, 3, 4] = 4, low_acceleration_index: Literal[1, 2, 3, 4] = 1, fold_up_at_end: bool = True, @@ -8041,16 +7043,3 @@ async def get_from_hotel( xe=f"{high_acceleration_index} {low_acceleration_index}", gc=int(fold_up_at_end), ) - - async def violently_shoot_down_tip(self, channel_idx: int): - """Shoot down the tip on the specified channel by releasing the drive that holds the spring. The - tips will shoot down in place at an acceleration bigger than g. This is done by initializing - the squeezer drive wihile a tip is mounted. - - Safe to do when above a tip rack, for example directly after a tip pickup. - - .. warning:: - - Consider this method an easter egg. Not for serious use. - """ - await self.star.send_command(module=STAR.channel_id(channel_idx), command="SI") diff --git a/pylabrobot/liquid_handling/backends/hamilton/vantage.py b/pylabrobot/liquid_handling/backends/hamilton/vantage.py index 901c3214f3..8dd1b0f3a5 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/vantage.py +++ b/pylabrobot/liquid_handling/backends/hamilton/vantage.py @@ -1,43 +1,29 @@ +# pylint: disable=invalid-name + import asyncio import random import re import sys from typing import Dict, List, Optional, Sequence, Union, cast -from pylabrobot.liquid_handling.backends.hamilton.base import ( - HamiltonLiquidHandler, -) -from pylabrobot.liquid_handling.liquid_classes.hamilton import ( - HamiltonLiquidClass, - get_vantage_liquid_class, -) +from pylabrobot.liquid_handling.backends.hamilton.base import HamiltonLiquidHandler +from pylabrobot.liquid_handling.liquid_classes.hamilton import HamiltonLiquidClass from pylabrobot.liquid_handling.standard import ( - Drop, - DropTipRack, - MultiHeadAspirationContainer, - MultiHeadAspirationPlate, - MultiHeadDispenseContainer, - MultiHeadDispensePlate, Pickup, PickupTipRack, - ResourceDrop, - ResourceMove, - ResourcePickup, - SingleChannelAspiration, - SingleChannelDispense, -) -from pylabrobot.resources import ( - Coordinate, - Liquid, - Resource, - TipRack, - Well, -) -from pylabrobot.resources.hamilton import ( - HamiltonTip, - TipPickupMethod, - TipSize, + Drop, + DropTipRack, + Aspiration, + AspirationPlate, + AspirationContainer, + Dispense, + DispensePlate, + DispenseContainer, + Move ) +from pylabrobot.resources import Coordinate, Resource, TipRack, Well +from pylabrobot.resources.ml_star import HamiltonTip, TipPickupMethod, TipSize + if sys.version_info >= (3, 8): from typing import Literal @@ -46,7 +32,7 @@ def parse_vantage_fw_string(s: str, fmt: Optional[Dict[str, str]] = None) -> dict: - """Parse a Vantage firmware string into a dict. + """ Parse a Vantage firmware string into a dict. The identifier parameter (id) is added automatically. @@ -79,22 +65,22 @@ def parse_vantage_fw_string(s: str, fmt: Optional[Dict[str, str]] = None) -> dic for key, data_type in fmt.items(): if data_type == "int": - matches = re.findall(rf"{key}([-+]?\d+)", s) + matches = re.findall(fr"{key}([-+]?\d+)", s) if len(matches) != 1: raise ValueError(f"Expected exactly one match for {key} in {s}") parsed[key] = int(matches[0]) elif data_type == "str": - matches = re.findall(rf"{key}\"(.*)\"", s) + matches = re.findall(fr"{key}\"(.*)\"", s) if len(matches) != 1: raise ValueError(f"Expected exactly one match for {key} in {s}") parsed[key] = matches[0] elif data_type == "[int]": - matches = re.findall(rf"{key}((?:[-+]?[\d ]+)+)", s) + matches = re.findall(fr"{key}((?:[-+]?[\d ]+)+)", s) if len(matches) != 1: raise ValueError(f"Expected exactly one match for {key} in {s}") parsed[key] = [int(x) for x in matches[0].split()] elif data_type == "hex": - matches = re.findall(rf"{key}([0-9a-fA-F]+)", s) + matches = re.findall(fr"{key}([0-9a-fA-F]+)", s) if len(matches) != 1: raise ValueError(f"Expected exactly one match for {key} in {s}") parsed[key] = int(matches[0], 16) @@ -103,7 +89,6 @@ def parse_vantage_fw_string(s: str, fmt: Optional[Dict[str, str]] = None) -> dic return parsed - core96_errors = { 0: "No error", 21: "No communication to digital potentiometer", @@ -156,112 +141,112 @@ def parse_vantage_fw_string(s: str, fmt: Optional[Dict[str, str]] = None) -> dic } pip_errors = { - 22: "Drive controller message error", - 23: "EC drive controller setup not executed", - 25: "wrong Flash EPROM data", - 26: "Flash EPROM not programmable", - 27: "Flash EPROM not erasable", - 28: "Flash EPROM checksum error", - 29: "wrong FW loaded", - 30: "Undefined command", - 31: "Undefined parameter", - 32: "Parameter out of range", - 35: "Voltages out of range", - 36: "Stop during command execution", - 37: "Adjustment sensor didn't switch (no teach in signal)", - 38: "Movement interrupted by partner channel", - 39: "Angle alignment offset error", - 40: "No parallel processes on level 1 permitted", - 41: "No parallel processes on level 2 permitted", - 42: "No parallel processes on level 3 permitted", - 50: "D drive initialization failed", - 51: "D drive not initialized", - 52: "D drive movement error", - 53: "Maximum volume in tip reached", - 54: "D drive position out of permitted area", - 55: "Y drive initialization failed", - 56: "Y drive not initialized", - 57: "Y drive movement error", - 58: "Y drive position out of permitted area", - 59: "Divergance Y motion controller to linear encoder to heigh", - 60: "Z drive initialization failed", - 61: "Z drive not initialized", - 62: "Z drive movement error", - 63: "Z drive position out of permitted area", - 64: "Limit stop not found", - 65: "S drive initialization failed", - 66: "S drive not initialized", - 67: "S drive movement error", - 68: "S drive position out of permitted area", - 69: "Init. position adjustment error", - 70: "No liquid level found", - 71: "Not enough liquid present", - 74: "Liquid at a not allowed position detected", - 75: "No tip picked up", - 76: "Tip already picked up", - 77: "Tip not discarded", - 78: "Wrong tip detected", - 79: "Tip not correct squeezed", - 80: "Liquid not correctly aspirated", - 81: "Clot detected", - 82: "TADM measurement out of lower limit curve", - 83: "TADM measurement out of upper limit curve", - 84: "Not enough memory for TADM measurement", - 85: "Jet dispense pressure not reached", - 86: "ADC algorithm error", - 90: "Limit curve not resetable", - 91: "Limit curve not programmable", - 92: "Limit curve name not found", - 93: "Limit curve data incorrect", - 94: "Not enough memory for limit curve", - 95: "Not allowed limit curve index", - 96: "Limit curve already stored", + 22: "Drive controller message error", + 23: "EC drive controller setup not executed", + 25: "wrong Flash EPROM data", + 26: "Flash EPROM not programmable", + 27: "Flash EPROM not erasable", + 28: "Flash EPROM checksum error", + 29: "wrong FW loaded", + 30: "Undefined command", + 31: "Undefined parameter", + 32: "Parameter out of range", + 35: "Voltages out of range", + 36: "Stop during command execution", + 37: "Adjustment sensor didn't switch (no teach in signal)", + 38: "Movement interrupted by partner channel", + 39: "Angle alignment offset error", + 40: "No parallel processes on level 1 permitted", + 41: "No parallel processes on level 2 permitted", + 42: "No parallel processes on level 3 permitted", + 50: "D drive initialization failed", + 51: "D drive not initialized", + 52: "D drive movement error", + 53: "Maximum volume in tip reached", + 54: "D drive position out of permitted area", + 55: "Y drive initialization failed", + 56: "Y drive not initialized", + 57: "Y drive movement error", + 58: "Y drive position out of permitted area", + 59: "Divergance Y motion controller to linear encoder to heigh", + 60: "Z drive initialization failed", + 61: "Z drive not initialized", + 62: "Z drive movement error", + 63: "Z drive position out of permitted area", + 64: "Limit stop not found", + 65: "S drive initialization failed", + 66: "S drive not initialized", + 67: "S drive movement error", + 68: "S drive position out of permitted area", + 69: "Init. position adjustment error", + 70: "No liquid level found", + 71: "Not enough liquid present", + 74: "Liquid at a not allowed position detected", + 75: "No tip picked up", + 76: "Tip already picked up", + 77: "Tip not discarded", + 78: "Wrong tip detected", + 79: "Tip not correct squeezed", + 80: "Liquid not correctly aspirated", + 81: "Clot detected", + 82: "TADM measurement out of lower limit curve", + 83: "TADM measurement out of upper limit curve", + 84: "Not enough memory for TADM measurement", + 85: "Jet dispense pressure not reached", + 86: "ADC algorithm error", + 90: "Limit curve not resetable", + 91: "Limit curve not programmable", + 92: "Limit curve name not found", + 93: "Limit curve data incorrect", + 94: "Not enough memory for limit curve", + 95: "Not allowed limit curve index", + 96: "Limit curve already stored", } ipg_errors = { 0: "No error", - 22: "Drive controller message error", - 23: "EC drive controller setup not executed", - 25: "Wrong Flash EPROM data", - 26: "Flash EPROM not programmable", - 27: "Flash EPROM not erasable", - 28: "Flash EPROM checksum error", - 29: "Wrong FW loaded", - 30: "Undefined command", - 31: "Undefined parameter", - 32: "Parameter out of range", - 35: "Voltages out of range", - 36: "Stop during command execution", - 37: "Adjustment sensor didn't switch (no teach in signal)", - 39: "Angle alignment offset error", - 40: "No parallel processes on level 1 permitted", - 41: "No parallel processes on level 2 permitted", - 42: "No parallel processes on level 3 permitted", - 50: "Y Drive initialization failed", - 51: "Y Drive not initialized", - 52: "Y Drive movement error", - 53: "Y Drive position out of permitted area", - 54: "Diff. motion controller and lin. encoder counter too high", - 55: "Z Drive initialization failed", - 56: "Z Drive not initialized", - 57: "Z Drive movement error", - 58: "Z Drive position out of permitted area", - 59: "Z Drive limit stop not found", - 60: "Rotation Drive initialization failed", - 61: "Rotation Drive not initialized", - 62: "Rotation Drive movement error", - 63: "Rotation Drive position out of permitted area", - 65: "Wrist Twist Drive initialization failed", - 66: "Wrist Twist Drive not initialized", - 67: "Wrist Twist Drive movement error", - 68: "Wrist Twist Drive position out of permitted area", - 70: "Gripper Drive initialization failed", - 71: "Gripper Drive not initialized", - 72: "Gripper Drive movement error", - 73: "Gripper Drive position out of permitted area", - 80: "Plate not found", - 81: "Plate is still held", - 82: "No plate is held", + 22: "Drive controller message error", + 23: "EC drive controller setup not executed", + 25: "Wrong Flash EPROM data", + 26: "Flash EPROM not programmable", + 27: "Flash EPROM not erasable", + 28: "Flash EPROM checksum error", + 29: "Wrong FW loaded", + 30: "Undefined command", + 31: "Undefined parameter", + 32: "Parameter out of range", + 35: "Voltages out of range", + 36: "Stop during command execution", + 37: "Adjustment sensor didn't switch (no teach in signal)", + 39: "Angle alignment offset error", + 40: "No parallel processes on level 1 permitted", + 41: "No parallel processes on level 2 permitted", + 42: "No parallel processes on level 3 permitted", + 50: "Y Drive initialization failed", + 51: "Y Drive not initialized", + 52: "Y Drive movement error", + 53: "Y Drive position out of permitted area", + 54: "Diff. motion controller and lin. encoder counter too high", + 55: "Z Drive initialization failed", + 56: "Z Drive not initialized", + 57: "Z Drive movement error", + 58: "Z Drive position out of permitted area", + 59: "Z Drive limit stop not found", + 60: "Rotation Drive initialization failed", + 61: "Rotation Drive not initialized", + 62: "Rotation Drive movement error", + 63: "Rotation Drive position out of permitted area", + 65: "Wrist Twist Drive initialization failed", + 66: "Wrist Twist Drive not initialized", + 67: "Wrist Twist Drive movement error", + 68: "Wrist Twist Drive position out of permitted area", + 70: "Gripper Drive initialization failed", + 71: "Gripper Drive not initialized", + 72: "Gripper Drive movement error", + 73: "Gripper Drive position out of permitted area", + 80: "Plate not found", + 81: "Plate is still held", + 82: "No plate is held", } @@ -274,18 +259,14 @@ def __str__(self): return f"VantageFirmwareError(errors={self.errors}, raw_response={self.raw_response})" def __eq__(self, __value: object) -> bool: - return ( - isinstance(__value, VantageFirmwareError) - and self.errors == __value.errors - and self.raw_response == __value.raw_response - ) + return isinstance(__value, VantageFirmwareError) and \ + self.errors == __value.errors and \ + self.raw_response == __value.raw_response -def vantage_response_string_to_error( - string: str, -) -> VantageFirmwareError: - """Convert a Vantage firmware response string to a VantageFirmwareError. Assumes that the - response is an error response.""" +def vantage_response_string_to_error(string: str) -> VantageFirmwareError: + """ Convert a Vantage firmware response string to a VantageFirmwareError. Assumes that the + response is an error response. """ try: error_format = r"[A-Z0-9]{2}[0-9]{2}" @@ -314,16 +295,15 @@ def vantage_response_string_to_error( "A1HM": "Core 96", "A1RM": "IPG", "A1AM": "Arm", - "A1XM": "X-arm", + "A1XM": "X-arm" }.get(module_id, "Unknown module") error_string = parse_vantage_fw_string(string, {"et": "str"})["et"] errors = {modules: error_string} return VantageFirmwareError(errors, string) - def _get_dispense_mode(jet: bool, empty: bool, blow_out: bool) -> Literal[0, 1, 2, 3, 4]: - """from docs: + """ from docs: 0 = part in jet 1 = blow in jet (called "empty" in VENUS liquid editor) 2 = Part at surface @@ -340,7 +320,7 @@ def _get_dispense_mode(jet: bool, empty: bool, blow_out: bool) -> Literal[0, 1, class Vantage(HamiltonLiquidHandler): - """A Hamilton Vantage liquid handler.""" + """ A Hamilton Vantage liquid handler. """ def __init__( self, @@ -350,7 +330,7 @@ def __init__( read_timeout: int = 60, write_timeout: int = 30, ): - """Create a new STAR interface. + """ Create a new STAR interface. Args: device_address: the USB device address of the Hamilton Vantage. Only useful if using more than @@ -368,8 +348,7 @@ def __init__( read_timeout=read_timeout, write_timeout=write_timeout, id_product=0x8003, - serial_number=serial_number, - ) + serial_number=serial_number) self._iswap_parked: Optional[bool] = None self._num_channels: Optional[int] = None @@ -377,33 +356,31 @@ def __init__( @property def module_id_length(self) -> int: - return 4 + return 4 def get_id_from_fw_response(self, resp: str) -> Optional[int]: - """Get the id from a firmware response.""" + """ Get the id from a firmware response. """ parsed = parse_vantage_fw_string(resp, {"id": "int"}) if "id" in parsed and parsed["id"] is not None: return int(parsed["id"]) return None def check_fw_string_error(self, resp: str): - """Raise an error if the firmware response is an error response.""" + """ Raise an error if the firmware response is an error response. """ - if "er" in resp and "er0" not in resp: + if "er" in resp and not "er0" in resp: error = vantage_response_string_to_error(resp) raise error def _parse_response(self, resp: str, fmt: Dict[str, str]) -> dict: - """Parse a firmware response.""" + """ Parse a firmware response. """ return parse_vantage_fw_string(resp, fmt) - async def setup( - self, - skip_loading_cover: bool = False, - skip_core96: bool = False, - skip_ipg: bool = False, - ): - """Creates a USB connection and finds read/write interfaces.""" + async def setup(self): + """ setup + + Creates a USB connection and finds read/write interfaces. + """ await super().setup() @@ -419,46 +396,45 @@ async def setup( pip_channels_initialized = await self.pip_request_initialization_status() if not pip_channels_initialized or any(tip_presences): await self.pip_initialize( - x_position=[7095] * self.num_channels, + x_position=[7095]*self.num_channels, y_position=[3891, 3623, 3355, 3087, 2819, 2551, 2283, 2016], begin_z_deposit_position=[int(self._traversal_height * 10)] * self.num_channels, end_z_deposit_position=[1235] * self.num_channels, minimal_height_at_command_end=[int(self._traversal_height * 10)] * self.num_channels, - tip_pattern=[True] * self.num_channels, - tip_type=[1] * self.num_channels, - TODO_DI_2=70, + tip_pattern=[True]*self.num_channels, + tip_type=[1]*self.num_channels, + TODO_DI_2=70 ) loading_cover_initialized = await self.loading_cover_request_initialization_status() - if not loading_cover_initialized and not skip_loading_cover: + if not loading_cover_initialized: await self.loading_cover_initialize() core96_initialized = await self.core96_request_initialization_status() - if not core96_initialized and not skip_core96: + if not core96_initialized: await self.core96_initialize( - x_position=7347, # TODO: get trash location from deck. - y_position=2684, # TODO: get trash location from deck. + x_position=7347, # TODO: get trash location from deck. + y_position=2684, # TODO: get trash location from deck. minimal_traverse_height_at_begin_of_command=int(self._traversal_height * 10), minimal_height_at_command_end=int(self._traversal_height * 10), end_z_deposit_position=2420, ) - if not skip_ipg: - ipg_initialized = await self.ipg_request_initialization_status() - if not ipg_initialized: - await self.ipg_initialize() - if not await self.ipg_get_parking_status(): - await self.ipg_park() + ipg_initialized = await self.ipg_request_initialization_status() + if not ipg_initialized: + await self.ipg_initialize() + if not await self.ipg_get_parking_status(): + await self.ipg_park() @property def num_channels(self) -> int: - """The number of channels on the robot.""" + """ The number of channels on the robot. """ if self._num_channels is None: raise RuntimeError("num_channels is not set.") return self._num_channels def set_minimum_traversal_height(self, traversal_height: float): - """Set the minimum traversal height for the robot. + """ Set the minimum traversal height for the robot. This refers to the bottom of the pipetting channel when no tip is present, or the bottom of the tip when a tip is present. This value will be used as the default value for the @@ -479,14 +455,15 @@ async def pick_up_tips( minimal_traverse_height_at_begin_of_command: Optional[List[float]] = None, minimal_height_at_command_end: Optional[List[float]] = None, ): - x_positions, y_positions, tip_pattern = self._ops_to_fw_positions(ops, use_channels) + x_positions, y_positions, tip_pattern = \ + self._ops_to_fw_positions(ops, use_channels) tips = [cast(HamiltonTip, op.resource.get_tip()) for op in ops] ttti = await self.get_ttti(tips) max_z = max(op.resource.get_absolute_location().z + op.offset.z for op in ops) max_total_tip_length = max(op.tip.total_tip_length for op in ops) - max_tip_length = max((op.tip.total_tip_length - op.tip.fitting_depth) for op in ops) + max_tip_length = max((op.tip.total_tip_length-op.tip.fitting_depth) for op in ops) # not sure why this is necessary, but it is according to log files and experiments if self._get_hamilton_tip([op.resource for op in ops]).tip_size == TipSize.LOW_VOLUME: @@ -500,19 +477,16 @@ async def pick_up_tips( y_position=y_positions, tip_pattern=tip_pattern, tip_type=ttti, - begin_z_deposit_position=[round((max_z + max_total_tip_length) * 10)] * len(ops), - end_z_deposit_position=[round((max_z + max_tip_length) * 10)] * len(ops), - minimal_traverse_height_at_begin_of_command=[ - round(th * 10) - for th in minimal_traverse_height_at_begin_of_command or [self._traversal_height] - ] - * len(ops), - minimal_height_at_command_end=[ - round(th * 10) for th in minimal_height_at_command_end or [self._traversal_height] - ] - * len(ops), - tip_handling_method=[1 for _ in tips], # always appears to be 1 # tip.pickup_method.value - blow_out_air_volume=[0] * len(ops), # Why is this here? Who knows. + begin_z_deposit_position=[round((max_z + max_total_tip_length)*10)]*len(ops), + end_z_deposit_position=[round((max_z + max_tip_length)*10)]*len(ops), + minimal_traverse_height_at_begin_of_command= + [round(th*10) for th in minimal_traverse_height_at_begin_of_command or + [self._traversal_height]]*len(ops), + minimal_height_at_command_end= + [round(th*10) for th in minimal_height_at_command_end or + [self._traversal_height]]*len(ops), + tip_handling_method=[1 for _ in tips], # always appears to be 1 # tip.pickup_method.value + blow_out_air_volume=[0]*len(ops), # Why is this here? Who knows. ) except Exception as e: raise e @@ -525,9 +499,10 @@ async def drop_tips( minimal_traverse_height_at_begin_of_command: Optional[List[float]] = None, minimal_height_at_command_end: Optional[List[float]] = None, ): - """Drop tips to a resource.""" + """ Drop tips to a resource. """ - x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) + x_positions, y_positions, channels_involved = \ + self._ops_to_fw_positions(ops, use_channels) max_z = max(op.resource.get_absolute_location().z + op.offset.z for op in ops) @@ -536,18 +511,15 @@ async def drop_tips( x_position=x_positions, y_position=y_positions, tip_pattern=channels_involved, - begin_z_deposit_position=[round((max_z + 10) * 10)] * len(ops), # +10 - end_z_deposit_position=[round(max_z * 10)] * len(ops), - minimal_traverse_height_at_begin_of_command=[ - round(th * 10) - for th in minimal_traverse_height_at_begin_of_command or [self._traversal_height] - ] - * len(ops), - minimal_height_at_command_end=[ - round(th * 10) for th in minimal_height_at_command_end or [self._traversal_height] - ] - * len(ops), - tip_handling_method=[0 for _ in ops], # Always appears to be 0, even in trash. + begin_z_deposit_position=[round((max_z+10)*10)]*len(ops), # +10 + end_z_deposit_position=[round(max_z*10)]*len(ops), + minimal_traverse_height_at_begin_of_command= + [round(th*10) for th in minimal_traverse_height_at_begin_of_command or + [self._traversal_height]]*len(ops), + minimal_height_at_command_end= + [round(th*10) for th in minimal_height_at_command_end or + [self._traversal_height]]*len(ops), + tip_handling_method=[0 for _ in ops], # Always appears to be 0, even in trash. # tip_handling_method=[TipDropMethod.DROP.value if isinstance(op.resource, TipSpot) \ # else TipDropMethod.PLACE_SHIFT.value for op in ops], TODO_TR_2=0, @@ -556,20 +528,20 @@ async def drop_tips( raise e def _assert_valid_resources(self, resources: Sequence[Resource]) -> None: - """Assert that resources are in a valid location for pipetting.""" + """ Assert that resources are in a valid location for pipetting. """ for resource in resources: if resource.get_absolute_location().z < 100: raise ValueError( - f"Resource {resource} is too low: {resource.get_absolute_location().z} < 100" - ) + f"Resource {resource} is too low: {resource.get_absolute_location().z} < 100") async def aspirate( self, - ops: List[SingleChannelAspiration], + ops: List[Aspiration], use_channels: List[int], jet: Optional[List[bool]] = None, blow_out: Optional[List[bool]] = None, hlcs: Optional[List[Optional[HamiltonLiquidClass]]] = None, + type_of_aspiration: Optional[List[int]] = None, minimal_traverse_height_at_begin_of_command: Optional[List[float]] = None, minimal_height_at_command_end: Optional[List[float]] = None, @@ -602,7 +574,7 @@ async def aspirate( limit_curve_index: Optional[List[int]] = None, recording_mode: int = 0, ): - """Aspirate from (a) resource(s). + """ Aspirate from (a) resource(s). See :meth:`pip_aspirate` (the firmware command) for parameter documentation. This method serves as a wrapper for that command, and will convert operations into the appropriate format. This @@ -615,143 +587,94 @@ async def aspirate( blow_out: Whether to search for a "blow out" liquid class. This is only used on dispense. Note that in the VENUS liquid editor, the term "empty" is used for this, but in the firmware documentation, "empty" is used for a different mode (dm4). - hlcs: The Hamiltonian liquid classes to use. If `None`, the liquid classes will be - determined automatically based on the tip and liquid used. """ - x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) + if hlcs is not None: + raise NotImplementedError("hlcs is deprecated") + + x_positions, y_positions, channels_involved = \ + self._ops_to_fw_positions(ops, use_channels) if jet is None: - jet = [False] * len(ops) + jet = [False]*len(ops) if blow_out is None: - blow_out = [False] * len(ops) - - if hlcs is None: - hlcs = [] - for j, bo, op in zip(jet, blow_out, ops): - liquid = Liquid.WATER # default to WATER - # [-1][0]: get last liquid in well, [0] is indexing into the tuple - if len(op.liquids) > 0 and op.liquids[-1][0] is not None: - liquid = op.liquids[-1][0] - hlcs.append( - get_vantage_liquid_class( - tip_volume=op.tip.maximal_volume, - is_core=False, - is_tip=True, - has_filter=op.tip.has_filter, - liquid=liquid, - jet=j, - blow_out=bo, - ) - ) + blow_out = [False]*len(ops) self._assert_valid_resources([op.resource for op in ops]) - # correct volumes using the liquid class - volumes = [ - hlc.compute_corrected_volume(op.volume) if hlc is not None else op.volume - for op, hlc in zip(ops, hlcs) - ] - - well_bottoms = [ - op.resource.get_absolute_location().z + op.offset.z + op.resource.material_z_thickness - for op in ops - ] - liquid_surfaces_no_lld = liquid_surface_at_function_without_lld or [ - wb + (op.liquid_height or 0) for wb, op in zip(well_bottoms, ops) - ] + well_bottoms = [op.resource.get_absolute_location().z + op.offset.z + \ + op.resource.material_z_thickness for op in ops] + liquid_surfaces_no_lld = liquid_surface_at_function_without_lld or [wb + (op.liquid_height or 0) + for wb, op in zip(well_bottoms, ops)] # -1 compared to STAR? - lld_search_heights = lld_search_height or [ - wb - + op.resource.get_absolute_size_z() - + (2.7 - 1 if isinstance(op.resource, Well) else 5) # ? - for wb, op in zip(well_bottoms, ops) - ] - - flow_rates = [ - op.flow_rate or (hlc.aspiration_flow_rate if hlc is not None else 100) - for op, hlc in zip(ops, hlcs) - ] - blow_out_air_volumes = [ - (op.blow_out_air_volume or (hlc.dispense_blow_out_volume if hlc is not None else 0)) - for op, hlc in zip(ops, hlcs) - ] + lld_search_heights = lld_search_height or [wb + op.resource.get_absolute_size_z() + \ + (2.7-1 if isinstance(op.resource, Well) else 5) #? + for wb, op in zip(well_bottoms, ops)] + + flow_rates = [op.flow_rate or 100 for op in ops] + blow_out_air_volumes = [op.blow_out_air_volume or 0 for op in ops] return await self.pip_aspirate( x_position=x_positions, y_position=y_positions, - type_of_aspiration=type_of_aspiration or [0] * len(ops), + type_of_aspiration=type_of_aspiration or [0]*len(ops), tip_pattern=channels_involved, - minimal_traverse_height_at_begin_of_command=[ - round(th * 10) - for th in minimal_traverse_height_at_begin_of_command or [self._traversal_height] - ] - * len(ops), - minimal_height_at_command_end=[ - round(th * 10) for th in minimal_height_at_command_end or [self._traversal_height] - ] - * len(ops), - lld_search_height=[round(ls * 10) for ls in lld_search_heights], - clot_detection_height=[round(cdh * 10) for cdh in clot_detection_height or [0] * len(ops)], + minimal_traverse_height_at_begin_of_command= + [round(th*10) for th in minimal_traverse_height_at_begin_of_command or + [self._traversal_height]]*len(ops), + minimal_height_at_command_end= + [round(th*10) for th in minimal_height_at_command_end or + [self._traversal_height]]*len(ops), + lld_search_height=[round(ls*10) for ls in lld_search_heights], + clot_detection_height=[round(cdh*10) for cdh in clot_detection_height or [0]*len(ops)], liquid_surface_at_function_without_lld=[round(lsn * 10) for lsn in liquid_surfaces_no_lld], - pull_out_distance_to_take_transport_air_in_function_without_lld=[ - round(pod * 10) - for pod in pull_out_distance_to_take_transport_air_in_function_without_lld - or [10.9] * len(ops) - ], - tube_2nd_section_height_measured_from_zm=[ - round(t2sh * 10) for t2sh in tube_2nd_section_height_measured_from_zm or [0] * len(ops) - ], - tube_2nd_section_ratio=[ - round(t2sr * 10) for t2sr in tube_2nd_section_ratio or [0] * len(ops) - ], + pull_out_distance_to_take_transport_air_in_function_without_lld=\ + [round(pod*10) for pod in pull_out_distance_to_take_transport_air_in_function_without_lld or + [10.9]*len(ops)], + tube_2nd_section_height_measured_from_zm= + [round(t2sh*10) for t2sh in tube_2nd_section_height_measured_from_zm or [0]*len(ops)], + tube_2nd_section_ratio=[round(t2sr*10) for t2sr in tube_2nd_section_ratio or [0]*len(ops)], minimum_height=[round(wb * 10) for wb in minimum_height or well_bottoms], - immersion_depth=[round(id_ * 10) for id_ in immersion_depth or [0] * len(ops)], - surface_following_distance=[ - round(sfd * 10) for sfd in surface_following_distance or [0] * len(ops) - ], - aspiration_volume=[round(vol * 100) for vol in volumes], + immersion_depth=[round(id_*10) for id_ in immersion_depth or [0]*len(ops)], + surface_following_distance=[round(sfd*10) for sfd in surface_following_distance or + [0]*len(ops)], + aspiration_volume=[round(op.volume*100) for op in ops], aspiration_speed=[round(fr * 10) for fr in flow_rates], - transport_air_volume=[ - round(tav * 10) - for tav in transport_air_volume - or [hlc.aspiration_air_transport_volume if hlc is not None else 0 for hlc in hlcs] - ], - blow_out_air_volume=[round(bav * 100) for bav in blow_out_air_volumes], - pre_wetting_volume=[round(pwv * 100) for pwv in pre_wetting_volume or [0] * len(ops)], - lld_mode=lld_mode or [0] * len(ops), - lld_sensitivity=lld_sensitivity or [4] * len(ops), - pressure_lld_sensitivity=pressure_lld_sensitivity or [4] * len(ops), - aspirate_position_above_z_touch_off=[ - round(apz * 10) for apz in aspirate_position_above_z_touch_off or [0.5] * len(ops) - ], - swap_speed=[round(ss * 10) for ss in swap_speed or [2] * len(ops)], - settling_time=[round(st * 10) for st in settling_time or [1] * len(ops)], - mix_volume=[round(mv * 100) for mv in mix_volume or [0] * len(ops)], - mix_cycles=mix_cycles or [0] * len(ops), - mix_position_in_z_direction_from_liquid_surface=[ - round(mp) for mp in mix_position_in_z_direction_from_liquid_surface or [0] * len(ops) - ], - mix_speed=[round(ms * 10) for ms in mix_speed or [250] * len(ops)], - surface_following_distance_during_mixing=[ - round(sfdm * 10) for sfdm in surface_following_distance_during_mixing or [0] * len(ops) - ], - TODO_DA_5=TODO_DA_5 or [0] * len(ops), - capacitive_mad_supervision_on_off=capacitive_mad_supervision_on_off or [0] * len(ops), - pressure_mad_supervision_on_off=pressure_mad_supervision_on_off or [0] * len(ops), + transport_air_volume=[round(tav*10) for tav in transport_air_volume or [0]*len(ops)], + blow_out_air_volume=[round(bav*100) for bav in blow_out_air_volumes], + pre_wetting_volume=[round(pwv*100) for pwv in pre_wetting_volume or [0]*len(ops)], + lld_mode=lld_mode or [0]*len(ops), + lld_sensitivity=lld_sensitivity or [4]*len(ops), + pressure_lld_sensitivity=pressure_lld_sensitivity or [4]*len(ops), + aspirate_position_above_z_touch_off= + [round(apz*10) for apz in aspirate_position_above_z_touch_off or [0.5]*len(ops)], + swap_speed=[round(ss*10) for ss in swap_speed or [2]*len(ops)], + settling_time=[round(st*10) for st in settling_time or [1]*len(ops)], + mix_volume=[round(mv*100) for mv in mix_volume or [0]*len(ops)], + mix_cycles=mix_cycles or [0]*len(ops), + mix_position_in_z_direction_from_liquid_surface= + [round(mp) for mp in mix_position_in_z_direction_from_liquid_surface or [0]*len(ops)], + mix_speed=[round(ms*10) for ms in mix_speed or [250]*len(ops)], + surface_following_distance_during_mixing= + [round(sfdm*10) for sfdm in surface_following_distance_during_mixing or [0]*len(ops)], + TODO_DA_5=TODO_DA_5 or [0]*len(ops), + capacitive_mad_supervision_on_off=capacitive_mad_supervision_on_off or [0]*len(ops), + pressure_mad_supervision_on_off=pressure_mad_supervision_on_off or [0]*len(ops), tadm_algorithm_on_off=tadm_algorithm_on_off or 0, - limit_curve_index=limit_curve_index or [0] * len(ops), + limit_curve_index=limit_curve_index or [0]*len(ops), recording_mode=recording_mode or 0, ) async def dispense( self, - ops: List[SingleChannelDispense], + ops: List[Dispense], use_channels: List[int], + jet: Optional[List[bool]] = None, - blow_out: Optional[List[bool]] = None, # "empty" in the VENUS liquid editor - empty: Optional[List[bool]] = None, # truly "empty", does not exist in liquid editor, dm4 + blow_out: Optional[List[bool]] = None, # "empty" in the VENUS liquid editor + empty: Optional[List[bool]] = None, # truly "empty", does not exist in liquid editor, dm4 hlcs: Optional[List[Optional[HamiltonLiquidClass]]] = None, + type_of_dispensing_mode: Optional[List[int]] = None, minimum_height: Optional[List[float]] = None, pull_out_distance_to_take_transport_air_in_function_without_lld: Optional[List[float]] = None, @@ -782,7 +705,7 @@ async def dispense( limit_curve_index: Optional[List[int]] = None, recording_mode: int = 0, ): - """Dispense to (a) resource(s). + """ Dispense to (a) resource(s). See :meth:`pip_dispense` (the firmware command) for parameter documentation. This method serves as a wrapper for that command, and will convert operations into the appropriate format. This @@ -792,8 +715,6 @@ async def dispense( Args: ops: The aspiration operations. use_channels: The channels to use. - hlcs: The Hamiltonian liquid classes to use. If `None`, the liquid classes will be - determined automatically based on the tip and liquid used. jet: Whether to use jetting for each dispense. Defaults to `False` for all. Used for determining the dispense mode. True for dispense mode 0 or 1. @@ -805,132 +726,84 @@ async def dispense( documentation. Dispense mode 4. """ - x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) + if hlcs is not None: + raise NotImplementedError("hlcs is deprecated") + + x_positions, y_positions, channels_involved = \ + self._ops_to_fw_positions(ops, use_channels) if jet is None: - jet = [False] * len(ops) + jet = [False]*len(ops) if empty is None: - empty = [False] * len(ops) + empty = [False]*len(ops) if blow_out is None: - blow_out = [False] * len(ops) - - if hlcs is None: - hlcs = [] - for j, bo, op in zip(jet, blow_out, ops): - liquid = Liquid.WATER # default to WATER - # [-1][0]: get last liquid in tip, [0] is indexing into the tuple - if len(op.liquids) > 0 and op.liquids[-1][0] is not None: - liquid = op.liquids[-1][0] - hlcs.append( - get_vantage_liquid_class( - tip_volume=op.tip.maximal_volume, - is_core=False, - is_tip=True, - has_filter=op.tip.has_filter, - liquid=liquid, - jet=j, - blow_out=bo, - ) - ) + blow_out = [False]*len(ops) self._assert_valid_resources([op.resource for op in ops]) - # correct volumes using the liquid class - volumes = [ - hlc.compute_corrected_volume(op.volume) if hlc is not None else op.volume - for op, hlc in zip(ops, hlcs) - ] - - well_bottoms = [ - op.resource.get_absolute_location().z + op.offset.z + op.resource.material_z_thickness - for op in ops - ] - liquid_surfaces_no_lld = [wb + (op.liquid_height or 0) for wb, op in zip(well_bottoms, ops)] + well_bottoms = [op.resource.get_absolute_location().z + op.offset.z + \ + op.resource.material_z_thickness for op in ops] + liquid_surfaces_no_lld = [wb + (op.liquid_height or 0) + for wb, op in zip(well_bottoms, ops)] # -1 compared to STAR? - lld_search_heights = lld_search_height or [ - wb - + op.resource.get_absolute_size_z() - + (2.7 - 1 if isinstance(op.resource, Well) else 5) # ? - for wb, op in zip(well_bottoms, ops) - ] - - flow_rates = [ - op.flow_rate or (hlc.dispense_flow_rate if hlc is not None else 100) - for op, hlc in zip(ops, hlcs) - ] - - blow_out_air_volumes = [ - (op.blow_out_air_volume or (hlc.dispense_blow_out_volume if hlc is not None else 0)) - for op, hlc in zip(ops, hlcs) - ] - - type_of_dispensing_mode = type_of_dispensing_mode or [ - _get_dispense_mode(jet=jet[i], empty=empty[i], blow_out=blow_out[i]) for i in range(len(ops)) - ] + lld_search_heights = lld_search_height or [wb + op.resource.get_absolute_size_z() + \ + (2.7-1 if isinstance(op.resource, Well) else 5) #? + for wb, op in zip(well_bottoms, ops)] + + flow_rates = [op.flow_rate or 100 for op in ops] + + blow_out_air_volumes = [op.blow_out_air_volume or 0 for op in ops] + + type_of_dispensing_mode = type_of_dispensing_mode or \ + [_get_dispense_mode(jet=jet[i], empty=empty[i], blow_out=blow_out[i]) + for i in range(len(ops))] return await self.pip_dispense( x_position=x_positions, y_position=y_positions, tip_pattern=channels_involved, type_of_dispensing_mode=type_of_dispensing_mode, - minimum_height=[round(wb * 10) for wb in minimum_height or well_bottoms], - lld_search_height=[round(sh * 10) for sh in lld_search_heights], - liquid_surface_at_function_without_lld=[round(ls * 10) for ls in liquid_surfaces_no_lld], - pull_out_distance_to_take_transport_air_in_function_without_lld=[ - round(pod * 10) - for pod in pull_out_distance_to_take_transport_air_in_function_without_lld - or [5.0] * len(ops) - ], - immersion_depth=[round(id * 10) for id in immersion_depth or [0] * len(ops)], - surface_following_distance=[ - round(sfd * 10) for sfd in surface_following_distance or [2.1] * len(ops) - ], - tube_2nd_section_height_measured_from_zm=[ - round(t2sh * 10) for t2sh in tube_2nd_section_height_measured_from_zm or [0] * len(ops) - ], - tube_2nd_section_ratio=[ - round(t2sr * 10) for t2sr in tube_2nd_section_ratio or [0] * len(ops) - ], - minimal_traverse_height_at_begin_of_command=[ - round(mth * 10) - for mth in minimal_traverse_height_at_begin_of_command - or [self._traversal_height] * len(ops) - ], - minimal_height_at_command_end=[ - round(mh * 10) - for mh in minimal_height_at_command_end or [self._traversal_height] * len(ops) - ], - dispense_volume=[round(vol * 100) for vol in volumes], - dispense_speed=[round(fr * 10) for fr in flow_rates], - cut_off_speed=[round(cs * 10) for cs in cut_off_speed or [250] * len(ops)], - stop_back_volume=[round(sbv * 100) for sbv in stop_back_volume or [0] * len(ops)], - transport_air_volume=[ - round(tav * 10) - for tav in transport_air_volume - or [hlc.dispense_air_transport_volume if hlc is not None else 0 for hlc in hlcs] - ], - blow_out_air_volume=[round(boav * 100) for boav in blow_out_air_volumes], - lld_mode=lld_mode or [0] * len(ops), - side_touch_off_distance=round(side_touch_off_distance * 10), - dispense_position_above_z_touch_off=[ - round(dpz * 10) for dpz in dispense_position_above_z_touch_off or [0.5] * len(ops) - ], - lld_sensitivity=lld_sensitivity or [1] * len(ops), - pressure_lld_sensitivity=pressure_lld_sensitivity or [1] * len(ops), - swap_speed=[round(ss * 10) for ss in swap_speed or [1] * len(ops)], - settling_time=[round(st * 10) for st in settling_time or [0] * len(ops)], - mix_volume=[round(mv * 100) for mv in mix_volume or [0] * len(ops)], - mix_cycles=mix_cycles or [0] * len(ops), - mix_position_in_z_direction_from_liquid_surface=[ - round(mp) for mp in mix_position_in_z_direction_from_liquid_surface or [0] * len(ops) - ], - mix_speed=[round(ms * 10) for ms in mix_speed or [1] * len(ops)], - surface_following_distance_during_mixing=[ - round(sfdm * 10) for sfdm in surface_following_distance_during_mixing or [0] * len(ops) - ], - TODO_DD_2=TODO_DD_2 or [0] * len(ops), + minimum_height=[round(wb*10) for wb in minimum_height or well_bottoms], + lld_search_height=[round(sh*10) for sh in lld_search_heights], + liquid_surface_at_function_without_lld=[round(ls*10) for ls in liquid_surfaces_no_lld], + pull_out_distance_to_take_transport_air_in_function_without_lld= + [round(pod*10) for pod in pull_out_distance_to_take_transport_air_in_function_without_lld or + [5.0]*len(ops)], + immersion_depth=[round(id*10) for id in immersion_depth or [0]*len(ops)], + surface_following_distance= + [round(sfd*10) for sfd in surface_following_distance or [2.1]*len(ops)], + tube_2nd_section_height_measured_from_zm= + [round(t2sh*10) for t2sh in tube_2nd_section_height_measured_from_zm or [0]*len(ops)], + tube_2nd_section_ratio=[round(t2sr*10) for t2sr in tube_2nd_section_ratio or [0]*len(ops)], + minimal_traverse_height_at_begin_of_command= + [round(mth*10) for mth in + minimal_traverse_height_at_begin_of_command or [self._traversal_height]*len(ops)], + minimal_height_at_command_end= + [round(mh*10) for mh in minimal_height_at_command_end or [self._traversal_height]*len(ops)], + dispense_volume=[round(op.volume*100) for op in ops], + dispense_speed=[round(fr*10) for fr in flow_rates], + cut_off_speed=[round(cs*10) for cs in cut_off_speed or [250]*len(ops)], + stop_back_volume=[round(sbv*100) for sbv in stop_back_volume or [0]*len(ops)], + transport_air_volume=[round(tav*10) for tav in transport_air_volume or [0]*len(ops)], + blow_out_air_volume=[round(boav*100) for boav in blow_out_air_volumes], + lld_mode=lld_mode or [0]*len(ops), + side_touch_off_distance=round(side_touch_off_distance*10), + dispense_position_above_z_touch_off= + [round(dpz*10) for dpz in dispense_position_above_z_touch_off or [0.5]*len(ops)], + lld_sensitivity=lld_sensitivity or [1]*len(ops), + pressure_lld_sensitivity=pressure_lld_sensitivity or [1]*len(ops), + swap_speed=[round(ss*10) for ss in swap_speed or [1]*len(ops)], + settling_time=[round(st*10) for st in settling_time or [0]*len(ops)], + mix_volume=[round(mv*100) for mv in mix_volume or [0]*len(ops)], + mix_cycles=mix_cycles or [0]*len(ops), + mix_position_in_z_direction_from_liquid_surface= + [round(mp) for mp in mix_position_in_z_direction_from_liquid_surface or [0]*len(ops)], + mix_speed=[round(ms*10) for ms in mix_speed or [1]*len(ops)], + surface_following_distance_during_mixing= + [round(sfdm*10) for sfdm in surface_following_distance_during_mixing or [0]*len(ops)], + TODO_DD_2=TODO_DD_2 or [0]*len(ops), tadm_algorithm_on_off=tadm_algorithm_on_off or 0, - limit_curve_index=limit_curve_index or [0] * len(ops), + limit_curve_index=limit_curve_index or [0]*len(ops), recording_mode=recording_mode or 0, ) @@ -940,7 +813,7 @@ async def pick_up_tips96( tip_handling_method: int = 0, z_deposit_position: float = 216.4, minimal_traverse_height_at_begin_of_command: Optional[float] = None, - minimal_height_at_command_end: Optional[float] = None, + minimal_height_at_command_end: Optional[float] = None ): # assert self.core96_head_installed, "96 head must be installed" tip_spot_a1 = pickup.resource.get_item("A1") @@ -956,12 +829,10 @@ async def pick_up_tips96( tip_type=ttti, tip_handling_method=tip_handling_method, z_deposit_position=round((z_deposit_position + offset_z) * 10), - minimal_traverse_height_at_begin_of_command=round( - (minimal_traverse_height_at_begin_of_command or self._traversal_height) * 10 - ), - minimal_height_at_command_end=round( - (minimal_height_at_command_end or self._traversal_height) * 10 - ), + minimal_traverse_height_at_begin_of_command= + round((minimal_traverse_height_at_begin_of_command or self._traversal_height) * 10), + minimal_height_at_command_end= + round((minimal_height_at_command_end or self._traversal_height)*10) ) async def drop_tips96( @@ -969,37 +840,34 @@ async def drop_tips96( drop: DropTipRack, z_deposit_position: float = 216.4, minimal_traverse_height_at_begin_of_command: Optional[float] = None, - minimal_height_at_command_end: Optional[float] = None, + minimal_height_at_command_end: Optional[float] = None ): # assert self.core96_head_installed, "96 head must be installed" if isinstance(drop.resource, TipRack): tip_spot_a1 = drop.resource.get_item("A1") position = tip_spot_a1.get_absolute_location() + tip_spot_a1.center() + drop.offset else: - raise NotImplementedError( - "Only TipRacks are supported for dropping tips on Vantage", - f"got {drop.resource}", - ) + raise NotImplementedError("Only TipRacks are supported for dropping tips on Vantage", + f"got {drop.resource}") offset_z = drop.offset.z return await self.core96_tip_discard( x_position=round(position.x * 10), y_position=round(position.y * 10), z_deposit_position=round((z_deposit_position + offset_z) * 10), - minimal_traverse_height_at_begin_of_command=round( - (minimal_traverse_height_at_begin_of_command or self._traversal_height) * 10 - ), - minimal_height_at_command_end=round( - (minimal_height_at_command_end or self._traversal_height) * 10 - ), + minimal_traverse_height_at_begin_of_command= + round((minimal_traverse_height_at_begin_of_command or self._traversal_height) * 10), + minimal_height_at_command_end= + round((minimal_height_at_command_end or self._traversal_height)*10) ) async def aspirate96( self, - aspiration: Union[MultiHeadAspirationPlate, MultiHeadAspirationContainer], + aspiration: Union[AspirationPlate, AspirationContainer], jet: bool = False, blow_out: bool = False, hlc: Optional[HamiltonLiquidClass] = None, + type_of_aspiration: int = 0, minimal_traverse_height_at_begin_of_command: Optional[float] = None, minimal_height_at_command_end: Optional[float] = None, @@ -1025,108 +893,75 @@ async def aspirate96( tadm_algorithm_on_off: int = 0, recording_mode: int = 0, ): - """Aspirate from a plate. + """ Aspirate from a plate. Args: jet: Whether to find a liquid class with "jet" mode. Only used on dispense. blow_out: Whether to find a liquid class with "blow out" mode. Only used on dispense. Note that this is called "empty" in the VENUS liquid editor, but "blow out" in the firmware documentation. - hlc: The Hamiltonian liquid classes to use. If `None`, the liquid classes will be - determined automatically based on the tip and liquid used in the first well. """ # assert self.core96_head_installed, "96 head must be installed" - if isinstance(aspiration, MultiHeadAspirationPlate): + if jet is not None or blow_out is not None: + raise NotImplementedError("jet and blow out are not implemented for aspirate96 yet") + + if hlc is not None: + raise NotImplementedError("hlc is deprecated") + + if isinstance(aspiration, AspirationPlate): top_left_well = aspiration.wells[0] - position = ( - top_left_well.get_absolute_location() - + top_left_well.center() - + aspiration.offset - + Coordinate(z=top_left_well.material_z_thickness) - ) + position = top_left_well.get_absolute_location() + top_left_well.center() + \ + aspiration.offset + Coordinate(z=top_left_well.material_z_thickness) # -1 compared to STAR? well_bottoms = position.z - lld_search_height = well_bottoms + top_left_well.get_absolute_size_z() + 2.7 - 1 + lld_search_height = well_bottoms + top_left_well.get_absolute_size_z() + 2.7-1 else: - position = ( - aspiration.container.get_absolute_location(y="b") - + aspiration.offset - + Coordinate(z=aspiration.container.material_z_thickness) - ) + position = aspiration.container.get_absolute_location(y="b") + aspiration.offset + \ + Coordinate(z=aspiration.container.material_z_thickness) bottom = position.z - lld_search_height = bottom + aspiration.container.get_absolute_size_z() + 2.7 - 1 + lld_search_height = bottom + aspiration.container.get_absolute_size_z() + 2.7-1 liquid_height = position.z + (aspiration.liquid_height or 0) - tip = aspiration.tips[0] - liquid_to_be_aspirated = Liquid.WATER # default to water - if len(aspiration.liquids[0]) > 0 and aspiration.liquids[0][-1][0] is not None: - # first part of tuple in last liquid of first well - liquid_to_be_aspirated = aspiration.liquids[0][-1][0] - if hlc is None: - hlc = get_vantage_liquid_class( - tip_volume=tip.maximal_volume, - is_core=True, - is_tip=True, - has_filter=tip.has_filter, - liquid=liquid_to_be_aspirated, - jet=jet, - blow_out=blow_out, - ) - - volume = ( - hlc.compute_corrected_volume(aspiration.volume) if hlc is not None else aspiration.volume - ) - - transport_air_volume = transport_air_volume or ( - hlc.aspiration_air_transport_volume if hlc is not None else 0 - ) - blow_out_air_volume = blow_out_air_volume or ( - hlc.aspiration_blow_out_volume if hlc is not None else 0 - ) - flow_rate = aspiration.flow_rate or (hlc.aspiration_flow_rate if hlc is not None else 250) - swap_speed = swap_speed or (hlc.aspiration_swap_speed if hlc is not None else 100) - settling_time = settling_time or (hlc.aspiration_settling_time if hlc is not None else 5) + transport_air_volume = transport_air_volume or 0 + blow_out_air_volume = blow_out_air_volume or 0 + flow_rate = aspiration.flow_rate or 250 + swap_speed = swap_speed or 100 + settling_time = settling_time or 5 return await self.core96_aspiration_of_liquid( x_position=round(position.x * 10), y_position=round(position.y * 10), type_of_aspiration=type_of_aspiration, - minimal_traverse_height_at_begin_of_command=round( - (minimal_traverse_height_at_begin_of_command or self._traversal_height) * 10 - ), - minimal_height_at_command_end=round( - minimal_height_at_command_end or self._traversal_height * 10 - ), + minimal_traverse_height_at_begin_of_command= + round((minimal_traverse_height_at_begin_of_command or self._traversal_height) * 10), + minimal_height_at_command_end= + round(minimal_height_at_command_end or self._traversal_height * 10), lld_search_height=round(lld_search_height * 10), liquid_surface_at_function_without_lld=round(liquid_height * 10), - pull_out_distance_to_take_transport_air_in_function_without_lld=round( - pull_out_distance_to_take_transport_air_in_function_without_lld * 10 - ), + pull_out_distance_to_take_transport_air_in_function_without_lld=\ + round(pull_out_distance_to_take_transport_air_in_function_without_lld*10), minimum_height=round(well_bottoms * 10), - tube_2nd_section_height_measured_from_zm=round(tube_2nd_section_height_measured_from_zm * 10), - tube_2nd_section_ratio=round(tube_2nd_section_ratio * 10), - immersion_depth=round(immersion_depth * 10), - surface_following_distance=round(surface_following_distance * 10), - aspiration_volume=round(volume * 100), + tube_2nd_section_height_measured_from_zm=round(tube_2nd_section_height_measured_from_zm*10), + tube_2nd_section_ratio=round(tube_2nd_section_ratio*10), + immersion_depth=round(immersion_depth*10), + surface_following_distance=round(surface_following_distance*10), + aspiration_volume=round(aspiration.volume * 100), aspiration_speed=round(flow_rate * 10), - transport_air_volume=round(transport_air_volume * 10), - blow_out_air_volume=round(blow_out_air_volume * 100), - pre_wetting_volume=round(pre_wetting_volume * 100), + transport_air_volume=round(transport_air_volume*10), + blow_out_air_volume=round(blow_out_air_volume*100), + pre_wetting_volume=round(pre_wetting_volume*100), lld_mode=lld_mode, lld_sensitivity=lld_sensitivity, - swap_speed=round(swap_speed * 10), - settling_time=round(settling_time * 10), - mix_volume=round(mix_volume * 100), + swap_speed=round(swap_speed*10), + settling_time=round(settling_time*10), + mix_volume=round(mix_volume*100), mix_cycles=mix_cycles, - mix_position_in_z_direction_from_liquid_surface=round( - mix_position_in_z_direction_from_liquid_surface * 100 - ), - surface_following_distance_during_mixing=round( - surface_following_distance_during_mixing * 100 - ), - mix_speed=round(mix_speed * 10), + mix_position_in_z_direction_from_liquid_surface=\ + round(mix_position_in_z_direction_from_liquid_surface*100), + surface_following_distance_during_mixing=round(surface_following_distance_during_mixing*100), + mix_speed=round(mix_speed*10), limit_curve_index=limit_curve_index, tadm_channel_pattern=tadm_channel_pattern, tadm_algorithm_on_off=tadm_algorithm_on_off, @@ -1135,10 +970,11 @@ async def aspirate96( async def dispense96( self, - dispense: Union[MultiHeadDispensePlate, MultiHeadDispenseContainer], + dispense: Union[DispensePlate, DispenseContainer], jet: bool = False, - blow_out: bool = False, # "empty" in the VENUS liquid editor - empty: bool = False, # truly "empty", does not exist in liquid editor, dm4 + blow_out: bool = False, # "empty" in the VENUS liquid editor + empty: bool = False, # truly "empty", does not exist in liquid editor, dm4 + hlc: Optional[HamiltonLiquidClass] = None, type_of_dispensing_mode: Optional[int] = None, tube_2nd_section_height_measured_from_zm: float = 0, @@ -1167,7 +1003,7 @@ async def dispense96( tadm_algorithm_on_off: int = 0, recording_mode: int = 0, ): - """Dispense to a plate using the 96 head. + """ Dispense to a plate using the 96 head. Args: jet: whether to dispense in jet mode. @@ -1182,106 +1018,90 @@ async def dispense96( determined based on the jet, blow_out, and empty parameters. """ - if isinstance(dispense, MultiHeadDispensePlate): + if hlc is not None: + raise NotImplementedError("hlc is deprecated") + + if isinstance(dispense, DispensePlate): top_left_well = dispense.wells[0] - position = ( - top_left_well.get_absolute_location() - + top_left_well.center() - + dispense.offset - + Coordinate(z=top_left_well.material_z_thickness) - ) + position = top_left_well.get_absolute_location() + top_left_well.center() + \ + dispense.offset + Coordinate(z=top_left_well.material_z_thickness) # -1 compared to STAR? well_bottoms = position.z - lld_search_height = well_bottoms + top_left_well.get_absolute_size_z() + 2.7 - 1 + lld_search_height = well_bottoms + top_left_well.get_absolute_size_z() + 2.7-1 else: - position = ( - dispense.container.get_absolute_location(y="b") - + dispense.offset - + Coordinate(z=dispense.container.material_z_thickness) - ) + position = dispense.container.get_absolute_location(y="b") + dispense.offset + \ + Coordinate(z=dispense.container.material_z_thickness) bottom = position.z - lld_search_height = bottom + dispense.container.get_absolute_size_z() + 2.7 - 1 + lld_search_height = bottom + dispense.container.get_absolute_size_z() + 2.7-1 liquid_height = position.z + (dispense.liquid_height or 0) + 10 - tip = dispense.tips[0] - liquid_to_be_dispensed = Liquid.WATER # default to WATER - if len(dispense.liquids[0]) > 0 and dispense.liquids[0][-1][0] is not None: - # first part of tuple in last liquid of first well - liquid_to_be_dispensed = dispense.liquids[0][-1][0] - if hlc is None: - hlc = get_vantage_liquid_class( - tip_volume=tip.maximal_volume, - is_core=True, - is_tip=True, - has_filter=tip.has_filter, - liquid=liquid_to_be_dispensed, - jet=jet, - blow_out=blow_out, # see method docstring - ) - volume = hlc.compute_corrected_volume(dispense.volume) if hlc is not None else dispense.volume - - transport_air_volume = transport_air_volume or ( - hlc.dispense_air_transport_volume if hlc is not None else 0 - ) - blow_out_air_volume = blow_out_air_volume or ( - hlc.dispense_blow_out_volume if hlc is not None else 0 - ) - flow_rate = dispense.flow_rate or (hlc.dispense_flow_rate if hlc is not None else 250) - swap_speed = swap_speed or (hlc.dispense_swap_speed if hlc is not None else 100) - settling_time = settling_time or (hlc.dispense_settling_time if hlc is not None else 5) - mix_speed = mix_speed or (hlc.dispense_mix_flow_rate if hlc is not None else 100) - type_of_dispensing_mode = type_of_dispensing_mode or _get_dispense_mode( - jet=jet, empty=empty, blow_out=blow_out - ) + transport_air_volume = transport_air_volume or 0 + blow_out_air_volume = blow_out_air_volume or 0 + flow_rate = dispense.flow_rate or 250 + swap_speed = swap_speed or 100 + settling_time = settling_time or 5 + mix_speed = mix_speed or 100 + type_of_dispensing_mode = type_of_dispensing_mode or \ + _get_dispense_mode(jet=jet, empty=empty, blow_out=blow_out) return await self.core96_dispensing_of_liquid( x_position=round(position.x * 10), y_position=round(position.y * 10), type_of_dispensing_mode=type_of_dispensing_mode, minimum_height=round(well_bottoms * 10), - tube_2nd_section_height_measured_from_zm=round(tube_2nd_section_height_measured_from_zm * 10), - tube_2nd_section_ratio=round(tube_2nd_section_ratio * 10), + tube_2nd_section_height_measured_from_zm=round(tube_2nd_section_height_measured_from_zm*10), + tube_2nd_section_ratio=round(tube_2nd_section_ratio*10), lld_search_height=round(lld_search_height * 10), liquid_surface_at_function_without_lld=round(liquid_height * 10), - pull_out_distance_to_take_transport_air_in_function_without_lld=round( - pull_out_distance_to_take_transport_air_in_function_without_lld * 10 - ), - immersion_depth=round(immersion_depth * 10), - surface_following_distance=round(surface_following_distance * 10), - minimal_traverse_height_at_begin_of_command=round( - (minimal_traverse_height_at_begin_of_command or self._traversal_height) * 10 - ), - minimal_height_at_command_end=round( - (minimal_height_at_command_end or self._traversal_height) * 10 - ), - dispense_volume=round(volume * 100), + pull_out_distance_to_take_transport_air_in_function_without_lld=\ + round(pull_out_distance_to_take_transport_air_in_function_without_lld*10), + immersion_depth=round(immersion_depth*10), + surface_following_distance=round(surface_following_distance*10), + minimal_traverse_height_at_begin_of_command= + round((minimal_traverse_height_at_begin_of_command or self._traversal_height) * 10), + minimal_height_at_command_end= + round((minimal_height_at_command_end or self._traversal_height)*10), + dispense_volume=round(dispense.volume * 100), dispense_speed=round(flow_rate * 10), cut_off_speed=round(cut_off_speed * 10), stop_back_volume=round(stop_back_volume * 100), - transport_air_volume=round(transport_air_volume * 10), - blow_out_air_volume=round(blow_out_air_volume * 100), + transport_air_volume=round(transport_air_volume*10), + blow_out_air_volume=round(blow_out_air_volume*100), lld_mode=lld_mode, lld_sensitivity=lld_sensitivity, - side_touch_off_distance=round(side_touch_off_distance * 10), - swap_speed=round(swap_speed * 10), - settling_time=round(settling_time * 10), - mix_volume=round(mix_volume * 10), + side_touch_off_distance=round(side_touch_off_distance*10), + swap_speed=round(swap_speed*10), + settling_time=round(settling_time*10), + mix_volume=round(mix_volume*10), mix_cycles=mix_cycles, - mix_position_in_z_direction_from_liquid_surface=round( - mix_position_in_z_direction_from_liquid_surface * 10 - ), - surface_following_distance_during_mixing=round(surface_following_distance_during_mixing * 10), - mix_speed=round(mix_speed * 10), + mix_position_in_z_direction_from_liquid_surface=\ + round(mix_position_in_z_direction_from_liquid_surface*10), + surface_following_distance_during_mixing=round(surface_following_distance_during_mixing*10), + mix_speed=round(mix_speed*10), limit_curve_index=limit_curve_index, tadm_channel_pattern=tadm_channel_pattern, tadm_algorithm_on_off=tadm_algorithm_on_off, recording_mode=recording_mode, ) + async def move_resource(self, move: Move): + await self.pick_up_resource( + resource=move.resource, + offset=move.resource_offset, + pickup_distance_from_top=move.pickup_distance_from_top) + + await self.release_picked_up_resource( + resource=move.resource, + destination=move.destination, + offset=move.destination_offset, + pickup_distance_from_top=move.pickup_distance_from_top) + async def pick_up_resource( self, - pickup: ResourcePickup, + resource: Resource, + offset: Coordinate, + pickup_distance_from_top: float, grip_strength: int = 81, plate_width_tolerance: float = 2.0, acceleration_index: int = 4, @@ -1289,31 +1109,30 @@ async def pick_up_resource( hotel_depth: float = 0, minimal_height_at_command_end: float = 284.0, ): - """Pick up a resource with the IPG. You probably want to use :meth:`move_resource`, which - allows you to pick up and move a resource with a single command.""" + """ Pick up a resource with the IPG. You probably want to use :meth:`move_resource`, which + allows you to pick up and move a resource with a single command. """ - center = pickup.resource.get_absolute_location(x="c", y="c", z="b") + pickup.offset - grip_height = center.z + pickup.resource.get_absolute_size_z() - pickup.pickup_distance_from_top - plate_width = pickup.resource.get_absolute_size_x() + center = resource.get_absolute_location() + resource.center() + offset + grip_height = center.z + resource.get_absolute_size_z() - pickup_distance_from_top + plate_width = resource.get_absolute_size_x() await self.ipg_grip_plate( x_position=round(center.x * 10), y_position=round(center.y * 10), z_position=round(grip_height * 10), grip_strength=grip_strength, - open_gripper_position=round(plate_width * 10) + 32, + open_gripper_position=round(plate_width*10) + 32, plate_width=round(plate_width * 10) - 33, - plate_width_tolerance=round(plate_width_tolerance * 10), + plate_width_tolerance=round(plate_width_tolerance*10), acceleration_index=acceleration_index, - z_clearance_height=round(z_clearance_height * 10), - hotel_depth=round(hotel_depth * 10), - minimal_height_at_command_end=round( - (minimal_height_at_command_end or self._traversal_height) * 10 - ), + z_clearance_height=round(z_clearance_height*10), + hotel_depth=round(hotel_depth*10), + minimal_height_at_command_end= + round((minimal_height_at_command_end or self._traversal_height) * 10), ) - async def move_picked_up_resource(self, move: ResourceMove): - """Move a resource picked up with the IPG. See :meth:`pick_up_resource`. + async def move_picked_up_resource(self): + """ Move a resource picked up with the IPG. See :meth:`pick_up_resource`. You probably want to use :meth:`move_resource`, which allows you to pick up and move a resource with a single command. @@ -1321,54 +1140,56 @@ async def move_picked_up_resource(self, move: ResourceMove): raise NotImplementedError() - async def drop_resource( + async def release_picked_up_resource( self, - drop: ResourceDrop, + resource: Resource, + destination: Coordinate, + offset: Coordinate, + pickup_distance_from_top: float, z_clearance_height: float = 0, press_on_distance: int = 5, hotel_depth: float = 0, - minimal_height_at_command_end: float = 284.0, + minimal_height_at_command_end: float = 284.0 ): - """Release a resource picked up with the IPG. See :meth:`pick_up_resource`. + """ Release a resource picked up with the IPG. See :meth:`pick_up_resource`. You probably want to use :meth:`move_resource`, which allows you to pick up and move a resource with a single command. """ - center = drop.destination + drop.resource.center() + drop.offset - grip_height = center.z + drop.resource.get_absolute_size_z() - drop.pickup_distance_from_top - plate_width = drop.resource.get_absolute_size_x() + center = destination + resource.center() + offset + grip_height = center.z + resource.get_absolute_size_z() - pickup_distance_from_top + plate_width = resource.get_absolute_size_x() await self.ipg_put_plate( x_position=round(center.x * 10), y_position=round(center.y * 10), z_position=round(grip_height * 10), - z_clearance_height=round(z_clearance_height * 10), - open_gripper_position=round(plate_width * 10) + 32, + z_clearance_height=round(z_clearance_height*10), + open_gripper_position=round(plate_width*10) + 32, press_on_distance=press_on_distance, - hotel_depth=round(hotel_depth * 10), - minimal_height_at_command_end=round( - (minimal_height_at_command_end or self._traversal_height) * 10 - ), + hotel_depth=round(hotel_depth*10), + minimal_height_at_command_end= + round((minimal_height_at_command_end or self._traversal_height) * 10), ) async def prepare_for_manual_channel_operation(self, channel: int): - """Prepare the robot for manual operation.""" + """ Prepare the robot for manual operation. """ - return await self.expose_channel_n(channel_index=channel + 1) # ? + return await self.expose_channel_n(channel_index=channel + 1) # ? - async def move_channel_x(self, channel: int, x: float): - """Move the specified channel to the specified x coordinate.""" + async def move_channel_x(self, channel: int, x: float): # pylint: disable=unused-argument + """ Move the specified channel to the specified x coordinate. """ return await self.x_arm_move_to_x_position(round(x * 10)) async def move_channel_y(self, channel: int, y: float): - """Move the specified channel to the specified y coordinate.""" + """ Move the specified channel to the specified y coordinate. """ return await self.position_single_channel_in_y_direction(channel + 1, round(y * 10)) async def move_channel_z(self, channel: int, z: float): - """Move the specified channel to the specified z coordinate.""" + """ Move the specified channel to the specified z coordinate. """ return await self.position_single_channel_in_z_direction(channel + 1, round(z * 10)) @@ -1385,7 +1206,7 @@ async def set_led_color( uv: int, blink_interval: Optional[int] = None, ): - """Set the LED color. + """ Set the LED color. Args: mode: The mode of the LED. One of "on", "off", or "blink". @@ -1411,21 +1232,25 @@ async def set_led_color( "blink": 2, }[mode], os=intensity, - ok=blink_interval or 750, # default non zero value + ok=blink_interval or 750, # default non zero value ol=f"{white} {red} {green} {blue} {uv}", ) async def set_loading_cover(self, cover_open: bool): - """Set the loading cover. + """ Set the loading cover. Args: cover_open: Whether the cover should be open or closed. """ - return await self.send_command(module="I1AM", command="LP", lp=not cover_open) + return await self.send_command( + module="I1AM", + command="LP", + lp=not cover_open + ) async def loading_cover_request_initialization_status(self) -> bool: - """Request the loading cover initialization status. + """ Request the loading cover initialization status. This command was based on the STAR command (QW) and the VStarTranslator log. @@ -1433,21 +1258,23 @@ async def loading_cover_request_initialization_status(self) -> bool: True if the cover module is initialized, False otherwise. """ - resp = await self.send_command(module="I1AM", command="QW", fmt={"qw": "int"}) + resp = await self.send_command( + module="I1AM", + command="QW", + fmt={"qw": "int"} + ) return resp is not None and resp["qw"] == 1 async def loading_cover_initialize(self): - """Initialize the loading cover.""" + """ Initialize the loading cover. """ return await self.send_command( module="I1AM", command="MI", ) - async def arm_request_instrument_initialization_status( - self, - ) -> bool: - """Request the instrument initialization status. + async def arm_request_instrument_initialization_status(self) -> bool: + """ Request the instrument initialization status. This command was based on the STAR command (QW) and the VStarTranslator log. A1AM corresponds to "arm". @@ -1460,12 +1287,12 @@ async def arm_request_instrument_initialization_status( return resp is not None and resp["qw"] == 1 async def arm_pre_initialize(self): - """Initialize the arm module.""" + """ Initialize the arm module. """ return await self.send_command(module="A1AM", command="MI") async def pip_request_initialization_status(self) -> bool: - """Request the pip initialization status. + """ Request the pip initialization status. This command was based on the STAR command (QW) and the VStarTranslator log. A1PM corresponds to all pip channels together. @@ -1488,7 +1315,7 @@ async def pip_initialize( tip_type: Optional[List[int]] = None, TODO_DI_2: int = 0, ): - """Initialize + """ Initialize Args: x_position: X Position [0.1mm]. @@ -1557,9 +1384,9 @@ async def define_tip_needle( tip_length: int, maximum_tip_volume: int, tip_size: TipSize, - pickup_method: TipPickupMethod, + pickup_method: TipPickupMethod ): - """Tip/needle definition. + """ Tip/needle definition. Args: tip_type_table_index: tip_table_index @@ -1573,19 +1400,17 @@ async def define_tip_needle( """ if not 0 <= tip_type_table_index <= 99: - raise ValueError( - "tip_type_table_index must be between 0 and 99, but is " f"{tip_type_table_index}" - ) + raise ValueError("tip_type_table_index must be between 0 and 99, but is " + f"{tip_type_table_index}") if not 0 <= tip_type_table_index <= 99: - raise ValueError( - "tip_type_table_index must be between 0 and 99, but is " f"{tip_type_table_index}" - ) + raise ValueError("tip_type_table_index must be between 0 and 99, but is " + f"{tip_type_table_index}") if not 1 <= tip_length <= 1999: - raise ValueError("tip_length must be between 1 and 1999, but is " f"{tip_length}") + raise ValueError("tip_length must be between 1 and 1999, but is " + f"{tip_length}") if not 1 <= maximum_tip_volume <= 56000: - raise ValueError( - "maximum_tip_volume must be between 1 and 56000, but is " f"{maximum_tip_volume}" - ) + raise ValueError("maximum_tip_volume must be between 1 and 56000, but is " + f"{maximum_tip_volume}") return await self.send_command( module="A1AM", @@ -1595,7 +1420,7 @@ async def define_tip_needle( tl=f"{tip_length:04}", tv=f"{maximum_tip_volume:05}", tg=tip_size.value, - tu=pickup_method.value, + tu=pickup_method.value ) async def pip_aspirate( @@ -1640,7 +1465,7 @@ async def pip_aspirate( limit_curve_index: Optional[List[int]] = None, recording_mode: int = 0, ): - """Aspiration of liquid + """ Aspiration of liquid Args: type_of_aspiration: Type of aspiration (0 = simple 1 = sequence 2 = cup emptied). @@ -1732,13 +1557,10 @@ async def pip_aspirate( if pull_out_distance_to_take_transport_air_in_function_without_lld is None: pull_out_distance_to_take_transport_air_in_function_without_lld = [50] * self.num_channels - elif not all( - 0 <= x <= 3600 for x in pull_out_distance_to_take_transport_air_in_function_without_lld - ): - raise ValueError( - "pull_out_distance_to_take_transport_air_in_function_without_lld must be " - "in range 0 to 3600" - ) + elif not all(0 <= x <= 3600 for x in + pull_out_distance_to_take_transport_air_in_function_without_lld): + raise ValueError("pull_out_distance_to_take_transport_air_in_function_without_lld must be " + "in range 0 to 3600") if tube_2nd_section_height_measured_from_zm is None: tube_2nd_section_height_measured_from_zm = [0] * self.num_channels @@ -1964,7 +1786,7 @@ async def pip_dispense( limit_curve_index: Optional[List[int]] = None, recording_mode: int = 0, ): - """Dispensing of liquid + """ Dispensing of liquid Args: type_of_dispensing_mode: Type of dispensing mode 0 = part in jet 1 = blow in jet 2 = Part at @@ -2047,13 +1869,10 @@ async def pip_dispense( if pull_out_distance_to_take_transport_air_in_function_without_lld is None: pull_out_distance_to_take_transport_air_in_function_without_lld = [50] * self.num_channels - elif not all( - 0 <= x <= 3600 for x in pull_out_distance_to_take_transport_air_in_function_without_lld - ): - raise ValueError( - "pull_out_distance_to_take_transport_air_in_function_without_lld must be " - "in range 0 to 3600" - ) + elif not all(0 <= x <= 3600 for x in + pull_out_distance_to_take_transport_air_in_function_without_lld): + raise ValueError("pull_out_distance_to_take_transport_air_in_function_without_lld must be " + "in range 0 to 3600") if immersion_depth is None: immersion_depth = [0] * self.num_channels @@ -2206,7 +2025,7 @@ async def pip_dispense( zr=tube_2nd_section_ratio, th=minimal_traverse_height_at_begin_of_command, te=minimal_height_at_command_end, - dv=[f"{vol:04}" for vol in dispense_volume], # it appears at least 4 digits are needed + dv=[f"{vol:04}" for vol in dispense_volume], # it appears at least 4 digits are needed ds=dispense_speed, ss=cut_off_speed, rv=stop_back_volume, @@ -2277,7 +2096,7 @@ async def simultaneous_aspiration_dispensation_of_liquid( limit_curve_index: Optional[List[int]] = None, recording_mode: int = 0, ): - """Simultaneous aspiration & dispensation of liquid + """ Simultaneous aspiration & dispensation of liquid Args: type_of_aspiration: Type of aspiration (0 = simple 1 = sequence 2 = cup emptied). @@ -2388,13 +2207,10 @@ async def simultaneous_aspiration_dispensation_of_liquid( if pull_out_distance_to_take_transport_air_in_function_without_lld is None: pull_out_distance_to_take_transport_air_in_function_without_lld = [50] * self.num_channels - elif not all( - 0 <= x <= 3600 for x in pull_out_distance_to_take_transport_air_in_function_without_lld - ): - raise ValueError( - "pull_out_distance_to_take_transport_air_in_function_without_lld must be " - "in range 0 to 3600" - ) + elif not all(0 <= x <= 3600 + for x in pull_out_distance_to_take_transport_air_in_function_without_lld): + raise ValueError("pull_out_distance_to_take_transport_air_in_function_without_lld must be " + "in range 0 to 3600") if minimum_height is None: minimum_height = [3600] * self.num_channels @@ -2605,12 +2421,12 @@ async def dispense_on_fly( self, y_position: List[int], tip_pattern: Optional[List[bool]] = None, - first_shoot_x_pos: int = 0, # 1 - dispense_on_fly_pos_command_end: int = 0, # 2 - x_acceleration_distance_before_first_shoot: int = 100, # 3 - space_between_shoots: int = 900, # 4 + first_shoot_x_pos: int = 0, #1 + dispense_on_fly_pos_command_end: int = 0, # 2 + x_acceleration_distance_before_first_shoot: int = 100, # 3 + space_between_shoots: int = 900, # 4 x_speed: int = 270, - number_of_shoots: int = 1, # 5 + number_of_shoots: int = 1, # 5 minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, minimal_height_at_command_end: Optional[List[int]] = None, liquid_surface_at_function_without_lld: Optional[List[int]] = None, @@ -2623,7 +2439,7 @@ async def dispense_on_fly( limit_curve_index: Optional[List[int]] = None, recording_mode: int = 0, ): - """Dispense on fly + """ Dispense on fly Args: tip_pattern: Tip pattern (channels involved). [0 = not involved, 1 = involved]. @@ -2773,7 +2589,7 @@ async def nano_pulse_dispense( TODO_DB_11: Optional[List[int]] = None, TODO_DB_12: Optional[List[int]] = None, ): - """Nano pulse dispense + """ Nano pulse dispense Args: TODO_DB_0: (0). @@ -2923,7 +2739,7 @@ async def wash_tips( wash_cycles: int = 0, minimal_height_at_command_end: Optional[List[int]] = None, ): - """Wash tips + """ Wash tips Args: tip_pattern: Tip pattern (channels involved). [0 = not involved, 1 = involved]. @@ -3025,7 +2841,7 @@ async def pip_tip_pick_up( blow_out_air_volume: Optional[List[int]] = None, tip_handling_method: Optional[List[int]] = None, ): - """Tip Pick up + """ Tip Pick up Args: x_position: X Position [0.1mm]. @@ -3117,7 +2933,7 @@ async def pip_tip_discard( TODO_TR_2: int = 0, tip_handling_method: Optional[List[int]] = None, ): - """Tip Discard + """ Tip Discard Args: x_position: X Position [0.1mm]. @@ -3193,7 +3009,7 @@ async def search_for_teach_in_signal_in_x_direction( x_search_distance: int = 0, x_speed: int = 270, ): - """Search for Teach in signal in X direction + """ Search for Teach in signal in X direction Args: channel_index: Channel index. @@ -3222,7 +3038,7 @@ async def position_all_channels_in_y_direction( self, y_position: List[int], ): - """Position all channels in Y direction + """ Position all channels in Y direction Args: y_position: Y Position [0.1mm]. @@ -3243,7 +3059,7 @@ async def position_all_channels_in_z_direction( self, z_position: Optional[List[int]] = None, ): - """Position all channels in Z direction + """ Position all channels in Z direction Args: z_position: Z Position [0.1mm]. @@ -3265,7 +3081,7 @@ async def position_single_channel_in_y_direction( channel_index: int = 1, y_position: int = 3000, ): - """Position single channel in Y direction + """ Position single channel in Y direction Args: channel_index: Channel index. @@ -3290,7 +3106,7 @@ async def position_single_channel_in_z_direction( channel_index: int = 1, z_position: int = 0, ): - """Position single channel in Z direction + """ Position single channel in Z direction Args: channel_index: Channel index. @@ -3318,7 +3134,7 @@ async def move_to_defined_position( minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, z_position: Optional[List[int]] = None, ): - """Move to defined position + """ Move to defined position Args: tip_pattern: Tip pattern (channels involved). [0 = not involved, 1 = involved]. @@ -3370,7 +3186,7 @@ async def teach_rack_using_channel_n( gap_center_z_direction: int = 0, minimal_height_at_command_end: Optional[List[int]] = None, ): - """Teach rack using channel n + """ Teach rack using channel n Attention! Channels not involved must first be taken out of measurement range. @@ -3413,7 +3229,7 @@ async def expose_channel_n( self, channel_index: int = 1, ): - """Expose channel n + """ Expose channel n Args: channel_index: Channel index. @@ -3438,7 +3254,7 @@ async def calculates_check_sums_and_compares_them_with_the_value_saved_in_flash_ minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, first_pip_channel_node_no: int = 1, ): - """Calculates check sums and compares them with the value saved in Flash EPROM + """ Calculates check sums and compares them with the value saved in Flash EPROM Args: TODO_DC_0: (0). @@ -3503,7 +3319,7 @@ async def discard_core_gripper_tool( first_pip_channel_node_no: int = 1, minimal_height_at_command_end: Optional[List[int]] = None, ): - """Discard CoRe gripper tool + """ Discard CoRe gripper tool Args: gripper_tool_x_position: (0). @@ -3577,7 +3393,7 @@ async def grip_plate( minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, minimal_height_at_command_end: Optional[List[int]] = None, ): - """Grip plate + """ Grip plate Args: plate_center_x_direction: Plate center X direction [0.1mm]. @@ -3653,7 +3469,7 @@ async def put_plate( minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, minimal_height_at_command_end: Optional[List[int]] = None, ): - """Put plate + """ Put plate Args: plate_center_x_direction: Plate center X direction [0.1mm]. @@ -3716,7 +3532,7 @@ async def move_to_position( z_speed: int = 1287, minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, ): - """Move to position + """ Move to position Args: plate_center_x_direction: Plate center X direction [0.1mm]. @@ -3758,7 +3574,7 @@ async def release_object( self, first_pip_channel_node_no: int = 1, ): - """Release object + """ Release object Args: first_pip_channel_node_no: First (lower) pip. channel node no. (0 = disabled). @@ -3774,7 +3590,7 @@ async def release_object( ) async def set_any_parameter_within_this_module(self): - """Set any parameter within this module""" + """ Set any parameter within this module """ return await self.send_command( module="A1PM", @@ -3782,7 +3598,7 @@ async def set_any_parameter_within_this_module(self): ) async def request_y_positions_of_all_channels(self): - """Request Y Positions of all channels""" + """ Request Y Positions of all channels """ return await self.send_command( module="A1PM", @@ -3790,7 +3606,7 @@ async def request_y_positions_of_all_channels(self): ) async def request_y_position_of_channel_n(self, channel_index: int = 1): - """Request Y Position of channel n""" + """ Request Y Position of channel n """ return await self.send_command( module="A1PM", @@ -3799,7 +3615,7 @@ async def request_y_position_of_channel_n(self, channel_index: int = 1): ) async def request_z_positions_of_all_channels(self): - """Request Z Positions of all channels""" + """ Request Z Positions of all channels """ return await self.send_command( module="A1PM", @@ -3807,7 +3623,7 @@ async def request_z_positions_of_all_channels(self): ) async def request_z_position_of_channel_n(self, channel_index: int = 1): - """Request Z Position of channel n""" + """ Request Z Position of channel n """ return await self.send_command( module="A1PM", @@ -3816,14 +3632,14 @@ async def request_z_position_of_channel_n(self, channel_index: int = 1): ) async def query_tip_presence(self) -> List[bool]: - """Query Tip presence""" + """ Query Tip presence """ resp = await self.send_command(module="A1PM", command="QA", fmt={"rt": "[int]"}) presences_int = cast(List[int], resp["rt"]) return [bool(p) for p in presences_int] async def request_height_of_last_lld(self): - """Request height of last LLD""" + """ Request height of last LLD """ return await self.send_command( module="A1PM", @@ -3831,7 +3647,7 @@ async def request_height_of_last_lld(self): ) async def request_channel_dispense_on_fly_status(self): - """Request channel dispense on fly status""" + """ Request channel dispense on fly status """ return await self.send_command( module="A1PM", @@ -3839,7 +3655,7 @@ async def request_channel_dispense_on_fly_status(self): ) async def core96_request_initialization_status(self) -> bool: - """Request CoRe96 initialization status + """ Request CoRe96 initialization status This method is inferred from I1AM and A1AM commands ("QW"). @@ -3860,7 +3676,7 @@ async def core96_initialize( end_z_deposit_position: int = 0, tip_type: int = 4, ): - """Initialize 96 head. + """ Initialize 96 head. Args: x_position: X Position [0.1mm]. @@ -3941,7 +3757,7 @@ async def core96_aspiration_of_liquid( tadm_algorithm_on_off: int = 0, recording_mode: int = 0, ): - """Aspiration of liquid using the 96 head. + """ Aspiration of liquid using the 96 head. Args: type_of_aspiration: Type of aspiration (0 = simple 1 = sequence 2 = cup emptied). @@ -4004,10 +3820,8 @@ async def core96_aspiration_of_liquid( raise ValueError("liquid_surface_at_function_without_lld must be in range 0 to 3900") if not 0 <= pull_out_distance_to_take_transport_air_in_function_without_lld <= 3900: - raise ValueError( - "pull_out_distance_to_take_transport_air_in_function_without_lld must be in " - "range 0 to 3900" - ) + raise ValueError("pull_out_distance_to_take_transport_air_in_function_without_lld must be in " + "range 0 to 3900") if not 0 <= minimum_height <= 3900: raise ValueError("minimum_height must be in range 0 to 3900") @@ -4072,9 +3886,8 @@ async def core96_aspiration_of_liquid( if tadm_channel_pattern is None: tadm_channel_pattern = [True] * 96 elif not len(tadm_channel_pattern) < 24: - raise ValueError( - "tadm_channel_pattern must be of length 24, but is " f"'{len(tadm_channel_pattern)}'" - ) + raise ValueError("tadm_channel_pattern must be of length 24, but is " + f"'{len(tadm_channel_pattern)}'") tadm_channel_pattern_num = sum(2**i if tadm_channel_pattern[i] else 0 for i in range(96)) if not 0 <= tadm_algorithm_on_off <= 1: @@ -4155,7 +3968,7 @@ async def core96_dispensing_of_liquid( tadm_algorithm_on_off: int = 0, recording_mode: int = 0, ): - """Dispensing of liquid using the 96 head. + """ Dispensing of liquid using the 96 head. Args: type_of_dispensing_mode: Type of dispensing mode 0 = part in jet 1 = blow in jet 2 = Part at @@ -4225,10 +4038,8 @@ async def core96_dispensing_of_liquid( raise ValueError("liquid_surface_at_function_without_lld must be in range 0 to 3900") if not 0 <= pull_out_distance_to_take_transport_air_in_function_without_lld <= 3900: - raise ValueError( - "pull_out_distance_to_take_transport_air_in_function_without_lld must be in " - "range 0 to 3900" - ) + raise ValueError("pull_out_distance_to_take_transport_air_in_function_without_lld must be in " + "range 0 to 3900") if not -990 <= immersion_depth <= 990: raise ValueError("immersion_depth must be in range -990 to 990") @@ -4296,9 +4107,8 @@ async def core96_dispensing_of_liquid( if tadm_channel_pattern is None: tadm_channel_pattern = [True] * 96 elif not len(tadm_channel_pattern) < 24: - raise ValueError( - "tadm_channel_pattern must be of length 24, but is " f"'{len(tadm_channel_pattern)}'" - ) + raise ValueError("tadm_channel_pattern must be of length 24, but is " + f"'{len(tadm_channel_pattern)}'") tadm_channel_pattern_num = sum(2**i if tadm_channel_pattern[i] else 0 for i in range(96)) if not 0 <= tadm_algorithm_on_off <= 1: @@ -4355,7 +4165,7 @@ async def core96_tip_pick_up( minimal_traverse_height_at_begin_of_command: int = 3900, minimal_height_at_command_end: int = 3900, ): - """Tip Pick up using the 96 head. + """ Tip Pick up using the 96 head. Args: x_position: X Position [0.1mm]. @@ -4409,7 +4219,7 @@ async def core96_tip_discard( minimal_traverse_height_at_begin_of_command: int = 3900, minimal_height_at_command_end: int = 3900, ): - """Tip Discard using the 96 head. + """ Tip Discard using the 96 head. Args: x_position: X Position [0.1mm]. @@ -4452,7 +4262,7 @@ async def core96_move_to_defined_position( z_position: int = 0, minimal_traverse_height_at_begin_of_command: int = 3900, ): - """Move to defined position using the 96 head. + """ Move to defined position using the 96 head. Args: x_position: X Position [0.1mm]. @@ -4495,7 +4305,7 @@ async def core96_wash_tips( mix_cycles: int = 0, mix_speed: int = 2000, ): - """Wash tips on the 96 head. + """ Wash tips on the 96 head. Args: x_position: X Position [0.1mm]. @@ -4556,7 +4366,7 @@ async def core96_empty_washed_tips( liquid_surface_at_function_without_lld: int = 3900, minimal_height_at_command_end: int = 3900, ): - """Empty washed tips (end of wash procedure only) on the 96 head. + """ Empty washed tips (end of wash procedure only) on the 96 head. Args: liquid_surface_at_function_without_lld: Liquid surface at function without LLD [0.1mm]. @@ -4581,7 +4391,7 @@ async def core96_search_for_teach_in_signal_in_x_direction( x_search_distance: int = 0, x_speed: int = 50, ): - """Search for Teach in signal in X direction on the 96 head. + """ Search for Teach in signal in X direction on the 96 head. Args: x_search_distance: X search distance [0.1mm]. @@ -4602,7 +4412,7 @@ async def core96_search_for_teach_in_signal_in_x_direction( ) async def core96_set_any_parameter(self): - """Set any parameter within the 96 head module.""" + """ Set any parameter within the 96 head module. """ return await self.send_command( module="A1HM", @@ -4610,7 +4420,7 @@ async def core96_set_any_parameter(self): ) async def core96_query_tip_presence(self): - """Query Tip presence on the 96 head.""" + """ Query Tip presence on the 96 head. """ return await self.send_command( module="A1HM", @@ -4618,7 +4428,7 @@ async def core96_query_tip_presence(self): ) async def core96_request_position(self): - """Request position of the 96 head.""" + """ Request position of the 96 head. """ return await self.send_command( module="A1HM", @@ -4629,7 +4439,7 @@ async def core96_request_tadm_error_status( self, tadm_channel_pattern: Optional[List[bool]] = None, ): - """Request TADM error status on the 96 head. + """ Request TADM error status on the 96 head. Args: tadm_channel_pattern: TADM Channel pattern. @@ -4638,9 +4448,8 @@ async def core96_request_tadm_error_status( if tadm_channel_pattern is None: tadm_channel_pattern = [True] * 96 elif not len(tadm_channel_pattern) < 24: - raise ValueError( - "tadm_channel_pattern must be of length 24, but is " f"'{len(tadm_channel_pattern)}'" - ) + raise ValueError("tadm_channel_pattern must be of length 24, but is " + f"'{len(tadm_channel_pattern)}'") tadm_channel_pattern_num = sum(2**i if tadm_channel_pattern[i] else 0 for i in range(96)) return await self.send_command( @@ -4650,7 +4459,7 @@ async def core96_request_tadm_error_status( ) async def ipg_request_initialization_status(self) -> bool: - """Request initialization status of IPG. + """ Request initialization status of IPG. This command was based on the STAR command (QW) and the VStarTranslator log. A1AM corresponds to "arm". @@ -4659,11 +4468,15 @@ async def ipg_request_initialization_status(self) -> bool: True if the ipg module is initialized, False otherwise. """ - resp = await self.send_command(module="A1RM", command="QW", fmt={"qw": "int"}) + resp = await self.send_command( + module="A1RM", + command="QW", + fmt={"qw": "int"} + ) return resp is not None and resp["qw"] == 1 async def ipg_initialize(self): - """Initialize IPG""" + """ Initialize IPG """ return await self.send_command( module="A1RM", @@ -4671,7 +4484,7 @@ async def ipg_initialize(self): ) async def ipg_park(self): - """Park IPG""" + """ Park IPG """ return await self.send_command( module="A1RM", @@ -4679,7 +4492,7 @@ async def ipg_park(self): ) async def ipg_expose_channel_n(self): - """Expose channel n""" + """ Expose channel n """ return await self.send_command( module="A1RM", @@ -4687,7 +4500,7 @@ async def ipg_expose_channel_n(self): ) async def ipg_release_object(self): - """Release object""" + """ Release object """ return await self.send_command( module="A1RM", @@ -4699,7 +4512,7 @@ async def ipg_search_for_teach_in_signal_in_x_direction( x_search_distance: int = 0, x_speed: int = 50, ): - """Search for Teach in signal in X direction + """ Search for Teach in signal in X direction Args: x_search_distance: X search distance [0.1mm]. @@ -4733,7 +4546,7 @@ async def ipg_grip_plate( hotel_depth: int = 0, minimal_height_at_command_end: int = 3600, ): - """Grip plate + """ Grip plate Args: x_position: X Position [0.1mm]. @@ -4809,7 +4622,7 @@ async def ipg_put_plate( hotel_depth: int = 0, minimal_height_at_command_end: int = 3600, ): - """Put plate + """ Put plate Args: x_position: X Position [0.1mm]. @@ -4864,7 +4677,7 @@ async def ipg_prepare_gripper_orientation( grip_orientation: int = 32, minimal_traverse_height_at_begin_of_command: int = 3600, ): - """Prepare gripper orientation + """ Prepare gripper orientation Args: grip_orientation: Grip orientation. @@ -4892,7 +4705,7 @@ async def ipg_move_to_defined_position( z_position: int = 3600, minimal_traverse_height_at_begin_of_command: int = 3600, ): - """Move to defined position + """ Move to defined position Args: x_position: X Position [0.1mm]. @@ -4924,7 +4737,7 @@ async def ipg_move_to_defined_position( ) async def ipg_set_any_parameter_within_this_module(self): - """Set any parameter within this module""" + """ Set any parameter within this module """ return await self.send_command( module="A1RM", @@ -4932,13 +4745,17 @@ async def ipg_set_any_parameter_within_this_module(self): ) async def ipg_get_parking_status(self) -> bool: - """Get parking status. Returns `True` if parked.""" + """ Get parking status. Returns `True` if parked. """ - resp = await self.send_command(module="A1RM", command="RG", fmt={"rg": "int"}) + resp = await self.send_command( + module="A1RM", + command="RG", + fmt={"rg": "int"} + ) return resp is not None and resp["rg"] == 1 async def ipg_query_tip_presence(self): - """Query Tip presence""" + """ Query Tip presence """ return await self.send_command( module="A1RM", @@ -4946,7 +4763,7 @@ async def ipg_query_tip_presence(self): ) async def ipg_request_access_range(self, grip_orientation: int = 32): - """Request access range + """ Request access range Args: grip_orientation: Grip orientation. @@ -4962,7 +4779,7 @@ async def ipg_request_access_range(self, grip_orientation: int = 32): ) async def ipg_request_position(self, grip_orientation: int = 32): - """Request position + """ Request position Args: grip_orientation: Grip orientation. @@ -4978,7 +4795,7 @@ async def ipg_request_position(self, grip_orientation: int = 32): ) async def ipg_request_actual_angular_dimensions(self): - """Request actual angular dimensions""" + """ Request actual angular dimensions """ return await self.send_command( module="A1RM", @@ -4986,7 +4803,7 @@ async def ipg_request_actual_angular_dimensions(self): ) async def ipg_request_configuration(self): - """Request configuration""" + """ Request configuration """ return await self.send_command( module="A1RM", @@ -4994,7 +4811,7 @@ async def ipg_request_configuration(self): ) async def x_arm_initialize(self): - """Initialize the x arm""" + """ Initialize the x arm """ return await self.send_command(module="A1XM", command="XI") async def x_arm_move_to_x_position( @@ -5003,7 +4820,7 @@ async def x_arm_move_to_x_position( x_speed: int = 25000, TODO_XI_1: int = 1, ): - """Move arm to X position + """ Move arm to X position Args: x_position: X Position [0.1mm]. @@ -5028,7 +4845,7 @@ async def x_arm_move_to_x_position_with_all_attached_components_in_z_safety_posi x_speed: int = 25000, TODO_XA_1: int = 1, ): - """Move arm to X position with all attached components in Z safety position + """ Move arm to X position with all attached components in Z safety position Args: x_position: X Position [0.1mm]. @@ -5059,7 +4876,7 @@ async def x_arm_move_arm_relatively_in_x( x_speed: int = 25000, TODO_XS_1: int = 1, ): - """Move arm relatively in X + """ Move arm relatively in X Args: x_search_distance: X search distance [0.1mm]. @@ -5090,7 +4907,7 @@ async def x_arm_search_x_for_teach_signal( x_speed: int = 25000, TODO_XT_1: int = 1, ): - """Search X for teach signal + """ Search X for teach signal Args: x_search_distance: X search distance [0.1mm]. @@ -5119,7 +4936,7 @@ async def x_arm_set_x_drive_angle_of_alignment( self, TODO_XL_1: int = 1, ): - """Set X drive angle of alignment + """ Set X drive angle of alignment Args: TODO_XL_1: (0). @@ -5141,7 +4958,7 @@ async def x_arm_send_message_to_motion_controller( self, TODO_BD_1: str = "", ): - """Send message to motion controller + """ Send message to motion controller Args: TODO_BD_1: (0). @@ -5158,7 +4975,7 @@ async def x_arm_set_any_parameter_within_this_module( TODO_AA_1: int = 0, TODO_AA_2: int = 1, ): - """Set any parameter within this module + """ Set any parameter within this module Args: TODO_AA_1: (0). @@ -5173,12 +4990,12 @@ async def x_arm_set_any_parameter_within_this_module( ) async def x_arm_request_arm_x_position(self): - """Request arm X position. This returns a list, of which the first value is one that can be - used with x_arm_move_to_x_position.""" + """ Request arm X position. This returns a list, of which the first value is one that can be + used with x_arm_move_to_x_position. """ return await self.send_command(module="A1XM", command="RX") async def x_arm_request_error_code(self): - """X arm request error code""" + """ X arm request error code """ return await self.send_command(module="A1XM", command="RE") async def x_arm_request_x_drive_recorded_data( @@ -5186,7 +5003,7 @@ async def x_arm_request_x_drive_recorded_data( TODO_QL_1: int = 0, TODO_QL_2: int = 0, ): - """Request X drive recorded data + """ Request X drive recorded data Args: TODO_QL_1: (0). @@ -5201,48 +5018,26 @@ async def x_arm_request_x_drive_recorded_data( ) async def disco_mode(self): - """Easter egg.""" + """ Easter egg. """ for _ in range(69): - r, g, b = ( - random.randint(30, 100), - random.randint(30, 100), - random.randint(30, 100), - ) + r, g, b = random.randint(30, 100), random.randint(30, 100), random.randint(30, 100) await self.set_led_color("on", intensity=100, white=0, red=r, green=g, blue=b, uv=0) await asyncio.sleep(0.1) async def russian_roulette(self): - """Dangerous easter egg.""" - sure = input( - "Are you sure you want to play Russian Roulette? This will turn on the uv-light " - "with a probability of 1/6. (yes/no) " - ) + """ Dangerous easter egg. """ + sure = input("Are you sure you want to play Russian Roulette? This will turn on the uv-light " + "with a probability of 1/6. (yes/no) ") if sure.lower() != "yes": print("boring") return if random.randint(1, 6) == 6: - await self.set_led_color( - "on", - intensity=100, - white=100, - red=100, - green=0, - blue=0, - uv=100, - ) + await self.set_led_color("on", intensity=100, white=100, red=100, green=0, blue=0, uv=100) print("You lost.") else: await self.set_led_color("on", intensity=100, white=100, red=0, green=100, blue=0, uv=0) print("You won.") await asyncio.sleep(5) - await self.set_led_color( - "on", - intensity=100, - white=100, - red=100, - green=100, - blue=100, - uv=0, - ) + await self.set_led_color("on", intensity=100, white=100, red=100, green=100, blue=100, uv=0) diff --git a/pylabrobot/liquid_handling/liquid_classes/hamilton/star.py b/pylabrobot/liquid_handling/liquid_classes/hamilton/star.py index 93b20a4d08..acb955a926 100644 --- a/pylabrobot/liquid_handling/liquid_classes/hamilton/star.py +++ b/pylabrobot/liquid_handling/liquid_classes/hamilton/star.py @@ -1,72 +1,20 @@ -from typing import Dict, Optional, Tuple +# pylint: skip-file + +from typing import Dict, Tuple -from pylabrobot.liquid_handling.liquid_classes.hamilton.base import ( - HamiltonLiquidClass, -) from pylabrobot.resources.liquid import Liquid +from pylabrobot.liquid_handling.liquid_classes.hamilton.base import HamiltonLiquidClass + + +star_mapping: Dict[Tuple[int, bool, bool, bool, Liquid, bool, bool], HamiltonLiquidClass] = {} + +def get_star_liquid_class(**kwargs): + raise NotImplementedError("Deprecated, use HamiltonLiquidClass directly") + -star_mapping: Dict[ - Tuple[int, bool, bool, bool, Liquid, bool, bool], - HamiltonLiquidClass, -] = {} - - -def get_star_liquid_class( - tip_volume: float, - is_core: bool, - is_tip: bool, - has_filter: bool, - liquid: Liquid, - jet: bool, - blow_out: bool, -) -> Optional[HamiltonLiquidClass]: - """Get the Hamilton STAR liquid class for the given parameters. - - Args: - tip_volume: The volume of the tip in microliters. - is_core: Whether the tip is a core tip. - is_tip: Whether the tip is a tip tip or a needle. - has_filter: Whether the tip has a filter. - liquid: The liquid to be dispensed. - jet: Whether the liquid is dispensed using a jet. - blow_out: This is called "empty" in the Hamilton Liquid editor and liquid class names, but - "blow out" in the firmware documentation. "Empty" in the firmware documentation means fully - emptying the tip, which is the terminology PyLabRobot adopts. Blow_out is the opposite of - partial dispense. - """ - - # Tip volumes from resources (mostly where they have filters) are slightly different from the ones - # in the liquid class mapping, so we need to map them here. If no mapping is found, we use the - # given maximal volume of the tip. - tip_volume = int( - { - 360.0: 300.0, - 1065.0: 1000.0, - 1250.0: 1000.0, - 4367.0: 4000.0, - 5420.0: 5000.0, - }.get(tip_volume, tip_volume) - ) - - return star_mapping.get( - (tip_volume, is_core, is_tip, has_filter, liquid, jet, blow_out), - None, - ) - - -star_mapping[(1000, False, False, False, Liquid.WATER, True, True)] = ( - _1000ulNeedleCRWater_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 520.0, - 50.0: 61.2, - 0.0: 0.0, - 20.0: 22.5, - 100.0: 113.0, - 10.0: 11.1, - 200.0: 214.0, - 1000.0: 1032.0, - }, +star_mapping[(1000, False, False, False, Liquid.WATER, True, True)] = \ +_1000ulNeedleCRWater_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 520.0, 50.0: 61.2, 0.0: 0.0, 20.0: 22.5, 100.0: 113.0, 10.0: 11.1, 200.0: 214.0, 1000.0: 1032.0}, aspiration_flow_rate=500.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=0.0, @@ -83,21 +31,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = ( - _1000ulNeedleCRWater_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 520.0, - 50.0: 62.2, - 0.0: 0.0, - 20.0: 32.0, - 100.0: 115.5, - 1000.0: 1032.0, - }, +star_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = \ +_1000ulNeedleCRWater_DispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 520.0, 50.0: 62.2, 0.0: 0.0, 20.0: 32.0, 100.0: 115.5, 1000.0: 1032.0}, aspiration_flow_rate=500.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=0.0, @@ -114,21 +54,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # -star_mapping[(1000, False, False, False, Liquid.WATER, False, True)] = ( - _1000ulNeedleCRWater_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 50.0: 59.0, - 0.0: 0.0, - 20.0: 25.9, - 10.0: 12.9, - 1000.0: 1000.0, - }, +star_mapping[(1000, False, False, False, Liquid.WATER, False, True)] = \ +_1000ulNeedleCRWater_DispenseSurface_Empty = HamiltonLiquidClass( + curve={50.0: 59.0, 0.0: 0.0, 20.0: 25.9, 10.0: 12.9, 1000.0: 1000.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=1.0, @@ -145,21 +78,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # -star_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = ( - _1000ulNeedleCRWater_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 50.0: 55.0, - 0.0: 0.0, - 20.0: 25.9, - 10.0: 12.9, - 1000.0: 1000.0, - }, +star_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = \ +_1000ulNeedleCRWater_DispenseSurface_Part = HamiltonLiquidClass( + curve={50.0: 55.0, 0.0: 0.0, 20.0: 25.9, 10.0: 12.9, 1000.0: 1000.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=1.0, @@ -176,7 +102,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -194,18 +120,9 @@ def get_star_liquid_class( # 200 1.25 - 0.51 # 500 0.91 0.02 # 1000 0.66 - 0.46 -star_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = ( - _1000ulNeedle_Water_DispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 530.0, - 50.0: 56.0, - 0.0: 0.0, - 100.0: 110.0, - 20.0: 22.5, - 1000.0: 1055.0, - 200.0: 214.0, - }, +star_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = \ +_1000ulNeedle_Water_DispenseJet = HamiltonLiquidClass( + curve={500.0: 530.0, 50.0: 56.0, 0.0: 0.0, 100.0: 110.0, 20.0: 22.5, 1000.0: 1055.0, 200.0: 214.0}, aspiration_flow_rate=500.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=0.0, @@ -222,7 +139,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=0.4, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -241,9 +158,8 @@ def get_star_liquid_class( # 20 10.12 - 4.66 # 50 3.79 - 1.18 # -star_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = ( - _1000ulNeedle_Water_DispenseSurface -) = HamiltonLiquidClass( +star_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = \ +_1000ulNeedle_Water_DispenseSurface = HamiltonLiquidClass( curve={50.0: 59.0, 0.0: 0.0, 20.0: 25.9, 1000.0: 1000.0}, aspiration_flow_rate=500.0, aspiration_mix_flow_rate=500.0, @@ -261,21 +177,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=0.4, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, False, False, Liquid.WATER, False, True)] = ( - _10ulNeedleCRWater_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.7, - 0.5: 0.5, - 0.0: 0.0, - 1.0: 1.2, - 2.0: 2.4, - 10.0: 11.4, - }, +star_mapping[(10, False, False, False, Liquid.WATER, False, True)] = \ +_10ulNeedleCRWater_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.7, 0.5: 0.5, 0.0: 0.0, 1.0: 1.2, 2.0: 2.4, 10.0: 11.4}, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, aspiration_air_transport_volume=1.0, @@ -292,21 +200,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, False, False, Liquid.WATER, False, False)] = ( - _10ulNeedleCRWater_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 5.0: 5.7, - 0.5: 0.5, - 0.0: 0.0, - 1.0: 1.2, - 2.0: 2.4, - 10.0: 11.4, - }, +star_mapping[(10, False, False, False, Liquid.WATER, False, False)] = \ +_10ulNeedleCRWater_DispenseSurface_Part = HamiltonLiquidClass( + curve={5.0: 5.7, 0.5: 0.5, 0.0: 0.0, 1.0: 1.2, 2.0: 2.4, 10.0: 11.4}, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, aspiration_air_transport_volume=1.0, @@ -323,13 +223,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, True, Liquid.DMSO, True, False)] = ( - _150ul_Piercing_Tip_Filter_DMSO_DispenseJet_Aliquot -) = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.DMSO, True, False)] = \ +_150ul_Piercing_Tip_Filter_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( curve={150.0: 150.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=180.0, aspiration_mix_flow_rate=100.0, @@ -347,13 +246,12 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, True, Liquid.DMSO, True, True)] = ( - _150ul_Piercing_Tip_Filter_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.DMSO, True, True)] = \ +_150ul_Piercing_Tip_Filter_DMSO_DispenseJet_Empty = HamiltonLiquidClass( curve={150.0: 154.0, 50.0: 52.9, 0.0: 0.0, 20.0: 21.8}, aspiration_flow_rate=180.0, aspiration_mix_flow_rate=100.0, @@ -371,22 +269,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, True, Liquid.DMSO, False, True)] = ( - _150ul_Piercing_Tip_Filter_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 3.0: 4.5, - 5.0: 6.5, - 150.0: 155.0, - 50.0: 53.7, - 0.0: 0.0, - 10.0: 12.0, - 2.0: 3.0, - }, +star_mapping[(50, False, True, True, Liquid.DMSO, False, True)] = \ +_150ul_Piercing_Tip_Filter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={3.0: 4.5, 5.0: 6.5, 150.0: 155.0, 50.0: 53.7, 0.0: 0.0, 10.0: 12.0, 2.0: 3.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -403,7 +292,7 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -424,9 +313,8 @@ def get_star_liquid_class( # 100 1.67 -0.35 # 300 0.46 -0.61 # -star_mapping[(50, False, True, True, Liquid.ETHANOL, True, True)] = ( - _150ul_Piercing_Tip_Filter_Ethanol_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.ETHANOL, True, True)] = \ +_150ul_Piercing_Tip_Filter_Ethanol_DispenseJet_Empty = HamiltonLiquidClass( curve={150.0: 166.0, 50.0: 58.3, 0.0: 0.0, 20.0: 25.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=50.0, @@ -444,7 +332,7 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -466,18 +354,9 @@ def get_star_liquid_class( # 20 0.95 2.97 # 50 0.31 -0.10 # -star_mapping[(50, False, True, True, Liquid.ETHANOL, False, True)] = ( - _150ul_Piercing_Tip_Filter_Ethanol_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 3.0: 5.0, - 5.0: 7.6, - 150.0: 165.0, - 50.0: 56.9, - 0.0: 0.0, - 10.0: 13.2, - 2.0: 3.3, - }, +star_mapping[(50, False, True, True, Liquid.ETHANOL, False, True)] = \ +_150ul_Piercing_Tip_Filter_Ethanol_DispenseSurface_Empty = HamiltonLiquidClass( + curve={3.0: 5.0, 5.0: 7.6, 150.0: 165.0, 50.0: 56.9, 0.0: 0.0, 10.0: 13.2, 2.0: 3.3}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=7.0, @@ -494,7 +373,7 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -517,19 +396,9 @@ def get_star_liquid_class( # 300 1.08 -0.87 # # -star_mapping[(50, False, True, True, Liquid.GLYCERIN80, False, True)] = ( - _150ul_Piercing_Tip_Filter_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 3.0: 4.5, - 5.0: 7.2, - 150.0: 167.5, - 50.0: 60.0, - 0.0: 0.0, - 1.0: 2.7, - 10.0: 13.0, - 2.0: 2.5, - }, +star_mapping[(50, False, True, True, Liquid.GLYCERIN80, False, True)] = \ +_150ul_Piercing_Tip_Filter_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={3.0: 4.5, 5.0: 7.2, 150.0: 167.5, 50.0: 60.0, 0.0: 0.0, 1.0: 2.7, 10.0: 13.0, 2.0: 2.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -546,7 +415,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -566,9 +435,8 @@ def get_star_liquid_class( # 100 0.81 0.99 # 300 1.00 0.65 # -star_mapping[(50, False, True, True, Liquid.SERUM, True, True)] = ( - _150ul_Piercing_Tip_Filter_Serum_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.SERUM, True, True)] = \ +_150ul_Piercing_Tip_Filter_Serum_DispenseJet_Empty = HamiltonLiquidClass( curve={150.0: 162.0, 50.0: 55.9, 0.0: 0.0, 20.0: 23.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -586,7 +454,7 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -609,18 +477,9 @@ def get_star_liquid_class( # 50 1.39 -0.12 # # -star_mapping[(50, False, True, True, Liquid.SERUM, False, True)] = ( - _150ul_Piercing_Tip_Filter_Serum_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 3.0: 3.4, - 5.0: 5.9, - 150.0: 161.5, - 50.0: 56.2, - 0.0: 0.0, - 10.0: 11.6, - 2.0: 2.2, - }, +star_mapping[(50, False, True, True, Liquid.SERUM, False, True)] = \ +_150ul_Piercing_Tip_Filter_Serum_DispenseSurface_Empty = HamiltonLiquidClass( + curve={3.0: 3.4, 5.0: 5.9, 150.0: 161.5, 50.0: 56.2, 0.0: 0.0, 10.0: 11.6, 2.0: 2.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -637,13 +496,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, True, Liquid.WATER, True, False)] = ( - _150ul_Piercing_Tip_Filter_Water_DispenseJet_Aliquot -) = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.WATER, True, False)] = \ +_150ul_Piercing_Tip_Filter_Water_DispenseJet_Aliquot = HamiltonLiquidClass( curve={150.0: 150.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -661,23 +519,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -star_mapping[(50, False, True, True, Liquid.WATER, True, True)] = ( - _150ul_Piercing_Tip_Filter_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 6.6, - 150.0: 159.1, - 50.0: 55.0, - 0.0: 0.0, - 100.0: 107.0, - 1.0: 1.6, - 20.0: 22.9, - 10.0: 12.2, - }, +star_mapping[(50, False, True, True, Liquid.WATER, True, True)] = \ +_150ul_Piercing_Tip_Filter_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={5.0: 6.6, 150.0: 159.1, 50.0: 55.0, 0.0: 0.0, 100.0: 107.0, 1.0: 1.6, 20.0: 22.9, 10.0: 12.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -694,23 +542,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, True, Liquid.WATER, False, True)] = ( - _150ul_Piercing_Tip_Filter_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 3.0: 3.5, - 5.0: 6.5, - 150.0: 158.1, - 50.0: 54.5, - 0.0: 0.0, - 1.0: 1.6, - 10.0: 11.9, - 2.0: 2.8, - }, +star_mapping[(50, False, True, True, Liquid.WATER, False, True)] = \ +_150ul_Piercing_Tip_Filter_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={3.0: 3.5, 5.0: 6.5, 150.0: 158.1, 50.0: 54.5, 0.0: 0.0, 1.0: 1.6, 10.0: 11.9, 2.0: 2.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -727,13 +565,12 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, False, Liquid.DMSO, True, True)] = ( - _250ul_Piercing_Tip_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.DMSO, True, True)] = \ +_250ul_Piercing_Tip_DMSO_DispenseJet_Empty = HamiltonLiquidClass( curve={250.0: 255.5, 50.0: 52.9, 0.0: 0.0, 20.0: 21.8}, aspiration_flow_rate=180.0, aspiration_mix_flow_rate=100.0, @@ -751,22 +588,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, False, Liquid.DMSO, False, True)] = ( - _250ul_Piercing_Tip_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 3.0: 4.2, - 5.0: 6.5, - 250.0: 256.0, - 50.0: 53.7, - 0.0: 0.0, - 10.0: 12.0, - 2.0: 3.0, - }, +star_mapping[(50, False, True, False, Liquid.DMSO, False, True)] = \ +_250ul_Piercing_Tip_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={3.0: 4.2, 5.0: 6.5, 250.0: 256.0, 50.0: 53.7, 0.0: 0.0, 10.0: 12.0, 2.0: 3.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -783,7 +611,7 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -804,9 +632,8 @@ def get_star_liquid_class( # 100 1.67 -0.35 # 300 0.46 -0.61 # -star_mapping[(50, False, True, False, Liquid.ETHANOL, True, True)] = ( - _250ul_Piercing_Tip_Ethanol_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.ETHANOL, True, True)] = \ +_250ul_Piercing_Tip_Ethanol_DispenseJet_Empty = HamiltonLiquidClass( curve={250.0: 270.2, 50.0: 59.2, 0.0: 0.0, 20.0: 27.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=50.0, @@ -824,7 +651,7 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -846,17 +673,9 @@ def get_star_liquid_class( # 20 0.95 2.97 # 50 0.31 -0.10 # -star_mapping[(50, False, True, False, Liquid.ETHANOL, False, True)] = ( - _250ul_Piercing_Tip_Ethanol_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 3.0: 5.0, - 5.0: 9.6, - 250.0: 270.5, - 50.0: 58.0, - 0.0: 0.0, - 10.0: 14.8, - }, +star_mapping[(50, False, True, False, Liquid.ETHANOL, False, True)] = \ +_250ul_Piercing_Tip_Ethanol_DispenseSurface_Empty = HamiltonLiquidClass( + curve={3.0: 5.0, 5.0: 9.6, 250.0: 270.5, 50.0: 58.0, 0.0: 0.0, 10.0: 14.8}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=10.0, @@ -873,7 +692,7 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -896,18 +715,9 @@ def get_star_liquid_class( # 300 1.08 -0.87 # # -star_mapping[(50, False, True, False, Liquid.GLYCERIN80, False, True)] = ( - _250ul_Piercing_Tip_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 3.0: 4.5, - 5.0: 7.2, - 250.0: 289.0, - 50.0: 65.0, - 0.0: 0.0, - 1.0: 2.7, - 10.0: 13.9, - }, +star_mapping[(50, False, True, False, Liquid.GLYCERIN80, False, True)] = \ +_250ul_Piercing_Tip_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={3.0: 4.5, 5.0: 7.2, 250.0: 289.0, 50.0: 65.0, 0.0: 0.0, 1.0: 2.7, 10.0: 13.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -924,7 +734,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -944,9 +754,8 @@ def get_star_liquid_class( # 100 0.81 0.99 # 300 1.00 0.65 # -star_mapping[(50, False, True, False, Liquid.SERUM, True, True)] = ( - _250ul_Piercing_Tip_Serum_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.SERUM, True, True)] = \ +_250ul_Piercing_Tip_Serum_DispenseJet_Empty = HamiltonLiquidClass( curve={250.0: 265.0, 50.0: 56.4, 0.0: 0.0, 20.0: 23.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -964,7 +773,7 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -987,17 +796,9 @@ def get_star_liquid_class( # 50 1.39 -0.12 # # -star_mapping[(50, False, True, False, Liquid.SERUM, False, True)] = ( - _250ul_Piercing_Tip_Serum_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 3.0: 3.4, - 5.0: 5.9, - 250.0: 264.2, - 50.0: 56.2, - 0.0: 0.0, - 10.0: 11.6, - }, +star_mapping[(50, False, True, False, Liquid.SERUM, False, True)] = \ +_250ul_Piercing_Tip_Serum_DispenseSurface_Empty = HamiltonLiquidClass( + curve={3.0: 3.4, 5.0: 5.9, 250.0: 264.2, 50.0: 56.2, 0.0: 0.0, 10.0: 11.6}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -1014,23 +815,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, False, Liquid.WATER, True, True)] = ( - _250ul_Piercing_Tip_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 6.6, - 250.0: 260.0, - 50.0: 55.0, - 0.0: 0.0, - 100.0: 107.0, - 1.0: 1.6, - 20.0: 22.5, - 10.0: 12.2, - }, +star_mapping[(50, False, True, False, Liquid.WATER, True, True)] = \ +_250ul_Piercing_Tip_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={5.0: 6.6, 250.0: 260.0, 50.0: 55.0, 0.0: 0.0, 100.0: 107.0, 1.0: 1.6, 20.0: 22.5, 10.0: 12.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -1047,23 +838,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, False, Liquid.WATER, False, True)] = ( - _250ul_Piercing_Tip_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 3.0: 4.0, - 5.0: 6.5, - 250.0: 259.0, - 50.0: 55.1, - 0.0: 0.0, - 1.0: 1.6, - 10.0: 12.6, - 2.0: 2.8, - }, +star_mapping[(50, False, True, False, Liquid.WATER, False, True)] = \ +_250ul_Piercing_Tip_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={3.0: 4.0, 5.0: 6.5, 250.0: 259.0, 50.0: 55.1, 0.0: 0.0, 1.0: 1.6, 10.0: 12.6, 2.0: 2.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -1080,7 +861,7 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1101,17 +882,9 @@ def get_star_liquid_class( # 100 1.04 0.05 # 300 0.63 -0.07 # -star_mapping[(300, False, False, False, Liquid.ACETONITRIL80WATER20, True, False)] = ( - _300ulNeedleAcetonitril80Water20DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 310.0, - 50.0: 57.8, - 0.0: 0.0, - 100.0: 106.5, - 20.0: 26.8, - 10.0: 16.5, - }, +star_mapping[(300, False, False, False, Liquid.ACETONITRIL80WATER20, True, False)] = \ +_300ulNeedleAcetonitril80Water20DispenseJet = HamiltonLiquidClass( + curve={300.0: 310.0, 50.0: 57.8, 0.0: 0.0, 100.0: 106.5, 20.0: 26.8, 10.0: 16.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=15.0, @@ -1128,20 +901,13 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, False, False, Liquid.WATER, True, True)] = ( - _300ulNeedleCRWater_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.0, - 50.0: 53.5, - 0.0: 0.0, - 100.0: 104.0, - 20.0: 22.3, - }, +star_mapping[(300, False, False, False, Liquid.WATER, True, True)] = \ +_300ulNeedleCRWater_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 313.0, 50.0: 53.5, 0.0: 0.0, 100.0: 104.0, 20.0: 22.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -1158,20 +924,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, False, False, Liquid.WATER, True, False)] = ( - _300ulNeedleCRWater_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 313.0, - 50.0: 59.5, - 0.0: 0.0, - 100.0: 109.0, - 20.0: 29.3, - }, +star_mapping[(300, False, False, False, Liquid.WATER, True, False)] = \ +_300ulNeedleCRWater_DispenseJet_Part = HamiltonLiquidClass( + curve={300.0: 313.0, 50.0: 59.5, 0.0: 0.0, 100.0: 109.0, 20.0: 29.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -1188,25 +947,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(300, False, False, False, Liquid.WATER, False, True)] = ( - _300ulNeedleCRWater_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 308.4, - 5.0: 6.8, - 50.0: 52.3, - 0.0: 0.0, - 100.0: 102.9, - 20.0: 22.3, - 1.0: 2.3, - 200.0: 205.8, - 10.0: 11.7, - 2.0: 3.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(300, False, False, False, Liquid.WATER, False, True)] = \ +_300ulNeedleCRWater_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 308.4, 5.0: 6.8, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 2.3, 200.0: 205.8, 10.0: 11.7, 2.0: 3.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=1.0, @@ -1223,25 +970,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(300, False, False, False, Liquid.WATER, False, False)] = ( - _300ulNeedleCRWater_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 308.4, - 5.0: 6.8, - 50.0: 52.3, - 0.0: 0.0, - 100.0: 102.9, - 20.0: 22.3, - 1.0: 2.3, - 200.0: 205.8, - 10.0: 11.7, - 2.0: 3.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(300, False, False, False, Liquid.WATER, False, False)] = \ +_300ulNeedleCRWater_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 308.4, 5.0: 6.8, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 2.3, 200.0: 205.8, 10.0: 11.7, 2.0: 3.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=1.0, @@ -1258,7 +993,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1278,16 +1013,9 @@ def get_star_liquid_class( # 100 0.55 -0.01 # 300 0.71 0.39 # -star_mapping[(300, False, False, False, Liquid.DIMETHYLSULFOXID, True, False)] = ( - _300ulNeedleDMSODispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 317.0, - 50.0: 53.5, - 0.0: 0.0, - 100.0: 106.5, - 20.0: 21.3, - }, +star_mapping[(300, False, False, False, Liquid.DIMETHYLSULFOXID, True, False)] = \ +_300ulNeedleDMSODispenseJet = HamiltonLiquidClass( + curve={300.0: 317.0, 50.0: 53.5, 0.0: 0.0, 100.0: 106.5, 20.0: 21.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -1304,7 +1032,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1325,17 +1053,9 @@ def get_star_liquid_class( # 50 1.32 -1.05 # # -star_mapping[(300, False, False, False, Liquid.DIMETHYLSULFOXID, False, False)] = ( - _300ulNeedleDMSODispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 6.0, - 50.0: 52.3, - 0.0: 0.0, - 20.0: 22.3, - 10.0: 11.4, - 2.0: 2.5, - }, +star_mapping[(300, False, False, False, Liquid.DIMETHYLSULFOXID, False, False)] = \ +_300ulNeedleDMSODispenseSurface = HamiltonLiquidClass( + curve={5.0: 6.0, 50.0: 52.3, 0.0: 0.0, 20.0: 22.3, 10.0: 11.4, 2.0: 2.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=5.0, @@ -1352,7 +1072,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1373,16 +1093,9 @@ def get_star_liquid_class( # 100 1.67 -0.35 # 300 0.46 -0.61 # -star_mapping[(300, False, False, False, Liquid.ETHANOL, True, False)] = ( - _300ulNeedleEtOHDispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 317.0, - 50.0: 57.8, - 0.0: 0.0, - 100.0: 109.0, - 20.0: 25.3, - }, +star_mapping[(300, False, False, False, Liquid.ETHANOL, True, False)] = \ +_300ulNeedleEtOHDispenseJet = HamiltonLiquidClass( + curve={300.0: 317.0, 50.0: 57.8, 0.0: 0.0, 100.0: 109.0, 20.0: 25.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=15.0, @@ -1399,7 +1112,7 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1421,9 +1134,8 @@ def get_star_liquid_class( # 20 0.95 2.97 # 50 0.31 -0.10 # -star_mapping[(300, False, False, False, Liquid.ETHANOL, False, False)] = ( - _300ulNeedleEtOHDispenseSurface -) = HamiltonLiquidClass( +star_mapping[(300, False, False, False, Liquid.ETHANOL, False, False)] = \ +_300ulNeedleEtOHDispenseSurface = HamiltonLiquidClass( curve={5.0: 7.2, 50.0: 55.0, 0.0: 0.0, 20.0: 24.5, 10.0: 13.1}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -1441,7 +1153,7 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1464,20 +1176,9 @@ def get_star_liquid_class( # 300 1.08 -0.87 # # -star_mapping[(300, False, False, False, Liquid.GLYCERIN80, False, False)] = ( - _300ulNeedleGlycerin80DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 325.0, - 5.0: 8.0, - 50.0: 61.3, - 0.0: 0.0, - 100.0: 117.0, - 20.0: 26.0, - 1.0: 2.7, - 10.0: 13.9, - 2.0: 4.2, - }, +star_mapping[(300, False, False, False, Liquid.GLYCERIN80, False, False)] = \ +_300ulNeedleGlycerin80DispenseSurface = HamiltonLiquidClass( + curve={300.0: 325.0, 5.0: 8.0, 50.0: 61.3, 0.0: 0.0, 100.0: 117.0, 20.0: 26.0, 1.0: 2.7, 10.0: 13.9, 2.0: 4.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=5.0, @@ -1494,7 +1195,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1514,16 +1215,9 @@ def get_star_liquid_class( # 100 0.81 0.99 # 300 1.00 0.65 # -star_mapping[(300, False, False, False, Liquid.SERUM, True, False)] = ( - _300ulNeedleSerumDispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 313.0, - 50.0: 53.5, - 0.0: 0.0, - 100.0: 105.0, - 20.0: 21.3, - }, +star_mapping[(300, False, False, False, Liquid.SERUM, True, False)] = \ +_300ulNeedleSerumDispenseJet = HamiltonLiquidClass( + curve={300.0: 313.0, 50.0: 53.5, 0.0: 0.0, 100.0: 105.0, 20.0: 21.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -1540,7 +1234,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1563,18 +1257,9 @@ def get_star_liquid_class( # 50 1.39 -0.12 # # -star_mapping[(300, False, False, False, Liquid.SERUM, False, False)] = ( - _300ulNeedleSerumDispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 6.0, - 50.0: 52.3, - 0.0: 0.0, - 20.0: 22.3, - 1.0: 2.2, - 10.0: 11.9, - 2.0: 3.2, - }, +star_mapping[(300, False, False, False, Liquid.SERUM, False, False)] = \ +_300ulNeedleSerumDispenseSurface = HamiltonLiquidClass( + curve={5.0: 6.0, 50.0: 52.3, 0.0: 0.0, 20.0: 22.3, 1.0: 2.2, 10.0: 11.9, 2.0: 3.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -1591,7 +1276,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1611,16 +1296,9 @@ def get_star_liquid_class( # 100 0.81 0.99 # 300 1.00 0.65 # -star_mapping[(300, False, False, False, Liquid.SERUM, True, False)] = ( - _300ulNeedle_Serum_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 313.0, - 50.0: 53.5, - 0.0: 0.0, - 100.0: 105.0, - 20.0: 21.3, - }, +star_mapping[(300, False, False, False, Liquid.SERUM, True, False)] = \ +_300ulNeedle_Serum_DispenseJet = HamiltonLiquidClass( + curve={300.0: 313.0, 50.0: 53.5, 0.0: 0.0, 100.0: 105.0, 20.0: 21.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -1637,7 +1315,7 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1660,19 +1338,9 @@ def get_star_liquid_class( # 50 1.39 -0.12 # # -star_mapping[(300, False, False, False, Liquid.SERUM, False, False)] = ( - _300ulNeedle_Serum_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 350.0, - 5.0: 6.0, - 50.0: 52.3, - 0.0: 0.0, - 20.0: 22.3, - 1.0: 2.2, - 10.0: 11.9, - 2.0: 3.2, - }, +star_mapping[(300, False, False, False, Liquid.SERUM, False, False)] = \ +_300ulNeedle_Serum_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 350.0, 5.0: 6.0, 50.0: 52.3, 0.0: 0.0, 20.0: 22.3, 1.0: 2.2, 10.0: 11.9, 2.0: 3.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -1689,7 +1357,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1710,16 +1378,9 @@ def get_star_liquid_class( # 200 0.16 0.55 # 300 0.17 0.35 # -star_mapping[(300, False, False, False, Liquid.WATER, True, False)] = ( - _300ulNeedle_Water_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 313.0, - 50.0: 53.5, - 0.0: 0.0, - 100.0: 105.0, - 20.0: 22.3, - }, +star_mapping[(300, False, False, False, Liquid.WATER, True, False)] = \ +_300ulNeedle_Water_DispenseJet = HamiltonLiquidClass( + curve={300.0: 313.0, 50.0: 53.5, 0.0: 0.0, 100.0: 105.0, 20.0: 22.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -1736,7 +1397,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1758,21 +1419,9 @@ def get_star_liquid_class( # 20 0.63 0.73 # # -star_mapping[(300, False, False, False, Liquid.WATER, False, False)] = ( - _300ulNeedle_Water_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 308.4, - 5.0: 6.5, - 50.0: 52.3, - 0.0: 0.0, - 100.0: 102.9, - 20.0: 22.3, - 1.0: 1.1, - 200.0: 205.8, - 10.0: 12.0, - 2.0: 2.1, - }, +star_mapping[(300, False, False, False, Liquid.WATER, False, False)] = \ +_300ulNeedle_Water_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 308.4, 5.0: 6.5, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 1.1, 200.0: 205.8, 10.0: 12.0, 2.0: 2.1}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -1789,27 +1438,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=0.4, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # Liquid class for washing rocket tips with CO-RE 384 head in 96 DC wash station. -star_mapping[(300, True, True, False, Liquid.WATER, False, False)] = ( - _300ul_RocketTip_384COREHead_96Washer_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 330.0, - 5.0: 6.3, - 0.5: 0.9, - 50.0: 55.1, - 0.0: 0.0, - 1.0: 1.6, - 20.0: 23.2, - 100.0: 107.2, - 2.0: 2.8, - 10.0: 11.9, - 200.0: 211.0, - }, +star_mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ +_300ul_RocketTip_384COREHead_96Washer_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 330.0, 5.0: 6.3, 0.5: 0.9, 50.0: 55.1, 0.0: 0.0, 1.0: 1.6, 20.0: 23.2, 100.0: 107.2, 2.0: 2.8, 10.0: 11.9, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=150.0, aspiration_air_transport_volume=0.0, @@ -1826,22 +1462,14 @@ def get_star_liquid_class( dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # Evaluation -star_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = ( - _300ul_RocketTip_384COREHead_DMSO_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 150.0: 150.0, - 50.0: 50.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - }, +star_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ +_300ul_RocketTip_384COREHead_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 150.0: 150.0, 50.0: 50.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -1858,21 +1486,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=120.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # Evaluation -star_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = ( - _300ul_RocketTip_384COREHead_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 303.5, - 0.0: 0.0, - 100.0: 105.8, - 200.0: 209.5, - 10.0: 11.4, - }, +star_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ +_300ul_RocketTip_384COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 303.5, 0.0: 0.0, 100.0: 105.8, 200.0: 209.5, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -1889,21 +1510,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # Evaluation -star_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = ( - _300ul_RocketTip_384COREHead_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 308.0, - 0.0: 0.0, - 100.0: 105.5, - 200.0: 209.0, - 10.0: 12.0, - }, +star_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ +_300ul_RocketTip_384COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 308.0, 0.0: 0.0, 100.0: 105.5, 200.0: 209.0, 10.0: 12.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -1920,21 +1534,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # Evaluation -star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( - _300ul_RocketTip_384COREHead_Water_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 309.0, - 0.0: 0.0, - 100.0: 106.5, - 20.0: 22.3, - 200.0: 207.0, - }, +star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ +_300ul_RocketTip_384COREHead_Water_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 309.0, 0.0: 0.0, 100.0: 106.5, 20.0: 22.3, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -1951,21 +1558,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=20.0, + dispense_stop_back_volume=20.0 ) # Evaluation -star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( - _300ul_RocketTip_384COREHead_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 309.0, - 0.0: 0.0, - 100.0: 106.5, - 20.0: 22.3, - 200.0: 207.0, - }, +star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ +_300ul_RocketTip_384COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 309.0, 0.0: 0.0, 100.0: 106.5, 20.0: 22.3, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -1982,21 +1582,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # Evaluation -star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( - _300ul_RocketTip_384COREHead_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 314.3, - 0.0: 0.0, - 100.0: 109.0, - 200.0: 214.7, - 10.0: 12.7, - }, +star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ +_300ul_RocketTip_384COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 314.3, 0.0: 0.0, 100.0: 109.0, 200.0: 214.7, 10.0: 12.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -2013,13 +1606,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(30, True, True, False, Liquid.DMSO, True, True)] = ( - _30ulTip_384COREHead_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(30, True, True, False, Liquid.DMSO, True, True)] = \ +_30ulTip_384COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( curve={5.0: 5.0, 15.0: 15.3, 30.0: 30.7, 0.0: 0.0, 1.0: 1.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2037,13 +1629,12 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(30, True, True, False, Liquid.DMSO, False, True)] = ( - _30ulTip_384COREHead_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( +star_mapping[(30, True, True, False, Liquid.DMSO, False, True)] = \ +_30ulTip_384COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 4.9, 15.0: 15.1, 30.0: 30.0, 0.0: 0.0, 1.0: 0.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2061,13 +1652,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(30, True, True, False, Liquid.ETHANOL, True, True)] = ( - _30ulTip_384COREHead_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(30, True, True, False, Liquid.ETHANOL, True, True)] = \ +_30ulTip_384COREHead_EtOH_DispenseJet_Empty = HamiltonLiquidClass( curve={5.0: 6.54, 15.0: 18.36, 30.0: 33.8, 0.0: 0.0, 1.0: 1.8}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2085,13 +1675,12 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(30, True, True, False, Liquid.ETHANOL, False, True)] = ( - _30ulTip_384COREHead_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( +star_mapping[(30, True, True, False, Liquid.ETHANOL, False, True)] = \ +_30ulTip_384COREHead_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 6.2, 15.0: 16.9, 30.0: 33.1, 0.0: 0.0, 1.0: 1.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2109,23 +1698,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(30, True, True, False, Liquid.GLYCERIN80, False, True)] = ( - _30ulTip_384COREHead_Glyzerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 6.3, - 0.5: 0.9, - 40.0: 44.0, - 0.0: 0.0, - 20.0: 22.2, - 1.0: 1.6, - 10.0: 11.9, - 2.0: 2.8, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(30, True, True, False, Liquid.GLYCERIN80, False, True)] = \ +_30ulTip_384COREHead_Glyzerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 6.3, 0.5: 0.9, 40.0: 44.0, 0.0: 0.0, 20.0: 22.2, 1.0: 1.6, 10.0: 11.9, 2.0: 2.8}, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -2142,13 +1721,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(30, True, True, False, Liquid.WATER, True, True)] = ( - _30ulTip_384COREHead_Water_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(30, True, True, False, Liquid.WATER, True, True)] = \ +_30ulTip_384COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( curve={5.0: 6.0, 15.0: 16.5, 30.0: 32.3, 0.0: 0.0, 1.0: 1.6}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2166,13 +1744,12 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(30, True, True, False, Liquid.WATER, False, True)] = ( - _30ulTip_384COREHead_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( +star_mapping[(30, True, True, False, Liquid.WATER, False, True)] = \ +_30ulTip_384COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 5.6, 15.0: 15.9, 30.0: 31.3, 0.0: 0.0, 1.0: 1.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2190,23 +1767,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(30, True, True, False, Liquid.WATER, False, False)] = ( - _30ulTip_384COREWasher_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 6.3, - 0.5: 0.9, - 40.0: 44.0, - 0.0: 0.0, - 1.0: 1.6, - 20.0: 22.2, - 2.0: 2.8, - 10.0: 11.9, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(30, True, True, False, Liquid.WATER, False, False)] = \ +_30ulTip_384COREWasher_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 6.3, 0.5: 0.9, 40.0: 44.0, 0.0: 0.0, 1.0: 1.6, 20.0: 22.2, 2.0: 2.8, 10.0: 11.9}, aspiration_flow_rate=10.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=0.0, @@ -2223,25 +1790,13 @@ def get_star_liquid_class( dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(4000, False, True, False, Liquid.DMSO, True, False)] = ( - _4mlTF_DMSO_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 3500.0: 3715.0, - 500.0: 631.0, - 2500.0: 2691.0, - 1500.0: 1667.0, - 4000.0: 4224.0, - 3000.0: 3202.0, - 0.0: 0.0, - 2000.0: 2179.0, - 100.0: 211.0, - 1000.0: 1151.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(4000, False, True, False, Liquid.DMSO, True, False)] = \ +_4mlTF_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={3500.0: 3715.0, 500.0: 631.0, 2500.0: 2691.0, 1500.0: 1667.0, 4000.0: 4224.0, 3000.0: 3202.0, 0.0: 0.0, 2000.0: 2179.0, 100.0: 211.0, 1000.0: 1151.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2258,23 +1813,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=20.0, -) - - -star_mapping[(4000, False, True, False, Liquid.DMSO, True, True)] = ( - _4mlTF_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 540.0, - 50.0: 61.5, - 4000.0: 4102.0, - 3000.0: 3083.0, - 0.0: 0.0, - 2000.0: 2070.0, - 100.0: 116.5, - 1000.0: 1060.0, - }, + dispense_stop_back_volume=20.0 +) + + +star_mapping[(4000, False, True, False, Liquid.DMSO, True, True)] = \ +_4mlTF_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 540.0, 50.0: 61.5, 4000.0: 4102.0, 3000.0: 3083.0, 0.0: 0.0, 2000.0: 2070.0, 100.0: 116.5, 1000.0: 1060.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2291,24 +1836,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(4000, False, True, False, Liquid.DMSO, False, True)] = ( - _4mlTF_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 536.5, - 50.0: 62.3, - 4000.0: 4128.0, - 3000.0: 3109.0, - 0.0: 0.0, - 2000.0: 2069.0, - 100.0: 116.6, - 1000.0: 1054.0, - 10.0: 15.5, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(4000, False, True, False, Liquid.DMSO, False, True)] = \ +_4mlTF_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 536.5, 50.0: 62.3, 4000.0: 4128.0, 3000.0: 3109.0, 0.0: 0.0, 2000.0: 2069.0, 100.0: 116.6, 1000.0: 1054.0, 10.0: 15.5}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2325,27 +1859,14 @@ def get_star_liquid_class( dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=500.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # First two times mixing with max volume. -star_mapping[(4000, False, True, False, Liquid.ETHANOL, True, False)] = ( - _4mlTF_EtOH_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 3500.0: 3500.0, - 500.0: 500.0, - 2500.0: 2500.0, - 1500.0: 1500.0, - 4000.0: 4000.0, - 3000.0: 3000.0, - 0.0: 0.0, - 2000.0: 2000.0, - 100.0: 100.0, - 1000.0: 1000.0, - }, +star_mapping[(4000, False, True, False, Liquid.ETHANOL, True, False)] = \ +_4mlTF_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 3500.0: 3500.0, 500.0: 500.0, 2500.0: 2500.0, 1500.0: 1500.0, 4000.0: 4000.0, 3000.0: 3000.0, 0.0: 0.0, 2000.0: 2000.0, 100.0: 100.0, 1000.0: 1000.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=2000.0, aspiration_air_transport_volume=0.0, @@ -2362,23 +1883,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(4000, False, True, False, Liquid.ETHANOL, True, True)] = ( - _4mlTF_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 563.0, - 50.0: 72.0, - 4000.0: 4215.0, - 3000.0: 3190.0, - 0.0: 0.0, - 2000.0: 2178.0, - 100.0: 127.5, - 1000.0: 1095.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(4000, False, True, False, Liquid.ETHANOL, True, True)] = \ +_4mlTF_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 563.0, 50.0: 72.0, 4000.0: 4215.0, 3000.0: 3190.0, 0.0: 0.0, 2000.0: 2178.0, 100.0: 127.5, 1000.0: 1095.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=30.0, @@ -2395,24 +1906,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=30.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(4000, False, True, False, Liquid.ETHANOL, False, True)] = ( - _4mlTF_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 555.0, - 50.0: 68.0, - 4000.0: 4177.0, - 3000.0: 3174.0, - 0.0: 0.0, - 2000.0: 2151.0, - 100.0: 123.5, - 1000.0: 1085.0, - 10.0: 18.6, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(4000, False, True, False, Liquid.ETHANOL, False, True)] = \ +_4mlTF_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 555.0, 50.0: 68.0, 4000.0: 4177.0, 3000.0: 3174.0, 0.0: 0.0, 2000.0: 2151.0, 100.0: 123.5, 1000.0: 1085.0, 10.0: 18.6}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=30.0, @@ -2429,23 +1929,13 @@ def get_star_liquid_class( dispense_swap_speed=30.0, dispense_settling_time=1.0, dispense_stop_flow_rate=30.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(4000, False, True, False, Liquid.GLYCERIN80, True, True)] = ( - _4mlTF_Glycerin80_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 599.0, - 50.0: 89.0, - 4000.0: 4223.0, - 3000.0: 3211.0, - 0.0: 0.0, - 2000.0: 2195.0, - 100.0: 140.0, - 1000.0: 1159.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(4000, False, True, False, Liquid.GLYCERIN80, True, True)] = \ +_4mlTF_Glycerin80_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 599.0, 50.0: 89.0, 4000.0: 4223.0, 3000.0: 3211.0, 0.0: 0.0, 2000.0: 2195.0, 100.0: 140.0, 1000.0: 1159.0}, aspiration_flow_rate=1200.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=30.0, @@ -2462,24 +1952,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(4000, False, True, False, Liquid.GLYCERIN80, False, True)] = ( - _4mlTF_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 555.0, - 50.0: 71.0, - 4000.0: 4135.0, - 3000.0: 3122.0, - 0.0: 0.0, - 2000.0: 2101.0, - 100.0: 129.0, - 1000.0: 1083.0, - 10.0: 16.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(4000, False, True, False, Liquid.GLYCERIN80, False, True)] = \ +_4mlTF_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 555.0, 50.0: 71.0, 4000.0: 4135.0, 3000.0: 3122.0, 0.0: 0.0, 2000.0: 2101.0, 100.0: 129.0, 1000.0: 1083.0, 10.0: 16.0}, aspiration_flow_rate=1000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=0.0, @@ -2496,21 +1975,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(4000, False, True, False, Liquid.WATER, True, False)] = ( - _4mlTF_Water_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 4000.0: 4160.0, - 3000.0: 3160.0, - 0.0: 0.0, - 2000.0: 2160.0, - 100.0: 214.0, - 1000.0: 1148.0, - }, +star_mapping[(4000, False, True, False, Liquid.WATER, True, False)] = \ +_4mlTF_Water_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={4000.0: 4160.0, 3000.0: 3160.0, 0.0: 0.0, 2000.0: 2160.0, 100.0: 214.0, 1000.0: 1148.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2527,23 +1998,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=20.0, -) - - -star_mapping[(4000, False, True, False, Liquid.WATER, True, True)] = ( - _4mlTF_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 551.8, - 50.0: 66.4, - 4000.0: 4165.0, - 3000.0: 3148.0, - 0.0: 0.0, - 2000.0: 2128.0, - 100.0: 122.7, - 1000.0: 1082.0, - }, + dispense_stop_back_volume=20.0 +) + + +star_mapping[(4000, False, True, False, Liquid.WATER, True, True)] = \ +_4mlTF_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 551.8, 50.0: 66.4, 4000.0: 4165.0, 3000.0: 3148.0, 0.0: 0.0, 2000.0: 2128.0, 100.0: 122.7, 1000.0: 1082.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2560,24 +2021,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(4000, False, True, False, Liquid.WATER, False, True)] = ( - _4mlTF_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 547.0, - 50.0: 65.5, - 4000.0: 4145.0, - 3000.0: 3135.0, - 0.0: 0.0, - 2000.0: 2125.0, - 100.0: 120.9, - 1000.0: 1075.0, - 10.0: 14.5, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(4000, False, True, False, Liquid.WATER, False, True)] = \ +_4mlTF_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 547.0, 50.0: 65.5, 4000.0: 4145.0, 3000.0: 3135.0, 0.0: 0.0, 2000.0: 2125.0, 100.0: 120.9, 1000.0: 1075.0, 10.0: 14.5}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2594,13 +2044,12 @@ def get_star_liquid_class( dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=500.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = ( - _50ulTip_384COREHead_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ +_50ulTip_384COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 52.0, 0.0: 0.0, 20.0: 21.1, 10.0: 10.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2618,21 +2067,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = ( - _50ulTip_384COREHead_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.0, - 50.0: 51.1, - 30.0: 30.7, - 0.0: 0.0, - 1.0: 0.9, - 10.0: 10.1, - }, +star_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = \ +_50ulTip_384COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.0, 50.0: 51.1, 30.0: 30.7, 0.0: 0.0, 1.0: 0.9, 10.0: 10.1}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -2649,21 +2090,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = ( - _50ulTip_384COREHead_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 6.54, - 15.0: 18.36, - 50.0: 53.0, - 30.0: 33.8, - 0.0: 0.0, - 1.0: 1.8, - }, +star_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = \ +_50ulTip_384COREHead_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={5.0: 6.54, 15.0: 18.36, 50.0: 53.0, 30.0: 33.8, 0.0: 0.0, 1.0: 1.8}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=1.0, @@ -2680,22 +2113,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(50, True, True, False, Liquid.ETHANOL, False, True)] = ( - _50ulTip_384COREHead_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 6.2, - 15.0: 16.9, - 0.5: 1.0, - 50.0: 54.0, - 30.0: 33.1, - 0.0: 0.0, - 1.0: 1.5, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(50, True, True, False, Liquid.ETHANOL, False, True)] = \ +_50ulTip_384COREHead_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 6.2, 15.0: 16.9, 0.5: 1.0, 50.0: 54.0, 30.0: 33.1, 0.0: 0.0, 1.0: 1.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=2.0, @@ -2712,22 +2136,13 @@ def get_star_liquid_class( dispense_swap_speed=6.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(50, True, True, False, Liquid.GLYCERIN80, False, True)] = ( - _50ulTip_384COREHead_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.6, - 0.5: 0.65, - 50.0: 55.0, - 0.0: 0.0, - 30.0: 31.5, - 1.0: 1.2, - 10.0: 10.9, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(50, True, True, False, Liquid.GLYCERIN80, False, True)] = \ +_50ulTip_384COREHead_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.6, 0.5: 0.65, 50.0: 55.0, 0.0: 0.0, 30.0: 31.5, 1.0: 1.2, 10.0: 10.9}, aspiration_flow_rate=30.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=0.0, @@ -2744,13 +2159,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, False, Liquid.WATER, True, True)] = ( - _50ulTip_384COREHead_Water_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ +_50ulTip_384COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 53.6, 0.0: 0.0, 20.0: 22.4, 10.0: 11.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2768,21 +2182,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, False, Liquid.WATER, False, True)] = ( - _50ulTip_384COREHead_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.5, - 50.0: 52.2, - 30.0: 31.5, - 0.0: 0.0, - 1.0: 1.2, - 10.0: 11.3, - }, +star_mapping[(50, True, True, False, Liquid.WATER, False, True)] = \ +_50ulTip_384COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.5, 50.0: 52.2, 30.0: 31.5, 0.0: 0.0, 1.0: 1.2, 10.0: 11.3}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -2799,24 +2205,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(50, True, True, False, Liquid.WATER, False, False)] = ( - _50ulTip_384COREWasher_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 6.3, - 0.5: 0.9, - 50.0: 55.0, - 40.0: 44.0, - 0.0: 0.0, - 20.0: 22.2, - 1.0: 1.6, - 10.0: 11.9, - 2.0: 2.8, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(50, True, True, False, Liquid.WATER, False, False)] = \ +_50ulTip_384COREWasher_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 6.3, 0.5: 0.9, 50.0: 55.0, 40.0: 44.0, 0.0: 0.0, 20.0: 22.2, 1.0: 1.6, 10.0: 11.9, 2.0: 2.8}, aspiration_flow_rate=20.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=0.0, @@ -2833,22 +2228,13 @@ def get_star_liquid_class( dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = ( - _50ulTip_conductive_384COREHead_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.2, - 50.0: 50.6, - 30.0: 30.4, - 0.0: 0.0, - 1.0: 0.9, - 20.0: 21.1, - 10.0: 9.3, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ +_50ulTip_conductive_384COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={5.0: 5.2, 50.0: 50.6, 30.0: 30.4, 0.0: 0.0, 1.0: 0.9, 20.0: 21.1, 10.0: 9.3}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -2865,22 +2251,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = ( - _50ulTip_conductive_384COREHead_DMSO_DispenseJet_Empty_below5ul -) = HamiltonLiquidClass( - curve={ - 5.0: 5.2, - 50.0: 50.6, - 30.0: 30.4, - 0.0: 0.0, - 1.0: 0.9, - 20.0: 21.1, - 10.0: 9.3, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ +_50ulTip_conductive_384COREHead_DMSO_DispenseJet_Empty_below5ul = HamiltonLiquidClass( + curve={5.0: 5.2, 50.0: 50.6, 30.0: 30.4, 0.0: 0.0, 1.0: 0.9, 20.0: 21.1, 10.0: 9.3}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -2897,13 +2274,12 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, False, Liquid.DMSO, True, False)] = ( - _50ulTip_conductive_384COREHead_DMSO_DispenseJet_Part -) = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.DMSO, True, False)] = \ +_50ulTip_conductive_384COREHead_DMSO_DispenseJet_Part = HamiltonLiquidClass( curve={50.0: 50.0, 0.0: 0.0, 10.0: 10.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2921,24 +2297,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=5.0, -) - - -star_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = ( - _50ulTip_conductive_384COREHead_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 0.1: 0.05, - 0.25: 0.1, - 5.0: 4.95, - 0.5: 0.22, - 50.0: 50.0, - 30.0: 30.6, - 0.0: 0.0, - 1.0: 0.74, - 10.0: 9.95, - }, + dispense_stop_back_volume=5.0 +) + + +star_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = \ +_50ulTip_conductive_384COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={0.1: 0.05, 0.25: 0.1, 5.0: 4.95, 0.5: 0.22, 50.0: 50.0, 30.0: 30.6, 0.0: 0.0, 1.0: 0.74, 10.0: 9.95}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -2955,22 +2320,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = ( - _50ulTip_conductive_384COREHead_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 6.85, - 15.0: 18.36, - 50.0: 54.3, - 30.0: 33.6, - 0.0: 0.0, - 1.0: 1.5, - 10.0: 12.1, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = \ +_50ulTip_conductive_384COREHead_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={5.0: 6.85, 15.0: 18.36, 50.0: 54.3, 30.0: 33.6, 0.0: 0.0, 1.0: 1.5, 10.0: 12.1}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=1.0, @@ -2987,22 +2343,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = ( - _50ulTip_conductive_384COREHead_EtOH_DispenseJet_Empty_below5ul -) = HamiltonLiquidClass( - curve={ - 5.0: 6.85, - 15.0: 18.36, - 50.0: 54.3, - 30.0: 33.6, - 0.0: 0.0, - 1.0: 1.5, - 10.0: 12.1, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = \ +_50ulTip_conductive_384COREHead_EtOH_DispenseJet_Empty_below5ul = HamiltonLiquidClass( + curve={5.0: 6.85, 15.0: 18.36, 50.0: 54.3, 30.0: 33.6, 0.0: 0.0, 1.0: 1.5, 10.0: 12.1}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=1.0, @@ -3019,13 +2366,12 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, False, Liquid.ETHANOL, True, False)] = ( - _50ulTip_conductive_384COREHead_EtOH_DispenseJet_Part -) = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.ETHANOL, True, False)] = \ +_50ulTip_conductive_384COREHead_EtOH_DispenseJet_Part = HamiltonLiquidClass( curve={50.0: 50.0, 0.0: 0.0, 10.0: 10.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -3043,24 +2389,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=2.0, -) - - -star_mapping[(50, True, True, False, Liquid.ETHANOL, False, True)] = ( - _50ulTip_conductive_384COREHead_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 0.25: 0.3, - 5.0: 6.1, - 0.5: 0.65, - 15.0: 16.9, - 50.0: 52.7, - 30.0: 32.1, - 0.0: 0.0, - 1.0: 1.35, - 10.0: 11.3, - }, + dispense_stop_back_volume=2.0 +) + + +star_mapping[(50, True, True, False, Liquid.ETHANOL, False, True)] = \ +_50ulTip_conductive_384COREHead_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={0.25: 0.3, 5.0: 6.1, 0.5: 0.65, 15.0: 16.9, 50.0: 52.7, 30.0: 32.1, 0.0: 0.0, 1.0: 1.35, 10.0: 11.3}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=2.0, @@ -3077,23 +2412,13 @@ def get_star_liquid_class( dispense_swap_speed=6.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(50, True, True, False, Liquid.GLYCERIN80, False, True)] = ( - _50ulTip_conductive_384COREHead_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 0.25: 0.05, - 5.0: 5.5, - 0.5: 0.3, - 50.0: 51.9, - 30.0: 31.8, - 0.0: 0.0, - 1.0: 1.0, - 10.0: 10.9, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(50, True, True, False, Liquid.GLYCERIN80, False, True)] = \ +_50ulTip_conductive_384COREHead_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={0.25: 0.05, 5.0: 5.5, 0.5: 0.3, 50.0: 51.9, 30.0: 31.8, 0.0: 0.0, 1.0: 1.0, 10.0: 10.9}, aspiration_flow_rate=30.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=0.0, @@ -3110,23 +2435,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(50, True, True, False, Liquid.WATER, True, True)] = ( - _50ulTip_conductive_384COREHead_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.67, - 0.5: 0.27, - 50.0: 51.9, - 30.0: 31.5, - 0.0: 0.0, - 1.0: 1.06, - 20.0: 20.0, - 10.0: 10.9, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ +_50ulTip_conductive_384COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={5.0: 5.67, 0.5: 0.27, 50.0: 51.9, 30.0: 31.5, 0.0: 0.0, 1.0: 1.06, 20.0: 20.0, 10.0: 10.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -3143,23 +2458,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(50, True, True, False, Liquid.WATER, True, True)] = ( - _50ulTip_conductive_384COREHead_Water_DispenseJet_Empty_below5ul -) = HamiltonLiquidClass( - curve={ - 5.0: 5.67, - 0.5: 0.27, - 50.0: 51.9, - 30.0: 31.5, - 0.0: 0.0, - 1.0: 1.06, - 20.0: 20.0, - 10.0: 10.9, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ +_50ulTip_conductive_384COREHead_Water_DispenseJet_Empty_below5ul = HamiltonLiquidClass( + curve={5.0: 5.67, 0.5: 0.27, 50.0: 51.9, 30.0: 31.5, 0.0: 0.0, 1.0: 1.06, 20.0: 20.0, 10.0: 10.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -3176,13 +2481,12 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, False, Liquid.WATER, True, False)] = ( - _50ulTip_conductive_384COREHead_Water_DispenseJet_Part -) = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.WATER, True, False)] = \ +_50ulTip_conductive_384COREHead_Water_DispenseJet_Part = HamiltonLiquidClass( curve={50.0: 50.0, 0.0: 0.0, 10.0: 10.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -3200,24 +2504,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=2.0, -) - - -star_mapping[(50, True, True, False, Liquid.WATER, False, True)] = ( - _50ulTip_conductive_384COREHead_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 0.1: 0.1, - 0.25: 0.15, - 5.0: 5.6, - 0.5: 0.45, - 50.0: 51.0, - 30.0: 31.0, - 0.0: 0.0, - 1.0: 0.98, - 10.0: 10.7, - }, + dispense_stop_back_volume=2.0 +) + + +star_mapping[(50, True, True, False, Liquid.WATER, False, True)] = \ +_50ulTip_conductive_384COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={0.1: 0.1, 0.25: 0.15, 5.0: 5.6, 0.5: 0.45, 50.0: 51.0, 30.0: 31.0, 0.0: 0.0, 1.0: 0.98, 10.0: 10.7}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -3234,25 +2527,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(50, True, True, False, Liquid.WATER, False, False)] = ( - _50ulTip_conductive_384COREWasher_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 6.3, - 0.5: 0.9, - 50.0: 55.0, - 40.0: 44.0, - 0.0: 0.0, - 1.0: 1.6, - 20.0: 22.2, - 65.0: 65.0, - 10.0: 11.9, - 2.0: 2.8, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(50, True, True, False, Liquid.WATER, False, False)] = \ +_50ulTip_conductive_384COREWasher_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 6.3, 0.5: 0.9, 50.0: 55.0, 40.0: 44.0, 0.0: 0.0, 1.0: 1.6, 20.0: 22.2, 65.0: 65.0, 10.0: 11.9, 2.0: 2.8}, aspiration_flow_rate=20.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=0.0, @@ -3269,27 +2550,13 @@ def get_star_liquid_class( dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(5000, False, True, False, Liquid.DMSO, True, False)] = ( - _5mlT_DMSO_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 4500.0: 4606.0, - 3500.0: 3591.0, - 500.0: 525.0, - 2500.0: 2576.0, - 1500.0: 1559.0, - 5000.0: 5114.0, - 4000.0: 4099.0, - 3000.0: 3083.0, - 0.0: 0.0, - 2000.0: 2068.0, - 100.0: 105.0, - 1000.0: 1044.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(5000, False, True, False, Liquid.DMSO, True, False)] = \ +_5mlT_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={4500.0: 4606.0, 3500.0: 3591.0, 500.0: 525.0, 2500.0: 2576.0, 1500.0: 1559.0, 5000.0: 5114.0, 4000.0: 4099.0, 3000.0: 3083.0, 0.0: 0.0, 2000.0: 2068.0, 100.0: 105.0, 1000.0: 1044.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=20.0, @@ -3306,24 +2573,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=20.0, -) - - -star_mapping[(5000, False, True, False, Liquid.DMSO, True, True)] = ( - _5mlT_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 540.0, - 50.0: 62.0, - 5000.0: 5095.0, - 4000.0: 4075.0, - 0.0: 0.0, - 3000.0: 3065.0, - 100.0: 117.0, - 2000.0: 2060.0, - 1000.0: 1060.0, - }, + dispense_stop_back_volume=20.0 +) + + +star_mapping[(5000, False, True, False, Liquid.DMSO, True, True)] = \ +_5mlT_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 540.0, 50.0: 62.0, 5000.0: 5095.0, 4000.0: 4075.0, 0.0: 0.0, 3000.0: 3065.0, 100.0: 117.0, 2000.0: 2060.0, 1000.0: 1060.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -3340,25 +2596,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(5000, False, True, False, Liquid.DMSO, False, True)] = ( - _5mlT_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 535.0, - 50.0: 60.3, - 5000.0: 5090.0, - 4000.0: 4078.0, - 0.0: 0.0, - 3000.0: 3066.0, - 100.0: 115.0, - 2000.0: 2057.0, - 10.0: 12.5, - 1000.0: 1054.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(5000, False, True, False, Liquid.DMSO, False, True)] = \ +_5mlT_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 535.0, 50.0: 60.3, 5000.0: 5090.0, 4000.0: 4078.0, 0.0: 0.0, 3000.0: 3066.0, 100.0: 115.0, 2000.0: 2057.0, 10.0: 12.5, 1000.0: 1054.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -3375,29 +2619,14 @@ def get_star_liquid_class( dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=500.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # First two times mixing with max volume. -star_mapping[(5000, False, True, False, Liquid.ETHANOL, True, False)] = ( - _5mlT_EtOH_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 312.0, - 4500.0: 4573.0, - 3500.0: 3560.0, - 500.0: 519.0, - 2500.0: 2551.0, - 1500.0: 1542.0, - 5000.0: 5081.0, - 4000.0: 4066.0, - 3000.0: 3056.0, - 0.0: 0.0, - 2000.0: 2047.0, - 100.0: 104.0, - 1000.0: 1033.0, - }, +star_mapping[(5000, False, True, False, Liquid.ETHANOL, True, False)] = \ +_5mlT_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 312.0, 4500.0: 4573.0, 3500.0: 3560.0, 500.0: 519.0, 2500.0: 2551.0, 1500.0: 1542.0, 5000.0: 5081.0, 4000.0: 4066.0, 3000.0: 3056.0, 0.0: 0.0, 2000.0: 2047.0, 100.0: 104.0, 1000.0: 1033.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=2000.0, aspiration_air_transport_volume=0.0, @@ -3414,24 +2643,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(5000, False, True, False, Liquid.ETHANOL, True, True)] = ( - _5mlT_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 563.0, - 50.0: 72.0, - 5000.0: 5230.0, - 4000.0: 4215.0, - 0.0: 0.0, - 3000.0: 3190.0, - 100.0: 129.5, - 2000.0: 2166.0, - 1000.0: 1095.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(5000, False, True, False, Liquid.ETHANOL, True, True)] = \ +_5mlT_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 563.0, 50.0: 72.0, 5000.0: 5230.0, 4000.0: 4215.0, 0.0: 0.0, 3000.0: 3190.0, 100.0: 129.5, 2000.0: 2166.0, 1000.0: 1095.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=30.0, @@ -3448,25 +2666,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=30.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(5000, False, True, False, Liquid.ETHANOL, False, True)] = ( - _5mlT_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 555.0, - 50.0: 68.0, - 5000.0: 5204.0, - 4000.0: 4200.0, - 0.0: 0.0, - 3000.0: 3180.0, - 100.0: 123.5, - 2000.0: 2160.0, - 10.0: 22.0, - 1000.0: 1085.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(5000, False, True, False, Liquid.ETHANOL, False, True)] = \ +_5mlT_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 555.0, 50.0: 68.0, 5000.0: 5204.0, 4000.0: 4200.0, 0.0: 0.0, 3000.0: 3180.0, 100.0: 123.5, 2000.0: 2160.0, 10.0: 22.0, 1000.0: 1085.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=30.0, @@ -3483,24 +2689,13 @@ def get_star_liquid_class( dispense_swap_speed=30.0, dispense_settling_time=1.0, dispense_stop_flow_rate=30.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(5000, False, True, False, Liquid.GLYCERIN80, True, True)] = ( - _5mlT_Glycerin80_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 597.0, - 50.0: 89.0, - 5000.0: 5240.0, - 4000.0: 4220.0, - 0.0: 0.0, - 3000.0: 3203.0, - 100.0: 138.0, - 2000.0: 2195.0, - 1000.0: 1166.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(5000, False, True, False, Liquid.GLYCERIN80, True, True)] = \ +_5mlT_Glycerin80_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 597.0, 50.0: 89.0, 5000.0: 5240.0, 4000.0: 4220.0, 0.0: 0.0, 3000.0: 3203.0, 100.0: 138.0, 2000.0: 2195.0, 1000.0: 1166.0}, aspiration_flow_rate=1200.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=30.0, @@ -3517,25 +2712,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(5000, False, True, False, Liquid.GLYCERIN80, False, True)] = ( - _5mlT_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 555.0, - 50.0: 71.0, - 5000.0: 5135.0, - 4000.0: 4115.0, - 0.0: 0.0, - 3000.0: 3127.0, - 100.0: 127.0, - 2000.0: 2115.0, - 10.0: 15.5, - 1000.0: 1075.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(5000, False, True, False, Liquid.GLYCERIN80, False, True)] = \ +_5mlT_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 555.0, 50.0: 71.0, 5000.0: 5135.0, 4000.0: 4115.0, 0.0: 0.0, 3000.0: 3127.0, 100.0: 127.0, 2000.0: 2115.0, 10.0: 15.5, 1000.0: 1075.0}, aspiration_flow_rate=1000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=0.0, @@ -3552,22 +2735,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(5000, False, True, False, Liquid.WATER, True, False)] = ( - _5mlT_Water_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 5000.0: 5030.0, - 4000.0: 4040.0, - 0.0: 0.0, - 3000.0: 3050.0, - 100.0: 104.0, - 2000.0: 2050.0, - 1000.0: 1040.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(5000, False, True, False, Liquid.WATER, True, False)] = \ +_5mlT_Water_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={5000.0: 5030.0, 4000.0: 4040.0, 0.0: 0.0, 3000.0: 3050.0, 100.0: 104.0, 2000.0: 2050.0, 1000.0: 1040.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -3584,24 +2758,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=20.0, -) - - -star_mapping[(5000, False, True, False, Liquid.WATER, True, True)] = ( - _5mlT_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 551.8, - 50.0: 66.4, - 5000.0: 5180.0, - 4000.0: 4165.0, - 0.0: 0.0, - 3000.0: 3148.0, - 100.0: 122.7, - 2000.0: 2128.0, - 1000.0: 1082.0, - }, + dispense_stop_back_volume=20.0 +) + + +star_mapping[(5000, False, True, False, Liquid.WATER, True, True)] = \ +_5mlT_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 551.8, 50.0: 66.4, 5000.0: 5180.0, 4000.0: 4165.0, 0.0: 0.0, 3000.0: 3148.0, 100.0: 122.7, 2000.0: 2128.0, 1000.0: 1082.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -3618,25 +2781,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(5000, False, True, False, Liquid.WATER, False, True)] = ( - _5mlT_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 547.0, - 50.0: 65.5, - 5000.0: 5145.0, - 4000.0: 4145.0, - 0.0: 0.0, - 3000.0: 3130.0, - 100.0: 120.9, - 2000.0: 2125.0, - 10.0: 15.1, - 1000.0: 1075.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(5000, False, True, False, Liquid.WATER, False, True)] = \ +_5mlT_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 547.0, 50.0: 65.5, 5000.0: 5145.0, 4000.0: 4145.0, 0.0: 0.0, 3000.0: 3130.0, 100.0: 120.9, 2000.0: 2125.0, 10.0: 15.1, 1000.0: 1075.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -3653,24 +2804,14 @@ def get_star_liquid_class( dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=500.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = ( - HighNeedle_Water_DispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 527.3, - 50.0: 56.8, - 0.0: 0.0, - 100.0: 110.4, - 20.0: 24.7, - 1000.0: 1046.5, - 200.0: 214.6, - 10.0: 13.2, - }, +star_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = \ +HighNeedle_Water_DispenseJet = HamiltonLiquidClass( + curve={500.0: 527.3, 50.0: 56.8, 0.0: 0.0, 100.0: 110.4, 20.0: 24.7, 1000.0: 1046.5, 200.0: 214.6, 10.0: 13.2}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3687,23 +2828,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=350.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, False, False, Liquid.WATER, True, True)] = ( - HighNeedle_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 527.3, - 50.0: 56.8, - 0.0: 0.0, - 100.0: 110.4, - 20.0: 24.7, - 1000.0: 1046.5, - 200.0: 214.6, - 10.0: 13.2, - }, +star_mapping[(1000, False, False, False, Liquid.WATER, True, True)] = \ +HighNeedle_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 527.3, 50.0: 56.8, 0.0: 0.0, 100.0: 110.4, 20.0: 24.7, 1000.0: 1046.5, 200.0: 214.6, 10.0: 13.2}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3720,23 +2851,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=350.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = ( - HighNeedle_Water_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 527.3, - 50.0: 56.8, - 0.0: 0.0, - 100.0: 110.4, - 20.0: 24.7, - 1000.0: 1046.5, - 200.0: 214.6, - 10.0: 13.2, - }, +star_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = \ +HighNeedle_Water_DispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 527.3, 50.0: 56.8, 0.0: 0.0, 100.0: 110.4, 20.0: 24.7, 1000.0: 1046.5, 200.0: 214.6, 10.0: 13.2}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3753,21 +2874,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=350.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 120 -star_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = ( - HighNeedle_Water_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 50.0: 53.1, - 0.0: 0.0, - 20.0: 22.3, - 1000.0: 1000.0, - 10.0: 10.8, - }, +star_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = \ +HighNeedle_Water_DispenseSurface = HamiltonLiquidClass( + curve={50.0: 53.1, 0.0: 0.0, 20.0: 22.3, 1000.0: 1000.0, 10.0: 10.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -3784,20 +2898,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, False, False, Liquid.WATER, False, True)] = ( - HighNeedle_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 50.0: 53.1, - 0.0: 0.0, - 20.0: 22.3, - 1000.0: 1000.0, - 10.0: 10.8, - }, +star_mapping[(1000, False, False, False, Liquid.WATER, False, True)] = \ +HighNeedle_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={50.0: 53.1, 0.0: 0.0, 20.0: 22.3, 1000.0: 1000.0, 10.0: 10.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -3814,20 +2921,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = ( - HighNeedle_Water_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 50.0: 53.1, - 0.0: 0.0, - 20.0: 22.3, - 1000.0: 1000.0, - 10.0: 10.8, - }, +star_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = \ +HighNeedle_Water_DispenseSurface_Part = HamiltonLiquidClass( + curve={50.0: 53.1, 0.0: 0.0, 20.0: 22.3, 1000.0: 1000.0, 10.0: 10.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -3844,7 +2944,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -3863,17 +2963,9 @@ def get_star_liquid_class( # 100 0.32 0.54 # 500 0.13 -0.06 # 1000 0.11 0.17 -star_mapping[(1000, False, True, False, Liquid.ACETONITRIL80WATER20, True, False)] = ( - HighVolumeAcetonitril80Water20DispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 514.5, - 50.0: 57.5, - 0.0: 0.0, - 20.0: 25.0, - 100.0: 110.5, - 1000.0: 1020.8, - }, +star_mapping[(1000, False, True, False, Liquid.ACETONITRIL80WATER20, True, False)] = \ +HighVolumeAcetonitril80Water20DispenseJet = HamiltonLiquidClass( + curve={500.0: 514.5, 50.0: 57.5, 0.0: 0.0, 20.0: 25.0, 100.0: 110.5, 1000.0: 1020.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -3890,7 +2982,7 @@ def get_star_liquid_class( dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -3909,18 +3001,9 @@ def get_star_liquid_class( # 200 0.22 0.71 # 500 0.14 0.01 # 1000 0.17 0.02 -star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, False)] = ( - HighVolumeAcetonitrilDispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 526.5, - 250.0: 269.0, - 50.0: 60.5, - 0.0: 0.0, - 20.0: 25.5, - 100.0: 112.7, - 1000.0: 1045.0, - }, +star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, False)] = \ +HighVolumeAcetonitrilDispenseJet = HamiltonLiquidClass( + curve={500.0: 526.5, 250.0: 269.0, 50.0: 60.5, 0.0: 0.0, 20.0: 25.5, 100.0: 112.7, 1000.0: 1045.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -3937,22 +3020,13 @@ def get_star_liquid_class( dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, True)] = ( - HighVolumeAcetonitrilDispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 526.5, - 250.0: 269.0, - 50.0: 60.5, - 0.0: 0.0, - 100.0: 112.7, - 20.0: 25.5, - 1000.0: 1045.0, - }, +star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, True)] = \ +HighVolumeAcetonitrilDispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 526.5, 250.0: 269.0, 50.0: 60.5, 0.0: 0.0, 100.0: 112.7, 20.0: 25.5, 1000.0: 1045.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -3969,22 +3043,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, False)] = ( - HighVolumeAcetonitrilDispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 526.5, - 250.0: 269.0, - 50.0: 60.5, - 0.0: 0.0, - 100.0: 112.7, - 20.0: 25.5, - 1000.0: 1045.0, - }, +star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, False)] = \ +HighVolumeAcetonitrilDispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 526.5, 250.0: 269.0, 50.0: 60.5, 0.0: 0.0, 100.0: 112.7, 20.0: 25.5, 1000.0: 1045.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -4001,7 +3066,7 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) @@ -4021,19 +3086,9 @@ def get_star_liquid_class( # 200 0.18 0.69 # 500 0.23 0.04 # 1000 0.22 0.05 -star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, False)] = ( - HighVolumeAcetonitrilDispenseSurface -) = HamiltonLiquidClass( - curve={ - 500.0: 525.4, - 250.0: 267.0, - 50.0: 57.6, - 0.0: 0.0, - 20.0: 23.8, - 100.0: 111.2, - 10.0: 12.1, - 1000.0: 1048.8, - }, +star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, False)] = \ +HighVolumeAcetonitrilDispenseSurface = HamiltonLiquidClass( + curve={500.0: 525.4, 250.0: 267.0, 50.0: 57.6, 0.0: 0.0, 20.0: 23.8, 100.0: 111.2, 10.0: 12.1, 1000.0: 1048.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=10.0, @@ -4050,23 +3105,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, True)] = ( - HighVolumeAcetonitrilDispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 525.4, - 250.0: 267.0, - 50.0: 57.6, - 0.0: 0.0, - 100.0: 111.2, - 20.0: 23.8, - 1000.0: 1048.8, - 10.0: 12.1, - }, +star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, True)] = \ +HighVolumeAcetonitrilDispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 525.4, 250.0: 267.0, 50.0: 57.6, 0.0: 0.0, 100.0: 111.2, 20.0: 23.8, 1000.0: 1048.8, 10.0: 12.1}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=10.0, @@ -4083,22 +3128,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, False)] = ( - HighVolumeAcetonitrilDispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 525.4, - 250.0: 267.0, - 50.0: 57.6, - 0.0: 0.0, - 100.0: 111.2, - 20.0: 23.8, - 1000.0: 1048.8, - }, +star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, False)] = \ +HighVolumeAcetonitrilDispenseSurface_Part = HamiltonLiquidClass( + curve={500.0: 525.4, 250.0: 267.0, 50.0: 57.6, 0.0: 0.0, 100.0: 111.2, 20.0: 23.8, 1000.0: 1048.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=10.0, @@ -4115,26 +3151,16 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # - Submerge depth: Aspiration 2.0mm # (bei Schaumbildung durch mischen/vorbenetzen evtl.5mm, LLD-Erkennung) # - Mischen 3-5 x 950µl, mix position 0.5mm, je nach Volumen im Tube -star_mapping[(1000, False, True, False, Liquid.BLOOD, True, False)] = ( - HighVolumeBloodDispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 536.3, - 250.0: 275.6, - 50.0: 59.8, - 0.0: 0.0, - 20.0: 26.2, - 100.0: 115.3, - 10.0: 12.2, - 1000.0: 1061.6, - }, +star_mapping[(1000, False, True, False, Liquid.BLOOD, True, False)] = \ +HighVolumeBloodDispenseJet = HamiltonLiquidClass( + curve={500.0: 536.3, 250.0: 275.6, 50.0: 59.8, 0.0: 0.0, 20.0: 26.2, 100.0: 115.3, 10.0: 12.2, 1000.0: 1061.6}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4151,7 +3177,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=300.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -4172,18 +3198,9 @@ def get_star_liquid_class( # 100 0.23 0.93 # 200 0.15 0.41 # -star_mapping[(1000, False, True, False, Liquid.BRAINHOMOGENATE, True, False)] = ( - HighVolumeBrainHomogenateDispenseJet -) = HamiltonLiquidClass( - curve={ - 50.0: 57.9, - 0.0: 0.0, - 20.0: 25.3, - 100.0: 111.3, - 10.0: 14.2, - 200.0: 214.5, - 1000.0: 1038.6, - }, +star_mapping[(1000, False, True, False, Liquid.BRAINHOMOGENATE, True, False)] = \ +HighVolumeBrainHomogenateDispenseJet = HamiltonLiquidClass( + curve={50.0: 57.9, 0.0: 0.0, 20.0: 25.3, 100.0: 111.3, 10.0: 14.2, 200.0: 214.5, 1000.0: 1038.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -4200,7 +3217,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -4220,17 +3237,9 @@ def get_star_liquid_class( # # # -star_mapping[(1000, False, True, False, Liquid.CHLOROFORM, True, False)] = ( - HighVolumeChloroformDispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 520.5, - 250.0: 269.0, - 50.0: 62.9, - 0.0: 0.0, - 100.0: 116.3, - 1000.0: 1030.0, - }, +star_mapping[(1000, False, True, False, Liquid.CHLOROFORM, True, False)] = \ +HighVolumeChloroformDispenseJet = HamiltonLiquidClass( + curve={500.0: 520.5, 250.0: 269.0, 50.0: 62.9, 0.0: 0.0, 100.0: 116.3, 1000.0: 1030.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=10.0, @@ -4247,7 +3256,7 @@ def get_star_liquid_class( dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -4268,20 +3277,9 @@ def get_star_liquid_class( # 100 ( 9 Aliquots) 0.25 -4.81 # # -star_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = ( - HighVolumeDMSOAliquotJet -) = HamiltonLiquidClass( - curve={ - 500.0: 500.0, - 250.0: 250.0, - 0.0: 0.0, - 30.0: 30.0, - 20.0: 20.0, - 100.0: 100.0, - 10.0: 10.0, - 750.0: 750.0, - 1000.0: 1000.0, - }, +star_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = \ +HighVolumeDMSOAliquotJet = HamiltonLiquidClass( + curve={500.0: 500.0, 250.0: 250.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 100.0: 100.0, 10.0: 10.0, 750.0: 750.0, 1000.0: 1000.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -4298,20 +3296,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -star_mapping[(1000, True, True, True, Liquid.DMSO, True, True)] = ( - HighVolumeFilter_96COREHead1000ul_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 508.2, - 0.0: 0.0, - 20.0: 21.7, - 100.0: 101.7, - 1000.0: 1017.0, - }, +star_mapping[(1000, True, True, True, Liquid.DMSO, True, True)] = \ +HighVolumeFilter_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 508.2, 0.0: 0.0, 20.0: 21.7, 100.0: 101.7, 1000.0: 1017.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4328,20 +3319,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, True, True, True, Liquid.DMSO, False, True)] = ( - HighVolumeFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 512.5, - 0.0: 0.0, - 100.0: 105.8, - 10.0: 12.7, - 1000.0: 1024.5, - }, +star_mapping[(1000, True, True, True, Liquid.DMSO, False, True)] = \ +HighVolumeFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 512.5, 0.0: 0.0, 100.0: 105.8, 10.0: 12.7, 1000.0: 1024.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4358,20 +3342,13 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, True, True, True, Liquid.WATER, True, True)] = ( - HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 524.0, - 0.0: 0.0, - 20.0: 24.0, - 100.0: 109.2, - 1000.0: 1040.0, - }, +star_mapping[(1000, True, True, True, Liquid.WATER, True, True)] = \ +HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 524.0, 0.0: 0.0, 20.0: 24.0, 100.0: 109.2, 1000.0: 1040.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4388,20 +3365,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, True, True, True, Liquid.WATER, False, True)] = ( - HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 522.0, - 0.0: 0.0, - 100.0: 108.3, - 1000.0: 1034.0, - 10.0: 12.5, - }, +star_mapping[(1000, True, True, True, Liquid.WATER, False, True)] = \ +HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 522.0, 0.0: 0.0, 100.0: 108.3, 1000.0: 1034.0, 10.0: 12.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -4418,7 +3388,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -4439,20 +3409,9 @@ def get_star_liquid_class( # 100 ( 9 Aliquots) 0.25 -4.81 # # -star_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = ( - HighVolumeFilter_DMSO_AliquotDispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 500.0, - 250.0: 250.0, - 30.0: 30.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - 1000.0: 1000.0, - 750.0: 750.0, - 10.0: 10.0, - }, +star_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = \ +HighVolumeFilter_DMSO_AliquotDispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -4469,25 +3428,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = ( - HighVolumeFilter_DMSO_DispenseJet -) = HamiltonLiquidClass( - curve={ - 5.0: 5.1, - 500.0: 511.2, - 250.0: 256.2, - 50.0: 52.2, - 0.0: 0.0, - 20.0: 21.3, - 100.0: 103.4, - 10.0: 10.7, - 1000.0: 1021.0, - }, +star_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = \ +HighVolumeFilter_DMSO_DispenseJet = HamiltonLiquidClass( + curve={5.0: 5.1, 500.0: 511.2, 250.0: 256.2, 50.0: 52.2, 0.0: 0.0, 20.0: 21.3, 100.0: 103.4, 10.0: 10.7, 1000.0: 1021.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4504,24 +3452,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, True, Liquid.DMSO, True, True)] = ( - HighVolumeFilter_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 511.2, - 5.0: 5.1, - 250.0: 256.2, - 50.0: 52.2, - 0.0: 0.0, - 100.0: 103.4, - 20.0: 21.3, - 1000.0: 1021.0, - 10.0: 10.7, - }, +star_mapping[(1000, False, True, True, Liquid.DMSO, True, True)] = \ +HighVolumeFilter_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 511.2, 5.0: 5.1, 250.0: 256.2, 50.0: 52.2, 0.0: 0.0, 100.0: 103.4, 20.0: 21.3, 1000.0: 1021.0, 10.0: 10.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4538,20 +3475,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = ( - HighVolumeFilter_DMSO_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 517.2, - 0.0: 0.0, - 100.0: 109.5, - 20.0: 27.0, - 1000.0: 1027.0, - }, +star_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = \ +HighVolumeFilter_DMSO_DispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 517.2, 0.0: 0.0, 100.0: 109.5, 20.0: 27.0, 1000.0: 1027.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4568,24 +3498,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 120 -star_mapping[(1000, False, True, True, Liquid.DMSO, False, False)] = ( - HighVolumeFilter_DMSO_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 500.0: 514.3, - 250.0: 259.0, - 50.0: 54.4, - 0.0: 0.0, - 20.0: 22.8, - 100.0: 105.8, - 10.0: 12.1, - 1000.0: 1024.5, - }, +star_mapping[(1000, False, True, True, Liquid.DMSO, False, False)] = \ +HighVolumeFilter_DMSO_DispenseSurface = HamiltonLiquidClass( + curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 20.0: 22.8, 100.0: 105.8, 10.0: 12.1, 1000.0: 1024.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4602,23 +3522,13 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, True, Liquid.DMSO, False, True)] = ( - HighVolumeFilter_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 514.3, - 250.0: 259.0, - 50.0: 54.4, - 0.0: 0.0, - 100.0: 105.8, - 20.0: 22.8, - 1000.0: 1024.5, - 10.0: 12.1, - }, +star_mapping[(1000, False, True, True, Liquid.DMSO, False, True)] = \ +HighVolumeFilter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 100.0: 105.8, 20.0: 22.8, 1000.0: 1024.5, 10.0: 12.1}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4635,24 +3545,14 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # -star_mapping[(1000, False, True, True, Liquid.DMSO, False, False)] = ( - HighVolumeFilter_DMSO_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 514.3, - 250.0: 259.0, - 50.0: 54.4, - 0.0: 0.0, - 100.0: 105.8, - 20.0: 22.8, - 1000.0: 1024.5, - 10.0: 12.1, - }, +star_mapping[(1000, False, True, True, Liquid.DMSO, False, False)] = \ +HighVolumeFilter_DMSO_DispenseSurface_Part = HamiltonLiquidClass( + curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 100.0: 105.8, 20.0: 22.8, 1000.0: 1024.5, 10.0: 12.1}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4669,24 +3569,14 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 250, Stop back volume = 0 -star_mapping[(1000, False, True, True, Liquid.ETHANOL, True, False)] = ( - HighVolumeFilter_EtOH_DispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 534.8, - 250.0: 273.0, - 50.0: 62.9, - 0.0: 0.0, - 20.0: 27.8, - 100.0: 116.3, - 10.0: 15.8, - 1000.0: 1053.9, - }, +star_mapping[(1000, False, True, True, Liquid.ETHANOL, True, False)] = \ +HighVolumeFilter_EtOH_DispenseJet = HamiltonLiquidClass( + curve={500.0: 534.8, 250.0: 273.0, 50.0: 62.9, 0.0: 0.0, 20.0: 27.8, 100.0: 116.3, 10.0: 15.8, 1000.0: 1053.9}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4703,23 +3593,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, True, Liquid.ETHANOL, True, True)] = ( - HighVolumeFilter_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 534.8, - 250.0: 273.0, - 50.0: 62.9, - 0.0: 0.0, - 100.0: 116.3, - 20.0: 27.8, - 1000.0: 1053.9, - 10.0: 15.8, - }, +star_mapping[(1000, False, True, True, Liquid.ETHANOL, True, True)] = \ +HighVolumeFilter_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 534.8, 250.0: 273.0, 50.0: 62.9, 0.0: 0.0, 100.0: 116.3, 20.0: 27.8, 1000.0: 1053.9, 10.0: 15.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4736,22 +3616,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, True, Liquid.ETHANOL, True, False)] = ( - HighVolumeFilter_EtOH_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 534.8, - 250.0: 273.0, - 50.0: 62.9, - 0.0: 0.0, - 100.0: 116.3, - 20.0: 27.8, - 1000.0: 1053.9, - }, +star_mapping[(1000, False, True, True, Liquid.ETHANOL, True, False)] = \ +HighVolumeFilter_EtOH_DispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 534.8, 250.0: 273.0, 50.0: 62.9, 0.0: 0.0, 100.0: 116.3, 20.0: 27.8, 1000.0: 1053.9}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4768,24 +3639,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=5.0, + dispense_stop_back_volume=5.0 ) # V1.1: Set mix flow rate to 120 -star_mapping[(1000, False, True, True, Liquid.ETHANOL, False, False)] = ( - HighVolumeFilter_EtOH_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 500.0: 528.4, - 250.0: 269.2, - 50.0: 61.2, - 0.0: 0.0, - 20.0: 27.6, - 100.0: 114.0, - 10.0: 15.7, - 1000.0: 1044.3, - }, +star_mapping[(1000, False, True, True, Liquid.ETHANOL, False, False)] = \ +HighVolumeFilter_EtOH_DispenseSurface = HamiltonLiquidClass( + curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 20.0: 27.6, 100.0: 114.0, 10.0: 15.7, 1000.0: 1044.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -4802,23 +3663,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, True, Liquid.ETHANOL, False, True)] = ( - HighVolumeFilter_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 528.4, - 250.0: 269.2, - 50.0: 61.2, - 0.0: 0.0, - 100.0: 114.0, - 20.0: 27.6, - 1000.0: 1044.3, - 10.0: 15.7, - }, +star_mapping[(1000, False, True, True, Liquid.ETHANOL, False, True)] = \ +HighVolumeFilter_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 100.0: 114.0, 20.0: 27.6, 1000.0: 1044.3, 10.0: 15.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -4835,23 +3686,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, True, Liquid.ETHANOL, False, False)] = ( - HighVolumeFilter_EtOH_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 528.4, - 250.0: 269.2, - 50.0: 61.2, - 0.0: 0.0, - 100.0: 114.0, - 20.0: 27.6, - 1000.0: 1044.3, - 10.0: 15.7, - }, +star_mapping[(1000, False, True, True, Liquid.ETHANOL, False, False)] = \ +HighVolumeFilter_EtOH_DispenseSurface_Part = HamiltonLiquidClass( + curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 100.0: 114.0, 20.0: 27.6, 1000.0: 1044.3, 10.0: 15.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -4868,24 +3709,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 200 -star_mapping[(1000, False, True, True, Liquid.GLYCERIN80, True, False)] = ( - HighVolumeFilter_Glycerin80_DispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 537.8, - 250.0: 277.0, - 50.0: 63.3, - 0.0: 0.0, - 20.0: 28.0, - 100.0: 118.8, - 10.0: 15.2, - 1000.0: 1060.0, - }, +star_mapping[(1000, False, True, True, Liquid.GLYCERIN80, True, False)] = \ +HighVolumeFilter_Glycerin80_DispenseJet = HamiltonLiquidClass( + curve={500.0: 537.8, 250.0: 277.0, 50.0: 63.3, 0.0: 0.0, 20.0: 28.0, 100.0: 118.8, 10.0: 15.2, 1000.0: 1060.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=5.0, @@ -4902,24 +3733,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 200 -star_mapping[(1000, False, True, True, Liquid.GLYCERIN80, True, True)] = ( - HighVolumeFilter_Glycerin80_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 537.8, - 250.0: 277.0, - 50.0: 63.3, - 0.0: 0.0, - 100.0: 118.8, - 20.0: 28.0, - 1000.0: 1060.0, - 10.0: 15.2, - }, +star_mapping[(1000, False, True, True, Liquid.GLYCERIN80, True, True)] = \ +HighVolumeFilter_Glycerin80_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 537.8, 250.0: 277.0, 50.0: 63.3, 0.0: 0.0, 100.0: 118.8, 20.0: 28.0, 1000.0: 1060.0, 10.0: 15.2}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=5.0, @@ -4936,24 +3757,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 120 -star_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, False)] = ( - HighVolumeFilter_Glycerin80_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 500.0: 513.5, - 250.0: 257.2, - 50.0: 55.0, - 0.0: 0.0, - 20.0: 22.7, - 100.0: 105.5, - 10.0: 12.2, - 1000.0: 1027.2, - }, +star_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, False)] = \ +HighVolumeFilter_Glycerin80_DispenseSurface = HamiltonLiquidClass( + curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 20.0: 22.7, 100.0: 105.5, 10.0: 12.2, 1000.0: 1027.2}, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4970,23 +3781,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, True)] = ( - HighVolumeFilter_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 513.5, - 250.0: 257.2, - 50.0: 55.0, - 0.0: 0.0, - 100.0: 105.5, - 20.0: 22.7, - 1000.0: 1027.2, - 10.0: 12.2, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, True)] = \ +HighVolumeFilter_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 100.0: 105.5, 20.0: 22.7, 1000.0: 1027.2, 10.0: 12.2}, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -5003,23 +3804,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, False)] = ( - HighVolumeFilter_Glycerin80_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 513.5, - 250.0: 257.2, - 50.0: 55.0, - 0.0: 0.0, - 100.0: 105.5, - 20.0: 22.7, - 1000.0: 1027.2, - 10.0: 12.2, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, False)] = \ +HighVolumeFilter_Glycerin80_DispenseSurface_Part = HamiltonLiquidClass( + curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 100.0: 105.5, 20.0: 22.7, 1000.0: 1027.2, 10.0: 12.2}, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -5036,25 +3827,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = ( - HighVolumeFilter_Serum_AliquotDispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 500.0, - 250.0: 250.0, - 30.0: 30.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - 1000.0: 1000.0, - 750.0: 750.0, - 10.0: 10.0, - }, +star_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = \ +HighVolumeFilter_Serum_AliquotDispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -5071,25 +3851,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=300.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = ( - HighVolumeFilter_Serum_AliquotJet -) = HamiltonLiquidClass( - curve={ - 500.0: 500.0, - 250.0: 250.0, - 0.0: 0.0, - 30.0: 30.0, - 20.0: 20.0, - 100.0: 100.0, - 10.0: 10.0, - 750.0: 750.0, - 1000.0: 1000.0, - }, +star_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = \ +HighVolumeFilter_Serum_AliquotJet = HamiltonLiquidClass( + curve={500.0: 500.0, 250.0: 250.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 100.0: 100.0, 10.0: 10.0, 750.0: 750.0, 1000.0: 1000.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -5106,24 +3875,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=300.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 250, Settling time = 0 -star_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = ( - HighVolumeFilter_Serum_DispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 525.3, - 250.0: 266.6, - 50.0: 57.9, - 0.0: 0.0, - 20.0: 24.2, - 100.0: 111.3, - 10.0: 12.2, - 1000.0: 1038.6, - }, +star_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = \ +HighVolumeFilter_Serum_DispenseJet = HamiltonLiquidClass( + curve={500.0: 525.3, 250.0: 266.6, 50.0: 57.9, 0.0: 0.0, 20.0: 24.2, 100.0: 111.3, 10.0: 12.2, 1000.0: 1038.6}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -5140,23 +3899,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, True, Liquid.SERUM, True, True)] = ( - HighVolumeFilter_Serum_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 525.3, - 250.0: 266.6, - 50.0: 57.9, - 0.0: 0.0, - 100.0: 111.3, - 20.0: 24.2, - 1000.0: 1038.6, - 10.0: 12.2, - }, +star_mapping[(1000, False, True, True, Liquid.SERUM, True, True)] = \ +HighVolumeFilter_Serum_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 525.3, 250.0: 266.6, 50.0: 57.9, 0.0: 0.0, 100.0: 111.3, 20.0: 24.2, 1000.0: 1038.6, 10.0: 12.2}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -5173,20 +3922,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = ( - HighVolumeFilter_Serum_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 525.3, - 0.0: 0.0, - 100.0: 111.3, - 20.0: 27.3, - 1000.0: 1046.6, - }, +star_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = \ +HighVolumeFilter_Serum_DispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 525.3, 0.0: 0.0, 100.0: 111.3, 20.0: 27.3, 1000.0: 1046.6}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -5203,24 +3945,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 120 -star_mapping[(1000, False, True, True, Liquid.SERUM, False, False)] = ( - HighVolumeFilter_Serum_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 500.0: 517.5, - 250.0: 261.9, - 50.0: 55.9, - 0.0: 0.0, - 20.0: 23.2, - 100.0: 108.2, - 10.0: 11.8, - 1000.0: 1026.7, - }, +star_mapping[(1000, False, True, True, Liquid.SERUM, False, False)] = \ +HighVolumeFilter_Serum_DispenseSurface = HamiltonLiquidClass( + curve={500.0: 517.5, 250.0: 261.9, 50.0: 55.9, 0.0: 0.0, 20.0: 23.2, 100.0: 108.2, 10.0: 11.8, 1000.0: 1026.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -5237,23 +3969,13 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, True, Liquid.SERUM, False, True)] = ( - HighVolumeFilter_Serum_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 517.5, - 250.0: 261.9, - 50.0: 55.9, - 0.0: 0.0, - 100.0: 108.2, - 20.0: 23.2, - 1000.0: 1026.7, - 10.0: 11.8, - }, +star_mapping[(1000, False, True, True, Liquid.SERUM, False, True)] = \ +HighVolumeFilter_Serum_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 517.5, 250.0: 261.9, 50.0: 55.9, 0.0: 0.0, 100.0: 108.2, 20.0: 23.2, 1000.0: 1026.7, 10.0: 11.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -5270,21 +3992,13 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, True, Liquid.SERUM, False, False)] = ( - HighVolumeFilter_Serum_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 523.5, - 0.0: 0.0, - 100.0: 111.2, - 20.0: 23.2, - 1000.0: 1038.7, - 10.0: 11.8, - }, +star_mapping[(1000, False, True, True, Liquid.SERUM, False, False)] = \ +HighVolumeFilter_Serum_DispenseSurface_Part = HamiltonLiquidClass( + curve={500.0: 523.5, 0.0: 0.0, 100.0: 111.2, 20.0: 23.2, 1000.0: 1038.7, 10.0: 11.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -5301,25 +4015,14 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = ( - HighVolumeFilter_Water_AliquotDispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 500.0, - 250.0: 250.0, - 30.0: 30.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - 1000.0: 1000.0, - 750.0: 750.0, - 10.0: 10.0, - }, +star_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = \ +HighVolumeFilter_Water_AliquotDispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -5336,25 +4039,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = ( - HighVolumeFilter_Water_AliquotJet -) = HamiltonLiquidClass( - curve={ - 500.0: 500.0, - 250.0: 250.0, - 0.0: 0.0, - 30.0: 30.0, - 20.0: 20.0, - 100.0: 100.0, - 10.0: 10.0, - 750.0: 750.0, - 1000.0: 1000.0, - }, +star_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = \ +HighVolumeFilter_Water_AliquotJet = HamiltonLiquidClass( + curve={500.0: 500.0, 250.0: 250.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 100.0: 100.0, 10.0: 10.0, 750.0: 750.0, 1000.0: 1000.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -5371,24 +4063,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = ( - HighVolumeFilter_Water_DispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 521.7, - 50.0: 57.2, - 0.0: 0.0, - 20.0: 24.6, - 100.0: 109.6, - 10.0: 13.3, - 200.0: 212.9, - 1000.0: 1034.0, - }, +star_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = \ +HighVolumeFilter_Water_DispenseJet = HamiltonLiquidClass( + curve={500.0: 521.7, 50.0: 57.2, 0.0: 0.0, 20.0: 24.6, 100.0: 109.6, 10.0: 13.3, 200.0: 212.9, 1000.0: 1034.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -5405,23 +4087,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, True, Liquid.WATER, True, True)] = ( - HighVolumeFilter_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 521.7, - 50.0: 57.2, - 0.0: 0.0, - 100.0: 109.6, - 20.0: 24.6, - 1000.0: 1034.0, - 200.0: 212.9, - 10.0: 13.3, - }, +star_mapping[(1000, False, True, True, Liquid.WATER, True, True)] = \ +HighVolumeFilter_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 521.7, 50.0: 57.2, 0.0: 0.0, 100.0: 109.6, 20.0: 24.6, 1000.0: 1034.0, 200.0: 212.9, 10.0: 13.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -5438,22 +4110,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = ( - HighVolumeFilter_Water_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 521.7, - 50.0: 57.2, - 0.0: 0.0, - 100.0: 109.6, - 20.0: 27.0, - 1000.0: 1034.0, - 200.0: 212.9, - }, +star_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = \ +HighVolumeFilter_Water_DispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 521.7, 50.0: 57.2, 0.0: 0.0, 100.0: 109.6, 20.0: 27.0, 1000.0: 1034.0, 200.0: 212.9}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -5470,24 +4133,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 120, Clot retract hight = 0 -star_mapping[(1000, False, True, True, Liquid.WATER, False, False)] = ( - HighVolumeFilter_Water_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 500.0: 518.3, - 50.0: 56.3, - 0.0: 0.0, - 20.0: 23.9, - 100.0: 108.3, - 10.0: 12.5, - 200.0: 211.0, - 1000.0: 1028.5, - }, +star_mapping[(1000, False, True, True, Liquid.WATER, False, False)] = \ +HighVolumeFilter_Water_DispenseSurface = HamiltonLiquidClass( + curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 20.0: 23.9, 100.0: 108.3, 10.0: 12.5, 200.0: 211.0, 1000.0: 1028.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -5504,23 +4157,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, True, Liquid.WATER, False, True)] = ( - HighVolumeFilter_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 518.3, - 50.0: 56.3, - 0.0: 0.0, - 20.0: 23.9, - 100.0: 108.3, - 10.0: 12.5, - 200.0: 211.0, - 1000.0: 1028.5, - }, +star_mapping[(1000, False, True, True, Liquid.WATER, False, True)] = \ +HighVolumeFilter_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 20.0: 23.9, 100.0: 108.3, 10.0: 12.5, 200.0: 211.0, 1000.0: 1028.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -5537,23 +4180,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, True, Liquid.WATER, False, False)] = ( - HighVolumeFilter_Water_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 518.3, - 50.0: 56.3, - 0.0: 0.0, - 100.0: 108.3, - 20.0: 23.9, - 1000.0: 1028.5, - 200.0: 211.0, - 10.0: 12.7, - }, +star_mapping[(1000, False, True, True, Liquid.WATER, False, False)] = \ +HighVolumeFilter_Water_DispenseSurface_Part = HamiltonLiquidClass( + curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 100.0: 108.3, 20.0: 23.9, 1000.0: 1028.5, 200.0: 211.0, 10.0: 12.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -5570,7 +4203,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -5594,17 +4227,9 @@ def get_star_liquid_class( # 500 0.49 - 0.17 # 1000 0.55 0.712 # -star_mapping[(1000, False, True, False, Liquid.METHANOL, True, False)] = ( - HighVolumeMeOHDispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 520.5, - 250.0: 269.0, - 50.0: 62.9, - 0.0: 0.0, - 100.0: 116.3, - 1000.0: 1030.0, - }, +star_mapping[(1000, False, True, False, Liquid.METHANOL, True, False)] = \ +HighVolumeMeOHDispenseJet = HamiltonLiquidClass( + curve={500.0: 520.5, 250.0: 269.0, 50.0: 62.9, 0.0: 0.0, 100.0: 116.3, 1000.0: 1030.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=10.0, @@ -5621,7 +4246,7 @@ def get_star_liquid_class( dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -5647,19 +4272,9 @@ def get_star_liquid_class( # 200 0.48 0.18 # 500 0.17 0.22 # 1000 0.75 0.29 -star_mapping[(1000, False, True, False, Liquid.METHANOL, False, False)] = ( - HighVolumeMeOHDispenseSurface -) = HamiltonLiquidClass( - curve={ - 500.0: 518.0, - 50.0: 61.3, - 0.0: 0.0, - 20.0: 29.3, - 100.0: 111.0, - 10.0: 19.3, - 200.0: 215.0, - 1000.0: 1030.0, - }, +star_mapping[(1000, False, True, False, Liquid.METHANOL, False, False)] = \ +HighVolumeMeOHDispenseSurface = HamiltonLiquidClass( + curve={500.0: 518.0, 50.0: 61.3, 0.0: 0.0, 20.0: 29.3, 100.0: 111.0, 10.0: 19.3, 200.0: 215.0, 1000.0: 1030.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=10.0, @@ -5676,7 +4291,7 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -5698,17 +4313,9 @@ def get_star_liquid_class( # 200 0.14 0.06 # 500 0.12 - 0.07 # 1000 0.16 0.08 -star_mapping[(1000, False, True, False, Liquid.METHANOL70WATER030, True, False)] = ( - HighVolumeMeOHH2ODispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 528.5, - 250.0: 269.0, - 50.0: 60.5, - 0.0: 0.0, - 100.0: 114.3, - 1000.0: 1050.0, - }, +star_mapping[(1000, False, True, False, Liquid.METHANOL70WATER030, True, False)] = \ +HighVolumeMeOHH2ODispenseJet = HamiltonLiquidClass( + curve={500.0: 528.5, 250.0: 269.0, 50.0: 60.5, 0.0: 0.0, 100.0: 114.3, 1000.0: 1050.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=10.0, @@ -5725,7 +4332,7 @@ def get_star_liquid_class( dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -5745,19 +4352,9 @@ def get_star_liquid_class( # 20 2.85 2.92 # 200 0.14 0.59 # -star_mapping[(1000, False, True, False, Liquid.OCTANOL, True, False)] = ( - HighVolumeOctanol100DispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 537.8, - 250.0: 277.0, - 50.0: 63.3, - 0.0: 0.0, - 20.0: 28.0, - 100.0: 118.8, - 10.0: 15.2, - 1000.0: 1060.0, - }, +star_mapping[(1000, False, True, False, Liquid.OCTANOL, True, False)] = \ +HighVolumeOctanol100DispenseJet = HamiltonLiquidClass( + curve={500.0: 537.8, 250.0: 277.0, 50.0: 63.3, 0.0: 0.0, 20.0: 28.0, 100.0: 118.8, 10.0: 15.2, 1000.0: 1060.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -5774,7 +4371,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -5795,19 +4392,9 @@ def get_star_liquid_class( # 200 0.30 1.30 # 500 0.31 0.01 # 1000 0.33 0.01 -star_mapping[(1000, False, True, False, Liquid.OCTANOL, False, False)] = ( - HighVolumeOctanol100DispenseSurface -) = HamiltonLiquidClass( - curve={ - 500.0: 531.3, - 250.0: 265.0, - 50.0: 54.4, - 0.0: 0.0, - 20.0: 23.3, - 100.0: 108.8, - 10.0: 12.1, - 1000.0: 1058.0, - }, +star_mapping[(1000, False, True, False, Liquid.OCTANOL, False, False)] = \ +HighVolumeOctanol100DispenseSurface = HamiltonLiquidClass( + curve={500.0: 531.3, 250.0: 265.0, 50.0: 54.4, 0.0: 0.0, 20.0: 23.3, 100.0: 108.8, 10.0: 12.1, 1000.0: 1058.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -5824,20 +4411,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, True, True, False, Liquid.DMSO, True, False)] = ( - HighVolume_96COREHead1000ul_DMSO_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 500.0: 524.0, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 24.0, - 1000.0: 1025.0, - }, +star_mapping[(1000, True, True, False, Liquid.DMSO, True, False)] = \ +HighVolume_96COREHead1000ul_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={500.0: 524.0, 0.0: 0.0, 100.0: 107.2, 20.0: 24.0, 1000.0: 1025.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -5854,20 +4434,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=20.0, + dispense_stop_back_volume=20.0 ) -star_mapping[(1000, True, True, False, Liquid.DMSO, True, True)] = ( - HighVolume_96COREHead1000ul_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 508.2, - 0.0: 0.0, - 100.0: 101.7, - 20.0: 21.7, - 1000.0: 1017.0, - }, +star_mapping[(1000, True, True, False, Liquid.DMSO, True, True)] = \ +HighVolume_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 508.2, 0.0: 0.0, 100.0: 101.7, 20.0: 21.7, 1000.0: 1017.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -5884,20 +4457,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, True, True, False, Liquid.DMSO, False, True)] = ( - HighVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 512.5, - 0.0: 0.0, - 100.0: 105.8, - 1000.0: 1024.5, - 10.0: 12.7, - }, +star_mapping[(1000, True, True, False, Liquid.DMSO, False, True)] = \ +HighVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 512.5, 0.0: 0.0, 100.0: 105.8, 1000.0: 1024.5, 10.0: 12.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -5914,22 +4480,14 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # to prevent drop's, mix 2x with e.g. 500ul -star_mapping[(1000, True, True, False, Liquid.ETHANOL, True, False)] = ( - HighVolume_96COREHead1000ul_EtOH_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 500.0: 500.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - 1000.0: 1000.0, - }, +star_mapping[(1000, True, True, False, Liquid.ETHANOL, True, False)] = \ +HighVolume_96COREHead1000ul_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 500.0: 500.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -5946,20 +4504,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -star_mapping[(1000, True, True, False, Liquid.ETHANOL, True, True)] = ( - HighVolume_96COREHead1000ul_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 516.5, - 0.0: 0.0, - 100.0: 108.3, - 20.0: 24.0, - 1000.0: 1027.0, - }, +star_mapping[(1000, True, True, False, Liquid.ETHANOL, True, True)] = \ +HighVolume_96COREHead1000ul_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 516.5, 0.0: 0.0, 100.0: 108.3, 20.0: 24.0, 1000.0: 1027.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -5976,21 +4527,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # to prevent drop's, mix 2x with e.g. 500ul -star_mapping[(1000, True, True, False, Liquid.ETHANOL, False, True)] = ( - HighVolume_96COREHead1000ul_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 516.5, - 0.0: 0.0, - 100.0: 107.0, - 1000.0: 1027.0, - 10.0: 14.0, - }, +star_mapping[(1000, True, True, False, Liquid.ETHANOL, False, True)] = \ +HighVolume_96COREHead1000ul_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 516.5, 0.0: 0.0, 100.0: 107.0, 1000.0: 1027.0, 10.0: 14.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=150.0, aspiration_air_transport_volume=5.0, @@ -6007,20 +4551,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, True, True, False, Liquid.GLYCERIN80, False, True)] = ( - HighVolume_96COREHead1000ul_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 522.0, - 0.0: 0.0, - 100.0: 115.3, - 1000.0: 1034.0, - 10.0: 12.5, - }, +star_mapping[(1000, True, True, False, Liquid.GLYCERIN80, False, True)] = \ +HighVolume_96COREHead1000ul_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 522.0, 0.0: 0.0, 100.0: 115.3, 1000.0: 1034.0, 10.0: 12.5}, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -6037,20 +4574,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, True, True, False, Liquid.WATER, True, False)] = ( - HighVolume_96COREHead1000ul_Water_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 500.0: 524.0, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 24.0, - 1000.0: 1025.0, - }, +star_mapping[(1000, True, True, False, Liquid.WATER, True, False)] = \ +HighVolume_96COREHead1000ul_Water_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={500.0: 524.0, 0.0: 0.0, 100.0: 107.2, 20.0: 24.0, 1000.0: 1025.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -6067,20 +4597,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -star_mapping[(1000, True, True, False, Liquid.WATER, True, True)] = ( - HighVolume_96COREHead1000ul_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 524.0, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 24.0, - 1000.0: 1025.0, - }, +star_mapping[(1000, True, True, False, Liquid.WATER, True, True)] = \ +HighVolume_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 524.0, 0.0: 0.0, 100.0: 107.2, 20.0: 24.0, 1000.0: 1025.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -6097,20 +4620,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, True, True, False, Liquid.WATER, False, True)] = ( - HighVolume_96COREHead1000ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 522.0, - 0.0: 0.0, - 100.0: 108.3, - 1000.0: 1034.0, - 10.0: 12.5, - }, +star_mapping[(1000, True, True, False, Liquid.WATER, False, True)] = \ +HighVolume_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 522.0, 0.0: 0.0, 100.0: 108.3, 1000.0: 1034.0, 10.0: 12.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -6127,24 +4643,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # Liquid class for wash high volume tips with CO-RE 96 Head in CO-RE 96 Head Washer. -star_mapping[(1000, True, True, False, Liquid.WATER, False, False)] = ( - HighVolume_Core96Washer_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 500.0: 520.0, - 50.0: 56.3, - 0.0: 0.0, - 100.0: 110.0, - 20.0: 23.9, - 1000.0: 1050.0, - 200.0: 212.0, - 10.0: 12.5, - }, +star_mapping[(1000, True, True, False, Liquid.WATER, False, False)] = \ +HighVolume_Core96Washer_DispenseSurface = HamiltonLiquidClass( + curve={500.0: 520.0, 50.0: 56.3, 0.0: 0.0, 100.0: 110.0, 20.0: 23.9, 1000.0: 1050.0, 200.0: 212.0, 10.0: 12.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=220.0, aspiration_air_transport_volume=0.0, @@ -6161,7 +4667,7 @@ def get_star_liquid_class( dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -6182,20 +4688,9 @@ def get_star_liquid_class( # 100 ( 9 Aliquots) 0.25 -4.81 # # -star_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = ( - HighVolume_DMSO_AliquotDispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 500.0, - 250.0: 250.0, - 30.0: 30.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - 1000.0: 1000.0, - 750.0: 750.0, - 10.0: 10.0, - }, +star_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = \ +HighVolume_DMSO_AliquotDispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -6212,25 +4707,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = ( - HighVolume_DMSO_DispenseJet -) = HamiltonLiquidClass( - curve={ - 5.0: 5.1, - 500.0: 511.2, - 250.0: 256.2, - 50.0: 52.2, - 0.0: 0.0, - 20.0: 21.3, - 100.0: 103.4, - 10.0: 10.7, - 1000.0: 1021.0, - }, +star_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = \ +HighVolume_DMSO_DispenseJet = HamiltonLiquidClass( + curve={5.0: 5.1, 500.0: 511.2, 250.0: 256.2, 50.0: 52.2, 0.0: 0.0, 20.0: 21.3, 100.0: 103.4, 10.0: 10.7, 1000.0: 1021.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -6247,24 +4731,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, False, Liquid.DMSO, True, True)] = ( - HighVolume_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 511.2, - 5.0: 5.1, - 250.0: 256.2, - 50.0: 52.2, - 0.0: 0.0, - 100.0: 103.4, - 20.0: 21.3, - 1000.0: 1021.0, - 10.0: 10.7, - }, +star_mapping[(1000, False, True, False, Liquid.DMSO, True, True)] = \ +HighVolume_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 511.2, 5.0: 5.1, 250.0: 256.2, 50.0: 52.2, 0.0: 0.0, 100.0: 103.4, 20.0: 21.3, 1000.0: 1021.0, 10.0: 10.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -6281,20 +4754,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = ( - HighVolume_DMSO_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 520.2, - 0.0: 0.0, - 100.0: 112.0, - 20.0: 27.0, - 1000.0: 1031.0, - }, +star_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = \ +HighVolume_DMSO_DispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 520.2, 0.0: 0.0, 100.0: 112.0, 20.0: 27.0, 1000.0: 1031.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -6311,24 +4777,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=5.0, + dispense_stop_back_volume=5.0 ) # V1.1: Set mix flow rate to 120 -star_mapping[(1000, False, True, False, Liquid.DMSO, False, False)] = ( - HighVolume_DMSO_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 500.0: 514.3, - 250.0: 259.0, - 50.0: 54.4, - 0.0: 0.0, - 20.0: 22.8, - 100.0: 105.8, - 10.0: 12.1, - 1000.0: 1024.5, - }, +star_mapping[(1000, False, True, False, Liquid.DMSO, False, False)] = \ +HighVolume_DMSO_DispenseSurface = HamiltonLiquidClass( + curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 20.0: 22.8, 100.0: 105.8, 10.0: 12.1, 1000.0: 1024.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -6345,23 +4801,13 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, False, Liquid.DMSO, False, True)] = ( - HighVolume_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 514.3, - 250.0: 259.0, - 50.0: 54.4, - 0.0: 0.0, - 100.0: 105.8, - 20.0: 22.8, - 1000.0: 1024.5, - 10.0: 12.1, - }, +star_mapping[(1000, False, True, False, Liquid.DMSO, False, True)] = \ +HighVolume_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 100.0: 105.8, 20.0: 22.8, 1000.0: 1024.5, 10.0: 12.1}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -6378,23 +4824,13 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, False, Liquid.DMSO, False, False)] = ( - HighVolume_DMSO_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 514.3, - 250.0: 259.0, - 50.0: 54.4, - 0.0: 0.0, - 100.0: 105.8, - 20.0: 22.8, - 1000.0: 1024.5, - 10.0: 12.4, - }, +star_mapping[(1000, False, True, False, Liquid.DMSO, False, False)] = \ +HighVolume_DMSO_DispenseSurface_Part = HamiltonLiquidClass( + curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 100.0: 105.8, 20.0: 22.8, 1000.0: 1024.5, 10.0: 12.4}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -6411,24 +4847,14 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set Stop back volume to 0 -star_mapping[(1000, False, True, False, Liquid.ETHANOL, True, False)] = ( - HighVolume_EtOH_DispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 534.8, - 250.0: 273.0, - 50.0: 62.9, - 0.0: 0.0, - 20.0: 27.8, - 100.0: 116.3, - 10.0: 15.8, - 1000.0: 1053.9, - }, +star_mapping[(1000, False, True, False, Liquid.ETHANOL, True, False)] = \ +HighVolume_EtOH_DispenseJet = HamiltonLiquidClass( + curve={500.0: 534.8, 250.0: 273.0, 50.0: 62.9, 0.0: 0.0, 20.0: 27.8, 100.0: 116.3, 10.0: 15.8, 1000.0: 1053.9}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -6445,23 +4871,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, False, Liquid.ETHANOL, True, True)] = ( - HighVolume_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 534.8, - 250.0: 273.0, - 50.0: 62.9, - 0.0: 0.0, - 100.0: 116.3, - 20.0: 27.8, - 1000.0: 1053.9, - 10.0: 15.8, - }, +star_mapping[(1000, False, True, False, Liquid.ETHANOL, True, True)] = \ +HighVolume_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 534.8, 250.0: 273.0, 50.0: 62.9, 0.0: 0.0, 100.0: 116.3, 20.0: 27.8, 1000.0: 1053.9, 10.0: 15.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -6478,21 +4894,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, False, Liquid.ETHANOL, True, False)] = ( - HighVolume_EtOH_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 529.0, - 50.0: 62.9, - 0.0: 0.0, - 100.0: 114.5, - 20.0: 27.8, - 1000.0: 1053.9, - }, +star_mapping[(1000, False, True, False, Liquid.ETHANOL, True, False)] = \ +HighVolume_EtOH_DispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 529.0, 50.0: 62.9, 0.0: 0.0, 100.0: 114.5, 20.0: 27.8, 1000.0: 1053.9}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -6509,23 +4917,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=5.0, + dispense_stop_back_volume=5.0 ) -star_mapping[(1000, False, True, False, Liquid.ETHANOL, False, False)] = ( - HighVolume_EtOH_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 500.0: 528.4, - 250.0: 269.2, - 50.0: 61.2, - 0.0: 0.0, - 100.0: 114.0, - 20.0: 27.6, - 1000.0: 1044.3, - 10.0: 15.7, - }, +star_mapping[(1000, False, True, False, Liquid.ETHANOL, False, False)] = \ +HighVolume_EtOH_DispenseSurface = HamiltonLiquidClass( + curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 100.0: 114.0, 20.0: 27.6, 1000.0: 1044.3, 10.0: 15.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -6542,23 +4940,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, False, Liquid.ETHANOL, False, True)] = ( - HighVolume_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 528.4, - 250.0: 269.2, - 50.0: 61.2, - 0.0: 0.0, - 20.0: 27.6, - 100.0: 114.0, - 10.0: 15.7, - 1000.0: 1044.3, - }, +star_mapping[(1000, False, True, False, Liquid.ETHANOL, False, True)] = \ +HighVolume_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 20.0: 27.6, 100.0: 114.0, 10.0: 15.7, 1000.0: 1044.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -6575,23 +4963,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, False, Liquid.ETHANOL, False, False)] = ( - HighVolume_EtOH_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 528.4, - 250.0: 269.2, - 50.0: 61.2, - 0.0: 0.0, - 100.0: 114.0, - 20.0: 27.6, - 1000.0: 1044.3, - 10.0: 14.7, - }, +star_mapping[(1000, False, True, False, Liquid.ETHANOL, False, False)] = \ +HighVolume_EtOH_DispenseSurface_Part = HamiltonLiquidClass( + curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 100.0: 114.0, 20.0: 27.6, 1000.0: 1044.3, 10.0: 14.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -6608,24 +4986,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 200 -star_mapping[(1000, False, True, False, Liquid.GLYCERIN80, True, False)] = ( - HighVolume_Glycerin80_DispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 537.8, - 250.0: 277.0, - 50.0: 63.3, - 0.0: 0.0, - 20.0: 28.0, - 100.0: 118.8, - 10.0: 15.2, - 1000.0: 1060.0, - }, +star_mapping[(1000, False, True, False, Liquid.GLYCERIN80, True, False)] = \ +HighVolume_Glycerin80_DispenseJet = HamiltonLiquidClass( + curve={500.0: 537.8, 250.0: 277.0, 50.0: 63.3, 0.0: 0.0, 20.0: 28.0, 100.0: 118.8, 10.0: 15.2, 1000.0: 1060.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=5.0, @@ -6642,23 +5010,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(1000, False, True, False, Liquid.GLYCERIN80, True, True)] = ( - HighVolume_Glycerin80_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 537.8, - 250.0: 277.0, - 50.0: 63.3, - 0.0: 0.0, - 100.0: 118.8, - 20.0: 28.0, - 1000.0: 1060.0, - 10.0: 15.2, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(1000, False, True, False, Liquid.GLYCERIN80, True, True)] = \ +HighVolume_Glycerin80_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 537.8, 250.0: 277.0, 50.0: 63.3, 0.0: 0.0, 100.0: 118.8, 20.0: 28.0, 1000.0: 1060.0, 10.0: 15.2}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=5.0, @@ -6675,24 +5033,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 120 -star_mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, False)] = ( - HighVolume_Glycerin80_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 500.0: 513.5, - 250.0: 257.2, - 50.0: 55.0, - 0.0: 0.0, - 20.0: 22.7, - 100.0: 105.5, - 10.0: 12.2, - 1000.0: 1027.2, - }, +star_mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, False)] = \ +HighVolume_Glycerin80_DispenseSurface = HamiltonLiquidClass( + curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 20.0: 22.7, 100.0: 105.5, 10.0: 12.2, 1000.0: 1027.2}, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -6709,23 +5057,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, True)] = ( - HighVolume_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 513.5, - 250.0: 257.2, - 50.0: 55.0, - 0.0: 0.0, - 100.0: 105.5, - 20.0: 22.7, - 1000.0: 1027.2, - 10.0: 12.2, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, True)] = \ +HighVolume_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 100.0: 105.5, 20.0: 22.7, 1000.0: 1027.2, 10.0: 12.2}, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -6742,23 +5080,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, False)] = ( - HighVolume_Glycerin80_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 513.5, - 250.0: 257.2, - 50.0: 55.0, - 0.0: 0.0, - 100.0: 105.5, - 20.0: 22.7, - 1000.0: 1027.2, - 10.0: 12.2, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, False)] = \ +HighVolume_Glycerin80_DispenseSurface_Part = HamiltonLiquidClass( + curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 100.0: 105.5, 20.0: 22.7, 1000.0: 1027.2, 10.0: 12.2}, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -6775,25 +5103,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = ( - HighVolume_Serum_AliquotDispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 500.0, - 250.0: 250.0, - 30.0: 30.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - 1000.0: 1000.0, - 750.0: 750.0, - 10.0: 10.0, - }, +star_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = \ +HighVolume_Serum_AliquotDispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -6810,25 +5127,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=300.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = ( - HighVolume_Serum_AliquotJet -) = HamiltonLiquidClass( - curve={ - 500.0: 500.0, - 250.0: 250.0, - 0.0: 0.0, - 30.0: 30.0, - 20.0: 20.0, - 100.0: 100.0, - 10.0: 10.0, - 750.0: 750.0, - 1000.0: 1000.0, - }, +star_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = \ +HighVolume_Serum_AliquotJet = HamiltonLiquidClass( + curve={500.0: 500.0, 250.0: 250.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 100.0: 100.0, 10.0: 10.0, 750.0: 750.0, 1000.0: 1000.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -6845,24 +5151,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=300.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 250, settling time = 0 -star_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = ( - HighVolume_Serum_DispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 525.3, - 250.0: 266.6, - 50.0: 57.9, - 0.0: 0.0, - 20.0: 24.2, - 100.0: 111.3, - 10.0: 12.2, - 1000.0: 1038.6, - }, +star_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = \ +HighVolume_Serum_DispenseJet = HamiltonLiquidClass( + curve={500.0: 525.3, 250.0: 266.6, 50.0: 57.9, 0.0: 0.0, 20.0: 24.2, 100.0: 111.3, 10.0: 12.2, 1000.0: 1038.6}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -6879,23 +5175,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, False, Liquid.SERUM, True, True)] = ( - HighVolume_Serum_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 525.3, - 250.0: 266.6, - 50.0: 57.9, - 0.0: 0.0, - 100.0: 111.3, - 20.0: 24.2, - 1000.0: 1038.6, - 10.0: 12.2, - }, +star_mapping[(1000, False, True, False, Liquid.SERUM, True, True)] = \ +HighVolume_Serum_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 525.3, 250.0: 266.6, 50.0: 57.9, 0.0: 0.0, 100.0: 111.3, 20.0: 24.2, 1000.0: 1038.6, 10.0: 12.2}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -6912,20 +5198,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = ( - HighVolume_Serum_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 525.3, - 0.0: 0.0, - 100.0: 111.3, - 20.0: 27.3, - 1000.0: 1046.6, - }, +star_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = \ +HighVolume_Serum_DispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 525.3, 0.0: 0.0, 100.0: 111.3, 20.0: 27.3, 1000.0: 1046.6}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -6942,24 +5221,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 120 -star_mapping[(1000, False, True, False, Liquid.SERUM, False, False)] = ( - HighVolume_Serum_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 500.0: 517.5, - 250.0: 261.9, - 50.0: 55.9, - 0.0: 0.0, - 20.0: 23.2, - 100.0: 108.2, - 10.0: 11.8, - 1000.0: 1026.7, - }, +star_mapping[(1000, False, True, False, Liquid.SERUM, False, False)] = \ +HighVolume_Serum_DispenseSurface = HamiltonLiquidClass( + curve={500.0: 517.5, 250.0: 261.9, 50.0: 55.9, 0.0: 0.0, 20.0: 23.2, 100.0: 108.2, 10.0: 11.8, 1000.0: 1026.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -6976,23 +5245,13 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, False, Liquid.SERUM, False, True)] = ( - HighVolume_Serum_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 517.5, - 250.0: 261.9, - 50.0: 55.9, - 0.0: 0.0, - 100.0: 108.2, - 20.0: 23.2, - 1000.0: 1026.7, - 10.0: 11.8, - }, +star_mapping[(1000, False, True, False, Liquid.SERUM, False, True)] = \ +HighVolume_Serum_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 517.5, 250.0: 261.9, 50.0: 55.9, 0.0: 0.0, 100.0: 108.2, 20.0: 23.2, 1000.0: 1026.7, 10.0: 11.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -7009,21 +5268,13 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, False, Liquid.SERUM, False, False)] = ( - HighVolume_Serum_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 50.0: 55.9, - 0.0: 0.0, - 100.0: 108.2, - 20.0: 23.2, - 1000.0: 1037.7, - 10.0: 11.8, - }, +star_mapping[(1000, False, True, False, Liquid.SERUM, False, False)] = \ +HighVolume_Serum_DispenseSurface_Part = HamiltonLiquidClass( + curve={50.0: 55.9, 0.0: 0.0, 100.0: 108.2, 20.0: 23.2, 1000.0: 1037.7, 10.0: 11.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -7040,25 +5291,14 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = ( - HighVolume_Water_AliquotDispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 500.0, - 250.0: 250.0, - 30.0: 30.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - 1000.0: 1000.0, - 750.0: 750.0, - 10.0: 10.0, - }, +star_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = \ +HighVolume_Water_AliquotDispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -7075,25 +5315,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = ( - HighVolume_Water_AliquotJet -) = HamiltonLiquidClass( - curve={ - 500.0: 500.0, - 250.0: 250.0, - 0.0: 0.0, - 30.0: 30.0, - 20.0: 20.0, - 100.0: 100.0, - 10.0: 10.0, - 750.0: 750.0, - 1000.0: 1000.0, - }, +star_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = \ +HighVolume_Water_AliquotJet = HamiltonLiquidClass( + curve={500.0: 500.0, 250.0: 250.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 100.0: 100.0, 10.0: 10.0, 750.0: 750.0, 1000.0: 1000.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -7110,24 +5339,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = ( - HighVolume_Water_DispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 521.7, - 50.0: 57.2, - 0.0: 0.0, - 20.0: 24.6, - 100.0: 109.6, - 10.0: 13.3, - 200.0: 212.9, - 1000.0: 1034.0, - }, +star_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = \ +HighVolume_Water_DispenseJet = HamiltonLiquidClass( + curve={500.0: 521.7, 50.0: 57.2, 0.0: 0.0, 20.0: 24.6, 100.0: 109.6, 10.0: 13.3, 200.0: 212.9, 1000.0: 1034.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -7144,23 +5363,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, False, Liquid.WATER, True, True)] = ( - HighVolume_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 521.7, - 50.0: 57.2, - 0.0: 0.0, - 100.0: 109.6, - 20.0: 24.6, - 1000.0: 1034.0, - 200.0: 212.9, - 10.0: 13.3, - }, +star_mapping[(1000, False, True, False, Liquid.WATER, True, True)] = \ +HighVolume_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 521.7, 50.0: 57.2, 0.0: 0.0, 100.0: 109.6, 20.0: 24.6, 1000.0: 1034.0, 200.0: 212.9, 10.0: 13.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -7177,20 +5386,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = ( - HighVolume_Water_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 521.7, - 0.0: 0.0, - 100.0: 109.6, - 20.0: 26.9, - 1000.0: 1040.0, - }, +star_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = \ +HighVolume_Water_DispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 521.7, 0.0: 0.0, 100.0: 109.6, 20.0: 26.9, 1000.0: 1040.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -7207,24 +5409,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=18.0, + dispense_stop_back_volume=18.0 ) # V1.1: Set mix flow rate to 120, clot retract height = 0 -star_mapping[(1000, False, True, False, Liquid.WATER, False, False)] = ( - HighVolume_Water_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 500.0: 518.3, - 50.0: 56.3, - 0.0: 0.0, - 20.0: 23.9, - 100.0: 108.3, - 10.0: 12.5, - 200.0: 211.0, - 1000.0: 1028.5, - }, +star_mapping[(1000, False, True, False, Liquid.WATER, False, False)] = \ +HighVolume_Water_DispenseSurface = HamiltonLiquidClass( + curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 20.0: 23.9, 100.0: 108.3, 10.0: 12.5, 200.0: 211.0, 1000.0: 1028.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -7241,23 +5433,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, False, Liquid.WATER, False, True)] = ( - HighVolume_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 518.3, - 50.0: 56.3, - 0.0: 0.0, - 100.0: 108.3, - 20.0: 23.9, - 1000.0: 1028.5, - 200.0: 211.0, - 10.0: 12.5, - }, +star_mapping[(1000, False, True, False, Liquid.WATER, False, True)] = \ +HighVolume_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 100.0: 108.3, 20.0: 23.9, 1000.0: 1028.5, 200.0: 211.0, 10.0: 12.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -7274,23 +5456,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(1000, False, True, False, Liquid.WATER, False, False)] = ( - HighVolume_Water_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 518.3, - 50.0: 56.3, - 0.0: 0.0, - 100.0: 108.3, - 20.0: 23.9, - 1000.0: 1036.5, - 200.0: 211.0, - 10.0: 12.5, - }, +star_mapping[(1000, False, True, False, Liquid.WATER, False, False)] = \ +HighVolume_Water_DispenseSurface_Part = HamiltonLiquidClass( + curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 100.0: 108.3, 20.0: 23.9, 1000.0: 1036.5, 200.0: 211.0, 10.0: 12.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -7307,7 +5479,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -7317,19 +5489,9 @@ def get_star_liquid_class( # - fix height from bottom between 0.5-0.7mm # - dispense mode jet empty tip # - also with higher DNA concentration -star_mapping[(10, False, False, False, Liquid.DNA_TRIS_EDTA, True, False)] = ( - LowNeedleDNADispenseJet -) = HamiltonLiquidClass( - curve={ - 5.0: 5.7, - 0.5: 1.0, - 50.0: 53.0, - 0.0: 0.0, - 20.0: 22.1, - 1.0: 1.5, - 10.0: 10.8, - 2.0: 2.7, - }, +star_mapping[(10, False, False, False, Liquid.DNA_TRIS_EDTA, True, False)] = \ +LowNeedleDNADispenseJet = HamiltonLiquidClass( + curve={5.0: 5.7, 0.5: 1.0, 50.0: 53.0, 0.0: 0.0, 20.0: 22.1, 1.0: 1.5, 10.0: 10.8, 2.0: 2.7}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=0.0, @@ -7346,7 +5508,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.5, + dispense_stop_back_volume=0.5 ) @@ -7355,19 +5517,9 @@ def get_star_liquid_class( # - for Disp. in empty PCR-Plate/on empty Plate from 1µl up # - fix height from bottom between 0.5-0.7mm # - also with higher DNA concentration -star_mapping[(10, False, False, False, Liquid.DNA_TRIS_EDTA, False, False)] = ( - LowNeedleDNADispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 5.7, - 0.5: 1.0, - 50.0: 53.0, - 0.0: 0.0, - 20.0: 22.1, - 1.0: 1.5, - 10.0: 10.8, - 2.0: 2.7, - }, +star_mapping[(10, False, False, False, Liquid.DNA_TRIS_EDTA, False, False)] = \ +LowNeedleDNADispenseSurface = HamiltonLiquidClass( + curve={5.0: 5.7, 0.5: 1.0, 50.0: 53.0, 0.0: 0.0, 20.0: 22.1, 1.0: 1.5, 10.0: 10.8, 2.0: 2.7}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=0.0, @@ -7384,24 +5536,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 60 -star_mapping[(10, False, False, False, Liquid.WATER, False, False)] = ( - LowNeedle_SysFlWater_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 35.0: 35.6, - 60.0: 62.7, - 50.0: 51.3, - 40.0: 40.9, - 30.0: 30.0, - 0.0: 0.0, - 31.0: 31.4, - 32.0: 32.7, - }, +star_mapping[(10, False, False, False, Liquid.WATER, False, False)] = \ +LowNeedle_SysFlWater_DispenseSurface = HamiltonLiquidClass( + curve={35.0: 35.6, 60.0: 62.7, 50.0: 51.3, 40.0: 40.9, 30.0: 30.0, 0.0: 0.0, 31.0: 31.4, 32.0: 32.7}, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, aspiration_air_transport_volume=0.0, @@ -7418,13 +5560,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, False, False, Liquid.WATER, True, False)] = ( - LowNeedle_Water_DispenseJet -) = HamiltonLiquidClass( +star_mapping[(10, False, False, False, Liquid.WATER, True, False)] = \ +LowNeedle_Water_DispenseJet = HamiltonLiquidClass( curve={50.0: 52.7, 30.0: 31.7, 0.0: 0.0, 20.0: 20.5, 10.0: 10.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7442,21 +5583,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, False, False, Liquid.WATER, True, True)] = ( - LowNeedle_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 70.0: 70.0, - 50.0: 52.7, - 30.0: 31.7, - 0.0: 0.0, - 20.0: 20.5, - 10.0: 10.3, - }, +star_mapping[(10, False, False, False, Liquid.WATER, True, True)] = \ +LowNeedle_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={70.0: 70.0, 50.0: 52.7, 30.0: 31.7, 0.0: 0.0, 20.0: 20.5, 10.0: 10.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=15.0, @@ -7473,21 +5606,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, False, False, Liquid.WATER, True, False)] = ( - LowNeedle_Water_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 70.0: 70.0, - 50.0: 52.7, - 30.0: 31.7, - 0.0: 0.0, - 20.0: 20.5, - 10.0: 10.3, - }, +star_mapping[(10, False, False, False, Liquid.WATER, True, False)] = \ +LowNeedle_Water_DispenseJet_Part = HamiltonLiquidClass( + curve={70.0: 70.0, 50.0: 52.7, 30.0: 31.7, 0.0: 0.0, 20.0: 20.5, 10.0: 10.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=15.0, @@ -7504,24 +5629,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 60 -star_mapping[(10, False, False, False, Liquid.WATER, False, False)] = ( - LowNeedle_Water_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 5.0, - 0.5: 0.5, - 50.0: 50.0, - 0.0: 0.0, - 20.0: 20.5, - 1.0: 1.0, - 10.0: 10.0, - 2.0: 2.0, - }, +star_mapping[(10, False, False, False, Liquid.WATER, False, False)] = \ +LowNeedle_Water_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 5.0, 0.5: 0.5, 50.0: 50.0, 0.0: 0.0, 20.0: 20.5, 1.0: 1.0, 10.0: 10.0, 2.0: 2.0}, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, aspiration_air_transport_volume=0.0, @@ -7538,24 +5653,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(10, False, False, False, Liquid.WATER, False, True)] = ( - LowNeedle_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.0, - 0.5: 0.5, - 70.0: 70.0, - 50.0: 50.0, - 0.0: 0.0, - 20.0: 20.5, - 1.0: 1.0, - 10.0: 10.0, - 2.0: 2.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(10, False, False, False, Liquid.WATER, False, True)] = \ +LowNeedle_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.0, 0.5: 0.5, 70.0: 70.0, 50.0: 50.0, 0.0: 0.0, 20.0: 20.5, 1.0: 1.0, 10.0: 10.0, 2.0: 2.0}, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, aspiration_air_transport_volume=0.0, @@ -7572,24 +5676,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(10, False, False, False, Liquid.WATER, False, False)] = ( - LowNeedle_Water_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 5.0: 5.0, - 0.5: 0.5, - 70.0: 70.0, - 50.0: 50.0, - 0.0: 0.0, - 20.0: 20.5, - 1.0: 1.0, - 10.0: 10.0, - 2.0: 2.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(10, False, False, False, Liquid.WATER, False, False)] = \ +LowNeedle_Water_DispenseSurface_Part = HamiltonLiquidClass( + curve={5.0: 5.0, 0.5: 0.5, 70.0: 70.0, 50.0: 50.0, 0.0: 0.0, 20.0: 20.5, 1.0: 1.0, 10.0: 10.0, 2.0: 2.0}, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, aspiration_air_transport_volume=0.0, @@ -7606,13 +5699,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, True, True, True, Liquid.DMSO, False, True)] = ( - LowVolumeFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( +star_mapping[(10, True, True, True, Liquid.DMSO, False, True)] = \ +LowVolumeFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 5.3, 0.0: 0.0, 1.0: 0.8, 10.0: 10.0}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -7630,13 +5722,12 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, True, True, True, Liquid.WATER, False, True)] = ( - LowVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( +star_mapping[(10, True, True, True, Liquid.WATER, False, True)] = \ +LowVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 5.8, 0.0: 0.0, 1.0: 1.0, 10.0: 10.0}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -7654,13 +5745,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, True, True, True, Liquid.DMSO, False, True)] = ( - LowVolumeFilter_96COREHead_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( +star_mapping[(10, True, True, True, Liquid.DMSO, False, True)] = \ +LowVolumeFilter_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 5.1, 0.0: 0.0, 1.0: 0.8, 10.0: 10.0}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -7678,13 +5768,12 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, True, True, True, Liquid.DMSO, False, False)] = ( - LowVolumeFilter_96COREHead_DMSO_DispenseSurface_Part -) = HamiltonLiquidClass( +star_mapping[(10, True, True, True, Liquid.DMSO, False, False)] = \ +LowVolumeFilter_96COREHead_DMSO_DispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 5.7, 0.0: 0.0, 1.0: 1.5, 10.0: 10.3}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -7702,13 +5791,12 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, True, True, True, Liquid.WATER, False, True)] = ( - LowVolumeFilter_96COREHead_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( +star_mapping[(10, True, True, True, Liquid.WATER, False, True)] = \ +LowVolumeFilter_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 5.6, 0.0: 0.0, 1.0: 1.2, 10.0: 10.0}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -7726,13 +5814,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, True, True, True, Liquid.WATER, False, False)] = ( - LowVolumeFilter_96COREHead_Water_DispenseSurface_Part -) = HamiltonLiquidClass( +star_mapping[(10, True, True, True, Liquid.WATER, False, False)] = \ +LowVolumeFilter_96COREHead_Water_DispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 5.8, 0.0: 0.0, 1.0: 1.5, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -7750,23 +5837,14 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 75 -star_mapping[(10, False, True, True, Liquid.DMSO, False, False)] = ( - LowVolumeFilter_DMSO_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 5.9, - 0.5: 0.8, - 15.0: 16.4, - 0.0: 0.0, - 1.0: 1.4, - 2.0: 2.6, - 10.0: 11.2, - }, +star_mapping[(10, False, True, True, Liquid.DMSO, False, False)] = \ +LowVolumeFilter_DMSO_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 5.9, 0.5: 0.8, 15.0: 16.4, 0.0: 0.0, 1.0: 1.4, 2.0: 2.6, 10.0: 11.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -7783,21 +5861,13 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=56.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, True, True, Liquid.DMSO, False, True)] = ( - LowVolumeFilter_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.9, - 0.5: 0.8, - 0.0: 0.0, - 1.0: 1.4, - 10.0: 10.0, - 2.0: 2.6, - }, +star_mapping[(10, False, True, True, Liquid.DMSO, False, True)] = \ +LowVolumeFilter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.9, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 10.0, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -7814,13 +5884,12 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, True, True, Liquid.DMSO, False, False)] = ( - LowVolumeFilter_DMSO_DispenseSurface_Part -) = HamiltonLiquidClass( +star_mapping[(10, False, True, True, Liquid.DMSO, False, False)] = \ +LowVolumeFilter_DMSO_DispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.4, 10.0: 10.0, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -7838,22 +5907,14 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 75 -star_mapping[(10, False, True, True, Liquid.ETHANOL, False, False)] = ( - LowVolumeFilter_EtOH_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 8.4, - 0.5: 1.9, - 0.0: 0.0, - 1.0: 2.7, - 2.0: 4.1, - 10.0: 13.0, - }, +star_mapping[(10, False, True, True, Liquid.ETHANOL, False, False)] = \ +LowVolumeFilter_EtOH_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 8.4, 0.5: 1.9, 0.0: 0.0, 1.0: 2.7, 2.0: 4.1, 10.0: 13.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=2.0, @@ -7870,13 +5931,12 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, True, True, Liquid.ETHANOL, False, True)] = ( - LowVolumeFilter_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( +star_mapping[(10, False, True, True, Liquid.ETHANOL, False, True)] = \ +LowVolumeFilter_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 6.6, 0.0: 0.0, 1.0: 1.8, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -7894,13 +5954,12 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, True, True, Liquid.ETHANOL, False, False)] = ( - LowVolumeFilter_EtOH_DispenseSurface_Part -) = HamiltonLiquidClass( +star_mapping[(10, False, True, True, Liquid.ETHANOL, False, False)] = \ +LowVolumeFilter_EtOH_DispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 6.4, 0.0: 0.0, 1.0: 1.8, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -7918,23 +5977,14 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 10 -star_mapping[(10, False, True, True, Liquid.GLYCERIN, False, False)] = ( - LowVolumeFilter_Glycerin_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 6.5, - 0.5: 1.4, - 15.0: 17.0, - 0.0: 0.0, - 1.0: 2.0, - 2.0: 3.2, - 10.0: 11.8, - }, +star_mapping[(10, False, True, True, Liquid.GLYCERIN, False, False)] = \ +LowVolumeFilter_Glycerin_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 6.5, 0.5: 1.4, 15.0: 17.0, 0.0: 0.0, 1.0: 2.0, 2.0: 3.2, 10.0: 11.8}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -7951,13 +6001,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, True, True, Liquid.GLYCERIN80, False, True)] = ( - LowVolumeFilter_Glycerin_DispenseSurface_Empty -) = HamiltonLiquidClass( +star_mapping[(10, False, True, True, Liquid.GLYCERIN80, False, True)] = \ +LowVolumeFilter_Glycerin_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 6.5, 0.0: 0.0, 1.0: 0.6, 10.0: 10.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, @@ -7975,23 +6024,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 75 -star_mapping[(10, False, True, True, Liquid.WATER, False, False)] = ( - LowVolumeFilter_Water_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 6.0, - 0.5: 0.8, - 15.0: 16.7, - 0.0: 0.0, - 1.0: 1.4, - 2.0: 2.6, - 10.0: 11.5, - }, +star_mapping[(10, False, True, True, Liquid.WATER, False, False)] = \ +LowVolumeFilter_Water_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 6.0, 0.5: 0.8, 15.0: 16.7, 0.0: 0.0, 1.0: 1.4, 2.0: 2.6, 10.0: 11.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -8008,21 +6048,13 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=56.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, True, True, Liquid.WATER, False, True)] = ( - LowVolumeFilter_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 6.0, - 0.5: 0.8, - 0.0: 0.0, - 1.0: 1.4, - 10.0: 10.0, - 2.0: 2.6, - }, +star_mapping[(10, False, True, True, Liquid.WATER, False, True)] = \ +LowVolumeFilter_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 6.0, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 10.0, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -8039,13 +6071,12 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, True, True, Liquid.WATER, False, False)] = ( - LowVolumeFilter_Water_DispenseSurface_Part -) = HamiltonLiquidClass( +star_mapping[(10, False, True, True, Liquid.WATER, False, False)] = \ +LowVolumeFilter_Water_DispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.2, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -8063,7 +6094,7 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -8084,17 +6115,9 @@ def get_star_liquid_class( # 5.0 1.08 -1.29 # 10.0 0.62 0.53 # -star_mapping[(10, False, True, False, Liquid.PLASMA, False, False)] = ( - LowVolumePlasmaDispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 5.9, - 0.5: 0.8, - 0.0: 0.0, - 1.0: 1.4, - 10.0: 11.5, - 2.0: 2.6, - }, +star_mapping[(10, False, True, False, Liquid.PLASMA, False, False)] = \ +LowVolumePlasmaDispenseSurface = HamiltonLiquidClass( + curve={5.0: 5.9, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 11.5, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -8111,21 +6134,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, True, False, Liquid.PLASMA, False, True)] = ( - LowVolumePlasmaDispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.6, - 0.5: 0.2, - 0.0: 0.0, - 1.0: 0.9, - 10.0: 11.3, - 2.0: 2.2, - }, +star_mapping[(10, False, True, False, Liquid.PLASMA, False, True)] = \ +LowVolumePlasmaDispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.6, 0.5: 0.2, 0.0: 0.0, 1.0: 0.9, 10.0: 11.3, 2.0: 2.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -8142,13 +6157,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, True, False, Liquid.PLASMA, False, False)] = ( - LowVolumePlasmaDispenseSurface_Part -) = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.PLASMA, False, False)] = \ +LowVolumePlasmaDispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.3, 10.0: 11.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8166,7 +6180,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -8187,17 +6201,9 @@ def get_star_liquid_class( # 5.0 1.08 -1.29 # 10.0 0.62 0.53 # -star_mapping[(10, False, True, False, Liquid.SERUM, False, False)] = ( - LowVolumeSerumDispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 5.6, - 0.5: 0.2, - 0.0: 0.0, - 1.0: 0.9, - 10.0: 11.3, - 2.0: 2.2, - }, +star_mapping[(10, False, True, False, Liquid.SERUM, False, False)] = \ +LowVolumeSerumDispenseSurface = HamiltonLiquidClass( + curve={5.0: 5.6, 0.5: 0.2, 0.0: 0.0, 1.0: 0.9, 10.0: 11.3, 2.0: 2.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -8214,21 +6220,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, True, False, Liquid.SERUM, False, True)] = ( - LowVolumeSerumDispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.6, - 0.5: 0.2, - 0.0: 0.0, - 1.0: 0.9, - 10.0: 11.3, - 2.0: 2.2, - }, +star_mapping[(10, False, True, False, Liquid.SERUM, False, True)] = \ +LowVolumeSerumDispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.6, 0.5: 0.2, 0.0: 0.0, 1.0: 0.9, 10.0: 11.3, 2.0: 2.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -8245,13 +6243,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, True, False, Liquid.SERUM, False, False)] = ( - LowVolumeSerumDispenseSurface_Part -) = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.SERUM, False, False)] = \ +LowVolumeSerumDispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.3, 10.0: 11.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8269,13 +6266,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, True, True, False, Liquid.DMSO, False, True)] = ( - LowVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( +star_mapping[(10, True, True, False, Liquid.DMSO, False, True)] = \ +LowVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 5.3, 0.0: 0.0, 1.0: 0.8, 10.0: 10.6}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -8293,13 +6289,12 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, True, True, False, Liquid.WATER, False, True)] = ( - LowVolume_96COREHead1000ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( +star_mapping[(10, True, True, False, Liquid.WATER, False, True)] = \ +LowVolume_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 5.8, 0.0: 0.0, 1.0: 1.0, 10.0: 11.2}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -8317,13 +6312,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, True, True, False, Liquid.DMSO, False, True)] = ( - LowVolume_96COREHead_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( +star_mapping[(10, True, True, False, Liquid.DMSO, False, True)] = \ +LowVolume_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 5.1, 0.0: 0.0, 1.0: 0.8, 10.0: 10.3}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -8341,13 +6335,12 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, True, True, False, Liquid.DMSO, False, False)] = ( - LowVolume_96COREHead_DMSO_DispenseSurface_Part -) = HamiltonLiquidClass( +star_mapping[(10, True, True, False, Liquid.DMSO, False, False)] = \ +LowVolume_96COREHead_DMSO_DispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.5, 10.0: 11.0}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -8365,13 +6358,12 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, True, True, False, Liquid.WATER, False, True)] = ( - LowVolume_96COREHead_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( +star_mapping[(10, True, True, False, Liquid.WATER, False, True)] = \ +LowVolume_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 5.8, 0.0: 0.0, 1.0: 1.3, 10.0: 11.1}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -8389,13 +6381,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, True, True, False, Liquid.WATER, False, False)] = ( - LowVolume_96COREHead_Water_DispenseSurface_Part -) = HamiltonLiquidClass( +star_mapping[(10, True, True, False, Liquid.WATER, False, False)] = \ +LowVolume_96COREHead_Water_DispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 5.7, 0.0: 0.0, 1.0: 1.4, 10.0: 10.8}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -8413,22 +6404,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # Liquid class for wash low volume tips with CO-RE 96 Head in CO-RE 96 Head Washer. -star_mapping[(10, True, True, False, Liquid.WATER, False, False)] = ( - LowVolume_Core96Washer_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 6.0, - 0.5: 0.8, - 0.0: 0.0, - 1.0: 1.4, - 10.0: 15.0, - 2.0: 2.6, - }, +star_mapping[(10, True, True, False, Liquid.WATER, False, False)] = \ +LowVolume_Core96Washer_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 6.0, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 15.0, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=150.0, aspiration_air_transport_volume=0.0, @@ -8445,23 +6428,14 @@ def get_star_liquid_class( dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=56.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 75 -star_mapping[(10, False, True, False, Liquid.DMSO, False, False)] = ( - LowVolume_DMSO_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 5.9, - 15.0: 16.4, - 0.5: 0.8, - 0.0: 0.0, - 1.0: 1.4, - 10.0: 11.2, - 2.0: 2.6, - }, +star_mapping[(10, False, True, False, Liquid.DMSO, False, False)] = \ +LowVolume_DMSO_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 5.9, 15.0: 16.4, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 11.2, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -8478,21 +6452,13 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=56.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, True, False, Liquid.DMSO, False, True)] = ( - LowVolume_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.9, - 0.5: 0.8, - 0.0: 0.0, - 1.0: 1.4, - 10.0: 11.2, - 2.0: 2.6, - }, +star_mapping[(10, False, True, False, Liquid.DMSO, False, True)] = \ +LowVolume_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.9, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 11.2, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -8509,13 +6475,12 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, True, False, Liquid.DMSO, False, False)] = ( - LowVolume_DMSO_DispenseSurface_Part -) = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.DMSO, False, False)] = \ +LowVolume_DMSO_DispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.4, 10.0: 11.2, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -8533,22 +6498,14 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 75 -star_mapping[(10, False, True, False, Liquid.ETHANOL, False, False)] = ( - LowVolume_EtOH_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 8.4, - 0.5: 1.9, - 0.0: 0.0, - 1.0: 2.7, - 10.0: 13.0, - 2.0: 4.1, - }, +star_mapping[(10, False, True, False, Liquid.ETHANOL, False, False)] = \ +LowVolume_EtOH_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 8.4, 0.5: 1.9, 0.0: 0.0, 1.0: 2.7, 10.0: 13.0, 2.0: 4.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=2.0, @@ -8565,13 +6522,12 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, True, False, Liquid.ETHANOL, False, True)] = ( - LowVolume_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.ETHANOL, False, True)] = \ +LowVolume_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 7.3, 0.0: 0.0, 1.0: 2.4, 10.0: 13.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -8589,13 +6545,12 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, True, False, Liquid.ETHANOL, False, False)] = ( - LowVolume_EtOH_DispenseSurface_Part -) = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.ETHANOL, False, False)] = \ +LowVolume_EtOH_DispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 7.0, 0.0: 0.0, 1.0: 2.4, 10.0: 13.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -8613,23 +6568,14 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 10 -star_mapping[(10, False, True, False, Liquid.GLYCERIN, False, False)] = ( - LowVolume_Glycerin_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 6.5, - 15.0: 17.0, - 0.5: 1.4, - 0.0: 0.0, - 1.0: 2.0, - 10.0: 11.8, - 2.0: 3.2, - }, +star_mapping[(10, False, True, False, Liquid.GLYCERIN, False, False)] = \ +LowVolume_Glycerin_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 6.5, 15.0: 17.0, 0.5: 1.4, 0.0: 0.0, 1.0: 2.0, 10.0: 11.8, 2.0: 3.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -8646,23 +6592,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 75 -star_mapping[(10, False, True, False, Liquid.WATER, False, False)] = ( - LowVolume_Water_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 6.0, - 15.0: 16.7, - 0.5: 0.8, - 0.0: 0.0, - 1.0: 1.4, - 10.0: 11.5, - 2.0: 2.6, - }, +star_mapping[(10, False, True, False, Liquid.WATER, False, False)] = \ +LowVolume_Water_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 6.0, 15.0: 16.7, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 11.5, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -8679,13 +6616,12 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=56.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, True, True, False, Liquid.WATER, False, False)] = ( - LowVolume_Water_DispenseSurface96Head -) = HamiltonLiquidClass( +star_mapping[(10, True, True, False, Liquid.WATER, False, False)] = \ +LowVolume_Water_DispenseSurface96Head = HamiltonLiquidClass( curve={5.0: 6.0, 0.0: 0.0, 1.0: 1.0, 10.0: 11.5}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -8703,13 +6639,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, True, True, False, Liquid.WATER, False, True)] = ( - LowVolume_Water_DispenseSurfaceEmpty96Head -) = HamiltonLiquidClass( +star_mapping[(10, True, True, False, Liquid.WATER, False, True)] = \ +LowVolume_Water_DispenseSurfaceEmpty96Head = HamiltonLiquidClass( curve={5.0: 6.0, 0.0: 0.0, 1.0: 1.0, 10.0: 10.9}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -8727,13 +6662,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, True, True, False, Liquid.WATER, False, False)] = ( - LowVolume_Water_DispenseSurfacePart96Head -) = HamiltonLiquidClass( +star_mapping[(10, True, True, False, Liquid.WATER, False, False)] = \ +LowVolume_Water_DispenseSurfacePart96Head = HamiltonLiquidClass( curve={5.0: 6.0, 0.0: 0.0, 1.0: 1.0, 10.0: 10.9}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -8751,21 +6685,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, True, False, Liquid.WATER, False, True)] = ( - LowVolume_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 6.0, - 0.5: 0.8, - 0.0: 0.0, - 1.0: 1.4, - 10.0: 11.5, - 2.0: 2.6, - }, +star_mapping[(10, False, True, False, Liquid.WATER, False, True)] = \ +LowVolume_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 6.0, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 11.5, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -8782,13 +6708,12 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(10, False, True, False, Liquid.WATER, False, False)] = ( - LowVolume_Water_DispenseSurface_Part -) = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.WATER, False, False)] = \ +LowVolume_Water_DispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.2, 10.0: 11.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -8806,7 +6731,7 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -8822,9 +6747,8 @@ def get_star_liquid_class( # 12 x 20ul = approximately 19.2 ul # 4 x 50 ul = approximately 48.1 ul # 2 x 100 ul = approximately 95.3 ul -star_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = ( - SlimTipFilter_96COREHead1000ul_DMSO_DispenseJet_Aliquot -) = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = \ +SlimTipFilter_96COREHead1000ul_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, @@ -8842,21 +6766,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=18.0, + dispense_stop_back_volume=18.0 ) -star_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = ( - SlimTipFilter_96COREHead1000ul_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 312.3, - 50.0: 55.3, - 0.0: 0.0, - 100.0: 107.7, - 20.0: 22.4, - 200.0: 210.5, - }, +star_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = \ +SlimTipFilter_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 312.3, 50.0: 55.3, 0.0: 0.0, 100.0: 107.7, 20.0: 22.4, 200.0: 210.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -8873,22 +6789,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = ( - SlimTipFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 311.9, - 50.0: 54.1, - 0.0: 0.0, - 100.0: 107.5, - 20.0: 22.5, - 10.0: 11.1, - 200.0: 209.4, - }, +star_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = \ +SlimTipFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 311.9, 50.0: 54.1, 0.0: 0.0, 100.0: 107.5, 20.0: 22.5, 10.0: 11.1, 200.0: 209.4}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=1.0, @@ -8905,7 +6812,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -8922,17 +6829,9 @@ def get_star_liquid_class( # 4 x 50 ul = approximately 48.9 ul # 2 x 100 ul = approximately 97.2 ul # -star_mapping[(300, True, True, True, Liquid.WATER, True, False)] = ( - SlimTipFilter_96COREHead1000ul_Water_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 50.0: 50.0, - 30.0: 30.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - }, +star_mapping[(300, True, True, True, Liquid.WATER, True, False)] = \ +SlimTipFilter_96COREHead1000ul_Water_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=5.0, @@ -8949,21 +6848,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -star_mapping[(300, True, True, True, Liquid.WATER, True, True)] = ( - SlimTipFilter_96COREHead1000ul_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 317.0, - 50.0: 55.8, - 0.0: 0.0, - 100.0: 109.4, - 20.0: 22.7, - 200.0: 213.7, - }, +star_mapping[(300, True, True, True, Liquid.WATER, True, True)] = \ +SlimTipFilter_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 317.0, 50.0: 55.8, 0.0: 0.0, 100.0: 109.4, 20.0: 22.7, 200.0: 213.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -8980,21 +6871,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, True, Liquid.WATER, False, True)] = ( - SlimTipFilter_96COREHead1000ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 318.7, - 50.0: 54.9, - 0.0: 0.0, - 100.0: 110.4, - 10.0: 11.7, - 200.0: 210.5, - }, +star_mapping[(300, True, True, True, Liquid.WATER, False, True)] = \ +SlimTipFilter_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 318.7, 50.0: 54.9, 0.0: 0.0, 100.0: 110.4, 10.0: 11.7, 200.0: 210.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -9011,7 +6894,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -9028,9 +6911,8 @@ def get_star_liquid_class( # 4 x 50 ul = approximately 48.3 ul # 2 x 100 ul = approximately 95.7 ul # -star_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = ( - SlimTipFilter_DMSO_DispenseJet_Aliquot -) = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = \ +SlimTipFilter_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -9048,21 +6930,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=18.0, + dispense_stop_back_volume=18.0 ) -star_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = ( - SlimTipFilter_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 309.5, - 50.0: 54.4, - 0.0: 0.0, - 100.0: 106.4, - 20.0: 22.1, - 200.0: 208.2, - }, +star_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = \ +SlimTipFilter_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 309.5, 50.0: 54.4, 0.0: 0.0, 100.0: 106.4, 20.0: 22.1, 200.0: 208.2}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -9079,23 +6953,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = ( - SlimTipFilter_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 309.7, - 5.0: 5.6, - 50.0: 53.8, - 0.0: 0.0, - 100.0: 105.4, - 20.0: 22.2, - 10.0: 11.3, - 200.0: 207.5, - }, +star_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = \ +SlimTipFilter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 309.7, 5.0: 5.6, 50.0: 53.8, 0.0: 0.0, 100.0: 105.4, 20.0: 22.2, 10.0: 11.3, 200.0: 207.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=1.0, @@ -9112,7 +6976,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -9128,16 +6992,9 @@ def get_star_liquid_class( # 12 x 20ul = approximately 21.3 ul # 4 x 50 ul = approximately 54.3 ul # 2 x 100 ul = approximately 105.2 ul -star_mapping[(300, True, True, True, Liquid.ETHANOL, True, False)] = ( - SlimTipFilter_EtOH_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 50.0: 50.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - }, +star_mapping[(300, True, True, True, Liquid.ETHANOL, True, False)] = \ +SlimTipFilter_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 50.0: 50.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -9154,21 +7011,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -star_mapping[(300, True, True, True, Liquid.ETHANOL, True, True)] = ( - SlimTipFilter_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 320.4, - 50.0: 57.2, - 0.0: 0.0, - 100.0: 110.5, - 20.0: 24.5, - 200.0: 215.0, - }, +star_mapping[(300, True, True, True, Liquid.ETHANOL, True, True)] = \ +SlimTipFilter_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 320.4, 50.0: 57.2, 0.0: 0.0, 100.0: 110.5, 20.0: 24.5, 200.0: 215.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -9185,22 +7034,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, True, Liquid.ETHANOL, False, True)] = ( - SlimTipFilter_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.9, - 50.0: 55.4, - 0.0: 0.0, - 100.0: 107.7, - 20.0: 23.2, - 10.0: 12.4, - 200.0: 210.6, - }, +star_mapping[(300, True, True, True, Liquid.ETHANOL, False, True)] = \ +SlimTipFilter_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 313.9, 50.0: 55.4, 0.0: 0.0, 100.0: 107.7, 20.0: 23.2, 10.0: 12.4, 200.0: 210.6}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=2.0, @@ -9217,22 +7057,13 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(300, True, True, True, Liquid.GLYCERIN80, False, True)] = ( - SlimTipFilter_Glycerin_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 312.0, - 50.0: 55.0, - 0.0: 0.0, - 100.0: 107.8, - 20.0: 22.9, - 10.0: 11.8, - 200.0: 210.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(300, True, True, True, Liquid.GLYCERIN80, False, True)] = \ +SlimTipFilter_Glycerin_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 312.0, 50.0: 55.0, 0.0: 0.0, 100.0: 107.8, 20.0: 22.9, 10.0: 11.8, 200.0: 210.0}, aspiration_flow_rate=30.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=0.0, @@ -9249,7 +7080,7 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=2.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -9265,17 +7096,9 @@ def get_star_liquid_class( # 12 x 20ul = approximately 19.6 ul # 4 x 50 ul = approximately 49.2 ul # 2 x 100 ul = approximately 97.5 ul -star_mapping[(300, True, True, True, Liquid.WATER, True, False)] = ( - SlimTipFilter_Water_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 50.0: 50.0, - 30.0: 30.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - }, +star_mapping[(300, True, True, True, Liquid.WATER, True, False)] = \ +SlimTipFilter_Water_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=3.0, @@ -9292,21 +7115,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -star_mapping[(300, True, True, True, Liquid.WATER, True, True)] = ( - SlimTipFilter_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 317.2, - 50.0: 55.6, - 0.0: 0.0, - 100.0: 108.6, - 20.0: 22.6, - 200.0: 212.8, - }, +star_mapping[(300, True, True, True, Liquid.WATER, True, True)] = \ +SlimTipFilter_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 317.2, 50.0: 55.6, 0.0: 0.0, 100.0: 108.6, 20.0: 22.6, 200.0: 212.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -9323,23 +7138,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, True, Liquid.WATER, False, True)] = ( - SlimTipFilter_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 314.1, - 5.0: 6.2, - 50.0: 54.7, - 0.0: 0.0, - 100.0: 108.0, - 20.0: 22.7, - 10.0: 11.9, - 200.0: 211.3, - }, +star_mapping[(300, True, True, True, Liquid.WATER, False, True)] = \ +SlimTipFilter_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 314.1, 5.0: 6.2, 50.0: 54.7, 0.0: 0.0, 100.0: 108.0, 20.0: 22.7, 10.0: 11.9, 200.0: 211.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -9356,7 +7161,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -9372,9 +7177,8 @@ def get_star_liquid_class( # 12 x 20ul = approximately 19.2 ul # 4 x 50 ul = approximately 48.1 ul # 2 x 100 ul = approximately 95.3 ul -star_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = ( - SlimTip_96COREHead1000ul_DMSO_DispenseJet_Aliquot -) = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ +SlimTip_96COREHead1000ul_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, @@ -9392,21 +7196,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=18.0, + dispense_stop_back_volume=18.0 ) -star_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = ( - SlimTip_96COREHead1000ul_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.8, - 50.0: 55.8, - 0.0: 0.0, - 100.0: 109.2, - 20.0: 23.1, - 200.0: 212.7, - }, +star_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ +SlimTip_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 313.8, 50.0: 55.8, 0.0: 0.0, 100.0: 109.2, 20.0: 23.1, 200.0: 212.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -9423,22 +7219,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = ( - SlimTip_96COREHead1000ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 312.9, - 50.0: 54.1, - 0.0: 0.0, - 20.0: 22.5, - 100.0: 108.8, - 200.0: 210.9, - 10.0: 11.1, - }, +star_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ +SlimTip_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 312.9, 50.0: 54.1, 0.0: 0.0, 20.0: 22.5, 100.0: 108.8, 200.0: 210.9, 10.0: 11.1}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=1.0, @@ -9455,7 +7242,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -9471,16 +7258,9 @@ def get_star_liquid_class( # 12 x 20ul = approximately 21.8 ul # 4 x 50 ul = approximately 53.6 ul # 2 x 100 ul = approximately 105.2 ul -star_mapping[(300, True, True, False, Liquid.ETHANOL, True, False)] = ( - SlimTip_96COREHead1000ul_EtOH_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 50.0: 50.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - }, +star_mapping[(300, True, True, False, Liquid.ETHANOL, True, False)] = \ +SlimTip_96COREHead1000ul_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 50.0: 50.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -9497,21 +7277,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=80.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -star_mapping[(300, True, True, False, Liquid.ETHANOL, True, True)] = ( - SlimTip_96COREHead1000ul_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 326.2, - 50.0: 58.8, - 0.0: 0.0, - 100.0: 112.7, - 20.0: 25.0, - 200.0: 218.2, - }, +star_mapping[(300, True, True, False, Liquid.ETHANOL, True, True)] = \ +SlimTip_96COREHead1000ul_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 326.2, 50.0: 58.8, 0.0: 0.0, 100.0: 112.7, 20.0: 25.0, 200.0: 218.2}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -9528,21 +7300,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.ETHANOL, False, True)] = ( - SlimTip_96COREHead1000ul_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 320.3, - 50.0: 56.7, - 0.0: 0.0, - 100.0: 109.5, - 10.0: 12.4, - 200.0: 213.9, - }, +star_mapping[(300, True, True, False, Liquid.ETHANOL, False, True)] = \ +SlimTip_96COREHead1000ul_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 320.3, 50.0: 56.7, 0.0: 0.0, 100.0: 109.5, 10.0: 12.4, 200.0: 213.9}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=2.0, @@ -9559,22 +7323,13 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=2.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(300, True, True, False, Liquid.GLYCERIN80, False, True)] = ( - SlimTip_96COREHead1000ul_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 319.3, - 50.0: 58.2, - 0.0: 0.0, - 100.0: 112.1, - 20.0: 23.9, - 10.0: 12.1, - 200.0: 216.9, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(300, True, True, False, Liquid.GLYCERIN80, False, True)] = \ +SlimTip_96COREHead1000ul_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 319.3, 50.0: 58.2, 0.0: 0.0, 100.0: 112.1, 20.0: 23.9, 10.0: 12.1, 200.0: 216.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -9591,7 +7346,7 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=2.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -9608,17 +7363,9 @@ def get_star_liquid_class( # 4 x 50 ul = approximately 48.9 ul # 2 x 100 ul = approximately 97.2 ul # -star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( - SlimTip_96COREHead1000ul_Water_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 50.0: 50.0, - 30.0: 30.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - }, +star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ +SlimTip_96COREHead1000ul_Water_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=5.0, @@ -9635,21 +7382,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( - SlimTip_96COREHead1000ul_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 315.0, - 50.0: 55.5, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 22.8, - 200.0: 211.0, - }, +star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ +SlimTip_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 315.0, 50.0: 55.5, 0.0: 0.0, 100.0: 107.2, 20.0: 22.8, 200.0: 211.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -9666,21 +7405,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( - SlimTip_96COREHead1000ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 322.7, - 50.0: 56.4, - 0.0: 0.0, - 100.0: 110.4, - 10.0: 11.9, - 200.0: 215.5, - }, +star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ +SlimTip_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 322.7, 50.0: 56.4, 0.0: 0.0, 100.0: 110.4, 10.0: 11.9, 200.0: 215.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -9697,7 +7428,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -9714,9 +7445,8 @@ def get_star_liquid_class( # 4 x 50 ul = approximately 48.3 ul # 2 x 100 ul = approximately 95.7 ul # -star_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = ( - SlimTip_DMSO_DispenseJet_Aliquot -) = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ +SlimTip_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -9734,21 +7464,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=18.0, + dispense_stop_back_volume=18.0 ) -star_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = ( - SlimTip_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 309.5, - 50.0: 54.7, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 22.5, - 200.0: 209.7, - }, +star_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ +SlimTip_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 309.5, 50.0: 54.7, 0.0: 0.0, 100.0: 107.2, 20.0: 22.5, 200.0: 209.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -9765,23 +7487,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = ( - SlimTip_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 310.2, - 5.0: 5.6, - 50.0: 54.1, - 0.0: 0.0, - 100.0: 106.2, - 20.0: 22.5, - 10.0: 11.3, - 200.0: 208.7, - }, +star_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ +SlimTip_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 310.2, 5.0: 5.6, 50.0: 54.1, 0.0: 0.0, 100.0: 106.2, 20.0: 22.5, 10.0: 11.3, 200.0: 208.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=1.0, @@ -9798,7 +7510,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -9814,16 +7526,9 @@ def get_star_liquid_class( # 12 x 20ul = approximately 21.3 ul # 4 x 50 ul = approximately 54.3 ul # 2 x 100 ul = approximately 105.2 ul -star_mapping[(300, True, True, False, Liquid.ETHANOL, True, False)] = ( - SlimTip_EtOH_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 50.0: 50.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - }, +star_mapping[(300, True, True, False, Liquid.ETHANOL, True, False)] = \ +SlimTip_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 50.0: 50.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -9840,21 +7545,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -star_mapping[(300, True, True, False, Liquid.ETHANOL, True, True)] = ( - SlimTip_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 323.4, - 50.0: 57.2, - 0.0: 0.0, - 100.0: 110.5, - 20.0: 24.7, - 200.0: 211.9, - }, +star_mapping[(300, True, True, False, Liquid.ETHANOL, True, True)] = \ +SlimTip_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 323.4, 50.0: 57.2, 0.0: 0.0, 100.0: 110.5, 20.0: 24.7, 200.0: 211.9}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -9871,23 +7568,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.ETHANOL, False, True)] = ( - SlimTip_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 312.9, - 5.0: 6.2, - 50.0: 55.4, - 0.0: 0.0, - 100.0: 107.7, - 20.0: 23.2, - 10.0: 11.9, - 200.0: 210.6, - }, +star_mapping[(300, True, True, False, Liquid.ETHANOL, False, True)] = \ +SlimTip_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 312.9, 5.0: 6.2, 50.0: 55.4, 0.0: 0.0, 100.0: 107.7, 20.0: 23.2, 10.0: 11.9, 200.0: 210.6}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=2.0, @@ -9904,23 +7591,13 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(300, True, True, False, Liquid.GLYCERIN80, False, True)] = ( - SlimTip_Glycerin_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.3, - 5.0: 6.0, - 50.0: 55.7, - 0.0: 0.0, - 100.0: 107.8, - 20.0: 22.9, - 10.0: 11.5, - 200.0: 210.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(300, True, True, False, Liquid.GLYCERIN80, False, True)] = \ +SlimTip_Glycerin_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 313.3, 5.0: 6.0, 50.0: 55.7, 0.0: 0.0, 100.0: 107.8, 20.0: 22.9, 10.0: 11.5, 200.0: 210.0}, aspiration_flow_rate=30.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=0.0, @@ -9937,7 +7614,7 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=2.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -9953,9 +7630,8 @@ def get_star_liquid_class( # 12 x 20ul = approximately 19.6 ul # 4 x 50 ul = approximately 50.0 ul # 2 x 100 ul = approximately 98.4 ul -star_mapping[(300, True, True, False, Liquid.SERUM, True, False)] = ( - SlimTip_Serum_DispenseJet_Aliquot -) = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.SERUM, True, False)] = \ +SlimTip_Serum_DispenseJet_Aliquot = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -9973,21 +7649,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -star_mapping[(300, True, True, False, Liquid.SERUM, True, True)] = ( - SlimTip_Serum_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 321.5, - 50.0: 56.0, - 0.0: 0.0, - 100.0: 109.7, - 20.0: 22.8, - 200.0: 215.7, - }, +star_mapping[(300, True, True, False, Liquid.SERUM, True, True)] = \ +SlimTip_Serum_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 321.5, 50.0: 56.0, 0.0: 0.0, 100.0: 109.7, 20.0: 22.8, 200.0: 215.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -10004,23 +7672,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.SERUM, False, True)] = ( - SlimTip_Serum_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 320.2, - 5.0: 5.5, - 50.0: 55.4, - 0.0: 0.0, - 20.0: 22.6, - 100.0: 109.7, - 200.0: 214.9, - 10.0: 11.3, - }, +star_mapping[(300, True, True, False, Liquid.SERUM, False, True)] = \ +SlimTip_Serum_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 320.2, 5.0: 5.5, 50.0: 55.4, 0.0: 0.0, 20.0: 22.6, 100.0: 109.7, 200.0: 214.9, 10.0: 11.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=1.0, @@ -10037,7 +7695,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -10053,17 +7711,9 @@ def get_star_liquid_class( # 12 x 20ul = approximately 19.6 ul # 4 x 50 ul = approximately 49.2 ul # 2 x 100 ul = approximately 97.5 ul -star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( - SlimTip_Water_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 50.0: 50.0, - 30.0: 30.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - }, +star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ +SlimTip_Water_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=3.0, @@ -10080,21 +7730,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( - SlimTip_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 317.2, - 50.0: 55.6, - 0.0: 0.0, - 20.0: 22.6, - 100.0: 108.6, - 200.0: 212.8, - }, +star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ +SlimTip_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 317.2, 50.0: 55.6, 0.0: 0.0, 20.0: 22.6, 100.0: 108.6, 200.0: 212.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -10111,23 +7753,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( - SlimTip_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 317.1, - 5.0: 6.2, - 50.0: 55.1, - 0.0: 0.0, - 100.0: 108.0, - 20.0: 22.9, - 10.0: 11.9, - 200.0: 213.0, - }, +star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ +SlimTip_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 317.1, 5.0: 6.2, 50.0: 55.1, 0.0: 0.0, 100.0: 108.0, 20.0: 22.9, 10.0: 11.9, 200.0: 213.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -10144,22 +7776,15 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 80 # V1.2: Stop back volume = 0 (previous value: 15) -star_mapping[(300, False, False, False, Liquid.WATER, True, False)] = ( - StandardNeedle_Water_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 311.2, - 50.0: 51.3, - 0.0: 0.0, - 100.0: 103.4, - 20.0: 19.5, - }, +star_mapping[(300, False, False, False, Liquid.WATER, True, False)] = \ +StandardNeedle_Water_DispenseJet = HamiltonLiquidClass( + curve={300.0: 311.2, 50.0: 51.3, 0.0: 0.0, 100.0: 103.4, 20.0: 19.5}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=10.0, @@ -10176,20 +7801,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, False, False, Liquid.WATER, True, True)] = ( - StandardNeedle_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 311.2, - 50.0: 51.3, - 0.0: 0.0, - 100.0: 103.4, - 20.0: 19.5, - }, +star_mapping[(300, False, False, False, Liquid.WATER, True, True)] = \ +StandardNeedle_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 311.2, 50.0: 51.3, 0.0: 0.0, 100.0: 103.4, 20.0: 19.5}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=10.0, @@ -10206,20 +7824,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, False, False, Liquid.WATER, True, False)] = ( - StandardNeedle_Water_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 311.2, - 50.0: 51.3, - 0.0: 0.0, - 100.0: 103.4, - 20.0: 19.5, - }, +star_mapping[(300, False, False, False, Liquid.WATER, True, False)] = \ +StandardNeedle_Water_DispenseJet_Part = HamiltonLiquidClass( + curve={300.0: 311.2, 50.0: 51.3, 0.0: 0.0, 100.0: 103.4, 20.0: 19.5}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=10.0, @@ -10236,25 +7847,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(300, False, False, False, Liquid.WATER, False, False)] = ( - StandardNeedle_Water_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 308.4, - 5.0: 6.5, - 50.0: 52.3, - 0.0: 0.0, - 100.0: 102.9, - 20.0: 22.3, - 1.0: 1.1, - 200.0: 205.8, - 10.0: 12.0, - 2.0: 2.1, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(300, False, False, False, Liquid.WATER, False, False)] = \ +StandardNeedle_Water_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 308.4, 5.0: 6.5, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 1.1, 200.0: 205.8, 10.0: 12.0, 2.0: 2.1}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=0.0, @@ -10271,25 +7870,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(300, False, False, False, Liquid.WATER, False, True)] = ( - StandardNeedle_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 308.4, - 5.0: 6.5, - 50.0: 52.3, - 0.0: 0.0, - 100.0: 102.9, - 20.0: 22.3, - 1.0: 1.1, - 200.0: 205.8, - 10.0: 12.0, - 2.0: 2.1, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(300, False, False, False, Liquid.WATER, False, True)] = \ +StandardNeedle_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 308.4, 5.0: 6.5, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 1.1, 200.0: 205.8, 10.0: 12.0, 2.0: 2.1}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=0.0, @@ -10306,25 +7893,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(300, False, False, False, Liquid.WATER, False, False)] = ( - StandardNeedle_Water_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 308.4, - 5.0: 6.5, - 50.0: 52.3, - 0.0: 0.0, - 100.0: 102.9, - 20.0: 22.3, - 1.0: 1.1, - 200.0: 205.8, - 10.0: 12.0, - 2.0: 2.1, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(300, False, False, False, Liquid.WATER, False, False)] = \ +StandardNeedle_Water_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 308.4, 5.0: 6.5, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 1.1, 200.0: 205.8, 10.0: 12.0, 2.0: 2.1}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=0.0, @@ -10341,7 +7916,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -10365,17 +7940,9 @@ def get_star_liquid_class( # 200 0.16 0.55 # 300 0.17 0.35 # -star_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, False)] = ( - StandardVolumeAcetonitrilDispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 326.2, - 50.0: 57.3, - 0.0: 0.0, - 100.0: 111.5, - 20.0: 24.6, - 200.0: 217.0, - }, +star_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, False)] = \ +StandardVolumeAcetonitrilDispenseJet = HamiltonLiquidClass( + curve={300.0: 326.2, 50.0: 57.3, 0.0: 0.0, 100.0: 111.5, 20.0: 24.6, 200.0: 217.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=25.0, @@ -10392,21 +7959,13 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, True)] = ( - StandardVolumeAcetonitrilDispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 326.2, - 50.0: 57.3, - 0.0: 0.0, - 100.0: 111.5, - 20.0: 24.6, - 200.0: 217.0, - }, +star_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, True)] = \ +StandardVolumeAcetonitrilDispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 326.2, 50.0: 57.3, 0.0: 0.0, 100.0: 111.5, 20.0: 24.6, 200.0: 217.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=25.0, @@ -10423,13 +7982,12 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, False)] = ( - StandardVolumeAcetonitrilDispenseJet_Part -) = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, False)] = \ +StandardVolumeAcetonitrilDispenseJet_Part = HamiltonLiquidClass( curve={300.0: 321.2, 50.0: 57.3, 0.0: 0.0, 100.0: 110.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10447,7 +8005,7 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) @@ -10471,21 +8029,9 @@ def get_star_liquid_class( # 200 0.65 0.65 # 300 0.21 0.88 # -star_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, False)] = ( - StandardVolumeAcetonitrilDispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 328.0, - 5.0: 6.8, - 50.0: 58.5, - 0.0: 0.0, - 100.0: 112.7, - 20.0: 24.8, - 1.0: 1.3, - 200.0: 220.0, - 10.0: 13.0, - 2.0: 3.0, - }, +star_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, False)] = \ +StandardVolumeAcetonitrilDispenseSurface = HamiltonLiquidClass( + curve={300.0: 328.0, 5.0: 6.8, 50.0: 58.5, 0.0: 0.0, 100.0: 112.7, 20.0: 24.8, 1.0: 1.3, 200.0: 220.0, 10.0: 13.0, 2.0: 3.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=10.0, @@ -10502,25 +8048,13 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, True)] = ( - StandardVolumeAcetonitrilDispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 328.0, - 5.0: 6.8, - 50.0: 58.5, - 0.0: 0.0, - 100.0: 112.7, - 20.0: 24.8, - 1.0: 1.3, - 200.0: 220.0, - 10.0: 13.0, - 2.0: 3.0, - }, +star_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, True)] = \ +StandardVolumeAcetonitrilDispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 328.0, 5.0: 6.8, 50.0: 58.5, 0.0: 0.0, 100.0: 112.7, 20.0: 24.8, 1.0: 1.3, 200.0: 220.0, 10.0: 13.0, 2.0: 3.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=10.0, @@ -10537,20 +8071,13 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, False)] = ( - StandardVolumeAcetonitrilDispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 328.0, - 5.0: 7.3, - 0.0: 0.0, - 100.0: 112.7, - 10.0: 13.5, - }, +star_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, False)] = \ +StandardVolumeAcetonitrilDispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 328.0, 5.0: 7.3, 0.0: 0.0, 100.0: 112.7, 10.0: 13.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=10.0, @@ -10567,7 +8094,7 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -10587,9 +8114,8 @@ def get_star_liquid_class( # 20 (12 Aliquots) 2.53 -2.97 # 50 ( 4 Aliquots) 0.84 -2.57 # -star_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = ( - StandardVolumeDMSOAliquotJet -) = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = \ +StandardVolumeDMSOAliquotJet = HamiltonLiquidClass( curve={350.0: 350.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10607,7 +8133,7 @@ def get_star_liquid_class( dispense_swap_speed=0.3, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) @@ -10628,17 +8154,9 @@ def get_star_liquid_class( # 200 0.53 0.08 # 300 0.54 0.22 # -star_mapping[(300, False, True, False, Liquid.ETHANOL, False, False)] = ( - StandardVolumeEtOHDispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 309.2, - 50.0: 54.8, - 0.0: 0.0, - 100.0: 106.5, - 20.0: 23.7, - 200.0: 208.2, - }, +star_mapping[(300, False, True, False, Liquid.ETHANOL, False, False)] = \ +StandardVolumeEtOHDispenseSurface = HamiltonLiquidClass( + curve={300.0: 309.2, 50.0: 54.8, 0.0: 0.0, 100.0: 106.5, 20.0: 23.7, 200.0: 208.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=3.0, @@ -10655,21 +8173,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=0.4, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.ETHANOL, False, True)] = ( - StandardVolumeEtOHDispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 309.2, - 50.0: 54.8, - 0.0: 0.0, - 100.0: 106.5, - 20.0: 23.7, - 200.0: 208.2, - }, +star_mapping[(300, False, True, False, Liquid.ETHANOL, False, True)] = \ +StandardVolumeEtOHDispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 309.2, 50.0: 54.8, 0.0: 0.0, 100.0: 106.5, 20.0: 23.7, 200.0: 208.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=3.0, @@ -10686,13 +8196,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.ETHANOL, False, False)] = ( - StandardVolumeEtOHDispenseSurface_Part -) = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.ETHANOL, False, False)] = \ +StandardVolumeEtOHDispenseSurface_Part = HamiltonLiquidClass( curve={300.0: 315.2, 0.0: 0.0, 100.0: 108.5, 20.0: 23.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=50.0, @@ -10710,20 +8219,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = ( - StandardVolumeFilter_96COREHead1000ul_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 302.5, - 0.0: 0.0, - 100.0: 101.0, - 20.0: 20.4, - 200.0: 201.5, - }, +star_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = \ +StandardVolumeFilter_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 302.5, 0.0: 0.0, 100.0: 101.0, 20.0: 20.4, 200.0: 201.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10740,20 +8242,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = ( - StandardVolumeFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 306.0, - 0.0: 0.0, - 100.0: 104.3, - 200.0: 205.0, - 10.0: 12.2, - }, +star_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = \ +StandardVolumeFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 306.0, 0.0: 0.0, 100.0: 104.3, 200.0: 205.0, 10.0: 12.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10770,20 +8265,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, True, Liquid.WATER, True, True)] = ( - StandardVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 23.2, - 200.0: 211.0, - }, +star_mapping[(300, True, True, True, Liquid.WATER, True, True)] = \ +StandardVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10800,20 +8288,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, True, Liquid.WATER, False, True)] = ( - StandardVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 0.0: 0.0, - 100.0: 107.2, - 200.0: 210.0, - 10.0: 11.9, - }, +star_mapping[(300, True, True, True, Liquid.WATER, False, True)] = \ +StandardVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 210.0, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10830,20 +8311,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = ( - StandardVolumeFilter_96COREHead_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 303.5, - 0.0: 0.0, - 100.0: 101.8, - 10.0: 10.2, - 200.0: 200.5, - }, +star_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = \ +StandardVolumeFilter_96COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 303.5, 0.0: 0.0, 100.0: 101.8, 10.0: 10.2, 200.0: 200.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10860,20 +8334,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = ( - StandardVolumeFilter_96COREHead_DMSO_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 305.0, - 0.0: 0.0, - 100.0: 103.6, - 10.0: 11.5, - 200.0: 206.0, - }, +star_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = \ +StandardVolumeFilter_96COREHead_DMSO_DispenseJet_Part = HamiltonLiquidClass( + curve={300.0: 305.0, 0.0: 0.0, 100.0: 103.6, 10.0: 11.5, 200.0: 206.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10890,20 +8357,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -star_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = ( - StandardVolumeFilter_96COREHead_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 303.0, - 0.0: 0.0, - 100.0: 101.3, - 10.0: 10.6, - 200.0: 202.0, - }, +star_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = \ +StandardVolumeFilter_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 303.0, 0.0: 0.0, 100.0: 101.3, 10.0: 10.6, 200.0: 202.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10920,20 +8380,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, True, Liquid.DMSO, False, False)] = ( - StandardVolumeFilter_96COREHead_DMSO_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 303.0, - 0.0: 0.0, - 100.0: 101.3, - 10.0: 10.1, - 200.0: 202.0, - }, +star_mapping[(300, True, True, True, Liquid.DMSO, False, False)] = \ +StandardVolumeFilter_96COREHead_DMSO_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 303.0, 0.0: 0.0, 100.0: 101.3, 10.0: 10.1, 200.0: 202.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10950,21 +8403,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, True, Liquid.WATER, True, True)] = ( - StandardVolumeFilter_96COREHead_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 309.0, - 0.0: 0.0, - 20.0: 22.3, - 100.0: 104.2, - 10.0: 11.9, - 200.0: 207.0, - }, +star_mapping[(300, True, True, True, Liquid.WATER, True, True)] = \ +StandardVolumeFilter_96COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 309.0, 0.0: 0.0, 20.0: 22.3, 100.0: 104.2, 10.0: 11.9, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10981,21 +8426,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, True, Liquid.WATER, True, False)] = ( - StandardVolumeFilter_96COREHead_Water_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 309.0, - 0.0: 0.0, - 20.0: 22.3, - 100.0: 104.2, - 10.0: 11.9, - 200.0: 207.0, - }, +star_mapping[(300, True, True, True, Liquid.WATER, True, False)] = \ +StandardVolumeFilter_96COREHead_Water_DispenseJet_Part = HamiltonLiquidClass( + curve={300.0: 309.0, 0.0: 0.0, 20.0: 22.3, 100.0: 104.2, 10.0: 11.9, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11012,20 +8449,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -star_mapping[(300, True, True, True, Liquid.WATER, False, True)] = ( - StandardVolumeFilter_96COREHead_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 306.3, - 0.0: 0.0, - 100.0: 104.5, - 10.0: 11.9, - 200.0: 205.7, - }, +star_mapping[(300, True, True, True, Liquid.WATER, False, True)] = \ +StandardVolumeFilter_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 306.3, 0.0: 0.0, 100.0: 104.5, 10.0: 11.9, 200.0: 205.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11042,20 +8472,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, True, Liquid.WATER, False, False)] = ( - StandardVolumeFilter_96COREHead_Water_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 304.0, - 0.0: 0.0, - 100.0: 105.3, - 10.0: 11.9, - 200.0: 205.7, - }, +star_mapping[(300, True, True, True, Liquid.WATER, False, False)] = \ +StandardVolumeFilter_96COREHead_Water_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 304.0, 0.0: 0.0, 100.0: 105.3, 10.0: 11.9, 200.0: 205.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -11072,7 +8495,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -11092,9 +8515,8 @@ def get_star_liquid_class( # 20 (12 Aliquots) 2.53 -2.97 # 50 ( 4 Aliquots) 0.84 -2.57 # -star_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = ( - StandardVolumeFilter_DMSO_AliquotDispenseJet_Part -) = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = \ +StandardVolumeFilter_DMSO_AliquotDispenseJet_Part = HamiltonLiquidClass( curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11112,22 +8534,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = ( - StandardVolumeFilter_DMSO_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 304.6, - 50.0: 51.1, - 0.0: 0.0, - 20.0: 20.7, - 100.0: 101.8, - 200.0: 203.0, - }, +star_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = \ +StandardVolumeFilter_DMSO_DispenseJet = HamiltonLiquidClass( + curve={300.0: 304.6, 50.0: 51.1, 0.0: 0.0, 20.0: 20.7, 100.0: 101.8, 200.0: 203.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11144,21 +8558,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, True, Liquid.DMSO, True, True)] = ( - StandardVolumeFilter_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 304.6, - 50.0: 51.1, - 0.0: 0.0, - 100.0: 101.8, - 20.0: 20.7, - 200.0: 203.0, - }, +star_mapping[(300, False, True, True, Liquid.DMSO, True, True)] = \ +StandardVolumeFilter_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 304.6, 50.0: 51.1, 0.0: 0.0, 100.0: 101.8, 20.0: 20.7, 200.0: 203.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11175,13 +8581,12 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = ( - StandardVolumeFilter_DMSO_DispenseJet_Part -) = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = \ +StandardVolumeFilter_DMSO_DispenseJet_Part = HamiltonLiquidClass( curve={300.0: 315.6, 0.0: 0.0, 100.0: 112.8, 20.0: 29.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11199,25 +8604,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0, -) - - -star_mapping[(300, False, True, True, Liquid.DMSO, False, False)] = ( - StandardVolumeFilter_DMSO_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 308.8, - 5.0: 6.6, - 50.0: 52.9, - 0.0: 0.0, - 1.0: 1.8, - 20.0: 22.1, - 100.0: 103.8, - 2.0: 3.0, - 10.0: 11.9, - 200.0: 205.0, - }, + dispense_stop_back_volume=10.0 +) + + +star_mapping[(300, False, True, True, Liquid.DMSO, False, False)] = \ +StandardVolumeFilter_DMSO_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 308.8, 5.0: 6.6, 50.0: 52.9, 0.0: 0.0, 1.0: 1.8, 20.0: 22.1, 100.0: 103.8, 2.0: 3.0, 10.0: 11.9, 200.0: 205.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -11234,25 +8627,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(300, False, True, True, Liquid.DMSO, False, True)] = ( - StandardVolumeFilter_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 308.8, - 5.0: 6.6, - 50.0: 52.9, - 0.0: 0.0, - 1.0: 1.8, - 20.0: 22.1, - 100.0: 103.8, - 2.0: 3.0, - 10.0: 11.9, - 200.0: 205.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(300, False, True, True, Liquid.DMSO, False, True)] = \ +StandardVolumeFilter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 308.8, 5.0: 6.6, 50.0: 52.9, 0.0: 0.0, 1.0: 1.8, 20.0: 22.1, 100.0: 103.8, 2.0: 3.0, 10.0: 11.9, 200.0: 205.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -11269,22 +8650,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, True, Liquid.DMSO, False, False)] = ( - StandardVolumeFilter_DMSO_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 306.8, - 5.0: 6.4, - 50.0: 52.9, - 0.0: 0.0, - 100.0: 103.8, - 20.0: 22.1, - 10.0: 11.9, - }, +star_mapping[(300, False, True, True, Liquid.DMSO, False, False)] = \ +StandardVolumeFilter_DMSO_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 306.8, 5.0: 6.4, 50.0: 52.9, 0.0: 0.0, 100.0: 103.8, 20.0: 22.1, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -11301,22 +8673,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 100, Stop back volume=0 -star_mapping[(300, False, True, True, Liquid.ETHANOL, True, False)] = ( - StandardVolumeFilter_EtOH_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 310.2, - 50.0: 55.8, - 0.0: 0.0, - 20.0: 24.6, - 100.0: 107.5, - 200.0: 209.2, - }, +star_mapping[(300, False, True, True, Liquid.ETHANOL, True, False)] = \ +StandardVolumeFilter_EtOH_DispenseJet = HamiltonLiquidClass( + curve={300.0: 310.2, 50.0: 55.8, 0.0: 0.0, 20.0: 24.6, 100.0: 107.5, 200.0: 209.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11333,21 +8697,13 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, True, Liquid.ETHANOL, True, True)] = ( - StandardVolumeFilter_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 310.2, - 50.0: 55.8, - 0.0: 0.0, - 100.0: 107.5, - 20.0: 24.6, - 200.0: 209.2, - }, +star_mapping[(300, False, True, True, Liquid.ETHANOL, True, True)] = \ +StandardVolumeFilter_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 310.2, 50.0: 55.8, 0.0: 0.0, 100.0: 107.5, 20.0: 24.6, 200.0: 209.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11364,13 +8720,12 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, True, Liquid.ETHANOL, True, False)] = ( - StandardVolumeFilter_EtOH_DispenseJet_Part -) = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.ETHANOL, True, False)] = \ +StandardVolumeFilter_EtOH_DispenseJet_Part = HamiltonLiquidClass( curve={300.0: 317.2, 0.0: 0.0, 100.0: 110.5, 20.0: 25.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11388,22 +8743,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=5.0, + dispense_stop_back_volume=5.0 ) # V1.1: Set mix flow rate to 20, dispense settling time=0, Stop back volume=0 -star_mapping[(300, False, True, True, Liquid.GLYCERIN, True, False)] = ( - StandardVolumeFilter_Glycerin_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 309.0, - 50.0: 53.6, - 0.0: 0.0, - 20.0: 22.3, - 100.0: 104.9, - 200.0: 207.2, - }, +star_mapping[(300, False, True, True, Liquid.GLYCERIN, True, False)] = \ +StandardVolumeFilter_Glycerin_DispenseJet = HamiltonLiquidClass( + curve={300.0: 309.0, 50.0: 53.6, 0.0: 0.0, 20.0: 22.3, 100.0: 104.9, 200.0: 207.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=20.0, aspiration_air_transport_volume=5.0, @@ -11420,22 +8767,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 20, dispense settling time=0, Stop back volume=0 -star_mapping[(300, False, True, True, Liquid.GLYCERIN80, True, True)] = ( - StandardVolumeFilter_Glycerin_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 309.0, - 50.0: 53.6, - 0.0: 0.0, - 100.0: 104.9, - 20.0: 22.3, - 200.0: 207.2, - }, +star_mapping[(300, False, True, True, Liquid.GLYCERIN80, True, True)] = \ +StandardVolumeFilter_Glycerin_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 309.0, 50.0: 53.6, 0.0: 0.0, 100.0: 104.9, 20.0: 22.3, 200.0: 207.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=20.0, aspiration_air_transport_volume=5.0, @@ -11452,25 +8791,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 10 -star_mapping[(300, False, True, True, Liquid.GLYCERIN, False, False)] = ( - StandardVolumeFilter_Glycerin_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 307.9, - 5.0: 6.5, - 50.0: 53.6, - 0.0: 0.0, - 20.0: 22.5, - 100.0: 105.7, - 2.0: 3.2, - 10.0: 12.0, - 200.0: 207.0, - }, +star_mapping[(300, False, True, True, Liquid.GLYCERIN, False, False)] = \ +StandardVolumeFilter_Glycerin_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 307.9, 5.0: 6.5, 50.0: 53.6, 0.0: 0.0, 20.0: 22.5, 100.0: 105.7, 2.0: 3.2, 10.0: 12.0, 200.0: 207.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -11487,24 +8815,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(300, False, True, True, Liquid.GLYCERIN80, False, True)] = ( - StandardVolumeFilter_Glycerin_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 307.9, - 5.0: 6.5, - 50.0: 53.6, - 0.0: 0.0, - 100.0: 105.7, - 20.0: 22.5, - 200.0: 207.0, - 10.0: 12.0, - 2.0: 3.2, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(300, False, True, True, Liquid.GLYCERIN80, False, True)] = \ +StandardVolumeFilter_Glycerin_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 307.9, 5.0: 6.5, 50.0: 53.6, 0.0: 0.0, 100.0: 105.7, 20.0: 22.5, 200.0: 207.0, 10.0: 12.0, 2.0: 3.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -11521,21 +8838,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, True, Liquid.GLYCERIN80, False, False)] = ( - StandardVolumeFilter_Glycerin_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 307.9, - 5.0: 6.1, - 0.0: 0.0, - 100.0: 104.7, - 200.0: 207.0, - 10.0: 11.5, - }, +star_mapping[(300, False, True, True, Liquid.GLYCERIN80, False, False)] = \ +StandardVolumeFilter_Glycerin_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 307.9, 5.0: 6.1, 0.0: 0.0, 100.0: 104.7, 200.0: 207.0, 10.0: 11.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -11552,14 +8861,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = ( - StandardVolumeFilter_Serum_AliquotDispenseJet_Part -) = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = \ +StandardVolumeFilter_Serum_AliquotDispenseJet_Part = HamiltonLiquidClass( curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11577,14 +8885,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = ( - StandardVolumeFilter_Serum_AliquotJet -) = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = \ +StandardVolumeFilter_Serum_AliquotJet = HamiltonLiquidClass( curve={300.0: 300.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11602,22 +8909,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = ( - StandardVolumeFilter_Serum_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 315.2, - 50.0: 55.6, - 0.0: 0.0, - 20.0: 23.2, - 100.0: 108.1, - 200.0: 212.1, - }, +star_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = \ +StandardVolumeFilter_Serum_DispenseJet = HamiltonLiquidClass( + curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 20.0: 23.2, 100.0: 108.1, 200.0: 212.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11634,21 +8933,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, True, Liquid.SERUM, True, True)] = ( - StandardVolumeFilter_Serum_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 315.2, - 50.0: 55.6, - 0.0: 0.0, - 100.0: 108.1, - 20.0: 23.2, - 200.0: 212.1, - }, +star_mapping[(300, False, True, True, Liquid.SERUM, True, True)] = \ +StandardVolumeFilter_Serum_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 100.0: 108.1, 20.0: 23.2, 200.0: 212.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11665,13 +8956,12 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = ( - StandardVolumeFilter_Serum_DispenseJet_Part -) = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = \ +StandardVolumeFilter_Serum_DispenseJet_Part = HamiltonLiquidClass( curve={300.0: 315.2, 0.0: 0.0, 100.0: 111.5, 20.0: 29.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11689,24 +8979,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=5.0, + dispense_stop_back_volume=5.0 ) -star_mapping[(300, False, True, True, Liquid.SERUM, False, False)] = ( - StandardVolumeFilter_Serum_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 313.4, - 5.0: 6.3, - 50.0: 54.9, - 0.0: 0.0, - 20.0: 23.0, - 100.0: 107.1, - 2.0: 2.6, - 10.0: 12.0, - 200.0: 210.5, - }, +star_mapping[(300, False, True, True, Liquid.SERUM, False, False)] = \ +StandardVolumeFilter_Serum_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 313.4, 5.0: 6.3, 50.0: 54.9, 0.0: 0.0, 20.0: 23.0, 100.0: 107.1, 2.0: 2.6, 10.0: 12.0, 200.0: 210.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -11723,13 +9002,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, True, Liquid.SERUM, False, False)] = ( - StandardVolumeFilter_Serum_DispenseSurface_Part -) = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.SERUM, False, False)] = \ +StandardVolumeFilter_Serum_DispenseSurface_Part = HamiltonLiquidClass( curve={300.0: 313.4, 0.0: 0.0, 100.0: 109.1, 10.0: 12.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -11747,14 +9025,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, True, Liquid.WATER, True, False)] = ( - StandardVolumeFilter_Water_AliquotDispenseJet_Part -) = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.WATER, True, False)] = \ +StandardVolumeFilter_Water_AliquotDispenseJet_Part = HamiltonLiquidClass( curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11772,14 +9049,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, True, Liquid.WATER, True, False)] = ( - StandardVolumeFilter_Water_AliquotJet -) = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.WATER, True, False)] = \ +StandardVolumeFilter_Water_AliquotJet = HamiltonLiquidClass( curve={300.0: 300.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11797,22 +9073,14 @@ def get_star_liquid_class( dispense_swap_speed=0.3, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, True, Liquid.WATER, True, False)] = ( - StandardVolumeFilter_Water_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 50.0: 55.1, - 0.0: 0.0, - 20.0: 23.2, - 100.0: 107.2, - 200.0: 211.0, - }, +star_mapping[(300, False, True, True, Liquid.WATER, True, False)] = \ +StandardVolumeFilter_Water_DispenseJet = HamiltonLiquidClass( + curve={300.0: 313.5, 50.0: 55.1, 0.0: 0.0, 20.0: 23.2, 100.0: 107.2, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11829,21 +9097,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, True, Liquid.WATER, True, True)] = ( - StandardVolumeFilter_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 50.0: 55.1, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 23.2, - 200.0: 211.0, - }, +star_mapping[(300, False, True, True, Liquid.WATER, True, True)] = \ +StandardVolumeFilter_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 313.5, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11860,13 +9120,12 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, True, Liquid.WATER, True, False)] = ( - StandardVolumeFilter_Water_DispenseJet_Part -) = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.WATER, True, False)] = \ +StandardVolumeFilter_Water_DispenseJet_Part = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 110.2, 20.0: 27.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11884,27 +9143,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, True, Liquid.WATER, False, False)] = ( - StandardVolumeFilter_Water_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 5.0: 6.3, - 0.5: 0.9, - 50.0: 55.1, - 0.0: 0.0, - 1.0: 1.6, - 20.0: 23.2, - 100.0: 107.2, - 2.0: 2.8, - 10.0: 11.9, - 200.0: 211.0, - }, +star_mapping[(300, False, True, True, Liquid.WATER, False, False)] = \ +StandardVolumeFilter_Water_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 313.5, 5.0: 6.3, 0.5: 0.9, 50.0: 55.1, 0.0: 0.0, 1.0: 1.6, 20.0: 23.2, 100.0: 107.2, 2.0: 2.8, 10.0: 11.9, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11921,26 +9167,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, True, Liquid.WATER, False, True)] = ( - StandardVolumeFilter_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 5.0: 6.3, - 0.5: 0.9, - 50.0: 55.1, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 23.2, - 1.0: 1.6, - 200.0: 211.0, - 10.0: 11.9, - 2.0: 2.8, - }, +star_mapping[(300, False, True, True, Liquid.WATER, False, True)] = \ +StandardVolumeFilter_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 313.5, 5.0: 6.3, 0.5: 0.9, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 1.0: 1.6, 200.0: 211.0, 10.0: 11.9, 2.0: 2.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11957,23 +9190,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, True, Liquid.WATER, False, False)] = ( - StandardVolumeFilter_Water_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 5.0: 6.5, - 50.0: 55.1, - 0.0: 0.0, - 20.0: 23.2, - 100.0: 107.2, - 10.0: 11.9, - 200.0: 211.0, - }, +star_mapping[(300, False, True, True, Liquid.WATER, False, False)] = \ +StandardVolumeFilter_Water_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 313.5, 5.0: 6.5, 50.0: 55.1, 0.0: 0.0, 20.0: 23.2, 100.0: 107.2, 10.0: 11.9, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -11990,7 +9213,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -12015,17 +9238,9 @@ def get_star_liquid_class( # 200 0.56 0.07 # 300 0.54 1.12 # -star_mapping[(300, False, True, False, Liquid.METHANOL, True, False)] = ( - StandardVolumeMeOHDispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 336.0, - 50.0: 63.0, - 0.0: 0.0, - 100.0: 119.5, - 20.0: 28.3, - 200.0: 230.0, - }, +star_mapping[(300, False, True, False, Liquid.METHANOL, True, False)] = \ +StandardVolumeMeOHDispenseJet = HamiltonLiquidClass( + curve={300.0: 336.0, 50.0: 63.0, 0.0: 0.0, 100.0: 119.5, 20.0: 28.3, 200.0: 230.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=5.0, @@ -12042,7 +9257,7 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -12069,19 +9284,9 @@ def get_star_liquid_class( # 200 0.51 0.59 # 300 0.81 0.22 # -star_mapping[(300, False, True, False, Liquid.METHANOL, False, False)] = ( - StandardVolumeMeOHDispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 310.2, - 5.0: 8.0, - 50.0: 55.8, - 0.0: 0.0, - 100.0: 107.5, - 20.0: 24.6, - 200.0: 209.2, - 10.0: 14.0, - }, +star_mapping[(300, False, True, False, Liquid.METHANOL, False, False)] = \ +StandardVolumeMeOHDispenseSurface = HamiltonLiquidClass( + curve={300.0: 310.2, 5.0: 8.0, 50.0: 55.8, 0.0: 0.0, 100.0: 107.5, 20.0: 24.6, 200.0: 209.2, 10.0: 14.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=10.0, @@ -12098,7 +9303,7 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -12119,17 +9324,9 @@ def get_star_liquid_class( # 200 0.29 0.17 # 300 0.16 0.80 # -star_mapping[(300, False, True, False, Liquid.OCTANOL, True, False)] = ( - StandardVolumeOctanol100DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 319.3, - 50.0: 56.6, - 0.0: 0.0, - 100.0: 109.9, - 20.0: 23.8, - 200.0: 216.2, - }, +star_mapping[(300, False, True, False, Liquid.OCTANOL, True, False)] = \ +StandardVolumeOctanol100DispenseJet = HamiltonLiquidClass( + curve={300.0: 319.3, 50.0: 56.6, 0.0: 0.0, 100.0: 109.9, 20.0: 23.8, 200.0: 216.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12146,7 +9343,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -12171,21 +9368,9 @@ def get_star_liquid_class( # 200 0.02 0.12 # 300 0.11 0.29 # -star_mapping[(300, False, True, False, Liquid.OCTANOL, False, False)] = ( - StandardVolumeOctanol100DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 315.0, - 5.0: 6.6, - 50.0: 55.9, - 0.0: 0.0, - 100.0: 106.8, - 20.0: 22.1, - 1.0: 0.8, - 200.0: 212.0, - 10.0: 12.6, - 2.0: 3.7, - }, +star_mapping[(300, False, True, False, Liquid.OCTANOL, False, False)] = \ +StandardVolumeOctanol100DispenseSurface = HamiltonLiquidClass( + curve={300.0: 315.0, 5.0: 6.6, 50.0: 55.9, 0.0: 0.0, 100.0: 106.8, 20.0: 22.1, 1.0: 0.8, 200.0: 212.0, 10.0: 12.6, 2.0: 3.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -12202,7 +9387,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -12221,20 +9406,9 @@ def get_star_liquid_class( # 10 1.99 4.39 # # -star_mapping[(300, False, True, False, Liquid.PBS_BUFFER, False, False)] = ( - StandardVolumePBSDispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 5.0: 7.5, - 50.0: 55.1, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 23.2, - 1.0: 2.6, - 200.0: 211.0, - 10.0: 12.8, - }, +star_mapping[(300, False, True, False, Liquid.PBS_BUFFER, False, False)] = \ +StandardVolumePBSDispenseSurface = HamiltonLiquidClass( + curve={300.0: 313.5, 5.0: 7.5, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 1.0: 2.6, 200.0: 211.0, 10.0: 12.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -12251,7 +9425,7 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -12271,18 +9445,9 @@ def get_star_liquid_class( # 100 0.08 1.09 # 200 0.09 0.91 # -star_mapping[(300, False, True, False, Liquid.PLASMA, True, False)] = ( - StandardVolumePlasmaDispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 315.2, - 50.0: 55.6, - 0.0: 0.0, - 100.0: 108.1, - 20.0: 23.2, - 200.0: 212.1, - 10.0: 12.3, - }, +star_mapping[(300, False, True, False, Liquid.PLASMA, True, False)] = \ +StandardVolumePlasmaDispenseJet = HamiltonLiquidClass( + curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 100.0: 108.1, 20.0: 23.2, 200.0: 212.1, 10.0: 12.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -12299,21 +9464,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.PLASMA, True, True)] = ( - StandardVolumePlasmaDispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 315.2, - 50.0: 55.6, - 0.0: 0.0, - 20.0: 23.2, - 100.0: 108.1, - 200.0: 212.1, - }, +star_mapping[(300, False, True, False, Liquid.PLASMA, True, True)] = \ +StandardVolumePlasmaDispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 20.0: 23.2, 100.0: 108.1, 200.0: 212.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12330,13 +9487,12 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.PLASMA, True, False)] = ( - StandardVolumePlasmaDispenseJet_Part -) = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.PLASMA, True, False)] = \ +StandardVolumePlasmaDispenseJet_Part = HamiltonLiquidClass( curve={300.0: 315.2, 0.0: 0.0, 20.0: 29.2, 100.0: 111.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -12354,7 +9510,7 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=5.0, + dispense_stop_back_volume=5.0 ) @@ -12375,20 +9531,9 @@ def get_star_liquid_class( # 60 0.55 2.06 # # -star_mapping[(300, False, True, False, Liquid.PLASMA, False, False)] = ( - StandardVolumePlasmaDispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 313.4, - 5.0: 6.3, - 50.0: 54.9, - 0.0: 0.0, - 100.0: 107.1, - 20.0: 23.0, - 200.0: 210.5, - 10.0: 12.0, - 2.0: 2.6, - }, +star_mapping[(300, False, True, False, Liquid.PLASMA, False, False)] = \ +StandardVolumePlasmaDispenseSurface = HamiltonLiquidClass( + curve={300.0: 313.4, 5.0: 6.3, 50.0: 54.9, 0.0: 0.0, 100.0: 107.1, 20.0: 23.0, 200.0: 210.5, 10.0: 12.0, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -12405,24 +9550,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.PLASMA, False, True)] = ( - StandardVolumePlasmaDispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.4, - 5.0: 6.3, - 50.0: 54.9, - 0.0: 0.0, - 20.0: 23.0, - 100.0: 107.1, - 2.0: 2.6, - 10.0: 12.0, - 200.0: 210.5, - }, +star_mapping[(300, False, True, False, Liquid.PLASMA, False, True)] = \ +StandardVolumePlasmaDispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 313.4, 5.0: 6.3, 50.0: 54.9, 0.0: 0.0, 20.0: 23.0, 100.0: 107.1, 2.0: 2.6, 10.0: 12.0, 200.0: 210.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -12439,13 +9573,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.PLASMA, False, False)] = ( - StandardVolumePlasmaDispenseSurface_Part -) = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.PLASMA, False, False)] = \ +StandardVolumePlasmaDispenseSurface_Part = HamiltonLiquidClass( curve={300.0: 313.4, 5.0: 6.8, 0.0: 0.0, 100.0: 109.1, 10.0: 12.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -12463,20 +9596,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = ( - StandardVolume_96COREHead1000ul_DMSO_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 150.0: 150.0, - 50.0: 50.0, - 0.0: 0.0, - 20.0: 20.0, - }, +star_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ +StandardVolume_96COREHead1000ul_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 150.0: 150.0, 50.0: 50.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -12493,20 +9619,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=20.0, + dispense_stop_back_volume=20.0 ) -star_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = ( - StandardVolume_96COREHead1000ul_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 302.5, - 0.0: 0.0, - 100.0: 101.0, - 20.0: 20.4, - 200.0: 201.5, - }, +star_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ +StandardVolume_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 302.5, 0.0: 0.0, 100.0: 101.0, 20.0: 20.4, 200.0: 201.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12523,20 +9642,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = ( - StandardVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 306.0, - 0.0: 0.0, - 100.0: 104.3, - 200.0: 205.0, - 10.0: 12.2, - }, +star_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ +StandardVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 306.0, 0.0: 0.0, 100.0: 104.3, 200.0: 205.0, 10.0: 12.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12553,20 +9665,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( - StandardVolume_96COREHead1000ul_Water_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 150.0: 150.0, - 50.0: 50.0, - 0.0: 0.0, - 20.0: 20.0, - }, +star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ +StandardVolume_96COREHead1000ul_Water_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 150.0: 150.0, 50.0: 50.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -12583,20 +9688,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( - StandardVolume_96COREHead1000ul_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 23.2, - 200.0: 207.5, - }, +star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ +StandardVolume_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 200.0: 207.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12613,20 +9711,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( - StandardVolume_96COREHead1000ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 0.0: 0.0, - 100.0: 107.2, - 200.0: 210.0, - 10.0: 11.9, - }, +star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ +StandardVolume_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 210.0, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12643,20 +9734,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = ( - StandardVolume_96COREHead_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 303.5, - 0.0: 0.0, - 100.0: 101.8, - 10.0: 10.2, - 200.0: 200.5, - }, +star_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ +StandardVolume_96COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 303.5, 0.0: 0.0, 100.0: 101.8, 10.0: 10.2, 200.0: 200.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12673,20 +9757,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = ( - StandardVolume_96COREHead_DMSO_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 306.0, - 0.0: 0.0, - 100.0: 105.6, - 10.0: 12.2, - 200.0: 207.0, - }, +star_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ +StandardVolume_96COREHead_DMSO_DispenseJet_Part = HamiltonLiquidClass( + curve={300.0: 306.0, 0.0: 0.0, 100.0: 105.6, 10.0: 12.2, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12703,20 +9780,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -star_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = ( - StandardVolume_96COREHead_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 303.0, - 0.0: 0.0, - 100.0: 101.3, - 10.0: 10.6, - 200.0: 202.0, - }, +star_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ +StandardVolume_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 303.0, 0.0: 0.0, 100.0: 101.3, 10.0: 10.6, 200.0: 202.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12733,20 +9803,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.DMSO, False, False)] = ( - StandardVolume_96COREHead_DMSO_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 303.0, - 0.0: 0.0, - 100.0: 101.3, - 10.0: 10.1, - 200.0: 202.0, - }, +star_mapping[(300, True, True, False, Liquid.DMSO, False, False)] = \ +StandardVolume_96COREHead_DMSO_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 303.0, 0.0: 0.0, 100.0: 101.3, 10.0: 10.1, 200.0: 202.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12763,21 +9826,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( - StandardVolume_96COREHead_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 309.0, - 0.0: 0.0, - 20.0: 22.3, - 100.0: 104.2, - 10.0: 11.9, - 200.0: 207.0, - }, +star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ +StandardVolume_96COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 309.0, 0.0: 0.0, 20.0: 22.3, 100.0: 104.2, 10.0: 11.9, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12794,20 +9849,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( - StandardVolume_96COREHead_Water_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 309.0, - 0.0: 0.0, - 20.0: 22.3, - 100.0: 104.2, - 10.0: 11.9, - }, +star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ +StandardVolume_96COREHead_Water_DispenseJet_Part = HamiltonLiquidClass( + curve={300.0: 309.0, 0.0: 0.0, 20.0: 22.3, 100.0: 104.2, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12824,20 +9872,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( - StandardVolume_96COREHead_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 306.3, - 0.0: 0.0, - 100.0: 104.5, - 10.0: 11.9, - 200.0: 205.7, - }, +star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ +StandardVolume_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 306.3, 0.0: 0.0, 100.0: 104.5, 10.0: 11.9, 200.0: 205.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12854,20 +9895,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.WATER, False, False)] = ( - StandardVolume_96COREHead_Water_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 304.0, - 0.0: 0.0, - 100.0: 105.3, - 10.0: 11.9, - 200.0: 205.7, - }, +star_mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ +StandardVolume_96COREHead_Water_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 304.0, 0.0: 0.0, 100.0: 105.3, 10.0: 11.9, 200.0: 205.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -12884,27 +9918,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # Liquid class for wash standard volume tips with CO-RE 96 Head in CO-RE 96 Head Washer. -star_mapping[(300, True, True, False, Liquid.WATER, False, False)] = ( - StandardVolume_Core96Washer_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 330.0, - 5.0: 6.3, - 0.5: 0.9, - 50.0: 55.1, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 23.2, - 1.0: 1.6, - 200.0: 211.0, - 10.0: 11.9, - 2.0: 2.8, - }, +star_mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ +StandardVolume_Core96Washer_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 330.0, 5.0: 6.3, 0.5: 0.9, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 1.0: 1.6, 200.0: 211.0, 10.0: 11.9, 2.0: 2.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=150.0, aspiration_air_transport_volume=0.0, @@ -12921,7 +9942,7 @@ def get_star_liquid_class( dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -12941,9 +9962,8 @@ def get_star_liquid_class( # 20 (12 Aliquots) 2.53 -2.97 # 50 ( 4 Aliquots) 0.84 -2.57 # -star_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = ( - StandardVolume_DMSO_AliquotDispenseJet_Part -) = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = \ +StandardVolume_DMSO_AliquotDispenseJet_Part = HamiltonLiquidClass( curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -12961,23 +9981,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = ( - StandardVolume_DMSO_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 304.6, - 350.0: 355.2, - 50.0: 51.1, - 0.0: 0.0, - 100.0: 101.8, - 20.0: 20.7, - 200.0: 203.0, - }, +star_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = \ +StandardVolume_DMSO_DispenseJet = HamiltonLiquidClass( + curve={300.0: 304.6, 350.0: 355.2, 50.0: 51.1, 0.0: 0.0, 100.0: 101.8, 20.0: 20.7, 200.0: 203.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12994,21 +10005,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.DMSO, True, True)] = ( - StandardVolume_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 304.6, - 50.0: 51.1, - 0.0: 0.0, - 20.0: 20.7, - 100.0: 101.8, - 200.0: 203.0, - }, +star_mapping[(300, False, True, False, Liquid.DMSO, True, True)] = \ +StandardVolume_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 304.6, 50.0: 51.1, 0.0: 0.0, 20.0: 20.7, 100.0: 101.8, 200.0: 203.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -13025,13 +10028,12 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = ( - StandardVolume_DMSO_DispenseJet_Part -) = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = \ +StandardVolume_DMSO_DispenseJet_Part = HamiltonLiquidClass( curve={300.0: 320.0, 0.0: 0.0, 20.0: 30.5, 100.0: 116.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13049,26 +10051,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, -) - - -star_mapping[(300, False, True, False, Liquid.DMSO, False, False)] = ( - StandardVolume_DMSO_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 308.8, - 5.0: 6.6, - 50.0: 52.9, - 350.0: 360.5, - 0.0: 0.0, - 1.0: 1.8, - 20.0: 22.1, - 100.0: 103.8, - 2.0: 3.0, - 10.0: 11.9, - 200.0: 205.0, - }, + dispense_stop_back_volume=10.0 +) + + +star_mapping[(300, False, True, False, Liquid.DMSO, False, False)] = \ +StandardVolume_DMSO_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 308.8, 5.0: 6.6, 50.0: 52.9, 350.0: 360.5, 0.0: 0.0, 1.0: 1.8, 20.0: 22.1, 100.0: 103.8, 2.0: 3.0, 10.0: 11.9, 200.0: 205.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -13085,25 +10074,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(300, False, True, False, Liquid.DMSO, False, True)] = ( - StandardVolume_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 308.8, - 5.0: 6.6, - 50.0: 52.9, - 0.0: 0.0, - 1.0: 1.8, - 20.0: 22.1, - 100.0: 103.8, - 2.0: 3.0, - 10.0: 11.9, - 200.0: 205.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(300, False, True, False, Liquid.DMSO, False, True)] = \ +StandardVolume_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 308.8, 5.0: 6.6, 50.0: 52.9, 0.0: 0.0, 1.0: 1.8, 20.0: 22.1, 100.0: 103.8, 2.0: 3.0, 10.0: 11.9, 200.0: 205.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -13120,23 +10097,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.DMSO, False, False)] = ( - StandardVolume_DMSO_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 308.8, - 5.0: 6.4, - 50.0: 52.9, - 0.0: 0.0, - 20.0: 22.1, - 100.0: 103.8, - 10.0: 11.9, - 200.0: 205.0, - }, +star_mapping[(300, False, True, False, Liquid.DMSO, False, False)] = \ +StandardVolume_DMSO_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 308.8, 5.0: 6.4, 50.0: 52.9, 0.0: 0.0, 20.0: 22.1, 100.0: 103.8, 10.0: 11.9, 200.0: 205.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -13153,23 +10120,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 100, stop back volume = 0 -star_mapping[(300, False, True, False, Liquid.ETHANOL, True, False)] = ( - StandardVolume_EtOH_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 310.2, - 350.0: 360.5, - 50.0: 55.8, - 0.0: 0.0, - 100.0: 107.5, - 20.0: 24.6, - 200.0: 209.2, - }, +star_mapping[(300, False, True, False, Liquid.ETHANOL, True, False)] = \ +StandardVolume_EtOH_DispenseJet = HamiltonLiquidClass( + curve={300.0: 310.2, 350.0: 360.5, 50.0: 55.8, 0.0: 0.0, 100.0: 107.5, 20.0: 24.6, 200.0: 209.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -13186,21 +10144,13 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.ETHANOL, True, True)] = ( - StandardVolume_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 310.2, - 50.0: 55.8, - 0.0: 0.0, - 20.0: 24.6, - 100.0: 107.5, - 200.0: 209.2, - }, +star_mapping[(300, False, True, False, Liquid.ETHANOL, True, True)] = \ +StandardVolume_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 310.2, 50.0: 55.8, 0.0: 0.0, 20.0: 24.6, 100.0: 107.5, 200.0: 209.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -13217,13 +10167,12 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.ETHANOL, True, False)] = ( - StandardVolume_EtOH_DispenseJet_Part -) = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.ETHANOL, True, False)] = \ +StandardVolume_EtOH_DispenseJet_Part = HamiltonLiquidClass( curve={300.0: 317.2, 0.0: 0.0, 20.0: 25.6, 100.0: 110.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13241,23 +10190,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=5.0, + dispense_stop_back_volume=5.0 ) # V1.1: Set mix flow rate to 20, dispense settling time=0, stop back volume = 0 -star_mapping[(300, False, True, False, Liquid.GLYCERIN, True, False)] = ( - StandardVolume_Glycerin_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 309.0, - 350.0: 360.0, - 50.0: 53.6, - 0.0: 0.0, - 100.0: 104.9, - 20.0: 22.3, - 200.0: 207.2, - }, +star_mapping[(300, False, True, False, Liquid.GLYCERIN, True, False)] = \ +StandardVolume_Glycerin_DispenseJet = HamiltonLiquidClass( + curve={300.0: 309.0, 350.0: 360.0, 50.0: 53.6, 0.0: 0.0, 100.0: 104.9, 20.0: 22.3, 200.0: 207.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=20.0, aspiration_air_transport_volume=5.0, @@ -13274,22 +10214,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 20, dispense settling time=0, stop back volume = 0 -star_mapping[(300, False, True, False, Liquid.GLYCERIN80, True, True)] = ( - StandardVolume_Glycerin_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 309.0, - 50.0: 53.6, - 0.0: 0.0, - 100.0: 104.9, - 20.0: 22.3, - 200.0: 207.2, - }, +star_mapping[(300, False, True, False, Liquid.GLYCERIN80, True, True)] = \ +StandardVolume_Glycerin_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 309.0, 50.0: 53.6, 0.0: 0.0, 100.0: 104.9, 20.0: 22.3, 200.0: 207.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=20.0, aspiration_air_transport_volume=5.0, @@ -13306,26 +10238,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 10 -star_mapping[(300, False, True, False, Liquid.GLYCERIN, False, False)] = ( - StandardVolume_Glycerin_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 307.9, - 5.0: 6.5, - 350.0: 358.4, - 50.0: 53.6, - 0.0: 0.0, - 100.0: 105.7, - 20.0: 22.5, - 200.0: 207.0, - 10.0: 12.0, - 2.0: 3.2, - }, +star_mapping[(300, False, True, False, Liquid.GLYCERIN, False, False)] = \ +StandardVolume_Glycerin_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 307.9, 5.0: 6.5, 350.0: 358.4, 50.0: 53.6, 0.0: 0.0, 100.0: 105.7, 20.0: 22.5, 200.0: 207.0, 10.0: 12.0, 2.0: 3.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -13342,24 +10262,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(300, False, True, False, Liquid.GLYCERIN80, False, True)] = ( - StandardVolume_Glycerin_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 307.9, - 5.0: 6.5, - 50.0: 53.6, - 0.0: 0.0, - 100.0: 105.7, - 20.0: 22.5, - 200.0: 207.0, - 10.0: 12.0, - 2.0: 3.2, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(300, False, True, False, Liquid.GLYCERIN80, False, True)] = \ +StandardVolume_Glycerin_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 307.9, 5.0: 6.5, 50.0: 53.6, 0.0: 0.0, 100.0: 105.7, 20.0: 22.5, 200.0: 207.0, 10.0: 12.0, 2.0: 3.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -13376,23 +10285,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, -) - - -star_mapping[(300, False, True, False, Liquid.GLYCERIN80, False, False)] = ( - StandardVolume_Glycerin_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 307.9, - 5.0: 6.2, - 50.0: 53.6, - 0.0: 0.0, - 100.0: 105.7, - 20.0: 22.5, - 200.0: 207.0, - 10.0: 12.0, - }, + dispense_stop_back_volume=0.0 +) + + +star_mapping[(300, False, True, False, Liquid.GLYCERIN80, False, False)] = \ +StandardVolume_Glycerin_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 307.9, 5.0: 6.2, 50.0: 53.6, 0.0: 0.0, 100.0: 105.7, 20.0: 22.5, 200.0: 207.0, 10.0: 12.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -13409,14 +10308,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = ( - StandardVolume_Serum_AliquotDispenseJet_Part -) = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = \ +StandardVolume_Serum_AliquotDispenseJet_Part = HamiltonLiquidClass( curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13434,14 +10332,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = ( - StandardVolume_Serum_AliquotJet -) = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = \ +StandardVolume_Serum_AliquotJet = HamiltonLiquidClass( curve={350.0: 350.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13459,22 +10356,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = ( - StandardVolume_Serum_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 315.2, - 50.0: 55.6, - 0.0: 0.0, - 100.0: 108.1, - 20.0: 23.2, - 200.0: 212.1, - }, +star_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = \ +StandardVolume_Serum_DispenseJet = HamiltonLiquidClass( + curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 100.0: 108.1, 20.0: 23.2, 200.0: 212.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -13491,21 +10380,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.SERUM, True, True)] = ( - StandardVolume_Serum_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 315.2, - 50.0: 55.6, - 0.0: 0.0, - 20.0: 23.2, - 100.0: 108.1, - 200.0: 212.1, - }, +star_mapping[(300, False, True, False, Liquid.SERUM, True, True)] = \ +StandardVolume_Serum_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 20.0: 23.2, 100.0: 108.1, 200.0: 212.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -13522,13 +10403,12 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = ( - StandardVolume_Serum_DispenseJet_Part -) = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = \ +StandardVolume_Serum_DispenseJet_Part = HamiltonLiquidClass( curve={300.0: 315.2, 0.0: 0.0, 20.0: 29.2, 100.0: 111.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13546,24 +10426,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=5.0, + dispense_stop_back_volume=5.0 ) -star_mapping[(300, False, True, False, Liquid.SERUM, False, False)] = ( - StandardVolume_Serum_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 313.4, - 5.0: 6.3, - 50.0: 54.9, - 0.0: 0.0, - 20.0: 23.0, - 100.0: 107.1, - 2.0: 2.6, - 10.0: 12.0, - 200.0: 210.5, - }, +star_mapping[(300, False, True, False, Liquid.SERUM, False, False)] = \ +StandardVolume_Serum_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 313.4, 5.0: 6.3, 50.0: 54.9, 0.0: 0.0, 20.0: 23.0, 100.0: 107.1, 2.0: 2.6, 10.0: 12.0, 200.0: 210.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -13580,24 +10449,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.SERUM, False, True)] = ( - StandardVolume_Serum_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.4, - 5.0: 6.3, - 50.0: 54.9, - 0.0: 0.0, - 20.0: 23.0, - 100.0: 107.1, - 2.0: 2.6, - 10.0: 12.0, - 200.0: 210.5, - }, +star_mapping[(300, False, True, False, Liquid.SERUM, False, True)] = \ +StandardVolume_Serum_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 313.4, 5.0: 6.3, 50.0: 54.9, 0.0: 0.0, 20.0: 23.0, 100.0: 107.1, 2.0: 2.6, 10.0: 12.0, 200.0: 210.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -13614,13 +10472,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.SERUM, False, False)] = ( - StandardVolume_Serum_DispenseSurface_Part -) = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.SERUM, False, False)] = \ +StandardVolume_Serum_DispenseSurface_Part = HamiltonLiquidClass( curve={300.0: 313.4, 5.0: 6.8, 0.0: 0.0, 100.0: 109.1, 10.0: 12.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -13638,14 +10495,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, False, Liquid.WATER, True, False)] = ( - StandardVolume_Water_AliquotDispenseJet_Part -) = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.WATER, True, False)] = \ +StandardVolume_Water_AliquotDispenseJet_Part = HamiltonLiquidClass( curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13663,14 +10519,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, False, Liquid.WATER, True, False)] = ( - StandardVolume_Water_AliquotJet -) = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.WATER, True, False)] = \ +StandardVolume_Water_AliquotJet = HamiltonLiquidClass( curve={350.0: 350.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13688,23 +10543,14 @@ def get_star_liquid_class( dispense_swap_speed=0.3, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, False, Liquid.WATER, True, False)] = ( - StandardVolume_Water_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 350.0: 364.3, - 50.0: 55.1, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 23.2, - 200.0: 211.0, - }, +star_mapping[(300, False, True, False, Liquid.WATER, True, False)] = \ +StandardVolume_Water_DispenseJet = HamiltonLiquidClass( + curve={300.0: 313.5, 350.0: 364.3, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -13721,20 +10567,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( - StandardVolume_Water_DispenseJetEmpty96Head -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 0.0: 0.0, - 100.0: 107.2, - 200.0: 205.3, - 10.0: 11.9, - }, +star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ +StandardVolume_Water_DispenseJetEmpty96Head = HamiltonLiquidClass( + curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 205.3, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -13751,20 +10590,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( - StandardVolume_Water_DispenseJetPart96Head -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 0.0: 0.0, - 100.0: 107.2, - 200.0: 205.3, - 10.0: 11.9, - }, +star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ +StandardVolume_Water_DispenseJetPart96Head = HamiltonLiquidClass( + curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 205.3, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -13781,21 +10613,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.WATER, True, True)] = ( - StandardVolume_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 50.0: 55.1, - 0.0: 0.0, - 20.0: 23.2, - 100.0: 107.2, - 200.0: 211.0, - }, +star_mapping[(300, False, True, False, Liquid.WATER, True, True)] = \ +StandardVolume_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 313.5, 50.0: 55.1, 0.0: 0.0, 20.0: 23.2, 100.0: 107.2, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -13812,13 +10636,12 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.WATER, True, False)] = ( - StandardVolume_Water_DispenseJet_Part -) = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.WATER, True, False)] = \ +StandardVolume_Water_DispenseJet_Part = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 20.0: 28.2, 100.0: 111.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13836,28 +10659,14 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, False, Liquid.WATER, False, False)] = ( - StandardVolume_Water_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 5.0: 6.3, - 0.5: 0.9, - 350.0: 364.3, - 50.0: 55.1, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 23.2, - 1.0: 1.6, - 200.0: 211.0, - 10.0: 11.9, - 2.0: 2.8, - }, +star_mapping[(300, False, True, False, Liquid.WATER, False, False)] = \ +StandardVolume_Water_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 313.5, 5.0: 6.3, 0.5: 0.9, 350.0: 364.3, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 1.0: 1.6, 200.0: 211.0, 10.0: 11.9, 2.0: 2.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -13874,13 +10683,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.WATER, False, False)] = ( - StandardVolume_Water_DispenseSurface96Head -) = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ +StandardVolume_Water_DispenseSurface96Head = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13898,20 +10706,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( - StandardVolume_Water_DispenseSurfaceEmpty96Head -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 0.0: 0.0, - 100.0: 107.2, - 200.0: 205.7, - 10.0: 11.9, - }, +star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ +StandardVolume_Water_DispenseSurfaceEmpty96Head = HamiltonLiquidClass( + curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 205.7, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -13928,20 +10729,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, True, True, False, Liquid.WATER, False, False)] = ( - StandardVolume_Water_DispenseSurfacePart96Head -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 0.0: 0.0, - 100.0: 107.2, - 200.0: 205.7, - 10.0: 11.9, - }, +star_mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ +StandardVolume_Water_DispenseSurfacePart96Head = HamiltonLiquidClass( + curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 205.7, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -13958,26 +10752,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.WATER, False, True)] = ( - StandardVolume_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 5.0: 6.3, - 0.5: 0.9, - 50.0: 55.1, - 0.0: 0.0, - 1.0: 1.6, - 20.0: 23.2, - 100.0: 107.2, - 2.0: 2.8, - 10.0: 11.9, - 200.0: 211.0, - }, +star_mapping[(300, False, True, False, Liquid.WATER, False, True)] = \ +StandardVolume_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 313.5, 5.0: 6.3, 0.5: 0.9, 50.0: 55.1, 0.0: 0.0, 1.0: 1.6, 20.0: 23.2, 100.0: 107.2, 2.0: 2.8, 10.0: 11.9, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -13994,23 +10775,13 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(300, False, True, False, Liquid.WATER, False, False)] = ( - StandardVolume_Water_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 5.0: 6.8, - 50.0: 55.1, - 0.0: 0.0, - 20.0: 23.2, - 100.0: 107.2, - 10.0: 12.3, - 200.0: 211.0, - }, +star_mapping[(300, False, True, False, Liquid.WATER, False, False)] = \ +StandardVolume_Water_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 313.5, 5.0: 6.8, 50.0: 55.1, 0.0: 0.0, 20.0: 23.2, 100.0: 107.2, 10.0: 12.3, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -14027,13 +10798,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, True, Liquid.DMSO, True, True)] = ( - Tip_50ulFilter_96COREHead1000ul_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, True, True, True, Liquid.DMSO, True, True)] = \ +Tip_50ulFilter_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 52.1, 30.0: 31.7, 0.0: 0.0, 20.0: 21.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -14051,21 +10821,13 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, True, Liquid.DMSO, False, True)] = ( - Tip_50ulFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.4, - 50.0: 52.1, - 30.0: 31.5, - 0.0: 0.0, - 1.0: 0.7, - 10.0: 10.8, - }, +star_mapping[(50, True, True, True, Liquid.DMSO, False, True)] = \ +Tip_50ulFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.4, 50.0: 52.1, 30.0: 31.5, 0.0: 0.0, 1.0: 0.7, 10.0: 10.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -14082,13 +10844,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, True, Liquid.WATER, True, True)] = ( - Tip_50ulFilter_96COREHead1000ul_Water_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, True, True, True, Liquid.WATER, True, True)] = \ +Tip_50ulFilter_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 54.2, 30.0: 33.2, 0.0: 0.0, 20.0: 22.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -14106,21 +10867,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, True, Liquid.WATER, False, True)] = ( - Tip_50ulFilter_96COREHead1000ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.6, - 50.0: 53.6, - 30.0: 32.6, - 0.0: 0.0, - 1.0: 0.8, - 10.0: 11.3, - }, +star_mapping[(50, True, True, True, Liquid.WATER, False, True)] = \ +Tip_50ulFilter_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.6, 50.0: 53.6, 30.0: 32.6, 0.0: 0.0, 1.0: 0.8, 10.0: 11.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -14137,13 +10890,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, True, Liquid.DMSO, True, True)] = ( - Tip_50ulFilter_96COREHead_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, True, True, True, Liquid.DMSO, True, True)] = \ +Tip_50ulFilter_96COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 51.4, 0.0: 0.0, 30.0: 31.3, 20.0: 21.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -14161,21 +10913,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, True, Liquid.DMSO, False, True)] = ( - Tip_50ulFilter_96COREHead_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.6, - 50.0: 51.1, - 0.0: 0.0, - 30.0: 31.0, - 1.0: 0.8, - 10.0: 10.7, - }, +star_mapping[(50, True, True, True, Liquid.DMSO, False, True)] = \ +Tip_50ulFilter_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.6, 50.0: 51.1, 0.0: 0.0, 30.0: 31.0, 1.0: 0.8, 10.0: 10.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -14192,13 +10936,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, True, Liquid.WATER, True, True)] = ( - Tip_50ulFilter_96COREHead_Water_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, True, True, True, Liquid.WATER, True, True)] = \ +Tip_50ulFilter_96COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 54.0, 30.0: 33.0, 0.0: 0.0, 20.0: 22.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -14216,21 +10959,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, True, Liquid.WATER, False, True)] = ( - Tip_50ulFilter_96COREHead_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.6, - 50.0: 53.5, - 30.0: 32.9, - 0.0: 0.0, - 1.0: 0.8, - 10.0: 11.4, - }, +star_mapping[(50, True, True, True, Liquid.WATER, False, True)] = \ +Tip_50ulFilter_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.6, 50.0: 53.5, 30.0: 32.9, 0.0: 0.0, 1.0: 0.8, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -14247,13 +10982,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, True, Liquid.DMSO, True, True)] = ( - Tip_50ulFilter_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.DMSO, True, True)] = \ +Tip_50ulFilter_DMSO_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 52.5, 0.0: 0.0, 30.0: 31.4, 20.0: 21.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -14271,21 +11005,13 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, True, Liquid.DMSO, False, True)] = ( - Tip_50ulFilter_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.5, - 50.0: 52.6, - 0.0: 0.0, - 30.0: 32.0, - 1.0: 0.7, - 10.0: 11.0, - }, +star_mapping[(50, False, True, True, Liquid.DMSO, False, True)] = \ +Tip_50ulFilter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.5, 50.0: 52.6, 0.0: 0.0, 30.0: 32.0, 1.0: 0.7, 10.0: 11.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -14302,13 +11028,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, True, Liquid.ETHANOL, True, True)] = ( - Tip_50ulFilter_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.ETHANOL, True, True)] = \ +Tip_50ulFilter_EtOH_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 57.5, 0.0: 0.0, 30.0: 35.8, 20.0: 24.4}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -14326,21 +11051,13 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, True, Liquid.ETHANOL, False, True)] = ( - Tip_50ulFilter_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 6.5, - 50.0: 54.1, - 0.0: 0.0, - 30.0: 33.8, - 1.0: 1.9, - 10.0: 12.0, - }, +star_mapping[(50, False, True, True, Liquid.ETHANOL, False, True)] = \ +Tip_50ulFilter_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 6.5, 50.0: 54.1, 0.0: 0.0, 30.0: 33.8, 1.0: 1.9, 10.0: 12.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=2.0, @@ -14357,21 +11074,13 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, True, Liquid.GLYCERIN80, False, True)] = ( - Tip_50ulFilter_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.5, - 50.0: 57.0, - 0.0: 0.0, - 30.0: 35.9, - 1.0: 0.6, - 10.0: 12.0, - }, +star_mapping[(50, False, True, True, Liquid.GLYCERIN80, False, True)] = \ +Tip_50ulFilter_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.5, 50.0: 57.0, 0.0: 0.0, 30.0: 35.9, 1.0: 0.6, 10.0: 12.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -14388,13 +11097,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, True, Liquid.SERUM, True, True)] = ( - Tip_50ulFilter_Serum_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.SERUM, True, True)] = \ +Tip_50ulFilter_Serum_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 54.6, 30.0: 33.5, 0.0: 0.0, 20.0: 22.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -14412,21 +11120,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, True, Liquid.SERUM, False, True)] = ( - Tip_50ulFilter_Serum_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.7, - 50.0: 54.9, - 30.0: 33.0, - 0.0: 0.0, - 1.0: 0.7, - 10.0: 11.3, - }, +star_mapping[(50, False, True, True, Liquid.SERUM, False, True)] = \ +Tip_50ulFilter_Serum_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.7, 50.0: 54.9, 30.0: 33.0, 0.0: 0.0, 1.0: 0.7, 10.0: 11.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -14443,13 +11143,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, True, Liquid.WATER, True, True)] = ( - Tip_50ulFilter_Water_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.WATER, True, True)] = \ +Tip_50ulFilter_Water_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 54.0, 30.0: 33.6, 0.0: 0.0, 20.0: 22.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -14467,21 +11166,13 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, True, Liquid.WATER, False, True)] = ( - Tip_50ulFilter_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.7, - 50.0: 54.2, - 30.0: 33.1, - 0.0: 0.0, - 1.0: 0.65, - 10.0: 11.4, - }, +star_mapping[(50, False, True, True, Liquid.WATER, False, True)] = \ +Tip_50ulFilter_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.7, 50.0: 54.2, 30.0: 33.1, 0.0: 0.0, 1.0: 0.65, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -14498,13 +11189,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = ( - Tip_50ul_96COREHead1000ul_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ +Tip_50ul_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 52.1, 30.0: 31.7, 0.0: 0.0, 20.0: 21.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -14522,21 +11212,13 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = ( - Tip_50ul_96COREHead1000ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.4, - 50.0: 52.1, - 30.0: 31.5, - 0.0: 0.0, - 1.0: 0.7, - 10.0: 10.8, - }, +star_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = \ +Tip_50ul_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.4, 50.0: 52.1, 30.0: 31.5, 0.0: 0.0, 1.0: 0.7, 10.0: 10.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -14553,13 +11235,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, False, Liquid.WATER, True, True)] = ( - Tip_50ul_96COREHead1000ul_Water_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ +Tip_50ul_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 52.8, 0.0: 0.0, 30.0: 33.2, 20.0: 22.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -14577,21 +11258,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, False, Liquid.WATER, False, True)] = ( - Tip_50ul_96COREHead1000ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.8, - 50.0: 53.6, - 30.0: 32.6, - 0.0: 0.0, - 1.0: 0.8, - 10.0: 11.3, - }, +star_mapping[(50, True, True, False, Liquid.WATER, False, True)] = \ +Tip_50ul_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.8, 50.0: 53.6, 30.0: 32.6, 0.0: 0.0, 1.0: 0.8, 10.0: 11.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -14608,13 +11281,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=3.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = ( - Tip_50ul_96COREHead_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ +Tip_50ul_96COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 51.4, 30.0: 31.3, 0.0: 0.0, 20.0: 21.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -14632,21 +11304,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = ( - Tip_50ul_96COREHead_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.6, - 50.0: 52.1, - 30.0: 31.6, - 0.0: 0.0, - 1.0: 0.8, - 10.0: 11.0, - }, +star_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = \ +Tip_50ul_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.6, 50.0: 52.1, 30.0: 31.6, 0.0: 0.0, 1.0: 0.8, 10.0: 11.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -14663,13 +11327,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, False, Liquid.WATER, True, True)] = ( - Tip_50ul_96COREHead_Water_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ +Tip_50ul_96COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 54.1, 0.0: 0.0, 30.0: 33.0, 20.0: 22.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -14687,21 +11350,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, True, True, False, Liquid.WATER, False, True)] = ( - Tip_50ul_96COREHead_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.6, - 50.0: 53.6, - 30.0: 32.9, - 0.0: 0.0, - 1.0: 0.7, - 10.0: 11.4, - }, +star_mapping[(50, True, True, False, Liquid.WATER, False, True)] = \ +Tip_50ul_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.6, 50.0: 53.6, 30.0: 32.9, 0.0: 0.0, 1.0: 0.7, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -14718,22 +11373,14 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # Liquid class for wash 50ul tips with CO-RE 96 Head in CO-RE 96 Head Washer. -star_mapping[(50, True, True, False, Liquid.WATER, False, False)] = ( - Tip_50ul_Core96Washer_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 5.7, - 50.0: 54.2, - 30.0: 33.2, - 0.0: 0.0, - 1.0: 0.5, - 10.0: 11.4, - }, +star_mapping[(50, True, True, False, Liquid.WATER, False, False)] = \ +Tip_50ul_Core96Washer_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 5.7, 50.0: 54.2, 30.0: 33.2, 0.0: 0.0, 1.0: 0.5, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -14750,13 +11397,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, False, Liquid.DMSO, True, True)] = ( - Tip_50ul_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.DMSO, True, True)] = \ +Tip_50ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 52.5, 30.0: 32.2, 0.0: 0.0, 20.0: 21.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -14774,21 +11420,13 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, False, Liquid.DMSO, False, True)] = ( - Tip_50ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.6, - 50.0: 52.6, - 30.0: 32.1, - 0.0: 0.0, - 1.0: 0.7, - 10.0: 11.0, - }, +star_mapping[(50, False, True, False, Liquid.DMSO, False, True)] = \ +Tip_50ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.6, 50.0: 52.6, 30.0: 32.1, 0.0: 0.0, 1.0: 0.7, 10.0: 11.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -14805,13 +11443,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, False, Liquid.ETHANOL, True, True)] = ( - Tip_50ul_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.ETHANOL, True, True)] = \ +Tip_50ul_EtOH_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 58.4, 0.0: 0.0, 30.0: 36.0, 20.0: 24.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -14829,21 +11466,13 @@ def get_star_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, False, Liquid.ETHANOL, False, True)] = ( - Tip_50ul_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 6.7, - 50.0: 54.1, - 0.0: 0.0, - 30.0: 33.7, - 1.0: 2.1, - 10.0: 12.1, - }, +star_mapping[(50, False, True, False, Liquid.ETHANOL, False, True)] = \ +Tip_50ul_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 6.7, 50.0: 54.1, 0.0: 0.0, 30.0: 33.7, 1.0: 2.1, 10.0: 12.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=2.0, @@ -14860,21 +11489,13 @@ def get_star_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, False, Liquid.GLYCERIN80, False, True)] = ( - Tip_50ul_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.7, - 50.0: 59.4, - 0.0: 0.0, - 30.0: 36.0, - 1.0: 0.3, - 10.0: 11.8, - }, +star_mapping[(50, False, True, False, Liquid.GLYCERIN80, False, True)] = \ +Tip_50ul_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.7, 50.0: 59.4, 0.0: 0.0, 30.0: 36.0, 1.0: 0.3, 10.0: 11.8}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -14891,13 +11512,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, False, Liquid.SERUM, True, True)] = ( - Tip_50ul_Serum_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.SERUM, True, True)] = \ +Tip_50ul_Serum_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 54.6, 30.0: 33.5, 0.0: 0.0, 20.0: 22.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -14915,21 +11535,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, False, Liquid.SERUM, False, True)] = ( - Tip_50ul_Serum_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.7, - 50.0: 54.9, - 30.0: 33.0, - 0.0: 0.0, - 1.0: 0.7, - 10.0: 11.3, - }, +star_mapping[(50, False, True, False, Liquid.SERUM, False, True)] = \ +Tip_50ul_Serum_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.7, 50.0: 54.9, 30.0: 33.0, 0.0: 0.0, 1.0: 0.7, 10.0: 11.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -14946,13 +11558,12 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, False, Liquid.WATER, True, True)] = ( - Tip_50ul_Water_DispenseJet_Empty -) = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.WATER, True, True)] = \ +Tip_50ul_Water_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 54.0, 30.0: 33.5, 0.0: 0.0, 20.0: 22.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -14970,21 +11581,13 @@ def get_star_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -star_mapping[(50, False, True, False, Liquid.WATER, False, True)] = ( - Tip_50ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.7, - 50.0: 54.2, - 30.0: 33.2, - 0.0: 0.0, - 1.0: 0.7, - 10.0: 11.4, - }, +star_mapping[(50, False, True, False, Liquid.WATER, False, True)] = \ +Tip_50ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.7, 50.0: 54.2, 30.0: 33.2, 0.0: 0.0, 1.0: 0.7, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -15001,5 +11604,5 @@ def get_star_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) diff --git a/pylabrobot/liquid_handling/liquid_classes/hamilton/vantage.py b/pylabrobot/liquid_handling/liquid_classes/hamilton/vantage.py index fce7d72a7a..6d0dd1926c 100644 --- a/pylabrobot/liquid_handling/liquid_classes/hamilton/vantage.py +++ b/pylabrobot/liquid_handling/liquid_classes/hamilton/vantage.py @@ -1,72 +1,19 @@ -from typing import Dict, Optional, Tuple +# pylint: skip-file + +from typing import Dict, Tuple -from pylabrobot.liquid_handling.liquid_classes.hamilton.base import ( - HamiltonLiquidClass, -) from pylabrobot.resources.liquid import Liquid +from pylabrobot.liquid_handling.liquid_classes.hamilton.base import HamiltonLiquidClass + + +vantage_mapping: Dict[Tuple[int, bool, bool, bool, Liquid, bool, bool], HamiltonLiquidClass] = {} + +def get_vantage_liquid_class(**kwargs): + raise NotImplementedError("deprecated") -vantage_mapping: Dict[ - Tuple[int, bool, bool, bool, Liquid, bool, bool], - HamiltonLiquidClass, -] = {} - - -def get_vantage_liquid_class( - tip_volume: float, - is_core: bool, - is_tip: bool, - has_filter: bool, - liquid: Liquid, - jet: bool, - blow_out: bool, -) -> Optional[HamiltonLiquidClass]: - """Get the Hamilton Vantage liquid class for the given parameters. - - Args: - tip_volume: The volume of the tip in microliters. - is_core: Whether the tip is a core tip. - is_tip: Whether the tip is a tip tip or a needle. - has_filter: Whether the tip has a filter. - liquid: The liquid to be dispensed. - jet: Whether the liquid is dispensed using a jet. - blow_out: This is called "empty" in the Hamilton Liquid editor and liquid class names, but - "blow out" in the firmware documentation. "Empty" in the firmware documentation means fully - emptying the tip, which is the terminology PyLabRobot adopts. Blow_out is the opposite of - partial dispense. - """ - - # Tip volumes from resources (mostly where they have filters) are slightly different form the ones - # in the liquid class mapping, so we need to map them here. If no mapping is found, we use the - # given maximal volume of the tip. - tip_volume = int( - { - 360.0: 300.0, - 1065.0: 1000.0, - 1250.0: 1000.0, - 4367.0: 4000.0, - 5420.0: 5000.0, - }.get(tip_volume, tip_volume) - ) - - return vantage_mapping.get( - (tip_volume, is_core, is_tip, has_filter, liquid, jet, blow_out), - None, - ) - - -vantage_mapping[(1000, False, False, False, Liquid.WATER, True, True)] = ( - _1000ulNeedleCRWater_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 520.0, - 50.0: 61.2, - 0.0: 0.0, - 20.0: 22.5, - 100.0: 113.0, - 10.0: 11.1, - 200.0: 214.0, - 1000.0: 1032.0, - }, +vantage_mapping[(1000, False, False, False, Liquid.WATER, True, True)] = \ +_1000ulNeedleCRWater_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 520.0, 50.0: 61.2, 0.0: 0.0, 20.0: 22.5, 100.0: 113.0, 10.0: 11.1, 200.0: 214.0, 1000.0: 1032.0}, aspiration_flow_rate=500.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=0.0, @@ -83,21 +30,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = ( - _1000ulNeedleCRWater_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 520.0, - 50.0: 62.2, - 0.0: 0.0, - 20.0: 32.0, - 100.0: 115.5, - 1000.0: 1032.0, - }, +vantage_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = \ +_1000ulNeedleCRWater_DispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 520.0, 50.0: 62.2, 0.0: 0.0, 20.0: 32.0, 100.0: 115.5, 1000.0: 1032.0}, aspiration_flow_rate=500.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=0.0, @@ -114,21 +53,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # -vantage_mapping[(1000, False, False, False, Liquid.WATER, False, True)] = ( - _1000ulNeedleCRWater_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 50.0: 59.0, - 0.0: 0.0, - 20.0: 25.9, - 10.0: 12.9, - 1000.0: 1000.0, - }, +vantage_mapping[(1000, False, False, False, Liquid.WATER, False, True)] = \ +_1000ulNeedleCRWater_DispenseSurface_Empty = HamiltonLiquidClass( + curve={50.0: 59.0, 0.0: 0.0, 20.0: 25.9, 10.0: 12.9, 1000.0: 1000.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=1.0, @@ -145,21 +77,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # -vantage_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = ( - _1000ulNeedleCRWater_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 50.0: 55.0, - 0.0: 0.0, - 20.0: 25.9, - 10.0: 12.9, - 1000.0: 1000.0, - }, +vantage_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = \ +_1000ulNeedleCRWater_DispenseSurface_Part = HamiltonLiquidClass( + curve={50.0: 55.0, 0.0: 0.0, 20.0: 25.9, 10.0: 12.9, 1000.0: 1000.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=1.0, @@ -176,7 +101,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -194,18 +119,9 @@ def get_vantage_liquid_class( # 200 1.25 - 0.51 # 500 0.91 0.02 # 1000 0.66 - 0.46 -vantage_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = ( - _1000ulNeedle_Water_DispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 530.0, - 50.0: 56.0, - 0.0: 0.0, - 100.0: 110.0, - 20.0: 22.5, - 1000.0: 1055.0, - 200.0: 214.0, - }, +vantage_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = \ +_1000ulNeedle_Water_DispenseJet = HamiltonLiquidClass( + curve={500.0: 530.0, 50.0: 56.0, 0.0: 0.0, 100.0: 110.0, 20.0: 22.5, 1000.0: 1055.0, 200.0: 214.0}, aspiration_flow_rate=500.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=0.0, @@ -222,7 +138,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=0.4, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -241,9 +157,8 @@ def get_vantage_liquid_class( # 20 10.12 - 4.66 # 50 3.79 - 1.18 # -vantage_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = ( - _1000ulNeedle_Water_DispenseSurface -) = HamiltonLiquidClass( +vantage_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = \ +_1000ulNeedle_Water_DispenseSurface = HamiltonLiquidClass( curve={50.0: 59.0, 0.0: 0.0, 20.0: 25.9, 1000.0: 1000.0}, aspiration_flow_rate=500.0, aspiration_mix_flow_rate=500.0, @@ -261,21 +176,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=0.4, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, False, False, Liquid.WATER, False, True)] = ( - _10ulNeedleCRWater_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.7, - 0.5: 0.5, - 0.0: 0.0, - 1.0: 1.2, - 2.0: 2.4, - 10.0: 11.4, - }, +vantage_mapping[(10, False, False, False, Liquid.WATER, False, True)] = \ +_10ulNeedleCRWater_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.7, 0.5: 0.5, 0.0: 0.0, 1.0: 1.2, 2.0: 2.4, 10.0: 11.4}, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, aspiration_air_transport_volume=1.0, @@ -292,21 +199,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, False, False, Liquid.WATER, False, False)] = ( - _10ulNeedleCRWater_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 5.0: 5.7, - 0.5: 0.5, - 0.0: 0.0, - 1.0: 1.2, - 2.0: 2.4, - 10.0: 11.4, - }, +vantage_mapping[(10, False, False, False, Liquid.WATER, False, False)] = \ +_10ulNeedleCRWater_DispenseSurface_Part = HamiltonLiquidClass( + curve={5.0: 5.7, 0.5: 0.5, 0.0: 0.0, 1.0: 1.2, 2.0: 2.4, 10.0: 11.4}, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, aspiration_air_transport_volume=1.0, @@ -323,13 +222,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, True, Liquid.DMSO, True, False)] = ( - _150ul_Piercing_Tip_Filter_DMSO_DispenseJet_Aliquot -) = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.DMSO, True, False)] = \ +_150ul_Piercing_Tip_Filter_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( curve={150.0: 150.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=180.0, aspiration_mix_flow_rate=100.0, @@ -347,13 +245,12 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, True, Liquid.DMSO, True, True)] = ( - _150ul_Piercing_Tip_Filter_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.DMSO, True, True)] = \ +_150ul_Piercing_Tip_Filter_DMSO_DispenseJet_Empty = HamiltonLiquidClass( curve={150.0: 154.0, 50.0: 52.9, 0.0: 0.0, 20.0: 21.8}, aspiration_flow_rate=180.0, aspiration_mix_flow_rate=100.0, @@ -371,22 +268,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, True, Liquid.DMSO, False, True)] = ( - _150ul_Piercing_Tip_Filter_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 3.0: 4.5, - 5.0: 6.5, - 150.0: 155.0, - 50.0: 53.7, - 0.0: 0.0, - 10.0: 12.0, - 2.0: 3.0, - }, +vantage_mapping[(50, False, True, True, Liquid.DMSO, False, True)] = \ +_150ul_Piercing_Tip_Filter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={3.0: 4.5, 5.0: 6.5, 150.0: 155.0, 50.0: 53.7, 0.0: 0.0, 10.0: 12.0, 2.0: 3.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -403,7 +291,7 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -424,9 +312,8 @@ def get_vantage_liquid_class( # 100 1.67 -0.35 # 300 0.46 -0.61 # -vantage_mapping[(50, False, True, True, Liquid.ETHANOL, True, True)] = ( - _150ul_Piercing_Tip_Filter_Ethanol_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.ETHANOL, True, True)] = \ +_150ul_Piercing_Tip_Filter_Ethanol_DispenseJet_Empty = HamiltonLiquidClass( curve={150.0: 166.0, 50.0: 58.3, 0.0: 0.0, 20.0: 25.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=50.0, @@ -444,7 +331,7 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -466,18 +353,9 @@ def get_vantage_liquid_class( # 20 0.95 2.97 # 50 0.31 -0.10 # -vantage_mapping[(50, False, True, True, Liquid.ETHANOL, False, True)] = ( - _150ul_Piercing_Tip_Filter_Ethanol_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 3.0: 5.0, - 5.0: 7.6, - 150.0: 165.0, - 50.0: 56.9, - 0.0: 0.0, - 10.0: 13.2, - 2.0: 3.3, - }, +vantage_mapping[(50, False, True, True, Liquid.ETHANOL, False, True)] = \ +_150ul_Piercing_Tip_Filter_Ethanol_DispenseSurface_Empty = HamiltonLiquidClass( + curve={3.0: 5.0, 5.0: 7.6, 150.0: 165.0, 50.0: 56.9, 0.0: 0.0, 10.0: 13.2, 2.0: 3.3}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=7.0, @@ -494,7 +372,7 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -517,19 +395,9 @@ def get_vantage_liquid_class( # 300 1.08 -0.87 # # -vantage_mapping[(50, False, True, True, Liquid.GLYCERIN80, False, True)] = ( - _150ul_Piercing_Tip_Filter_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 3.0: 4.5, - 5.0: 7.2, - 150.0: 167.5, - 50.0: 60.0, - 0.0: 0.0, - 1.0: 2.7, - 10.0: 13.0, - 2.0: 2.5, - }, +vantage_mapping[(50, False, True, True, Liquid.GLYCERIN80, False, True)] = \ +_150ul_Piercing_Tip_Filter_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={3.0: 4.5, 5.0: 7.2, 150.0: 167.5, 50.0: 60.0, 0.0: 0.0, 1.0: 2.7, 10.0: 13.0, 2.0: 2.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -546,7 +414,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -566,9 +434,8 @@ def get_vantage_liquid_class( # 100 0.81 0.99 # 300 1.00 0.65 # -vantage_mapping[(50, False, True, True, Liquid.SERUM, True, True)] = ( - _150ul_Piercing_Tip_Filter_Serum_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.SERUM, True, True)] = \ +_150ul_Piercing_Tip_Filter_Serum_DispenseJet_Empty = HamiltonLiquidClass( curve={150.0: 162.0, 50.0: 55.9, 0.0: 0.0, 20.0: 23.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -586,7 +453,7 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -609,18 +476,9 @@ def get_vantage_liquid_class( # 50 1.39 -0.12 # # -vantage_mapping[(50, False, True, True, Liquid.SERUM, False, True)] = ( - _150ul_Piercing_Tip_Filter_Serum_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 3.0: 3.4, - 5.0: 5.9, - 150.0: 161.5, - 50.0: 56.2, - 0.0: 0.0, - 10.0: 11.6, - 2.0: 2.2, - }, +vantage_mapping[(50, False, True, True, Liquid.SERUM, False, True)] = \ +_150ul_Piercing_Tip_Filter_Serum_DispenseSurface_Empty = HamiltonLiquidClass( + curve={3.0: 3.4, 5.0: 5.9, 150.0: 161.5, 50.0: 56.2, 0.0: 0.0, 10.0: 11.6, 2.0: 2.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -637,13 +495,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, True, Liquid.WATER, True, False)] = ( - _150ul_Piercing_Tip_Filter_Water_DispenseJet_Aliquot -) = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.WATER, True, False)] = \ +_150ul_Piercing_Tip_Filter_Water_DispenseJet_Aliquot = HamiltonLiquidClass( curve={150.0: 150.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -661,23 +518,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -vantage_mapping[(50, False, True, True, Liquid.WATER, True, True)] = ( - _150ul_Piercing_Tip_Filter_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 6.6, - 150.0: 159.1, - 50.0: 55.0, - 0.0: 0.0, - 100.0: 107.0, - 1.0: 1.6, - 20.0: 22.9, - 10.0: 12.2, - }, +vantage_mapping[(50, False, True, True, Liquid.WATER, True, True)] = \ +_150ul_Piercing_Tip_Filter_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={5.0: 6.6, 150.0: 159.1, 50.0: 55.0, 0.0: 0.0, 100.0: 107.0, 1.0: 1.6, 20.0: 22.9, 10.0: 12.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -694,23 +541,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, True, Liquid.WATER, False, True)] = ( - _150ul_Piercing_Tip_Filter_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 3.0: 3.5, - 5.0: 6.5, - 150.0: 158.1, - 50.0: 54.5, - 0.0: 0.0, - 1.0: 1.6, - 10.0: 11.9, - 2.0: 2.8, - }, +vantage_mapping[(50, False, True, True, Liquid.WATER, False, True)] = \ +_150ul_Piercing_Tip_Filter_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={3.0: 3.5, 5.0: 6.5, 150.0: 158.1, 50.0: 54.5, 0.0: 0.0, 1.0: 1.6, 10.0: 11.9, 2.0: 2.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -727,13 +564,12 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, False, Liquid.DMSO, True, True)] = ( - _250ul_Piercing_Tip_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.DMSO, True, True)] = \ +_250ul_Piercing_Tip_DMSO_DispenseJet_Empty = HamiltonLiquidClass( curve={250.0: 255.5, 50.0: 52.9, 0.0: 0.0, 20.0: 21.8}, aspiration_flow_rate=180.0, aspiration_mix_flow_rate=100.0, @@ -751,22 +587,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, False, Liquid.DMSO, False, True)] = ( - _250ul_Piercing_Tip_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 3.0: 4.2, - 5.0: 6.5, - 250.0: 256.0, - 50.0: 53.7, - 0.0: 0.0, - 10.0: 12.0, - 2.0: 3.0, - }, +vantage_mapping[(50, False, True, False, Liquid.DMSO, False, True)] = \ +_250ul_Piercing_Tip_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={3.0: 4.2, 5.0: 6.5, 250.0: 256.0, 50.0: 53.7, 0.0: 0.0, 10.0: 12.0, 2.0: 3.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -783,7 +610,7 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -804,9 +631,8 @@ def get_vantage_liquid_class( # 100 1.67 -0.35 # 300 0.46 -0.61 # -vantage_mapping[(50, False, True, False, Liquid.ETHANOL, True, True)] = ( - _250ul_Piercing_Tip_Ethanol_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.ETHANOL, True, True)] = \ +_250ul_Piercing_Tip_Ethanol_DispenseJet_Empty = HamiltonLiquidClass( curve={250.0: 270.2, 50.0: 59.2, 0.0: 0.0, 20.0: 27.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=50.0, @@ -824,7 +650,7 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -846,17 +672,9 @@ def get_vantage_liquid_class( # 20 0.95 2.97 # 50 0.31 -0.10 # -vantage_mapping[(50, False, True, False, Liquid.ETHANOL, False, True)] = ( - _250ul_Piercing_Tip_Ethanol_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 3.0: 5.0, - 5.0: 9.6, - 250.0: 270.5, - 50.0: 58.0, - 0.0: 0.0, - 10.0: 14.8, - }, +vantage_mapping[(50, False, True, False, Liquid.ETHANOL, False, True)] = \ +_250ul_Piercing_Tip_Ethanol_DispenseSurface_Empty = HamiltonLiquidClass( + curve={3.0: 5.0, 5.0: 9.6, 250.0: 270.5, 50.0: 58.0, 0.0: 0.0, 10.0: 14.8}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=10.0, @@ -873,7 +691,7 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -896,18 +714,9 @@ def get_vantage_liquid_class( # 300 1.08 -0.87 # # -vantage_mapping[(50, False, True, False, Liquid.GLYCERIN80, False, True)] = ( - _250ul_Piercing_Tip_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 3.0: 4.5, - 5.0: 7.2, - 250.0: 289.0, - 50.0: 65.0, - 0.0: 0.0, - 1.0: 2.7, - 10.0: 13.9, - }, +vantage_mapping[(50, False, True, False, Liquid.GLYCERIN80, False, True)] = \ +_250ul_Piercing_Tip_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={3.0: 4.5, 5.0: 7.2, 250.0: 289.0, 50.0: 65.0, 0.0: 0.0, 1.0: 2.7, 10.0: 13.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -924,7 +733,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -944,9 +753,8 @@ def get_vantage_liquid_class( # 100 0.81 0.99 # 300 1.00 0.65 # -vantage_mapping[(50, False, True, False, Liquid.SERUM, True, True)] = ( - _250ul_Piercing_Tip_Serum_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.SERUM, True, True)] = \ +_250ul_Piercing_Tip_Serum_DispenseJet_Empty = HamiltonLiquidClass( curve={250.0: 265.0, 50.0: 56.4, 0.0: 0.0, 20.0: 23.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -964,7 +772,7 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -987,17 +795,9 @@ def get_vantage_liquid_class( # 50 1.39 -0.12 # # -vantage_mapping[(50, False, True, False, Liquid.SERUM, False, True)] = ( - _250ul_Piercing_Tip_Serum_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 3.0: 3.4, - 5.0: 5.9, - 250.0: 264.2, - 50.0: 56.2, - 0.0: 0.0, - 10.0: 11.6, - }, +vantage_mapping[(50, False, True, False, Liquid.SERUM, False, True)] = \ +_250ul_Piercing_Tip_Serum_DispenseSurface_Empty = HamiltonLiquidClass( + curve={3.0: 3.4, 5.0: 5.9, 250.0: 264.2, 50.0: 56.2, 0.0: 0.0, 10.0: 11.6}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -1014,23 +814,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, False, Liquid.WATER, True, True)] = ( - _250ul_Piercing_Tip_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 6.6, - 250.0: 260.0, - 50.0: 55.0, - 0.0: 0.0, - 100.0: 107.0, - 1.0: 1.6, - 20.0: 22.5, - 10.0: 12.2, - }, +vantage_mapping[(50, False, True, False, Liquid.WATER, True, True)] = \ +_250ul_Piercing_Tip_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={5.0: 6.6, 250.0: 260.0, 50.0: 55.0, 0.0: 0.0, 100.0: 107.0, 1.0: 1.6, 20.0: 22.5, 10.0: 12.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -1047,23 +837,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, False, Liquid.WATER, False, True)] = ( - _250ul_Piercing_Tip_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 3.0: 4.0, - 5.0: 6.5, - 250.0: 259.0, - 50.0: 55.1, - 0.0: 0.0, - 1.0: 1.6, - 10.0: 12.6, - 2.0: 2.8, - }, +vantage_mapping[(50, False, True, False, Liquid.WATER, False, True)] = \ +_250ul_Piercing_Tip_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={3.0: 4.0, 5.0: 6.5, 250.0: 259.0, 50.0: 55.1, 0.0: 0.0, 1.0: 1.6, 10.0: 12.6, 2.0: 2.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -1080,7 +860,7 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1101,17 +881,9 @@ def get_vantage_liquid_class( # 100 1.04 0.05 # 300 0.63 -0.07 # -vantage_mapping[(300, False, False, False, Liquid.ACETONITRIL80WATER20, True, False)] = ( - _300ulNeedleAcetonitril80Water20DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 310.0, - 50.0: 57.8, - 0.0: 0.0, - 100.0: 106.5, - 20.0: 26.8, - 10.0: 16.5, - }, +vantage_mapping[(300, False, False, False, Liquid.ACETONITRIL80WATER20, True, False)] = \ +_300ulNeedleAcetonitril80Water20DispenseJet = HamiltonLiquidClass( + curve={300.0: 310.0, 50.0: 57.8, 0.0: 0.0, 100.0: 106.5, 20.0: 26.8, 10.0: 16.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=15.0, @@ -1128,20 +900,13 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, False, False, Liquid.WATER, True, True)] = ( - _300ulNeedleCRWater_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.0, - 50.0: 53.5, - 0.0: 0.0, - 100.0: 104.0, - 20.0: 22.3, - }, +vantage_mapping[(300, False, False, False, Liquid.WATER, True, True)] = \ +_300ulNeedleCRWater_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 313.0, 50.0: 53.5, 0.0: 0.0, 100.0: 104.0, 20.0: 22.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -1158,20 +923,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, False, False, Liquid.WATER, True, False)] = ( - _300ulNeedleCRWater_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 313.0, - 50.0: 59.5, - 0.0: 0.0, - 100.0: 109.0, - 20.0: 29.3, - }, +vantage_mapping[(300, False, False, False, Liquid.WATER, True, False)] = \ +_300ulNeedleCRWater_DispenseJet_Part = HamiltonLiquidClass( + curve={300.0: 313.0, 50.0: 59.5, 0.0: 0.0, 100.0: 109.0, 20.0: 29.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -1188,25 +946,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, False, False, False, Liquid.WATER, False, True)] = ( - _300ulNeedleCRWater_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 308.4, - 5.0: 6.8, - 50.0: 52.3, - 0.0: 0.0, - 100.0: 102.9, - 20.0: 22.3, - 1.0: 2.3, - 200.0: 205.8, - 10.0: 11.7, - 2.0: 3.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, False, False, False, Liquid.WATER, False, True)] = \ +_300ulNeedleCRWater_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 308.4, 5.0: 6.8, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 2.3, 200.0: 205.8, 10.0: 11.7, 2.0: 3.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=1.0, @@ -1223,25 +969,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, False, False, False, Liquid.WATER, False, False)] = ( - _300ulNeedleCRWater_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 308.4, - 5.0: 6.8, - 50.0: 52.3, - 0.0: 0.0, - 100.0: 102.9, - 20.0: 22.3, - 1.0: 2.3, - 200.0: 205.8, - 10.0: 11.7, - 2.0: 3.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, False, False, False, Liquid.WATER, False, False)] = \ +_300ulNeedleCRWater_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 308.4, 5.0: 6.8, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 2.3, 200.0: 205.8, 10.0: 11.7, 2.0: 3.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=1.0, @@ -1258,7 +992,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1278,16 +1012,9 @@ def get_vantage_liquid_class( # 100 0.55 -0.01 # 300 0.71 0.39 # -vantage_mapping[(300, False, False, False, Liquid.DIMETHYLSULFOXID, True, False)] = ( - _300ulNeedleDMSODispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 317.0, - 50.0: 53.5, - 0.0: 0.0, - 100.0: 106.5, - 20.0: 21.3, - }, +vantage_mapping[(300, False, False, False, Liquid.DIMETHYLSULFOXID, True, False)] = \ +_300ulNeedleDMSODispenseJet = HamiltonLiquidClass( + curve={300.0: 317.0, 50.0: 53.5, 0.0: 0.0, 100.0: 106.5, 20.0: 21.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -1304,7 +1031,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1325,17 +1052,9 @@ def get_vantage_liquid_class( # 50 1.32 -1.05 # # -vantage_mapping[(300, False, False, False, Liquid.DIMETHYLSULFOXID, False, False)] = ( - _300ulNeedleDMSODispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 6.0, - 50.0: 52.3, - 0.0: 0.0, - 20.0: 22.3, - 10.0: 11.4, - 2.0: 2.5, - }, +vantage_mapping[(300, False, False, False, Liquid.DIMETHYLSULFOXID, False, False)] = \ +_300ulNeedleDMSODispenseSurface = HamiltonLiquidClass( + curve={5.0: 6.0, 50.0: 52.3, 0.0: 0.0, 20.0: 22.3, 10.0: 11.4, 2.0: 2.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=5.0, @@ -1352,7 +1071,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1373,16 +1092,9 @@ def get_vantage_liquid_class( # 100 1.67 -0.35 # 300 0.46 -0.61 # -vantage_mapping[(300, False, False, False, Liquid.ETHANOL, True, False)] = ( - _300ulNeedleEtOHDispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 317.0, - 50.0: 57.8, - 0.0: 0.0, - 100.0: 109.0, - 20.0: 25.3, - }, +vantage_mapping[(300, False, False, False, Liquid.ETHANOL, True, False)] = \ +_300ulNeedleEtOHDispenseJet = HamiltonLiquidClass( + curve={300.0: 317.0, 50.0: 57.8, 0.0: 0.0, 100.0: 109.0, 20.0: 25.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=15.0, @@ -1399,7 +1111,7 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1421,9 +1133,8 @@ def get_vantage_liquid_class( # 20 0.95 2.97 # 50 0.31 -0.10 # -vantage_mapping[(300, False, False, False, Liquid.ETHANOL, False, False)] = ( - _300ulNeedleEtOHDispenseSurface -) = HamiltonLiquidClass( +vantage_mapping[(300, False, False, False, Liquid.ETHANOL, False, False)] = \ +_300ulNeedleEtOHDispenseSurface = HamiltonLiquidClass( curve={5.0: 7.2, 50.0: 55.0, 0.0: 0.0, 20.0: 24.5, 10.0: 13.1}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -1441,7 +1152,7 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1464,20 +1175,9 @@ def get_vantage_liquid_class( # 300 1.08 -0.87 # # -vantage_mapping[(300, False, False, False, Liquid.GLYCERIN80, False, False)] = ( - _300ulNeedleGlycerin80DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 325.0, - 5.0: 8.0, - 50.0: 61.3, - 0.0: 0.0, - 100.0: 117.0, - 20.0: 26.0, - 1.0: 2.7, - 10.0: 13.9, - 2.0: 4.2, - }, +vantage_mapping[(300, False, False, False, Liquid.GLYCERIN80, False, False)] = \ +_300ulNeedleGlycerin80DispenseSurface = HamiltonLiquidClass( + curve={300.0: 325.0, 5.0: 8.0, 50.0: 61.3, 0.0: 0.0, 100.0: 117.0, 20.0: 26.0, 1.0: 2.7, 10.0: 13.9, 2.0: 4.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=5.0, @@ -1494,7 +1194,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1514,16 +1214,9 @@ def get_vantage_liquid_class( # 100 0.81 0.99 # 300 1.00 0.65 # -vantage_mapping[(300, False, False, False, Liquid.SERUM, True, False)] = ( - _300ulNeedleSerumDispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 313.0, - 50.0: 53.5, - 0.0: 0.0, - 100.0: 105.0, - 20.0: 21.3, - }, +vantage_mapping[(300, False, False, False, Liquid.SERUM, True, False)] = \ +_300ulNeedleSerumDispenseJet = HamiltonLiquidClass( + curve={300.0: 313.0, 50.0: 53.5, 0.0: 0.0, 100.0: 105.0, 20.0: 21.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -1540,7 +1233,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1563,18 +1256,9 @@ def get_vantage_liquid_class( # 50 1.39 -0.12 # # -vantage_mapping[(300, False, False, False, Liquid.SERUM, False, False)] = ( - _300ulNeedleSerumDispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 6.0, - 50.0: 52.3, - 0.0: 0.0, - 20.0: 22.3, - 1.0: 2.2, - 10.0: 11.9, - 2.0: 3.2, - }, +vantage_mapping[(300, False, False, False, Liquid.SERUM, False, False)] = \ +_300ulNeedleSerumDispenseSurface = HamiltonLiquidClass( + curve={5.0: 6.0, 50.0: 52.3, 0.0: 0.0, 20.0: 22.3, 1.0: 2.2, 10.0: 11.9, 2.0: 3.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -1591,7 +1275,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1611,16 +1295,9 @@ def get_vantage_liquid_class( # 100 0.81 0.99 # 300 1.00 0.65 # -vantage_mapping[(300, False, False, False, Liquid.SERUM, True, False)] = ( - _300ulNeedle_Serum_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 313.0, - 50.0: 53.5, - 0.0: 0.0, - 100.0: 105.0, - 20.0: 21.3, - }, +vantage_mapping[(300, False, False, False, Liquid.SERUM, True, False)] = \ +_300ulNeedle_Serum_DispenseJet = HamiltonLiquidClass( + curve={300.0: 313.0, 50.0: 53.5, 0.0: 0.0, 100.0: 105.0, 20.0: 21.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -1637,7 +1314,7 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1660,19 +1337,9 @@ def get_vantage_liquid_class( # 50 1.39 -0.12 # # -vantage_mapping[(300, False, False, False, Liquid.SERUM, False, False)] = ( - _300ulNeedle_Serum_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 350.0, - 5.0: 6.0, - 50.0: 52.3, - 0.0: 0.0, - 20.0: 22.3, - 1.0: 2.2, - 10.0: 11.9, - 2.0: 3.2, - }, +vantage_mapping[(300, False, False, False, Liquid.SERUM, False, False)] = \ +_300ulNeedle_Serum_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 350.0, 5.0: 6.0, 50.0: 52.3, 0.0: 0.0, 20.0: 22.3, 1.0: 2.2, 10.0: 11.9, 2.0: 3.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -1689,7 +1356,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1710,16 +1377,9 @@ def get_vantage_liquid_class( # 200 0.16 0.55 # 300 0.17 0.35 # -vantage_mapping[(300, False, False, False, Liquid.WATER, True, False)] = ( - _300ulNeedle_Water_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 313.0, - 50.0: 53.5, - 0.0: 0.0, - 100.0: 105.0, - 20.0: 22.3, - }, +vantage_mapping[(300, False, False, False, Liquid.WATER, True, False)] = \ +_300ulNeedle_Water_DispenseJet = HamiltonLiquidClass( + curve={300.0: 313.0, 50.0: 53.5, 0.0: 0.0, 100.0: 105.0, 20.0: 22.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -1736,7 +1396,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -1758,21 +1418,9 @@ def get_vantage_liquid_class( # 20 0.63 0.73 # # -vantage_mapping[(300, False, False, False, Liquid.WATER, False, False)] = ( - _300ulNeedle_Water_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 308.4, - 5.0: 6.5, - 50.0: 52.3, - 0.0: 0.0, - 100.0: 102.9, - 20.0: 22.3, - 1.0: 1.1, - 200.0: 205.8, - 10.0: 12.0, - 2.0: 2.1, - }, +vantage_mapping[(300, False, False, False, Liquid.WATER, False, False)] = \ +_300ulNeedle_Water_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 308.4, 5.0: 6.5, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 1.1, 200.0: 205.8, 10.0: 12.0, 2.0: 2.1}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -1789,22 +1437,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=0.4, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # Evaluation -vantage_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = ( - _300ul_RocketTip_384COREHead_DMSO_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 150.0: 150.0, - 50.0: 50.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - }, +vantage_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ +_300ul_RocketTip_384COREHead_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 150.0: 150.0, 50.0: 50.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -1821,21 +1461,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=120.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # Evaluation -vantage_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = ( - _300ul_RocketTip_384COREHead_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 303.5, - 0.0: 0.0, - 100.0: 105.8, - 200.0: 209.5, - 10.0: 11.4, - }, +vantage_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ +_300ul_RocketTip_384COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 303.5, 0.0: 0.0, 100.0: 105.8, 200.0: 209.5, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -1852,21 +1485,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # Evaluation -vantage_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = ( - _300ul_RocketTip_384COREHead_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 308.0, - 0.0: 0.0, - 100.0: 105.5, - 200.0: 209.0, - 10.0: 12.0, - }, +vantage_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ +_300ul_RocketTip_384COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 308.0, 0.0: 0.0, 100.0: 105.5, 200.0: 209.0, 10.0: 12.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -1883,21 +1509,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # Evaluation -vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( - _300ul_RocketTip_384COREHead_Water_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 309.0, - 0.0: 0.0, - 100.0: 106.5, - 20.0: 22.3, - 200.0: 207.0, - }, +vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ +_300ul_RocketTip_384COREHead_Water_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 309.0, 0.0: 0.0, 100.0: 106.5, 20.0: 22.3, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -1914,21 +1533,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=20.0, + dispense_stop_back_volume=20.0 ) # Evaluation -vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( - _300ul_RocketTip_384COREHead_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 309.0, - 0.0: 0.0, - 100.0: 106.5, - 20.0: 22.3, - 200.0: 207.0, - }, +vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ +_300ul_RocketTip_384COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 309.0, 0.0: 0.0, 100.0: 106.5, 20.0: 22.3, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -1945,21 +1557,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # Evaluation -vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( - _300ul_RocketTip_384COREHead_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 314.3, - 0.0: 0.0, - 100.0: 109.0, - 200.0: 214.7, - 10.0: 12.7, - }, +vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ +_300ul_RocketTip_384COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 314.3, 0.0: 0.0, 100.0: 109.0, 200.0: 214.7, 10.0: 12.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -1976,13 +1581,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(30, True, True, False, Liquid.DMSO, True, True)] = ( - _30ulTip_384COREHead_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(30, True, True, False, Liquid.DMSO, True, True)] = \ +_30ulTip_384COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( curve={5.0: 5.0, 15.0: 15.3, 30.0: 30.7, 0.0: 0.0, 1.0: 1.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2000,13 +1604,12 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(30, True, True, False, Liquid.DMSO, False, True)] = ( - _30ulTip_384COREHead_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( +vantage_mapping[(30, True, True, False, Liquid.DMSO, False, True)] = \ +_30ulTip_384COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 4.9, 15.0: 15.1, 30.0: 30.0, 0.0: 0.0, 1.0: 0.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2024,13 +1627,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(30, True, True, False, Liquid.ETHANOL, True, True)] = ( - _30ulTip_384COREHead_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(30, True, True, False, Liquid.ETHANOL, True, True)] = \ +_30ulTip_384COREHead_EtOH_DispenseJet_Empty = HamiltonLiquidClass( curve={5.0: 6.54, 15.0: 18.36, 30.0: 33.8, 0.0: 0.0, 1.0: 1.8}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2048,13 +1650,12 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(30, True, True, False, Liquid.ETHANOL, False, True)] = ( - _30ulTip_384COREHead_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( +vantage_mapping[(30, True, True, False, Liquid.ETHANOL, False, True)] = \ +_30ulTip_384COREHead_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 6.2, 15.0: 16.9, 30.0: 33.1, 0.0: 0.0, 1.0: 1.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2072,23 +1673,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(30, True, True, False, Liquid.GLYCERIN80, False, True)] = ( - _30ulTip_384COREHead_Glyzerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 6.3, - 0.5: 0.9, - 40.0: 44.0, - 0.0: 0.0, - 20.0: 22.2, - 1.0: 1.6, - 10.0: 11.9, - 2.0: 2.8, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(30, True, True, False, Liquid.GLYCERIN80, False, True)] = \ +_30ulTip_384COREHead_Glyzerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 6.3, 0.5: 0.9, 40.0: 44.0, 0.0: 0.0, 20.0: 22.2, 1.0: 1.6, 10.0: 11.9, 2.0: 2.8}, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -2105,13 +1696,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(30, True, True, False, Liquid.WATER, True, True)] = ( - _30ulTip_384COREHead_Water_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(30, True, True, False, Liquid.WATER, True, True)] = \ +_30ulTip_384COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( curve={5.0: 6.0, 15.0: 16.5, 30.0: 32.3, 0.0: 0.0, 1.0: 1.6}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2129,13 +1719,12 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(30, True, True, False, Liquid.WATER, False, True)] = ( - _30ulTip_384COREHead_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( +vantage_mapping[(30, True, True, False, Liquid.WATER, False, True)] = \ +_30ulTip_384COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 5.6, 15.0: 15.9, 30.0: 31.3, 0.0: 0.0, 1.0: 1.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2153,23 +1742,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(30, True, True, False, Liquid.WATER, False, False)] = ( - _30ulTip_384COREWasher_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 6.3, - 0.5: 0.9, - 40.0: 44.0, - 0.0: 0.0, - 1.0: 1.6, - 20.0: 22.2, - 2.0: 2.8, - 10.0: 11.9, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(30, True, True, False, Liquid.WATER, False, False)] = \ +_30ulTip_384COREWasher_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 6.3, 0.5: 0.9, 40.0: 44.0, 0.0: 0.0, 1.0: 1.6, 20.0: 22.2, 2.0: 2.8, 10.0: 11.9}, aspiration_flow_rate=10.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=0.0, @@ -2186,25 +1765,13 @@ def get_vantage_liquid_class( dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(4000, False, True, False, Liquid.DMSO, True, False)] = ( - _4mlTF_DMSO_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 3500.0: 3715.0, - 500.0: 631.0, - 2500.0: 2691.0, - 1500.0: 1667.0, - 4000.0: 4224.0, - 3000.0: 3202.0, - 0.0: 0.0, - 2000.0: 2179.0, - 100.0: 211.0, - 1000.0: 1151.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(4000, False, True, False, Liquid.DMSO, True, False)] = \ +_4mlTF_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={3500.0: 3715.0, 500.0: 631.0, 2500.0: 2691.0, 1500.0: 1667.0, 4000.0: 4224.0, 3000.0: 3202.0, 0.0: 0.0, 2000.0: 2179.0, 100.0: 211.0, 1000.0: 1151.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2221,23 +1788,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=20.0, -) - - -vantage_mapping[(4000, False, True, False, Liquid.DMSO, True, True)] = ( - _4mlTF_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 540.0, - 50.0: 61.5, - 4000.0: 4102.0, - 3000.0: 3083.0, - 0.0: 0.0, - 2000.0: 2070.0, - 100.0: 116.5, - 1000.0: 1060.0, - }, + dispense_stop_back_volume=20.0 +) + + +vantage_mapping[(4000, False, True, False, Liquid.DMSO, True, True)] = \ +_4mlTF_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 540.0, 50.0: 61.5, 4000.0: 4102.0, 3000.0: 3083.0, 0.0: 0.0, 2000.0: 2070.0, 100.0: 116.5, 1000.0: 1060.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2254,24 +1811,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(4000, False, True, False, Liquid.DMSO, False, True)] = ( - _4mlTF_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 536.5, - 50.0: 62.3, - 4000.0: 4128.0, - 3000.0: 3109.0, - 0.0: 0.0, - 2000.0: 2069.0, - 100.0: 116.6, - 1000.0: 1054.0, - 10.0: 15.5, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(4000, False, True, False, Liquid.DMSO, False, True)] = \ +_4mlTF_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 536.5, 50.0: 62.3, 4000.0: 4128.0, 3000.0: 3109.0, 0.0: 0.0, 2000.0: 2069.0, 100.0: 116.6, 1000.0: 1054.0, 10.0: 15.5}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2288,27 +1834,14 @@ def get_vantage_liquid_class( dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=500.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # First two times mixing with max volume. -vantage_mapping[(4000, False, True, False, Liquid.ETHANOL, True, False)] = ( - _4mlTF_EtOH_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 3500.0: 3500.0, - 500.0: 500.0, - 2500.0: 2500.0, - 1500.0: 1500.0, - 4000.0: 4000.0, - 3000.0: 3000.0, - 0.0: 0.0, - 2000.0: 2000.0, - 100.0: 100.0, - 1000.0: 1000.0, - }, +vantage_mapping[(4000, False, True, False, Liquid.ETHANOL, True, False)] = \ +_4mlTF_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 3500.0: 3500.0, 500.0: 500.0, 2500.0: 2500.0, 1500.0: 1500.0, 4000.0: 4000.0, 3000.0: 3000.0, 0.0: 0.0, 2000.0: 2000.0, 100.0: 100.0, 1000.0: 1000.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=2000.0, aspiration_air_transport_volume=0.0, @@ -2325,23 +1858,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(4000, False, True, False, Liquid.ETHANOL, True, True)] = ( - _4mlTF_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 563.0, - 50.0: 72.0, - 4000.0: 4215.0, - 3000.0: 3190.0, - 0.0: 0.0, - 2000.0: 2178.0, - 100.0: 127.5, - 1000.0: 1095.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(4000, False, True, False, Liquid.ETHANOL, True, True)] = \ +_4mlTF_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 563.0, 50.0: 72.0, 4000.0: 4215.0, 3000.0: 3190.0, 0.0: 0.0, 2000.0: 2178.0, 100.0: 127.5, 1000.0: 1095.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=30.0, @@ -2358,24 +1881,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=30.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(4000, False, True, False, Liquid.ETHANOL, False, True)] = ( - _4mlTF_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 555.0, - 50.0: 68.0, - 4000.0: 4177.0, - 3000.0: 3174.0, - 0.0: 0.0, - 2000.0: 2151.0, - 100.0: 123.5, - 1000.0: 1085.0, - 10.0: 18.6, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(4000, False, True, False, Liquid.ETHANOL, False, True)] = \ +_4mlTF_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 555.0, 50.0: 68.0, 4000.0: 4177.0, 3000.0: 3174.0, 0.0: 0.0, 2000.0: 2151.0, 100.0: 123.5, 1000.0: 1085.0, 10.0: 18.6}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=30.0, @@ -2392,23 +1904,13 @@ def get_vantage_liquid_class( dispense_swap_speed=30.0, dispense_settling_time=1.0, dispense_stop_flow_rate=30.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(4000, False, True, False, Liquid.GLYCERIN80, True, True)] = ( - _4mlTF_Glycerin80_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 599.0, - 50.0: 89.0, - 4000.0: 4223.0, - 3000.0: 3211.0, - 0.0: 0.0, - 2000.0: 2195.0, - 100.0: 140.0, - 1000.0: 1159.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(4000, False, True, False, Liquid.GLYCERIN80, True, True)] = \ +_4mlTF_Glycerin80_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 599.0, 50.0: 89.0, 4000.0: 4223.0, 3000.0: 3211.0, 0.0: 0.0, 2000.0: 2195.0, 100.0: 140.0, 1000.0: 1159.0}, aspiration_flow_rate=1200.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=30.0, @@ -2425,24 +1927,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(4000, False, True, False, Liquid.GLYCERIN80, False, True)] = ( - _4mlTF_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 555.0, - 50.0: 71.0, - 4000.0: 4135.0, - 3000.0: 3122.0, - 0.0: 0.0, - 2000.0: 2101.0, - 100.0: 129.0, - 1000.0: 1083.0, - 10.0: 16.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(4000, False, True, False, Liquid.GLYCERIN80, False, True)] = \ +_4mlTF_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 555.0, 50.0: 71.0, 4000.0: 4135.0, 3000.0: 3122.0, 0.0: 0.0, 2000.0: 2101.0, 100.0: 129.0, 1000.0: 1083.0, 10.0: 16.0}, aspiration_flow_rate=1000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=0.0, @@ -2459,21 +1950,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(4000, False, True, False, Liquid.WATER, True, False)] = ( - _4mlTF_Water_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 4000.0: 4160.0, - 3000.0: 3160.0, - 0.0: 0.0, - 2000.0: 2160.0, - 100.0: 214.0, - 1000.0: 1148.0, - }, +vantage_mapping[(4000, False, True, False, Liquid.WATER, True, False)] = \ +_4mlTF_Water_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={4000.0: 4160.0, 3000.0: 3160.0, 0.0: 0.0, 2000.0: 2160.0, 100.0: 214.0, 1000.0: 1148.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2490,23 +1973,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=20.0, -) - - -vantage_mapping[(4000, False, True, False, Liquid.WATER, True, True)] = ( - _4mlTF_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 551.8, - 50.0: 66.4, - 4000.0: 4165.0, - 3000.0: 3148.0, - 0.0: 0.0, - 2000.0: 2128.0, - 100.0: 122.7, - 1000.0: 1082.0, - }, + dispense_stop_back_volume=20.0 +) + + +vantage_mapping[(4000, False, True, False, Liquid.WATER, True, True)] = \ +_4mlTF_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 551.8, 50.0: 66.4, 4000.0: 4165.0, 3000.0: 3148.0, 0.0: 0.0, 2000.0: 2128.0, 100.0: 122.7, 1000.0: 1082.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2523,24 +1996,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(4000, False, True, False, Liquid.WATER, False, True)] = ( - _4mlTF_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 547.0, - 50.0: 65.5, - 4000.0: 4145.0, - 3000.0: 3135.0, - 0.0: 0.0, - 2000.0: 2125.0, - 100.0: 120.9, - 1000.0: 1075.0, - 10.0: 14.5, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(4000, False, True, False, Liquid.WATER, False, True)] = \ +_4mlTF_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 547.0, 50.0: 65.5, 4000.0: 4145.0, 3000.0: 3135.0, 0.0: 0.0, 2000.0: 2125.0, 100.0: 120.9, 1000.0: 1075.0, 10.0: 14.5}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2557,13 +2019,12 @@ def get_vantage_liquid_class( dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=500.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = ( - _50ulTip_384COREHead_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ +_50ulTip_384COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 52.0, 0.0: 0.0, 20.0: 21.1, 10.0: 10.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2581,21 +2042,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = ( - _50ulTip_384COREHead_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.0, - 50.0: 51.1, - 30.0: 30.7, - 0.0: 0.0, - 1.0: 0.9, - 10.0: 10.1, - }, +vantage_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = \ +_50ulTip_384COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.0, 50.0: 51.1, 30.0: 30.7, 0.0: 0.0, 1.0: 0.9, 10.0: 10.1}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -2612,21 +2065,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = ( - _50ulTip_384COREHead_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 6.54, - 15.0: 18.36, - 50.0: 53.0, - 30.0: 33.8, - 0.0: 0.0, - 1.0: 1.8, - }, +vantage_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = \ +_50ulTip_384COREHead_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={5.0: 6.54, 15.0: 18.36, 50.0: 53.0, 30.0: 33.8, 0.0: 0.0, 1.0: 1.8}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=1.0, @@ -2643,22 +2088,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(50, True, True, False, Liquid.ETHANOL, False, True)] = ( - _50ulTip_384COREHead_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 6.2, - 15.0: 16.9, - 0.5: 1.0, - 50.0: 54.0, - 30.0: 33.1, - 0.0: 0.0, - 1.0: 1.5, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(50, True, True, False, Liquid.ETHANOL, False, True)] = \ +_50ulTip_384COREHead_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 6.2, 15.0: 16.9, 0.5: 1.0, 50.0: 54.0, 30.0: 33.1, 0.0: 0.0, 1.0: 1.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=2.0, @@ -2675,22 +2111,13 @@ def get_vantage_liquid_class( dispense_swap_speed=6.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(50, True, True, False, Liquid.GLYCERIN80, False, True)] = ( - _50ulTip_384COREHead_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.6, - 0.5: 0.65, - 50.0: 55.0, - 0.0: 0.0, - 30.0: 31.5, - 1.0: 1.2, - 10.0: 10.9, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(50, True, True, False, Liquid.GLYCERIN80, False, True)] = \ +_50ulTip_384COREHead_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.6, 0.5: 0.65, 50.0: 55.0, 0.0: 0.0, 30.0: 31.5, 1.0: 1.2, 10.0: 10.9}, aspiration_flow_rate=30.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=0.0, @@ -2707,13 +2134,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, False, Liquid.WATER, True, True)] = ( - _50ulTip_384COREHead_Water_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ +_50ulTip_384COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 53.6, 0.0: 0.0, 20.0: 22.4, 10.0: 11.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2731,21 +2157,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, False, Liquid.WATER, False, True)] = ( - _50ulTip_384COREHead_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.5, - 50.0: 52.2, - 30.0: 31.5, - 0.0: 0.0, - 1.0: 1.2, - 10.0: 11.3, - }, +vantage_mapping[(50, True, True, False, Liquid.WATER, False, True)] = \ +_50ulTip_384COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.5, 50.0: 52.2, 30.0: 31.5, 0.0: 0.0, 1.0: 1.2, 10.0: 11.3}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -2762,24 +2180,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(50, True, True, False, Liquid.WATER, False, False)] = ( - _50ulTip_384COREWasher_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 6.3, - 0.5: 0.9, - 50.0: 55.0, - 40.0: 44.0, - 0.0: 0.0, - 20.0: 22.2, - 1.0: 1.6, - 10.0: 11.9, - 2.0: 2.8, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(50, True, True, False, Liquid.WATER, False, False)] = \ +_50ulTip_384COREWasher_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 6.3, 0.5: 0.9, 50.0: 55.0, 40.0: 44.0, 0.0: 0.0, 20.0: 22.2, 1.0: 1.6, 10.0: 11.9, 2.0: 2.8}, aspiration_flow_rate=20.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=0.0, @@ -2796,22 +2203,13 @@ def get_vantage_liquid_class( dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = ( - _50ulTip_conductive_384COREHead_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.2, - 50.0: 50.6, - 30.0: 30.4, - 0.0: 0.0, - 1.0: 0.9, - 20.0: 21.1, - 10.0: 9.3, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ +_50ulTip_conductive_384COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={5.0: 5.2, 50.0: 50.6, 30.0: 30.4, 0.0: 0.0, 1.0: 0.9, 20.0: 21.1, 10.0: 9.3}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -2828,22 +2226,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = ( - _50ulTip_conductive_384COREHead_DMSO_DispenseJet_Empty_below5ul -) = HamiltonLiquidClass( - curve={ - 5.0: 5.2, - 50.0: 50.6, - 30.0: 30.4, - 0.0: 0.0, - 1.0: 0.9, - 20.0: 21.1, - 10.0: 9.3, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ +_50ulTip_conductive_384COREHead_DMSO_DispenseJet_Empty_below5ul = HamiltonLiquidClass( + curve={5.0: 5.2, 50.0: 50.6, 30.0: 30.4, 0.0: 0.0, 1.0: 0.9, 20.0: 21.1, 10.0: 9.3}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -2860,13 +2249,12 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, False, Liquid.DMSO, True, False)] = ( - _50ulTip_conductive_384COREHead_DMSO_DispenseJet_Part -) = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.DMSO, True, False)] = \ +_50ulTip_conductive_384COREHead_DMSO_DispenseJet_Part = HamiltonLiquidClass( curve={50.0: 50.0, 0.0: 0.0, 10.0: 10.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2884,24 +2272,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=5.0, -) - - -vantage_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = ( - _50ulTip_conductive_384COREHead_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 0.1: 0.05, - 0.25: 0.1, - 5.0: 4.95, - 0.5: 0.22, - 50.0: 50.0, - 30.0: 30.6, - 0.0: 0.0, - 1.0: 0.74, - 10.0: 9.95, - }, + dispense_stop_back_volume=5.0 +) + + +vantage_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = \ +_50ulTip_conductive_384COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={0.1: 0.05, 0.25: 0.1, 5.0: 4.95, 0.5: 0.22, 50.0: 50.0, 30.0: 30.6, 0.0: 0.0, 1.0: 0.74, 10.0: 9.95}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -2918,22 +2295,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = ( - _50ulTip_conductive_384COREHead_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 6.85, - 15.0: 18.36, - 50.0: 54.3, - 30.0: 33.6, - 0.0: 0.0, - 1.0: 1.5, - 10.0: 12.1, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = \ +_50ulTip_conductive_384COREHead_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={5.0: 6.85, 15.0: 18.36, 50.0: 54.3, 30.0: 33.6, 0.0: 0.0, 1.0: 1.5, 10.0: 12.1}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=1.0, @@ -2950,22 +2318,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = ( - _50ulTip_conductive_384COREHead_EtOH_DispenseJet_Empty_below5ul -) = HamiltonLiquidClass( - curve={ - 5.0: 6.85, - 15.0: 18.36, - 50.0: 54.3, - 30.0: 33.6, - 0.0: 0.0, - 1.0: 1.5, - 10.0: 12.1, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = \ +_50ulTip_conductive_384COREHead_EtOH_DispenseJet_Empty_below5ul = HamiltonLiquidClass( + curve={5.0: 6.85, 15.0: 18.36, 50.0: 54.3, 30.0: 33.6, 0.0: 0.0, 1.0: 1.5, 10.0: 12.1}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=1.0, @@ -2982,13 +2341,12 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, False, Liquid.ETHANOL, True, False)] = ( - _50ulTip_conductive_384COREHead_EtOH_DispenseJet_Part -) = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.ETHANOL, True, False)] = \ +_50ulTip_conductive_384COREHead_EtOH_DispenseJet_Part = HamiltonLiquidClass( curve={50.0: 50.0, 0.0: 0.0, 10.0: 10.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -3006,24 +2364,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=2.0, -) - - -vantage_mapping[(50, True, True, False, Liquid.ETHANOL, False, True)] = ( - _50ulTip_conductive_384COREHead_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 0.25: 0.3, - 5.0: 6.1, - 0.5: 0.65, - 15.0: 16.9, - 50.0: 52.7, - 30.0: 32.1, - 0.0: 0.0, - 1.0: 1.35, - 10.0: 11.3, - }, + dispense_stop_back_volume=2.0 +) + + +vantage_mapping[(50, True, True, False, Liquid.ETHANOL, False, True)] = \ +_50ulTip_conductive_384COREHead_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={0.25: 0.3, 5.0: 6.1, 0.5: 0.65, 15.0: 16.9, 50.0: 52.7, 30.0: 32.1, 0.0: 0.0, 1.0: 1.35, 10.0: 11.3}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=2.0, @@ -3040,23 +2387,13 @@ def get_vantage_liquid_class( dispense_swap_speed=6.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(50, True, True, False, Liquid.GLYCERIN80, False, True)] = ( - _50ulTip_conductive_384COREHead_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 0.25: 0.05, - 5.0: 5.5, - 0.5: 0.3, - 50.0: 51.9, - 30.0: 31.8, - 0.0: 0.0, - 1.0: 1.0, - 10.0: 10.9, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(50, True, True, False, Liquid.GLYCERIN80, False, True)] = \ +_50ulTip_conductive_384COREHead_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={0.25: 0.05, 5.0: 5.5, 0.5: 0.3, 50.0: 51.9, 30.0: 31.8, 0.0: 0.0, 1.0: 1.0, 10.0: 10.9}, aspiration_flow_rate=30.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=0.0, @@ -3073,23 +2410,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(50, True, True, False, Liquid.WATER, True, True)] = ( - _50ulTip_conductive_384COREHead_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.67, - 0.5: 0.27, - 50.0: 51.9, - 30.0: 31.5, - 0.0: 0.0, - 1.0: 1.06, - 20.0: 20.0, - 10.0: 10.9, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ +_50ulTip_conductive_384COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={5.0: 5.67, 0.5: 0.27, 50.0: 51.9, 30.0: 31.5, 0.0: 0.0, 1.0: 1.06, 20.0: 20.0, 10.0: 10.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -3106,23 +2433,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(50, True, True, False, Liquid.WATER, True, True)] = ( - _50ulTip_conductive_384COREHead_Water_DispenseJet_Empty_below5ul -) = HamiltonLiquidClass( - curve={ - 5.0: 5.67, - 0.5: 0.27, - 50.0: 51.9, - 30.0: 31.5, - 0.0: 0.0, - 1.0: 1.06, - 20.0: 20.0, - 10.0: 10.9, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ +_50ulTip_conductive_384COREHead_Water_DispenseJet_Empty_below5ul = HamiltonLiquidClass( + curve={5.0: 5.67, 0.5: 0.27, 50.0: 51.9, 30.0: 31.5, 0.0: 0.0, 1.0: 1.06, 20.0: 20.0, 10.0: 10.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -3139,13 +2456,12 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, False, Liquid.WATER, True, False)] = ( - _50ulTip_conductive_384COREHead_Water_DispenseJet_Part -) = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.WATER, True, False)] = \ +_50ulTip_conductive_384COREHead_Water_DispenseJet_Part = HamiltonLiquidClass( curve={50.0: 50.0, 0.0: 0.0, 10.0: 10.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -3163,24 +2479,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=2.0, -) - - -vantage_mapping[(50, True, True, False, Liquid.WATER, False, True)] = ( - _50ulTip_conductive_384COREHead_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 0.1: 0.1, - 0.25: 0.15, - 5.0: 5.6, - 0.5: 0.45, - 50.0: 51.0, - 30.0: 31.0, - 0.0: 0.0, - 1.0: 0.98, - 10.0: 10.7, - }, + dispense_stop_back_volume=2.0 +) + + +vantage_mapping[(50, True, True, False, Liquid.WATER, False, True)] = \ +_50ulTip_conductive_384COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={0.1: 0.1, 0.25: 0.15, 5.0: 5.6, 0.5: 0.45, 50.0: 51.0, 30.0: 31.0, 0.0: 0.0, 1.0: 0.98, 10.0: 10.7}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -3197,25 +2502,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(50, True, True, False, Liquid.WATER, False, False)] = ( - _50ulTip_conductive_384COREWasher_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 6.3, - 0.5: 0.9, - 50.0: 55.0, - 40.0: 44.0, - 0.0: 0.0, - 1.0: 1.6, - 20.0: 22.2, - 65.0: 65.0, - 10.0: 11.9, - 2.0: 2.8, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(50, True, True, False, Liquid.WATER, False, False)] = \ +_50ulTip_conductive_384COREWasher_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 6.3, 0.5: 0.9, 50.0: 55.0, 40.0: 44.0, 0.0: 0.0, 1.0: 1.6, 20.0: 22.2, 65.0: 65.0, 10.0: 11.9, 2.0: 2.8}, aspiration_flow_rate=20.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=0.0, @@ -3232,27 +2525,13 @@ def get_vantage_liquid_class( dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(5000, False, True, False, Liquid.DMSO, True, False)] = ( - _5mlT_DMSO_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 4500.0: 4606.0, - 3500.0: 3591.0, - 500.0: 525.0, - 2500.0: 2576.0, - 1500.0: 1559.0, - 5000.0: 5114.0, - 4000.0: 4099.0, - 3000.0: 3083.0, - 0.0: 0.0, - 2000.0: 2068.0, - 100.0: 105.0, - 1000.0: 1044.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(5000, False, True, False, Liquid.DMSO, True, False)] = \ +_5mlT_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={4500.0: 4606.0, 3500.0: 3591.0, 500.0: 525.0, 2500.0: 2576.0, 1500.0: 1559.0, 5000.0: 5114.0, 4000.0: 4099.0, 3000.0: 3083.0, 0.0: 0.0, 2000.0: 2068.0, 100.0: 105.0, 1000.0: 1044.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=20.0, @@ -3269,24 +2548,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=20.0, -) - - -vantage_mapping[(5000, False, True, False, Liquid.DMSO, True, True)] = ( - _5mlT_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 540.0, - 50.0: 62.0, - 5000.0: 5095.0, - 4000.0: 4075.0, - 0.0: 0.0, - 3000.0: 3065.0, - 100.0: 117.0, - 2000.0: 2060.0, - 1000.0: 1060.0, - }, + dispense_stop_back_volume=20.0 +) + + +vantage_mapping[(5000, False, True, False, Liquid.DMSO, True, True)] = \ +_5mlT_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 540.0, 50.0: 62.0, 5000.0: 5095.0, 4000.0: 4075.0, 0.0: 0.0, 3000.0: 3065.0, 100.0: 117.0, 2000.0: 2060.0, 1000.0: 1060.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -3303,25 +2571,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(5000, False, True, False, Liquid.DMSO, False, True)] = ( - _5mlT_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 535.0, - 50.0: 60.3, - 5000.0: 5090.0, - 4000.0: 4078.0, - 0.0: 0.0, - 3000.0: 3066.0, - 100.0: 115.0, - 2000.0: 2057.0, - 10.0: 12.5, - 1000.0: 1054.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(5000, False, True, False, Liquid.DMSO, False, True)] = \ +_5mlT_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 535.0, 50.0: 60.3, 5000.0: 5090.0, 4000.0: 4078.0, 0.0: 0.0, 3000.0: 3066.0, 100.0: 115.0, 2000.0: 2057.0, 10.0: 12.5, 1000.0: 1054.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -3338,29 +2594,14 @@ def get_vantage_liquid_class( dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=500.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # First two times mixing with max volume. -vantage_mapping[(5000, False, True, False, Liquid.ETHANOL, True, False)] = ( - _5mlT_EtOH_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 312.0, - 4500.0: 4573.0, - 3500.0: 3560.0, - 500.0: 519.0, - 2500.0: 2551.0, - 1500.0: 1542.0, - 5000.0: 5081.0, - 4000.0: 4066.0, - 3000.0: 3056.0, - 0.0: 0.0, - 2000.0: 2047.0, - 100.0: 104.0, - 1000.0: 1033.0, - }, +vantage_mapping[(5000, False, True, False, Liquid.ETHANOL, True, False)] = \ +_5mlT_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 312.0, 4500.0: 4573.0, 3500.0: 3560.0, 500.0: 519.0, 2500.0: 2551.0, 1500.0: 1542.0, 5000.0: 5081.0, 4000.0: 4066.0, 3000.0: 3056.0, 0.0: 0.0, 2000.0: 2047.0, 100.0: 104.0, 1000.0: 1033.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=2000.0, aspiration_air_transport_volume=0.0, @@ -3377,24 +2618,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(5000, False, True, False, Liquid.ETHANOL, True, True)] = ( - _5mlT_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 563.0, - 50.0: 72.0, - 5000.0: 5230.0, - 4000.0: 4215.0, - 0.0: 0.0, - 3000.0: 3190.0, - 100.0: 129.5, - 2000.0: 2166.0, - 1000.0: 1095.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(5000, False, True, False, Liquid.ETHANOL, True, True)] = \ +_5mlT_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 563.0, 50.0: 72.0, 5000.0: 5230.0, 4000.0: 4215.0, 0.0: 0.0, 3000.0: 3190.0, 100.0: 129.5, 2000.0: 2166.0, 1000.0: 1095.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=30.0, @@ -3411,25 +2641,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=30.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(5000, False, True, False, Liquid.ETHANOL, False, True)] = ( - _5mlT_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 555.0, - 50.0: 68.0, - 5000.0: 5204.0, - 4000.0: 4200.0, - 0.0: 0.0, - 3000.0: 3180.0, - 100.0: 123.5, - 2000.0: 2160.0, - 10.0: 22.0, - 1000.0: 1085.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(5000, False, True, False, Liquid.ETHANOL, False, True)] = \ +_5mlT_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 555.0, 50.0: 68.0, 5000.0: 5204.0, 4000.0: 4200.0, 0.0: 0.0, 3000.0: 3180.0, 100.0: 123.5, 2000.0: 2160.0, 10.0: 22.0, 1000.0: 1085.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=30.0, @@ -3446,24 +2664,13 @@ def get_vantage_liquid_class( dispense_swap_speed=30.0, dispense_settling_time=1.0, dispense_stop_flow_rate=30.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(5000, False, True, False, Liquid.GLYCERIN80, True, True)] = ( - _5mlT_Glycerin80_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 597.0, - 50.0: 89.0, - 5000.0: 5240.0, - 4000.0: 4220.0, - 0.0: 0.0, - 3000.0: 3203.0, - 100.0: 138.0, - 2000.0: 2195.0, - 1000.0: 1166.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(5000, False, True, False, Liquid.GLYCERIN80, True, True)] = \ +_5mlT_Glycerin80_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 597.0, 50.0: 89.0, 5000.0: 5240.0, 4000.0: 4220.0, 0.0: 0.0, 3000.0: 3203.0, 100.0: 138.0, 2000.0: 2195.0, 1000.0: 1166.0}, aspiration_flow_rate=1200.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=30.0, @@ -3480,25 +2687,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(5000, False, True, False, Liquid.GLYCERIN80, False, True)] = ( - _5mlT_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 555.0, - 50.0: 71.0, - 5000.0: 5135.0, - 4000.0: 4115.0, - 0.0: 0.0, - 3000.0: 3127.0, - 100.0: 127.0, - 2000.0: 2115.0, - 10.0: 15.5, - 1000.0: 1075.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(5000, False, True, False, Liquid.GLYCERIN80, False, True)] = \ +_5mlT_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 555.0, 50.0: 71.0, 5000.0: 5135.0, 4000.0: 4115.0, 0.0: 0.0, 3000.0: 3127.0, 100.0: 127.0, 2000.0: 2115.0, 10.0: 15.5, 1000.0: 1075.0}, aspiration_flow_rate=1000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=0.0, @@ -3515,22 +2710,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(5000, False, True, False, Liquid.WATER, True, False)] = ( - _5mlT_Water_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 5000.0: 5030.0, - 4000.0: 4040.0, - 0.0: 0.0, - 3000.0: 3050.0, - 100.0: 104.0, - 2000.0: 2050.0, - 1000.0: 1040.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(5000, False, True, False, Liquid.WATER, True, False)] = \ +_5mlT_Water_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={5000.0: 5030.0, 4000.0: 4040.0, 0.0: 0.0, 3000.0: 3050.0, 100.0: 104.0, 2000.0: 2050.0, 1000.0: 1040.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -3547,24 +2733,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=20.0, -) - - -vantage_mapping[(5000, False, True, False, Liquid.WATER, True, True)] = ( - _5mlT_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 551.8, - 50.0: 66.4, - 5000.0: 5180.0, - 4000.0: 4165.0, - 0.0: 0.0, - 3000.0: 3148.0, - 100.0: 122.7, - 2000.0: 2128.0, - 1000.0: 1082.0, - }, + dispense_stop_back_volume=20.0 +) + + +vantage_mapping[(5000, False, True, False, Liquid.WATER, True, True)] = \ +_5mlT_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 551.8, 50.0: 66.4, 5000.0: 5180.0, 4000.0: 4165.0, 0.0: 0.0, 3000.0: 3148.0, 100.0: 122.7, 2000.0: 2128.0, 1000.0: 1082.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -3581,25 +2756,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(5000, False, True, False, Liquid.WATER, False, True)] = ( - _5mlT_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 547.0, - 50.0: 65.5, - 5000.0: 5145.0, - 4000.0: 4145.0, - 0.0: 0.0, - 3000.0: 3130.0, - 100.0: 120.9, - 2000.0: 2125.0, - 10.0: 15.1, - 1000.0: 1075.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(5000, False, True, False, Liquid.WATER, False, True)] = \ +_5mlT_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 547.0, 50.0: 65.5, 5000.0: 5145.0, 4000.0: 4145.0, 0.0: 0.0, 3000.0: 3130.0, 100.0: 120.9, 2000.0: 2125.0, 10.0: 15.1, 1000.0: 1075.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -3616,24 +2779,14 @@ def get_vantage_liquid_class( dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=500.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 250 -vantage_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = ( - HighNeedle_Water_DispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 527.3, - 50.0: 56.8, - 0.0: 0.0, - 100.0: 110.4, - 20.0: 24.7, - 1000.0: 1046.5, - 200.0: 214.6, - 10.0: 13.2, - }, +vantage_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = \ +HighNeedle_Water_DispenseJet = HamiltonLiquidClass( + curve={500.0: 527.3, 50.0: 56.8, 0.0: 0.0, 100.0: 110.4, 20.0: 24.7, 1000.0: 1046.5, 200.0: 214.6, 10.0: 13.2}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3650,23 +2803,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=350.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, False, False, Liquid.WATER, True, True)] = ( - HighNeedle_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 527.3, - 50.0: 56.8, - 0.0: 0.0, - 100.0: 110.4, - 20.0: 24.7, - 1000.0: 1046.5, - 200.0: 214.6, - 10.0: 13.2, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, False, False, Liquid.WATER, True, True)] = \ +HighNeedle_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 527.3, 50.0: 56.8, 0.0: 0.0, 100.0: 110.4, 20.0: 24.7, 1000.0: 1046.5, 200.0: 214.6, 10.0: 13.2}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3683,23 +2826,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=350.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = ( - HighNeedle_Water_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 527.3, - 50.0: 56.8, - 0.0: 0.0, - 100.0: 110.4, - 20.0: 24.7, - 1000.0: 1046.5, - 200.0: 214.6, - 10.0: 13.2, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = \ +HighNeedle_Water_DispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 527.3, 50.0: 56.8, 0.0: 0.0, 100.0: 110.4, 20.0: 24.7, 1000.0: 1046.5, 200.0: 214.6, 10.0: 13.2}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3716,21 +2849,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=350.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 120 -vantage_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = ( - HighNeedle_Water_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 50.0: 53.1, - 0.0: 0.0, - 20.0: 22.3, - 1000.0: 1000.0, - 10.0: 10.8, - }, +vantage_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = \ +HighNeedle_Water_DispenseSurface = HamiltonLiquidClass( + curve={50.0: 53.1, 0.0: 0.0, 20.0: 22.3, 1000.0: 1000.0, 10.0: 10.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -3747,20 +2873,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(1000, False, False, False, Liquid.WATER, False, True)] = ( - HighNeedle_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 50.0: 53.1, - 0.0: 0.0, - 20.0: 22.3, - 1000.0: 1000.0, - 10.0: 10.8, - }, +vantage_mapping[(1000, False, False, False, Liquid.WATER, False, True)] = \ +HighNeedle_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={50.0: 53.1, 0.0: 0.0, 20.0: 22.3, 1000.0: 1000.0, 10.0: 10.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -3777,20 +2896,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = ( - HighNeedle_Water_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 50.0: 53.1, - 0.0: 0.0, - 20.0: 22.3, - 1000.0: 1000.0, - 10.0: 10.8, - }, +vantage_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = \ +HighNeedle_Water_DispenseSurface_Part = HamiltonLiquidClass( + curve={50.0: 53.1, 0.0: 0.0, 20.0: 22.3, 1000.0: 1000.0, 10.0: 10.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -3807,22 +2919,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, True)] = ( - HighVolumeAcetonitrilDispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 526.5, - 250.0: 269.0, - 50.0: 60.5, - 0.0: 0.0, - 100.0: 112.7, - 20.0: 25.5, - 1000.0: 1045.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, True)] = \ +HighVolumeAcetonitrilDispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 526.5, 250.0: 269.0, 50.0: 60.5, 0.0: 0.0, 100.0: 112.7, 20.0: 25.5, 1000.0: 1045.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -3839,22 +2942,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, False)] = ( - HighVolumeAcetonitrilDispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 526.5, - 250.0: 269.0, - 50.0: 60.5, - 0.0: 0.0, - 100.0: 112.7, - 20.0: 25.5, - 1000.0: 1045.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, False)] = \ +HighVolumeAcetonitrilDispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 526.5, 250.0: 269.0, 50.0: 60.5, 0.0: 0.0, 100.0: 112.7, 20.0: 25.5, 1000.0: 1045.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -3871,23 +2965,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0, -) - - -vantage_mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, True)] = ( - HighVolumeAcetonitrilDispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 525.4, - 250.0: 267.0, - 50.0: 57.6, - 0.0: 0.0, - 100.0: 111.2, - 20.0: 23.8, - 1000.0: 1048.8, - 10.0: 12.1, - }, + dispense_stop_back_volume=10.0 +) + + +vantage_mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, True)] = \ +HighVolumeAcetonitrilDispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 525.4, 250.0: 267.0, 50.0: 57.6, 0.0: 0.0, 100.0: 111.2, 20.0: 23.8, 1000.0: 1048.8, 10.0: 12.1}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=10.0, @@ -3904,22 +2988,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, False)] = ( - HighVolumeAcetonitrilDispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 525.4, - 250.0: 267.0, - 50.0: 57.6, - 0.0: 0.0, - 100.0: 111.2, - 20.0: 23.8, - 1000.0: 1048.8, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, False)] = \ +HighVolumeAcetonitrilDispenseSurface_Part = HamiltonLiquidClass( + curve={500.0: 525.4, 250.0: 267.0, 50.0: 57.6, 0.0: 0.0, 100.0: 111.2, 20.0: 23.8, 1000.0: 1048.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=10.0, @@ -3936,26 +3011,16 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # - Submerge depth: Aspiration 2.0mm # (bei Schaumbildung durch mischen/vorbenetzen evtl.5mm, LLD-Erkennung) # - Mischen 3-5 x 950µl, mix position 0.5mm, je nach Volumen im Tube -vantage_mapping[(1000, False, True, False, Liquid.BLOOD, True, False)] = ( - HighVolumeBloodDispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 536.3, - 250.0: 275.6, - 50.0: 59.8, - 0.0: 0.0, - 20.0: 26.2, - 100.0: 115.3, - 10.0: 12.2, - 1000.0: 1061.6, - }, +vantage_mapping[(1000, False, True, False, Liquid.BLOOD, True, False)] = \ +HighVolumeBloodDispenseJet = HamiltonLiquidClass( + curve={500.0: 536.3, 250.0: 275.6, 50.0: 59.8, 0.0: 0.0, 20.0: 26.2, 100.0: 115.3, 10.0: 12.2, 1000.0: 1061.6}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3972,20 +3037,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=300.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(1000, True, True, True, Liquid.DMSO, True, True)] = ( - HighVolumeFilter_96COREHead1000ul_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 508.2, - 0.0: 0.0, - 20.0: 21.7, - 100.0: 101.7, - 1000.0: 1017.0, - }, +vantage_mapping[(1000, True, True, True, Liquid.DMSO, True, True)] = \ +HighVolumeFilter_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 508.2, 0.0: 0.0, 20.0: 21.7, 100.0: 101.7, 1000.0: 1017.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4002,20 +3060,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(1000, True, True, True, Liquid.DMSO, False, True)] = ( - HighVolumeFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 512.5, - 0.0: 0.0, - 100.0: 105.8, - 10.0: 12.7, - 1000.0: 1024.5, - }, +vantage_mapping[(1000, True, True, True, Liquid.DMSO, False, True)] = \ +HighVolumeFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 512.5, 0.0: 0.0, 100.0: 105.8, 10.0: 12.7, 1000.0: 1024.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4032,20 +3083,13 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(1000, True, True, True, Liquid.WATER, True, True)] = ( - HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 524.0, - 0.0: 0.0, - 20.0: 24.0, - 100.0: 109.2, - 1000.0: 1040.0, - }, +vantage_mapping[(1000, True, True, True, Liquid.WATER, True, True)] = \ +HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 524.0, 0.0: 0.0, 20.0: 24.0, 100.0: 109.2, 1000.0: 1040.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4062,20 +3106,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(1000, True, True, True, Liquid.WATER, False, True)] = ( - HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 522.0, - 0.0: 0.0, - 100.0: 108.3, - 1000.0: 1034.0, - 10.0: 12.5, - }, +vantage_mapping[(1000, True, True, True, Liquid.WATER, False, True)] = \ +HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 522.0, 0.0: 0.0, 100.0: 108.3, 1000.0: 1034.0, 10.0: 12.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -4092,7 +3129,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -4113,20 +3150,9 @@ def get_vantage_liquid_class( # 100 ( 9 Aliquots) 0.25 -4.81 # # -vantage_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = ( - HighVolumeFilter_DMSO_AliquotDispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 500.0, - 250.0: 250.0, - 30.0: 30.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - 1000.0: 1000.0, - 750.0: 750.0, - 10.0: 10.0, - }, +vantage_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = \ +HighVolumeFilter_DMSO_AliquotDispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -4143,25 +3169,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 250 -vantage_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = ( - HighVolumeFilter_DMSO_DispenseJet -) = HamiltonLiquidClass( - curve={ - 5.0: 5.1, - 500.0: 511.2, - 250.0: 256.2, - 50.0: 52.2, - 0.0: 0.0, - 20.0: 21.3, - 100.0: 103.4, - 10.0: 10.7, - 1000.0: 1021.0, - }, +vantage_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = \ +HighVolumeFilter_DMSO_DispenseJet = HamiltonLiquidClass( + curve={5.0: 5.1, 500.0: 511.2, 250.0: 256.2, 50.0: 52.2, 0.0: 0.0, 20.0: 21.3, 100.0: 103.4, 10.0: 10.7, 1000.0: 1021.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4178,24 +3193,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, True, Liquid.DMSO, True, True)] = ( - HighVolumeFilter_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 511.2, - 5.0: 5.1, - 250.0: 256.2, - 50.0: 52.2, - 0.0: 0.0, - 100.0: 103.4, - 20.0: 21.3, - 1000.0: 1021.0, - 10.0: 10.7, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, True, Liquid.DMSO, True, True)] = \ +HighVolumeFilter_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 511.2, 5.0: 5.1, 250.0: 256.2, 50.0: 52.2, 0.0: 0.0, 100.0: 103.4, 20.0: 21.3, 1000.0: 1021.0, 10.0: 10.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4212,20 +3216,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = ( - HighVolumeFilter_DMSO_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 517.2, - 0.0: 0.0, - 100.0: 109.5, - 20.0: 27.0, - 1000.0: 1027.0, - }, +vantage_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = \ +HighVolumeFilter_DMSO_DispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 517.2, 0.0: 0.0, 100.0: 109.5, 20.0: 27.0, 1000.0: 1027.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4242,24 +3239,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 120 -vantage_mapping[(1000, False, True, True, Liquid.DMSO, False, False)] = ( - HighVolumeFilter_DMSO_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 500.0: 514.3, - 250.0: 259.0, - 50.0: 54.4, - 0.0: 0.0, - 20.0: 22.8, - 100.0: 105.8, - 10.0: 12.1, - 1000.0: 1024.5, - }, +vantage_mapping[(1000, False, True, True, Liquid.DMSO, False, False)] = \ +HighVolumeFilter_DMSO_DispenseSurface = HamiltonLiquidClass( + curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 20.0: 22.8, 100.0: 105.8, 10.0: 12.1, 1000.0: 1024.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4276,23 +3263,13 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, True, Liquid.DMSO, False, True)] = ( - HighVolumeFilter_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 514.3, - 250.0: 259.0, - 50.0: 54.4, - 0.0: 0.0, - 100.0: 105.8, - 20.0: 22.8, - 1000.0: 1024.5, - 10.0: 12.1, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, True, Liquid.DMSO, False, True)] = \ +HighVolumeFilter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 100.0: 105.8, 20.0: 22.8, 1000.0: 1024.5, 10.0: 12.1}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4309,24 +3286,14 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # -vantage_mapping[(1000, False, True, True, Liquid.DMSO, False, False)] = ( - HighVolumeFilter_DMSO_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 514.3, - 250.0: 259.0, - 50.0: 54.4, - 0.0: 0.0, - 100.0: 105.8, - 20.0: 22.8, - 1000.0: 1024.5, - 10.0: 12.1, - }, +vantage_mapping[(1000, False, True, True, Liquid.DMSO, False, False)] = \ +HighVolumeFilter_DMSO_DispenseSurface_Part = HamiltonLiquidClass( + curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 100.0: 105.8, 20.0: 22.8, 1000.0: 1024.5, 10.0: 12.1}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4343,24 +3310,14 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 250, Stop back volume = 0 -vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, True, False)] = ( - HighVolumeFilter_EtOH_DispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 534.8, - 250.0: 273.0, - 50.0: 62.9, - 0.0: 0.0, - 20.0: 27.8, - 100.0: 116.3, - 10.0: 15.8, - 1000.0: 1053.9, - }, +vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, True, False)] = \ +HighVolumeFilter_EtOH_DispenseJet = HamiltonLiquidClass( + curve={500.0: 534.8, 250.0: 273.0, 50.0: 62.9, 0.0: 0.0, 20.0: 27.8, 100.0: 116.3, 10.0: 15.8, 1000.0: 1053.9}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4377,23 +3334,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, True, True)] = ( - HighVolumeFilter_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 534.8, - 250.0: 273.0, - 50.0: 62.9, - 0.0: 0.0, - 100.0: 116.3, - 20.0: 27.8, - 1000.0: 1053.9, - 10.0: 15.8, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, True, True)] = \ +HighVolumeFilter_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 534.8, 250.0: 273.0, 50.0: 62.9, 0.0: 0.0, 100.0: 116.3, 20.0: 27.8, 1000.0: 1053.9, 10.0: 15.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4410,22 +3357,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, True, False)] = ( - HighVolumeFilter_EtOH_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 534.8, - 250.0: 273.0, - 50.0: 62.9, - 0.0: 0.0, - 100.0: 116.3, - 20.0: 27.8, - 1000.0: 1053.9, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, True, False)] = \ +HighVolumeFilter_EtOH_DispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 534.8, 250.0: 273.0, 50.0: 62.9, 0.0: 0.0, 100.0: 116.3, 20.0: 27.8, 1000.0: 1053.9}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4442,24 +3380,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=5.0, + dispense_stop_back_volume=5.0 ) # V1.1: Set mix flow rate to 120 -vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, False, False)] = ( - HighVolumeFilter_EtOH_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 500.0: 528.4, - 250.0: 269.2, - 50.0: 61.2, - 0.0: 0.0, - 20.0: 27.6, - 100.0: 114.0, - 10.0: 15.7, - 1000.0: 1044.3, - }, +vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, False, False)] = \ +HighVolumeFilter_EtOH_DispenseSurface = HamiltonLiquidClass( + curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 20.0: 27.6, 100.0: 114.0, 10.0: 15.7, 1000.0: 1044.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -4476,23 +3404,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, False, True)] = ( - HighVolumeFilter_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 528.4, - 250.0: 269.2, - 50.0: 61.2, - 0.0: 0.0, - 100.0: 114.0, - 20.0: 27.6, - 1000.0: 1044.3, - 10.0: 15.7, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, False, True)] = \ +HighVolumeFilter_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 100.0: 114.0, 20.0: 27.6, 1000.0: 1044.3, 10.0: 15.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -4509,23 +3427,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, False, False)] = ( - HighVolumeFilter_EtOH_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 528.4, - 250.0: 269.2, - 50.0: 61.2, - 0.0: 0.0, - 100.0: 114.0, - 20.0: 27.6, - 1000.0: 1044.3, - 10.0: 15.7, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, False, False)] = \ +HighVolumeFilter_EtOH_DispenseSurface_Part = HamiltonLiquidClass( + curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 100.0: 114.0, 20.0: 27.6, 1000.0: 1044.3, 10.0: 15.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -4542,24 +3450,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 200 -vantage_mapping[(1000, False, True, True, Liquid.GLYCERIN80, True, False)] = ( - HighVolumeFilter_Glycerin80_DispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 537.8, - 250.0: 277.0, - 50.0: 63.3, - 0.0: 0.0, - 20.0: 28.0, - 100.0: 118.8, - 10.0: 15.2, - 1000.0: 1060.0, - }, +vantage_mapping[(1000, False, True, True, Liquid.GLYCERIN80, True, False)] = \ +HighVolumeFilter_Glycerin80_DispenseJet = HamiltonLiquidClass( + curve={500.0: 537.8, 250.0: 277.0, 50.0: 63.3, 0.0: 0.0, 20.0: 28.0, 100.0: 118.8, 10.0: 15.2, 1000.0: 1060.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=5.0, @@ -4576,24 +3474,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 200 -vantage_mapping[(1000, False, True, True, Liquid.GLYCERIN80, True, True)] = ( - HighVolumeFilter_Glycerin80_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 537.8, - 250.0: 277.0, - 50.0: 63.3, - 0.0: 0.0, - 100.0: 118.8, - 20.0: 28.0, - 1000.0: 1060.0, - 10.0: 15.2, - }, +vantage_mapping[(1000, False, True, True, Liquid.GLYCERIN80, True, True)] = \ +HighVolumeFilter_Glycerin80_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 537.8, 250.0: 277.0, 50.0: 63.3, 0.0: 0.0, 100.0: 118.8, 20.0: 28.0, 1000.0: 1060.0, 10.0: 15.2}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=5.0, @@ -4610,24 +3498,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 120 -vantage_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, False)] = ( - HighVolumeFilter_Glycerin80_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 500.0: 513.5, - 250.0: 257.2, - 50.0: 55.0, - 0.0: 0.0, - 20.0: 22.7, - 100.0: 105.5, - 10.0: 12.2, - 1000.0: 1027.2, - }, +vantage_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, False)] = \ +HighVolumeFilter_Glycerin80_DispenseSurface = HamiltonLiquidClass( + curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 20.0: 22.7, 100.0: 105.5, 10.0: 12.2, 1000.0: 1027.2}, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4644,23 +3522,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, True)] = ( - HighVolumeFilter_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 513.5, - 250.0: 257.2, - 50.0: 55.0, - 0.0: 0.0, - 100.0: 105.5, - 20.0: 22.7, - 1000.0: 1027.2, - 10.0: 12.2, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, True)] = \ +HighVolumeFilter_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 100.0: 105.5, 20.0: 22.7, 1000.0: 1027.2, 10.0: 12.2}, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4677,23 +3545,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, False)] = ( - HighVolumeFilter_Glycerin80_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 513.5, - 250.0: 257.2, - 50.0: 55.0, - 0.0: 0.0, - 100.0: 105.5, - 20.0: 22.7, - 1000.0: 1027.2, - 10.0: 12.2, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, False)] = \ +HighVolumeFilter_Glycerin80_DispenseSurface_Part = HamiltonLiquidClass( + curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 100.0: 105.5, 20.0: 22.7, 1000.0: 1027.2, 10.0: 12.2}, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4710,25 +3568,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 250 -vantage_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = ( - HighVolumeFilter_Serum_AliquotDispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 500.0, - 250.0: 250.0, - 30.0: 30.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - 1000.0: 1000.0, - 750.0: 750.0, - 10.0: 10.0, - }, +vantage_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = \ +HighVolumeFilter_Serum_AliquotDispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -4745,25 +3592,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=300.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 250 -vantage_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = ( - HighVolumeFilter_Serum_AliquotJet -) = HamiltonLiquidClass( - curve={ - 500.0: 500.0, - 250.0: 250.0, - 0.0: 0.0, - 30.0: 30.0, - 20.0: 20.0, - 100.0: 100.0, - 10.0: 10.0, - 750.0: 750.0, - 1000.0: 1000.0, - }, +vantage_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = \ +HighVolumeFilter_Serum_AliquotJet = HamiltonLiquidClass( + curve={500.0: 500.0, 250.0: 250.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 100.0: 100.0, 10.0: 10.0, 750.0: 750.0, 1000.0: 1000.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -4780,24 +3616,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=300.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 250, Settling time = 0 -vantage_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = ( - HighVolumeFilter_Serum_DispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 525.3, - 250.0: 266.6, - 50.0: 57.9, - 0.0: 0.0, - 20.0: 24.2, - 100.0: 111.3, - 10.0: 12.2, - 1000.0: 1038.6, - }, +vantage_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = \ +HighVolumeFilter_Serum_DispenseJet = HamiltonLiquidClass( + curve={500.0: 525.3, 250.0: 266.6, 50.0: 57.9, 0.0: 0.0, 20.0: 24.2, 100.0: 111.3, 10.0: 12.2, 1000.0: 1038.6}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4814,23 +3640,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, True, Liquid.SERUM, True, True)] = ( - HighVolumeFilter_Serum_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 525.3, - 250.0: 266.6, - 50.0: 57.9, - 0.0: 0.0, - 100.0: 111.3, - 20.0: 24.2, - 1000.0: 1038.6, - 10.0: 12.2, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, True, Liquid.SERUM, True, True)] = \ +HighVolumeFilter_Serum_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 525.3, 250.0: 266.6, 50.0: 57.9, 0.0: 0.0, 100.0: 111.3, 20.0: 24.2, 1000.0: 1038.6, 10.0: 12.2}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4847,20 +3663,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = ( - HighVolumeFilter_Serum_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 525.3, - 0.0: 0.0, - 100.0: 111.3, - 20.0: 27.3, - 1000.0: 1046.6, - }, +vantage_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = \ +HighVolumeFilter_Serum_DispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 525.3, 0.0: 0.0, 100.0: 111.3, 20.0: 27.3, 1000.0: 1046.6}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4877,24 +3686,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 120 -vantage_mapping[(1000, False, True, True, Liquid.SERUM, False, False)] = ( - HighVolumeFilter_Serum_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 500.0: 517.5, - 250.0: 261.9, - 50.0: 55.9, - 0.0: 0.0, - 20.0: 23.2, - 100.0: 108.2, - 10.0: 11.8, - 1000.0: 1026.7, - }, +vantage_mapping[(1000, False, True, True, Liquid.SERUM, False, False)] = \ +HighVolumeFilter_Serum_DispenseSurface = HamiltonLiquidClass( + curve={500.0: 517.5, 250.0: 261.9, 50.0: 55.9, 0.0: 0.0, 20.0: 23.2, 100.0: 108.2, 10.0: 11.8, 1000.0: 1026.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -4911,23 +3710,13 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, True, Liquid.SERUM, False, True)] = ( - HighVolumeFilter_Serum_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 517.5, - 250.0: 261.9, - 50.0: 55.9, - 0.0: 0.0, - 100.0: 108.2, - 20.0: 23.2, - 1000.0: 1026.7, - 10.0: 11.8, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, True, Liquid.SERUM, False, True)] = \ +HighVolumeFilter_Serum_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 517.5, 250.0: 261.9, 50.0: 55.9, 0.0: 0.0, 100.0: 108.2, 20.0: 23.2, 1000.0: 1026.7, 10.0: 11.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -4944,21 +3733,13 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(1000, False, True, True, Liquid.SERUM, False, False)] = ( - HighVolumeFilter_Serum_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 523.5, - 0.0: 0.0, - 100.0: 111.2, - 20.0: 23.2, - 1000.0: 1038.7, - 10.0: 11.8, - }, +vantage_mapping[(1000, False, True, True, Liquid.SERUM, False, False)] = \ +HighVolumeFilter_Serum_DispenseSurface_Part = HamiltonLiquidClass( + curve={500.0: 523.5, 0.0: 0.0, 100.0: 111.2, 20.0: 23.2, 1000.0: 1038.7, 10.0: 11.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -4975,25 +3756,14 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 250 -vantage_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = ( - HighVolumeFilter_Water_AliquotDispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 500.0, - 250.0: 250.0, - 30.0: 30.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - 1000.0: 1000.0, - 750.0: 750.0, - 10.0: 10.0, - }, +vantage_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = \ +HighVolumeFilter_Water_AliquotDispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -5010,25 +3780,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 250 -vantage_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = ( - HighVolumeFilter_Water_AliquotJet -) = HamiltonLiquidClass( - curve={ - 500.0: 500.0, - 250.0: 250.0, - 0.0: 0.0, - 30.0: 30.0, - 20.0: 20.0, - 100.0: 100.0, - 10.0: 10.0, - 750.0: 750.0, - 1000.0: 1000.0, - }, +vantage_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = \ +HighVolumeFilter_Water_AliquotJet = HamiltonLiquidClass( + curve={500.0: 500.0, 250.0: 250.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 100.0: 100.0, 10.0: 10.0, 750.0: 750.0, 1000.0: 1000.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -5045,24 +3804,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 250 -vantage_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = ( - HighVolumeFilter_Water_DispenseJet -) = HamiltonLiquidClass( - curve={ - 500.0: 521.7, - 50.0: 57.2, - 0.0: 0.0, - 20.0: 24.6, - 100.0: 109.6, - 10.0: 13.3, - 200.0: 212.9, - 1000.0: 1034.0, - }, +vantage_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = \ +HighVolumeFilter_Water_DispenseJet = HamiltonLiquidClass( + curve={500.0: 521.7, 50.0: 57.2, 0.0: 0.0, 20.0: 24.6, 100.0: 109.6, 10.0: 13.3, 200.0: 212.9, 1000.0: 1034.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -5079,23 +3828,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, True, Liquid.WATER, True, True)] = ( - HighVolumeFilter_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 521.7, - 50.0: 57.2, - 0.0: 0.0, - 100.0: 109.6, - 20.0: 24.6, - 1000.0: 1034.0, - 200.0: 212.9, - 10.0: 13.3, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, True, Liquid.WATER, True, True)] = \ +HighVolumeFilter_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 521.7, 50.0: 57.2, 0.0: 0.0, 100.0: 109.6, 20.0: 24.6, 1000.0: 1034.0, 200.0: 212.9, 10.0: 13.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -5112,22 +3851,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = ( - HighVolumeFilter_Water_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 521.7, - 50.0: 57.2, - 0.0: 0.0, - 100.0: 109.6, - 20.0: 27.0, - 1000.0: 1034.0, - 200.0: 212.9, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = \ +HighVolumeFilter_Water_DispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 521.7, 50.0: 57.2, 0.0: 0.0, 100.0: 109.6, 20.0: 27.0, 1000.0: 1034.0, 200.0: 212.9}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -5144,24 +3874,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 120, Clot retract hight = 0 -vantage_mapping[(1000, False, True, True, Liquid.WATER, False, False)] = ( - HighVolumeFilter_Water_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 500.0: 518.3, - 50.0: 56.3, - 0.0: 0.0, - 20.0: 23.9, - 100.0: 108.3, - 10.0: 12.5, - 200.0: 211.0, - 1000.0: 1028.5, - }, +vantage_mapping[(1000, False, True, True, Liquid.WATER, False, False)] = \ +HighVolumeFilter_Water_DispenseSurface = HamiltonLiquidClass( + curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 20.0: 23.9, 100.0: 108.3, 10.0: 12.5, 200.0: 211.0, 1000.0: 1028.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -5178,23 +3898,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, True, Liquid.WATER, False, True)] = ( - HighVolumeFilter_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 518.3, - 50.0: 56.3, - 0.0: 0.0, - 20.0: 23.9, - 100.0: 108.3, - 10.0: 12.5, - 200.0: 211.0, - 1000.0: 1028.5, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, True, Liquid.WATER, False, True)] = \ +HighVolumeFilter_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 20.0: 23.9, 100.0: 108.3, 10.0: 12.5, 200.0: 211.0, 1000.0: 1028.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -5211,23 +3921,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, True, Liquid.WATER, False, False)] = ( - HighVolumeFilter_Water_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 518.3, - 50.0: 56.3, - 0.0: 0.0, - 100.0: 108.3, - 20.0: 23.9, - 1000.0: 1028.5, - 200.0: 211.0, - 10.0: 12.7, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, True, Liquid.WATER, False, False)] = \ +HighVolumeFilter_Water_DispenseSurface_Part = HamiltonLiquidClass( + curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 100.0: 108.3, 20.0: 23.9, 1000.0: 1028.5, 200.0: 211.0, 10.0: 12.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -5244,20 +3944,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(1000, True, True, False, Liquid.DMSO, True, False)] = ( - HighVolume_96COREHead1000ul_DMSO_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 500.0: 524.0, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 24.0, - 1000.0: 1025.0, - }, +vantage_mapping[(1000, True, True, False, Liquid.DMSO, True, False)] = \ +HighVolume_96COREHead1000ul_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={500.0: 524.0, 0.0: 0.0, 100.0: 107.2, 20.0: 24.0, 1000.0: 1025.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -5274,20 +3967,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=20.0, + dispense_stop_back_volume=20.0 ) -vantage_mapping[(1000, True, True, False, Liquid.DMSO, True, True)] = ( - HighVolume_96COREHead1000ul_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 508.2, - 0.0: 0.0, - 100.0: 101.7, - 20.0: 21.7, - 1000.0: 1017.0, - }, +vantage_mapping[(1000, True, True, False, Liquid.DMSO, True, True)] = \ +HighVolume_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 508.2, 0.0: 0.0, 100.0: 101.7, 20.0: 21.7, 1000.0: 1017.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -5304,20 +3990,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(1000, True, True, False, Liquid.DMSO, False, True)] = ( - HighVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 512.5, - 0.0: 0.0, - 100.0: 105.8, - 1000.0: 1024.5, - 10.0: 12.7, - }, +vantage_mapping[(1000, True, True, False, Liquid.DMSO, False, True)] = \ +HighVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 512.5, 0.0: 0.0, 100.0: 105.8, 1000.0: 1024.5, 10.0: 12.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -5334,22 +4013,14 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # to prevent drop's, mix 2x with e.g. 500ul -vantage_mapping[(1000, True, True, False, Liquid.ETHANOL, True, False)] = ( - HighVolume_96COREHead1000ul_EtOH_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 500.0: 500.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - 1000.0: 1000.0, - }, +vantage_mapping[(1000, True, True, False, Liquid.ETHANOL, True, False)] = \ +HighVolume_96COREHead1000ul_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 500.0: 500.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -5366,20 +4037,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -vantage_mapping[(1000, True, True, False, Liquid.ETHANOL, True, True)] = ( - HighVolume_96COREHead1000ul_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 516.5, - 0.0: 0.0, - 100.0: 108.3, - 20.0: 24.0, - 1000.0: 1027.0, - }, +vantage_mapping[(1000, True, True, False, Liquid.ETHANOL, True, True)] = \ +HighVolume_96COREHead1000ul_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 516.5, 0.0: 0.0, 100.0: 108.3, 20.0: 24.0, 1000.0: 1027.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -5396,21 +4060,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # to prevent drop's, mix 2x with e.g. 500ul -vantage_mapping[(1000, True, True, False, Liquid.ETHANOL, False, True)] = ( - HighVolume_96COREHead1000ul_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 516.5, - 0.0: 0.0, - 100.0: 107.0, - 1000.0: 1027.0, - 10.0: 14.0, - }, +vantage_mapping[(1000, True, True, False, Liquid.ETHANOL, False, True)] = \ +HighVolume_96COREHead1000ul_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 516.5, 0.0: 0.0, 100.0: 107.0, 1000.0: 1027.0, 10.0: 14.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=150.0, aspiration_air_transport_volume=5.0, @@ -5427,20 +4084,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(1000, True, True, False, Liquid.GLYCERIN80, False, True)] = ( - HighVolume_96COREHead1000ul_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 522.0, - 0.0: 0.0, - 100.0: 115.3, - 1000.0: 1034.0, - 10.0: 12.5, - }, +vantage_mapping[(1000, True, True, False, Liquid.GLYCERIN80, False, True)] = \ +HighVolume_96COREHead1000ul_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 522.0, 0.0: 0.0, 100.0: 115.3, 1000.0: 1034.0, 10.0: 12.5}, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -5457,20 +4107,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(1000, True, True, False, Liquid.WATER, True, False)] = ( - HighVolume_96COREHead1000ul_Water_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 500.0: 524.0, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 24.0, - 1000.0: 1025.0, - }, +vantage_mapping[(1000, True, True, False, Liquid.WATER, True, False)] = \ +HighVolume_96COREHead1000ul_Water_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={500.0: 524.0, 0.0: 0.0, 100.0: 107.2, 20.0: 24.0, 1000.0: 1025.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -5487,20 +4130,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -vantage_mapping[(1000, True, True, False, Liquid.WATER, True, True)] = ( - HighVolume_96COREHead1000ul_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 524.0, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 24.0, - 1000.0: 1025.0, - }, +vantage_mapping[(1000, True, True, False, Liquid.WATER, True, True)] = \ +HighVolume_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 524.0, 0.0: 0.0, 100.0: 107.2, 20.0: 24.0, 1000.0: 1025.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -5517,20 +4153,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(1000, True, True, False, Liquid.WATER, False, True)] = ( - HighVolume_96COREHead1000ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 522.0, - 0.0: 0.0, - 100.0: 108.3, - 1000.0: 1034.0, - 10.0: 12.5, - }, +vantage_mapping[(1000, True, True, False, Liquid.WATER, False, True)] = \ +HighVolume_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 522.0, 0.0: 0.0, 100.0: 108.3, 1000.0: 1034.0, 10.0: 12.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -5547,24 +4176,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # Liquid class for wash high volume tips with CO-RE 96 Head in CO-RE 96 Head Washer. -vantage_mapping[(1000, True, True, False, Liquid.WATER, False, False)] = ( - HighVolume_Core96Washer_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 500.0: 520.0, - 50.0: 56.3, - 0.0: 0.0, - 100.0: 110.0, - 20.0: 23.9, - 1000.0: 1050.0, - 200.0: 212.0, - 10.0: 12.5, - }, +vantage_mapping[(1000, True, True, False, Liquid.WATER, False, False)] = \ +HighVolume_Core96Washer_DispenseSurface = HamiltonLiquidClass( + curve={500.0: 520.0, 50.0: 56.3, 0.0: 0.0, 100.0: 110.0, 20.0: 23.9, 1000.0: 1050.0, 200.0: 212.0, 10.0: 12.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=220.0, aspiration_air_transport_volume=0.0, @@ -5581,7 +4200,7 @@ def get_vantage_liquid_class( dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -5602,20 +4221,9 @@ def get_vantage_liquid_class( # 100 ( 9 Aliquots) 0.25 -4.81 # # -vantage_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = ( - HighVolume_DMSO_AliquotDispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 500.0, - 250.0: 250.0, - 30.0: 30.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - 1000.0: 1000.0, - 750.0: 750.0, - 10.0: 10.0, - }, +vantage_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = \ +HighVolume_DMSO_AliquotDispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -5632,24 +4240,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, -) - - -vantage_mapping[(1000, False, True, False, Liquid.DMSO, True, True)] = ( - HighVolume_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 511.2, - 5.0: 5.1, - 250.0: 256.2, - 50.0: 52.2, - 0.0: 0.0, - 100.0: 103.4, - 20.0: 21.3, - 1000.0: 1021.0, - 10.0: 10.7, - }, + dispense_stop_back_volume=10.0 +) + + +vantage_mapping[(1000, False, True, False, Liquid.DMSO, True, True)] = \ +HighVolume_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 511.2, 5.0: 5.1, 250.0: 256.2, 50.0: 52.2, 0.0: 0.0, 100.0: 103.4, 20.0: 21.3, 1000.0: 1021.0, 10.0: 10.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -5666,20 +4263,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = ( - HighVolume_DMSO_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 520.2, - 0.0: 0.0, - 100.0: 112.0, - 20.0: 27.0, - 1000.0: 1031.0, - }, +vantage_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = \ +HighVolume_DMSO_DispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 520.2, 0.0: 0.0, 100.0: 112.0, 20.0: 27.0, 1000.0: 1031.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -5696,23 +4286,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=5.0, -) - - -vantage_mapping[(1000, False, True, False, Liquid.DMSO, False, True)] = ( - HighVolume_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 514.3, - 250.0: 259.0, - 50.0: 54.4, - 0.0: 0.0, - 100.0: 105.8, - 20.0: 22.8, - 1000.0: 1024.5, - 10.0: 12.1, - }, + dispense_stop_back_volume=5.0 +) + + +vantage_mapping[(1000, False, True, False, Liquid.DMSO, False, True)] = \ +HighVolume_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 100.0: 105.8, 20.0: 22.8, 1000.0: 1024.5, 10.0: 12.1}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -5729,23 +4309,13 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, False, Liquid.DMSO, False, False)] = ( - HighVolume_DMSO_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 514.3, - 250.0: 259.0, - 50.0: 54.4, - 0.0: 0.0, - 100.0: 105.8, - 20.0: 22.8, - 1000.0: 1024.5, - 10.0: 12.4, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, False, Liquid.DMSO, False, False)] = \ +HighVolume_DMSO_DispenseSurface_Part = HamiltonLiquidClass( + curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 100.0: 105.8, 20.0: 22.8, 1000.0: 1024.5, 10.0: 12.4}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -5762,23 +4332,13 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, False, Liquid.ETHANOL, True, True)] = ( - HighVolume_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 534.8, - 250.0: 273.0, - 50.0: 62.9, - 0.0: 0.0, - 100.0: 116.3, - 20.0: 27.8, - 1000.0: 1053.9, - 10.0: 15.8, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, False, Liquid.ETHANOL, True, True)] = \ +HighVolume_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 534.8, 250.0: 273.0, 50.0: 62.9, 0.0: 0.0, 100.0: 116.3, 20.0: 27.8, 1000.0: 1053.9, 10.0: 15.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -5795,21 +4355,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(1000, False, True, False, Liquid.ETHANOL, True, False)] = ( - HighVolume_EtOH_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 529.0, - 50.0: 62.9, - 0.0: 0.0, - 100.0: 114.5, - 20.0: 27.8, - 1000.0: 1053.9, - }, +vantage_mapping[(1000, False, True, False, Liquid.ETHANOL, True, False)] = \ +HighVolume_EtOH_DispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 529.0, 50.0: 62.9, 0.0: 0.0, 100.0: 114.5, 20.0: 27.8, 1000.0: 1053.9}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -5826,23 +4378,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=5.0, -) - - -vantage_mapping[(1000, False, True, False, Liquid.ETHANOL, False, True)] = ( - HighVolume_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 528.4, - 250.0: 269.2, - 50.0: 61.2, - 0.0: 0.0, - 20.0: 27.6, - 100.0: 114.0, - 10.0: 15.7, - 1000.0: 1044.3, - }, + dispense_stop_back_volume=5.0 +) + + +vantage_mapping[(1000, False, True, False, Liquid.ETHANOL, False, True)] = \ +HighVolume_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 20.0: 27.6, 100.0: 114.0, 10.0: 15.7, 1000.0: 1044.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -5859,23 +4401,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, False, Liquid.ETHANOL, False, False)] = ( - HighVolume_EtOH_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 528.4, - 250.0: 269.2, - 50.0: 61.2, - 0.0: 0.0, - 100.0: 114.0, - 20.0: 27.6, - 1000.0: 1044.3, - 10.0: 14.7, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, False, Liquid.ETHANOL, False, False)] = \ +HighVolume_EtOH_DispenseSurface_Part = HamiltonLiquidClass( + curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 100.0: 114.0, 20.0: 27.6, 1000.0: 1044.3, 10.0: 14.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -5892,23 +4424,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, False, Liquid.GLYCERIN80, True, True)] = ( - HighVolume_Glycerin80_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 537.8, - 250.0: 277.0, - 50.0: 63.3, - 0.0: 0.0, - 100.0: 118.8, - 20.0: 28.0, - 1000.0: 1060.0, - 10.0: 15.2, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, False, Liquid.GLYCERIN80, True, True)] = \ +HighVolume_Glycerin80_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 537.8, 250.0: 277.0, 50.0: 63.3, 0.0: 0.0, 100.0: 118.8, 20.0: 28.0, 1000.0: 1060.0, 10.0: 15.2}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=5.0, @@ -5925,23 +4447,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, True)] = ( - HighVolume_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 513.5, - 250.0: 257.2, - 50.0: 55.0, - 0.0: 0.0, - 100.0: 105.5, - 20.0: 22.7, - 1000.0: 1027.2, - 10.0: 12.2, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, True)] = \ +HighVolume_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 100.0: 105.5, 20.0: 22.7, 1000.0: 1027.2, 10.0: 12.2}, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -5958,23 +4470,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, False)] = ( - HighVolume_Glycerin80_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 513.5, - 250.0: 257.2, - 50.0: 55.0, - 0.0: 0.0, - 100.0: 105.5, - 20.0: 22.7, - 1000.0: 1027.2, - 10.0: 12.2, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, False)] = \ +HighVolume_Glycerin80_DispenseSurface_Part = HamiltonLiquidClass( + curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 100.0: 105.5, 20.0: 22.7, 1000.0: 1027.2, 10.0: 12.2}, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -5991,25 +4493,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 250 -vantage_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = ( - HighVolume_Serum_AliquotDispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 500.0, - 250.0: 250.0, - 30.0: 30.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - 1000.0: 1000.0, - 750.0: 750.0, - 10.0: 10.0, - }, +vantage_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = \ +HighVolume_Serum_AliquotDispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -6026,23 +4517,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=300.0, - dispense_stop_back_volume=10.0, -) - - -vantage_mapping[(1000, False, True, False, Liquid.SERUM, True, True)] = ( - HighVolume_Serum_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 525.3, - 250.0: 266.6, - 50.0: 57.9, - 0.0: 0.0, - 100.0: 111.3, - 20.0: 24.2, - 1000.0: 1038.6, - 10.0: 12.2, - }, + dispense_stop_back_volume=10.0 +) + + +vantage_mapping[(1000, False, True, False, Liquid.SERUM, True, True)] = \ +HighVolume_Serum_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 525.3, 250.0: 266.6, 50.0: 57.9, 0.0: 0.0, 100.0: 111.3, 20.0: 24.2, 1000.0: 1038.6, 10.0: 12.2}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -6059,20 +4540,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = ( - HighVolume_Serum_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 525.3, - 0.0: 0.0, - 100.0: 111.3, - 20.0: 27.3, - 1000.0: 1046.6, - }, +vantage_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = \ +HighVolume_Serum_DispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 525.3, 0.0: 0.0, 100.0: 111.3, 20.0: 27.3, 1000.0: 1046.6}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -6089,23 +4563,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0, -) - - -vantage_mapping[(1000, False, True, False, Liquid.SERUM, False, True)] = ( - HighVolume_Serum_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 517.5, - 250.0: 261.9, - 50.0: 55.9, - 0.0: 0.0, - 100.0: 108.2, - 20.0: 23.2, - 1000.0: 1026.7, - 10.0: 11.8, - }, + dispense_stop_back_volume=10.0 +) + + +vantage_mapping[(1000, False, True, False, Liquid.SERUM, False, True)] = \ +HighVolume_Serum_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 517.5, 250.0: 261.9, 50.0: 55.9, 0.0: 0.0, 100.0: 108.2, 20.0: 23.2, 1000.0: 1026.7, 10.0: 11.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -6122,21 +4586,13 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(1000, False, True, False, Liquid.SERUM, False, False)] = ( - HighVolume_Serum_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 50.0: 55.9, - 0.0: 0.0, - 100.0: 108.2, - 20.0: 23.2, - 1000.0: 1037.7, - 10.0: 11.8, - }, +vantage_mapping[(1000, False, True, False, Liquid.SERUM, False, False)] = \ +HighVolume_Serum_DispenseSurface_Part = HamiltonLiquidClass( + curve={50.0: 55.9, 0.0: 0.0, 100.0: 108.2, 20.0: 23.2, 1000.0: 1037.7, 10.0: 11.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -6153,25 +4609,14 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 250 -vantage_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = ( - HighVolume_Water_AliquotDispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 500.0, - 250.0: 250.0, - 30.0: 30.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - 1000.0: 1000.0, - 750.0: 750.0, - 10.0: 10.0, - }, +vantage_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = \ +HighVolume_Water_AliquotDispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -6188,23 +4633,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, -) - - -vantage_mapping[(1000, False, True, False, Liquid.WATER, True, True)] = ( - HighVolume_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 521.7, - 50.0: 57.2, - 0.0: 0.0, - 100.0: 109.6, - 20.0: 24.6, - 1000.0: 1034.0, - 200.0: 212.9, - 10.0: 13.3, - }, + dispense_stop_back_volume=10.0 +) + + +vantage_mapping[(1000, False, True, False, Liquid.WATER, True, True)] = \ +HighVolume_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={500.0: 521.7, 50.0: 57.2, 0.0: 0.0, 100.0: 109.6, 20.0: 24.6, 1000.0: 1034.0, 200.0: 212.9, 10.0: 13.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -6221,20 +4656,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = ( - HighVolume_Water_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 521.7, - 0.0: 0.0, - 100.0: 109.6, - 20.0: 26.9, - 1000.0: 1040.0, - }, +vantage_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = \ +HighVolume_Water_DispenseJet_Part = HamiltonLiquidClass( + curve={500.0: 521.7, 0.0: 0.0, 100.0: 109.6, 20.0: 26.9, 1000.0: 1040.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -6251,23 +4679,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=18.0, -) - - -vantage_mapping[(1000, False, True, False, Liquid.WATER, False, True)] = ( - HighVolume_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 500.0: 518.3, - 50.0: 56.3, - 0.0: 0.0, - 100.0: 108.3, - 20.0: 23.9, - 1000.0: 1028.5, - 200.0: 211.0, - 10.0: 12.5, - }, + dispense_stop_back_volume=18.0 +) + + +vantage_mapping[(1000, False, True, False, Liquid.WATER, False, True)] = \ +HighVolume_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 100.0: 108.3, 20.0: 23.9, 1000.0: 1028.5, 200.0: 211.0, 10.0: 12.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -6284,23 +4702,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(1000, False, True, False, Liquid.WATER, False, False)] = ( - HighVolume_Water_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 500.0: 518.3, - 50.0: 56.3, - 0.0: 0.0, - 100.0: 108.3, - 20.0: 23.9, - 1000.0: 1036.5, - 200.0: 211.0, - 10.0: 12.5, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(1000, False, True, False, Liquid.WATER, False, False)] = \ +HighVolume_Water_DispenseSurface_Part = HamiltonLiquidClass( + curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 100.0: 108.3, 20.0: 23.9, 1000.0: 1036.5, 200.0: 211.0, 10.0: 12.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -6317,7 +4725,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -6327,19 +4735,9 @@ def get_vantage_liquid_class( # - fix height from bottom between 0.5-0.7mm # - dispense mode jet empty tip # - also with higher DNA concentration -vantage_mapping[(10, False, False, False, Liquid.DNA_TRIS_EDTA, True, False)] = ( - LowNeedleDNADispenseJet -) = HamiltonLiquidClass( - curve={ - 5.0: 5.7, - 0.5: 1.0, - 50.0: 53.0, - 0.0: 0.0, - 20.0: 22.1, - 1.0: 1.5, - 10.0: 10.8, - 2.0: 2.7, - }, +vantage_mapping[(10, False, False, False, Liquid.DNA_TRIS_EDTA, True, False)] = \ +LowNeedleDNADispenseJet = HamiltonLiquidClass( + curve={5.0: 5.7, 0.5: 1.0, 50.0: 53.0, 0.0: 0.0, 20.0: 22.1, 1.0: 1.5, 10.0: 10.8, 2.0: 2.7}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=0.0, @@ -6356,7 +4754,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.5, + dispense_stop_back_volume=0.5 ) @@ -6365,19 +4763,9 @@ def get_vantage_liquid_class( # - for Disp. in empty PCR-Plate/on empty Plate from 1µl up # - fix height from bottom between 0.5-0.7mm # - also with higher DNA concentration -vantage_mapping[(10, False, False, False, Liquid.DNA_TRIS_EDTA, False, False)] = ( - LowNeedleDNADispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 5.7, - 0.5: 1.0, - 50.0: 53.0, - 0.0: 0.0, - 20.0: 22.1, - 1.0: 1.5, - 10.0: 10.8, - 2.0: 2.7, - }, +vantage_mapping[(10, False, False, False, Liquid.DNA_TRIS_EDTA, False, False)] = \ +LowNeedleDNADispenseSurface = HamiltonLiquidClass( + curve={5.0: 5.7, 0.5: 1.0, 50.0: 53.0, 0.0: 0.0, 20.0: 22.1, 1.0: 1.5, 10.0: 10.8, 2.0: 2.7}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=0.0, @@ -6394,24 +4782,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 60 -vantage_mapping[(10, False, False, False, Liquid.WATER, False, False)] = ( - LowNeedle_SysFlWater_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 35.0: 35.6, - 60.0: 62.7, - 50.0: 51.3, - 40.0: 40.9, - 30.0: 30.0, - 0.0: 0.0, - 31.0: 31.4, - 32.0: 32.7, - }, +vantage_mapping[(10, False, False, False, Liquid.WATER, False, False)] = \ +LowNeedle_SysFlWater_DispenseSurface = HamiltonLiquidClass( + curve={35.0: 35.6, 60.0: 62.7, 50.0: 51.3, 40.0: 40.9, 30.0: 30.0, 0.0: 0.0, 31.0: 31.4, 32.0: 32.7}, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, aspiration_air_transport_volume=0.0, @@ -6428,13 +4806,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, False, False, Liquid.WATER, True, False)] = ( - LowNeedle_Water_DispenseJet -) = HamiltonLiquidClass( +vantage_mapping[(10, False, False, False, Liquid.WATER, True, False)] = \ +LowNeedle_Water_DispenseJet = HamiltonLiquidClass( curve={50.0: 52.7, 30.0: 31.7, 0.0: 0.0, 20.0: 20.5, 10.0: 10.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -6452,21 +4829,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, False, False, Liquid.WATER, True, True)] = ( - LowNeedle_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 70.0: 70.0, - 50.0: 52.7, - 30.0: 31.7, - 0.0: 0.0, - 20.0: 20.5, - 10.0: 10.3, - }, +vantage_mapping[(10, False, False, False, Liquid.WATER, True, True)] = \ +LowNeedle_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={70.0: 70.0, 50.0: 52.7, 30.0: 31.7, 0.0: 0.0, 20.0: 20.5, 10.0: 10.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=15.0, @@ -6483,21 +4852,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, False, False, Liquid.WATER, True, False)] = ( - LowNeedle_Water_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 70.0: 70.0, - 50.0: 52.7, - 30.0: 31.7, - 0.0: 0.0, - 20.0: 20.5, - 10.0: 10.3, - }, +vantage_mapping[(10, False, False, False, Liquid.WATER, True, False)] = \ +LowNeedle_Water_DispenseJet_Part = HamiltonLiquidClass( + curve={70.0: 70.0, 50.0: 52.7, 30.0: 31.7, 0.0: 0.0, 20.0: 20.5, 10.0: 10.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=15.0, @@ -6514,24 +4875,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 60 -vantage_mapping[(10, False, False, False, Liquid.WATER, False, False)] = ( - LowNeedle_Water_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 5.0, - 0.5: 0.5, - 50.0: 50.0, - 0.0: 0.0, - 20.0: 20.5, - 1.0: 1.0, - 10.0: 10.0, - 2.0: 2.0, - }, +vantage_mapping[(10, False, False, False, Liquid.WATER, False, False)] = \ +LowNeedle_Water_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 5.0, 0.5: 0.5, 50.0: 50.0, 0.0: 0.0, 20.0: 20.5, 1.0: 1.0, 10.0: 10.0, 2.0: 2.0}, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, aspiration_air_transport_volume=0.0, @@ -6548,24 +4899,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(10, False, False, False, Liquid.WATER, False, True)] = ( - LowNeedle_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.0, - 0.5: 0.5, - 70.0: 70.0, - 50.0: 50.0, - 0.0: 0.0, - 20.0: 20.5, - 1.0: 1.0, - 10.0: 10.0, - 2.0: 2.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(10, False, False, False, Liquid.WATER, False, True)] = \ +LowNeedle_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.0, 0.5: 0.5, 70.0: 70.0, 50.0: 50.0, 0.0: 0.0, 20.0: 20.5, 1.0: 1.0, 10.0: 10.0, 2.0: 2.0}, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, aspiration_air_transport_volume=0.0, @@ -6582,24 +4922,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(10, False, False, False, Liquid.WATER, False, False)] = ( - LowNeedle_Water_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 5.0: 5.0, - 0.5: 0.5, - 70.0: 70.0, - 50.0: 50.0, - 0.0: 0.0, - 20.0: 20.5, - 1.0: 1.0, - 10.0: 10.0, - 2.0: 2.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(10, False, False, False, Liquid.WATER, False, False)] = \ +LowNeedle_Water_DispenseSurface_Part = HamiltonLiquidClass( + curve={5.0: 5.0, 0.5: 0.5, 70.0: 70.0, 50.0: 50.0, 0.0: 0.0, 20.0: 20.5, 1.0: 1.0, 10.0: 10.0, 2.0: 2.0}, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, aspiration_air_transport_volume=0.0, @@ -6616,13 +4945,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, True, True, True, Liquid.DMSO, False, True)] = ( - LowVolumeFilter_96COREHead_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( +vantage_mapping[(10, True, True, True, Liquid.DMSO, False, True)] = \ +LowVolumeFilter_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 5.1, 0.0: 0.0, 1.0: 0.8, 10.0: 10.0}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -6640,13 +4968,12 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, True, True, True, Liquid.DMSO, False, False)] = ( - LowVolumeFilter_96COREHead_DMSO_DispenseSurface_Part -) = HamiltonLiquidClass( +vantage_mapping[(10, True, True, True, Liquid.DMSO, False, False)] = \ +LowVolumeFilter_96COREHead_DMSO_DispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 5.7, 0.0: 0.0, 1.0: 1.5, 10.0: 10.3}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -6664,13 +4991,12 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, True, True, True, Liquid.WATER, False, True)] = ( - LowVolumeFilter_96COREHead_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( +vantage_mapping[(10, True, True, True, Liquid.WATER, False, True)] = \ +LowVolumeFilter_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 5.6, 0.0: 0.0, 1.0: 1.2, 10.0: 10.0}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -6688,13 +5014,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, True, True, True, Liquid.WATER, False, False)] = ( - LowVolumeFilter_96COREHead_Water_DispenseSurface_Part -) = HamiltonLiquidClass( +vantage_mapping[(10, True, True, True, Liquid.WATER, False, False)] = \ +LowVolumeFilter_96COREHead_Water_DispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 5.8, 0.0: 0.0, 1.0: 1.5, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -6712,23 +5037,14 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 75 -vantage_mapping[(10, False, True, True, Liquid.DMSO, False, False)] = ( - LowVolumeFilter_DMSO_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 5.9, - 0.5: 0.8, - 15.0: 16.4, - 0.0: 0.0, - 1.0: 1.4, - 2.0: 2.6, - 10.0: 11.2, - }, +vantage_mapping[(10, False, True, True, Liquid.DMSO, False, False)] = \ +LowVolumeFilter_DMSO_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 5.9, 0.5: 0.8, 15.0: 16.4, 0.0: 0.0, 1.0: 1.4, 2.0: 2.6, 10.0: 11.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -6745,21 +5061,13 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=56.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, True, True, Liquid.DMSO, False, True)] = ( - LowVolumeFilter_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.9, - 0.5: 0.8, - 0.0: 0.0, - 1.0: 1.4, - 10.0: 10.0, - 2.0: 2.6, - }, +vantage_mapping[(10, False, True, True, Liquid.DMSO, False, True)] = \ +LowVolumeFilter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.9, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 10.0, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -6776,13 +5084,12 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, True, True, Liquid.DMSO, False, False)] = ( - LowVolumeFilter_DMSO_DispenseSurface_Part -) = HamiltonLiquidClass( +vantage_mapping[(10, False, True, True, Liquid.DMSO, False, False)] = \ +LowVolumeFilter_DMSO_DispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.4, 10.0: 10.0, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -6800,22 +5107,14 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 75 -vantage_mapping[(10, False, True, True, Liquid.ETHANOL, False, False)] = ( - LowVolumeFilter_EtOH_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 8.4, - 0.5: 1.9, - 0.0: 0.0, - 1.0: 2.7, - 2.0: 4.1, - 10.0: 13.0, - }, +vantage_mapping[(10, False, True, True, Liquid.ETHANOL, False, False)] = \ +LowVolumeFilter_EtOH_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 8.4, 0.5: 1.9, 0.0: 0.0, 1.0: 2.7, 2.0: 4.1, 10.0: 13.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=2.0, @@ -6832,13 +5131,12 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, True, True, Liquid.ETHANOL, False, True)] = ( - LowVolumeFilter_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( +vantage_mapping[(10, False, True, True, Liquid.ETHANOL, False, True)] = \ +LowVolumeFilter_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 6.6, 0.0: 0.0, 1.0: 1.8, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -6856,13 +5154,12 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, True, True, Liquid.ETHANOL, False, False)] = ( - LowVolumeFilter_EtOH_DispenseSurface_Part -) = HamiltonLiquidClass( +vantage_mapping[(10, False, True, True, Liquid.ETHANOL, False, False)] = \ +LowVolumeFilter_EtOH_DispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 6.4, 0.0: 0.0, 1.0: 1.8, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -6880,23 +5177,14 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 10 -vantage_mapping[(10, False, True, True, Liquid.GLYCERIN, False, False)] = ( - LowVolumeFilter_Glycerin_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 6.5, - 0.5: 1.4, - 15.0: 17.0, - 0.0: 0.0, - 1.0: 2.0, - 2.0: 3.2, - 10.0: 11.8, - }, +vantage_mapping[(10, False, True, True, Liquid.GLYCERIN, False, False)] = \ +LowVolumeFilter_Glycerin_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 6.5, 0.5: 1.4, 15.0: 17.0, 0.0: 0.0, 1.0: 2.0, 2.0: 3.2, 10.0: 11.8}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -6913,13 +5201,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, True, True, Liquid.GLYCERIN80, False, True)] = ( - LowVolumeFilter_Glycerin_DispenseSurface_Empty -) = HamiltonLiquidClass( +vantage_mapping[(10, False, True, True, Liquid.GLYCERIN80, False, True)] = \ +LowVolumeFilter_Glycerin_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 6.5, 0.0: 0.0, 1.0: 0.6, 10.0: 10.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, @@ -6937,23 +5224,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 75 -vantage_mapping[(10, False, True, True, Liquid.WATER, False, False)] = ( - LowVolumeFilter_Water_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 6.0, - 0.5: 0.8, - 15.0: 16.7, - 0.0: 0.0, - 1.0: 1.4, - 2.0: 2.6, - 10.0: 11.5, - }, +vantage_mapping[(10, False, True, True, Liquid.WATER, False, False)] = \ +LowVolumeFilter_Water_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 6.0, 0.5: 0.8, 15.0: 16.7, 0.0: 0.0, 1.0: 1.4, 2.0: 2.6, 10.0: 11.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -6970,21 +5248,13 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=56.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, True, True, Liquid.WATER, False, True)] = ( - LowVolumeFilter_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 6.0, - 0.5: 0.8, - 0.0: 0.0, - 1.0: 1.4, - 10.0: 10.0, - 2.0: 2.6, - }, +vantage_mapping[(10, False, True, True, Liquid.WATER, False, True)] = \ +LowVolumeFilter_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 6.0, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 10.0, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -7001,13 +5271,12 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, True, True, Liquid.WATER, False, False)] = ( - LowVolumeFilter_Water_DispenseSurface_Part -) = HamiltonLiquidClass( +vantage_mapping[(10, False, True, True, Liquid.WATER, False, False)] = \ +LowVolumeFilter_Water_DispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.2, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -7025,7 +5294,7 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -7046,17 +5315,9 @@ def get_vantage_liquid_class( # 5.0 1.08 -1.29 # 10.0 0.62 0.53 # -vantage_mapping[(10, False, True, False, Liquid.PLASMA, False, False)] = ( - LowVolumePlasmaDispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 5.9, - 0.5: 0.8, - 0.0: 0.0, - 1.0: 1.4, - 10.0: 11.5, - 2.0: 2.6, - }, +vantage_mapping[(10, False, True, False, Liquid.PLASMA, False, False)] = \ +LowVolumePlasmaDispenseSurface = HamiltonLiquidClass( + curve={5.0: 5.9, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 11.5, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -7073,21 +5334,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, True, False, Liquid.PLASMA, False, True)] = ( - LowVolumePlasmaDispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.6, - 0.5: 0.2, - 0.0: 0.0, - 1.0: 0.9, - 10.0: 11.3, - 2.0: 2.2, - }, +vantage_mapping[(10, False, True, False, Liquid.PLASMA, False, True)] = \ +LowVolumePlasmaDispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.6, 0.5: 0.2, 0.0: 0.0, 1.0: 0.9, 10.0: 11.3, 2.0: 2.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -7104,13 +5357,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, True, False, Liquid.PLASMA, False, False)] = ( - LowVolumePlasmaDispenseSurface_Part -) = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.PLASMA, False, False)] = \ +LowVolumePlasmaDispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.3, 10.0: 11.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7128,7 +5380,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -7149,17 +5401,9 @@ def get_vantage_liquid_class( # 5.0 1.08 -1.29 # 10.0 0.62 0.53 # -vantage_mapping[(10, False, True, False, Liquid.SERUM, False, False)] = ( - LowVolumeSerumDispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 5.6, - 0.5: 0.2, - 0.0: 0.0, - 1.0: 0.9, - 10.0: 11.3, - 2.0: 2.2, - }, +vantage_mapping[(10, False, True, False, Liquid.SERUM, False, False)] = \ +LowVolumeSerumDispenseSurface = HamiltonLiquidClass( + curve={5.0: 5.6, 0.5: 0.2, 0.0: 0.0, 1.0: 0.9, 10.0: 11.3, 2.0: 2.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -7176,21 +5420,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, True, False, Liquid.SERUM, False, True)] = ( - LowVolumeSerumDispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.6, - 0.5: 0.2, - 0.0: 0.0, - 1.0: 0.9, - 10.0: 11.3, - 2.0: 2.2, - }, +vantage_mapping[(10, False, True, False, Liquid.SERUM, False, True)] = \ +LowVolumeSerumDispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.6, 0.5: 0.2, 0.0: 0.0, 1.0: 0.9, 10.0: 11.3, 2.0: 2.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -7207,13 +5443,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, True, False, Liquid.SERUM, False, False)] = ( - LowVolumeSerumDispenseSurface_Part -) = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.SERUM, False, False)] = \ +LowVolumeSerumDispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.3, 10.0: 11.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7231,13 +5466,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, True, True, False, Liquid.DMSO, False, True)] = ( - LowVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( +vantage_mapping[(10, True, True, False, Liquid.DMSO, False, True)] = \ +LowVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 5.3, 0.0: 0.0, 1.0: 0.8, 10.0: 10.6}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -7255,13 +5489,12 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, True, True, False, Liquid.WATER, False, True)] = ( - LowVolume_96COREHead1000ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( +vantage_mapping[(10, True, True, False, Liquid.WATER, False, True)] = \ +LowVolume_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 5.8, 0.0: 0.0, 1.0: 1.0, 10.0: 11.2}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -7279,13 +5512,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, True, True, False, Liquid.DMSO, False, True)] = ( - LowVolume_96COREHead_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( +vantage_mapping[(10, True, True, False, Liquid.DMSO, False, True)] = \ +LowVolume_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 5.1, 0.0: 0.0, 1.0: 0.8, 10.0: 10.3}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -7303,13 +5535,12 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, True, True, False, Liquid.DMSO, False, False)] = ( - LowVolume_96COREHead_DMSO_DispenseSurface_Part -) = HamiltonLiquidClass( +vantage_mapping[(10, True, True, False, Liquid.DMSO, False, False)] = \ +LowVolume_96COREHead_DMSO_DispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.5, 10.0: 11.0}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -7327,13 +5558,12 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, True, True, False, Liquid.WATER, False, True)] = ( - LowVolume_96COREHead_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( +vantage_mapping[(10, True, True, False, Liquid.WATER, False, True)] = \ +LowVolume_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 5.8, 0.0: 0.0, 1.0: 1.3, 10.0: 11.1}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -7351,13 +5581,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, True, True, False, Liquid.WATER, False, False)] = ( - LowVolume_96COREHead_Water_DispenseSurface_Part -) = HamiltonLiquidClass( +vantage_mapping[(10, True, True, False, Liquid.WATER, False, False)] = \ +LowVolume_96COREHead_Water_DispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 5.7, 0.0: 0.0, 1.0: 1.4, 10.0: 10.8}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -7375,22 +5604,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # Liquid class for wash low volume tips with CO-RE 96 Head in CO-RE 96 Head Washer. -vantage_mapping[(10, True, True, False, Liquid.WATER, False, False)] = ( - LowVolume_Core96Washer_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 6.0, - 0.5: 0.8, - 0.0: 0.0, - 1.0: 1.4, - 10.0: 15.0, - 2.0: 2.6, - }, +vantage_mapping[(10, True, True, False, Liquid.WATER, False, False)] = \ +LowVolume_Core96Washer_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 6.0, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 15.0, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=150.0, aspiration_air_transport_volume=0.0, @@ -7407,23 +5628,14 @@ def get_vantage_liquid_class( dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=56.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 75 -vantage_mapping[(10, False, True, False, Liquid.DMSO, False, False)] = ( - LowVolume_DMSO_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 5.9, - 15.0: 16.4, - 0.5: 0.8, - 0.0: 0.0, - 1.0: 1.4, - 10.0: 11.2, - 2.0: 2.6, - }, +vantage_mapping[(10, False, True, False, Liquid.DMSO, False, False)] = \ +LowVolume_DMSO_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 5.9, 15.0: 16.4, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 11.2, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -7440,21 +5652,13 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=56.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, True, False, Liquid.DMSO, False, True)] = ( - LowVolume_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.9, - 0.5: 0.8, - 0.0: 0.0, - 1.0: 1.4, - 10.0: 11.2, - 2.0: 2.6, - }, +vantage_mapping[(10, False, True, False, Liquid.DMSO, False, True)] = \ +LowVolume_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.9, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 11.2, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -7471,13 +5675,12 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, True, False, Liquid.DMSO, False, False)] = ( - LowVolume_DMSO_DispenseSurface_Part -) = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.DMSO, False, False)] = \ +LowVolume_DMSO_DispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.4, 10.0: 11.2, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -7495,22 +5698,14 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 75 -vantage_mapping[(10, False, True, False, Liquid.ETHANOL, False, False)] = ( - LowVolume_EtOH_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 8.4, - 0.5: 1.9, - 0.0: 0.0, - 1.0: 2.7, - 10.0: 13.0, - 2.0: 4.1, - }, +vantage_mapping[(10, False, True, False, Liquid.ETHANOL, False, False)] = \ +LowVolume_EtOH_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 8.4, 0.5: 1.9, 0.0: 0.0, 1.0: 2.7, 10.0: 13.0, 2.0: 4.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=2.0, @@ -7527,13 +5722,12 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, True, False, Liquid.ETHANOL, False, True)] = ( - LowVolume_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.ETHANOL, False, True)] = \ +LowVolume_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( curve={5.0: 7.3, 0.0: 0.0, 1.0: 2.4, 10.0: 13.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -7551,13 +5745,12 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, True, False, Liquid.ETHANOL, False, False)] = ( - LowVolume_EtOH_DispenseSurface_Part -) = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.ETHANOL, False, False)] = \ +LowVolume_EtOH_DispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 7.0, 0.0: 0.0, 1.0: 2.4, 10.0: 13.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -7575,23 +5768,14 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 10 -vantage_mapping[(10, False, True, False, Liquid.GLYCERIN, False, False)] = ( - LowVolume_Glycerin_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 6.5, - 15.0: 17.0, - 0.5: 1.4, - 0.0: 0.0, - 1.0: 2.0, - 10.0: 11.8, - 2.0: 3.2, - }, +vantage_mapping[(10, False, True, False, Liquid.GLYCERIN, False, False)] = \ +LowVolume_Glycerin_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 6.5, 15.0: 17.0, 0.5: 1.4, 0.0: 0.0, 1.0: 2.0, 10.0: 11.8, 2.0: 3.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -7608,23 +5792,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 75 -vantage_mapping[(10, False, True, False, Liquid.WATER, False, False)] = ( - LowVolume_Water_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 6.0, - 15.0: 16.7, - 0.5: 0.8, - 0.0: 0.0, - 1.0: 1.4, - 10.0: 11.5, - 2.0: 2.6, - }, +vantage_mapping[(10, False, True, False, Liquid.WATER, False, False)] = \ +LowVolume_Water_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 6.0, 15.0: 16.7, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 11.5, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -7641,13 +5816,12 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=56.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, True, True, False, Liquid.WATER, False, False)] = ( - LowVolume_Water_DispenseSurface96Head -) = HamiltonLiquidClass( +vantage_mapping[(10, True, True, False, Liquid.WATER, False, False)] = \ +LowVolume_Water_DispenseSurface96Head = HamiltonLiquidClass( curve={5.0: 6.0, 0.0: 0.0, 1.0: 1.0, 10.0: 11.5}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -7665,13 +5839,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, True, True, False, Liquid.WATER, False, True)] = ( - LowVolume_Water_DispenseSurfaceEmpty96Head -) = HamiltonLiquidClass( +vantage_mapping[(10, True, True, False, Liquid.WATER, False, True)] = \ +LowVolume_Water_DispenseSurfaceEmpty96Head = HamiltonLiquidClass( curve={5.0: 6.0, 0.0: 0.0, 1.0: 1.0, 10.0: 10.9}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -7689,13 +5862,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, True, True, False, Liquid.WATER, False, False)] = ( - LowVolume_Water_DispenseSurfacePart96Head -) = HamiltonLiquidClass( +vantage_mapping[(10, True, True, False, Liquid.WATER, False, False)] = \ +LowVolume_Water_DispenseSurfacePart96Head = HamiltonLiquidClass( curve={5.0: 6.0, 0.0: 0.0, 1.0: 1.0, 10.0: 10.9}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -7713,21 +5885,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, True, False, Liquid.WATER, False, True)] = ( - LowVolume_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 6.0, - 0.5: 0.8, - 0.0: 0.0, - 1.0: 1.4, - 10.0: 11.5, - 2.0: 2.6, - }, +vantage_mapping[(10, False, True, False, Liquid.WATER, False, True)] = \ +LowVolume_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 6.0, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 11.5, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -7744,13 +5908,12 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(10, False, True, False, Liquid.WATER, False, False)] = ( - LowVolume_Water_DispenseSurface_Part -) = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.WATER, False, False)] = \ +LowVolume_Water_DispenseSurface_Part = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.2, 10.0: 11.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -7768,7 +5931,7 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -7784,9 +5947,8 @@ def get_vantage_liquid_class( # 12 x 20ul = approximately 19.2 ul # 4 x 50 ul = approximately 48.1 ul # 2 x 100 ul = approximately 95.3 ul -vantage_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = ( - SlimTipFilter_96COREHead1000ul_DMSO_DispenseJet_Aliquot -) = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = \ +SlimTipFilter_96COREHead1000ul_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, @@ -7804,21 +5966,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=18.0, + dispense_stop_back_volume=18.0 ) -vantage_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = ( - SlimTipFilter_96COREHead1000ul_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 312.3, - 50.0: 55.3, - 0.0: 0.0, - 100.0: 107.7, - 20.0: 22.4, - 200.0: 210.5, - }, +vantage_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = \ +SlimTipFilter_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 312.3, 50.0: 55.3, 0.0: 0.0, 100.0: 107.7, 20.0: 22.4, 200.0: 210.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -7835,22 +5989,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = ( - SlimTipFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 311.9, - 50.0: 54.1, - 0.0: 0.0, - 100.0: 107.5, - 20.0: 22.5, - 10.0: 11.1, - 200.0: 209.4, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = \ +SlimTipFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 311.9, 50.0: 54.1, 0.0: 0.0, 100.0: 107.5, 20.0: 22.5, 10.0: 11.1, 200.0: 209.4}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=1.0, @@ -7867,7 +6012,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -7884,17 +6029,9 @@ def get_vantage_liquid_class( # 4 x 50 ul = approximately 48.9 ul # 2 x 100 ul = approximately 97.2 ul # -vantage_mapping[(300, True, True, True, Liquid.WATER, True, False)] = ( - SlimTipFilter_96COREHead1000ul_Water_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 50.0: 50.0, - 30.0: 30.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - }, +vantage_mapping[(300, True, True, True, Liquid.WATER, True, False)] = \ +SlimTipFilter_96COREHead1000ul_Water_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=5.0, @@ -7911,21 +6048,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -vantage_mapping[(300, True, True, True, Liquid.WATER, True, True)] = ( - SlimTipFilter_96COREHead1000ul_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 317.0, - 50.0: 55.8, - 0.0: 0.0, - 100.0: 109.4, - 20.0: 22.7, - 200.0: 213.7, - }, +vantage_mapping[(300, True, True, True, Liquid.WATER, True, True)] = \ +SlimTipFilter_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 317.0, 50.0: 55.8, 0.0: 0.0, 100.0: 109.4, 20.0: 22.7, 200.0: 213.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -7942,21 +6071,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, True, Liquid.WATER, False, True)] = ( - SlimTipFilter_96COREHead1000ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 318.7, - 50.0: 54.9, - 0.0: 0.0, - 100.0: 110.4, - 10.0: 11.7, - 200.0: 210.5, - }, +vantage_mapping[(300, True, True, True, Liquid.WATER, False, True)] = \ +SlimTipFilter_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 318.7, 50.0: 54.9, 0.0: 0.0, 100.0: 110.4, 10.0: 11.7, 200.0: 210.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -7973,7 +6094,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -7990,9 +6111,8 @@ def get_vantage_liquid_class( # 4 x 50 ul = approximately 48.3 ul # 2 x 100 ul = approximately 95.7 ul # -vantage_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = ( - SlimTipFilter_DMSO_DispenseJet_Aliquot -) = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = \ +SlimTipFilter_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -8010,21 +6130,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=18.0, + dispense_stop_back_volume=18.0 ) -vantage_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = ( - SlimTipFilter_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 309.5, - 50.0: 54.4, - 0.0: 0.0, - 100.0: 106.4, - 20.0: 22.1, - 200.0: 208.2, - }, +vantage_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = \ +SlimTipFilter_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 309.5, 50.0: 54.4, 0.0: 0.0, 100.0: 106.4, 20.0: 22.1, 200.0: 208.2}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -8041,23 +6153,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = ( - SlimTipFilter_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 309.7, - 5.0: 5.6, - 50.0: 53.8, - 0.0: 0.0, - 100.0: 105.4, - 20.0: 22.2, - 10.0: 11.3, - 200.0: 207.5, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = \ +SlimTipFilter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 309.7, 5.0: 5.6, 50.0: 53.8, 0.0: 0.0, 100.0: 105.4, 20.0: 22.2, 10.0: 11.3, 200.0: 207.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=1.0, @@ -8074,7 +6176,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -8090,16 +6192,9 @@ def get_vantage_liquid_class( # 12 x 20ul = approximately 21.3 ul # 4 x 50 ul = approximately 54.3 ul # 2 x 100 ul = approximately 105.2 ul -vantage_mapping[(300, True, True, True, Liquid.ETHANOL, True, False)] = ( - SlimTipFilter_EtOH_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 50.0: 50.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - }, +vantage_mapping[(300, True, True, True, Liquid.ETHANOL, True, False)] = \ +SlimTipFilter_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 50.0: 50.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -8116,21 +6211,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -vantage_mapping[(300, True, True, True, Liquid.ETHANOL, True, True)] = ( - SlimTipFilter_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 320.4, - 50.0: 57.2, - 0.0: 0.0, - 100.0: 110.5, - 20.0: 24.5, - 200.0: 215.0, - }, +vantage_mapping[(300, True, True, True, Liquid.ETHANOL, True, True)] = \ +SlimTipFilter_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 320.4, 50.0: 57.2, 0.0: 0.0, 100.0: 110.5, 20.0: 24.5, 200.0: 215.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -8147,22 +6234,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, True, True, True, Liquid.ETHANOL, False, True)] = ( - SlimTipFilter_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.9, - 50.0: 55.4, - 0.0: 0.0, - 100.0: 107.7, - 20.0: 23.2, - 10.0: 12.4, - 200.0: 210.6, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, True, True, True, Liquid.ETHANOL, False, True)] = \ +SlimTipFilter_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 313.9, 50.0: 55.4, 0.0: 0.0, 100.0: 107.7, 20.0: 23.2, 10.0: 12.4, 200.0: 210.6}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=2.0, @@ -8179,22 +6257,13 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, True, True, True, Liquid.GLYCERIN80, False, True)] = ( - SlimTipFilter_Glycerin_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 312.0, - 50.0: 55.0, - 0.0: 0.0, - 100.0: 107.8, - 20.0: 22.9, - 10.0: 11.8, - 200.0: 210.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, True, True, True, Liquid.GLYCERIN80, False, True)] = \ +SlimTipFilter_Glycerin_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 312.0, 50.0: 55.0, 0.0: 0.0, 100.0: 107.8, 20.0: 22.9, 10.0: 11.8, 200.0: 210.0}, aspiration_flow_rate=30.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=0.0, @@ -8211,7 +6280,7 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=2.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -8227,17 +6296,9 @@ def get_vantage_liquid_class( # 12 x 20ul = approximately 19.6 ul # 4 x 50 ul = approximately 49.2 ul # 2 x 100 ul = approximately 97.5 ul -vantage_mapping[(300, True, True, True, Liquid.WATER, True, False)] = ( - SlimTipFilter_Water_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 50.0: 50.0, - 30.0: 30.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - }, +vantage_mapping[(300, True, True, True, Liquid.WATER, True, False)] = \ +SlimTipFilter_Water_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=3.0, @@ -8254,21 +6315,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -vantage_mapping[(300, True, True, True, Liquid.WATER, True, True)] = ( - SlimTipFilter_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 317.2, - 50.0: 55.6, - 0.0: 0.0, - 100.0: 108.6, - 20.0: 22.6, - 200.0: 212.8, - }, +vantage_mapping[(300, True, True, True, Liquid.WATER, True, True)] = \ +SlimTipFilter_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 317.2, 50.0: 55.6, 0.0: 0.0, 100.0: 108.6, 20.0: 22.6, 200.0: 212.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -8285,23 +6338,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, True, True, True, Liquid.WATER, False, True)] = ( - SlimTipFilter_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 314.1, - 5.0: 6.2, - 50.0: 54.7, - 0.0: 0.0, - 100.0: 108.0, - 20.0: 22.7, - 10.0: 11.9, - 200.0: 211.3, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, True, True, True, Liquid.WATER, False, True)] = \ +SlimTipFilter_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 314.1, 5.0: 6.2, 50.0: 54.7, 0.0: 0.0, 100.0: 108.0, 20.0: 22.7, 10.0: 11.9, 200.0: 211.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -8318,7 +6361,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -8334,16 +6377,9 @@ def get_vantage_liquid_class( # 12 x 20ul = approximately 19.2 ul # 4 x 50 ul = approximately 48.1 ul # 2 x 100 ul = approximately 95.3 ul -vantage_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = ( - SlimTip_96COREHead1000ul_DMSO_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 50.0: 50.0, - 30.0: 30.0, - 0.0: 0.0, - 20.0: 20.0, - }, +vantage_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ +SlimTip_96COREHead1000ul_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=5.0, @@ -8360,21 +6396,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=18.0, + dispense_stop_back_volume=18.0 ) -vantage_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = ( - SlimTip_96COREHead1000ul_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.8, - 50.0: 55.8, - 0.0: 0.0, - 100.0: 109.2, - 20.0: 23.1, - 200.0: 212.7, - }, +vantage_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ +SlimTip_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 313.8, 50.0: 55.8, 0.0: 0.0, 100.0: 109.2, 20.0: 23.1, 200.0: 212.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -8391,22 +6419,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = ( - SlimTip_96COREHead1000ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 312.9, - 50.0: 54.1, - 0.0: 0.0, - 20.0: 22.5, - 100.0: 108.8, - 200.0: 210.9, - 10.0: 11.1, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ +SlimTip_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 312.9, 50.0: 54.1, 0.0: 0.0, 20.0: 22.5, 100.0: 108.8, 200.0: 210.9, 10.0: 11.1}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=1.0, @@ -8423,7 +6442,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -8439,16 +6458,9 @@ def get_vantage_liquid_class( # 12 x 20ul = approximately 21.8 ul # 4 x 50 ul = approximately 53.6 ul # 2 x 100 ul = approximately 105.2 ul -vantage_mapping[(300, True, True, False, Liquid.ETHANOL, True, False)] = ( - SlimTip_96COREHead1000ul_EtOH_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 50.0: 50.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - }, +vantage_mapping[(300, True, True, False, Liquid.ETHANOL, True, False)] = \ +SlimTip_96COREHead1000ul_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 50.0: 50.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -8465,21 +6477,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=80.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -vantage_mapping[(300, True, True, False, Liquid.ETHANOL, True, True)] = ( - SlimTip_96COREHead1000ul_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 326.2, - 50.0: 58.8, - 0.0: 0.0, - 100.0: 112.7, - 20.0: 25.0, - 200.0: 218.2, - }, +vantage_mapping[(300, True, True, False, Liquid.ETHANOL, True, True)] = \ +SlimTip_96COREHead1000ul_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 326.2, 50.0: 58.8, 0.0: 0.0, 100.0: 112.7, 20.0: 25.0, 200.0: 218.2}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -8496,21 +6500,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, False, Liquid.ETHANOL, False, True)] = ( - SlimTip_96COREHead1000ul_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 320.3, - 50.0: 56.7, - 0.0: 0.0, - 100.0: 109.5, - 10.0: 12.4, - 200.0: 213.9, - }, +vantage_mapping[(300, True, True, False, Liquid.ETHANOL, False, True)] = \ +SlimTip_96COREHead1000ul_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 320.3, 50.0: 56.7, 0.0: 0.0, 100.0: 109.5, 10.0: 12.4, 200.0: 213.9}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=2.0, @@ -8527,22 +6523,13 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=2.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, True, True, False, Liquid.GLYCERIN80, False, True)] = ( - SlimTip_96COREHead1000ul_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 319.3, - 50.0: 58.2, - 0.0: 0.0, - 100.0: 112.1, - 20.0: 23.9, - 10.0: 12.1, - 200.0: 216.9, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, True, True, False, Liquid.GLYCERIN80, False, True)] = \ +SlimTip_96COREHead1000ul_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 319.3, 50.0: 58.2, 0.0: 0.0, 100.0: 112.1, 20.0: 23.9, 10.0: 12.1, 200.0: 216.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -8559,7 +6546,7 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=2.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -8576,17 +6563,9 @@ def get_vantage_liquid_class( # 4 x 50 ul = approximately 48.9 ul # 2 x 100 ul = approximately 97.2 ul # -vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( - SlimTip_96COREHead1000ul_Water_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 50.0: 50.0, - 30.0: 30.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - }, +vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ +SlimTip_96COREHead1000ul_Water_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=5.0, @@ -8603,21 +6582,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( - SlimTip_96COREHead1000ul_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 315.0, - 50.0: 55.5, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 22.8, - 200.0: 211.0, - }, +vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ +SlimTip_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 315.0, 50.0: 55.5, 0.0: 0.0, 100.0: 107.2, 20.0: 22.8, 200.0: 211.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -8634,21 +6605,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( - SlimTip_96COREHead1000ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 322.7, - 50.0: 56.4, - 0.0: 0.0, - 100.0: 110.4, - 10.0: 11.9, - 200.0: 215.5, - }, +vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ +SlimTip_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 322.7, 50.0: 56.4, 0.0: 0.0, 100.0: 110.4, 10.0: 11.9, 200.0: 215.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -8665,7 +6628,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -8682,9 +6645,8 @@ def get_vantage_liquid_class( # 4 x 50 ul = approximately 48.3 ul # 2 x 100 ul = approximately 95.7 ul # -vantage_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = ( - SlimTip_DMSO_DispenseJet_Aliquot -) = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ +SlimTip_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -8702,21 +6664,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=18.0, + dispense_stop_back_volume=18.0 ) -vantage_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = ( - SlimTip_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 309.5, - 50.0: 54.7, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 22.5, - 200.0: 209.7, - }, +vantage_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ +SlimTip_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 309.5, 50.0: 54.7, 0.0: 0.0, 100.0: 107.2, 20.0: 22.5, 200.0: 209.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -8733,23 +6687,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = ( - SlimTip_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 310.2, - 5.0: 5.6, - 50.0: 54.1, - 0.0: 0.0, - 100.0: 106.2, - 20.0: 22.5, - 10.0: 11.3, - 200.0: 208.7, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ +SlimTip_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 310.2, 5.0: 5.6, 50.0: 54.1, 0.0: 0.0, 100.0: 106.2, 20.0: 22.5, 10.0: 11.3, 200.0: 208.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=1.0, @@ -8766,7 +6710,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -8782,16 +6726,9 @@ def get_vantage_liquid_class( # 12 x 20ul = approximately 21.3 ul # 4 x 50 ul = approximately 54.3 ul # 2 x 100 ul = approximately 105.2 ul -vantage_mapping[(300, True, True, False, Liquid.ETHANOL, True, False)] = ( - SlimTip_EtOH_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 50.0: 50.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - }, +vantage_mapping[(300, True, True, False, Liquid.ETHANOL, True, False)] = \ +SlimTip_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 50.0: 50.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -8808,21 +6745,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -vantage_mapping[(300, True, True, False, Liquid.ETHANOL, True, True)] = ( - SlimTip_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 323.4, - 50.0: 57.2, - 0.0: 0.0, - 100.0: 110.5, - 20.0: 24.7, - 200.0: 211.9, - }, +vantage_mapping[(300, True, True, False, Liquid.ETHANOL, True, True)] = \ +SlimTip_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 323.4, 50.0: 57.2, 0.0: 0.0, 100.0: 110.5, 20.0: 24.7, 200.0: 211.9}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -8839,23 +6768,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, True, True, False, Liquid.ETHANOL, False, True)] = ( - SlimTip_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 312.9, - 5.0: 6.2, - 50.0: 55.4, - 0.0: 0.0, - 100.0: 107.7, - 20.0: 23.2, - 10.0: 11.9, - 200.0: 210.6, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, True, True, False, Liquid.ETHANOL, False, True)] = \ +SlimTip_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 312.9, 5.0: 6.2, 50.0: 55.4, 0.0: 0.0, 100.0: 107.7, 20.0: 23.2, 10.0: 11.9, 200.0: 210.6}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=2.0, @@ -8872,23 +6791,13 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, True, True, False, Liquid.GLYCERIN80, False, True)] = ( - SlimTip_Glycerin_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.3, - 5.0: 6.0, - 50.0: 55.7, - 0.0: 0.0, - 100.0: 107.8, - 20.0: 22.9, - 10.0: 11.5, - 200.0: 210.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, True, True, False, Liquid.GLYCERIN80, False, True)] = \ +SlimTip_Glycerin_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 313.3, 5.0: 6.0, 50.0: 55.7, 0.0: 0.0, 100.0: 107.8, 20.0: 22.9, 10.0: 11.5, 200.0: 210.0}, aspiration_flow_rate=30.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=0.0, @@ -8905,7 +6814,7 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=2.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -8921,9 +6830,8 @@ def get_vantage_liquid_class( # 12 x 20ul = approximately 19.6 ul # 4 x 50 ul = approximately 50.0 ul # 2 x 100 ul = approximately 98.4 ul -vantage_mapping[(300, True, True, False, Liquid.SERUM, True, False)] = ( - SlimTip_Serum_DispenseJet_Aliquot -) = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.SERUM, True, False)] = \ +SlimTip_Serum_DispenseJet_Aliquot = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -8941,21 +6849,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -vantage_mapping[(300, True, True, False, Liquid.SERUM, True, True)] = ( - SlimTip_Serum_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 321.5, - 50.0: 56.0, - 0.0: 0.0, - 100.0: 109.7, - 20.0: 22.8, - 200.0: 215.7, - }, +vantage_mapping[(300, True, True, False, Liquid.SERUM, True, True)] = \ +SlimTip_Serum_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 321.5, 50.0: 56.0, 0.0: 0.0, 100.0: 109.7, 20.0: 22.8, 200.0: 215.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -8972,23 +6872,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, True, True, False, Liquid.SERUM, False, True)] = ( - SlimTip_Serum_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 320.2, - 5.0: 5.5, - 50.0: 55.4, - 0.0: 0.0, - 20.0: 22.6, - 100.0: 109.7, - 200.0: 214.9, - 10.0: 11.3, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, True, True, False, Liquid.SERUM, False, True)] = \ +SlimTip_Serum_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 320.2, 5.0: 5.5, 50.0: 55.4, 0.0: 0.0, 20.0: 22.6, 100.0: 109.7, 200.0: 214.9, 10.0: 11.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=1.0, @@ -9005,7 +6895,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -9021,17 +6911,9 @@ def get_vantage_liquid_class( # 12 x 20ul = approximately 19.6 ul # 4 x 50 ul = approximately 49.2 ul # 2 x 100 ul = approximately 97.5 ul -vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( - SlimTip_Water_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 50.0: 50.0, - 30.0: 30.0, - 0.0: 0.0, - 100.0: 100.0, - 20.0: 20.0, - }, +vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ +SlimTip_Water_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=3.0, @@ -9048,21 +6930,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( - SlimTip_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 317.2, - 50.0: 55.6, - 0.0: 0.0, - 20.0: 22.6, - 100.0: 108.6, - 200.0: 212.8, - }, +vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ +SlimTip_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 317.2, 50.0: 55.6, 0.0: 0.0, 20.0: 22.6, 100.0: 108.6, 200.0: 212.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -9079,23 +6953,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( - SlimTip_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 317.1, - 5.0: 6.2, - 50.0: 55.1, - 0.0: 0.0, - 100.0: 108.0, - 20.0: 22.9, - 10.0: 11.9, - 200.0: 213.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ +SlimTip_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 317.1, 5.0: 6.2, 50.0: 55.1, 0.0: 0.0, 100.0: 108.0, 20.0: 22.9, 10.0: 11.9, 200.0: 213.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -9112,22 +6976,15 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 80 # V1.2: Stop back volume = 0 (previous value: 15) -vantage_mapping[(300, False, False, False, Liquid.WATER, True, False)] = ( - StandardNeedle_Water_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 311.2, - 50.0: 51.3, - 0.0: 0.0, - 100.0: 103.4, - 20.0: 19.5, - }, +vantage_mapping[(300, False, False, False, Liquid.WATER, True, False)] = \ +StandardNeedle_Water_DispenseJet = HamiltonLiquidClass( + curve={300.0: 311.2, 50.0: 51.3, 0.0: 0.0, 100.0: 103.4, 20.0: 19.5}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=10.0, @@ -9144,20 +7001,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, False, False, Liquid.WATER, True, True)] = ( - StandardNeedle_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 311.2, - 50.0: 51.3, - 0.0: 0.0, - 100.0: 103.4, - 20.0: 19.5, - }, +vantage_mapping[(300, False, False, False, Liquid.WATER, True, True)] = \ +StandardNeedle_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 311.2, 50.0: 51.3, 0.0: 0.0, 100.0: 103.4, 20.0: 19.5}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=10.0, @@ -9174,20 +7024,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, False, False, Liquid.WATER, True, False)] = ( - StandardNeedle_Water_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 311.2, - 50.0: 51.3, - 0.0: 0.0, - 100.0: 103.4, - 20.0: 19.5, - }, +vantage_mapping[(300, False, False, False, Liquid.WATER, True, False)] = \ +StandardNeedle_Water_DispenseJet_Part = HamiltonLiquidClass( + curve={300.0: 311.2, 50.0: 51.3, 0.0: 0.0, 100.0: 103.4, 20.0: 19.5}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=10.0, @@ -9204,25 +7047,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, False, False, False, Liquid.WATER, False, False)] = ( - StandardNeedle_Water_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 308.4, - 5.0: 6.5, - 50.0: 52.3, - 0.0: 0.0, - 100.0: 102.9, - 20.0: 22.3, - 1.0: 1.1, - 200.0: 205.8, - 10.0: 12.0, - 2.0: 2.1, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, False, False, False, Liquid.WATER, False, False)] = \ +StandardNeedle_Water_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 308.4, 5.0: 6.5, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 1.1, 200.0: 205.8, 10.0: 12.0, 2.0: 2.1}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=0.0, @@ -9239,25 +7070,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, False, False, False, Liquid.WATER, False, True)] = ( - StandardNeedle_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 308.4, - 5.0: 6.5, - 50.0: 52.3, - 0.0: 0.0, - 100.0: 102.9, - 20.0: 22.3, - 1.0: 1.1, - 200.0: 205.8, - 10.0: 12.0, - 2.0: 2.1, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, False, False, False, Liquid.WATER, False, True)] = \ +StandardNeedle_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 308.4, 5.0: 6.5, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 1.1, 200.0: 205.8, 10.0: 12.0, 2.0: 2.1}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=0.0, @@ -9274,25 +7093,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, False, False, False, Liquid.WATER, False, False)] = ( - StandardNeedle_Water_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 308.4, - 5.0: 6.5, - 50.0: 52.3, - 0.0: 0.0, - 100.0: 102.9, - 20.0: 22.3, - 1.0: 1.1, - 200.0: 205.8, - 10.0: 12.0, - 2.0: 2.1, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, False, False, False, Liquid.WATER, False, False)] = \ +StandardNeedle_Water_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 308.4, 5.0: 6.5, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 1.1, 200.0: 205.8, 10.0: 12.0, 2.0: 2.1}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=0.0, @@ -9309,7 +7116,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -9333,17 +7140,9 @@ def get_vantage_liquid_class( # 200 0.16 0.55 # 300 0.17 0.35 # -vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, False)] = ( - StandardVolumeAcetonitrilDispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 326.2, - 50.0: 57.3, - 0.0: 0.0, - 100.0: 111.5, - 20.0: 24.6, - 200.0: 217.0, - }, +vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, False)] = \ +StandardVolumeAcetonitrilDispenseJet = HamiltonLiquidClass( + curve={300.0: 326.2, 50.0: 57.3, 0.0: 0.0, 100.0: 111.5, 20.0: 24.6, 200.0: 217.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=25.0, @@ -9360,21 +7159,13 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, True)] = ( - StandardVolumeAcetonitrilDispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 326.2, - 50.0: 57.3, - 0.0: 0.0, - 100.0: 111.5, - 20.0: 24.6, - 200.0: 217.0, - }, +vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, True)] = \ +StandardVolumeAcetonitrilDispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 326.2, 50.0: 57.3, 0.0: 0.0, 100.0: 111.5, 20.0: 24.6, 200.0: 217.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=25.0, @@ -9391,13 +7182,12 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, False)] = ( - StandardVolumeAcetonitrilDispenseJet_Part -) = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, False)] = \ +StandardVolumeAcetonitrilDispenseJet_Part = HamiltonLiquidClass( curve={300.0: 321.2, 50.0: 57.3, 0.0: 0.0, 100.0: 110.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9415,7 +7205,7 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) @@ -9439,21 +7229,9 @@ def get_vantage_liquid_class( # 200 0.65 0.65 # 300 0.21 0.88 # -vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, False)] = ( - StandardVolumeAcetonitrilDispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 328.0, - 5.0: 6.8, - 50.0: 58.5, - 0.0: 0.0, - 100.0: 112.7, - 20.0: 24.8, - 1.0: 1.3, - 200.0: 220.0, - 10.0: 13.0, - 2.0: 3.0, - }, +vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, False)] = \ +StandardVolumeAcetonitrilDispenseSurface = HamiltonLiquidClass( + curve={300.0: 328.0, 5.0: 6.8, 50.0: 58.5, 0.0: 0.0, 100.0: 112.7, 20.0: 24.8, 1.0: 1.3, 200.0: 220.0, 10.0: 13.0, 2.0: 3.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=10.0, @@ -9470,25 +7248,13 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, True)] = ( - StandardVolumeAcetonitrilDispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 328.0, - 5.0: 6.8, - 50.0: 58.5, - 0.0: 0.0, - 100.0: 112.7, - 20.0: 24.8, - 1.0: 1.3, - 200.0: 220.0, - 10.0: 13.0, - 2.0: 3.0, - }, +vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, True)] = \ +StandardVolumeAcetonitrilDispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 328.0, 5.0: 6.8, 50.0: 58.5, 0.0: 0.0, 100.0: 112.7, 20.0: 24.8, 1.0: 1.3, 200.0: 220.0, 10.0: 13.0, 2.0: 3.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=10.0, @@ -9505,20 +7271,13 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, False)] = ( - StandardVolumeAcetonitrilDispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 328.0, - 5.0: 7.3, - 0.0: 0.0, - 100.0: 112.7, - 10.0: 13.5, - }, +vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, False)] = \ +StandardVolumeAcetonitrilDispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 328.0, 5.0: 7.3, 0.0: 0.0, 100.0: 112.7, 10.0: 13.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=10.0, @@ -9535,7 +7294,7 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -9555,9 +7314,8 @@ def get_vantage_liquid_class( # 20 (12 Aliquots) 2.53 -2.97 # 50 ( 4 Aliquots) 0.84 -2.57 # -vantage_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = ( - StandardVolumeDMSOAliquotJet -) = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = \ +StandardVolumeDMSOAliquotJet = HamiltonLiquidClass( curve={350.0: 350.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9575,7 +7333,7 @@ def get_vantage_liquid_class( dispense_swap_speed=0.3, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) @@ -9596,17 +7354,9 @@ def get_vantage_liquid_class( # 200 0.53 0.08 # 300 0.54 0.22 # -vantage_mapping[(300, False, True, False, Liquid.ETHANOL, False, False)] = ( - StandardVolumeEtOHDispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 309.2, - 50.0: 54.8, - 0.0: 0.0, - 100.0: 106.5, - 20.0: 23.7, - 200.0: 208.2, - }, +vantage_mapping[(300, False, True, False, Liquid.ETHANOL, False, False)] = \ +StandardVolumeEtOHDispenseSurface = HamiltonLiquidClass( + curve={300.0: 309.2, 50.0: 54.8, 0.0: 0.0, 100.0: 106.5, 20.0: 23.7, 200.0: 208.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=3.0, @@ -9623,21 +7373,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=0.4, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.ETHANOL, False, True)] = ( - StandardVolumeEtOHDispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 309.2, - 50.0: 54.8, - 0.0: 0.0, - 100.0: 106.5, - 20.0: 23.7, - 200.0: 208.2, - }, +vantage_mapping[(300, False, True, False, Liquid.ETHANOL, False, True)] = \ +StandardVolumeEtOHDispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 309.2, 50.0: 54.8, 0.0: 0.0, 100.0: 106.5, 20.0: 23.7, 200.0: 208.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=3.0, @@ -9654,13 +7396,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.ETHANOL, False, False)] = ( - StandardVolumeEtOHDispenseSurface_Part -) = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.ETHANOL, False, False)] = \ +StandardVolumeEtOHDispenseSurface_Part = HamiltonLiquidClass( curve={300.0: 315.2, 0.0: 0.0, 100.0: 108.5, 20.0: 23.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=50.0, @@ -9678,20 +7419,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = ( - StandardVolumeFilter_96COREHead1000ul_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 302.5, - 0.0: 0.0, - 100.0: 101.0, - 20.0: 20.4, - 200.0: 201.5, - }, +vantage_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = \ +StandardVolumeFilter_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 302.5, 0.0: 0.0, 100.0: 101.0, 20.0: 20.4, 200.0: 201.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -9708,20 +7442,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = ( - StandardVolumeFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 306.0, - 0.0: 0.0, - 100.0: 104.3, - 200.0: 205.0, - 10.0: 12.2, - }, +vantage_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = \ +StandardVolumeFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 306.0, 0.0: 0.0, 100.0: 104.3, 200.0: 205.0, 10.0: 12.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -9738,20 +7465,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, True, Liquid.WATER, True, True)] = ( - StandardVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 23.2, - 200.0: 211.0, - }, +vantage_mapping[(300, True, True, True, Liquid.WATER, True, True)] = \ +StandardVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -9768,20 +7488,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, True, Liquid.WATER, False, True)] = ( - StandardVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 0.0: 0.0, - 100.0: 107.2, - 200.0: 210.0, - 10.0: 11.9, - }, +vantage_mapping[(300, True, True, True, Liquid.WATER, False, True)] = \ +StandardVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 210.0, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -9798,20 +7511,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = ( - StandardVolumeFilter_96COREHead_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 303.5, - 0.0: 0.0, - 100.0: 101.8, - 10.0: 10.2, - 200.0: 200.5, - }, +vantage_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = \ +StandardVolumeFilter_96COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 303.5, 0.0: 0.0, 100.0: 101.8, 10.0: 10.2, 200.0: 200.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -9828,20 +7534,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = ( - StandardVolumeFilter_96COREHead_DMSO_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 305.0, - 0.0: 0.0, - 100.0: 103.6, - 10.0: 11.5, - 200.0: 206.0, - }, +vantage_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = \ +StandardVolumeFilter_96COREHead_DMSO_DispenseJet_Part = HamiltonLiquidClass( + curve={300.0: 305.0, 0.0: 0.0, 100.0: 103.6, 10.0: 11.5, 200.0: 206.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -9858,20 +7557,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -vantage_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = ( - StandardVolumeFilter_96COREHead_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 303.0, - 0.0: 0.0, - 100.0: 101.3, - 10.0: 10.6, - 200.0: 202.0, - }, +vantage_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = \ +StandardVolumeFilter_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 303.0, 0.0: 0.0, 100.0: 101.3, 10.0: 10.6, 200.0: 202.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -9888,20 +7580,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, True, Liquid.DMSO, False, False)] = ( - StandardVolumeFilter_96COREHead_DMSO_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 303.0, - 0.0: 0.0, - 100.0: 101.3, - 10.0: 10.1, - 200.0: 202.0, - }, +vantage_mapping[(300, True, True, True, Liquid.DMSO, False, False)] = \ +StandardVolumeFilter_96COREHead_DMSO_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 303.0, 0.0: 0.0, 100.0: 101.3, 10.0: 10.1, 200.0: 202.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -9918,21 +7603,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, True, Liquid.WATER, True, True)] = ( - StandardVolumeFilter_96COREHead_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 309.0, - 0.0: 0.0, - 20.0: 22.3, - 100.0: 104.2, - 10.0: 11.9, - 200.0: 207.0, - }, +vantage_mapping[(300, True, True, True, Liquid.WATER, True, True)] = \ +StandardVolumeFilter_96COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 309.0, 0.0: 0.0, 20.0: 22.3, 100.0: 104.2, 10.0: 11.9, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -9949,21 +7626,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, True, Liquid.WATER, True, False)] = ( - StandardVolumeFilter_96COREHead_Water_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 309.0, - 0.0: 0.0, - 20.0: 22.3, - 100.0: 104.2, - 10.0: 11.9, - 200.0: 207.0, - }, +vantage_mapping[(300, True, True, True, Liquid.WATER, True, False)] = \ +StandardVolumeFilter_96COREHead_Water_DispenseJet_Part = HamiltonLiquidClass( + curve={300.0: 309.0, 0.0: 0.0, 20.0: 22.3, 100.0: 104.2, 10.0: 11.9, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -9980,20 +7649,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -vantage_mapping[(300, True, True, True, Liquid.WATER, False, True)] = ( - StandardVolumeFilter_96COREHead_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 306.3, - 0.0: 0.0, - 100.0: 104.5, - 10.0: 11.9, - 200.0: 205.7, - }, +vantage_mapping[(300, True, True, True, Liquid.WATER, False, True)] = \ +StandardVolumeFilter_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 306.3, 0.0: 0.0, 100.0: 104.5, 10.0: 11.9, 200.0: 205.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10010,20 +7672,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, True, Liquid.WATER, False, False)] = ( - StandardVolumeFilter_96COREHead_Water_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 304.0, - 0.0: 0.0, - 100.0: 105.3, - 10.0: 11.9, - 200.0: 205.7, - }, +vantage_mapping[(300, True, True, True, Liquid.WATER, False, False)] = \ +StandardVolumeFilter_96COREHead_Water_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 304.0, 0.0: 0.0, 100.0: 105.3, 10.0: 11.9, 200.0: 205.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -10040,7 +7695,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -10060,16 +7715,9 @@ def get_vantage_liquid_class( # 20 (12 Aliquots) 2.53 -2.97 # 50 ( 4 Aliquots) 0.84 -2.57 # -vantage_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = ( - StandardVolumeFilter_DMSO_AliquotDispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 30.0: 30.0, - 0.0: 0.0, - 20.0: 20.0, - 10.0: 10.0, - }, +vantage_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = \ +StandardVolumeFilter_DMSO_AliquotDispenseJet_Part = HamiltonLiquidClass( + curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -10086,22 +7734,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = ( - StandardVolumeFilter_DMSO_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 304.6, - 50.0: 51.1, - 0.0: 0.0, - 20.0: 20.7, - 100.0: 101.8, - 200.0: 203.0, - }, +vantage_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = \ +StandardVolumeFilter_DMSO_DispenseJet = HamiltonLiquidClass( + curve={300.0: 304.6, 50.0: 51.1, 0.0: 0.0, 20.0: 20.7, 100.0: 101.8, 200.0: 203.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10118,21 +7758,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, True, Liquid.DMSO, True, True)] = ( - StandardVolumeFilter_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 304.6, - 50.0: 51.1, - 0.0: 0.0, - 100.0: 101.8, - 20.0: 20.7, - 200.0: 203.0, - }, +vantage_mapping[(300, False, True, True, Liquid.DMSO, True, True)] = \ +StandardVolumeFilter_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 304.6, 50.0: 51.1, 0.0: 0.0, 100.0: 101.8, 20.0: 20.7, 200.0: 203.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10149,13 +7781,12 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = ( - StandardVolumeFilter_DMSO_DispenseJet_Part -) = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = \ +StandardVolumeFilter_DMSO_DispenseJet_Part = HamiltonLiquidClass( curve={300.0: 315.6, 0.0: 0.0, 100.0: 112.8, 20.0: 29.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10173,25 +7804,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0, -) - - -vantage_mapping[(300, False, True, True, Liquid.DMSO, False, False)] = ( - StandardVolumeFilter_DMSO_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 308.8, - 5.0: 6.6, - 50.0: 52.9, - 0.0: 0.0, - 1.0: 1.8, - 20.0: 22.1, - 100.0: 103.8, - 2.0: 3.0, - 10.0: 11.9, - 200.0: 205.0, - }, + dispense_stop_back_volume=10.0 +) + + +vantage_mapping[(300, False, True, True, Liquid.DMSO, False, False)] = \ +StandardVolumeFilter_DMSO_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 308.8, 5.0: 6.6, 50.0: 52.9, 0.0: 0.0, 1.0: 1.8, 20.0: 22.1, 100.0: 103.8, 2.0: 3.0, 10.0: 11.9, 200.0: 205.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -10208,25 +7827,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, False, True, True, Liquid.DMSO, False, True)] = ( - StandardVolumeFilter_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 308.8, - 5.0: 6.6, - 50.0: 52.9, - 0.0: 0.0, - 1.0: 1.8, - 20.0: 22.1, - 100.0: 103.8, - 2.0: 3.0, - 10.0: 11.9, - 200.0: 205.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, False, True, True, Liquid.DMSO, False, True)] = \ +StandardVolumeFilter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 308.8, 5.0: 6.6, 50.0: 52.9, 0.0: 0.0, 1.0: 1.8, 20.0: 22.1, 100.0: 103.8, 2.0: 3.0, 10.0: 11.9, 200.0: 205.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -10243,22 +7850,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, True, Liquid.DMSO, False, False)] = ( - StandardVolumeFilter_DMSO_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 306.8, - 5.0: 6.4, - 50.0: 52.9, - 0.0: 0.0, - 100.0: 103.8, - 20.0: 22.1, - 10.0: 11.9, - }, +vantage_mapping[(300, False, True, True, Liquid.DMSO, False, False)] = \ +StandardVolumeFilter_DMSO_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 306.8, 5.0: 6.4, 50.0: 52.9, 0.0: 0.0, 100.0: 103.8, 20.0: 22.1, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -10275,22 +7873,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 100, Stop back volume=0 -vantage_mapping[(300, False, True, True, Liquid.ETHANOL, True, False)] = ( - StandardVolumeFilter_EtOH_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 310.2, - 50.0: 55.8, - 0.0: 0.0, - 20.0: 24.6, - 100.0: 107.5, - 200.0: 209.2, - }, +vantage_mapping[(300, False, True, True, Liquid.ETHANOL, True, False)] = \ +StandardVolumeFilter_EtOH_DispenseJet = HamiltonLiquidClass( + curve={300.0: 310.2, 50.0: 55.8, 0.0: 0.0, 20.0: 24.6, 100.0: 107.5, 200.0: 209.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10307,21 +7897,13 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, True, Liquid.ETHANOL, True, True)] = ( - StandardVolumeFilter_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 310.2, - 50.0: 55.8, - 0.0: 0.0, - 100.0: 107.5, - 20.0: 24.6, - 200.0: 209.2, - }, +vantage_mapping[(300, False, True, True, Liquid.ETHANOL, True, True)] = \ +StandardVolumeFilter_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 310.2, 50.0: 55.8, 0.0: 0.0, 100.0: 107.5, 20.0: 24.6, 200.0: 209.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10338,13 +7920,12 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, True, Liquid.ETHANOL, True, False)] = ( - StandardVolumeFilter_EtOH_DispenseJet_Part -) = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.ETHANOL, True, False)] = \ +StandardVolumeFilter_EtOH_DispenseJet_Part = HamiltonLiquidClass( curve={300.0: 317.2, 0.0: 0.0, 100.0: 110.5, 20.0: 25.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10362,22 +7943,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=5.0, + dispense_stop_back_volume=5.0 ) # V1.1: Set mix flow rate to 20, dispense settling time=0, Stop back volume=0 -vantage_mapping[(300, False, True, True, Liquid.GLYCERIN, True, False)] = ( - StandardVolumeFilter_Glycerin_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 309.0, - 50.0: 53.6, - 0.0: 0.0, - 20.0: 22.3, - 100.0: 104.9, - 200.0: 207.2, - }, +vantage_mapping[(300, False, True, True, Liquid.GLYCERIN, True, False)] = \ +StandardVolumeFilter_Glycerin_DispenseJet = HamiltonLiquidClass( + curve={300.0: 309.0, 50.0: 53.6, 0.0: 0.0, 20.0: 22.3, 100.0: 104.9, 200.0: 207.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=20.0, aspiration_air_transport_volume=5.0, @@ -10394,22 +7967,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 20, dispense settling time=0, Stop back volume=0 -vantage_mapping[(300, False, True, True, Liquid.GLYCERIN80, True, True)] = ( - StandardVolumeFilter_Glycerin_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 309.0, - 50.0: 53.6, - 0.0: 0.0, - 100.0: 104.9, - 20.0: 22.3, - 200.0: 207.2, - }, +vantage_mapping[(300, False, True, True, Liquid.GLYCERIN80, True, True)] = \ +StandardVolumeFilter_Glycerin_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 309.0, 50.0: 53.6, 0.0: 0.0, 100.0: 104.9, 20.0: 22.3, 200.0: 207.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=20.0, aspiration_air_transport_volume=5.0, @@ -10426,25 +7991,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 10 -vantage_mapping[(300, False, True, True, Liquid.GLYCERIN, False, False)] = ( - StandardVolumeFilter_Glycerin_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 307.9, - 5.0: 6.5, - 50.0: 53.6, - 0.0: 0.0, - 20.0: 22.5, - 100.0: 105.7, - 2.0: 3.2, - 10.0: 12.0, - 200.0: 207.0, - }, +vantage_mapping[(300, False, True, True, Liquid.GLYCERIN, False, False)] = \ +StandardVolumeFilter_Glycerin_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 307.9, 5.0: 6.5, 50.0: 53.6, 0.0: 0.0, 20.0: 22.5, 100.0: 105.7, 2.0: 3.2, 10.0: 12.0, 200.0: 207.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -10461,24 +8015,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, False, True, True, Liquid.GLYCERIN80, False, True)] = ( - StandardVolumeFilter_Glycerin_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 307.9, - 5.0: 6.5, - 50.0: 53.6, - 0.0: 0.0, - 100.0: 105.7, - 20.0: 22.5, - 200.0: 207.0, - 10.0: 12.0, - 2.0: 3.2, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, False, True, True, Liquid.GLYCERIN80, False, True)] = \ +StandardVolumeFilter_Glycerin_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 307.9, 5.0: 6.5, 50.0: 53.6, 0.0: 0.0, 100.0: 105.7, 20.0: 22.5, 200.0: 207.0, 10.0: 12.0, 2.0: 3.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -10495,21 +8038,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, True, Liquid.GLYCERIN80, False, False)] = ( - StandardVolumeFilter_Glycerin_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 307.9, - 5.0: 6.1, - 0.0: 0.0, - 100.0: 104.7, - 200.0: 207.0, - 10.0: 11.5, - }, +vantage_mapping[(300, False, True, True, Liquid.GLYCERIN80, False, False)] = \ +StandardVolumeFilter_Glycerin_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 307.9, 5.0: 6.1, 0.0: 0.0, 100.0: 104.7, 200.0: 207.0, 10.0: 11.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -10526,21 +8061,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = ( - StandardVolumeFilter_Serum_AliquotDispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 30.0: 30.0, - 0.0: 0.0, - 20.0: 20.0, - 10.0: 10.0, - }, +vantage_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = \ +StandardVolumeFilter_Serum_AliquotDispenseJet_Part = HamiltonLiquidClass( + curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -10557,14 +8085,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = ( - StandardVolumeFilter_Serum_AliquotJet -) = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = \ +StandardVolumeFilter_Serum_AliquotJet = HamiltonLiquidClass( curve={300.0: 300.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10582,22 +8109,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = ( - StandardVolumeFilter_Serum_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 315.2, - 50.0: 55.6, - 0.0: 0.0, - 20.0: 23.2, - 100.0: 108.1, - 200.0: 212.1, - }, +vantage_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = \ +StandardVolumeFilter_Serum_DispenseJet = HamiltonLiquidClass( + curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 20.0: 23.2, 100.0: 108.1, 200.0: 212.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10614,21 +8133,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, True, Liquid.SERUM, True, True)] = ( - StandardVolumeFilter_Serum_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 315.2, - 50.0: 55.6, - 0.0: 0.0, - 100.0: 108.1, - 20.0: 23.2, - 200.0: 212.1, - }, +vantage_mapping[(300, False, True, True, Liquid.SERUM, True, True)] = \ +StandardVolumeFilter_Serum_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 100.0: 108.1, 20.0: 23.2, 200.0: 212.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10645,13 +8156,12 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = ( - StandardVolumeFilter_Serum_DispenseJet_Part -) = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = \ +StandardVolumeFilter_Serum_DispenseJet_Part = HamiltonLiquidClass( curve={300.0: 315.2, 0.0: 0.0, 100.0: 111.5, 20.0: 29.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10669,24 +8179,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=5.0, + dispense_stop_back_volume=5.0 ) -vantage_mapping[(300, False, True, True, Liquid.SERUM, False, False)] = ( - StandardVolumeFilter_Serum_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 313.4, - 5.0: 6.3, - 50.0: 54.9, - 0.0: 0.0, - 20.0: 23.0, - 100.0: 107.1, - 2.0: 2.6, - 10.0: 12.0, - 200.0: 210.5, - }, +vantage_mapping[(300, False, True, True, Liquid.SERUM, False, False)] = \ +StandardVolumeFilter_Serum_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 313.4, 5.0: 6.3, 50.0: 54.9, 0.0: 0.0, 20.0: 23.0, 100.0: 107.1, 2.0: 2.6, 10.0: 12.0, 200.0: 210.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -10703,13 +8202,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, True, Liquid.SERUM, False, False)] = ( - StandardVolumeFilter_Serum_DispenseSurface_Part -) = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.SERUM, False, False)] = \ +StandardVolumeFilter_Serum_DispenseSurface_Part = HamiltonLiquidClass( curve={300.0: 313.4, 0.0: 0.0, 100.0: 109.1, 10.0: 12.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10727,21 +8225,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, True, Liquid.WATER, True, False)] = ( - StandardVolumeFilter_Water_AliquotDispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 30.0: 30.0, - 0.0: 0.0, - 20.0: 20.0, - 10.0: 10.0, - }, +vantage_mapping[(300, False, True, True, Liquid.WATER, True, False)] = \ +StandardVolumeFilter_Water_AliquotDispenseJet_Part = HamiltonLiquidClass( + curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -10758,14 +8249,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, True, Liquid.WATER, True, False)] = ( - StandardVolumeFilter_Water_AliquotJet -) = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.WATER, True, False)] = \ +StandardVolumeFilter_Water_AliquotJet = HamiltonLiquidClass( curve={300.0: 300.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10783,22 +8273,14 @@ def get_vantage_liquid_class( dispense_swap_speed=0.3, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, True, Liquid.WATER, True, False)] = ( - StandardVolumeFilter_Water_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 50.0: 55.1, - 0.0: 0.0, - 20.0: 23.2, - 100.0: 107.2, - 200.0: 211.0, - }, +vantage_mapping[(300, False, True, True, Liquid.WATER, True, False)] = \ +StandardVolumeFilter_Water_DispenseJet = HamiltonLiquidClass( + curve={300.0: 313.5, 50.0: 55.1, 0.0: 0.0, 20.0: 23.2, 100.0: 107.2, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10815,21 +8297,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, True, Liquid.WATER, True, True)] = ( - StandardVolumeFilter_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 50.0: 55.1, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 23.2, - 200.0: 211.0, - }, +vantage_mapping[(300, False, True, True, Liquid.WATER, True, True)] = \ +StandardVolumeFilter_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 313.5, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10846,13 +8320,12 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, True, Liquid.WATER, True, False)] = ( - StandardVolumeFilter_Water_DispenseJet_Part -) = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.WATER, True, False)] = \ +StandardVolumeFilter_Water_DispenseJet_Part = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 110.2, 20.0: 27.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10870,27 +8343,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, True, Liquid.WATER, False, False)] = ( - StandardVolumeFilter_Water_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 5.0: 6.3, - 0.5: 0.9, - 50.0: 55.1, - 0.0: 0.0, - 1.0: 1.6, - 20.0: 23.2, - 100.0: 107.2, - 2.0: 2.8, - 10.0: 11.9, - 200.0: 211.0, - }, +vantage_mapping[(300, False, True, True, Liquid.WATER, False, False)] = \ +StandardVolumeFilter_Water_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 313.5, 5.0: 6.3, 0.5: 0.9, 50.0: 55.1, 0.0: 0.0, 1.0: 1.6, 20.0: 23.2, 100.0: 107.2, 2.0: 2.8, 10.0: 11.9, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10907,26 +8367,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, True, Liquid.WATER, False, True)] = ( - StandardVolumeFilter_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 5.0: 6.3, - 0.5: 0.9, - 50.0: 55.1, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 23.2, - 1.0: 1.6, - 200.0: 211.0, - 10.0: 11.9, - 2.0: 2.8, - }, +vantage_mapping[(300, False, True, True, Liquid.WATER, False, True)] = \ +StandardVolumeFilter_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 313.5, 5.0: 6.3, 0.5: 0.9, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 1.0: 1.6, 200.0: 211.0, 10.0: 11.9, 2.0: 2.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10943,23 +8390,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, True, Liquid.WATER, False, False)] = ( - StandardVolumeFilter_Water_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 5.0: 6.5, - 50.0: 55.1, - 0.0: 0.0, - 20.0: 23.2, - 100.0: 107.2, - 10.0: 11.9, - 200.0: 211.0, - }, +vantage_mapping[(300, False, True, True, Liquid.WATER, False, False)] = \ +StandardVolumeFilter_Water_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 313.5, 5.0: 6.5, 50.0: 55.1, 0.0: 0.0, 20.0: 23.2, 100.0: 107.2, 10.0: 11.9, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -10976,7 +8413,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -11001,17 +8438,9 @@ def get_vantage_liquid_class( # 200 0.56 0.07 # 300 0.54 1.12 # -vantage_mapping[(300, False, True, False, Liquid.METHANOL, True, False)] = ( - StandardVolumeMeOHDispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 336.0, - 50.0: 63.0, - 0.0: 0.0, - 100.0: 119.5, - 20.0: 28.3, - 200.0: 230.0, - }, +vantage_mapping[(300, False, True, False, Liquid.METHANOL, True, False)] = \ +StandardVolumeMeOHDispenseJet = HamiltonLiquidClass( + curve={300.0: 336.0, 50.0: 63.0, 0.0: 0.0, 100.0: 119.5, 20.0: 28.3, 200.0: 230.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=5.0, @@ -11028,7 +8457,7 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -11055,19 +8484,9 @@ def get_vantage_liquid_class( # 200 0.51 0.59 # 300 0.81 0.22 # -vantage_mapping[(300, False, True, False, Liquid.METHANOL, False, False)] = ( - StandardVolumeMeOHDispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 310.2, - 5.0: 8.0, - 50.0: 55.8, - 0.0: 0.0, - 100.0: 107.5, - 20.0: 24.6, - 200.0: 209.2, - 10.0: 14.0, - }, +vantage_mapping[(300, False, True, False, Liquid.METHANOL, False, False)] = \ +StandardVolumeMeOHDispenseSurface = HamiltonLiquidClass( + curve={300.0: 310.2, 5.0: 8.0, 50.0: 55.8, 0.0: 0.0, 100.0: 107.5, 20.0: 24.6, 200.0: 209.2, 10.0: 14.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=10.0, @@ -11084,7 +8503,7 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -11105,17 +8524,9 @@ def get_vantage_liquid_class( # 200 0.29 0.17 # 300 0.16 0.80 # -vantage_mapping[(300, False, True, False, Liquid.OCTANOL, True, False)] = ( - StandardVolumeOctanol100DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 319.3, - 50.0: 56.6, - 0.0: 0.0, - 100.0: 109.9, - 20.0: 23.8, - 200.0: 216.2, - }, +vantage_mapping[(300, False, True, False, Liquid.OCTANOL, True, False)] = \ +StandardVolumeOctanol100DispenseJet = HamiltonLiquidClass( + curve={300.0: 319.3, 50.0: 56.6, 0.0: 0.0, 100.0: 109.9, 20.0: 23.8, 200.0: 216.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11132,7 +8543,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -11157,21 +8568,9 @@ def get_vantage_liquid_class( # 200 0.02 0.12 # 300 0.11 0.29 # -vantage_mapping[(300, False, True, False, Liquid.OCTANOL, False, False)] = ( - StandardVolumeOctanol100DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 315.0, - 5.0: 6.6, - 50.0: 55.9, - 0.0: 0.0, - 100.0: 106.8, - 20.0: 22.1, - 1.0: 0.8, - 200.0: 212.0, - 10.0: 12.6, - 2.0: 3.7, - }, +vantage_mapping[(300, False, True, False, Liquid.OCTANOL, False, False)] = \ +StandardVolumeOctanol100DispenseSurface = HamiltonLiquidClass( + curve={300.0: 315.0, 5.0: 6.6, 50.0: 55.9, 0.0: 0.0, 100.0: 106.8, 20.0: 22.1, 1.0: 0.8, 200.0: 212.0, 10.0: 12.6, 2.0: 3.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -11188,7 +8587,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -11207,20 +8606,9 @@ def get_vantage_liquid_class( # 10 1.99 4.39 # # -vantage_mapping[(300, False, True, False, Liquid.PBS_BUFFER, False, False)] = ( - StandardVolumePBSDispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 5.0: 7.5, - 50.0: 55.1, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 23.2, - 1.0: 2.6, - 200.0: 211.0, - 10.0: 12.8, - }, +vantage_mapping[(300, False, True, False, Liquid.PBS_BUFFER, False, False)] = \ +StandardVolumePBSDispenseSurface = HamiltonLiquidClass( + curve={300.0: 313.5, 5.0: 7.5, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 1.0: 2.6, 200.0: 211.0, 10.0: 12.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -11237,7 +8625,7 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -11257,18 +8645,9 @@ def get_vantage_liquid_class( # 100 0.08 1.09 # 200 0.09 0.91 # -vantage_mapping[(300, False, True, False, Liquid.PLASMA, True, False)] = ( - StandardVolumePlasmaDispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 315.2, - 50.0: 55.6, - 0.0: 0.0, - 100.0: 108.1, - 20.0: 23.2, - 200.0: 212.1, - 10.0: 12.3, - }, +vantage_mapping[(300, False, True, False, Liquid.PLASMA, True, False)] = \ +StandardVolumePlasmaDispenseJet = HamiltonLiquidClass( + curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 100.0: 108.1, 20.0: 23.2, 200.0: 212.1, 10.0: 12.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -11285,21 +8664,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.PLASMA, True, True)] = ( - StandardVolumePlasmaDispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 315.2, - 50.0: 55.6, - 0.0: 0.0, - 20.0: 23.2, - 100.0: 108.1, - 200.0: 212.1, - }, +vantage_mapping[(300, False, True, False, Liquid.PLASMA, True, True)] = \ +StandardVolumePlasmaDispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 20.0: 23.2, 100.0: 108.1, 200.0: 212.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11316,13 +8687,12 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.PLASMA, True, False)] = ( - StandardVolumePlasmaDispenseJet_Part -) = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.PLASMA, True, False)] = \ +StandardVolumePlasmaDispenseJet_Part = HamiltonLiquidClass( curve={300.0: 315.2, 0.0: 0.0, 20.0: 29.2, 100.0: 111.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11340,7 +8710,7 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=5.0, + dispense_stop_back_volume=5.0 ) @@ -11361,20 +8731,9 @@ def get_vantage_liquid_class( # 60 0.55 2.06 # # -vantage_mapping[(300, False, True, False, Liquid.PLASMA, False, False)] = ( - StandardVolumePlasmaDispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 313.4, - 5.0: 6.3, - 50.0: 54.9, - 0.0: 0.0, - 100.0: 107.1, - 20.0: 23.0, - 200.0: 210.5, - 10.0: 12.0, - 2.0: 2.6, - }, +vantage_mapping[(300, False, True, False, Liquid.PLASMA, False, False)] = \ +StandardVolumePlasmaDispenseSurface = HamiltonLiquidClass( + curve={300.0: 313.4, 5.0: 6.3, 50.0: 54.9, 0.0: 0.0, 100.0: 107.1, 20.0: 23.0, 200.0: 210.5, 10.0: 12.0, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -11391,24 +8750,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.PLASMA, False, True)] = ( - StandardVolumePlasmaDispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.4, - 5.0: 6.3, - 50.0: 54.9, - 0.0: 0.0, - 20.0: 23.0, - 100.0: 107.1, - 2.0: 2.6, - 10.0: 12.0, - 200.0: 210.5, - }, +vantage_mapping[(300, False, True, False, Liquid.PLASMA, False, True)] = \ +StandardVolumePlasmaDispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 313.4, 5.0: 6.3, 50.0: 54.9, 0.0: 0.0, 20.0: 23.0, 100.0: 107.1, 2.0: 2.6, 10.0: 12.0, 200.0: 210.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -11425,13 +8773,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.PLASMA, False, False)] = ( - StandardVolumePlasmaDispenseSurface_Part -) = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.PLASMA, False, False)] = \ +StandardVolumePlasmaDispenseSurface_Part = HamiltonLiquidClass( curve={300.0: 313.4, 5.0: 6.8, 0.0: 0.0, 100.0: 109.1, 10.0: 12.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -11449,20 +8796,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = ( - StandardVolume_96COREHead1000ul_DMSO_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 150.0: 150.0, - 50.0: 50.0, - 0.0: 0.0, - 20.0: 20.0, - }, +vantage_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ +StandardVolume_96COREHead1000ul_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 150.0: 150.0, 50.0: 50.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -11479,20 +8819,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=20.0, + dispense_stop_back_volume=20.0 ) -vantage_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = ( - StandardVolume_96COREHead1000ul_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 302.5, - 0.0: 0.0, - 100.0: 101.0, - 20.0: 20.4, - 200.0: 201.5, - }, +vantage_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ +StandardVolume_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 302.5, 0.0: 0.0, 100.0: 101.0, 20.0: 20.4, 200.0: 201.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11509,20 +8842,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = ( - StandardVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 306.0, - 0.0: 0.0, - 100.0: 104.3, - 200.0: 205.0, - 10.0: 12.2, - }, +vantage_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ +StandardVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 306.0, 0.0: 0.0, 100.0: 104.3, 200.0: 205.0, 10.0: 12.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11539,20 +8865,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( - StandardVolume_96COREHead1000ul_Water_DispenseJet_Aliquot -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 150.0: 150.0, - 50.0: 50.0, - 0.0: 0.0, - 20.0: 20.0, - }, +vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ +StandardVolume_96COREHead1000ul_Water_DispenseJet_Aliquot = HamiltonLiquidClass( + curve={300.0: 300.0, 150.0: 150.0, 50.0: 50.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -11569,20 +8888,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( - StandardVolume_96COREHead1000ul_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 23.2, - 200.0: 207.5, - }, +vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ +StandardVolume_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 200.0: 207.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11599,20 +8911,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( - StandardVolume_96COREHead1000ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 0.0: 0.0, - 100.0: 107.2, - 200.0: 210.0, - 10.0: 11.9, - }, +vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ +StandardVolume_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 210.0, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11629,20 +8934,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = ( - StandardVolume_96COREHead_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 303.5, - 0.0: 0.0, - 100.0: 101.8, - 10.0: 10.2, - 200.0: 200.5, - }, +vantage_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ +StandardVolume_96COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 303.5, 0.0: 0.0, 100.0: 101.8, 10.0: 10.2, 200.0: 200.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11659,20 +8957,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = ( - StandardVolume_96COREHead_DMSO_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 306.0, - 0.0: 0.0, - 100.0: 105.6, - 10.0: 12.2, - 200.0: 207.0, - }, +vantage_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ +StandardVolume_96COREHead_DMSO_DispenseJet_Part = HamiltonLiquidClass( + curve={300.0: 306.0, 0.0: 0.0, 100.0: 105.6, 10.0: 12.2, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11689,20 +8980,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -vantage_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = ( - StandardVolume_96COREHead_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 303.0, - 0.0: 0.0, - 100.0: 101.3, - 10.0: 10.6, - 200.0: 202.0, - }, +vantage_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ +StandardVolume_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 303.0, 0.0: 0.0, 100.0: 101.3, 10.0: 10.6, 200.0: 202.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11719,20 +9003,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, False, Liquid.DMSO, False, False)] = ( - StandardVolume_96COREHead_DMSO_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 303.0, - 0.0: 0.0, - 100.0: 101.3, - 10.0: 10.1, - 200.0: 202.0, - }, +vantage_mapping[(300, True, True, False, Liquid.DMSO, False, False)] = \ +StandardVolume_96COREHead_DMSO_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 303.0, 0.0: 0.0, 100.0: 101.3, 10.0: 10.1, 200.0: 202.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11749,21 +9026,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( - StandardVolume_96COREHead_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 309.0, - 0.0: 0.0, - 20.0: 22.3, - 100.0: 104.2, - 10.0: 11.9, - 200.0: 207.0, - }, +vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ +StandardVolume_96COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 309.0, 0.0: 0.0, 20.0: 22.3, 100.0: 104.2, 10.0: 11.9, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11780,20 +9049,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( - StandardVolume_96COREHead_Water_DispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 309.0, - 0.0: 0.0, - 20.0: 22.3, - 100.0: 104.2, - 10.0: 11.9, - }, +vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ +StandardVolume_96COREHead_Water_DispenseJet_Part = HamiltonLiquidClass( + curve={300.0: 309.0, 0.0: 0.0, 20.0: 22.3, 100.0: 104.2, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11810,20 +9072,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) -vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( - StandardVolume_96COREHead_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 306.3, - 0.0: 0.0, - 100.0: 104.5, - 10.0: 11.9, - 200.0: 205.7, - }, +vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ +StandardVolume_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 306.3, 0.0: 0.0, 100.0: 104.5, 10.0: 11.9, 200.0: 205.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11840,20 +9095,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, False, Liquid.WATER, False, False)] = ( - StandardVolume_96COREHead_Water_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 304.0, - 0.0: 0.0, - 100.0: 105.3, - 10.0: 11.9, - 200.0: 205.7, - }, +vantage_mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ +StandardVolume_96COREHead_Water_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 304.0, 0.0: 0.0, 100.0: 105.3, 10.0: 11.9, 200.0: 205.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -11870,27 +9118,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # Liquid class for wash standard volume tips with CO-RE 96 Head in CO-RE 96 Head Washer. -vantage_mapping[(300, True, True, False, Liquid.WATER, False, False)] = ( - StandardVolume_Core96Washer_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 330.0, - 5.0: 6.3, - 0.5: 0.9, - 50.0: 55.1, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 23.2, - 1.0: 1.6, - 200.0: 211.0, - 10.0: 11.9, - 2.0: 2.8, - }, +vantage_mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ +StandardVolume_Core96Washer_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 330.0, 5.0: 6.3, 0.5: 0.9, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 1.0: 1.6, 200.0: 211.0, 10.0: 11.9, 2.0: 2.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=150.0, aspiration_air_transport_volume=0.0, @@ -11907,7 +9142,7 @@ def get_vantage_liquid_class( dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) @@ -11927,9 +9162,8 @@ def get_vantage_liquid_class( # 20 (12 Aliquots) 2.53 -2.97 # 50 ( 4 Aliquots) 0.84 -2.57 # -vantage_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = ( - StandardVolume_DMSO_AliquotDispenseJet_Part -) = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = \ +StandardVolume_DMSO_AliquotDispenseJet_Part = HamiltonLiquidClass( curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11947,23 +9181,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = ( - StandardVolume_DMSO_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 304.6, - 350.0: 355.2, - 50.0: 51.1, - 0.0: 0.0, - 100.0: 101.8, - 20.0: 20.7, - 200.0: 203.0, - }, +vantage_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = \ +StandardVolume_DMSO_DispenseJet = HamiltonLiquidClass( + curve={300.0: 304.6, 350.0: 355.2, 50.0: 51.1, 0.0: 0.0, 100.0: 101.8, 20.0: 20.7, 200.0: 203.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -11980,21 +9205,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.DMSO, True, True)] = ( - StandardVolume_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 304.6, - 50.0: 51.1, - 0.0: 0.0, - 20.0: 20.7, - 100.0: 101.8, - 200.0: 203.0, - }, +vantage_mapping[(300, False, True, False, Liquid.DMSO, True, True)] = \ +StandardVolume_DMSO_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 304.6, 50.0: 51.1, 0.0: 0.0, 20.0: 20.7, 100.0: 101.8, 200.0: 203.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12011,13 +9228,12 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = ( - StandardVolume_DMSO_DispenseJet_Part -) = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = \ +StandardVolume_DMSO_DispenseJet_Part = HamiltonLiquidClass( curve={300.0: 320.0, 0.0: 0.0, 20.0: 30.5, 100.0: 116.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -12035,26 +9251,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, -) - - -vantage_mapping[(300, False, True, False, Liquid.DMSO, False, False)] = ( - StandardVolume_DMSO_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 308.8, - 5.0: 6.6, - 50.0: 52.9, - 350.0: 360.5, - 0.0: 0.0, - 1.0: 1.8, - 20.0: 22.1, - 100.0: 103.8, - 2.0: 3.0, - 10.0: 11.9, - 200.0: 205.0, - }, + dispense_stop_back_volume=10.0 +) + + +vantage_mapping[(300, False, True, False, Liquid.DMSO, False, False)] = \ +StandardVolume_DMSO_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 308.8, 5.0: 6.6, 50.0: 52.9, 350.0: 360.5, 0.0: 0.0, 1.0: 1.8, 20.0: 22.1, 100.0: 103.8, 2.0: 3.0, 10.0: 11.9, 200.0: 205.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -12071,25 +9274,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, False, True, False, Liquid.DMSO, False, True)] = ( - StandardVolume_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 308.8, - 5.0: 6.6, - 50.0: 52.9, - 0.0: 0.0, - 1.0: 1.8, - 20.0: 22.1, - 100.0: 103.8, - 2.0: 3.0, - 10.0: 11.9, - 200.0: 205.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, False, True, False, Liquid.DMSO, False, True)] = \ +StandardVolume_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 308.8, 5.0: 6.6, 50.0: 52.9, 0.0: 0.0, 1.0: 1.8, 20.0: 22.1, 100.0: 103.8, 2.0: 3.0, 10.0: 11.9, 200.0: 205.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -12106,23 +9297,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.DMSO, False, False)] = ( - StandardVolume_DMSO_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 308.8, - 5.0: 6.4, - 50.0: 52.9, - 0.0: 0.0, - 20.0: 22.1, - 100.0: 103.8, - 10.0: 11.9, - 200.0: 205.0, - }, +vantage_mapping[(300, False, True, False, Liquid.DMSO, False, False)] = \ +StandardVolume_DMSO_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 308.8, 5.0: 6.4, 50.0: 52.9, 0.0: 0.0, 20.0: 22.1, 100.0: 103.8, 10.0: 11.9, 200.0: 205.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -12139,23 +9320,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 100, stop back volume = 0 -vantage_mapping[(300, False, True, False, Liquid.ETHANOL, True, False)] = ( - StandardVolume_EtOH_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 310.2, - 350.0: 360.5, - 50.0: 55.8, - 0.0: 0.0, - 100.0: 107.5, - 20.0: 24.6, - 200.0: 209.2, - }, +vantage_mapping[(300, False, True, False, Liquid.ETHANOL, True, False)] = \ +StandardVolume_EtOH_DispenseJet = HamiltonLiquidClass( + curve={300.0: 310.2, 350.0: 360.5, 50.0: 55.8, 0.0: 0.0, 100.0: 107.5, 20.0: 24.6, 200.0: 209.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12172,21 +9344,13 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.ETHANOL, True, True)] = ( - StandardVolume_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 310.2, - 50.0: 55.8, - 0.0: 0.0, - 20.0: 24.6, - 100.0: 107.5, - 200.0: 209.2, - }, +vantage_mapping[(300, False, True, False, Liquid.ETHANOL, True, True)] = \ +StandardVolume_EtOH_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 310.2, 50.0: 55.8, 0.0: 0.0, 20.0: 24.6, 100.0: 107.5, 200.0: 209.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12203,13 +9367,12 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.ETHANOL, True, False)] = ( - StandardVolume_EtOH_DispenseJet_Part -) = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.ETHANOL, True, False)] = \ +StandardVolume_EtOH_DispenseJet_Part = HamiltonLiquidClass( curve={300.0: 317.2, 0.0: 0.0, 20.0: 25.6, 100.0: 110.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -12227,23 +9390,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=5.0, + dispense_stop_back_volume=5.0 ) # V1.1: Set mix flow rate to 20, dispense settling time=0, stop back volume = 0 -vantage_mapping[(300, False, True, False, Liquid.GLYCERIN, True, False)] = ( - StandardVolume_Glycerin_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 309.0, - 350.0: 360.0, - 50.0: 53.6, - 0.0: 0.0, - 100.0: 104.9, - 20.0: 22.3, - 200.0: 207.2, - }, +vantage_mapping[(300, False, True, False, Liquid.GLYCERIN, True, False)] = \ +StandardVolume_Glycerin_DispenseJet = HamiltonLiquidClass( + curve={300.0: 309.0, 350.0: 360.0, 50.0: 53.6, 0.0: 0.0, 100.0: 104.9, 20.0: 22.3, 200.0: 207.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=20.0, aspiration_air_transport_volume=5.0, @@ -12260,22 +9414,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 20, dispense settling time=0, stop back volume = 0 -vantage_mapping[(300, False, True, False, Liquid.GLYCERIN80, True, True)] = ( - StandardVolume_Glycerin_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 309.0, - 50.0: 53.6, - 0.0: 0.0, - 100.0: 104.9, - 20.0: 22.3, - 200.0: 207.2, - }, +vantage_mapping[(300, False, True, False, Liquid.GLYCERIN80, True, True)] = \ +StandardVolume_Glycerin_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 309.0, 50.0: 53.6, 0.0: 0.0, 100.0: 104.9, 20.0: 22.3, 200.0: 207.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=20.0, aspiration_air_transport_volume=5.0, @@ -12292,26 +9438,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 10 -vantage_mapping[(300, False, True, False, Liquid.GLYCERIN, False, False)] = ( - StandardVolume_Glycerin_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 307.9, - 5.0: 6.5, - 350.0: 358.4, - 50.0: 53.6, - 0.0: 0.0, - 100.0: 105.7, - 20.0: 22.5, - 200.0: 207.0, - 10.0: 12.0, - 2.0: 3.2, - }, +vantage_mapping[(300, False, True, False, Liquid.GLYCERIN, False, False)] = \ +StandardVolume_Glycerin_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 307.9, 5.0: 6.5, 350.0: 358.4, 50.0: 53.6, 0.0: 0.0, 100.0: 105.7, 20.0: 22.5, 200.0: 207.0, 10.0: 12.0, 2.0: 3.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -12328,24 +9462,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, False, True, False, Liquid.GLYCERIN80, False, True)] = ( - StandardVolume_Glycerin_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 307.9, - 5.0: 6.5, - 50.0: 53.6, - 0.0: 0.0, - 100.0: 105.7, - 20.0: 22.5, - 200.0: 207.0, - 10.0: 12.0, - 2.0: 3.2, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, False, True, False, Liquid.GLYCERIN80, False, True)] = \ +StandardVolume_Glycerin_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 307.9, 5.0: 6.5, 50.0: 53.6, 0.0: 0.0, 100.0: 105.7, 20.0: 22.5, 200.0: 207.0, 10.0: 12.0, 2.0: 3.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -12362,23 +9485,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, -) - - -vantage_mapping[(300, False, True, False, Liquid.GLYCERIN80, False, False)] = ( - StandardVolume_Glycerin_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 307.9, - 5.0: 6.2, - 50.0: 53.6, - 0.0: 0.0, - 100.0: 105.7, - 20.0: 22.5, - 200.0: 207.0, - 10.0: 12.0, - }, + dispense_stop_back_volume=0.0 +) + + +vantage_mapping[(300, False, True, False, Liquid.GLYCERIN80, False, False)] = \ +StandardVolume_Glycerin_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 307.9, 5.0: 6.2, 50.0: 53.6, 0.0: 0.0, 100.0: 105.7, 20.0: 22.5, 200.0: 207.0, 10.0: 12.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -12395,21 +9508,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = ( - StandardVolume_Serum_AliquotDispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 30.0: 30.0, - 0.0: 0.0, - 20.0: 20.0, - 10.0: 10.0, - }, +vantage_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = \ +StandardVolume_Serum_AliquotDispenseJet_Part = HamiltonLiquidClass( + curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -12426,14 +9532,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = ( - StandardVolume_Serum_AliquotJet -) = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = \ +StandardVolume_Serum_AliquotJet = HamiltonLiquidClass( curve={350.0: 350.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -12451,22 +9556,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = ( - StandardVolume_Serum_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 315.2, - 50.0: 55.6, - 0.0: 0.0, - 100.0: 108.1, - 20.0: 23.2, - 200.0: 212.1, - }, +vantage_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = \ +StandardVolume_Serum_DispenseJet = HamiltonLiquidClass( + curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 100.0: 108.1, 20.0: 23.2, 200.0: 212.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12483,21 +9580,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.SERUM, True, True)] = ( - StandardVolume_Serum_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 315.2, - 50.0: 55.6, - 0.0: 0.0, - 20.0: 23.2, - 100.0: 108.1, - 200.0: 212.1, - }, +vantage_mapping[(300, False, True, False, Liquid.SERUM, True, True)] = \ +StandardVolume_Serum_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 20.0: 23.2, 100.0: 108.1, 200.0: 212.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12514,13 +9603,12 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = ( - StandardVolume_Serum_DispenseJet_Part -) = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = \ +StandardVolume_Serum_DispenseJet_Part = HamiltonLiquidClass( curve={300.0: 315.2, 0.0: 0.0, 20.0: 29.2, 100.0: 111.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -12538,24 +9626,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=5.0, + dispense_stop_back_volume=5.0 ) -vantage_mapping[(300, False, True, False, Liquid.SERUM, False, False)] = ( - StandardVolume_Serum_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 313.4, - 5.0: 6.3, - 50.0: 54.9, - 0.0: 0.0, - 20.0: 23.0, - 100.0: 107.1, - 2.0: 2.6, - 10.0: 12.0, - 200.0: 210.5, - }, +vantage_mapping[(300, False, True, False, Liquid.SERUM, False, False)] = \ +StandardVolume_Serum_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 313.4, 5.0: 6.3, 50.0: 54.9, 0.0: 0.0, 20.0: 23.0, 100.0: 107.1, 2.0: 2.6, 10.0: 12.0, 200.0: 210.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -12572,24 +9649,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.SERUM, False, True)] = ( - StandardVolume_Serum_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.4, - 5.0: 6.3, - 50.0: 54.9, - 0.0: 0.0, - 20.0: 23.0, - 100.0: 107.1, - 2.0: 2.6, - 10.0: 12.0, - 200.0: 210.5, - }, +vantage_mapping[(300, False, True, False, Liquid.SERUM, False, True)] = \ +StandardVolume_Serum_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 313.4, 5.0: 6.3, 50.0: 54.9, 0.0: 0.0, 20.0: 23.0, 100.0: 107.1, 2.0: 2.6, 10.0: 12.0, 200.0: 210.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -12606,13 +9672,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.SERUM, False, False)] = ( - StandardVolume_Serum_DispenseSurface_Part -) = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.SERUM, False, False)] = \ +StandardVolume_Serum_DispenseSurface_Part = HamiltonLiquidClass( curve={300.0: 313.4, 5.0: 6.8, 0.0: 0.0, 100.0: 109.1, 10.0: 12.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -12630,21 +9695,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, False, Liquid.WATER, True, False)] = ( - StandardVolume_Water_AliquotDispenseJet_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 300.0, - 30.0: 30.0, - 0.0: 0.0, - 20.0: 20.0, - 10.0: 10.0, - }, +vantage_mapping[(300, False, True, False, Liquid.WATER, True, False)] = \ +StandardVolume_Water_AliquotDispenseJet_Part = HamiltonLiquidClass( + curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -12661,14 +9719,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, False, Liquid.WATER, True, False)] = ( - StandardVolume_Water_AliquotJet -) = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.WATER, True, False)] = \ +StandardVolume_Water_AliquotJet = HamiltonLiquidClass( curve={350.0: 350.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -12686,23 +9743,14 @@ def get_vantage_liquid_class( dispense_swap_speed=0.3, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, False, Liquid.WATER, True, False)] = ( - StandardVolume_Water_DispenseJet -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 350.0: 364.3, - 50.0: 55.1, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 23.2, - 200.0: 211.0, - }, +vantage_mapping[(300, False, True, False, Liquid.WATER, True, False)] = \ +StandardVolume_Water_DispenseJet = HamiltonLiquidClass( + curve={300.0: 313.5, 350.0: 364.3, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12719,20 +9767,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( - StandardVolume_Water_DispenseJetEmpty96Head -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 0.0: 0.0, - 100.0: 107.2, - 200.0: 205.3, - 10.0: 11.9, - }, +vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ +StandardVolume_Water_DispenseJetEmpty96Head = HamiltonLiquidClass( + curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 205.3, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12749,20 +9790,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( - StandardVolume_Water_DispenseJetPart96Head -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 0.0: 0.0, - 100.0: 107.2, - 200.0: 205.3, - 10.0: 11.9, - }, +vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ +StandardVolume_Water_DispenseJetPart96Head = HamiltonLiquidClass( + curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 205.3, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12779,21 +9813,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.WATER, True, True)] = ( - StandardVolume_Water_DispenseJet_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 50.0: 55.1, - 0.0: 0.0, - 20.0: 23.2, - 100.0: 107.2, - 200.0: 211.0, - }, +vantage_mapping[(300, False, True, False, Liquid.WATER, True, True)] = \ +StandardVolume_Water_DispenseJet_Empty = HamiltonLiquidClass( + curve={300.0: 313.5, 50.0: 55.1, 0.0: 0.0, 20.0: 23.2, 100.0: 107.2, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12810,13 +9836,12 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.WATER, True, False)] = ( - StandardVolume_Water_DispenseJet_Part -) = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.WATER, True, False)] = \ +StandardVolume_Water_DispenseJet_Part = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 20.0: 28.2, 100.0: 111.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -12834,28 +9859,14 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0, + dispense_stop_back_volume=10.0 ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, False, Liquid.WATER, False, False)] = ( - StandardVolume_Water_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 5.0: 6.3, - 0.5: 0.9, - 350.0: 364.3, - 50.0: 55.1, - 0.0: 0.0, - 100.0: 107.2, - 20.0: 23.2, - 1.0: 1.6, - 200.0: 211.0, - 10.0: 11.9, - 2.0: 2.8, - }, +vantage_mapping[(300, False, True, False, Liquid.WATER, False, False)] = \ +StandardVolume_Water_DispenseSurface = HamiltonLiquidClass( + curve={300.0: 313.5, 5.0: 6.3, 0.5: 0.9, 350.0: 364.3, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 1.0: 1.6, 200.0: 211.0, 10.0: 11.9, 2.0: 2.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12872,13 +9883,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, False, Liquid.WATER, False, False)] = ( - StandardVolume_Water_DispenseSurface96Head -) = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ +StandardVolume_Water_DispenseSurface96Head = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -12896,20 +9906,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( - StandardVolume_Water_DispenseSurfaceEmpty96Head -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 0.0: 0.0, - 100.0: 107.2, - 200.0: 205.7, - 10.0: 11.9, - }, +vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ +StandardVolume_Water_DispenseSurfaceEmpty96Head = HamiltonLiquidClass( + curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 205.7, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12926,20 +9929,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, True, True, False, Liquid.WATER, False, False)] = ( - StandardVolume_Water_DispenseSurfacePart96Head -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 0.0: 0.0, - 100.0: 107.2, - 200.0: 205.7, - 10.0: 11.9, - }, +vantage_mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ +StandardVolume_Water_DispenseSurfacePart96Head = HamiltonLiquidClass( + curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 205.7, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12956,26 +9952,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.WATER, False, True)] = ( - StandardVolume_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 5.0: 6.3, - 0.5: 0.9, - 50.0: 55.1, - 0.0: 0.0, - 1.0: 1.6, - 20.0: 23.2, - 100.0: 107.2, - 2.0: 2.8, - 10.0: 11.9, - 200.0: 211.0, - }, +vantage_mapping[(300, False, True, False, Liquid.WATER, False, True)] = \ +StandardVolume_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={300.0: 313.5, 5.0: 6.3, 0.5: 0.9, 50.0: 55.1, 0.0: 0.0, 1.0: 1.6, 20.0: 23.2, 100.0: 107.2, 2.0: 2.8, 10.0: 11.9, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -12992,23 +9975,13 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(300, False, True, False, Liquid.WATER, False, False)] = ( - StandardVolume_Water_DispenseSurface_Part -) = HamiltonLiquidClass( - curve={ - 300.0: 313.5, - 5.0: 6.8, - 50.0: 55.1, - 0.0: 0.0, - 20.0: 23.2, - 100.0: 107.2, - 10.0: 12.3, - 200.0: 211.0, - }, +vantage_mapping[(300, False, True, False, Liquid.WATER, False, False)] = \ +StandardVolume_Water_DispenseSurface_Part = HamiltonLiquidClass( + curve={300.0: 313.5, 5.0: 6.8, 50.0: 55.1, 0.0: 0.0, 20.0: 23.2, 100.0: 107.2, 10.0: 12.3, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -13025,13 +9998,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, True, Liquid.DMSO, True, True)] = ( - Tip_50ulFilter_96COREHead1000ul_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, True, True, True, Liquid.DMSO, True, True)] = \ +Tip_50ulFilter_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 52.1, 30.0: 31.7, 0.0: 0.0, 20.0: 21.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13049,21 +10021,13 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, True, Liquid.DMSO, False, True)] = ( - Tip_50ulFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.4, - 50.0: 52.1, - 30.0: 31.5, - 0.0: 0.0, - 1.0: 0.7, - 10.0: 10.8, - }, +vantage_mapping[(50, True, True, True, Liquid.DMSO, False, True)] = \ +Tip_50ulFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.4, 50.0: 52.1, 30.0: 31.5, 0.0: 0.0, 1.0: 0.7, 10.0: 10.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -13080,13 +10044,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, True, Liquid.WATER, True, True)] = ( - Tip_50ulFilter_96COREHead1000ul_Water_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, True, True, True, Liquid.WATER, True, True)] = \ +Tip_50ulFilter_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 54.2, 30.0: 33.2, 0.0: 0.0, 20.0: 22.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13104,21 +10067,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, True, Liquid.WATER, False, True)] = ( - Tip_50ulFilter_96COREHead1000ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.6, - 50.0: 53.6, - 30.0: 32.6, - 0.0: 0.0, - 1.0: 0.8, - 10.0: 11.3, - }, +vantage_mapping[(50, True, True, True, Liquid.WATER, False, True)] = \ +Tip_50ulFilter_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.6, 50.0: 53.6, 30.0: 32.6, 0.0: 0.0, 1.0: 0.8, 10.0: 11.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -13135,13 +10090,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, True, Liquid.DMSO, True, True)] = ( - Tip_50ulFilter_96COREHead_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, True, True, True, Liquid.DMSO, True, True)] = \ +Tip_50ulFilter_96COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 51.4, 0.0: 0.0, 30.0: 31.3, 20.0: 21.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13159,21 +10113,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, True, Liquid.DMSO, False, True)] = ( - Tip_50ulFilter_96COREHead_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.6, - 50.0: 51.1, - 0.0: 0.0, - 30.0: 31.0, - 1.0: 0.8, - 10.0: 10.7, - }, +vantage_mapping[(50, True, True, True, Liquid.DMSO, False, True)] = \ +Tip_50ulFilter_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.6, 50.0: 51.1, 0.0: 0.0, 30.0: 31.0, 1.0: 0.8, 10.0: 10.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -13190,13 +10136,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, True, Liquid.WATER, True, True)] = ( - Tip_50ulFilter_96COREHead_Water_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, True, True, True, Liquid.WATER, True, True)] = \ +Tip_50ulFilter_96COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 54.0, 30.0: 33.0, 0.0: 0.0, 20.0: 22.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13214,21 +10159,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, True, Liquid.WATER, False, True)] = ( - Tip_50ulFilter_96COREHead_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.6, - 50.0: 53.5, - 30.0: 32.9, - 0.0: 0.0, - 1.0: 0.8, - 10.0: 11.4, - }, +vantage_mapping[(50, True, True, True, Liquid.WATER, False, True)] = \ +Tip_50ulFilter_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.6, 50.0: 53.5, 30.0: 32.9, 0.0: 0.0, 1.0: 0.8, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -13245,13 +10182,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, True, Liquid.DMSO, True, True)] = ( - Tip_50ulFilter_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.DMSO, True, True)] = \ +Tip_50ulFilter_DMSO_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 52.5, 0.0: 0.0, 30.0: 31.4, 20.0: 21.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13269,21 +10205,13 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, True, Liquid.DMSO, False, True)] = ( - Tip_50ulFilter_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.5, - 50.0: 52.6, - 0.0: 0.0, - 30.0: 32.0, - 1.0: 0.7, - 10.0: 11.0, - }, +vantage_mapping[(50, False, True, True, Liquid.DMSO, False, True)] = \ +Tip_50ulFilter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.5, 50.0: 52.6, 0.0: 0.0, 30.0: 32.0, 1.0: 0.7, 10.0: 11.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -13300,13 +10228,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, True, Liquid.ETHANOL, True, True)] = ( - Tip_50ulFilter_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.ETHANOL, True, True)] = \ +Tip_50ulFilter_EtOH_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 57.5, 0.0: 0.0, 30.0: 35.8, 20.0: 24.4}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -13324,21 +10251,13 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, True, Liquid.ETHANOL, False, True)] = ( - Tip_50ulFilter_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 6.5, - 50.0: 54.1, - 0.0: 0.0, - 30.0: 33.8, - 1.0: 1.9, - 10.0: 12.0, - }, +vantage_mapping[(50, False, True, True, Liquid.ETHANOL, False, True)] = \ +Tip_50ulFilter_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 6.5, 50.0: 54.1, 0.0: 0.0, 30.0: 33.8, 1.0: 1.9, 10.0: 12.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=2.0, @@ -13355,21 +10274,13 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, True, Liquid.GLYCERIN80, False, True)] = ( - Tip_50ulFilter_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.5, - 50.0: 57.0, - 0.0: 0.0, - 30.0: 35.9, - 1.0: 0.6, - 10.0: 12.0, - }, +vantage_mapping[(50, False, True, True, Liquid.GLYCERIN80, False, True)] = \ +Tip_50ulFilter_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.5, 50.0: 57.0, 0.0: 0.0, 30.0: 35.9, 1.0: 0.6, 10.0: 12.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -13386,13 +10297,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, True, Liquid.SERUM, True, True)] = ( - Tip_50ulFilter_Serum_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.SERUM, True, True)] = \ +Tip_50ulFilter_Serum_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 54.6, 30.0: 33.5, 0.0: 0.0, 20.0: 22.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13410,21 +10320,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, True, Liquid.SERUM, False, True)] = ( - Tip_50ulFilter_Serum_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.7, - 50.0: 54.9, - 30.0: 33.0, - 0.0: 0.0, - 1.0: 0.7, - 10.0: 11.3, - }, +vantage_mapping[(50, False, True, True, Liquid.SERUM, False, True)] = \ +Tip_50ulFilter_Serum_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.7, 50.0: 54.9, 30.0: 33.0, 0.0: 0.0, 1.0: 0.7, 10.0: 11.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -13441,13 +10343,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, True, Liquid.WATER, True, True)] = ( - Tip_50ulFilter_Water_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.WATER, True, True)] = \ +Tip_50ulFilter_Water_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 54.0, 30.0: 33.6, 0.0: 0.0, 20.0: 22.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13465,21 +10366,13 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, True, Liquid.WATER, False, True)] = ( - Tip_50ulFilter_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.7, - 50.0: 54.2, - 30.0: 33.1, - 0.0: 0.0, - 1.0: 0.65, - 10.0: 11.4, - }, +vantage_mapping[(50, False, True, True, Liquid.WATER, False, True)] = \ +Tip_50ulFilter_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.7, 50.0: 54.2, 30.0: 33.1, 0.0: 0.0, 1.0: 0.65, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -13496,13 +10389,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = ( - Tip_50ul_96COREHead1000ul_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ +Tip_50ul_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 52.1, 30.0: 31.7, 0.0: 0.0, 20.0: 21.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13520,21 +10412,13 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = ( - Tip_50ul_96COREHead1000ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.4, - 50.0: 52.1, - 30.0: 31.5, - 0.0: 0.0, - 1.0: 0.7, - 10.0: 10.8, - }, +vantage_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = \ +Tip_50ul_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.4, 50.0: 52.1, 30.0: 31.5, 0.0: 0.0, 1.0: 0.7, 10.0: 10.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -13551,13 +10435,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, False, Liquid.WATER, True, True)] = ( - Tip_50ul_96COREHead1000ul_Water_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ +Tip_50ul_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 52.8, 0.0: 0.0, 30.0: 33.2, 20.0: 22.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13575,21 +10458,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, False, Liquid.WATER, False, True)] = ( - Tip_50ul_96COREHead1000ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.8, - 50.0: 53.6, - 30.0: 32.6, - 0.0: 0.0, - 1.0: 0.8, - 10.0: 11.3, - }, +vantage_mapping[(50, True, True, False, Liquid.WATER, False, True)] = \ +Tip_50ul_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.8, 50.0: 53.6, 30.0: 32.6, 0.0: 0.0, 1.0: 0.8, 10.0: 11.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -13606,13 +10481,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=3.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = ( - Tip_50ul_96COREHead_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ +Tip_50ul_96COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 51.4, 30.0: 31.3, 0.0: 0.0, 20.0: 21.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13630,21 +10504,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = ( - Tip_50ul_96COREHead_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.6, - 50.0: 52.1, - 30.0: 31.6, - 0.0: 0.0, - 1.0: 0.8, - 10.0: 11.0, - }, +vantage_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = \ +Tip_50ul_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.6, 50.0: 52.1, 30.0: 31.6, 0.0: 0.0, 1.0: 0.8, 10.0: 11.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -13661,13 +10527,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, False, Liquid.WATER, True, True)] = ( - Tip_50ul_96COREHead_Water_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ +Tip_50ul_96COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 54.1, 0.0: 0.0, 30.0: 33.0, 20.0: 22.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13685,21 +10550,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, True, True, False, Liquid.WATER, False, True)] = ( - Tip_50ul_96COREHead_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.6, - 50.0: 53.6, - 30.0: 32.9, - 0.0: 0.0, - 1.0: 0.7, - 10.0: 11.4, - }, +vantage_mapping[(50, True, True, False, Liquid.WATER, False, True)] = \ +Tip_50ul_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.6, 50.0: 53.6, 30.0: 32.9, 0.0: 0.0, 1.0: 0.7, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -13716,22 +10573,14 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) # Liquid class for wash 50ul tips with CO-RE 96 Head in CO-RE 96 Head Washer. -vantage_mapping[(50, True, True, False, Liquid.WATER, False, False)] = ( - Tip_50ul_Core96Washer_DispenseSurface -) = HamiltonLiquidClass( - curve={ - 5.0: 5.7, - 50.0: 54.2, - 30.0: 33.2, - 0.0: 0.0, - 1.0: 0.5, - 10.0: 11.4, - }, +vantage_mapping[(50, True, True, False, Liquid.WATER, False, False)] = \ +Tip_50ul_Core96Washer_DispenseSurface = HamiltonLiquidClass( + curve={5.0: 5.7, 50.0: 54.2, 30.0: 33.2, 0.0: 0.0, 1.0: 0.5, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -13748,13 +10597,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, False, Liquid.DMSO, True, True)] = ( - Tip_50ul_DMSO_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.DMSO, True, True)] = \ +Tip_50ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 52.5, 30.0: 32.2, 0.0: 0.0, 20.0: 21.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13772,21 +10620,13 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, False, Liquid.DMSO, False, True)] = ( - Tip_50ul_DMSO_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.6, - 50.0: 52.6, - 30.0: 32.1, - 0.0: 0.0, - 1.0: 0.7, - 10.0: 11.0, - }, +vantage_mapping[(50, False, True, False, Liquid.DMSO, False, True)] = \ +Tip_50ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.6, 50.0: 52.6, 30.0: 32.1, 0.0: 0.0, 1.0: 0.7, 10.0: 11.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -13803,13 +10643,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, False, Liquid.ETHANOL, True, True)] = ( - Tip_50ul_EtOH_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.ETHANOL, True, True)] = \ +Tip_50ul_EtOH_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 58.4, 0.0: 0.0, 30.0: 36.0, 20.0: 24.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -13827,21 +10666,13 @@ def get_vantage_liquid_class( dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, False, Liquid.ETHANOL, False, True)] = ( - Tip_50ul_EtOH_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 6.7, - 50.0: 54.1, - 0.0: 0.0, - 30.0: 33.7, - 1.0: 2.1, - 10.0: 12.1, - }, +vantage_mapping[(50, False, True, False, Liquid.ETHANOL, False, True)] = \ +Tip_50ul_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 6.7, 50.0: 54.1, 0.0: 0.0, 30.0: 33.7, 1.0: 2.1, 10.0: 12.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=2.0, @@ -13858,21 +10689,13 @@ def get_vantage_liquid_class( dispense_swap_speed=50.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, False, Liquid.GLYCERIN80, False, True)] = ( - Tip_50ul_Glycerin80_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.7, - 50.0: 59.4, - 0.0: 0.0, - 30.0: 36.0, - 1.0: 0.3, - 10.0: 11.8, - }, +vantage_mapping[(50, False, True, False, Liquid.GLYCERIN80, False, True)] = \ +Tip_50ul_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.7, 50.0: 59.4, 0.0: 0.0, 30.0: 36.0, 1.0: 0.3, 10.0: 11.8}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -13889,13 +10712,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, False, Liquid.SERUM, True, True)] = ( - Tip_50ul_Serum_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.SERUM, True, True)] = \ +Tip_50ul_Serum_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 54.6, 30.0: 33.5, 0.0: 0.0, 20.0: 22.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13913,21 +10735,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, False, Liquid.SERUM, False, True)] = ( - Tip_50ul_Serum_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.7, - 50.0: 54.9, - 30.0: 33.0, - 0.0: 0.0, - 1.0: 0.7, - 10.0: 11.3, - }, +vantage_mapping[(50, False, True, False, Liquid.SERUM, False, True)] = \ +Tip_50ul_Serum_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.7, 50.0: 54.9, 30.0: 33.0, 0.0: 0.0, 1.0: 0.7, 10.0: 11.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -13944,13 +10758,12 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, False, Liquid.WATER, True, True)] = ( - Tip_50ul_Water_DispenseJet_Empty -) = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.WATER, True, True)] = \ +Tip_50ul_Water_DispenseJet_Empty = HamiltonLiquidClass( curve={50.0: 54.0, 30.0: 33.5, 0.0: 0.0, 20.0: 22.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -13968,21 +10781,13 @@ def get_vantage_liquid_class( dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) -vantage_mapping[(50, False, True, False, Liquid.WATER, False, True)] = ( - Tip_50ul_Water_DispenseSurface_Empty -) = HamiltonLiquidClass( - curve={ - 5.0: 5.7, - 50.0: 54.2, - 30.0: 33.2, - 0.0: 0.0, - 1.0: 0.7, - 10.0: 11.4, - }, +vantage_mapping[(50, False, True, False, Liquid.WATER, False, True)] = \ +Tip_50ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( + curve={5.0: 5.7, 50.0: 54.2, 30.0: 33.2, 0.0: 0.0, 1.0: 0.7, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -13999,5 +10804,5 @@ def get_vantage_liquid_class( dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0, + dispense_stop_back_volume=0.0 ) From 9fe9f930693f732419f8f57668802be317006ddb Mon Sep 17 00:00:00 2001 From: Rick Wierenga Date: Fri, 20 Sep 2024 11:31:32 -0700 Subject: [PATCH 08/18] fix these params --- pylabrobot/liquid_handling/parameter_sets/star.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pylabrobot/liquid_handling/parameter_sets/star.py b/pylabrobot/liquid_handling/parameter_sets/star.py index e30f363ec9..aefb08f684 100644 --- a/pylabrobot/liquid_handling/parameter_sets/star.py +++ b/pylabrobot/liquid_handling/parameter_sets/star.py @@ -40,7 +40,7 @@ def make_asp_kwargs(self) -> dict[str, float]: "jet": self.aspiration_jet, "blow_out": self.aspiration_blow_out, "flow_rates": self.aspiration_flow_rates, - "mix_flow_rate": self.aspiration_mix_flow_rates, + "homogenization_speed": self.aspiration_mix_flow_rates, "transport_air_volume": self.transport_air_volumes, "swap_speed": self.aspiration_swap_speeds, "settling_time": self.aspiration_settling_times, @@ -53,7 +53,7 @@ def make_disp_kwargs(self) -> dict[str, float]: return { "jet": self.dispense_jet, "blow_out": self.dispense_blow_out, - "flow_rate": self.dispense_flow_rates, + "flow_rates": self.dispense_flow_rates, "mix_speed": self.dispense_mix_speeds, "transport_air_volume": self.transport_air_volumes, "swap_speed": self.dispense_swap_speeds, From 1c09434bcbece40d16e2ce1f0bb049cf87e4db7a Mon Sep 17 00:00:00 2001 From: Rick Wierenga Date: Thu, 26 Sep 2024 13:22:42 -0700 Subject: [PATCH 09/18] need amend --- .../backends/hamilton/STAR_tests.py | 1416 ++++++----------- .../liquid_classes/hamilton/base.py | 3 + 2 files changed, 512 insertions(+), 907 deletions(-) diff --git a/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py b/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py index b103940f42..49d38a604c 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py +++ b/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py @@ -1,45 +1,59 @@ -# mypy: disable-error-code="attr-defined,method-assign" - +from typing import cast import unittest import unittest.mock -from typing import cast from pylabrobot.liquid_handling import LiquidHandler -from pylabrobot.liquid_handling.standard import GripDirection, Pickup +from pylabrobot.liquid_handling.standard import Pickup, GripDirection +from pylabrobot.liquid_handling.liquid_classes.hamilton.star import ( + StandardVolumeFilter_Water_DispenseSurface, + StandardVolumeFilter_Water_DispenseJet_Empty) +from pylabrobot.liquid_handling.parameter_sets.star import STARParameterSet from pylabrobot.plate_reading import PlateReader -from pylabrobot.plate_reading.chatterbox import PlateReaderChatterboxBackend +from pylabrobot.plate_reading.plate_reader_tests import MockPlateReaderBackend from pylabrobot.resources import ( - HT, - HTF, - PLT_CAR_L5AC_A00, - PLT_CAR_L5MD_A00, - PLT_CAR_P3AC_A01, - TIP_CAR_288_C00, - TIP_CAR_480_A00, - AGenBio_1_troughplate_190000uL_Fl, - CellTreat_96_wellplate_350ul_Ub, - Container, - Coordinate, - Cor_96_wellplate_360ul_Fb, - Lid, - ResourceStack, - no_volume_tracking, + Plate, Coordinate, Container, ResourceStack, Lid, + TIP_CAR_480_A00, TIP_CAR_288_C00, PLT_CAR_L5AC_A00, HT_P, HTF_L, Cor_96_wellplate_360ul_Fb, + no_volume_tracking ) -from pylabrobot.resources.hamilton import STF, STARLetDeck +from pylabrobot.resources.hamilton import STARLetDeck +from pylabrobot.resources.ml_star import STF_L + +from tests.usb import MockDev, MockEndpoint from .STAR import ( STAR, + parse_star_fw_string, + STARFirmwareError, CommandSyntaxError, HamiltonNoTipError, HardwareError, - STARFirmwareError, - UnknownHamiltonError, - parse_star_fw_string, + UnknownHamiltonError ) +PICKUP_TIP_FORMAT = "xp##### (n)yp#### (n)tm# (n)tt##tp####tz####th####td#" +DROP_TIP_FORMAT = "xp##### (n)yp#### (n)tm# (n)tp####tz####th####ti#" +ASPIRATION_COMMAND_FORMAT = ( + "at# (n)tm# (n)xp##### (n)yp#### (n)th####te####lp#### (n)ch### (n)zl#### (n)zx#### (n)" + "ip#### (n)it# (n)fp#### (n)av#### (n)as#### (n)ta### (n)ba#### (n)oa### (n)lm# (n)ll# (n)" + "lv# (n)ld## (n)de#### (n)wt## (n)mv##### (n)mc## (n)mp### (n)ms#### (n)gi### (n)gj#gk#" + "zu#### (n)zr#### (n)mh#### (n)zo### (n)po#### (n)lk# (n)ik#### (n)sd#### (n)se#### (n)" + "sz#### (n)io#### (n)il##### (n)in#### (n)" +) +DISPENSE_RESPONSE_FORMAT = ( + "dm# (n)tm# (n)xp##### (n)yp#### (n)zx#### (n)lp#### (n)zl#### (n)ip#### (n)it# (n)fp#### (n)" + "th####te####dv##### (n)ds#### (n)ss#### (n)rv### (n)ta### (n)ba#### (n)lm# (n)zo### (n)" + "ll# (n)lv# (n)de#### (n)mv##### (n)mc## (n)mp### (n)ms#### (n)wt## (n)gi### (n)gj#gk#" + "zu#### (n)zr##### (n)mh#### (n)po#### (n)" +) + +GET_PLATE_FMT = "xs#####xd#yj####yd#zj####zd#gr#th####te####gw#go####gb####gt##ga#gc#" +PUT_PLATE_FMT = "xs#####xd#yj####yd#zj####zd#th####te####gr#go####ga#" +INTERMEDIATE_FMT = "xs#####xd#yj####yd#zj####zd#gr#th####ga#xe# #" + + class TestSTARResponseParsing(unittest.TestCase): - """Test parsing of response from Hamilton.""" + """ Test parsing of response from Hamilton. """ def setUp(self): super().setUp() @@ -67,10 +81,10 @@ def test_parse_response_params(self): self.assertEqual(parsed, "") with self.assertRaises(ValueError): - parse_star_fw_string("C0QM", "id####") + parse_star_fw_string("C0QM", "id####") # pylint: disable=expression-not-assigned with self.assertRaises(ValueError): - parse_star_fw_string("C0RV", "") + parse_star_fw_string("C0RV", "") # pylint: disable=expression-not-assigned def test_parse_response_no_errors(self): parsed = parse_star_fw_string("C0QMid1111", "") @@ -108,14 +122,8 @@ def test_parse_response_slave_errors(self): self.assertIsInstance(e.errors["Pipetting channel 16"], HamiltonNoTipError) self.assertEqual(e.errors["Pipetting channel 2"].message, "No error") - self.assertEqual( - e.errors["Pipetting channel 4"].message, - "Unknown trace information code 98", - ) - self.assertEqual( - e.errors["Pipetting channel 16"].message, - "Tip already picked up", - ) + self.assertEqual(e.errors["Pipetting channel 4"].message, "Unknown trace information code 98") + self.assertEqual(e.errors["Pipetting channel 16"].message, "Tip already picked up") def test_parse_slave_response_errors(self): with self.assertRaises(STARFirmwareError) as ctx: @@ -129,69 +137,54 @@ def test_parse_slave_response_errors(self): self.assertEqual(e.errors["Pipetting channel 1"].message, "Unknown command") -def _any_write_and_read_command_call(cmd): - return unittest.mock.call( - id_=unittest.mock.ANY, - cmd=cmd, - write_timeout=unittest.mock.ANY, - read_timeout=unittest.mock.ANY, - wait=unittest.mock.ANY, - ) +class STARUSBCommsMocker(STAR): + """ Mocks PyUSB """ + async def setup(self, send_response: str): # type: ignore + self.dev = MockDev(send_response) + self.read_endpoint = MockEndpoint() + self.write_endpoint = MockEndpoint() -class TestSTARUSBComms(unittest.IsolatedAsyncioTestCase): - """Test that USB data is parsed correctly.""" - async def asyncSetUp(self): - self.star = STAR(read_timeout=2, packet_read_timeout=1) - self.star.set_deck(STARLetDeck()) - self.star.io = unittest.mock.MagicMock() - await super().asyncSetUp() +class TestSTARUSBComms(unittest.IsolatedAsyncioTestCase): + """ Test that USB data is parsed correctly. """ async def test_send_command_correct_response(self): - self.star.io.read.side_effect = [b"C0QMid0001"] - resp = await self.star.send_command("C0", command="QM", fmt="id####") + star = STARUSBCommsMocker() + await star.setup(send_response="C0QMid0001") # correct response + resp = await star.send_command("C0", command="QM", fmt="id####") self.assertEqual(resp, {"id": 1}) async def test_send_command_wrong_id(self): - self.star.io.read.side_effect = lambda: b"C0QMid0002" + star = STARUSBCommsMocker(read_timeout=2, packet_read_timeout=1) + await star.setup(send_response="C0QMid0000") # wrong response with self.assertRaises(TimeoutError): - await self.star.send_command("C0", command="QM", fmt="id####") + await star.send_command("C0", command="QM") async def test_send_command_plaintext_response(self): - self.star.io.read.side_effect = lambda: b"this is plaintext" + star = STARUSBCommsMocker(read_timeout=2, packet_read_timeout=1) + await star.setup(send_response="this is plain text") # wrong response with self.assertRaises(TimeoutError): - await self.star.send_command("C0", command="QM", fmt="id####") + await star.send_command("C0", command="QM") class STARCommandCatcher(STAR): - """Mock backend for star that catches commands and saves them instead of sending them to the - machine.""" + """ Mock backend for star that catches commands and saves them instead of sending them to the + machine. """ def __init__(self): super().__init__() self.commands = [] - async def setup(self) -> None: # type: ignore + async def setup(self) -> None: self._num_channels = 8 self.iswap_installed = True self.core96_head_installed = True self._core_parked = True - async def send_command( # type: ignore - self, - module, - command, - auto_id=True, - tip_pattern=None, - fmt="", - read_timeout=0, - write_timeout=0, - **kwargs, - ): - cmd, _ = self._assemble_command( - module=module, command=command, auto_id=auto_id, tip_pattern=tip_pattern, **kwargs - ) + async def send_command(self, module, command, tip_pattern=None, fmt="", # type: ignore + read_timeout=0, write_timeout=0, **kwargs): + cmd, _ = self._assemble_command(module, command, tip_pattern, **kwargs) self.commands.append(cmd) async def stop(self): @@ -199,86 +192,107 @@ async def stop(self): class TestSTARLiquidHandlerCommands(unittest.IsolatedAsyncioTestCase): - """Test STAR backend for liquid handling.""" + """ Test STAR backend for liquid handling. """ async def asyncSetUp(self): - self.STAR = STAR(read_timeout=1) - self.STAR._write_and_read_command = unittest.mock.AsyncMock() - self.STAR.io = unittest.mock.MagicMock() - self.STAR.io.setup = unittest.mock.AsyncMock() - self.STAR.io.write = unittest.mock.MagicMock() - self.STAR.io.read = unittest.mock.MagicMock() - + # pylint: disable=invalid-name + self.mockSTAR = STARCommandCatcher() self.deck = STARLetDeck() - self.lh = LiquidHandler(self.STAR, deck=self.deck) + self.lh = LiquidHandler(self.mockSTAR, deck=self.deck) self.tip_car = TIP_CAR_480_A00(name="tip carrier") - self.tip_car[1] = self.tip_rack = STF(name="tip_rack_01") - self.tip_car[2] = self.tip_rack2 = HTF(name="tip_rack_02") + self.tip_car[1] = self.tip_rack = STF_L(name="tip_rack_01") + self.tip_car[2] = self.tip_rack2 = HTF_L(name="tip_rack_02") self.deck.assign_child_resource(self.tip_car, rails=1) self.plt_car = PLT_CAR_L5AC_A00(name="plate carrier") self.plt_car[0] = self.plate = Cor_96_wellplate_360ul_Fb(name="plate_01") - lid = Lid( - name="plate_01_lid", - size_x=self.plate.get_size_x(), - size_y=self.plate.get_size_y(), - size_z=10, - nesting_z_height=10, - ) + lid = Lid(name="plate_01_lid", size_x=self.plate.get_size_x(), size_y=self.plate.get_size_y(), + size_z=10, nesting_z_height=10) self.plate.assign_child_resource(lid) assert self.plate.lid is not None self.plt_car[1] = self.other_plate = Cor_96_wellplate_360ul_Fb(name="plate_02") - lid = Lid( - name="plate_02_lid", - size_x=self.other_plate.get_size_x(), - size_y=self.other_plate.get_size_y(), - size_z=10, - nesting_z_height=10, - ) + lid = Lid(name="plate_02_lid", size_x=self.other_plate.get_size_x(), + size_y=self.other_plate.get_size_y(), size_z=10, nesting_z_height=10) self.other_plate.assign_child_resource(lid) self.deck.assign_child_resource(self.plt_car, rails=9) class BlueBucket(Container): def __init__(self, name: str): - super().__init__( - name, - size_x=123, - size_y=82, - size_z=75, - category="bucket", - max_volume=123 * 82 * 75, - material_z_thickness=1, - ) - + super().__init__(name, size_x=123, size_y=82, size_z=75, category="bucket", + max_volume=123 * 82 * 75, material_z_thickness=1) self.bb = BlueBucket(name="blue bucket") - self.deck.assign_child_resource(self.bb, location=Coordinate(425, 141.5, 120 - 1)) + self.deck.assign_child_resource(self.bb, location=Coordinate(425, 141.5, 120-1)) self.maxDiff = None - self.STAR._num_channels = 8 - self.STAR.core96_head_installed = True - self.STAR.iswap_installed = True - self.STAR.setup = unittest.mock.AsyncMock() - self.STAR._core_parked = True - self.STAR._iswap_parked = True await self.lh.setup() + self.hlc = StandardVolumeFilter_Water_DispenseSurface.copy() + self.hlc.aspiration_air_transport_volume = 0 + self.hlc.dispense_air_transport_volume = 0 + async def asyncTearDown(self): await self.lh.stop() + def _assert_command_in_command_buffer(self, cmd: str, should_be: bool, fmt: str): + """ Assert that the given command was sent to the backend. The ordering of the parameters is not + taken into account, but the values and formatting should match. The id parameter of the command + is ignored. + + If a command is found, it is removed from the command buffer. + + Args: + cmd: the command to look for + should_be: whether the command should be found or not + fmt: the format of the command + """ + + found = False + # Command that fits the format, but is not the same as the command we are looking for. + similar = None + + parsed_cmd = parse_star_fw_string(cmd, fmt) + parsed_cmd.pop("id") + + for sent_cmd in self.mockSTAR.commands: + # When the module and command do not match, there is no point in comparing the parameters. + if sent_cmd[0:4] != cmd[0:4]: + continue + + try: + parsed_sent_cmd = parse_star_fw_string(sent_cmd, fmt) + parsed_sent_cmd.pop("id") + + if parsed_cmd == parsed_sent_cmd: + self.mockSTAR.commands.remove(sent_cmd) + found = True + break + else: + similar = parsed_sent_cmd + except ValueError as e: + # The command could not be parsed. + print(e) + continue + + if should_be and not found: + if similar is not None: + # These will not be equal, but this method does give a better error message than `fail`. + self.assertEqual(similar, parsed_cmd) + else: + self.fail(f"Command {cmd} not found in sent commands: {self.mockSTAR.commands}") + elif not should_be and found: + self.fail(f"Command {cmd} was found in sent commands: {self.mockSTAR.commands}") + async def test_indictor_light(self): - await self.STAR.set_loading_indicators(bit_pattern=[True] * 54, blink_pattern=[False] * 54) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0CPid0001cl3FFFFFFFFFFFFFcb00000000000000", - ) - ] - ) + """ Test the indicator light. """ + await self.mockSTAR.set_loading_indicators(bit_pattern=[True]*54, blink_pattern=[False]*54) + self._assert_command_sent_once("C0CPid0000cl3FFFFFFFFFFFFFcb00000000000000", + "cl**************cb**************") def test_ops_to_fw_positions(self): - """Convert channel positions to firmware positions.""" + """ Convert channel positions to firmware positions. """ + # pylint: disable=protected-access tip_a1 = self.tip_rack.get_item("A1") tip_f1 = self.tip_rack.get_item("F1") tip = self.tip_rack.get_tip("A1") @@ -286,30 +300,26 @@ def test_ops_to_fw_positions(self): op1 = Pickup(resource=tip_a1, tip=tip, offset=Coordinate.zero()) op2 = Pickup(resource=tip_f1, tip=tip, offset=Coordinate.zero()) self.assertEqual( - self.STAR._ops_to_fw_positions((op1,), use_channels=[0]), - ([1179, 0], [2418, 0], [True, False]), + self.mockSTAR._ops_to_fw_positions((op1,), use_channels=[0]), + ([1179, 0], [2418, 0], [True, False]) ) self.assertEqual( - self.STAR._ops_to_fw_positions((op1, op2), use_channels=[0, 1]), - ([1179, 1179, 0], [2418, 1968, 0], [True, True, False]), + self.mockSTAR._ops_to_fw_positions((op1, op2), use_channels=[0, 1]), + ([1179, 1179, 0], [2418, 1968, 0], [True, True, False]) ) self.assertEqual( - self.STAR._ops_to_fw_positions((op1, op2), use_channels=[1, 2]), - ( - [0, 1179, 1179, 0], - [0, 2418, 1968, 0], - [False, True, True, False], - ), + self.mockSTAR._ops_to_fw_positions((op1, op2), use_channels=[1, 2]), + ([0, 1179, 1179, 0], [0, 2418, 1968, 0], [False, True, True, False]) ) # check two operations on the same row, different column. tip_a2 = self.tip_rack.get_item("A2") op3 = Pickup(resource=tip_a2, tip=tip, offset=Coordinate.zero()) self.assertEqual( - self.STAR._ops_to_fw_positions((op1, op3), use_channels=[0, 1]), - ([1179, 1269, 0], [2418, 2418, 0], [True, True, False]), + self.mockSTAR._ops_to_fw_positions((op1, op3), use_channels=[0, 1]), + ([1179, 1269, 0], [2418, 2418, 0], [True, True, False]) ) # A1, A2, B1, B2 @@ -318,113 +328,95 @@ def test_ops_to_fw_positions(self): tip_b2 = self.tip_rack.get_item("B2") op5 = Pickup(resource=tip_b2, tip=tip, offset=Coordinate.zero()) self.assertEqual( - self.STAR._ops_to_fw_positions((op1, op4, op3, op5), use_channels=[0, 1, 2, 3]), - ( - [1179, 1179, 1269, 1269, 0], - [2418, 2328, 2418, 2328, 0], - [True, True, True, True, False], - ), + self.mockSTAR._ops_to_fw_positions((op1, op4, op3, op5), use_channels=[0, 1, 2, 3]), + ([1179, 1179, 1269, 1269, 0], [2418, 2328, 2418, 2328, 0], [True, True, True, True, False]) ) # make sure two operations on the same spot are not allowed with self.assertRaises(ValueError): - self.STAR._ops_to_fw_positions((op1, op1), use_channels=[0, 1]) + self.mockSTAR._ops_to_fw_positions((op1, op1), use_channels=[0, 1]) + + def _assert_command_sent_once(self, cmd: str, fmt: str): + """ Assert that the given command was sent to the backend exactly once. """ + self._assert_command_in_command_buffer(cmd, True, fmt) + self._assert_command_in_command_buffer(cmd, False, fmt) def test_tip_definition(self): pass async def test_tip_pickup_01(self): await self.lh.pick_up_tips(self.tip_rack["A1", "B1"]) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0TTid0001tt01tf1tl0519tv03600tg2tu0", - ), - _any_write_and_read_command_call( - "C0TPid0002xp01179 01179 00000&yp2418 2328 0000&tm1 1 0&tt01tp2244tz2164th2450td0", - ), - ] - ) + self._assert_command_sent_once( + "C0TPid0000xp01179 01179 00000&yp2418 2328 0000tm1 1 0&tt01tp2244tz2164th2450td0", + PICKUP_TIP_FORMAT) async def test_tip_pickup_56(self): await self.lh.pick_up_tips(self.tip_rack["E1", "F1"], use_channels=[4, 5]) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0TTid0001tt01tf1tl0519tv03600tg2tu0", - ), - _any_write_and_read_command_call( - "C0TPid0002xp00000 00000 00000 00000 01179 01179 00000&yp0000 0000 0000 0000 2058 1968 0000&tm0 0 0 0 1 1 0&tt01tp2244tz2164th2450td0", - ), - ] - ) - self.STAR.io.write.reset_mock() + self._assert_command_sent_once( + "C0TPid0000xp00000 00000 00000 00000 01179 01179 00000&yp0000 0000 0000 0000 2058 1968 " + "0000&tm0 0 0 0 1 1 0 &tt01tp2244tz2164th2450td0", + PICKUP_TIP_FORMAT) + + async def test_tip_pickup_15(self): + await self.lh.pick_up_tips(self.tip_rack["A1", "F1"], use_channels=[0, 4]) + self._assert_command_sent_once( + "C0TPid0000xp01179 00000 00000 00000 01179 00000&yp2418 0000 0000 0000 1968 0000 " + "&tm1 0 0 0 1 0&tt01tp2244tz2164th2450td0", + PICKUP_TIP_FORMAT) async def test_tip_drop_56(self): - await self.test_tip_pickup_56() # pick up tips first - self.STAR._write_and_read_command.side_effect = [ - "C0TRid0003kz000 000 000 000 000 000 000 000vz000 000 000 000 000 000 000 000" - ] + await self.test_tip_pickup_56() # pick up tips first await self.lh.drop_tips(self.tip_rack["E1", "F1"], use_channels=[4, 5]) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0TRid0003xp00000 00000 00000 00000 01179 01179 00000&yp0000 0000 0000 0000 2058 1968 " - "0000&tm0 0 0 0 1 1 0&tp2244tz2164th2450te2450ti1", - ) - ] - ) + self._assert_command_sent_once( + "C0TRid0000xp00000 00000 00000 00000 01179 01179 00000&yp0000 0000 0000 0000 2058 1968 " + "0000&tm0 0 0 0 1 1 0&tp2244tz2164th2450ti1", DROP_TIP_FORMAT) async def test_aspirate56(self): self.maxDiff = None - await self.test_tip_pickup_56() # pick up tips first + await self.test_tip_pickup_56() # pick up tips first assert self.plate.lid is not None self.plate.lid.unassign() for well in self.plate.get_items(["A1", "B1"]): - well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction - await self.lh.aspirate(self.plate["A1", "B1"], vols=[100, 100], use_channels=[4, 5]) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0ASid0003at0 0 0 0 0 0 0&tm0 0 0 0 1 1 0&xp00000 00000 00000 " - "00000 02983 02983 00000&yp0000 0000 0000 0000 1457 1367 0000&th2450te2450lp2000 2000 2000 " - "2000 2000 2000 2000&ch000 000 000 000 000 000 000&zl1866 1866 1866 1866 1866 1866 1866&" - "po0100 0100 0100 0100 0100 0100 0100&zu0032 0032 0032 0032 0032 0032 0032&zr06180 06180 " - "06180 06180 06180 06180 06180&zx1866 1866 1866 1866 1866 1866 1866&ip0000 0000 0000 0000 " - "0000 0000 0000&it0 0 0 0 0 0 0&fp0000 0000 0000 0000 0000 0000 0000&av01072 01072 01072 " - "01072 01072 01072 01072&as1000 1000 1000 1000 1000 1000 1000&ta000 000 000 000 000 000 000&" - "ba0000 0000 0000 0000 0000 0000 0000&oa000 000 000 000 000 000 000&lm0 0 0 0 0 0 0&ll1 1 1 " - "1 1 1 1&lv1 1 1 1 1 1 1&zo000 000 000 000 000 000 000&ld00 00 00 00 00 00 00&de0020 0020 " - "0020 0020 0020 0020 0020&wt10 10 10 10 10 10 10&mv00000 00000 00000 00000 00000 00000 00000&" - "mc00 00 00 00 00 00 00&mp000 000 000 000 000 000 000&ms1000 1000 1000 1000 1000 1000 1000&" - "mh0000 0000 0000 0000 0000 0000 0000&gi000 000 000 000 000 000 000&gj0gk0lk0 0 0 0 0 0 0&" - "ik0000 0000 0000 0000 0000 0000 0000&sd0500 0500 0500 0500 0500 0500 0500&se0500 0500 0500 " - "0500 0500 0500 0500&sz0300 0300 0300 0300 0300 0300 0300&io0000 0000 0000 0000 0000 0000 0" - "000&il00000 00000 00000 00000 00000 00000 00000&in0000 0000 0000 0000 0000 0000 0000&", - ) - ] - ) - self.STAR.io.write.reset_mock() + well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction + ps = STARParameterSet.from_hamilton_liquid_class(self.hlc, num_channels=2) + corrected_vol = self.hlc.compute_corrected_volume(100) + await self.lh.aspirate(self.plate["A1", "B1"], vols=[corrected_vol, corrected_vol], + use_channels=[4, 5], **ps.make_asp_kwargs()) + self._assert_command_sent_once("C0ASid0004at0 0 0 0 0 0 0&tm0 0 0 0 1 1 0&xp00000 00000 00000 " + "00000 02983 02983 00000&yp0000 0000 0000 0000 1457 1367 0000&th2450te2450lp2000 2000 2000 " + "2000 2000 2000 2000&ch000 000 000 000 000 000 000&zl1866 1866 1866 1866 1866 1866 1866&" + "po0100 0100 0100 0100 0100 0100 0100&zu0032 0032 0032 0032 0032 0032 0032&zr06180 06180 " + "06180 06180 06180 06180 06180&zx1866 1866 1866 1866 1866 1866 1866&ip0000 0000 0000 0000 " + "0000 0000 0000&it0 0 0 0 0 0 0&fp0000 0000 0000 0000 0000 0000 0000&av01072 01072 01072 " + "01072 01072 01072 01072&as1000 1000 1000 1000 1000 1000 1000&ta000 000 000 000 000 000 000&" + "ba0000 0000 0000 0000 0000 0000 0000&oa000 000 000 000 000 000 000&lm0 0 0 0 0 0 0&ll1 1 1 " + "1 1 1 1&lv1 1 1 1 1 1 1&zo000 000 000 000 000 000 000&ld00 00 00 00 00 00 00&de0020 0020 " + "0020 0020 0020 0020 0020&wt10 10 10 10 10 10 10&mv00000 00000 00000 00000 00000 00000 00000&" + "mc00 00 00 00 00 00 00&mp000 000 000 000 000 000 000&ms1000 1000 1000 1000 1000 1000 1000&" + "mh0000 0000 0000 0000 0000 0000 0000&gi000 000 000 000 000 000 000&gj0gk0lk0 0 0 0 0 0 0&" + "ik0000 0000 0000 0000 0000 0000 0000&sd0500 0500 0500 0500 0500 0500 0500&se0500 0500 0500 " + "0500 0500 0500 0500&sz0300 0300 0300 0300 0300 0300 0300&io0000 0000 0000 0000 0000 0000 0" + "000&il00000 00000 00000 00000 00000 00000 00000&in0000 0000 0000 0000 0000 0000 0000&", + ASPIRATION_COMMAND_FORMAT) async def test_single_channel_aspiration(self): self.lh.update_head_state({0: self.tip_rack.get_tip("A1")}) assert self.plate.lid is not None self.plate.lid.unassign() well = self.plate.get_item("A1") - well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction - await self.lh.aspirate([well], vols=[100]) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0ASid0001at0 0&tm1 0&xp02983 00000&yp1457 0000&th2450te2450lp2000 2000&ch000 000&zl1866 " - "1866&po0100 0100&zu0032 0032&zr06180 06180&zx1866 1866&ip0000 0000&it0 0&fp0000 0000&" - "av01072 01072&as1000 1000&ta000 000&ba0000 0000&oa000 000&lm0 0&ll1 1&lv1 1&zo000 000&" - "ld00 00&de0020 0020&wt10 10&mv00000 00000&mc00 00&mp000 000&ms1000 1000&mh0000 0000&" - "gi000 000&gj0gk0lk0 0&ik0000 0000&sd0500 0500&se0500 0500&sz0300 0300&io0000 0000&" - "il00000 00000&in0000 0000&", - ) - ] - ) + well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction + ps = STARParameterSet.from_hamilton_liquid_class(self.hlc, num_channels=1) + await self.lh.aspirate([well], vols=[self.hlc.compute_corrected_volume(100)], **ps.make_asp_kwargs()) + + # This passes the test, but is not the real command. + self._assert_command_sent_once( + "C0ASid0002at0 0&tm1 0&xp02983 00000&yp1457 0000&th2450te2450lp2000 2000&ch000 000&zl1866 " + "1866&po0100 0100&zu0032 0032&zr06180 06180&zx1866 1866&ip0000 0000&it0 0&fp0000 0000&" + "av01072 01072&as1000 1000&ta000 000&ba0000 0000&oa000 000&lm0 0&ll1 1&lv1 1&zo000 000&" + "ld00 00&de0020 0020&wt10 10&mv00000 00000&mc00 00&mp000 000&ms1000 1000&mh0000 0000&" + "gi000 000&gj0gk0lk0 0&ik0000 0000&sd0500 0500&se0500 0500&sz0300 0300&io0000 0000&" + "il00000 00000&in0000 0000&", + fmt=ASPIRATION_COMMAND_FORMAT) async def test_single_channel_aspiration_liquid_height(self): self.lh.update_head_state({0: self.tip_rack.get_tip("A1")}) @@ -432,22 +424,20 @@ async def test_single_channel_aspiration_liquid_height(self): assert self.plate.lid is not None self.plate.lid.unassign() well = self.plate.get_item("A1") - well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction - await self.lh.aspirate([well], vols=[100], liquid_height=[10]) + well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction + ps = STARParameterSet.from_hamilton_liquid_class(self.hlc, num_channels=1) + await self.lh.aspirate([well], vols=[self.hlc.compute_corrected_volume(100)], + liquid_height=[10], **ps.make_asp_kwargs()) # This passes the test, but is not the real command. - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0ASid0001at0 0&tm1 0&xp02983 00000&yp1457 0000&th2450te2450lp2000 2000&ch000 000&zl1966 " - "1966&po0100 0100&zu0032 0032&zr06180 06180&zx1866 1866&ip0000 0000&it0 0&fp0000 0000&" - "av01072 01072&as1000 1000&ta000 000&ba0000 0000&oa000 000&lm0 0&ll1 1&lv1 1&zo000 000&" - "ld00 00&de0020 0020&wt10 10&mv00000 00000&mc00 00&mp000 000&ms1000 1000&mh0000 0000&" - "gi000 000&gj0gk0lk0 0&ik0000 0000&sd0500 0500&se0500 0500&sz0300 0300&io0000 0000&" - "il00000 00000&in0000 0000&", - ) - ] - ) + self._assert_command_sent_once( + "C0ASid0002at0 0&tm1 0&xp02983 00000&yp1457 0000&th2450te2450lp2000 2000&ch000 000&zl1966 " + "1966&po0100 0100&zu0032 0032&zr06180 06180&zx1866 1866&ip0000 0000&it0 0&fp0000 0000&" + "av01072 01072&as1000 1000&ta000 000&ba0000 0000&oa000 000&lm0 0&ll1 1&lv1 1&zo000 000&" + "ld00 00&de0020 0020&wt10 10&mv00000 00000&mc00 00&mp000 000&ms1000 1000&mh0000 0000&" + "gi000 000&gj0gk0lk0 0&ik0000 0000&sd0500 0500&se0500 0500&sz0300 0300&io0000 0000&" + "il00000 00000&in0000 0000&", + fmt=ASPIRATION_COMMAND_FORMAT) async def test_multi_channel_aspiration(self): self.lh.update_head_state({0: self.tip_rack.get_tip("A1"), 1: self.tip_rack.get_tip("B1")}) @@ -456,81 +446,68 @@ async def test_multi_channel_aspiration(self): self.plate.lid.unassign() wells = self.plate.get_items("A1:B1") for well in wells: - well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction - await self.lh.aspirate(self.plate["A1:B1"], vols=[100] * 2) + well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction + ps = STARParameterSet.from_hamilton_liquid_class(self.hlc, num_channels=2) + corrected_vol = self.hlc.compute_corrected_volume(100) + await self.lh.aspirate(self.plate["A1:B1"], vols=[corrected_vol]*2, **ps.make_asp_kwargs()) # This passes the test, but is not the real command. - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0ASid0001at0 0 0&tm1 1 0&xp02983 02983 00000&yp1457 1367 0000&th2450te2450lp2000 2000 2000&" - "ch000 000 000&zl1866 1866 1866&po0100 0100 0100&zu0032 0032 0032&zr06180 06180 06180&" - "zx1866 1866 1866&ip0000 0000 0000&it0 0 0&fp0000 0000 0000&av01072 01072 01072&as1000 1000 " - "1000&ta000 000 000&ba0000 0000 0000&oa000 000 000&lm0 0 0&ll1 1 1&lv1 1 1&zo000 000 000&" - "ld00 00 00&de0020 0020 0020&wt10 10 10&mv00000 00000 00000&mc00 00 00&mp000 000 000&" - "ms1000 1000 1000&mh0000 0000 0000&gi000 000 000&gj0gk0lk0 0 0&ik0000 0000 0000&sd0500 0500 " - "0500&se0500 0500 0500&sz0300 0300 0300&io0000 0000 0000&il00000 00000 00000&in0000 0000 " - "0000&", - ) - ] - ) + self._assert_command_sent_once( + "C0ASid0002at0 0 0&tm1 1 0&xp02983 02983 00000&yp1457 1367 0000&th2450te2450lp2000 2000 2000&" + "ch000 000 000&zl1866 1866 1866&po0100 0100 0100&zu0032 0032 0032&zr06180 06180 06180&" + "zx1866 1866 1866&ip0000 0000 0000&it0 0 0&fp0000 0000 0000&av01072 01072 01072&as1000 1000 " + "1000&ta000 000 000&ba0000 0000 0000&oa000 000 000&lm0 0 0&ll1 1 1&lv1 1 1&zo000 000 000&" + "ld00 00 00&de0020 0020 0020&wt10 10 10&mv00000 00000 00000&mc00 00 00&mp000 000 000&" + "ms1000 1000 1000&mh0000 0000 0000&gi000 000 000&gj0gk0lk0 0 0&ik0000 0000 0000&sd0500 0500 " + "0500&se0500 0500 0500&sz0300 0300 0300&io0000 0000 0000&il00000 00000 00000&in0000 0000 " + "0000&", + fmt=ASPIRATION_COMMAND_FORMAT) async def test_aspirate_single_resource(self): self.lh.update_head_state({i: self.tip_rack.get_tip(i) for i in range(5)}) + ps = STARParameterSet.from_hamilton_liquid_class(self.hlc, num_channels=5) + corrected_vol = self.hlc.compute_corrected_volume(10) with no_volume_tracking(): - await self.lh.aspirate( - [self.bb] * 5, - vols=[10] * 5, - use_channels=[0, 1, 2, 3, 4], - liquid_height=[1] * 5, - ) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0ASid0001at0 0 0 0 0 0&tm1 1 1 1 1 0&xp04865 04865 04865 04865 04865 00000&yp2098 1962 " - "1825 1688 1552 0000&th2450te2450lp2000 2000 2000 2000 2000 2000&ch000 000 000 000 000 000&" - "zl1210 1210 1210 1210 1210 1210&po0100 0100 0100 0100 0100 0100&zu0032 0032 0032 0032 0032 " - "0032&zr06180 06180 06180 06180 06180 06180&zx1200 1200 1200 1200 1200 1200&ip0000 0000 0000 " - "0000 0000 0000&it0 0 0 0 0 0&fp0000 0000 0000 0000 0000 0000&av00119 00119 00119 00119 " - "00119 00119&as1000 1000 1000 1000 1000 1000&ta000 000 000 000 000 000&ba0000 0000 0000 0000 " - "0000 0000&oa000 000 000 000 000 000&lm0 0 0 0 0 0&ll1 1 1 1 1 1&lv1 1 1 1 1 1&zo000 000 000 " - "000 000 000&ld00 00 00 00 00 00&de0020 0020 0020 0020 0020 0020&wt10 10 10 10 10 10&mv00000 " - "00000 00000 00000 00000 00000&mc00 00 00 00 00 00&mp000 000 000 000 000 000&ms1000 1000 " - "1000 1000 1000 1000&mh0000 0000 0000 0000 0000 0000&gi000 000 000 000 000 000&gj0gk0lk0 0 0 " - "0 0 0&ik0000 0000 0000 0000 0000 0000&sd0500 0500 0500 0500 0500 0500&se0500 0500 0500 0500 " - "0500 0500&sz0300 0300 0300 0300 0300 0300&io0000 0000 0000 0000 0000 0000&il00000 00000 " - "00000 00000 00000 00000&in0000 0000 0000 0000 0000 0000&", - ) - ] - ) + await self.lh.aspirate([self.bb]*5,vols=[corrected_vol]*5, use_channels=[0,1,2,3,4], + liquid_height=[1]*5, **ps.make_asp_kwargs()) + self._assert_command_sent_once( + "C0ASid0002at0 0 0 0 0 0&tm1 1 1 1 1 0&xp04865 04865 04865 04865 04865 00000&yp2098 1962 " + "1825 1688 1552 0000&th2450te2450lp2000 2000 2000 2000 2000 2000&ch000 000 000 000 000 000&" + "zl1210 1210 1210 1210 1210 1210&po0100 0100 0100 0100 0100 0100&zu0032 0032 0032 0032 0032 " + "0032&zr06180 06180 06180 06180 06180 06180&zx1200 1200 1200 1200 1200 1200&ip0000 0000 0000 " + "0000 0000 0000&it0 0 0 0 0 0&fp0000 0000 0000 0000 0000 0000&av00119 00119 00119 00119 " + "00119 00119&as1000 1000 1000 1000 1000 1000&ta000 000 000 000 000 000&ba0000 0000 0000 0000 " + "0000 0000&oa000 000 000 000 000 000&lm0 0 0 0 0 0&ll1 1 1 1 1 1&lv1 1 1 1 1 1&zo000 000 000 " + "000 000 000&ld00 00 00 00 00 00&de0020 0020 0020 0020 0020 0020&wt10 10 10 10 10 10&mv00000 " + "00000 00000 00000 00000 00000&mc00 00 00 00 00 00&mp000 000 000 000 000 000&ms1000 1000 " + "1000 1000 1000 1000&mh0000 0000 0000 0000 0000 0000&gi000 000 000 000 000 000&gj0gk0lk0 0 0 " + "0 0 0&ik0000 0000 0000 0000 0000 0000&sd0500 0500 0500 0500 0500 0500&se0500 0500 0500 0500 " + "0500 0500&sz0300 0300 0300 0300 0300 0300&io0000 0000 0000 0000 0000 0000&il00000 00000 " + "00000 00000 00000 00000&in0000 0000 0000 0000 0000 0000&", + fmt=ASPIRATION_COMMAND_FORMAT) async def test_dispense_single_resource(self): self.lh.update_head_state({i: self.tip_rack.get_tip(i) for i in range(5)}) + hlc = StandardVolumeFilter_Water_DispenseJet_Empty + ps = STARParameterSet.from_hamilton_liquid_class(hlc, num_channels=5, + jet=[True]*5, blow_out=[True]*5) + print(ps.make_disp_kwargs()) + corrected_vol = hlc.compute_corrected_volume(10) with no_volume_tracking(): - await self.lh.dispense( - [self.bb] * 5, - vols=[10] * 5, - use_channels=[0, 1, 2, 3, 4], - liquid_height=[1] * 5, - blow_out=[True] * 5, - jet=[True] * 5, - ) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0DSid0001dm1 1 1 1 1 1&tm1 1 1 1 1 0&xp04865 04865 04865 04865 04865 00000&yp2098 1962 " - "1825 1688 1552 0000&zx1200 1200 1200 1200 1200 1200&lp2000 2000 2000 2000 2000 2000&zl1210 " - "1210 1210 1210 1210 1210&po0100 0100 0100 0100 0100 0100&ip0000 0000 0000 0000 0000 0000&" - "it0 0 0 0 0 0&fp0000 0000 0000 0000 0000 0000&zu0032 0032 0032 0032 0032 0032&zr06180 06180 " - "06180 06180 06180 06180&th2450te2450dv00116 00116 00116 00116 00116 00116&ds1800 1800 1800 " - "1800 1800 1800&ss0050 0050 0050 0050 0050 0050&rv000 000 000 000 000 000&ta050 050 050 050 " - "050 050&ba0300 0300 0300 0300 0300 0300&lm0 0 0 0 0 0&dj00zo000 000 000 000 000 000&ll1 1 1 " - "1 1 1&lv1 1 1 1 1 1&de0010 0010 0010 0010 0010 0010&wt00 00 00 00 00 00&mv00000 00000 00000 " - "00000 00000 00000&mc00 00 00 00 00 00&mp000 000 000 000 000 000&ms0010 0010 0010 0010 0010 " - "0010&mh0000 0000 0000 0000 0000 0000&gi000 000 000 000 000 000&gj0gk0", - ) - ] - ) + await self.lh.dispense([self.bb]*5, vols=[corrected_vol]*5, liquid_height=[1]*5, + **ps.make_disp_kwargs()) + self._assert_command_sent_once( + "C0DSid0002dm1 1 1 1 1 1&tm1 1 1 1 1 0&xp04865 04865 04865 04865 04865 00000&yp2098 1962 " + "1825 1688 1552 0000&zx1200 1200 1200 1200 1200 1200&lp2000 2000 2000 2000 2000 2000&zl1210 " + "1210 1210 1210 1210 1210&po0100 0100 0100 0100 0100 0100&ip0000 0000 0000 0000 0000 0000&" + "it0 0 0 0 0 0&fp0000 0000 0000 0000 0000 0000&zu0032 0032 0032 0032 0032 0032&zr06180 06180 " + "06180 06180 06180 06180&th2450te2450dv00116 00116 00116 00116 00116 00116&ds1800 1800 1800 " + "1800 1800 1800&ss0050 0050 0050 0050 0050 0050&rv000 000 000 000 000 000&ta050 050 050 050 " + "050 050&ba0300 0300 0300 0300 0300 0300&lm0 0 0 0 0 0&dj00zo000 000 000 000 000 000&ll1 1 1 " + "1 1 1&lv1 1 1 1 1 1&de0010 0010 0010 0010 0010 0010&wt00 00 00 00 00 00&mv00000 00000 00000 " + "00000 00000 00000&mc00 00 00 00 00 00&mp000 000 000 000 000 000&ms0010 0010 0010 0010 0010 " + "0010&mh0000 0000 0000 0000 0000 0000&gi000 000 000 000 000 000&gj0gk0", + fmt=DISPENSE_RESPONSE_FORMAT) async def test_single_channel_dispense(self): self.lh.update_head_state({0: self.tip_rack.get_tip("A1")}) @@ -538,13 +515,13 @@ async def test_single_channel_dispense(self): self.plate.lid.unassign() with no_volume_tracking(): await self.lh.dispense(self.plate["A1"], vols=[100], jet=[True], blow_out=[True]) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0DSid0001dm1 1&tm1 0&xp02983 00000&yp1457 0000&zx1866 1866&lp2000 2000&zl1866 1866&po0100 0100&ip0000 0000&it0 0&fp0000 0000&zu0032 0032&zr06180 06180&th2450te2450dv01072 01072&ds1800 1800&ss0050 0050&rv000 000&ta050 050&ba0300 0300&lm0 0&dj00zo000 000&ll1 1&lv1 1&de0010 0010&wt00 00&mv00000 00000&mc00 00&mp000 000&ms0010 0010&mh0000 0000&gi000 000&gj0gk0", - ) - ] - ) + self._assert_command_sent_once( + "C0DSid0002dm1 1&tm1 0&xp02983 00000&yp1457 0000&zx1866 1866&lp2000 2000&zl1866 1866&" + "po0100 0100&ip0000 0000&it0 0&fp0000 0000&zu0032 0032&zr06180 06180&th2450te2450" + "dv01072 01072&ds1800 1800&ss0050 0050&rv000 000&ta050 050&ba0300 03000&lm0 0&" + "dj00zo000 000&ll1 1&lv1 1&de0010 0010&wt00 00&mv00000 00000&mc00 00&mp000 000&" + "ms0010 0010&mh0000 0000&gi000 000&gj0gk0", + fmt=DISPENSE_RESPONSE_FORMAT) async def test_multi_channel_dispense(self): self.lh.update_head_state({0: self.tip_rack.get_tip("A1"), 1: self.tip_rack.get_tip("B1")}) @@ -552,58 +529,50 @@ async def test_multi_channel_dispense(self): assert self.plate.lid is not None self.plate.lid.unassign() with no_volume_tracking(): - await self.lh.dispense( - self.plate["A1:B1"], - vols=[100] * 2, - jet=[True] * 2, - blow_out=[True] * 2, - ) - - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0DSid0001dm1 1 1&tm1 1 0&xp02983 02983 00000&yp1457 1367 0000&zx1866 1866 1866&lp2000 2000 " - "2000&zl1866 1866 1866&po0100 0100 0100&ip0000 0000 0000&it0 0 0&fp0000 0000 0000&zu0032 " - "0032 0032&zr06180 06180 06180&th2450te2450dv01072 01072 01072&ds1800 1800 1800&" - "ss0050 0050 0050&rv000 000 000&ta050 050 050&ba0300 0300 0300&lm0 0 0&dj00zo000 000 000&" - "ll1 1 1&lv1 1 1&de0010 0010 0010&wt00 00 00&mv00000 00000 00000&mc00 00 00&mp000 000 000&" - "ms0010 0010 0010&mh0000 0000 0000&gi000 000 000&gj0gk0", - ) - ] - ) + await self.lh.dispense(self.plate["A1:B1"], vols=[100]*2, jet=[True]*2, blow_out=[True]*2) + + self._assert_command_sent_once( + "C0DSid0002dm1 1 1&tm1 1 0&xp02983 02983 00000&yp1457 1367 0000&zx1866 1866 1866&lp2000 2000 " + "2000&zl1866 1866 1866&po0100 0100 0100&ip0000 0000 0000&it0 0 0&fp0000 0000 0000&zu0032 " + "0032 0032&zr06180 06180 06180&th2450te2450dv01072 01072 01072&ds1800 1800 1800&" + "ss0050 0050 0050&rv000 000 000&ta050 050 050&ba0300 0300 0300&lm0 0 0&dj00zo000 000 000&" + "ll1 1 1&lv1 1 1&de0010 0010 0010&wt00 00 00&mv00000 00000 00000&mc00 00 00&mp000 000 000&" + "ms0010 0010 0010&mh0000 0000 0000&gi000 000 000&gj0gk0", + fmt=DISPENSE_RESPONSE_FORMAT) + + async def test_zero_volume_liquid_handling(self): + # just test that this does not throw an error + self.lh.update_head_state({0: self.tip_rack.get_tip("A1")}) + assert self.plate.lid is not None + self.plate.lid.unassign() + await self.lh.aspirate(self.plate["A1"], vols=[0]) + await self.lh.dispense(self.plate["A1"], vols=[0]) async def test_core_96_tip_pickup(self): await self.lh.pick_up_tips96(self.tip_rack) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call("C0TTid0001tt01tf1tl0519tv03600tg2tu0"), - _any_write_and_read_command_call("C0EPid0002xs01179xd0yh2418tt01wu0za2164zh2450ze2450"), - ] - ) + + self._assert_command_sent_once( + "C0EPid0208xs01179xd0yh2418tt01wu0za2164zh2450ze2450", + "xs#####xd#yh####tt##wu#za####zh####ze####") async def test_core_96_tip_drop(self): - await self.lh.pick_up_tips96(self.tip_rack) # pick up tips first - self.STAR._write_and_read_command.reset_mock() + await self.lh.pick_up_tips96(self.tip_rack) # pick up tips first await self.lh.drop_tips96(self.tip_rack) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call("C0ERid0003xs01179xd0yh2418za2164zh2450ze2450"), - ] - ) + + self._assert_command_sent_once( + "C0ERid0213xs01179xd0yh2418za2164zh2450ze2450", + "xs#####xd#yh####za####zh####ze####") async def test_core_96_tip_discard(self): - await self.lh.pick_up_tips96(self.tip_rack) # pick up tips first - self.STAR._write_and_read_command.reset_mock() + await self.lh.pick_up_tips96(self.tip_rack) # pick up tips first await self.lh.discard_tips96() - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call("C0ERid0003xs00420xd1yh1203za2164zh2450ze2450"), - ] - ) + + self._assert_command_sent_once( + "C0ERid0213xs02321xd1yh1103za2164zh2450ze2450", + "xs#####xd#yh####za####zh####ze####") async def test_core_96_aspirate(self): - await self.lh.pick_up_tips96(self.tip_rack2) # pick up high volume tips - self.STAR._write_and_read_command.reset_mock() + await self.lh.pick_up_tips96(self.tip_rack2) # pick up high volume tips # TODO: Hamilton liquid classes assert self.plate.lid is not None @@ -611,32 +580,31 @@ async def test_core_96_aspirate(self): await self.lh.aspirate96(self.plate, volume=100, blow_out=True) # volume used to be 01072, but that was generated using a non-core liquid class. - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0EAid0003aa0xs02983xd0yh1457zh2450ze2450lz1999zt1866pp0100zm1866zv0032zq06180iw000ix0fh000af01083ag2500vt050bv00000wv00050cm0cs1bs0020wh10hv00000hc00hp000mj000hs1200cwFFFFFFFFFFFFFFFFFFFFFFFFcr000cj0cx0" - ), - ] - ) + self._assert_command_sent_once( + "C0EAid0001aa0xs02983xd0yh1457zh2450ze2450lz1999zt1866zm1866iw000ix0fh000af01083ag2500vt050" + "bv00000wv00050cm0cs1bs0020wh10hv00000hc00hp000hs1200zv0032zq06180mj000cj0cx0cr000" + "cwFFFFFFFFFFFFFFFFFFFFFFFFpp0100", + "xs#####xd#yh####zh####ze####lz####zt####zm####iw###ix#fh###af#####ag####vt###" + "bv#####wv#####cm#cs#bs####wh##hv#####hc##hp###hs####zv####zq#####mj###cj#cx#cr###" + "cw************************pp####") async def test_core_96_dispense(self): - await self.lh.pick_up_tips96(self.tip_rack2) # pick up high volume tips + await self.lh.pick_up_tips96(self.tip_rack2) # pick up high volume tips if self.plate.lid is not None: self.plate.lid.unassign() - await self.lh.aspirate96(self.plate, 100, blow_out=True) # aspirate first - self.STAR._write_and_read_command.reset_mock() + await self.lh.aspirate96(self.plate, 100, blow_out=True) # aspirate first with no_volume_tracking(): await self.lh.dispense96(self.plate, 100, blow_out=True) # volume used to be 01072, but that was generated using a non-core liquid class. - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0EDid0004da3xs02983xd0yh1457zm1866zv0032zq06180lz1999zt1866pp0100iw000ix0fh000zh2450ze2450df01083dg1200es0050ev000vt050bv00000cm0cs1ej00bs0020wh00hv00000hc00hp000mj000hs1200cwFFFFFFFFFFFFFFFFFFFFFFFFcr000cj0cx0" - ), - ] - ) + self._assert_command_sent_once( + "C0EDid0001da3xs02983xd0yh1457zh2450ze2450lz1999zt1866zm1866iw000ix0fh000df01083dg1200vt050" + "bv00000cm0cs1bs0020wh00hv00000hc00hp000hs1200es0050ev000zv0032ej00zq06180mj000cj0cx0cr000" + "cwFFFFFFFFFFFFFFFFFFFFFFFFpp0100", + "da#xs#####xd#yh##6#zh####ze####lz####zt####zm##6#iw###ix#fh###df#####dg####vt###" + "bv#####cm#cs#bs####wh##hv#####hc##hp###hs####es####ev###zv####ej##zq#6###mj###cj#cx#cr###" + "cw************************pp####") async def test_zero_volume_liquid_handling96(self): # just test that this does not throw an error @@ -647,256 +615,196 @@ async def test_zero_volume_liquid_handling96(self): await self.lh.dispense96(self.plate, 0) async def test_iswap(self): - await self.lh.move_plate( - self.plate, - self.plt_car[2], - pickup_distance_from_top=13.2 - 3.33, - ) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0PPid0001xs03479xd0yj1142yd0zj1874zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1", - ), - _any_write_and_read_command_call( - "C0PRid0002xs03479xd0yj3062yd0zj1874zd0th2840te2840gr1go1308ga0", - ), - ] - ) + await self.lh.move_plate(self.plate, self.plt_car[2], pickup_distance_from_top=13.2-3.33) + self._assert_command_sent_once( + "C0PPid0011xs03479xd0yj1142yd0zj1874zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", + "xs#####xd#yj####yd#zj####zd#gr#th####te####gw#go####gb####gt##ga#gc#") + self._assert_command_sent_once( + "C0PRid0012xs03479xd0yj3062yd0zj1874zd0th2450te2450gr1go1308ga0", + "xs#####xd#yj####yd#zj####zd#th####te####go####ga#") async def test_iswap_plate_reader(self): - plate_reader = PlateReader( - name="plate_reader", - backend=PlateReaderChatterboxBackend(), - size_x=0, - size_y=0, - size_z=0, - ) - self.deck.assign_child_resource( - plate_reader, location=Coordinate(1000, 264.7, 200 - 3.03) - ) # 666: 00002 - - await self.lh.move_plate( - self.plate, - plate_reader, - pickup_distance_from_top=8.2 - 3.33, - pickup_direction=GripDirection.FRONT, - drop_direction=GripDirection.LEFT, - ) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0PPid0001xs03479xd0yj1142yd0zj1924zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1", - ), - _any_write_and_read_command_call( - "C0PRid0002xs10427xd0yj3286yd0zj2063zd0th2840te2840gr4go1308ga0", - ), - ] - ) - self.STAR._write_and_read_command.reset_mock() + plate_reader = PlateReader(name="plate_reader", backend=MockPlateReaderBackend(), + size_x=0, size_y=0, size_z=0) + self.lh.deck.assign_child_resource(plate_reader, + location=Coordinate(1000, 264.7, 200-3.03)) # 666: 00002 + + await self.lh.move_plate(self.plate, plate_reader, pickup_distance_from_top=8.2-3.33, + get_direction=GripDirection.FRONT, put_direction=GripDirection.LEFT) + plate_origin_location = { + "xs": "03479", + "xd": "0", + "yj": "1142", + "yd": "0", + "zj": "1924", + "zd": "0", + } + plate_reader_location = { + "xs": "10427", + "xd": "0", + "yj": "3286", + "yd": "0", + "zj": "2063", + "zd": "0", + } + self._assert_command_sent_once( + f"C0PPid0003xs{plate_origin_location['xs']}xd{plate_origin_location['xd']}" + f"yj{plate_origin_location['yj']}yd{plate_origin_location['yd']}" + f"zj{plate_origin_location['zj']}zd{plate_origin_location['zd']}" + f"th2450te2450gw4gb1245go1308gt20gr1ga0gc1", + "xs#####xd#yj####yd#zj####zd#th####te####gw#gb####go####gt##gr#ga#gc#") + self._assert_command_sent_once( + f"C0PRid0004xs{plate_reader_location['xs']}xd{plate_reader_location['xd']}" + f"yj{plate_reader_location['yj']}yd{plate_reader_location['yd']}" + f"zj{plate_reader_location['zj']}zd{plate_reader_location['zd']}" + f"th2450te2450go1308gr4ga0", + "xs#####xd#yj####yd#zj####zd#th####te####go####gr#ga#") assert self.plate.rotation.z == 270 self.assertAlmostEqual(self.plate.get_absolute_size_x(), 85.48, places=2) self.assertAlmostEqual(self.plate.get_absolute_size_y(), 127.76, places=2) - await self.lh.move_plate( - plate_reader.get_plate(), - self.plt_car[0], - pickup_distance_from_top=8.2 - 3.33, - pickup_direction=GripDirection.LEFT, - drop_direction=GripDirection.FRONT, - ) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0PPid0003xs10427xd0yj3286yd0zj2063zd0gr4th2840te2840gw4go1308gb1245gt20ga0gc1", - ), - _any_write_and_read_command_call( - "C0PRid0004xs03479xd0yj1142yd0zj1924zd0th2840te2840gr1go1308ga0", - ), - ] - ) + await self.lh.move_plate(plate_reader.get_plate(), self.plt_car[0], + pickup_distance_from_top=8.2-3.33, get_direction=GripDirection.LEFT, + put_direction=GripDirection.FRONT) + self._assert_command_sent_once( + f"C0PPid0005xs{plate_reader_location['xs']}xd{plate_reader_location['xd']}" + f"yj{plate_reader_location['yj']}yd{plate_reader_location['yd']}" + f"zj{plate_reader_location['zj']}zd{plate_reader_location['zd']}" + f"gr4th2450te2450gw4go1308gb1245gt20ga0gc1", + "xs#####xd#yj####yd#zj####zd#gr#th####te####gw#go####gb####gt##ga#gc#") + self._assert_command_sent_once( + f"C0PRid0006xs{plate_origin_location['xs']}xd{plate_origin_location['xd']}" + f"yj{plate_origin_location['yj']}yd{plate_origin_location['yd']}" + f"zj{plate_origin_location['zj']}zd{plate_origin_location['zd']}" + f"th2450te2450gr1go1308ga0", + "xs#####xd#yj####yd#zj####zd#th####te####gr#go####ga#") async def test_iswap_move_lid(self): assert self.plate.lid is not None and self.other_plate.lid is not None - self.other_plate.lid.unassign() # remove lid from plate + self.other_plate.lid.unassign() # remove lid from plate await self.lh.move_lid(self.plate.lid, self.other_plate) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0PPid0001xs03479xd0yj1142yd0zj1950zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1" - ), - _any_write_and_read_command_call( - "C0PRid0002xs03479xd0yj2102yd0zj1950zd0th2840te2840gr1go1308ga0" - ), - ] - ) + self._assert_command_sent_once( + "C0PPid0002xs03479xd0yj1142yd0zj1950zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", + GET_PLATE_FMT) + self._assert_command_sent_once( # zj sent = 1849 + "C0PRid0003xs03479xd0yj2102yd0zj1950zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT) async def test_iswap_stacking_area(self): stacking_area = ResourceStack("stacking_area", direction="z") # for some reason it was like this at some point # self.lh.assign_resource(hotel, location=Coordinate(6, 414-63, 217.2 - 100)) - # f.lh.deck.assign_child_resource(hotel, location=Coordinate(6, 414-63, 231.7 - 100 +4.5)) - self.deck.assign_child_resource(stacking_area, location=Coordinate(6, 414, 226.2 - 3.33)) + # self.lh.deck.assign_child_resource(hotel, location=Coordinate(6, 414-63, 231.7 - 100 +4.5)) + self.lh.deck.assign_child_resource(stacking_area, location=Coordinate(6, 414, 226.2-3.33)) assert self.plate.lid is not None await self.lh.move_lid(self.plate.lid, stacking_area) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0PPid0001xs03479xd0yj1142yd0zj1950zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1" - ), - _any_write_and_read_command_call( - "C0PRid0002xs00699xd0yj4567yd0zj2305zd0th2840te2840gr1go1308ga0" - ), - ] - ) - self.STAR._write_and_read_command.reset_mock() + self._assert_command_sent_once( + "C0PPid0002xs03479xd0yj1142yd0zj1950zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", + GET_PLATE_FMT) + self._assert_command_sent_once( + "C0PRid0003xs00699xd0yj4567yd0zj2305zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT) # Move lids back (reverse order) await self.lh.move_lid(cast(Lid, stacking_area.get_top_item()), self.plate) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0PPid0003xs00699xd0yj4567yd0zj2305zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1" - ), - _any_write_and_read_command_call( - "C0PRid0004xs03479xd0yj1142yd0zj1950zd0th2840te2840gr1go1308ga0" - ), - ] - ) + self._assert_command_sent_once( + "C0PPid0004xs00699xd0yj4567yd0zj2305zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", + GET_PLATE_FMT) + self._assert_command_sent_once( + "C0PRid0005xs03479xd0yj1142yd0zj1950zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT) async def test_iswap_stacking_area_2lids(self): # for some reason it was like this at some point # self.lh.assign_resource(hotel, location=Coordinate(6, 414-63, 217.2 - 100)) stacking_area = ResourceStack("stacking_area", direction="z") - self.deck.assign_child_resource(stacking_area, location=Coordinate(6, 414, 226.2 - 3.33)) + self.lh.deck.assign_child_resource(stacking_area, location=Coordinate(6, 414, 226.2-3.33)) assert self.plate.lid is not None and self.other_plate.lid is not None await self.lh.move_lid(self.plate.lid, stacking_area) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0PPid0001xs03479xd0yj1142yd0zj1950zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1" - ), - _any_write_and_read_command_call( - "C0PRid0002xs00699xd0yj4567yd0zj2305zd0th2840te2840gr1go1308ga0" - ), - ] - ) - self.STAR._write_and_read_command.reset_mock() + self._assert_command_sent_once( + "C0PPid0002xs03479xd0yj1142yd0zj1950zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", + GET_PLATE_FMT) + self._assert_command_sent_once( + "C0PRid0003xs00699xd0yj4567yd0zj2305zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT) await self.lh.move_lid(self.other_plate.lid, stacking_area) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0PPid0003xs03479xd0yj2102yd0zj1950zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1" - ), - _any_write_and_read_command_call( - "C0PRid0004xs00699xd0yj4567yd0zj2405zd0th2840te2840gr1go1308ga0" - ), - ] - ) - self.STAR._write_and_read_command.reset_mock() + self._assert_command_sent_once( + "C0PPid0004xs03479xd0yj2102yd0zj1950zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", + GET_PLATE_FMT) + self._assert_command_sent_once( + "C0PRid0005xs00699xd0yj4567yd0zj2405zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT) # Move lids back (reverse order) top_item = stacking_area.get_top_item() assert isinstance(top_item, Lid) await self.lh.move_lid(top_item, self.plate) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0PPid0005xs00699xd0yj4567yd0zj2405zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1" - ), - _any_write_and_read_command_call( - "C0PRid0006xs03479xd0yj1142yd0zj1950zd0th2840te2840gr1go1308ga0" - ), - ] - ) - self.STAR._write_and_read_command.reset_mock() + self._assert_command_sent_once( + "C0PPid0004xs00699xd0yj4567yd0zj2405zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", + GET_PLATE_FMT) + self._assert_command_sent_once( + "C0PRid0005xs03479xd0yj1142yd0zj1950zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT) top_item = stacking_area.get_top_item() assert isinstance(top_item, Lid) await self.lh.move_lid(top_item, self.other_plate) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0PPid0007xs00699xd0yj4567yd0zj2305zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1" - ), - _any_write_and_read_command_call( - "C0PRid0008xs03479xd0yj2102yd0zj1950zd0th2840te2840gr1go1308ga0" - ), - ] - ) - self.STAR._write_and_read_command.reset_mock() + self._assert_command_sent_once( + "C0PPid0004xs00699xd0yj4567yd0zj2305zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", + GET_PLATE_FMT) + self._assert_command_sent_once( + "C0PRid0005xs03479xd0yj2102yd0zj1950zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT) async def test_iswap_move_with_intermediate_locations(self): - self.plt_car[1].resource.unassign() - await self.lh.move_plate( - self.plate, - self.plt_car[1], - intermediate_locations=[ - self.plt_car[2].get_absolute_location() + Coordinate(50, 0, 50), - self.plt_car[3].get_absolute_location() + Coordinate(-50, 0, 50), - ], - ) - - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0PPid0001xs03479xd0yj1142yd0zj1874zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1" - ), - _any_write_and_read_command_call("C0PMid0002xs03979xd0yj3062yd0zj2432zd0gr1th2840ga1xe4 1"), - _any_write_and_read_command_call("C0PMid0003xs02979xd0yj4022yd0zj2432zd0gr1th2840ga1xe4 1"), - _any_write_and_read_command_call( - "C0PRid0004xs03479xd0yj2102yd0zj1874zd0th2840te2840gr1go1308ga0" - ), - ] - ) + await self.lh.move_plate(self.plate, self.plt_car[1], intermediate_locations=[ + self.plt_car[2].get_absolute_location() + Coordinate(50, 0, 50), + self.plt_car[3].get_absolute_location() + Coordinate(-50, 0, 50), + ]) + + self._assert_command_sent_once( + "C0PPid0023xs03479xd0yj1142yd0zj1874zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", + GET_PLATE_FMT) + self._assert_command_sent_once( + "C0PMid0024xs02979xd0yj4022yd0zj2432zd0gr1th2450ga1xe4 1", INTERMEDIATE_FMT) + self._assert_command_sent_once( + "C0PMid0025xs03979xd0yj3062yd0zj2432zd0gr1th2450ga1xe4 1", INTERMEDIATE_FMT) + self._assert_command_sent_once( + "C0PRid0026xs03479xd0yj2102yd0zj1874zd0th2450te2450gr1go1308ga0", + PUT_PLATE_FMT) async def test_discard_tips(self): await self.lh.pick_up_tips(self.tip_rack["A1:H1"]) - # {"id": 2, "kz": [000, 000, 000, 000, 000, 000, 000, 000], "vz": [000, 000, 000, 000, 000, 000, 000, 000]} - self.STAR._write_and_read_command.side_effect = [ - "C0TRid0003kz000 000 000 000 000 000 000 000vz000 000 000 000 000 000 000 000" - ] - self.STAR._write_and_read_command.reset_mock() await self.lh.discard_tips() - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0TRid0003xp08000 08000 08000 08000 08000 08000 08000 08000yp3427 3337 3247 3157 3067 2977 2887 2797tm1 1 1 1 1 1 1 1tp1970tz1870th2450te2450ti0", - ) - ] - ) + self._assert_command_sent_once( + "C0TRid0206xp08000 08000 08000 08000 08000 08000 08000 08000yp4050 3782 3514 3246 2978 2710 " + "2442 2174tp1970tz1870th2450te2450tm1 1 1 1 1 1 1 1ti0", + DROP_TIP_FORMAT) async def test_portrait_tip_rack_handling(self): + # Test with an alternative setup. + deck = STARLetDeck() - lh = LiquidHandler(self.STAR, deck=deck) + lh = LiquidHandler(self.mockSTAR, deck=deck) tip_car = TIP_CAR_288_C00(name="tip carrier") - tip_car[0] = tr = HT(name="tips_01").rotated(z=90) + tip_car[0] = tr = HT_P(name="tips_01") assert tr.rotation.z == 90 assert tr.location == Coordinate(82.6, 0, 0) deck.assign_child_resource(tip_car, rails=2) await lh.setup() await lh.pick_up_tips(tr["A4:A1"]) - self.STAR._write_and_read_command.side_effect = [ - "C0TRid0002kz000 000 000 000 000 000 000 000vz000 000 000 000 000 000 000 000" - ] + + self._assert_command_sent_once( + "C0TPid0035xp01360 01360 01360 01360 00000&yp1380 1290 1200 1110 0000&tm1 1 1 1 0&tt01tp2263tz" + "2163th2450td0", + PICKUP_TIP_FORMAT) + await lh.drop_tips(tr["A4:A1"]) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0TPid0002xp01360 01360 01360 01360 00000&yp1380 1290 1200 1110 0000&tm1 1 1 1 0&tt01tp2263tz2163th2450td0" - ), - _any_write_and_read_command_call( - "C0TRid0003xp01360 01360 01360 01360 00000&yp1380 1290 1200 1110 0000&tm1 1 1 1 0&tp2263tz2183th2450te2450ti1" - ), - ] - ) + self._assert_command_sent_once( + "C0TRid0036xp01360 01360 01360 01360 00000&yp1380 1290 1200 1110 0000&tm1 1 1 1 0&tp2263tz" + "2183th2450ti1", + DROP_TIP_FORMAT) def test_serialize(self): serialized = LiquidHandler(backend=STAR(), deck=STARLetDeck()).serialize() @@ -905,362 +813,56 @@ def test_serialize(self): self.assertEqual(deserialized.backend.__class__.__name__, "STAR") async def test_move_core(self): - self.plt_car[1].resource.unassign() - await self.lh.move_plate( - self.plate, - self.plt_car[1], - pickup_distance_from_top=13 - 3.33, - use_arm="core", - # kwargs specific to pickup and drop - channel_1=7, - channel_2=8, - return_core_gripper=True, - ) - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0ZTid0001xs07975xd0ya1240yb1065pa07pb08tp2350tz2250th2840tt14" - ), - _any_write_and_read_command_call( - "C0ZPid0002xs03479xd0yj1142yv0050zj1876zy0500yo0885yg0825yw15" "th2840te2840" - ), - _any_write_and_read_command_call( - "C0ZRid0003xs03479xd0yj2102zj1876zi000zy0500yo0885th2840te2840" - ), - _any_write_and_read_command_call( - "C0ZSid0004xs07975xd0ya1240yb1065tp2150tz2050th2840te2840" - ), - ] - ) - - -class STARIswapMovementTests(unittest.IsolatedAsyncioTestCase): - async def asyncSetUp(self): - self.STAR = STAR() - self.STAR._write_and_read_command = unittest.mock.AsyncMock() - self.deck = STARLetDeck() - self.lh = LiquidHandler(self.STAR, deck=self.deck) - - self.plt_car = PLT_CAR_L5MD_A00(name="plt_car") - self.plt_car[0] = self.plate = CellTreat_96_wellplate_350ul_Ub(name="plate", with_lid=True) - self.deck.assign_child_resource(self.plt_car, rails=15) - - self.plt_car2 = PLT_CAR_P3AC_A01(name="plt_car2") - self.deck.assign_child_resource(self.plt_car2, rails=3) - - self.STAR._num_channels = 8 - self.STAR.core96_head_installed = True - self.STAR.iswap_installed = True - self.STAR.setup = unittest.mock.AsyncMock() - self.STAR._core_parked = True - self.STAR._iswap_parked = True - await self.lh.setup() - - async def test_simple_movement(self): - await self.lh.move_plate(self.plate, self.plt_car[1]) - await self.lh.move_plate(self.plate, self.plt_car[0]) - - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0PPid0001xs04829xd0yj1141yd0zj2143zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1", - ), - _any_write_and_read_command_call( - "C0PRid0002xs04829xd0yj2101yd0zj2143zd0th2840te2840gr1go1308ga0", - ), - _any_write_and_read_command_call( - "C0PPid0003xs04829xd0yj2101yd0zj2143zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1", - ), - _any_write_and_read_command_call( - "C0PRid0004xs04829xd0yj1141yd0zj2143zd0th2840te2840gr1go1308ga0" - ), - ] - ) - - async def test_movement_to_portrait_site_left(self): - await self.lh.move_plate(self.plate, self.plt_car2[0], drop_direction=GripDirection.LEFT) - await self.lh.move_plate(self.plate, self.plt_car[0], drop_direction=GripDirection.LEFT) - - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0PPid0001xs04829xd0yj1141yd0zj2143zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1", - ), - _any_write_and_read_command_call( - "C0PRid0002xs02317xd0yj1644yd0zj1884zd0th2840te2840gr4go1308ga0", - ), - _any_write_and_read_command_call( - "C0PPid0003xs02317xd0yj1644yd0zj1884zd0gr1th2840te2840gw4go0881gb0818gt20ga0gc1", - ), - _any_write_and_read_command_call( - "C0PRid0004xs04829xd0yj1141yd0zj2143zd0th2840te2840gr4go0881ga0", - ), - ] - ) - - async def test_movement_to_portrait_site_right(self): - await self.lh.move_plate(self.plate, self.plt_car2[0], drop_direction=GripDirection.RIGHT) - await self.lh.move_plate(self.plate, self.plt_car[0], drop_direction=GripDirection.RIGHT) - - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0PPid0001xs04829xd0yj1141yd0zj2143zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1", - ), - _any_write_and_read_command_call( - "C0PRid0002xs02317xd0yj1644yd0zj1884zd0th2840te2840gr2go1308ga0", - ), - _any_write_and_read_command_call( - "C0PPid0003xs02317xd0yj1644yd0zj1884zd0gr1th2840te2840gw4go0881gb0818gt20ga0gc1", - ), - _any_write_and_read_command_call( - "C0PRid0004xs04829xd0yj1141yd0zj2143zd0th2840te2840gr2go0881ga0", - ), - ] - ) - - async def test_move_lid_across_rotated_resources(self): - self.plt_car2[0] = plate2 = CellTreat_96_wellplate_350ul_Ub( - name="plate2", with_lid=False - ).rotated(z=270) - self.plt_car2[1] = plate3 = CellTreat_96_wellplate_350ul_Ub( - name="plate3", with_lid=False - ).rotated(z=90) - - assert plate2.get_absolute_location() == Coordinate(x=189.1, y=228.26, z=183.98) - assert plate3.get_absolute_location() == Coordinate(x=274.21, y=246.5, z=183.98) - - assert self.plate.lid is not None - await self.lh.move_lid(self.plate.lid, plate2, drop_direction=GripDirection.LEFT) - assert plate2.lid is not None - await self.lh.move_lid(plate2.lid, plate3, drop_direction=GripDirection.BACK) - assert plate3.lid is not None - await self.lh.move_lid(plate3.lid, self.plate, drop_direction=GripDirection.LEFT) - - self.STAR._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call( - "C0PPid0001xs04829xd0yj1142yd0zj2242zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1", - ), - _any_write_and_read_command_call( - "C0PRid0002xs02318xd0yj1644yd0zj1983zd0th2840te2840gr4go1308ga0", - ), - _any_write_and_read_command_call( - "C0PPid0003xs02318xd0yj1644yd0zj1983zd0gr1th2840te2840gw4go0885gb0822gt20ga0gc1", - ), - _any_write_and_read_command_call( - "C0PRid0004xs02315xd0yj3104yd0zj1983zd0th2840te2840gr3go0885ga0", - ), - _any_write_and_read_command_call( - "C0PPid0005xs02315xd0yj3104yd0zj1983zd0gr1th2840te2840gw4go0885gb0822gt20ga0gc1", - ), - _any_write_and_read_command_call( - "C0PRid0006xs04829xd0yj1142yd0zj2242zd0th2840te2840gr4go0885ga0", - ), - ] - ) - - -class STARFoilTests(unittest.IsolatedAsyncioTestCase): - async def asyncSetUp(self): - self.star = STAR() - self.star._write_and_read_command = unittest.mock.AsyncMock() - self.deck = STARLetDeck() - self.lh = LiquidHandler(backend=self.star, deck=self.deck) - - tip_carrier = TIP_CAR_480_A00(name="tip_carrier") - tip_carrier[1] = self.tip_rack = HT(name="tip_rack") - self.deck.assign_child_resource(tip_carrier, rails=1) - - plt_carrier = PLT_CAR_L5AC_A00(name="plt_carrier") - plt_carrier[0] = self.plate = AGenBio_1_troughplate_190000uL_Fl(name="plate") - self.well = self.plate.get_well("A1") - self.deck.assign_child_resource(plt_carrier, rails=10) - - self.star._num_channels = 8 - self.star.core96_head_installed = True - self.star.iswap_installed = True - self.star.setup = unittest.mock.AsyncMock() - self.star._core_parked = True - self.star._iswap_parked = True - await self.lh.setup() - - await self.lh.pick_up_tips(self.tip_rack["A1:H1"]) - - async def test_pierce_foil_wide(self): - aspiration_channels = [1, 2, 3, 4, 5, 6] - hold_down_channels = [0, 7] - self.star._write_and_read_command.side_effect = [ - "C0JXid0051er00/00", - "C0RYid0052er00/00ry+1530 +1399 +1297 +1196 +1095 +0994 +0892 +0755", - "C0JYid0053er00/00", - "C0RZid0054er00/00rz+2476 +2476 +2476 +2476 +2476 +2476 +2476 +2476", - "C0JZid0055er00/00", - "C0RYid0056er00/00ry+1530 +1399 +1297 +1196 +1095 +0994 +0892 +0755", - "C0JYid0057er00/00", - "C0KZid0058er00/00", - "C0KZid0059er00/00", - "C0RZid0060er00/00rz+2256 +2083 +2083 +2083 +2083 +2083 +2083 +2256", - "C0RZid0061er00/00rz+2256 +2083 +2083 +2083 +2083 +2083 +2083 +2256", - "C0JZid0062er00/00", - "C0ZAid0063er00/00", - ] - await self.star.pierce_foil( - wells=[self.well], - piercing_channels=aspiration_channels, - hold_down_channels=hold_down_channels, - move_inwards=4, - one_by_one=False, - spread="wide", - ) - self.star._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call("C0JXid0003xs03702"), - _any_write_and_read_command_call("C0RYid0004"), - _any_write_and_read_command_call("C0JYid0005yp1530 1399 1297 1196 1095 0994 0892 0755"), - _any_write_and_read_command_call("C0RZid0006"), - _any_write_and_read_command_call("C0JZid0007zp2476 2083 2083 2083 2083 2083 2083 2476"), - _any_write_and_read_command_call("C0RYid0008"), - _any_write_and_read_command_call("C0JYid0009yp1530 1399 1297 1196 1095 0994 0892 0755"), - _any_write_and_read_command_call("C0KZid0010pn08zj2256"), - _any_write_and_read_command_call("C0KZid0011pn01zj2256"), - _any_write_and_read_command_call("C0RZid0012"), - _any_write_and_read_command_call("C0RZid0013"), - _any_write_and_read_command_call("C0JZid0014zp2256 2406 2406 2406 2406 2406 2406 2256"), - _any_write_and_read_command_call("C0ZAid0015"), - ] - ) - - async def test_pierce_foil_tight(self): - aspiration_channels = [1, 2, 3, 4, 5, 6] - hold_down_channels = [0, 7] - self.star._write_and_read_command.side_effect = [ - "C0JXid0064er00/00", - "C0RYid0065er00/00ry+1530 +1399 +1297 +1196 +1095 +0994 +0892 +0755", - "C0JYid0066er00/00", - "C0RZid0067er00/00rz+2476 +2476 +2476 +2476 +2476 +2476 +2476 +2476", - "C0JZid0068er00/00", - "C0RYid0069er00/00ry+1530 +1370 +1280 +1190 +1100 +1010 +0920 +0755", - "C0JYid0070er00/00", - "C0KZid0071er00/00", - "C0KZid0072er00/00", - "C0RZid0073er00/00rz+2256 +2083 +2083 +2083 +2083 +2083 +2083 +2256", - "C0RZid0074er00/00rz+2256 +2083 +2083 +2083 +2083 +2083 +2083 +2256", - "C0JZid0075er00/00", - "C0ZAid0076er00/00", - ] - await self.star.pierce_foil( - wells=[self.well], - piercing_channels=aspiration_channels, - hold_down_channels=hold_down_channels, - move_inwards=4, - one_by_one=False, - spread="tight", - ) - self.star._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call("C0JXid0003xs03702"), - _any_write_and_read_command_call("C0RYid0004"), - _any_write_and_read_command_call("C0JYid0005yp1530 1370 1280 1190 1100 1010 0920 0755"), - _any_write_and_read_command_call("C0RZid0006"), - _any_write_and_read_command_call("C0JZid0007zp2476 2083 2083 2083 2083 2083 2083 2476"), - _any_write_and_read_command_call("C0RYid0008"), - _any_write_and_read_command_call("C0JYid0009yp1530 1370 1280 1190 1100 1010 0920 0755"), - _any_write_and_read_command_call("C0KZid0010pn08zj2256"), - _any_write_and_read_command_call("C0KZid0011pn01zj2256"), - _any_write_and_read_command_call("C0RZid0012"), - _any_write_and_read_command_call("C0RZid0013"), - _any_write_and_read_command_call("C0JZid0014zp2256 2406 2406 2406 2406 2406 2406 2256"), - _any_write_and_read_command_call("C0ZAid0015"), - ] - ) - - async def test_pierce_foil_portrait_wide(self): - self.plate.rotate(z=90) - aspiration_channels = [1, 2, 3, 4, 5, 6] - hold_down_channels = [0, 7] - self.star._write_and_read_command.side_effect = [ - "C0JXid0170er00/00", - "C0RYid0171er00/00ry+1530 +1399 +1297 +1196 +1095 +0994 +0892 +0755", - "C0JYid0172er00/00", - "C0RZid0173er00/00rz+2476 +2476 +2476 +2476 +2476 +2476 +2476 +2476", - "C0JZid0174er00/00", - "C0RYid0175er00/00ry+1825 +1735 +1582 +1429 +1275 +1122 +0969 +0755", - "C0JYid0176er00/00", - "C0KZid0177er00/00", - "C0KZid0178er00/00", - "C0RZid0179er00/00rz+2256 +2083 +2083 +2083 +2083 +2083 +2083 +2256", - "C0RZid0180er00/00rz+2256 +2083 +2083 +2083 +2083 +2083 +2083 +2256", - "C0JZid0181er00/00", - "C0ZAid0182er00/00", - ] - await self.star.pierce_foil( - wells=[self.well], - piercing_channels=aspiration_channels, - hold_down_channels=hold_down_channels, - move_inwards=4, - one_by_one=False, - spread="tight", - ) - self.star._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call("C0JXid0003xs02634"), - _any_write_and_read_command_call("C0RYid0004"), - _any_write_and_read_command_call("C0JYid0005yp1667 1577 1487 1397 1307 1217 1127 0755"), - _any_write_and_read_command_call("C0RZid0006"), - _any_write_and_read_command_call("C0JZid0007zp2476 2083 2083 2083 2083 2083 2083 2476"), - _any_write_and_read_command_call("C0RYid0008"), - _any_write_and_read_command_call("C0JYid0009yp1953 1735 1582 1429 1275 1122 0969 0755"), - _any_write_and_read_command_call("C0KZid0010pn08zj2256"), - _any_write_and_read_command_call("C0KZid0011pn01zj2256"), - _any_write_and_read_command_call("C0RZid0012"), - _any_write_and_read_command_call("C0RZid0013"), - _any_write_and_read_command_call("C0JZid0014zp2256 2406 2406 2406 2406 2406 2406 2256"), - _any_write_and_read_command_call("C0ZAid0015"), - ] - ) - - async def test_pierce_foil_portrait_tight(self): - self.plate.rotate(z=90) - aspiration_channels = [1, 2, 3, 4, 5, 6] - hold_down_channels = [0, 7] - self.star._write_and_read_command.side_effect = [ - "C0JXid0183er00/00", - "C0RYid0184er00/00ry+1953 +1735 +1582 +1429 +1275 +1122 +0969 +0755", - "C0JYid0185er00/00", - "C0RZid0186er00/00rz+2476 +2476 +2476 +2476 +2476 +2476 +2476 +2476", - "C0JZid0187er00/00", - "C0RYid0188er00/00ry+1953 +1577 +1487 +1397 +1307 +1217 +1127 +0755", - "C0JYid0189er00/00", - "C0KZid0190er00/00", - "C0KZid0191er00/00", - "C0RZid0192er00/00rz+2256 +2083 +2083 +2083 +2083 +2083 +2083 +2256", - "C0RZid0193er00/00rz+2256 +2083 +2083 +2083 +2083 +2083 +2083 +2256", - "C0JZid0194er00/00", - "C0ZAid0195er00/00", - ] - await self.star.pierce_foil( - wells=[self.well], - piercing_channels=aspiration_channels, - hold_down_channels=hold_down_channels, - move_inwards=4, - one_by_one=False, - spread="tight", - ) - self.star._write_and_read_command.assert_has_calls( - [ - _any_write_and_read_command_call("C0JXid0003xs02634"), - _any_write_and_read_command_call("C0RYid0004"), - _any_write_and_read_command_call("C0JYid0005yp1953 1577 1487 1397 1307 1217 1127 0755"), - _any_write_and_read_command_call("C0RZid0006"), - _any_write_and_read_command_call("C0JZid0007zp2476 2083 2083 2083 2083 2083 2083 2476"), - _any_write_and_read_command_call("C0RYid0008"), - _any_write_and_read_command_call("C0JYid0009yp1953 1577 1487 1397 1307 1217 1127 0755"), - _any_write_and_read_command_call("C0KZid0010pn08zj2256"), - _any_write_and_read_command_call("C0KZid0011pn01zj2256"), - _any_write_and_read_command_call("C0RZid0012"), - _any_write_and_read_command_call("C0RZid0013"), - _any_write_and_read_command_call("C0JZid0014zp2256 2406 2406 2406 2406 2406 2406 2256"), - _any_write_and_read_command_call("C0ZAid0015"), - ] - ) + await self.lh.move_plate(self.plate, self.plt_car[1], pickup_distance_from_top=13-3.33, + use_arm="core") + self._assert_command_sent_once("C0ZTid0020xs07975xd0ya1240yb1065pa07pb08tp2350tz2250th2450tt14", + "xs#####xd#ya####yb####pa##pb##tp####tz####th####tt##") + self._assert_command_sent_once("C0ZPid0021xs03479xd0yj1142yv0050zj1876zy0500yo0885yg0825yw15" + "th2450te2450", + "xs#####xd#yj####yv####zj####zy####yo####yg####yw##th####te####") + self._assert_command_sent_once("C0ZRid0022xs03479xd0yj2102zj1876zi000zy0500yo0885th2450te2450", + "xs#####xd#yj####zj####zi###zy####yo####th####te####") + self._assert_command_sent_once("C0ZSid0023xs07975xd0ya1240yb1065tp2150tz2050th2450te2450", + "xs#####xd#ya####yb####tp####tz####th####te####") + + async def test_iswap_pick_up_resource_grip_direction_changes_plate_width(self): + size_x = 100 + size_y = 200 + plate = Plate("dummy", size_x=size_x, size_y=size_y, size_z=100, ordered_items={}) + plate.location = Coordinate.zero() + + with unittest.mock.patch.object(self.lh.backend, "iswap_get_plate") as mocked_iswap_get_plate: + await cast(STAR, self.lh.backend).iswap_pick_up_resource(plate, GripDirection.FRONT, 1) + assert mocked_iswap_get_plate.call_args.kwargs["plate_width"] == size_x * 10 - 33 + + with unittest.mock.patch.object(self.lh.backend, "iswap_get_plate") as mocked_iswap_get_plate: + await cast(STAR, self.lh.backend).iswap_pick_up_resource(plate, GripDirection.LEFT, 1) + assert mocked_iswap_get_plate.call_args.kwargs["plate_width"] == size_y * 10 - 33 + + async def test_iswap_release_picked_up_resource_grip_direction_changes_plate_width(self): + size_x = 100 + size_y = 200 + plate = Plate("dummy", size_x=size_x, size_y=size_y, size_z=100, ordered_items={}) + plate.location = Coordinate.zero() + + with unittest.mock.patch.object(self.lh.backend, "iswap_put_plate") as mocked_iswap_get_plate: + await cast(STAR, self.lh.backend).iswap_release_picked_up_resource( + location=Coordinate.zero(), + resource=plate, + rotation=0, + offset=Coordinate.zero(), + grip_direction=GripDirection.FRONT, + pickup_distance_from_top=1, + ) + assert mocked_iswap_get_plate.call_args.kwargs["open_gripper_position"] == size_x * 10 + 30 + + with unittest.mock.patch.object(self.lh.backend, "iswap_put_plate") as mocked_iswap_get_plate: + await cast(STAR, self.lh.backend).iswap_release_picked_up_resource( + location=Coordinate.zero(), + resource=plate, + rotation=0, + offset=Coordinate.zero(), + grip_direction=GripDirection.LEFT, + pickup_distance_from_top=1, + ) + assert mocked_iswap_get_plate.call_args.kwargs["open_gripper_position"] == size_y * 10 + 30 diff --git a/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py b/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py index 6a115d268c..ed11a92acf 100644 --- a/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py +++ b/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py @@ -108,3 +108,6 @@ def serialize(self) -> Dict[str, Any]: "dispense_stop_flow_rate": self.dispense_stop_flow_rate, "dispense_stop_back_volume": self.dispense_stop_back_volume, } + + def copy(self) -> "HamiltonLiquidClass": + return HamiltonLiquidClass(**self.serialize()) From 598f82d6e52d9b77df17fff7b80756238b3d158c Mon Sep 17 00:00:00 2001 From: Rick Wierenga Date: Thu, 26 Sep 2024 13:35:44 -0700 Subject: [PATCH 10/18] fix some tests --- .../liquid_handling/backends/hamilton/STAR.py | 210 +-- .../backends/hamilton/STAR_tests.py | 15 +- pylabrobot/liquid_handling/liquid_handler.py | 1212 ++++++----------- .../liquid_handling/parameter_sets/star.py | 52 +- 4 files changed, 592 insertions(+), 897 deletions(-) diff --git a/pylabrobot/liquid_handling/backends/hamilton/STAR.py b/pylabrobot/liquid_handling/backends/hamilton/STAR.py index 0369c5729c..f3083e1e71 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/STAR.py +++ b/pylabrobot/liquid_handling/backends/hamilton/STAR.py @@ -1456,11 +1456,11 @@ async def aspirate( detection_height_difference_for_dual_lld: Optional[List[float]] = None, swap_speed: Optional[List[float]] = None, settling_time: Optional[List[float]] = None, - homogenization_volume: Optional[List[float]] = None, - homogenization_cycles: Optional[List[int]] = None, - homogenization_position_from_liquid_surface: Optional[List[float]] = None, - homogenization_speed: Optional[List[float]] = None, - homogenization_surface_following_distance: Optional[List[float]] = None, + mix_volume: Optional[List[float]] = None, + mix_cycles: Optional[List[int]] = None, + mix_position_from_liquid_surface: Optional[List[float]] = None, + mix_speed: Optional[List[float]] = None, + mix_surface_following_distance: Optional[List[float]] = None, limit_curve_index: Optional[List[int]] = None, use_2nd_section_aspiration: Optional[List[bool]] = None, @@ -1514,14 +1514,14 @@ async def aspirate( detection_height_difference_for_dual_lld: Difference between the gamma and DP LLD heights if the LLD mode is DUAL. swap_speed: Swap speed (on leaving liquid) [1mm/s]. Must be between 3 and 1600. Default 100. - settling_time: The time to wait after homogenization. - homogenization_volume: The volume to aspirate for homogenization. - homogenization_cycles: The number of cycles to perform for homogenization. - homogenization_position_from_liquid_surface: The height to aspirate from for homogenization + settling_time: The time to wait after mix. + mix_volume: The volume to aspirate for mix. + mix_cycles: The number of cycles to perform for mix. + mix_position_from_liquid_surface: The height to aspirate from for mix (LLD or absolute terms). - homogenization_speed: The speed to aspirate at for homogenization. - homogenization_surface_following_distance: The distance to follow the liquid surface for - homogenization. + mix_speed: The speed to aspirate at for mix. + mix_surface_following_distance: The distance to follow the liquid surface for + mix. limit_curve_index: The index of the limit curve to use. use_2nd_section_aspiration: Whether to use the second section of aspiration. @@ -1568,7 +1568,7 @@ async def aspirate( ] else: lld_search_height = [(wb + sh) for wb, sh in zip(well_bottoms, lld_search_height)] - clot_detection_height = _fill_in_defaults(clot_detection_height, default=[0]) + clot_detection_height = _fill_in_defaults(clot_detection_height, default=[0]*n) pull_out_distance_transport_air = _fill_in_defaults(pull_out_distance_transport_air, [10]*n) second_section_height = _fill_in_defaults(second_section_height, [3.2]*n) second_section_ratio = _fill_in_defaults(second_section_ratio, [618.0]*n) @@ -1590,13 +1590,13 @@ async def aspirate( _fill_in_defaults(detection_height_difference_for_dual_lld, [0]*n) swap_speed = _fill_in_defaults(swap_speed, default=[100]*n) settling_time = _fill_in_defaults(settling_time, default=[0]*n) - homogenization_volume = _fill_in_defaults(homogenization_volume, [0]*n) - homogenization_cycles = _fill_in_defaults(homogenization_cycles, [0]*n) - homogenization_position_from_liquid_surface = \ - _fill_in_defaults(homogenization_position_from_liquid_surface, [0]*n) - homogenization_speed = _fill_in_defaults(homogenization_speed, [50]*n) - homogenization_surface_following_distance = \ - _fill_in_defaults(homogenization_surface_following_distance, [0]*n) + mix_volume = _fill_in_defaults(mix_volume, [0]*n) + mix_cycles = _fill_in_defaults(mix_cycles, [0]*n) + mix_position_from_liquid_surface = \ + _fill_in_defaults(mix_position_from_liquid_surface, [0]*n) + mix_speed = _fill_in_defaults(mix_speed, [50]*n) + mix_surface_following_distance = \ + _fill_in_defaults(mix_surface_following_distance, [0]*n) limit_curve_index = _fill_in_defaults(limit_curve_index, [0]*n) use_2nd_section_aspiration = _fill_in_defaults(use_2nd_section_aspiration, [False]*n) @@ -1643,13 +1643,13 @@ async def aspirate( for dh in detection_height_difference_for_dual_lld], swap_speed=[round(ss * 10) for ss in swap_speed], settling_time=[round(st * 10) for st in settling_time], - homogenization_volume=[round(hv * 10) for hv in homogenization_volume], - homogenization_cycles=homogenization_cycles, - homogenization_position_from_liquid_surface=[round(hp * 10) - for hp in homogenization_position_from_liquid_surface], - homogenization_speed=[round(hs * 10) for hs in homogenization_speed], - homogenization_surface_following_distance=[round(hsd * 10) - for hsd in homogenization_surface_following_distance], + mix_volume=[round(hv * 10) for hv in mix_volume], + mix_cycles=mix_cycles, + mix_position_from_liquid_surface=[round(hp * 10) + for hp in mix_position_from_liquid_surface], + mix_speed=[round(hs * 10) for hs in mix_speed], + mix_surface_following_distance=[round(hsd * 10) + for hsd in mix_surface_following_distance], limit_curve_index=limit_curve_index, use_2nd_section_aspiration=use_2nd_section_aspiration, @@ -1745,12 +1745,12 @@ async def dispense( dp_lld_sensitivity: The dp LLD sensitivity. (1 = high, 4 = low) swap_speed: Swap speed (on leaving liquid) [0.1mm/s]. Must be between 3 and 1600. Default 100. settling_time: The settling time. - mix_volume: The volume to use for homogenization. - mix_cycles: The number of homogenization cycles. + mix_volume: The volume to use for mix. + mix_cycles: The number of mix cycles. mix_position_from_liquid_surface: The height to move above the liquid surface for - homogenization. - mix_speed: The homogenization speed. - mix_surface_following_distance: The distance to follow the liquid surface for homogenization. + mix. + mix_speed: The mix speed. + mix_surface_following_distance: The distance to follow the liquid surface for mix. limit_curve_index: The limit curve to use for the dispense. minimum_traverse_height_at_beginning_of_a_command: The minimum height to move to before starting a dispense. @@ -1958,11 +1958,11 @@ async def aspirate96( gamma_lld_sensitivity: int = 1, swap_speed: float = 2.0, settling_time: float = 1.0, - homogenization_volume: float = 0, - homogenization_cycles: int = 0, - homogenization_position_from_liquid_surface: float = 0, - surface_following_distance_during_homogenization: float = 0, - speed_of_homogenization: float = 120.0, + mix_volume: float = 0, + mix_cycles: int = 0, + mix_position_from_liquid_surface: float = 0, + surface_following_distance_during_mix: float = 0, + speed_of_mix: float = 120.0, limit_curve_index: int = 0, ): """ Aspirate using the Core96 head. @@ -1997,13 +1997,13 @@ async def aspirate96( gamma_lld_sensitivity: The sensitivity of the gamma liquid level detection. swap_speed: Swap speed (on leaving liquid) [1mm/s]. Must be between 0.3 and 160. Default 2. settling_time: The time to wait after aspirating. - homogenization_volume: The volume of liquid to aspirate for homogenization. - homogenization_cycles: The number of cycles to perform for homogenization. - homogenization_position_from_liquid_surface: The position of the homogenization from the + mix_volume: The volume of liquid to aspirate for mix. + mix_cycles: The number of cycles to perform for mix. + mix_position_from_liquid_surface: The position of the mix from the liquid surface. - surface_following_distance_during_homogenization: The distance to follow the liquid surface - during homogenization. - speed_of_homogenization: The speed of homogenization. + surface_following_distance_during_mix: The distance to follow the liquid surface + during mix. + speed_of_mix: The speed of mix. limit_curve_index: The index of the limit curve to use. """ @@ -2012,7 +2012,7 @@ async def aspirate96( assert self.core96_head_installed, "96 head must be installed" - if jet is not None or blow_out is not None: + if jet or blow_out: raise NotImplementedError("jet and blow out are not implemented for aspirate96 yet") # get the first well and tip as representatives @@ -2030,7 +2030,7 @@ async def aspirate96( flow_rate = aspiration.flow_rate or 250 swap_speed = swap_speed or 100 settling_time = settling_time or 0.5 - speed_of_homogenization = speed_of_homogenization or 10.0 + speed_of_mix = speed_of_mix or 10.0 channel_pattern = [True]*12*8 @@ -2076,13 +2076,13 @@ async def aspirate96( gamma_lld_sensitivity=gamma_lld_sensitivity, swap_speed=round(swap_speed*10), settling_time=round(settling_time * 10), - homogenization_volume=round(homogenization_volume * 10), - homogenization_cycles=homogenization_cycles, - homogenization_position_from_liquid_surface= - round(homogenization_position_from_liquid_surface * 10), - surface_following_distance_during_homogenization= - round(surface_following_distance_during_homogenization * 10), - speed_of_homogenization=round(speed_of_homogenization * 10), + mix_volume=round(mix_volume * 10), + mix_cycles=mix_cycles, + mix_position_from_liquid_surface= + round(mix_position_from_liquid_surface * 10), + surface_following_distance_during_mix= + round(surface_following_distance_during_mix * 10), + speed_of_mix=round(speed_of_mix * 10), channel_pattern=channel_pattern, limit_curve_index=limit_curve_index, tadm_algorithm=False, @@ -2164,7 +2164,7 @@ async def dispense96( if hlc is not None: raise NotImplementedError("Hamilton liquid classes are deprecated.") - if jet is not None or blow_out is not None: + if jet or blow_out: raise NotImplementedError("jet and blow out are not implemented for aspirate96 yet") assert self.core96_head_installed, "96 head must be installed" @@ -3767,11 +3767,11 @@ async def aspirate_pip( detection_height_difference_for_dual_lld: List[int] = [0], swap_speed: List[int] = [100], settling_time: List[int] = [5], - homogenization_volume: List[int] = [0], - homogenization_cycles: List[int] = [0], - homogenization_position_from_liquid_surface: List[int] = [250], - homogenization_speed: List[int] = [500], - homogenization_surface_following_distance: List[int] = [0], + mix_volume: List[int] = [0], + mix_cycles: List[int] = [0], + mix_position_from_liquid_surface: List[int] = [250], + mix_speed: List[int] = [500], + mix_surface_following_distance: List[int] = [0], limit_curve_index: List[int] = [0], tadm_algorithm: bool = False, recording_mode: int = 0, @@ -3845,14 +3845,14 @@ async def aspirate_pip( swap_speed: Swap speed (on leaving liquid) [0.1mm/s]. Must be between 3 and 1600. Default 100. settling_time: Settling time [0.1s]. Must be between 0 and 99. Default 5. - homogenization_volume: Homogenization volume [0.1ul]. Must be between 0 and 12500. Default 0 - homogenization_cycles: Number of homogenization cycles. Must be between 0 and 99. Default 0. - homogenization_position_from_liquid_surface: Homogenization position in Z- direction from + mix_volume: mix volume [0.1ul]. Must be between 0 and 12500. Default 0 + mix_cycles: Number of mix cycles. Must be between 0 and 99. Default 0. + mix_position_from_liquid_surface: mix position in Z- direction from liquid surface (LLD or absolute terms) [0.1mm]. Must be between 0 and 900. Default 250. - homogenization_speed: Speed of homogenization [0.1ul/s]. Must be between 4 and 5000. + mix_speed: Speed of mix [0.1ul/s]. Must be between 4 and 5000. Default 500. - homogenization_surface_following_distance: Surface following distance during - homogenization [0.1mm]. Must be between 0 and 3600. Default 0. + mix_surface_following_distance: Surface following distance during + mix [0.1mm]. Must be between 0 and 3600. Default 0. limit_curve_index: limit curve index. Must be between 0 and 999. Default 0. tadm_algorithm: TADM algorithm. Default False. recording_mode: Recording mode 0 : no 1 : TADM errors only 2 : all TADM measurement. Must @@ -3919,16 +3919,16 @@ async def aspirate_pip( "detection_height_difference_for_dual_lld must be between 0 and 99" assert all(3 <= x <= 1600 for x in swap_speed), "swap_speed must be between 3 and 1600" assert all(0 <= x <= 99 for x in settling_time), "settling_time must be between 0 and 99" - assert all(0 <= x <= 12500 for x in homogenization_volume), \ - "homogenization_volume must be between 0 and 12500" - assert all(0 <= x <= 99 for x in homogenization_cycles), \ - "homogenization_cycles must be between 0 and 99" - assert all(0 <= x <= 900 for x in homogenization_position_from_liquid_surface), \ - "homogenization_position_from_liquid_surface must be between 0 and 900" - assert all(4 <= x <= 5000 for x in homogenization_speed), \ - "homogenization_speed must be between 4 and 5000" - assert all(0 <= x <= 3600 for x in homogenization_surface_following_distance), \ - "homogenization_surface_following_distance must be between 0 and 3600" + assert all(0 <= x <= 12500 for x in mix_volume), \ + "mix_volume must be between 0 and 12500" + assert all(0 <= x <= 99 for x in mix_cycles), \ + "mix_cycles must be between 0 and 99" + assert all(0 <= x <= 900 for x in mix_position_from_liquid_surface), \ + "mix_position_from_liquid_surface must be between 0 and 900" + assert all(4 <= x <= 5000 for x in mix_speed), \ + "mix_speed must be between 4 and 5000" + assert all(0 <= x <= 3600 for x in mix_surface_following_distance), \ + "mix_surface_following_distance must be between 0 and 3600" assert all(0 <= x <= 999 for x in limit_curve_index), \ "limit_curve_index must be between 0 and 999" assert 0 <= recording_mode <= 2, "recording_mode must be between 0 and 2" @@ -3979,11 +3979,11 @@ async def aspirate_pip( ld=[f"{ld:02}" for ld in detection_height_difference_for_dual_lld], de=[f"{de:04}" for de in swap_speed], wt=[f"{wt:02}" for wt in settling_time], - mv=[f"{mv:05}" for mv in homogenization_volume], - mc=[f"{mc:02}" for mc in homogenization_cycles], - mp=[f"{mp:03}" for mp in homogenization_position_from_liquid_surface], - ms=[f"{ms:04}" for ms in homogenization_speed], - mh=[f"{mh:04}" for mh in homogenization_surface_following_distance], + mv=[f"{mv:05}" for mv in mix_volume], + mc=[f"{mc:02}" for mc in mix_cycles], + mp=[f"{mp:03}" for mp in mix_position_from_liquid_surface], + ms=[f"{ms:04}" for ms in mix_speed], + mh=[f"{mh:04}" for mh in mix_surface_following_distance], gi=[f"{gi:03}" for gi in limit_curve_index], gj=tadm_algorithm, gk=recording_mode, @@ -4935,11 +4935,11 @@ async def aspirate_core_96( gamma_lld_sensitivity: int = 1, swap_speed: int = 100, settling_time: int = 5, - homogenization_volume: int = 0, - homogenization_cycles: int = 0, - homogenization_position_from_liquid_surface: int = 250, - surface_following_distance_during_homogenization: int = 0, - speed_of_homogenization: int = 1000, + mix_volume: int = 0, + mix_cycles: int = 0, + mix_position_from_liquid_surface: int = 250, + surface_following_distance_during_mix: int = 0, + speed_of_mix: int = 1000, channel_pattern: List[bool] = [True] * 96, limit_curve_index: int = 0, tadm_algorithm: bool = False, @@ -4987,13 +4987,13 @@ async def aspirate_core_96( Default 1. swap_speed: Swap speed (on leaving liquid) [0.1mm/s]. Must be between 3 and 1000. Default 100. settling_time: Settling time [0.1s]. Must be between 0 and 99. Default 5. - homogenization_volume: Homogenization volume [0.1ul]. Must be between 0 and 11500. Default 0. - homogenization_cycles: Number of homogenization cycles. Must be between 0 and 99. Default 0. - homogenization_position_from_liquid_surface: Homogenization position in Z- direction from + mix_volume: mix volume [0.1ul]. Must be between 0 and 11500. Default 0. + mix_cycles: Number of mix cycles. Must be between 0 and 99. Default 0. + mix_position_from_liquid_surface: mix position in Z- direction from liquid surface (LLD or absolute terms) [0.1mm]. Must be between 0 and 990. Default 250. - surface_following_distance_during_homogenization: surface following distance during - homogenization [0.1mm]. Must be between 0 and 990. Default 0. - speed_of_homogenization: Speed of homogenization [0.1ul/s]. Must be between 3 and 5000. + surface_following_distance_during_mix: surface following distance during + mix [0.1mm]. Must be between 0 and 990. Default 0. + speed_of_mix: Speed of mix [0.1ul/s]. Must be between 3 and 5000. Default 1000. todo: TODO: 24 hex chars. Must be between 4 and 5000. limit_curve_index: limit curve index. Must be between 0 and 999. Default 0. @@ -5033,14 +5033,14 @@ async def aspirate_core_96( assert 1 <= gamma_lld_sensitivity <= 4, "gamma_lld_sensitivity must be between 1 and 4" assert 3 <= swap_speed <= 1000, "swap_speed must be between 3 and 1000" assert 0 <= settling_time <= 99, "settling_time must be between 0 and 99" - assert 0 <= homogenization_volume <= 11500, "homogenization_volume must be between 0 and 11500" - assert 0 <= homogenization_cycles <= 99, "homogenization_cycles must be between 0 and 99" - assert 0 <= homogenization_position_from_liquid_surface <= 990, \ - "homogenization_position_from_liquid_surface must be between 0 and 990" - assert 0 <= surface_following_distance_during_homogenization <= 990, \ - "surface_following_distance_during_homogenization must be between 0 and 990" - assert 3 <= speed_of_homogenization <= 5000, \ - "speed_of_homogenization must be between 3 and 5000" + assert 0 <= mix_volume <= 11500, "mix_volume must be between 0 and 11500" + assert 0 <= mix_cycles <= 99, "mix_cycles must be between 0 and 99" + assert 0 <= mix_position_from_liquid_surface <= 990, \ + "mix_position_from_liquid_surface must be between 0 and 990" + assert 0 <= surface_following_distance_during_mix <= 990, \ + "surface_following_distance_during_mix must be between 0 and 990" + assert 3 <= speed_of_mix <= 5000, \ + "speed_of_mix must be between 3 and 5000" assert 0 <= limit_curve_index <= 999, "limit_curve_index must be between 0 and 999" assert 0 <= recording_mode <= 2, "recording_mode must be between 0 and 2" @@ -5077,11 +5077,11 @@ async def aspirate_core_96( cs=gamma_lld_sensitivity, bs=f"{swap_speed:04}", wh=f"{settling_time:02}", - hv=f"{homogenization_volume:05}", - hc=f"{homogenization_cycles:02}", - hp=f"{homogenization_position_from_liquid_surface:03}", - mj=f"{surface_following_distance_during_homogenization:03}", - hs=f"{speed_of_homogenization:04}", + hv=f"{mix_volume:05}", + hc=f"{mix_cycles:02}", + hp=f"{mix_position_from_liquid_surface:03}", + mj=f"{surface_following_distance_during_mix:03}", + hs=f"{speed_of_mix:04}", cw=channel_pattern_hex, cr=f"{limit_curve_index:03}", cj=tadm_algorithm, @@ -5172,9 +5172,9 @@ async def dispense_core_96( Must be between 0 and 45. Default 1. swap_speed: Swap speed (on leaving liquid) [0.1mm/s]. Must be between 3 and 1000. Default 100. settling_time: Settling time [0.1s]. Must be between 0 and 99. Default 5. - mixing_volume: Homogenization volume [0.1ul]. Must be between 0 and 11500. Default 0. + mixing_volume: mix volume [0.1ul]. Must be between 0 and 11500. Default 0. mixing_cycles: Number of mixing cycles. Must be between 0 and 99. Default 0. - mixing_position_from_liquid_surface: Homogenization position in Z- direction from liquid + mixing_position_from_liquid_surface: mix position in Z- direction from liquid surface (LLD or absolute terms) [0.1mm]. Must be between 0 and 990. Default 250. surface_following_distance_during_mixing: surface following distance during mixing [0.1mm]. Must be between 0 and 990. Default 0. diff --git a/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py b/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py index 49d38a604c..dda8ffe98a 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py +++ b/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py @@ -514,7 +514,9 @@ async def test_single_channel_dispense(self): assert self.plate.lid is not None self.plate.lid.unassign() with no_volume_tracking(): - await self.lh.dispense(self.plate["A1"], vols=[100], jet=[True], blow_out=[True]) + corrected_vol = self.hlc.compute_corrected_volume(100) + await self.lh.dispense(self.plate["A1"], vols=[corrected_vol], + jet=[True], blow_out=[True]) self._assert_command_sent_once( "C0DSid0002dm1 1&tm1 0&xp02983 00000&yp1457 0000&zx1866 1866&lp2000 2000&zl1866 1866&" "po0100 0100&ip0000 0000&it0 0&fp0000 0000&zu0032 0032&zr06180 06180&th2450te2450" @@ -529,7 +531,8 @@ async def test_multi_channel_dispense(self): assert self.plate.lid is not None self.plate.lid.unassign() with no_volume_tracking(): - await self.lh.dispense(self.plate["A1:B1"], vols=[100]*2, jet=[True]*2, blow_out=[True]*2) + corrected_vol = self.hlc.compute_corrected_volume(100) + await self.lh.dispense(self.plate["A1:B1"], vols=[corrected_vol]*2, jet=[True]*2, blow_out=[True]*2) self._assert_command_sent_once( "C0DSid0002dm1 1 1&tm1 1 0&xp02983 02983 00000&yp1457 1367 0000&zx1866 1866 1866&lp2000 2000 " @@ -577,7 +580,8 @@ async def test_core_96_aspirate(self): # TODO: Hamilton liquid classes assert self.plate.lid is not None self.plate.lid.unassign() - await self.lh.aspirate96(self.plate, volume=100, blow_out=True) + corrected_volume = self.hlc.compute_corrected_volume(100) # need different liquid class + await self.lh.aspirate96(self.plate, volume=corrected_volume) # volume used to be 01072, but that was generated using a non-core liquid class. self._assert_command_sent_once( @@ -592,10 +596,11 @@ async def test_core_96_dispense(self): await self.lh.pick_up_tips96(self.tip_rack2) # pick up high volume tips if self.plate.lid is not None: self.plate.lid.unassign() - await self.lh.aspirate96(self.plate, 100, blow_out=True) # aspirate first + corrected_volume = self.hlc.compute_corrected_volume(100) # need different liquid class + await self.lh.aspirate96(self.plate, corrected_volume) # aspirate first with no_volume_tracking(): - await self.lh.dispense96(self.plate, 100, blow_out=True) + await self.lh.dispense96(self.plate, corrected_volume) # volume used to be 01072, but that was generated using a non-core liquid class. self._assert_command_sent_once( diff --git a/pylabrobot/liquid_handling/liquid_handler.py b/pylabrobot/liquid_handling/liquid_handler.py index 0afc7a4b32..0fd8b3d94b 100644 --- a/pylabrobot/liquid_handling/liquid_handler.py +++ b/pylabrobot/liquid_handling/liquid_handler.py @@ -1,4 +1,4 @@ -"""Defines LiquidHandler class, the coordinator for liquid handling operations.""" +""" Defines LiquidHandler class, the coordinator for liquid handling operations. """ from __future__ import annotations @@ -8,101 +8,77 @@ import json import logging import threading +from typing import Any, Callable, Dict, Union, Optional, List, Sequence, Set, Tuple, Protocol, cast import warnings -from typing import ( - Any, - Callable, - Dict, - List, - Literal, - Optional, - Protocol, - Sequence, - Set, - Tuple, - Union, - cast, -) -from pylabrobot.liquid_handling.errors import ChannelizedError -from pylabrobot.liquid_handling.strictness import ( - Strictness, - get_strictness, -) -from pylabrobot.liquid_handling.utils import ( - get_tight_single_resource_liquid_op_offsets, - get_wide_single_resource_liquid_op_offsets, -) from pylabrobot.machines.machine import Machine, need_setup_finished +from pylabrobot.liquid_handling.strictness import Strictness, get_strictness +from pylabrobot.liquid_handling.errors import ChannelizedError +from pylabrobot.resources.errors import HasTipError from pylabrobot.plate_reading import PlateReader +from pylabrobot.resources.errors import CrossContaminationError from pylabrobot.resources import ( Container, - Coordinate, Deck, + Resource, + ResourceStack, + Coordinate, + CarrierSite, + PlateCarrierSite, Lid, + MFXModule, Plate, PlateAdapter, - PlateHolder, - Resource, - ResourceHolder, - ResourceStack, Tip, TipRack, TipSpot, - TipTracker, Trash, - VolumeTracker, Well, - does_cross_contamination_tracking, + TipTracker, + VolumeTracker, does_tip_tracking, does_volume_tracking, + does_cross_contamination_tracking ) -from pylabrobot.resources.errors import CrossContaminationError, HasTipError from pylabrobot.resources.liquid import Liquid -from pylabrobot.resources.rotation import Rotation from pylabrobot.tilting.tilter import Tilter from .backends import LiquidHandlerBackend from .standard import ( - Drop, - DropTipRack, - GripDirection, - MultiHeadAspirationContainer, - MultiHeadAspirationPlate, - MultiHeadDispenseContainer, - MultiHeadDispensePlate, Pickup, PickupTipRack, - ResourceDrop, - ResourceMove, - ResourcePickup, - SingleChannelAspiration, - SingleChannelDispense, + Drop, + DropTipRack, + Aspiration, + AspirationPlate, + AspirationContainer, + Dispense, + DispensePlate, + DispenseContainer, + Move, + GripDirection ) -logger = logging.getLogger("pylabrobot") +logger = logging.getLogger("pylabrobot") def check_contaminated(liquid_history_tip, liquid_history_well): """Helper function used to check if adding a liquid to the container - would result in cross contamination""" + would result in cross contamination""" return not liquid_history_tip.issubset(liquid_history_well) and len(liquid_history_tip) > 0 - def check_updatable(src_tracker: VolumeTracker, dest_tracker: VolumeTracker): """Helper function used to check if it is possible to update the - liquid_history of src based on contents of dst""" - return ( - not src_tracker.is_cross_contamination_tracking_disabled - and not dest_tracker.is_cross_contamination_tracking_disabled - ) + liquid_history of src based on contents of dst""" + return not src_tracker.is_cross_contamination_tracking_disabled and \ + not dest_tracker.is_cross_contamination_tracking_disabled class BlowOutVolumeError(Exception): - pass + ... -class LiquidHandler(Resource, Machine): +class LiquidHandler(Machine): """ Front end for liquid handlers. @@ -124,24 +100,23 @@ class LiquidHandler(Resource, Machine): } def __init__(self, backend: LiquidHandlerBackend, deck: Deck): - """Initialize a LiquidHandler. + """ Initialize a LiquidHandler. Args: backend: Backend to use. deck: Deck to use. """ - Resource.__init__( - self, + super().__init__( name=f"lh_{deck.name}", size_x=deck._size_x, size_y=deck._size_y, size_z=deck._size_z, + backend=backend, category="liquid_handler", ) - Machine.__init__(self, backend=backend) - self.backend: LiquidHandlerBackend = backend # fix type + self.backend: LiquidHandlerBackend = backend # fix type self._callbacks: Dict[str, OperationCallback] = {} self.deck = deck @@ -159,16 +134,13 @@ def __init__(self, backend: LiquidHandlerBackend, deck: Deck): self.location = Coordinate.zero() super().assign_child_resource(deck, location=deck.location or Coordinate.zero()) - self._resource_pickup: Optional[ResourcePickup] = None - async def setup(self, **backend_kwargs): - """Prepare the robot for use.""" + """ Prepare the robot for use. """ if self.setup_finished: raise RuntimeError("The setup has already finished. See `LiquidHandler.stop`.") self.backend.set_deck(self.deck) - self.backend.set_heads(head=self.head, head96=self.head96) await super().setup(**backend_kwargs) self.head = {c: TipTracker(thing=f"Channel {c}") for c in range(self.backend.num_channels)} @@ -178,25 +150,23 @@ async def setup(self, **backend_kwargs): for resource in self.deck.children: self._send_assigned_resource_to_backend(resource) - self._resource_pickup = None - def serialize_state(self) -> Dict[str, Any]: - """Serialize the state of this liquid handler. Use :meth:`~Resource.serialize_all_states` to - serialize the state of the liquid handler and all children (the deck).""" + """ Serialize the state of this liquid handler. Use :meth:`~Resource.serialize_all_states` to + serialize the state of the liquid handler and all children (the deck). """ head_state = {channel: tracker.serialize() for channel, tracker in self.head.items()} return {"head_state": head_state} def load_state(self, state: Dict[str, Any]): - """Load the liquid handler state from a file. Use :meth:`~Resource.load_all_state` to load the - state of the liquid handler and all children (the deck).""" + """ Load the liquid handler state from a file. Use :meth:`~Resource.load_all_state` to load the + state of the liquid handler and all children (the deck). """ head_state = state["head_state"] for channel, tracker_state in head_state.items(): self.head[channel].load_state(tracker_state) def update_head_state(self, state: Dict[int, Optional[Tip]]): - """Update the state of the liquid handler head. + """ Update the state of the liquid handler head. All keys in `state` must be valid channels. Channels for which no key is specified will keep their current state. @@ -213,12 +183,12 @@ def update_head_state(self, state: Dict[int, Optional[Tip]]): if self.head[channel].has_tip: self.head[channel].remove_tip() else: - if self.head[channel].has_tip: # remove tip so we can update the head. + if self.head[channel].has_tip: # remove tip so we can update the head. self.head[channel].remove_tip() self.head[channel].add_tip(tip) def clear_head_state(self): - """Clear the state of the liquid handler head.""" + """ Clear the state of the liquid handler head. """ self.update_head_state({c: None for c in self.head.keys()}) @@ -234,22 +204,22 @@ def callback(*args, **kwargs): t.join() def _send_assigned_resource_to_backend(self, resource: Resource): - """This method is called when a resource is assigned to the deck, and passes this information - to the backend.""" + """ This method is called when a resource is assigned to the deck, and passes this information + to the backend. """ self._run_async_in_thread(self.backend.assigned_resource_callback, resource) def _send_unassigned_resource_to_backend(self, resource: Resource): - """This method is called when a resource is unassigned from the deck, and passes this - information to the backend.""" + """ This method is called when a resource is unassigned from the deck, and passes this + information to the backend. """ self._run_async_in_thread(self.backend.unassigned_resource_callback, resource.name) def summary(self): - """Prints a string summary of the deck layout.""" + """ Prints a string summary of the deck layout. """ print(self.deck.summary()) def _assert_positions_unique(self, positions: List[str]): - """Returns whether all items in `positions` are unique where they are not `None`. + """ Returns whether all items in `positions` are unique where they are not `None`. Args: positions: List of positions. @@ -260,7 +230,7 @@ def _assert_positions_unique(self, positions: List[str]): raise ValueError("Positions must be unique.") def _assert_resources_exist(self, resources: Sequence[Resource]): - """Checks that each resource in `resources` is assigned to the deck. + """ Checks that each resource in `resources` is assigned to the deck. Args: resources: List of resources. @@ -281,18 +251,13 @@ def _check_args( self, method: Callable, backend_kwargs: Dict[str, Any], - default: Set[str], - strictness: Strictness, + default: Set[str] ) -> Set[str]: - """Checks that the arguments to `method` are valid. + """ Checks that the arguments to `method` are valid. Args: method: Method to check. backend_kwargs: Keyword arguments to `method`. - default: Default arguments to `method`. (Of the abstract backend) - strictness: Strictness level. If `Strictness.STRICT`, raises an error if there are extra - arguments. If `Strictness.WARN`, raises a warning. If `Strictness.IGNORE`, logs a debug - message. Raises: TypeError: If the arguments are invalid. @@ -305,22 +270,14 @@ def _check_args( sig = inspect.signature(method) args = {arg: param for arg, param in sig.parameters.items() if arg not in default_args} - vars_keyword = { - arg - for arg, param in sig.parameters.items() # **kwargs - if param.kind == inspect.Parameter.VAR_KEYWORD - } - args = { - arg: param - for arg, param in args.items() # keep only *args and **kwargs - if param.kind - not in { - inspect.Parameter.VAR_POSITIONAL, - inspect.Parameter.VAR_KEYWORD, - } - } + vars_keyword = {arg for arg, param in sig.parameters.items() # **kwargs + if param.kind == inspect.Parameter.VAR_KEYWORD} + args = {arg: param for arg, param in args.items() # keep only *args and **kwargs + if param.kind not in {inspect.Parameter.VAR_POSITIONAL, inspect.Parameter.VAR_KEYWORD}} non_default = {arg for arg, param in args.items() if param.default == inspect.Parameter.empty} + strictness = get_strictness() + backend_kws = set(backend_kwargs.keys()) missing = non_default - backend_kws @@ -328,7 +285,7 @@ def _check_args( raise TypeError(f"Missing arguments to backend.{method.__name__}: {missing}") if len(vars_keyword) > 0: - return set() # no extra arguments if the method accepts **kwargs + return set() # no extra arguments if the method accepts **kwargs extra = backend_kws - set(args.keys()) if len(extra) > 0 and len(vars_keyword) == 0: @@ -342,7 +299,7 @@ def _check_args( return extra def _make_sure_channels_exist(self, channels: List[int]): - """Checks that the channels exist.""" + """ Checks that the channels exist. """ invalid_channels = [c for c in channels if c not in self.head] if not len(invalid_channels) == 0: raise ValueError(f"Invalid channels: {invalid_channels}") @@ -353,26 +310,26 @@ async def pick_up_tips( tip_spots: List[TipSpot], use_channels: Optional[List[int]] = None, offsets: Optional[List[Coordinate]] = None, - **backend_kwargs, + **backend_kwargs ): - """Pick up tips from a resource. + """ Pick up tips from a resource. Examples: Pick up all tips in the first column. - >>> await lh.pick_up_tips(tips_resource["A1":"H1"]) + >>> lh.pick_up_tips(tips_resource["A1":"H1"]) Pick up tips on odd numbered rows, skipping the other channels. - >>> await lh.pick_up_tips(tips_resource["A1", "C1", "E1", "G1"],use_channels=[0, 2, 4, 6]) + >>> lh.pick_up_tips(tips_resource["A1", "C1", "E1", "G1"],use_channels=[0, 2, 4, 6]) Pick up tips from different tip resources: - >>> await lh.pick_up_tips(tips_resource1["A1"] + tips_resource2["B2"] + tips_resource3["C3"]) + >>> lh.pick_up_tips(tips_resource1["A1"] + tips_resource2["B2"] + tips_resource3["C3"]) Picking up tips with different offsets: - >>> await lh.pick_up_tips( + >>> lh.pick_up_tips( ... tip_spots=tips_resource["A1":"C1"], ... offsets=[ ... Coordinate(0, 0, 0), # A1 @@ -417,15 +374,12 @@ async def pick_up_tips( # checks self._assert_resources_exist(tip_spots) self._make_sure_channels_exist(use_channels) - assert ( - len(tip_spots) == len(offsets) == len(use_channels) - ), "Number of tips and offsets and use_channels must be equal." + assert len(tip_spots) == len(offsets) == len(use_channels), \ + "Number of tips and offsets and use_channels must be equal." # create operations - pickups = [ - Pickup(resource=tip_spot, offset=offset, tip=tip) - for tip_spot, offset, tip in zip(tip_spots, offsets, tips) - ] + pickups = [Pickup(resource=tip_spot, offset=offset, tip=tip) + for tip_spot, offset, tip in zip(tip_spots, offsets, tips)] # queue operations on the trackers for channel, op in zip(use_channels, pickups): @@ -436,12 +390,8 @@ async def pick_up_tips( self.head[channel].add_tip(op.tip, origin=op.resource, commit=False) # fix the backend kwargs - extras = self._check_args( - self.backend.pick_up_tips, - backend_kwargs, - default={"ops", "use_channels"}, - strictness=get_strictness(), - ) + extras = self._check_args(self.backend.pick_up_tips, backend_kwargs, + default={"ops", "use_channels"}) for extra in extras: del backend_kwargs[extra] @@ -449,7 +399,7 @@ async def pick_up_tips( error: Optional[Exception] = None try: await self.backend.pick_up_tips(ops=pickups, use_channels=use_channels, **backend_kwargs) - except Exception as e: + except Exception as e: # pylint: disable=broad-except error = e # determine which channels were successful @@ -476,22 +426,22 @@ async def pick_up_tips( @need_setup_finished async def drop_tips( self, - tip_spots: Sequence[Union[TipSpot, Trash]], + tip_spots: List[Union[TipSpot, Trash]], use_channels: Optional[List[int]] = None, offsets: Optional[List[Coordinate]] = None, allow_nonzero_volume: bool = False, - **backend_kwargs, + **backend_kwargs ): - """Drop tips to a resource. + """ Drop tips to a resource. Examples: Dropping tips to the first column. - >>> await lh.pick_up_tips(tip_rack["A1:H1"]) + >>> lh.pick_up_tips(tip_rack["A1:H1"]) Dropping tips with different offsets: - >>> await lh.drop_tips( + >>> lh.drop_tips( ... channels=tips_resource["A1":"C1"], ... offsets=[ ... Coordinate(0, 0, 0), # A1 @@ -547,33 +497,23 @@ async def drop_tips( # checks self._assert_resources_exist(tip_spots) self._make_sure_channels_exist(use_channels) - assert ( - len(tip_spots) == len(offsets) == len(use_channels) == len(tips) - ), "Number of channels and offsets and use_channels and tips must be equal." + assert len(tip_spots) == len(offsets) == len(use_channels) == len(tips), \ + "Number of channels and offsets and use_channels and tips must be equal." # create operations - drops = [ - Drop(resource=tip_spot, offset=offset, tip=tip) - for tip_spot, tip, offset in zip(tip_spots, tips, offsets) - ] + drops = [Drop(resource=tip_spot, offset=offset, tip=tip) + for tip_spot, tip, offset in zip(tip_spots, tips, offsets)] # queue operations on the trackers for channel, op in zip(use_channels, drops): - if ( - does_tip_tracking() - and isinstance(op.resource, TipSpot) - and not op.resource.tracker.is_disabled - ): + if does_tip_tracking() and isinstance(op.resource, TipSpot) and \ + not op.resource.tracker.is_disabled: op.resource.tracker.add_tip(op.tip, commit=False) self.head[channel].remove_tip() # fix the backend kwargs - extras = self._check_args( - self.backend.drop_tips, - backend_kwargs, - default={"ops", "use_channels"}, - strictness=get_strictness(), - ) + extras = self._check_args(self.backend.drop_tips, backend_kwargs, + default={"ops", "use_channels"}) for extra in extras: del backend_kwargs[extra] @@ -581,7 +521,7 @@ async def drop_tips( error: Optional[Exception] = None try: await self.backend.drop_tips(ops=drops, use_channels=use_channels, **backend_kwargs) - except Exception as e: + except Exception as e: # pylint: disable=broad-except error = e # determine which channels were successful @@ -591,11 +531,8 @@ async def drop_tips( # commit or rollback the state trackers for channel, op, success in zip(use_channels, drops, successes): - if ( - does_tip_tracking() - and isinstance(op.resource, TipSpot) - and not op.resource.tracker.is_disabled - ): + if does_tip_tracking() and isinstance(op.resource, TipSpot) and \ + not op.resource.tracker.is_disabled: (op.resource.tracker.commit if success else op.resource.tracker.rollback)() (self.head[channel].commit if success else self.head[channel].rollback)() @@ -609,24 +546,16 @@ async def drop_tips( **backend_kwargs, ) - async def return_tips( - self, - use_channels: Optional[list[int]] = None, - allow_nonzero_volume: bool = False, - **backend_kwargs, - ): - """Return all tips that are currently picked up to their original place. + async def return_tips(self, use_channels: Optional[list[int]] = None, **backend_kwargs): + """ Return all tips that are currently picked up to their original place. Examples: Return the tips on the head to the tip rack where they were picked up: - >>> await lh.pick_up_tips(tip_rack["A1"]) - >>> await lh.return_tips() + >>> lh.pick_up_tips(tip_rack["A1"]) + >>> lh.return_tips() Args: - use_channels: List of channels to use. Index from front to back. If `None`, all that have - tips will be used. - allow_nonzero_volume: If `True`, tips will be returned even if their volumes are not zero. backend_kwargs: backend kwargs passed to `drop_tips`. Raises: @@ -649,35 +578,28 @@ async def return_tips( if len(tip_spots) == 0: raise RuntimeError("No tips have been picked up.") - return await self.drop_tips( - tip_spots=tip_spots, - use_channels=channels, - allow_nonzero_volume=allow_nonzero_volume, - **backend_kwargs, - ) + return await self.drop_tips(tip_spots=tip_spots, use_channels=channels, **backend_kwargs) async def discard_tips( self, use_channels: Optional[List[int]] = None, allow_nonzero_volume: bool = True, - offsets: Optional[List[Coordinate]] = None, - **backend_kwargs, + **backend_kwargs ): - """Permanently discard tips in the trash. + """ Permanently discard tips in the trash. Examples: Discarding the tips on channels 1 and 2: - >>> await lh.discard_tips(use_channels=[0, 1]) + >>> lh.discard_tips(use_channels=[0, 1]) Discarding all tips currently picked up: - >>> await lh.discard_tips() + >>> lh.discard_tips() Args: use_channels: List of channels to use. Index from front to back. If `None`, all that have tips will be used. - allow_nonzero_volume: If `True`, tips will be returned even if their volumes are not zero. backend_kwargs: Additional keyword arguments for the backend, optional. """ @@ -691,27 +613,17 @@ async def discard_tips( raise RuntimeError("No tips have been picked up and no channels were specified.") trash = self.deck.get_trash_area() - trash_offsets = get_tight_single_resource_liquid_op_offsets( - trash, - num_channels=n, - ) - # add trash_offsets to offsets if defined, otherwise use trash_offsets - # too advanced for mypy - offsets = [ - o + to if o is not None else to - for o, to in zip(offsets or [None] * n, trash_offsets) # type: ignore - ] + offsets = [c - trash.center() for c in reversed(trash.centers(yn=n))] # offset is wrt center return await self.drop_tips( - tip_spots=[trash] * n, - use_channels=use_channels, - offsets=offsets, - allow_nonzero_volume=allow_nonzero_volume, - **backend_kwargs, - ) + tip_spots=[trash]*n, + use_channels=use_channels, + offsets=offsets, + allow_nonzero_volume=allow_nonzero_volume, + **backend_kwargs) def _check_containers(self, resources: Sequence[Resource]): - """Checks that all resources are containers.""" + """ Checks that all resources are containers. """ not_containers = [r for r in resources if not isinstance(r, Container)] if len(not_containers) > 0: raise TypeError(f"Resources must be `Container`s, got {not_containers}") @@ -726,36 +638,35 @@ async def aspirate( offsets: Optional[List[Coordinate]] = None, liquid_height: Optional[List[Optional[float]]] = None, blow_out_air_volume: Optional[List[Optional[float]]] = None, - spread: Literal["wide", "tight", "custom"] = "wide", - **backend_kwargs, + **backend_kwargs ): - """Aspirate liquid from the specified wells. + """ Aspirate liquid from the specified wells. Examples: Aspirate a constant amount of liquid from the first column: - >>> await lh.aspirate(plate["A1:H1"], 50) + >>> lh.aspirate(plate["A1:H1"], 50) Aspirate an linearly increasing amount of liquid from the first column: - >>> await lh.aspirate(plate["A1:H1"], range(0, 500, 50)) + >>> lh.aspirate(plate["A1:H1"], range(0, 500, 50)) Aspirate arbitrary amounts of liquid from the first column: - >>> await lh.aspirate(plate["A1:H1"], [0, 40, 10, 50, 100, 200, 300, 400]) + >>> lh.aspirate(plate["A1:H1"], [0, 40, 10, 50, 100, 200, 300, 400]) Aspirate liquid from wells in different plates: - >>> await lh.aspirate(plate["A1"] + plate2["A1"] + plate3["A1"], 50) + >>> lh.aspirate(plate["A1"] + plate2["A1"] + plate3["A1"], 50) Aspirating with a 10mm z-offset: - >>> await lh.aspirate(plate["A1"], vols=50, offsets=[Coordinate(0, 0, 10)]) + >>> lh.aspirate(plate["A1"], vols=50, offsets=[Coordinate(0, 0, 10)]) Aspirate from a blue bucket (big container), with the first 4 channels (which will be spaced equally apart): - >>> await lh.aspirate(blue_bucket, vols=50, use_channels=[0, 1, 2, 3]) + >>> lh.aspirate(blue_bucket, vols=50, use_channels=[0, 1, 2, 3]) Args: resources: A list of wells to aspirate liquid from. Can be a single resource, or a list of @@ -771,10 +682,6 @@ async def aspirate( liquid_height: The height of the liquid in the well wrt the bottom, in mm. blow_out_air_volume: The volume of air to aspirate after the liquid, in ul. If `None`, the backend default will be used. - spread: Used if aspirating from a single resource with multiple channels. If "tight", the - channels will be spaced as close as possible. If "wide", the channels will be spaced as far - apart as possible. If "custom", the user must specify the offsets wrt the center of the - resource. backend_kwargs: Additional keyword arguments for the backend, optional. Raises: @@ -815,22 +722,11 @@ async def aspirate( # center of the resource. if len(set(resources)) == 1: resource = resources[0] + n = len(use_channels) resources = [resource] * len(use_channels) - if spread == "tight": - center_offsets = get_tight_single_resource_liquid_op_offsets( - resource=resource, num_channels=len(use_channels) - ) - elif spread == "wide": - center_offsets = get_wide_single_resource_liquid_op_offsets( - resource=resource, num_channels=len(use_channels) - ) - elif spread == "custom": - center_offsets = [Coordinate.zero()] * len(use_channels) - else: - raise ValueError("Invalid value for 'spread'. Must be 'tight', 'wide', or 'custom'.") - - # add user defined offsets to the computed centers - offsets = [c + o for c, o in zip(center_offsets, offsets)] + centers = list(reversed(resource.centers(yn=n, zn=0))) + centers = [c - resource.center() for c in centers] # offset is wrt center + offsets = [c + o for c, o in zip(centers, offsets)] # user-defined # liquid(s) for each channel. If volume tracking is disabled, use None as the liquid. liquids: List[List[Tuple[Optional[Liquid], float]]] = [] @@ -841,28 +737,11 @@ async def aspirate( liquids.append(r.tracker.get_liquids(top_volume=vol)) # create operations - aspirations = [ - SingleChannelAspiration( - resource=r, - volume=v, - offset=o, - flow_rate=fr, - liquid_height=lh, - tip=t, - blow_out_air_volume=bav, - liquids=lvs, - ) - for r, v, o, fr, lh, t, bav, lvs in zip( - resources, - vols, - offsets, - flow_rates, - liquid_height, - tips, - blow_out_air_volume, - liquids, - ) - ] + aspirations = [Aspiration(resource=r, volume=v, offset=o, flow_rate=fr, liquid_height=lh, tip=t, + blow_out_air_volume=bav, liquids=lvs) + for r, v, o, fr, lh, t, bav, lvs in + zip(resources, vols, offsets, flow_rates, liquid_height, tips, + blow_out_air_volume, liquids)] # queue the operations on the resource (source) and mounted tips (destination) trackers for op in aspirations: @@ -872,24 +751,16 @@ async def aspirate( # Cross contamination check if does_cross_contamination_tracking(): - if check_contaminated( - op.tip.tracker.liquid_history, - op.resource.tracker.liquid_history, - ): + if check_contaminated(op.tip.tracker.liquid_history, op.resource.tracker.liquid_history): raise CrossContaminationError( f"Attempting to aspirate {next(reversed(op.liquids))[0]} with a tip contaminated " - f"with {op.tip.tracker.liquid_history}." - ) + f"with {op.tip.tracker.liquid_history}.") for liquid, volume in reversed(op.liquids): op.tip.tracker.add_liquid(liquid=liquid, volume=volume) - extras = self._check_args( - self.backend.aspirate, - backend_kwargs, - default={"ops", "use_channels"}, - strictness=get_strictness(), - ) + extras = self._check_args(self.backend.aspirate, backend_kwargs, + default={"ops", "use_channels"}) for extra in extras: del backend_kwargs[extra] @@ -897,7 +768,7 @@ async def aspirate( error: Optional[Exception] = None try: await self.backend.aspirate(ops=aspirations, use_channels=use_channels, **backend_kwargs) - except Exception as e: + except Exception as e: # pylint: disable=broad-exception-caught error = e # determine which channels were successful @@ -910,8 +781,7 @@ async def aspirate( if does_volume_tracking(): if not op.resource.tracker.is_disabled: (op.resource.tracker.commit if success else op.resource.tracker.rollback)() - tip_volume_tracker = self.head[channel].get_tip().tracker - (tip_volume_tracker.commit if success else tip_volume_tracker.rollback)() + (self.head[channel].get_tip().tracker.commit if success else self.head[channel].rollback)() # trigger callback self._trigger_callback( @@ -933,36 +803,35 @@ async def dispense( offsets: Optional[List[Coordinate]] = None, liquid_height: Optional[List[Optional[float]]] = None, blow_out_air_volume: Optional[List[Optional[float]]] = None, - spread: Literal["wide", "tight", "custom"] = "wide", - **backend_kwargs, + **backend_kwargs ): - """Dispense liquid to the specified channels. + """ Dispense liquid to the specified channels. Examples: Dispense a constant amount of liquid to the first column: - >>> await lh.dispense(plate["A1:H1"], 50) + >>> lh.dispense(plate["A1:H1"], 50) Dispense an linearly increasing amount of liquid to the first column: - >>> await lh.dispense(plate["A1:H1"], range(0, 500, 50)) + >>> lh.dispense(plate["A1:H1"], range(0, 500, 50)) Dispense arbitrary amounts of liquid to the first column: - >>> await lh.dispense(plate["A1:H1"], [0, 40, 10, 50, 100, 200, 300, 400]) + >>> lh.dispense(plate["A1:H1"], [0, 40, 10, 50, 100, 200, 300, 400]) Dispense liquid to wells in different plates: - >>> await lh.dispense((plate["A1"], 50), (plate2["A1"], 50), (plate3["A1"], 50)) + >>> lh.dispense((plate["A1"], 50), (plate2["A1"], 50), (plate3["A1"], 50)) Dispensing with a 10mm z-offset: - >>> await lh.dispense(plate["A1"], vols=50, offsets=[Coordinate(0, 0, 10)]) + >>> lh.dispense(plate["A1"], vols=50, offsets=[Coordinate(0, 0, 10)]) Dispense a blue bucket (big container), with the first 4 channels (which will be spaced equally apart): - >>> await lh.dispense(blue_bucket, vols=50, use_channels=[0, 1, 2, 3]) + >>> lh.dispense(blue_bucket, vols=50, use_channels=[0, 1, 2, 3]) Args: wells: A list of resources to dispense liquid to. Can be a list of resources, or a single @@ -1013,22 +882,11 @@ async def dispense( # center of the resource. if len(set(resources)) == 1: resource = resources[0] + n = len(use_channels) resources = [resource] * len(use_channels) - if spread == "tight": - center_offsets = get_tight_single_resource_liquid_op_offsets( - resource=resource, num_channels=len(use_channels) - ) - elif spread == "wide": - center_offsets = get_wide_single_resource_liquid_op_offsets( - resource=resource, num_channels=len(use_channels) - ) - elif spread == "custom": - center_offsets = [Coordinate.zero()] * len(use_channels) - else: - raise ValueError("Invalid value for 'spread'. Must be 'tight', 'wide', or 'custom'.") - - # add user defined offsets to the computed centers - offsets = [c + o for c, o in zip(center_offsets, offsets)] + centers = list(reversed(resource.centers(yn=n, zn=0))) + centers = [c - resource.center() for c in centers] # offset is wrt center + offsets = [c + o for c, o in zip(centers, offsets)] # user-defined tips = [self.head[channel].get_tip() for channel in use_channels] @@ -1036,6 +894,7 @@ async def dispense( if does_volume_tracking(): if any(bav is not None and bav != 0.0 for bav in blow_out_air_volume): if self._blow_out_air_volume is None: + print(blow_out_air_volume) raise BlowOutVolumeError("No blowout volume was aspirated.") for requested_bav, done_bav in zip(blow_out_air_volume, self._blow_out_air_volume): if requested_bav is not None and done_bav is not None and requested_bav > done_bav: @@ -1049,34 +908,17 @@ async def dispense( # liquid(s) for each channel. If volume tracking is disabled, use None as the liquid. if does_volume_tracking(): - channels = [self.head[channel] for channel in use_channels] - liquids = [c.get_tip().tracker.get_liquids(top_volume=vol) for c, vol in zip(channels, vols)] + liquids = [c.get_tip().tracker.get_liquids(top_volume=vol) + for c, vol in zip(self.head.values(), vols)] else: liquids = [[(None, vol)] for vol in vols] # create operations - dispenses = [ - SingleChannelDispense( - resource=r, - volume=v, - offset=o, - flow_rate=fr, - liquid_height=lh, - tip=t, - liquids=lvs, - blow_out_air_volume=bav, - ) - for r, v, o, fr, lh, t, bav, lvs in zip( - resources, - vols, - offsets, - flow_rates, - liquid_height, - tips, - blow_out_air_volume, - liquids, - ) - ] + dispenses = [Dispense(resource=r, volume=v, offset=o, flow_rate=fr, liquid_height=lh, tip=t, + liquids=lvs, blow_out_air_volume=bav) + for r, v, o, fr, lh, t, bav, lvs in + zip(resources, vols, offsets, flow_rates, liquid_height, tips, + blow_out_air_volume, liquids)] # queue the operations on the resource (source) and mounted tips (destination) trackers for op in dispenses: @@ -1091,12 +933,8 @@ async def dispense( op.tip.tracker.remove_liquid(op.volume) # fix the backend kwargs - extras = self._check_args( - self.backend.dispense, - backend_kwargs, - default={"ops", "use_channels"}, - strictness=get_strictness(), - ) + extras = self._check_args(self.backend.dispense, backend_kwargs, + default={"ops", "use_channels"}) for extra in extras: del backend_kwargs[extra] @@ -1104,7 +942,7 @@ async def dispense( error: Optional[Exception] = None try: await self.backend.dispense(ops=dispenses, use_channels=use_channels, **backend_kwargs) - except Exception as e: + except Exception as e: # pylint: disable=broad-except error = e # determine which channels were successful @@ -1117,8 +955,7 @@ async def dispense( if does_volume_tracking(): if not op.resource.tracker.is_disabled: (op.resource.tracker.commit if success else op.resource.tracker.rollback)() - tip_volume_tracker = self.head[channel].get_tip().tracker - (tip_volume_tracker.commit if success else tip_volume_tracker.rollback)() + (self.head[channel].get_tip().tracker.commit if success else self.head[channel].rollback)() if any(bav is not None for bav in blow_out_air_volume): self._blow_out_air_volume = None @@ -1141,8 +978,8 @@ async def transfer( ratios: Optional[List[float]] = None, target_vols: Optional[List[float]] = None, aspiration_flow_rate: Optional[float] = None, - dispense_flow_rates: Optional[List[Optional[float]]] = None, - **backend_kwargs, + dispense_flow_rates: Optional[Union[float, List[Optional[float]]]] = None, + **backend_kwargs ): """Transfer liquid from one well to another. @@ -1150,19 +987,19 @@ async def transfer( Transfer 50 uL of liquid from the first well to the second well: - >>> await lh.transfer(plate["A1"], plate["B1"], source_vol=50) + >>> lh.transfer(plate["A1"], plate["B1"], source_vol=50) Transfer 80 uL of liquid from the first well equally to the first column: - >>> await lh.transfer(plate["A1"], plate["A1:H1"], source_vol=80) + >>> lh.transfer(plate["A1"], plate["A1:H1"], source_vol=80) Transfer 60 uL of liquid from the first well in a 1:2 ratio to 2 other wells: - >>> await lh.transfer(plate["A1"], plate["B1:C1"], source_vol=60, ratios=[2, 1]) + >>> lh.transfer(plate["A1"], plate["B1:C1"], source_vol=60, ratios=[2, 1]) Transfer arbitrary volumes to the first column: - >>> await lh.transfer(plate["A1"], plate["A1:H1"], target_vols=[3, 1, 4, 1, 5, 9, 6, 2]) + >>> lh.transfer(plate["A1"], plate["A1:H1"], target_vols=[3, 1, 4, 1, 5, 9, 6, 2]) Args: source: The source well. @@ -1199,36 +1036,33 @@ async def transfer( await self.aspirate( resources=[source], vols=[sum(target_vols)], - flow_rates=[aspiration_flow_rate], - **backend_kwargs, - ) - dispense_flow_rates = dispense_flow_rates or [None] * len(targets) - for target, vol, dfr in zip(targets, target_vols, dispense_flow_rates): + flow_rates=aspiration_flow_rate, + **backend_kwargs) + for target, vol in zip(targets, target_vols): await self.dispense( resources=[target], vols=[vol], - flow_rates=[dfr], + flow_rates=dispense_flow_rates, use_channels=[0], - **backend_kwargs, - ) + **backend_kwargs) @contextlib.contextmanager def use_channels(self, channels: List[int]): - """Temporarily use the specified channels as a default argument to `use_channels`. + """ Temporarily use the specified channels as a default argument to `use_channels`. Examples: Use channel index 2 for all liquid handling operations inside the context: >>> with lh.use_channels([2]): - ... await lh.pick_up_tips(tip_rack["A1"]) - ... await lh.aspirate(plate["A1"], 50) - ... await lh.dispense(plate["A1"], 50) + ... lh.pick_up_tips(tip_rack["A1"]) + ... lh.aspirate(plate["A1"], 50) + ... lh.dispense(plate["A1"], 50) This is equivalent to: - >>> await lh.pick_up_tips(tip_rack["A1"], use_channels=[2]) - >>> await lh.aspirate(plate["A1"], 50, use_channels=[2]) - >>> await lh.dispense(plate["A1"], 50, use_channels=[2]) + >>> lh.pick_up_tips(tip_rack["A1"], use_channels=[2]) + >>> lh.aspirate(plate["A1"], 50, use_channels=[2]) + >>> lh.dispense(plate["A1"], 50, use_channels=[2]) Within the context manager, you can override the default channels by specifying the `use_channels` argument explicitly. @@ -1245,14 +1079,14 @@ async def pick_up_tips96( self, tip_rack: TipRack, offset: Coordinate = Coordinate.zero(), - **backend_kwargs, + **backend_kwargs ): - """Pick up tips using the 96 head. This will pick up 96 tips. + """ Pick up tips using the 96 head. This will pick up 96 tips. Examples: Pick up tips from a 96-tip tiprack: - >>> await lh.pick_up_tips96(my_tiprack) + >>> lh.pick_up_tips96(my_tiprack) Args: tip_rack: The tip rack to pick up tips from. @@ -1265,9 +1099,7 @@ async def pick_up_tips96( if not tip_rack.num_items == 96: raise ValueError("Tip rack must have 96 tips") - extras = self._check_args( - self.backend.pick_up_tips96, backend_kwargs, default={"pickup"}, strictness=get_strictness() - ) + extras = self._check_args(self.backend.pick_up_tips96, backend_kwargs, default={"pickup"}) for extra in extras: del backend_kwargs[extra] @@ -1281,8 +1113,11 @@ async def pick_up_tips96( pickup_operation = PickupTipRack(resource=tip_rack, offset=offset) try: - await self.backend.pick_up_tips96(pickup=pickup_operation, **backend_kwargs) - except Exception as error: + await self.backend.pick_up_tips96( + pickup=pickup_operation, + **backend_kwargs + ) + except Exception as error: # pylint: disable=broad-except for i, tip_spot in enumerate(tip_rack.get_all_items()): if does_tip_tracking() and not tip_spot.tracker.is_disabled: tip_spot.tracker.rollback() @@ -1312,18 +1147,18 @@ async def drop_tips96( resource: Union[TipRack, Trash], offset: Coordinate = Coordinate.zero(), allow_nonzero_volume: bool = False, - **backend_kwargs, + **backend_kwargs ): - """Drop tips using the 96 head. This will drop 96 tips. + """ Drop tips using the 96 head. This will drop 96 tips. Examples: Drop tips to a 96-tip tiprack: - >>> await lh.drop_tips96(my_tiprack) + >>> lh.drop_tips96(my_tiprack) Drop tips to the trash: - >>> await lh.drop_tips96(lh.deck.get_trash_area96()) + >>> lh.drop_tips96(lh.deck.get_trash_area96()) Args: resource: The tip rack to drop tips to. @@ -1339,9 +1174,7 @@ async def drop_tips96( if isinstance(resource, TipRack) and not resource.num_items == 96: raise ValueError("Tip rack must have 96 tips") - extras = self._check_args( - self.backend.drop_tips96, backend_kwargs, default={"drop"}, strictness=get_strictness() - ) + extras = self._check_args(self.backend.drop_tips96, backend_kwargs, default={"drop"}) for extra in extras: del backend_kwargs[extra] @@ -1359,8 +1192,11 @@ async def drop_tips96( drop_operation = DropTipRack(resource=resource, offset=offset) try: - await self.backend.drop_tips96(drop=drop_operation, **backend_kwargs) - except Exception as e: + await self.backend.drop_tips96( + drop=drop_operation, + **backend_kwargs + ) + except Exception as e: # pylint: disable=broad-except for i in range(96): if isinstance(resource, TipRack): tip_spot = resource.get_item(i) @@ -1390,9 +1226,9 @@ async def drop_tips96( ) def _get_96_head_origin_tip_rack(self) -> Optional[TipRack]: - """Get the tip rack where the tips on the 96 head were picked up. If no tips were picked up, + """ Get the tip rack where the tips on the 96 head were picked up. If no tips were picked up, return `None`. If different tip racks were found for different tips on the head, raise a - RuntimeError.""" + RuntimeError. """ tip_spot = self.head96[0].get_tip_origin() if tip_spot is None: @@ -1411,13 +1247,13 @@ def _get_96_head_origin_tip_rack(self) -> Optional[TipRack]: return tip_rack async def return_tips96(self, allow_nonzero_volume: bool = False, **backend_kwargs): - """Return the tips on the 96 head to the tip rack where they were picked up. + """ Return the tips on the 96 head to the tip rack where they were picked up. Examples: Return the tips on the 96 head to the tip rack where they were picked up: - >>> await lh.pick_up_tips96(my_tiprack) - >>> await lh.return_tips96() + >>> lh.pick_up_tips96(my_tiprack) + >>> lh.return_tips96() Raises: RuntimeError: If no tips have been picked up. @@ -1429,18 +1265,17 @@ async def return_tips96(self, allow_nonzero_volume: bool = False, **backend_kwar return await self.drop_tips96( tip_rack, allow_nonzero_volume=allow_nonzero_volume, - **backend_kwargs, - ) + **backend_kwargs) async def discard_tips96(self, allow_nonzero_volume: bool = True, **backend_kwargs): - """Permanently discard tips from the 96 head in the trash. This method only works when this + """ Permanently discard tips from the 96 head in the trash. This method only works when this LiquidHandler is configured with a deck that implements the `get_trash_area96` method. Otherwise, an `ImplementationError` will be raised. Examples: Discard the tips on the 96 head: - >>> await lh.discard_tips96() + >>> lh.discard_tips96() Args: allow_nonzero_volume: If `True`, the tip will be dropped even if its volume is not zero (there @@ -1455,8 +1290,7 @@ async def discard_tips96(self, allow_nonzero_volume: bool = True, **backend_kwar return await self.drop_tips96( self.deck.get_trash_area96(), allow_nonzero_volume=allow_nonzero_volume, - **backend_kwargs, - ) + **backend_kwargs) async def aspirate96( self, @@ -1465,15 +1299,15 @@ async def aspirate96( offset: Coordinate = Coordinate.zero(), flow_rate: Optional[float] = None, blow_out_air_volume: Optional[float] = None, - **backend_kwargs, + **backend_kwargs ): - """Aspirate from all wells in a plate or from a container of a sufficient size. + """ Aspirate from all wells in a plate or from a container of a sufficient size. Examples: Aspirate an entire 96 well plate or a container of sufficient size: - >>> await lh.aspirate96(plate, volume=50) - >>> await lh.aspirate96(container, volume=50) + >>> lh.aspirate96(plate, volume=50) + >>> lh.aspirate96(container, volume=50) Args: resource (Union[Plate, Container, List[Well]]): Resource object or list of wells. @@ -1487,32 +1321,26 @@ async def aspirate96( backend_kwargs: Additional keyword arguments for the backend, optional. """ - if not ( - isinstance(resource, (Plate, Container)) - or (isinstance(resource, list) and all(isinstance(w, Well) for w in resource)) - ): + if not (isinstance(resource, (Plate, Container)) or \ + (isinstance(resource, list) and all(isinstance(w, Well) for w in resource))): raise TypeError(f"Resource must be a Plate, Container, or list of Wells, got {resource}") - extras = self._check_args( - self.backend.aspirate96, backend_kwargs, default={"aspiration"}, strictness=get_strictness() - ) + extras = self._check_args(self.backend.aspirate96, backend_kwargs, default={"aspiration"}) for extra in extras: del backend_kwargs[extra] tips = [channel.get_tip() for channel in self.head96.values()] all_liquids: List[List[Tuple[Optional[Liquid], float]]] = [] - aspiration: Union[MultiHeadAspirationPlate, MultiHeadAspirationContainer] + aspiration: Union[AspirationPlate, AspirationContainer] # Convert everything to floats to handle exotic number types volume = float(volume) flow_rate = float(flow_rate) if flow_rate is not None else None blow_out_air_volume = float(blow_out_air_volume) if blow_out_air_volume is not None else None - containers: Sequence[Container] if isinstance(resource, Container): - if ( - resource.get_absolute_size_x() < 108.0 or resource.get_absolute_size_y() < 70.0 - ): # TODO: analyze as attr + if resource.get_absolute_size_x() < 108.0 or \ + resource.get_absolute_size_y() < 70.0: # TODO: analyze as attr raise ValueError("Container too small to accommodate 96 head") for channel in self.head96.values(): @@ -1523,13 +1351,13 @@ async def aspirate96( liquids = [(None, volume)] all_liquids.append(liquids) else: - liquids = resource.tracker.remove_liquid(volume=volume) # type: ignore + liquids = resource.tracker.remove_liquid(volume=volume) # type: ignore all_liquids.append(liquids) for liquid, vol in reversed(liquids): channel.get_tip().tracker.add_liquid(liquid=liquid, volume=vol) - aspiration = MultiHeadAspirationContainer( + aspiration = AspirationContainer( container=resource, volume=volume, offset=offset, @@ -1537,57 +1365,55 @@ async def aspirate96( tips=tips, liquid_height=None, blow_out_air_volume=blow_out_air_volume, - liquids=cast(List[List[Tuple[Optional[Liquid], float]]], all_liquids), # stupid + liquids=cast(List[List[Tuple[Optional[Liquid], float]]], all_liquids) # stupid ) - - containers = [resource] else: if isinstance(resource, Plate): if resource.has_lid(): raise ValueError("Aspirating from plate with lid") - containers = resource.get_all_items() + wells = resource.get_all_items() else: - containers = resource + wells = resource # ensure that wells are all in the same plate - plate = containers[0].parent - for well in containers: + plate = wells[0].parent + for well in wells: if well.parent != plate: raise ValueError("All wells must be in the same plate") - if not len(containers) == 96: - raise ValueError(f"aspirate96 expects 96 wells, got {len(containers)}") + if not len(wells) == 96: + raise ValueError(f"aspirate96 expects 96 wells, got {len(wells)}") - for well, channel in zip(containers, self.head96.values()): + for well, channel in zip(wells, self.head96.values()): # superfluous to have append in two places but the type checker is very angry and does not # understand that Optional[Liquid] (remove_liquid) is the same as None from the first case if well.tracker.is_disabled or not does_volume_tracking(): liquids = [(None, volume)] all_liquids.append(liquids) else: - liquids = well.tracker.remove_liquid(volume=volume) # type: ignore + liquids = well.tracker.remove_liquid(volume=volume) # type: ignore all_liquids.append(liquids) for liquid, vol in reversed(liquids): channel.get_tip().tracker.add_liquid(liquid=liquid, volume=vol) - aspiration = MultiHeadAspirationPlate( - wells=cast(List[Well], containers), + aspiration = AspirationPlate( + wells=wells, volume=volume, offset=offset, flow_rate=flow_rate, tips=tips, liquid_height=None, blow_out_air_volume=blow_out_air_volume, - liquids=cast(List[List[Tuple[Optional[Liquid], float]]], all_liquids), # stupid + liquids=cast(List[List[Tuple[Optional[Liquid], float]]], all_liquids) # stupid ) try: await self.backend.aspirate96(aspiration=aspiration, **backend_kwargs) - except Exception as error: - for channel, container in zip(self.head96.values(), containers): - if does_volume_tracking() and not container.tracker.is_disabled: - container.tracker.rollback() + except Exception as error: # pylint: disable=broad-except + for channel, well in zip(self.head96.values(), wells): + if does_volume_tracking() and not well.tracker.is_disabled: + well.tracker.rollback() channel.get_tip().tracker.rollback() self._trigger_callback( "aspirate96", @@ -1597,11 +1423,10 @@ async def aspirate96( **backend_kwargs, ) else: - for channel, container in zip(self.head96.values(), containers): - if does_volume_tracking() and not container.tracker.is_disabled: - container.tracker.commit() - channel.get_tip().tracker.commit() - + for channel, well in zip(self.head96.values(), wells): + if does_volume_tracking() and not well.tracker.is_disabled: + well.tracker.commit() + channel.get_tip().tracker.commit() self._trigger_callback( "aspirate96", liquid_handler=self, @@ -1617,14 +1442,14 @@ async def dispense96( offset: Coordinate = Coordinate.zero(), flow_rate: Optional[float] = None, blow_out_air_volume: Optional[float] = None, - **backend_kwargs, + **backend_kwargs ): - """Dispense to all wells in a plate. + """ Dispense to all wells in a plate. Examples: Dispense an entire 96 well plate: - >>> await lh.dispense96(plate, volume=50) + >>> lh.dispense96(plate, volume=50) Args: resource (Union[Plate, Container, List[Well]]): Resource object or list of wells. @@ -1638,49 +1463,43 @@ async def dispense96( backend_kwargs: Additional keyword arguments for the backend, optional. """ - if not ( - isinstance(resource, (Plate, Container)) - or (isinstance(resource, list) and all(isinstance(w, Well) for w in resource)) - ): + if not (isinstance(resource, (Plate, Container)) or \ + (isinstance(resource, list) and all(isinstance(w, Well) for w in resource))): raise TypeError(f"Resource must be a Plate, Container, or list of Wells, got {resource}") - extras = self._check_args( - self.backend.dispense96, backend_kwargs, default={"dispense"}, strictness=get_strictness() - ) + extras = self._check_args(self.backend.dispense96, backend_kwargs, default={"dispense"}) for extra in extras: del backend_kwargs[extra] tips = [channel.get_tip() for channel in self.head96.values()] all_liquids: List[List[Tuple[Optional[Liquid], float]]] = [] - dispense: Union[MultiHeadDispensePlate, MultiHeadDispenseContainer] + dispense: Union[DispensePlate, DispenseContainer] # Convert everything to floats to handle exotic number types volume = float(volume) flow_rate = float(flow_rate) if flow_rate is not None else None blow_out_air_volume = float(blow_out_air_volume) if blow_out_air_volume is not None else None - containers: Sequence[Container] if isinstance(resource, Container): - if ( - resource.get_absolute_size_x() < 108.0 or resource.get_absolute_size_y() < 70.0 - ): # TODO: analyze as attr + if resource.get_absolute_size_x() < 108.0 or \ + resource.get_absolute_size_y() < 70.0: # TODO: analyze as attr raise ValueError("Container too small to accommodate 96 head") for channel in self.head96.values(): # superfluous to have append in two places but the type checker is very angry and does not # understand that Optional[Liquid] (remove_liquid) is the same as None from the first case - reversed_liquids: List[Tuple[Optional[Liquid], float]] + liquids: List[Tuple[Optional[Liquid], float]] if resource.tracker.is_disabled or not does_volume_tracking(): - reversed_liquids = [(None, volume)] - all_liquids.append(reversed_liquids) + liquids = [(None, volume)] + all_liquids.append(liquids) else: - reversed_liquids = resource.tracker.remove_liquid(volume=volume) # type: ignore - all_liquids.append(reversed_liquids) + liquids = resource.tracker.remove_liquid(volume=volume) # type: ignore + all_liquids.append(liquids) - for liquid, vol in reversed(reversed_liquids): + for liquid, vol in reversed(liquids): channel.get_tip().tracker.add_liquid(liquid=liquid, volume=vol) - dispense = MultiHeadDispenseContainer( + dispense = DispenseContainer( container=resource, volume=volume, offset=offset, @@ -1688,39 +1507,37 @@ async def dispense96( tips=tips, liquid_height=None, blow_out_air_volume=blow_out_air_volume, - liquids=cast(List[List[Tuple[Optional[Liquid], float]]], all_liquids), # stupid + liquids=cast(List[List[Tuple[Optional[Liquid], float]]], all_liquids) # stupid ) - - containers = [resource] else: if isinstance(resource, Plate): if resource.has_lid(): raise ValueError("Aspirating from plate with lid") - containers = resource.get_all_items() - else: # List[Well] - containers = resource + wells = resource.get_all_items() + else: + wells = resource # ensure that wells are all in the same plate - plate = containers[0].parent - for well in containers: + plate = wells[0].parent + for well in wells: if well.parent != plate: raise ValueError("All wells must be in the same plate") - if not len(containers) == 96: - raise ValueError(f"dispense96 expects 96 wells, got {len(containers)}") + if not len(wells) == 96: + raise ValueError(f"dispense96 expects 96 wells, got {len(wells)}") - for channel, well in zip(self.head96.values(), containers): + for channel, well in zip(self.head96.values(), wells): # even if the volume tracker is disabled, a liquid (None, volume) is added to the list # during the aspiration command - liquids = channel.get_tip().tracker.remove_liquid(volume=volume) - reversed_liquids = list(reversed(liquids)) - all_liquids.append(reversed_liquids) + l = channel.get_tip().tracker.remove_liquid(volume=volume) + liquids = list(reversed(l)) + all_liquids.append(liquids) - for liquid, vol in reversed_liquids: + for liquid, vol in liquids: well.tracker.add_liquid(liquid=liquid, volume=vol) - dispense = MultiHeadDispensePlate( - wells=cast(List[Well], containers), + dispense = DispensePlate( + wells=wells, volume=volume, offset=offset, flow_rate=flow_rate, @@ -1732,10 +1549,10 @@ async def dispense96( try: await self.backend.dispense96(dispense=dispense, **backend_kwargs) - except Exception as error: - for channel, container in zip(self.head96.values(), containers): + except Exception as error: # pylint: disable=broad-except + for channel, well in zip(self.head96.values(), wells): if does_volume_tracking() and not well.tracker.is_disabled: - container.tracker.rollback() + well.tracker.rollback() channel.get_tip().tracker.rollback() self._trigger_callback( @@ -1746,9 +1563,9 @@ async def dispense96( **backend_kwargs, ) else: - for channel, container in zip(self.head96.values(), containers): + for channel, well in zip(self.head96.values(), wells): if does_volume_tracking() and not well.tracker.is_disabled: - container.tracker.commit() + well.tracker.commit() channel.get_tip().tracker.commit() self._trigger_callback( @@ -1761,13 +1578,13 @@ async def dispense96( async def stamp( self, - source: Plate, # TODO + source: Plate, # TODO target: Plate, volume: float, aspiration_flow_rate: Optional[float] = None, dispense_flow_rate: Optional[float] = None, ): - """Stamp (aspiration and dispense) one plate onto another. + """ Stamp (aspiration and dispense) one plate onto another. Args: source: the source plate @@ -1779,407 +1596,260 @@ async def stamp( will be used. """ - assert (source.num_items_x, source.num_items_y) == ( - target.num_items_x, - target.num_items_y, - ), "Source and target plates must be the same shape" - - await self.aspirate96(resource=source, volume=volume, flow_rate=aspiration_flow_rate) - await self.dispense96(resource=source, volume=volume, flow_rate=dispense_flow_rate) - - async def pick_up_resource( - self, - resource: Resource, - offset: Coordinate = Coordinate.zero(), - pickup_distance_from_top: float = 0, - direction: GripDirection = GripDirection.FRONT, - **backend_kwargs, - ): - if self._resource_pickup is not None: - raise RuntimeError(f"Resource {self._resource_pickup.resource.name} already picked up") - - self._resource_pickup = ResourcePickup( - resource=resource, - offset=offset, - pickup_distance_from_top=pickup_distance_from_top, - direction=direction, - ) - - extras = self._check_args( - self.backend.pick_up_resource, backend_kwargs, default={"pickup"}, strictness=get_strictness() - ) - for extra in extras: - del backend_kwargs[extra] - - try: - await self.backend.pick_up_resource( - pickup=self._resource_pickup, - **backend_kwargs, - ) - except Exception as e: - self._resource_pickup = None - raise e - - async def move_picked_up_resource( - self, - to: Coordinate, - ): - if self._resource_pickup is None: - raise RuntimeError("No resource picked up") - await self.backend.move_picked_up_resource( - ResourceMove( - location=to, - resource=self._resource_pickup.resource, - gripped_direction=self._resource_pickup.direction, - ) - ) - - async def drop_resource( - self, - destination: Union[ResourceStack, ResourceHolder, Resource, Coordinate], - offset: Coordinate = Coordinate.zero(), - direction: GripDirection = GripDirection.FRONT, - **backend_kwargs, - ): - if self._resource_pickup is None: - raise RuntimeError("No resource picked up") - resource = self._resource_pickup.resource - - # compute rotation based on the pickup_direction and drop_direction - if self._resource_pickup.direction == direction: - rotation_applied_by_move = 0 - if (self._resource_pickup.direction, direction) in ( - (GripDirection.FRONT, GripDirection.RIGHT), - (GripDirection.RIGHT, GripDirection.BACK), - (GripDirection.BACK, GripDirection.LEFT), - (GripDirection.LEFT, GripDirection.FRONT), - ): - rotation_applied_by_move = 90 - if (self._resource_pickup.direction, direction) in ( - (GripDirection.FRONT, GripDirection.BACK), - (GripDirection.BACK, GripDirection.FRONT), - (GripDirection.LEFT, GripDirection.RIGHT), - (GripDirection.RIGHT, GripDirection.LEFT), - ): - rotation_applied_by_move = 180 - if (self._resource_pickup.direction, direction) in ( - (GripDirection.RIGHT, GripDirection.FRONT), - (GripDirection.BACK, GripDirection.RIGHT), - (GripDirection.LEFT, GripDirection.BACK), - (GripDirection.FRONT, GripDirection.LEFT), - ): - rotation_applied_by_move = 270 - - # the resource's absolute rotation should be the resource's previous rotation plus the - # rotation the move applied. The resource's absolute rotation is the rotation of the - # new parent plus the resource's rotation relative to the parent. So to find the new - # rotation of the resource wrt its new parent, we compute what the new absolute rotation - # should be and subtract the rotation of the new parent. - - # moving from a resource from a rotated parent to a non-rotated parent means child inherits/'houses' the rotation after move - resource_absolute_rotation_after_move = ( - resource.get_absolute_rotation().z + rotation_applied_by_move - ) - destination_rotation = ( - destination.get_absolute_rotation().z if not isinstance(destination, Coordinate) else 0 - ) - resource_rotation_wrt_destination = resource_absolute_rotation_after_move - destination_rotation - - # `get_default_child_location`, which is used to compute the translation of the child wrt the parent, - # only considers the child's local rotation. In order to set this new child rotation locally for the - # translation computation, we have to subtract the current rotation of the resource, so we can use - # resource.rotated(z=resource_rotation_wrt_destination_wrt_local) to 'set' the new local rotation. - # Remember, rotated() applies the rotation on top of the current rotation. <- TODO: stupid - resource_rotation_wrt_destination_wrt_local = ( - resource_rotation_wrt_destination - resource.rotation.z - ) - - # get the location of the destination - if isinstance(destination, ResourceStack): - assert ( - destination.direction == "z" - ), "Only ResourceStacks with direction 'z' are currently supported" - to_location = destination.get_absolute_location(z="top") - elif isinstance(destination, Coordinate): - to_location = destination - elif isinstance(destination, ResourceHolder): - if destination.resource is not None and destination.resource is not resource: - raise RuntimeError("Destination already has a plate") - child_wrt_parent = destination.get_default_child_location( - resource.rotated(z=resource_rotation_wrt_destination_wrt_local) - ).rotated(destination.get_absolute_rotation()) - to_location = (destination.get_absolute_location()) + child_wrt_parent - elif isinstance(destination, PlateAdapter): - if not isinstance(resource, Plate): - raise ValueError("Only plates can be moved to a PlateAdapter") - # Calculate location adjustment of Plate based on PlateAdapter geometry - adjusted_plate_anchor = destination.compute_plate_location( - resource.rotated(z=resource_rotation_wrt_destination_wrt_local) - ).rotated(destination.get_absolute_rotation()) - to_location = destination.get_absolute_location() + adjusted_plate_anchor - elif isinstance(destination, Plate) and isinstance(resource, Lid): - lid = resource - plate_location = destination.get_absolute_location() - child_wrt_parent = destination.get_lid_location( - lid.rotated(z=resource_rotation_wrt_destination_wrt_local) - ).rotated(destination.get_absolute_rotation()) - to_location = plate_location + child_wrt_parent - else: - to_location = destination.get_absolute_location() - - drop = ResourceDrop( - resource=self._resource_pickup.resource, - destination=to_location, - destination_absolute_rotation=destination.get_absolute_rotation() - if isinstance(destination, Resource) - else Rotation(0, 0, 0), - offset=offset, - pickup_distance_from_top=self._resource_pickup.pickup_distance_from_top, - pickup_direction=self._resource_pickup.direction, - drop_direction=direction, - rotation=rotation_applied_by_move, - ) - result = await self.backend.drop_resource(drop=drop, **backend_kwargs) - - # we rotate the resource on top of its original rotation. So in order to set the new rotation, - # we have to subtract its current rotation. - resource.rotate(z=resource_rotation_wrt_destination - resource.rotation.z) - - # assign to destination - resource.unassign() - if isinstance(destination, Coordinate): - to_location -= self.deck.location # passed as an absolute location, but stored as relative - self.deck.assign_child_resource(resource, location=to_location) - elif isinstance(destination, PlateHolder): # .zero() resources - destination.assign_child_resource(resource) - elif isinstance(destination, ResourceHolder): # .zero() resources - destination.assign_child_resource(resource) - elif isinstance(destination, (ResourceStack, PlateReader)): # manage its own resources - if isinstance(destination, ResourceStack) and destination.direction != "z": - raise ValueError("Only ResourceStacks with direction 'z' are currently supported") - destination.assign_child_resource(resource) - elif isinstance(destination, Tilter): - destination.assign_child_resource(resource, location=destination.child_location) - elif isinstance(destination, PlateAdapter): - if not isinstance(resource, Plate): - raise ValueError("Only plates can be moved to a PlateAdapter") - destination.assign_child_resource( - resource, location=destination.compute_plate_location(resource) - ) - elif isinstance(destination, Plate) and isinstance(resource, Lid): - destination.assign_child_resource(resource) - else: - destination.assign_child_resource(resource, location=to_location) - - self._resource_pickup = None + assert (source.num_items_x, source.num_items_y) == (target.num_items_x, target.num_items_y), \ + "Source and target plates must be the same shape" - return result + await self.aspirate96( + resource=source, + volume=volume, + flow_rate=aspiration_flow_rate) + await self.dispense96( + resource=source, + volume=volume, + flow_rate=dispense_flow_rate) async def move_resource( self, resource: Resource, - to: Union[ResourceStack, ResourceHolder, Resource, Coordinate], + to: Coordinate, intermediate_locations: Optional[List[Coordinate]] = None, - resource_offset: Optional[Coordinate] = None, - pickup_offset: Coordinate = Coordinate.zero(), + resource_offset: Coordinate = Coordinate.zero(), destination_offset: Coordinate = Coordinate.zero(), pickup_distance_from_top: float = 0, - pickup_direction: GripDirection = GripDirection.FRONT, - drop_direction: GripDirection = GripDirection.FRONT, - get_direction: Optional[GripDirection] = None, - put_direction: Optional[GripDirection] = None, - **backend_kwargs, + get_direction: GripDirection = GripDirection.FRONT, + put_direction: GripDirection = GripDirection.FRONT, + **backend_kwargs ): - """Move a resource to a new location. + """ Move a resource to a new location. Has convenience methods :meth:`move_plate` and :meth:`move_lid`. Examples: Move a plate to a new location: - >>> await lh.move_resource(plate, to=Coordinate(100, 100, 100)) + >>> lh.move_resource(plate, to=Coordinate(100, 100, 100)) Args: resource: The Resource object. to: The absolute coordinate (meaning relative to deck) to move the resource to. intermediate_locations: A list of intermediate locations to move the resource through. - pickup_offset: The offset from the resource's origin, optional (rarely necessary). + resource_offset: The offset from the resource's origin, optional (rarely necessary). destination_offset: The offset from the location's origin, optional (rarely necessary). pickup_distance_from_top: The distance from the top of the resource to pick up from. - pickup_direction: The direction from which to pick up the resource. - drop_direction: The direction from which to put down the resource. + get_direction: The direction from which to pick up the resource. + put_direction: The direction from which to put down the resource. """ # TODO: move conditional statements from move_plate into move_resource to enable # movement to other types besides Coordinate - # https://github.com/PyLabRobot/pylabrobot/issues/329 - if resource_offset is not None: - raise NotImplementedError("resource_offset is deprecated, use pickup_offset instead") - if get_direction is not None: - raise NotImplementedError("get_direction is deprecated, use pickup_direction instead") - if put_direction is not None: - raise NotImplementedError("put_direction is deprecated, use drop_direction instead") - - extra = self._check_args( - self.backend.pick_up_resource, - backend_kwargs, - default={"pickup"}, - strictness=Strictness.IGNORE, - ) - pickup_kwargs = {k: v for k, v in backend_kwargs.items() if k not in extra} + extras = self._check_args(self.backend.move_resource, backend_kwargs, default={"move"}) + for extra in extras: + del backend_kwargs[extra] - await self.pick_up_resource( + move_operation = Move( resource=resource, - offset=pickup_offset, + destination=to, + intermediate_locations=intermediate_locations or [], + resource_offset=resource_offset, + destination_offset=destination_offset, pickup_distance_from_top=pickup_distance_from_top, - direction=pickup_direction, - **pickup_kwargs, + get_direction=get_direction, + put_direction=put_direction, ) - for intermediate_location in intermediate_locations or []: - await self.move_picked_up_resource(to=intermediate_location) + result = await self.backend.move_resource(move=move_operation, **backend_kwargs) - extra = self._check_args( - self.backend.drop_resource, - backend_kwargs, - default={"drop"}, - strictness=Strictness.IGNORE, - ) - drop_kwargs = {k: v for k, v in backend_kwargs.items() if k not in extra} + # rotate the resource if the move operation has a rotation. + # this code should be expanded to also update the resource's location + if move_operation.rotation != 0: + move_operation.resource.rotate(z=move_operation.rotation) - await self.drop_resource( - destination=to, - offset=destination_offset, - direction=drop_direction, - **drop_kwargs, + self._trigger_callback( + "move_resource", + liquid_handler=self, + move=move_operation, + error=None, + **backend_kwargs, ) + return result + async def move_lid( self, lid: Lid, to: Union[Plate, ResourceStack, Coordinate], intermediate_locations: Optional[List[Coordinate]] = None, - resource_offset: Optional[Coordinate] = None, - pickup_offset: Coordinate = Coordinate.zero(), + resource_offset: Coordinate = Coordinate.zero(), destination_offset: Coordinate = Coordinate.zero(), - pickup_direction: GripDirection = GripDirection.FRONT, - drop_direction: GripDirection = GripDirection.FRONT, - get_direction: Optional[GripDirection] = None, - put_direction: Optional[GripDirection] = None, - pickup_distance_from_top: float = 5.7 - 3.33, - **backend_kwargs, + get_direction: GripDirection = GripDirection.FRONT, + put_direction: GripDirection = GripDirection.FRONT, + pickup_distance_from_top: float = 5.7-3.33, + **backend_kwargs ): - """Move a lid to a new location. + """ Move a lid to a new location. A convenience method for :meth:`move_resource`. Examples: Move a lid to the :class:`~resources.ResourceStack`: - >>> await lh.move_lid(plate.lid, stacking_area) + >>> lh.move_lid(plate.lid, stacking_area) Move a lid to the stacking area and back, grabbing it from the left side: - >>> await lh.move_lid(plate.lid, stacking_area, pickup_direction=GripDirection.LEFT) - >>> await lh.move_lid(stacking_area.get_top_item(), plate, drop_direction=GripDirection.LEFT) + >>> lh.move_lid(plate.lid, stacking_area, get_direction=GripDirection.LEFT) + >>> lh.move_lid(stacking_area.get_top_item(), plate, put_direction=GripDirection.LEFT) Args: lid: The lid to move. Can be either a Plate object or a Lid object. to: The location to move the lid to, either a plate, ResourceStack or a Coordinate. - pickup_offset: The offset from the resource's origin, optional (rarely necessary). + resource_offset: The offset from the resource's origin, optional (rarely necessary). destination_offset: The offset from the location's origin, optional (rarely necessary). Raises: ValueError: If the lid is not assigned to a resource. """ - # https://github.com/PyLabRobot/pylabrobot/issues/329 - if resource_offset is not None: - raise NotImplementedError("resource_offset is deprecated, use pickup_offset instead") - if get_direction is not None: - raise NotImplementedError("get_direction is deprecated, use pickup_direction instead") - if put_direction is not None: - raise NotImplementedError("put_direction is deprecated, use drop_direction instead") + if isinstance(to, Plate): + to_location = to.get_absolute_location() + to_location = Coordinate( + x=to_location.x, + y=to_location.y, + z=to_location.z + to.get_absolute_size_z() - lid.nesting_z_height) + elif isinstance(to, ResourceStack): + assert to.direction == "z", "Only ResourceStacks with direction 'z' are currently supported" + to_location = to.get_absolute_location(z="top") + elif isinstance(to, Coordinate): + to_location = to + else: + raise ValueError(f"Cannot move lid to {to}") await self.move_resource( lid, - to=to, + to=to_location, intermediate_locations=intermediate_locations, pickup_distance_from_top=pickup_distance_from_top, - pickup_offset=pickup_offset, + resource_offset=resource_offset, destination_offset=destination_offset, - pickup_direction=pickup_direction, - drop_direction=drop_direction, - **backend_kwargs, - ) + get_direction=get_direction, + put_direction=put_direction, + **backend_kwargs) + + lid.unassign() + if isinstance(to, Coordinate): + self.deck.assign_child_resource(lid, location=to_location) + elif isinstance(to, ResourceStack): # manage its own resources + to.assign_child_resource(lid) + elif isinstance(to, Plate): + to.assign_child_resource(resource=lid) + else: + raise ValueError("'to' must be either a Coordinate, ResourceStack or Plate") async def move_plate( self, plate: Plate, - to: Union[ResourceStack, ResourceHolder, Resource, Coordinate], + to: Union[ResourceStack, CarrierSite, Resource, Coordinate], intermediate_locations: Optional[List[Coordinate]] = None, - resource_offset: Optional[Coordinate] = None, - pickup_offset: Coordinate = Coordinate.zero(), + resource_offset: Coordinate = Coordinate.zero(), destination_offset: Coordinate = Coordinate.zero(), - drop_direction: GripDirection = GripDirection.FRONT, - pickup_direction: GripDirection = GripDirection.FRONT, - get_direction: Optional[GripDirection] = None, - put_direction: Optional[GripDirection] = None, - pickup_distance_from_top: float = 13.2 - 3.33, - **backend_kwargs, + put_direction: GripDirection = GripDirection.FRONT, + get_direction: GripDirection = GripDirection.FRONT, + pickup_distance_from_top: float = 13.2-3.33, + **backend_kwargs ): - """Move a plate to a new location. + """ Move a plate to a new location. A convenience method for :meth:`move_resource`. Examples: Move a plate to into a carrier spot: - >>> await lh.move_plate(plate, plt_car[1]) + >>> lh.move_plate(plate, plt_car[1]) Move a plate to an absolute location: - >>> await lh.move_plate(plate_01, Coordinate(100, 100, 100)) + >>> lh.move_plate(plate_01, Coordinate(100, 100, 100)) Move a lid to another carrier spot, grabbing it from the left side: - >>> await lh.move_plate(plate, plt_car[1], pickup_direction=GripDirection.LEFT) - >>> await lh.move_plate(plate, plt_car[0], drop_direction=GripDirection.LEFT) + >>> lh.move_plate(plate, plt_car[1], get_direction=GripDirection.LEFT) + >>> lh.move_plate(plate, plt_car[0], put_direction=GripDirection.LEFT) Move a resource while visiting a few intermediate locations along the way: - >>> await lh.move_plate(plate, plt_car[1], intermediate_locations=[ + >>> lh.move_plate(plate, plt_car[1], intermediate_locations=[ ... Coordinate(100, 100, 100), ... Coordinate(200, 200, 200), ... ]) Args: - plate: The plate to move. Can be either a Plate object or a ResourceHolder object. - to: The location to move the plate to, either a plate, ResourceHolder or a Coordinate. - pickup_offset: The offset from the resource's origin, optional (rarely necessary). + plate: The plate to move. Can be either a Plate object or a CarrierSite object. + to: The location to move the plate to, either a plate, CarrierSite or a Coordinate. + resource_offset: The offset from the resource's origin, optional (rarely necessary). destination_offset: The offset from the location's origin, optional (rarely necessary). """ - # https://github.com/PyLabRobot/pylabrobot/issues/329 - if resource_offset is not None: - raise NotImplementedError("resource_offset is deprecated, use pickup_offset instead") - if get_direction is not None: - raise NotImplementedError("get_direction is deprecated, use pickup_direction instead") - if put_direction is not None: - raise NotImplementedError("put_direction is deprecated, use drop_direction instead") + if isinstance(to, ResourceStack): + assert to.direction == "z", "Only ResourceStacks with direction 'z' are currently supported" + to_location = to.get_absolute_location(z="top") + elif isinstance(to, Coordinate): + to_location = to + elif isinstance(to, (MFXModule, Tilter)): + to_location = to.get_absolute_location() + to.child_resource_location + elif isinstance(to, PlateCarrierSite): + to_location = to.get_absolute_location() + # Sanity check for equal well clearances / dz + well_dz_set = {round(well.location.z, 2) for well in plate.get_all_children() + if well.category == "well" and well.location is not None} + assert len(well_dz_set) == 1, "All wells must have the same dz" + well_dz = well_dz_set.pop() + # Plate "sinking" logic based on well dz to pedestal relationship + # 1. no pedestal + # 2. pedestal taller than plate.well.dz + # 3. pedestal shorter than plate.well.dz + pedestal_size_z = abs(to.pedestal_size_z) + z_sinking_depth = min(pedestal_size_z, well_dz) + correction_anchor = Coordinate(0, 0, -z_sinking_depth) + to_location += correction_anchor + elif isinstance(to, PlateAdapter): + # Calculate location adjustment of Plate based on PlateAdapter geometry + adjusted_plate_anchor = to.compute_plate_location(plate) + to_location = to.get_absolute_location() + adjusted_plate_anchor + else: + to_location = to.get_absolute_location() await self.move_resource( plate, - to=to, + to=to_location, intermediate_locations=intermediate_locations, pickup_distance_from_top=pickup_distance_from_top, - pickup_offset=pickup_offset, + resource_offset=resource_offset, destination_offset=destination_offset, - pickup_direction=pickup_direction, - drop_direction=drop_direction, - **backend_kwargs, - ) + get_direction=get_direction, + put_direction=put_direction, + **backend_kwargs) + + # Some of the code below should probably be moved to `move_resource` so that is can be shared + # with the `move_lid` convenience method. + plate.unassign() + if isinstance(to, Coordinate): + to_location -= self.deck.location # passed as an absolute location, but stored as relative + self.deck.assign_child_resource(plate, location=to_location) + elif isinstance(to, PlateCarrierSite): # .zero() resources + to.assign_child_resource(plate) + elif isinstance(to, CarrierSite): # .zero() resources + to.assign_child_resource(plate) + elif isinstance(to, (ResourceStack, PlateReader)): # manage its own resources + if isinstance(to, ResourceStack) and to.direction != "z": + raise ValueError("Only ResourceStacks with direction 'z' are currently supported") + to.assign_child_resource(plate) + elif isinstance(to, (MFXModule, Tilter)): + to.assign_child_resource(plate, location=to.child_resource_location) + elif isinstance(to, PlateAdapter): + to.assign_child_resource(plate, location=to.compute_plate_location(plate)) + else: + to.assign_child_resource(plate, location=to_location) def register_callback(self, method_name: str, callback: OperationCallback): """Registers a callback for a specific method.""" @@ -2191,13 +1861,7 @@ def register_callback(self, method_name: str, callback: OperationCallback): raise RuntimeError(error_message) self._callbacks[method_name] = callback - def _trigger_callback( - self, - method_name: str, - *args, - error: Optional[Exception] = None, - **kwargs, - ): + def _trigger_callback(self, method_name: str, *args, error: Optional[Exception] = None, **kwargs): """Triggers the callback associated with a method, if any. NB: If an error exists it will be passed to the callback instead of being raised. @@ -2211,12 +1875,9 @@ def _trigger_callback( def callbacks(self): return self._callbacks - def serialize(self): - return {**Resource.serialize(self), **Machine.serialize(self)} - @classmethod def deserialize(cls, data: dict, allow_marshal: bool = False) -> LiquidHandler: - """Deserialize a liquid handler from a dictionary. + """ Deserialize a liquid handler from a dictionary. Args: data: A dictionary representation of the liquid handler. @@ -2229,7 +1890,7 @@ def deserialize(cls, data: dict, allow_marshal: bool = False) -> LiquidHandler: @classmethod def load(cls, path: str) -> LiquidHandler: - """Load a liquid handler from a file. + """ Load a liquid handler from a file. Args: path: The path to the file to load from. @@ -2238,38 +1899,17 @@ def load(cls, path: str) -> LiquidHandler: with open(path, "r", encoding="utf-8") as f: return cls.deserialize(json.load(f)) - async def prepare_for_manual_channel_operation(self, channel: int): - assert 0 <= channel < self.backend.num_channels, f"Invalid channel: {channel}" - await self.backend.prepare_for_manual_channel_operation(channel=channel) - - async def move_channel_x(self, channel: int, x: float): - """Move channel to absolute x position""" - assert 0 <= channel < self.backend.num_channels, f"Invalid channel: {channel}" - await self.backend.move_channel_x(channel=channel, x=x) - - async def move_channel_y(self, channel: int, y: float): - """Move channel to absolute y position""" - assert 0 <= channel < self.backend.num_channels, f"Invalid channel: {channel}" - await self.backend.move_channel_y(channel=channel, y=y) - - async def move_channel_z(self, channel: int, z: float): - """Move channel to absolute z position""" - assert 0 <= channel < self.backend.num_channels, f"Invalid channel: {channel}" - await self.backend.move_channel_z(channel=channel, z=z) - # -- Resource methods -- def assign_child_resource( self, resource: Resource, - location: Optional[Coordinate], + location: Coordinate, reassign: bool = True, ): - """Not implement on LiquidHandler, since the deck is managed by the :attr:`deck` attribute.""" - raise NotImplementedError( - "Cannot assign child resource to liquid handler. Use " - "lh.deck.assign_child_resource() instead." - ) + """ Not implement on LiquidHandler, since the deck is managed by the :attr:`deck` attribute. """ + raise NotImplementedError("Cannot assign child resource to liquid handler. Use " + "lh.deck.assign_child_resource() instead.") class OperationCallback(Protocol): diff --git a/pylabrobot/liquid_handling/parameter_sets/star.py b/pylabrobot/liquid_handling/parameter_sets/star.py index aefb08f684..d32e4da7ab 100644 --- a/pylabrobot/liquid_handling/parameter_sets/star.py +++ b/pylabrobot/liquid_handling/parameter_sets/star.py @@ -1,7 +1,10 @@ import dataclasses from typing import Optional +import warnings + from pylabrobot.liquid_handling.parameter_sets.parameter_set import ParameterSet from pylabrobot.liquid_handling.backends.hamilton.STAR import STAR +from pylabrobot.liquid_handling.liquid_classes.hamilton.base import HamiltonLiquidClass @dataclasses.dataclass @@ -40,7 +43,7 @@ def make_asp_kwargs(self) -> dict[str, float]: "jet": self.aspiration_jet, "blow_out": self.aspiration_blow_out, "flow_rates": self.aspiration_flow_rates, - "homogenization_speed": self.aspiration_mix_flow_rates, + "mix_speed": self.aspiration_mix_flow_rates, "transport_air_volume": self.transport_air_volumes, "swap_speed": self.aspiration_swap_speeds, "settling_time": self.aspiration_settling_times, @@ -62,3 +65,50 @@ def make_disp_kwargs(self) -> dict[str, float]: "blow_out_air_volume": self.blow_out_air_volumes, "lld_mode": self.dispense_lld_modes, } + + @classmethod + def from_hamilton_liquid_class( + cls, + hlc: HamiltonLiquidClass, + jet: Optional[list[bool]] = None, + blow_out: Optional[list[bool]] = None, + aspiration_lld_modes: Optional[list[STAR.LLDMode]] = None, + dispense_lld_modes: Optional[list[STAR.LLDMode]] = None, + num_channels: int = 8, + ): + warnings.warn("This method is deprecated. Hamilton liquid classes will be removed soon.", + DeprecationWarning) + + if jet is not None and len(jet) != num_channels: + raise ValueError(f"jet must have length {num_channels}") + if blow_out is not None and len(blow_out) != num_channels: + raise ValueError(f"blow_out must have length {num_channels}") + if aspiration_lld_modes is not None and len(aspiration_lld_modes) != num_channels: + raise ValueError(f"aspiration_lld_modes must have length {num_channels}") + if dispense_lld_modes is not None and len(dispense_lld_modes) != num_channels: + raise ValueError(f"dispense_lld_modes must have length {num_channels}") + if not hlc.aspiration_air_transport_volume == hlc.dispense_air_transport_volume: + raise ValueError("Different transport air volumes not supported.") + if not hlc.aspiration_blow_out_volume == hlc.dispense_blow_out_volume: + raise ValueError("Different blow out volumes not supported.") + + return cls( + blow_out_air_volumes=[hlc.aspiration_blow_out_volume] * num_channels, + transport_air_volumes=[hlc.aspiration_air_transport_volume] * num_channels, + aspiration_blow_out=[blow_out] * num_channels, + aspiration_jet=[jet] * num_channels, + aspiration_flow_rates=[hlc.aspiration_flow_rate] * num_channels, + aspiration_mix_flow_rates=[hlc.aspiration_mix_flow_rate] * num_channels, + aspiration_swap_speeds=[hlc.aspiration_swap_speed] * num_channels, + aspiration_settling_times=[hlc.aspiration_settling_time] * num_channels, + aspiration_clot_retract_heights=[hlc.aspiration_clot_retract_height] * num_channels, + aspiration_lld_modes=aspiration_lld_modes, + dispense_blow_out=[blow_out] * num_channels, + dispense_jet=[jet] * num_channels, + dispense_flow_rates=[hlc.dispense_flow_rate] * num_channels, + dispense_mix_speeds=[hlc.dispense_mode] * num_channels, + dispense_swap_speeds=[hlc.dispense_swap_speed] * num_channels, + dispense_settling_times=[hlc.dispense_settling_time] * num_channels, + dispense_stop_back_volumes=[hlc.dispense_stop_back_volume] * num_channels, + dispense_lld_modes=dispense_lld_modes, + ) From 395c94ba6bb88a6c31d3eba763c4799773bab872 Mon Sep 17 00:00:00 2001 From: Rick Wierenga Date: Thu, 26 Sep 2024 19:26:00 -0700 Subject: [PATCH 11/18] all except 96, and vantage --- .../backends/hamilton/STAR_tests.py | 25 ++++++++++++------- .../liquid_classes/hamilton/base.py | 22 ++++++++++++++++ .../liquid_handling/parameter_sets/star.py | 6 ++--- 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py b/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py index dda8ffe98a..20e5196357 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py +++ b/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py @@ -6,7 +6,8 @@ from pylabrobot.liquid_handling.standard import Pickup, GripDirection from pylabrobot.liquid_handling.liquid_classes.hamilton.star import ( StandardVolumeFilter_Water_DispenseSurface, - StandardVolumeFilter_Water_DispenseJet_Empty) + StandardVolumeFilter_Water_DispenseJet_Empty, + HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty) from pylabrobot.liquid_handling.parameter_sets.star import STARParameterSet from pylabrobot.plate_reading import PlateReader from pylabrobot.plate_reading.plate_reader_tests import MockPlateReaderBackend @@ -491,7 +492,6 @@ async def test_dispense_single_resource(self): hlc = StandardVolumeFilter_Water_DispenseJet_Empty ps = STARParameterSet.from_hamilton_liquid_class(hlc, num_channels=5, jet=[True]*5, blow_out=[True]*5) - print(ps.make_disp_kwargs()) corrected_vol = hlc.compute_corrected_volume(10) with no_volume_tracking(): await self.lh.dispense([self.bb]*5, vols=[corrected_vol]*5, liquid_height=[1]*5, @@ -513,10 +513,12 @@ async def test_single_channel_dispense(self): self.lh.update_head_state({0: self.tip_rack.get_tip("A1")}) assert self.plate.lid is not None self.plate.lid.unassign() + hlc = StandardVolumeFilter_Water_DispenseJet_Empty + ps = STARParameterSet.from_hamilton_liquid_class(hlc, num_channels=1, + jet=[True]*1, blow_out=[True]*1) + corrected_vol = hlc.compute_corrected_volume(100) with no_volume_tracking(): - corrected_vol = self.hlc.compute_corrected_volume(100) - await self.lh.dispense(self.plate["A1"], vols=[corrected_vol], - jet=[True], blow_out=[True]) + await self.lh.dispense(self.plate["A1"], vols=[corrected_vol], **ps.make_disp_kwargs()) self._assert_command_sent_once( "C0DSid0002dm1 1&tm1 0&xp02983 00000&yp1457 0000&zx1866 1866&lp2000 2000&zl1866 1866&" "po0100 0100&ip0000 0000&it0 0&fp0000 0000&zu0032 0032&zr06180 06180&th2450te2450" @@ -530,9 +532,12 @@ async def test_multi_channel_dispense(self): # TODO: Hamilton liquid classes assert self.plate.lid is not None self.plate.lid.unassign() + hlc = StandardVolumeFilter_Water_DispenseJet_Empty + ps = STARParameterSet.from_hamilton_liquid_class(hlc, num_channels=2, + jet=[True]*2, blow_out=[True]*2) + corrected_vol = hlc.compute_corrected_volume(100) with no_volume_tracking(): - corrected_vol = self.hlc.compute_corrected_volume(100) - await self.lh.dispense(self.plate["A1:B1"], vols=[corrected_vol]*2, jet=[True]*2, blow_out=[True]*2) + await self.lh.dispense(self.plate["A1:B1"], vols=[corrected_vol]*2, **ps.make_disp_kwargs()) self._assert_command_sent_once( "C0DSid0002dm1 1 1&tm1 1 0&xp02983 02983 00000&yp1457 1367 0000&zx1866 1866 1866&lp2000 2000 " @@ -580,8 +585,10 @@ async def test_core_96_aspirate(self): # TODO: Hamilton liquid classes assert self.plate.lid is not None self.plate.lid.unassign() - corrected_volume = self.hlc.compute_corrected_volume(100) # need different liquid class - await self.lh.aspirate96(self.plate, volume=corrected_volume) + hlc = HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty + ps = STARParameterSet.from_hamilton_liquid_class(hlc) + corrected_volume = hlc.compute_corrected_volume(100) # need different liquid class + await self.lh.aspirate96(self.plate, volume=corrected_volume, **ps.make_asp96_kwargs()) # volume used to be 01072, but that was generated using a non-core liquid class. self._assert_command_sent_once( diff --git a/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py b/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py index ed11a92acf..0f04b17b8e 100644 --- a/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py +++ b/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py @@ -111,3 +111,25 @@ def serialize(self) -> Dict[str, Any]: def copy(self) -> "HamiltonLiquidClass": return HamiltonLiquidClass(**self.serialize()) + + def create_asp_kwargs(self, num_channels: int): + return { + "flow_rates": [self.aspiration_flow_rate] * num_channels, + "mix_speed": [self.aspiration_mix_flow_rate] * num_channels, + "transport_air_volume": [self.aspiration_air_transport_volume] * num_channels, + "blow_out_air_volume": [self.aspiration_blow_out_volume] * num_channels, + "swap_speed": [self.aspiration_swap_speed] * num_channels, + "settling_time": [self.aspiration_settling_time] * num_channels, + "clot_detection_height": [self.aspiration_clot_retract_height] * num_channels, + } + + def create_disp_kwargs(self, num_channels: int): + return { + "flow_rates": [self.dispense_flow_rate] * num_channels, + "mix_speed": [self.dispense_mix_flow_rate] * num_channels, + "transport_air_volume": [self.dispense_air_transport_volume] * num_channels, + "blow_out_air_volume": [self.dispense_blow_out_volume] * num_channels, + "swap_speed": [self.dispense_swap_speed] * num_channels, + "settling_time": [self.dispense_settling_time] * num_channels, + "stop_back_volume": [self.dispense_stop_back_volume] * num_channels, + } diff --git a/pylabrobot/liquid_handling/parameter_sets/star.py b/pylabrobot/liquid_handling/parameter_sets/star.py index d32e4da7ab..618e069fe6 100644 --- a/pylabrobot/liquid_handling/parameter_sets/star.py +++ b/pylabrobot/liquid_handling/parameter_sets/star.py @@ -38,7 +38,7 @@ class STARParameterSet(ParameterSet): dispense_stop_back_volumes: Optional[list[float]] dispense_lld_modes: Optional[list[STAR.LLDMode]] - def make_asp_kwargs(self) -> dict[str, float]: + def make_asp_kwargs(self) -> dict[str, list[float]]: return { "jet": self.aspiration_jet, "blow_out": self.aspiration_blow_out, @@ -52,7 +52,7 @@ def make_asp_kwargs(self) -> dict[str, float]: "lld_mode": self.aspiration_lld_modes, } - def make_disp_kwargs(self) -> dict[str, float]: + def make_disp_kwargs(self) -> dict[str, list[float]]: return { "jet": self.dispense_jet, "blow_out": self.dispense_blow_out, @@ -106,7 +106,7 @@ def from_hamilton_liquid_class( dispense_blow_out=[blow_out] * num_channels, dispense_jet=[jet] * num_channels, dispense_flow_rates=[hlc.dispense_flow_rate] * num_channels, - dispense_mix_speeds=[hlc.dispense_mode] * num_channels, + dispense_mix_speeds=[hlc.dispense_mix_flow_rate] * num_channels, dispense_swap_speeds=[hlc.dispense_swap_speed] * num_channels, dispense_settling_times=[hlc.dispense_settling_time] * num_channels, dispense_stop_back_volumes=[hlc.dispense_stop_back_volume] * num_channels, From 63a06314b26fca2a57f5386c667d0bf56c7a3352 Mon Sep 17 00:00:00 2001 From: Rick Wierenga Date: Fri, 27 Sep 2024 10:15:24 -0700 Subject: [PATCH 12/18] fix star tests without parameterset --- .../liquid_handling/backends/hamilton/STAR.py | 110 ++++++++---------- .../backends/hamilton/STAR_tests.py | 46 +++----- .../liquid_classes/hamilton/base.py | 31 ++++- 3 files changed, 92 insertions(+), 95 deletions(-) diff --git a/pylabrobot/liquid_handling/backends/hamilton/STAR.py b/pylabrobot/liquid_handling/backends/hamilton/STAR.py index f3083e1e71..f8d0c15bea 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/STAR.py +++ b/pylabrobot/liquid_handling/backends/hamilton/STAR.py @@ -1436,8 +1436,6 @@ async def aspirate( self, ops: List[Aspiration], use_channels: List[int], - jet: Optional[List[bool]] = None, - blow_out: Optional[List[bool]] = None, lld_search_height: Optional[List[float]] = None, clot_detection_height: Optional[List[float]] = None, pull_out_distance_transport_air: Optional[List[float]] = None, @@ -1487,9 +1485,6 @@ async def aspirate( Args: ops: The aspiration operations to perform. use_channels: The channels to use for the operations. - jet: whether to search for a jet liquid class. Only used on dispense. Default is False. - blow_out: whether to blow out air. Only used on dispense. Note that in the VENUS Liquid - Editor, this is called "empty". Default is False. lld_search_height: The height to start searching for the liquid level when using LLD. clot_detection_height: Unknown, but probably the height to search for clots when doing LLD. @@ -1550,11 +1545,6 @@ async def aspirate( n = len(ops) - if jet is None: - jet = [False] * n - if blow_out is None: - blow_out = [False] * n - self._assert_valid_resources([op.resource for op in ops]) well_bottoms = [op.resource.get_absolute_location().z + op.offset.z + \ @@ -1935,8 +1925,6 @@ async def drop_tips96( async def aspirate96( self, aspiration: Union[AspirationPlate, AspirationContainer], - jet: bool = False, - blow_out: bool = False, use_lld: bool = False, liquid_height: float = 0, @@ -1962,7 +1950,7 @@ async def aspirate96( mix_cycles: int = 0, mix_position_from_liquid_surface: float = 0, surface_following_distance_during_mix: float = 0, - speed_of_mix: float = 120.0, + mix_speed: float = 120.0, limit_curve_index: int = 0, ): """ Aspirate using the Core96 head. @@ -1970,11 +1958,6 @@ async def aspirate96( Args: aspiration: The aspiration to perform. - jet: Whether to search for a jet liquid class. Only used on dispense. - blow_out: Whether to use "blow out" dispense mode. Only used on dispense. Note that this is - labelled as "empty" in the VENUS liquid editor, but "blow out" in the firmware - documentation. - use_lld: If True, use gamma liquid level detection. If False, use liquid height. liquid_height: The height of the liquid above the bottom of the well, in millimeters. air_transport_retract_dist: The distance to retract after aspirating, in millimeters. @@ -2003,7 +1986,7 @@ async def aspirate96( liquid surface. surface_following_distance_during_mix: The distance to follow the liquid surface during mix. - speed_of_mix: The speed of mix. + mix_speed: The speed of mix. limit_curve_index: The index of the limit curve to use. """ @@ -2012,9 +1995,6 @@ async def aspirate96( assert self.core96_head_installed, "96 head must be installed" - if jet or blow_out: - raise NotImplementedError("jet and blow out are not implemented for aspirate96 yet") - # get the first well and tip as representatives if isinstance(aspiration, AspirationPlate): top_left_well = aspiration.wells[0] @@ -2025,28 +2005,25 @@ async def aspirate96( liquid_height = position.z + liquid_height - transport_air_volume = transport_air_volume or 0 - blow_out_air_volume = aspiration.blow_out_air_volume or 0 - flow_rate = aspiration.flow_rate or 250 - swap_speed = swap_speed or 100 - settling_time = settling_time or 0.5 - speed_of_mix = speed_of_mix or 10.0 + if transport_air_volume is None: + transport_air_volume = 0 + if aspiration.blow_out_air_volume is None: + blow_out_air_volume = 0 + else: + blow_out_air_volume = aspiration.blow_out_air_volume + if aspiration.flow_rate is None: + flow_rate = 250 + else: + flow_rate = aspiration.flow_rate + if swap_speed is None: + swap_speed = 100 + if settling_time is None: + settling_time = 0.5 + if mix_speed is None: + mix_speed = 10.0 channel_pattern = [True]*12*8 - # Was this ever true? Just copied it over from pyhamilton. Could have something to do with - # the liquid classes and whether blow_out mode is enabled. - # # Unfortunately, `blow_out_air_volume` does not work correctly, so instead we aspirate air - # # manually. - # if blow_out_air_volume is not None and blow_out_air_volume > 0: - # await self.aspirate_core_96( - # x_position=int(position.x * 10), - # y_positions=int(position.y * 10), - # lld_mode=0, - # liquid_surface_at_function_without_lld=int((liquid_height + 30) * 10), - # aspiration_volumes=int(blow_out_air_volume * 10) - # ) - return await self.aspirate_core_96( x_position=round(position.x * 10), x_direction=0, @@ -2082,7 +2059,7 @@ async def aspirate96( round(mix_position_from_liquid_surface * 10), surface_following_distance_during_mix= round(surface_following_distance_during_mix * 10), - speed_of_mix=round(speed_of_mix * 10), + mix_speed=round(mix_speed * 10), channel_pattern=channel_pattern, limit_curve_index=limit_curve_index, tadm_algorithm=False, @@ -2119,7 +2096,7 @@ async def dispense96( mixing_cycles: int = 0, mixing_position_from_liquid_surface: float = 0, surface_following_distance_during_mixing: float = 0, - speed_of_mixing: float = 120.0, + mix_speed: float = 120.0, limit_curve_index: int = 0, cut_off_speed: float = 5.0, stop_back_volume: float = 0, @@ -2155,7 +2132,7 @@ async def dispense96( mixing_cycles: Mixing cycles. mixing_position_from_liquid_surface: Mixing position from liquid surface, in mm. surface_following_distance_during_mixing: Surface following distance during mixing, in mm. - speed_of_mixing: Speed of mixing, in ul/s. + mix_speed: Speed of mixing, in ul/s. limit_curve_index: Limit curve index. cut_off_speed: Unknown. stop_back_volume: Unknown. @@ -2164,9 +2141,6 @@ async def dispense96( if hlc is not None: raise NotImplementedError("Hamilton liquid classes are deprecated.") - if jet or blow_out: - raise NotImplementedError("jet and blow out are not implemented for aspirate96 yet") - assert self.core96_head_installed, "96 head must be installed" # get the first well and tip as representatives @@ -2181,12 +2155,22 @@ async def dispense96( dispense_mode = _dispensing_mode_for_op(empty=empty, jet=jet, blow_out=blow_out) - transport_air_volume = transport_air_volume or 0 - blow_out_air_volume = dispense.blow_out_air_volume or 0 - flow_rate = dispense.flow_rate or 120 - swap_speed = swap_speed or 100 - settling_time = settling_time or 5 - speed_of_mixing = speed_of_mixing or 100 + if transport_air_volume is None: + transport_air_volume = 0 + if dispense.blow_out_air_volume is None: + blow_out_air_volume = 0 + else: + blow_out_air_volume = dispense.blow_out_air_volume + if dispense.flow_rate is None: + flow_rate = 120 + else: + flow_rate = dispense.flow_rate + if swap_speed is None: + swap_speed = 100 + if settling_time is None: + settling_time = 5 + if mix_speed is None: + mix_speed = 100 channel_pattern = [True]*12*8 @@ -2222,7 +2206,7 @@ async def dispense96( mixing_cycles=mixing_cycles, mixing_position_from_liquid_surface=round(mixing_position_from_liquid_surface*10), surface_following_distance_during_mixing=round(surface_following_distance_during_mixing*10), - speed_of_mixing=round(speed_of_mixing*10), + mix_speed=round(mix_speed*10), channel_pattern=channel_pattern, limit_curve_index=limit_curve_index, tadm_algorithm=False, @@ -4939,7 +4923,7 @@ async def aspirate_core_96( mix_cycles: int = 0, mix_position_from_liquid_surface: int = 250, surface_following_distance_during_mix: int = 0, - speed_of_mix: int = 1000, + mix_speed: int = 1000, channel_pattern: List[bool] = [True] * 96, limit_curve_index: int = 0, tadm_algorithm: bool = False, @@ -4993,7 +4977,7 @@ async def aspirate_core_96( liquid surface (LLD or absolute terms) [0.1mm]. Must be between 0 and 990. Default 250. surface_following_distance_during_mix: surface following distance during mix [0.1mm]. Must be between 0 and 990. Default 0. - speed_of_mix: Speed of mix [0.1ul/s]. Must be between 3 and 5000. + mix_speed: Speed of mix [0.1ul/s]. Must be between 3 and 5000. Default 1000. todo: TODO: 24 hex chars. Must be between 4 and 5000. limit_curve_index: limit curve index. Must be between 0 and 999. Default 0. @@ -5039,8 +5023,8 @@ async def aspirate_core_96( "mix_position_from_liquid_surface must be between 0 and 990" assert 0 <= surface_following_distance_during_mix <= 990, \ "surface_following_distance_during_mix must be between 0 and 990" - assert 3 <= speed_of_mix <= 5000, \ - "speed_of_mix must be between 3 and 5000" + assert 3 <= mix_speed <= 5000, \ + "mix_speed must be between 3 and 5000" assert 0 <= limit_curve_index <= 999, "limit_curve_index must be between 0 and 999" assert 0 <= recording_mode <= 2, "recording_mode must be between 0 and 2" @@ -5081,7 +5065,7 @@ async def aspirate_core_96( hc=f"{mix_cycles:02}", hp=f"{mix_position_from_liquid_surface:03}", mj=f"{surface_following_distance_during_mix:03}", - hs=f"{speed_of_mix:04}", + hs=f"{mix_speed:04}", cw=channel_pattern_hex, cr=f"{limit_curve_index:03}", cj=tadm_algorithm, @@ -5121,7 +5105,7 @@ async def dispense_core_96( mixing_cycles: int = 0, mixing_position_from_liquid_surface: int = 250, surface_following_distance_during_mixing: int = 0, - speed_of_mixing: int = 1000, + mix_speed: int = 1000, channel_pattern: List[bool] = [True]*12*8, limit_curve_index: int = 0, tadm_algorithm: bool = False, @@ -5178,7 +5162,7 @@ async def dispense_core_96( surface (LLD or absolute terms) [0.1mm]. Must be between 0 and 990. Default 250. surface_following_distance_during_mixing: surface following distance during mixing [0.1mm]. Must be between 0 and 990. Default 0. - speed_of_mixing: Speed of mixing [0.1ul/s]. Must be between 3 and 5000. Default 1000. + mix_speed: Speed of mixing [0.1ul/s]. Must be between 3 and 5000. Default 1000. channel_pattern: list of 96 boolean values limit_curve_index: limit curve index. Must be between 0 and 999. Default 0. tadm_algorithm: TADM algorithm. Default False. @@ -5225,7 +5209,7 @@ async def dispense_core_96( "mixing_position_from_liquid_surface must be between 0 and 990" assert 0 <= surface_following_distance_during_mixing <= 990, \ "surface_following_distance_during_mixing must be between 0 and 990" - assert 3 <= speed_of_mixing <= 5000, "speed_of_mixing must be between 3 and 5000" + assert 3 <= mix_speed <= 5000, "mix_speed must be between 3 and 5000" assert 0 <= limit_curve_index <= 999, "limit_curve_index must be between 0 and 999" assert 0 <= recording_mode <= 2, "recording_mode must be between 0 and 2" @@ -5267,7 +5251,7 @@ async def dispense_core_96( hc=f"{mixing_cycles:02}", hp=f"{mixing_position_from_liquid_surface:03}", mj=f"{surface_following_distance_during_mixing:03}", - hs=f"{speed_of_mixing:04}", + hs=f"{mix_speed:04}", cw=channel_pattern_hex, cr=f"{limit_curve_index:03}", cj=tadm_algorithm, diff --git a/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py b/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py index 20e5196357..8a35469d36 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py +++ b/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py @@ -8,7 +8,6 @@ StandardVolumeFilter_Water_DispenseSurface, StandardVolumeFilter_Water_DispenseJet_Empty, HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty) -from pylabrobot.liquid_handling.parameter_sets.star import STARParameterSet from pylabrobot.plate_reading import PlateReader from pylabrobot.plate_reading.plate_reader_tests import MockPlateReaderBackend from pylabrobot.resources import ( @@ -379,10 +378,9 @@ async def test_aspirate56(self): self.plate.lid.unassign() for well in self.plate.get_items(["A1", "B1"]): well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction - ps = STARParameterSet.from_hamilton_liquid_class(self.hlc, num_channels=2) corrected_vol = self.hlc.compute_corrected_volume(100) await self.lh.aspirate(self.plate["A1", "B1"], vols=[corrected_vol, corrected_vol], - use_channels=[4, 5], **ps.make_asp_kwargs()) + use_channels=[4, 5], **self.hlc.make_asp_kwargs(2)) self._assert_command_sent_once("C0ASid0004at0 0 0 0 0 0 0&tm0 0 0 0 1 1 0&xp00000 00000 00000 " "00000 02983 02983 00000&yp0000 0000 0000 0000 1457 1367 0000&th2450te2450lp2000 2000 2000 " "2000 2000 2000 2000&ch000 000 000 000 000 000 000&zl1866 1866 1866 1866 1866 1866 1866&" @@ -406,8 +404,8 @@ async def test_single_channel_aspiration(self): self.plate.lid.unassign() well = self.plate.get_item("A1") well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction - ps = STARParameterSet.from_hamilton_liquid_class(self.hlc, num_channels=1) - await self.lh.aspirate([well], vols=[self.hlc.compute_corrected_volume(100)], **ps.make_asp_kwargs()) + await self.lh.aspirate([well], vols=[self.hlc.compute_corrected_volume(100)], + **self.hlc.make_asp_kwargs(1)) # This passes the test, but is not the real command. self._assert_command_sent_once( @@ -426,9 +424,8 @@ async def test_single_channel_aspiration_liquid_height(self): self.plate.lid.unassign() well = self.plate.get_item("A1") well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction - ps = STARParameterSet.from_hamilton_liquid_class(self.hlc, num_channels=1) await self.lh.aspirate([well], vols=[self.hlc.compute_corrected_volume(100)], - liquid_height=[10], **ps.make_asp_kwargs()) + liquid_height=[10], **self.hlc.make_asp_kwargs(1)) # This passes the test, but is not the real command. self._assert_command_sent_once( @@ -448,9 +445,9 @@ async def test_multi_channel_aspiration(self): wells = self.plate.get_items("A1:B1") for well in wells: well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction - ps = STARParameterSet.from_hamilton_liquid_class(self.hlc, num_channels=2) corrected_vol = self.hlc.compute_corrected_volume(100) - await self.lh.aspirate(self.plate["A1:B1"], vols=[corrected_vol]*2, **ps.make_asp_kwargs()) + await self.lh.aspirate(self.plate["A1:B1"], vols=[corrected_vol]*2, + **self.hlc.make_asp_kwargs(2)) # This passes the test, but is not the real command. self._assert_command_sent_once( @@ -466,11 +463,10 @@ async def test_multi_channel_aspiration(self): async def test_aspirate_single_resource(self): self.lh.update_head_state({i: self.tip_rack.get_tip(i) for i in range(5)}) - ps = STARParameterSet.from_hamilton_liquid_class(self.hlc, num_channels=5) corrected_vol = self.hlc.compute_corrected_volume(10) with no_volume_tracking(): await self.lh.aspirate([self.bb]*5,vols=[corrected_vol]*5, use_channels=[0,1,2,3,4], - liquid_height=[1]*5, **ps.make_asp_kwargs()) + liquid_height=[1]*5, **self.hlc.make_asp_kwargs(5)) self._assert_command_sent_once( "C0ASid0002at0 0 0 0 0 0&tm1 1 1 1 1 0&xp04865 04865 04865 04865 04865 00000&yp2098 1962 " "1825 1688 1552 0000&th2450te2450lp2000 2000 2000 2000 2000 2000&ch000 000 000 000 000 000&" @@ -490,12 +486,10 @@ async def test_aspirate_single_resource(self): async def test_dispense_single_resource(self): self.lh.update_head_state({i: self.tip_rack.get_tip(i) for i in range(5)}) hlc = StandardVolumeFilter_Water_DispenseJet_Empty - ps = STARParameterSet.from_hamilton_liquid_class(hlc, num_channels=5, - jet=[True]*5, blow_out=[True]*5) corrected_vol = hlc.compute_corrected_volume(10) with no_volume_tracking(): await self.lh.dispense([self.bb]*5, vols=[corrected_vol]*5, liquid_height=[1]*5, - **ps.make_disp_kwargs()) + jet=[True]*5, blow_out=[True]*5, **hlc.make_disp_kwargs(5)) self._assert_command_sent_once( "C0DSid0002dm1 1 1 1 1 1&tm1 1 1 1 1 0&xp04865 04865 04865 04865 04865 00000&yp2098 1962 " "1825 1688 1552 0000&zx1200 1200 1200 1200 1200 1200&lp2000 2000 2000 2000 2000 2000&zl1210 " @@ -514,11 +508,10 @@ async def test_single_channel_dispense(self): assert self.plate.lid is not None self.plate.lid.unassign() hlc = StandardVolumeFilter_Water_DispenseJet_Empty - ps = STARParameterSet.from_hamilton_liquid_class(hlc, num_channels=1, - jet=[True]*1, blow_out=[True]*1) corrected_vol = hlc.compute_corrected_volume(100) with no_volume_tracking(): - await self.lh.dispense(self.plate["A1"], vols=[corrected_vol], **ps.make_disp_kwargs()) + await self.lh.dispense(self.plate["A1"], vols=[corrected_vol], jet=[True], blow_out=[True], + **hlc.make_disp_kwargs(1)) self._assert_command_sent_once( "C0DSid0002dm1 1&tm1 0&xp02983 00000&yp1457 0000&zx1866 1866&lp2000 2000&zl1866 1866&" "po0100 0100&ip0000 0000&it0 0&fp0000 0000&zu0032 0032&zr06180 06180&th2450te2450" @@ -533,11 +526,10 @@ async def test_multi_channel_dispense(self): assert self.plate.lid is not None self.plate.lid.unassign() hlc = StandardVolumeFilter_Water_DispenseJet_Empty - ps = STARParameterSet.from_hamilton_liquid_class(hlc, num_channels=2, - jet=[True]*2, blow_out=[True]*2) corrected_vol = hlc.compute_corrected_volume(100) with no_volume_tracking(): - await self.lh.dispense(self.plate["A1:B1"], vols=[corrected_vol]*2, **ps.make_disp_kwargs()) + await self.lh.dispense(self.plate["A1:B1"], vols=[corrected_vol]*2, jet=[True]*2, + blow_out=[True]*2, **hlc.make_disp_kwargs(2)) self._assert_command_sent_once( "C0DSid0002dm1 1 1&tm1 1 0&xp02983 02983 00000&yp1457 1367 0000&zx1866 1866 1866&lp2000 2000 " @@ -586,9 +578,8 @@ async def test_core_96_aspirate(self): assert self.plate.lid is not None self.plate.lid.unassign() hlc = HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty - ps = STARParameterSet.from_hamilton_liquid_class(hlc) - corrected_volume = hlc.compute_corrected_volume(100) # need different liquid class - await self.lh.aspirate96(self.plate, volume=corrected_volume, **ps.make_asp96_kwargs()) + corrected_volume = hlc.compute_corrected_volume(100) + await self.lh.aspirate96(self.plate, volume=corrected_volume, **hlc.make_asp96_kwargs()) # volume used to be 01072, but that was generated using a non-core liquid class. self._assert_command_sent_once( @@ -603,13 +594,14 @@ async def test_core_96_dispense(self): await self.lh.pick_up_tips96(self.tip_rack2) # pick up high volume tips if self.plate.lid is not None: self.plate.lid.unassign() - corrected_volume = self.hlc.compute_corrected_volume(100) # need different liquid class - await self.lh.aspirate96(self.plate, corrected_volume) # aspirate first + hlc = HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty + corrected_volume = hlc.compute_corrected_volume(100) + await self.lh.aspirate96(self.plate, corrected_volume, **hlc.make_asp96_kwargs()) with no_volume_tracking(): - await self.lh.dispense96(self.plate, corrected_volume) + await self.lh.dispense96(self.plate, corrected_volume, blow_out=True, + **hlc.make_disp96_kwargs()) - # volume used to be 01072, but that was generated using a non-core liquid class. self._assert_command_sent_once( "C0EDid0001da3xs02983xd0yh1457zh2450ze2450lz1999zt1866zm1866iw000ix0fh000df01083dg1200vt050" "bv00000cm0cs1bs0020wh00hv00000hc00hp000hs1200es0050ev000zv0032ej00zq06180mj000cj0cx0cr000" diff --git a/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py b/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py index 0f04b17b8e..d9db91d43a 100644 --- a/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py +++ b/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py @@ -1,4 +1,4 @@ -from typing import Any, Dict +from typing import Any, Dict, List class HamiltonLiquidClass: @@ -111,8 +111,8 @@ def serialize(self) -> Dict[str, Any]: def copy(self) -> "HamiltonLiquidClass": return HamiltonLiquidClass(**self.serialize()) - - def create_asp_kwargs(self, num_channels: int): + + def make_asp_kwargs(self, num_channels: int) -> Dict[str, List[Any]]: return { "flow_rates": [self.aspiration_flow_rate] * num_channels, "mix_speed": [self.aspiration_mix_flow_rate] * num_channels, @@ -122,8 +122,8 @@ def create_asp_kwargs(self, num_channels: int): "settling_time": [self.aspiration_settling_time] * num_channels, "clot_detection_height": [self.aspiration_clot_retract_height] * num_channels, } - - def create_disp_kwargs(self, num_channels: int): + + def make_disp_kwargs(self, num_channels: int) -> Dict[str, List[Any]]: return { "flow_rates": [self.dispense_flow_rate] * num_channels, "mix_speed": [self.dispense_mix_flow_rate] * num_channels, @@ -133,3 +133,24 @@ def create_disp_kwargs(self, num_channels: int): "settling_time": [self.dispense_settling_time] * num_channels, "stop_back_volume": [self.dispense_stop_back_volume] * num_channels, } + + def make_asp96_kwargs(self) -> Dict[str, Any]: + return { + "flow_rate": self.aspiration_flow_rate, + "mix_speed": self.aspiration_mix_flow_rate, + "transport_air_volume": self.aspiration_air_transport_volume, + "blow_out_air_volume": self.aspiration_blow_out_volume, + "swap_speed": self.aspiration_swap_speed, + "settling_time": self.aspiration_settling_time, + } + + def make_disp96_kwargs(self) -> Dict[str, Any]: + return { + "flow_rate": self.dispense_flow_rate, + "mix_speed": self.dispense_mix_flow_rate, + "transport_air_volume": self.dispense_air_transport_volume, + "blow_out_air_volume": self.dispense_blow_out_volume, + "swap_speed": self.dispense_swap_speed, + "settling_time": self.dispense_settling_time, + "stop_back_volume": self.dispense_stop_back_volume, + } From 623d370a73e9ee3a716c9c65fb62691eea41ad72 Mon Sep 17 00:00:00 2001 From: Rick Wierenga Date: Fri, 27 Sep 2024 10:20:34 -0700 Subject: [PATCH 13/18] remove parameter set --- .../parameter_sets/__init__.py | 2 - .../parameter_sets/parameter_set.py | 13 -- .../liquid_handling/parameter_sets/star.py | 114 ------------------ 3 files changed, 129 deletions(-) delete mode 100644 pylabrobot/liquid_handling/parameter_sets/__init__.py delete mode 100644 pylabrobot/liquid_handling/parameter_sets/parameter_set.py delete mode 100644 pylabrobot/liquid_handling/parameter_sets/star.py diff --git a/pylabrobot/liquid_handling/parameter_sets/__init__.py b/pylabrobot/liquid_handling/parameter_sets/__init__.py deleted file mode 100644 index b1944dce91..0000000000 --- a/pylabrobot/liquid_handling/parameter_sets/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .parameter_set import ParameterSet -from .star import STARParameterSet diff --git a/pylabrobot/liquid_handling/parameter_sets/parameter_set.py b/pylabrobot/liquid_handling/parameter_sets/parameter_set.py deleted file mode 100644 index ecb50f8649..0000000000 --- a/pylabrobot/liquid_handling/parameter_sets/parameter_set.py +++ /dev/null @@ -1,13 +0,0 @@ -import abc -import dataclasses - - -@dataclasses.dataclass -class ParameterSet(abc.ABC): - @abc.abstractmethod - def make_asp_kwargs(self) -> dict: - pass - - @abc.abstractmethod - def make_disp_kwargs(self) -> dict: - pass diff --git a/pylabrobot/liquid_handling/parameter_sets/star.py b/pylabrobot/liquid_handling/parameter_sets/star.py deleted file mode 100644 index 618e069fe6..0000000000 --- a/pylabrobot/liquid_handling/parameter_sets/star.py +++ /dev/null @@ -1,114 +0,0 @@ -import dataclasses -from typing import Optional -import warnings - -from pylabrobot.liquid_handling.parameter_sets.parameter_set import ParameterSet -from pylabrobot.liquid_handling.backends.hamilton.STAR import STAR -from pylabrobot.liquid_handling.liquid_classes.hamilton.base import HamiltonLiquidClass - - -@dataclasses.dataclass -class STARParameterSet(ParameterSet): - """ A collection of parameters for a liquid transfer on a Hamilton STAR. - - A rough adoption of HamiltonLiquidClass. - - This includes blow_out and jet configuration - - Parameters are lists to allow channel-specific values. - - `blow_out_air_volumes` is shared between aspiration and dispense. - """ - - blow_out_air_volumes: Optional[list[float]] - transport_air_volumes: Optional[list[float]] - - aspiration_blow_out: Optional[list[bool]] - aspiration_jet: Optional[list[bool]] - aspiration_flow_rates: Optional[list[float]] - aspiration_mix_flow_rates: Optional[list[float]] - aspiration_swap_speeds: Optional[list[float]] - aspiration_settling_times: Optional[list[float]] - aspiration_clot_retract_heights: Optional[list[float]] - aspiration_lld_modes: Optional[list[STAR.LLDMode]] - - dispense_blow_out: Optional[list[bool]] - dispense_jet: Optional[list[bool]] - dispense_flow_rates: Optional[list[float]] - dispense_mix_speeds: Optional[list[float]] - dispense_swap_speeds: Optional[list[float]] - dispense_settling_times: Optional[list[float]] - dispense_stop_back_volumes: Optional[list[float]] - dispense_lld_modes: Optional[list[STAR.LLDMode]] - - def make_asp_kwargs(self) -> dict[str, list[float]]: - return { - "jet": self.aspiration_jet, - "blow_out": self.aspiration_blow_out, - "flow_rates": self.aspiration_flow_rates, - "mix_speed": self.aspiration_mix_flow_rates, - "transport_air_volume": self.transport_air_volumes, - "swap_speed": self.aspiration_swap_speeds, - "settling_time": self.aspiration_settling_times, - "clot_detection_height": self.aspiration_clot_retract_heights, - "blow_out_air_volume": self.blow_out_air_volumes, - "lld_mode": self.aspiration_lld_modes, - } - - def make_disp_kwargs(self) -> dict[str, list[float]]: - return { - "jet": self.dispense_jet, - "blow_out": self.dispense_blow_out, - "flow_rates": self.dispense_flow_rates, - "mix_speed": self.dispense_mix_speeds, - "transport_air_volume": self.transport_air_volumes, - "swap_speed": self.dispense_swap_speeds, - "settling_time": self.dispense_settling_times, - "stop_back_volume": self.dispense_stop_back_volumes, - "blow_out_air_volume": self.blow_out_air_volumes, - "lld_mode": self.dispense_lld_modes, - } - - @classmethod - def from_hamilton_liquid_class( - cls, - hlc: HamiltonLiquidClass, - jet: Optional[list[bool]] = None, - blow_out: Optional[list[bool]] = None, - aspiration_lld_modes: Optional[list[STAR.LLDMode]] = None, - dispense_lld_modes: Optional[list[STAR.LLDMode]] = None, - num_channels: int = 8, - ): - warnings.warn("This method is deprecated. Hamilton liquid classes will be removed soon.", - DeprecationWarning) - - if jet is not None and len(jet) != num_channels: - raise ValueError(f"jet must have length {num_channels}") - if blow_out is not None and len(blow_out) != num_channels: - raise ValueError(f"blow_out must have length {num_channels}") - if aspiration_lld_modes is not None and len(aspiration_lld_modes) != num_channels: - raise ValueError(f"aspiration_lld_modes must have length {num_channels}") - if dispense_lld_modes is not None and len(dispense_lld_modes) != num_channels: - raise ValueError(f"dispense_lld_modes must have length {num_channels}") - if not hlc.aspiration_air_transport_volume == hlc.dispense_air_transport_volume: - raise ValueError("Different transport air volumes not supported.") - if not hlc.aspiration_blow_out_volume == hlc.dispense_blow_out_volume: - raise ValueError("Different blow out volumes not supported.") - - return cls( - blow_out_air_volumes=[hlc.aspiration_blow_out_volume] * num_channels, - transport_air_volumes=[hlc.aspiration_air_transport_volume] * num_channels, - aspiration_blow_out=[blow_out] * num_channels, - aspiration_jet=[jet] * num_channels, - aspiration_flow_rates=[hlc.aspiration_flow_rate] * num_channels, - aspiration_mix_flow_rates=[hlc.aspiration_mix_flow_rate] * num_channels, - aspiration_swap_speeds=[hlc.aspiration_swap_speed] * num_channels, - aspiration_settling_times=[hlc.aspiration_settling_time] * num_channels, - aspiration_clot_retract_heights=[hlc.aspiration_clot_retract_height] * num_channels, - aspiration_lld_modes=aspiration_lld_modes, - dispense_blow_out=[blow_out] * num_channels, - dispense_jet=[jet] * num_channels, - dispense_flow_rates=[hlc.dispense_flow_rate] * num_channels, - dispense_mix_speeds=[hlc.dispense_mix_flow_rate] * num_channels, - dispense_swap_speeds=[hlc.dispense_swap_speed] * num_channels, - dispense_settling_times=[hlc.dispense_settling_time] * num_channels, - dispense_stop_back_volumes=[hlc.dispense_stop_back_volume] * num_channels, - dispense_lld_modes=dispense_lld_modes, - ) From ee480e770f6313552a806b808ce2f9b2ce6a208e Mon Sep 17 00:00:00 2001 From: Rick Wierenga Date: Fri, 27 Sep 2024 10:25:32 -0700 Subject: [PATCH 14/18] vantage & lint & type --- .../liquid_handling/backends/hamilton/STAR.py | 8 +- .../backends/hamilton/vantage.py | 69 ++- .../backends/hamilton/vantage_tests.py | 428 +++++------------- .../liquid_classes/hamilton/base.py | 2 +- 4 files changed, 157 insertions(+), 350 deletions(-) diff --git a/pylabrobot/liquid_handling/backends/hamilton/STAR.py b/pylabrobot/liquid_handling/backends/hamilton/STAR.py index f8d0c15bea..80586e691c 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/STAR.py +++ b/pylabrobot/liquid_handling/backends/hamilton/STAR.py @@ -2008,11 +2008,11 @@ async def aspirate96( if transport_air_volume is None: transport_air_volume = 0 if aspiration.blow_out_air_volume is None: - blow_out_air_volume = 0 + blow_out_air_volume = 0.0 else: blow_out_air_volume = aspiration.blow_out_air_volume if aspiration.flow_rate is None: - flow_rate = 250 + flow_rate = 250.0 else: flow_rate = aspiration.flow_rate if swap_speed is None: @@ -2158,11 +2158,11 @@ async def dispense96( if transport_air_volume is None: transport_air_volume = 0 if dispense.blow_out_air_volume is None: - blow_out_air_volume = 0 + blow_out_air_volume = 0.0 else: blow_out_air_volume = dispense.blow_out_air_volume if dispense.flow_rate is None: - flow_rate = 120 + flow_rate = 120.0 else: flow_rate = dispense.flow_rate if swap_speed is None: diff --git a/pylabrobot/liquid_handling/backends/hamilton/vantage.py b/pylabrobot/liquid_handling/backends/hamilton/vantage.py index 8dd1b0f3a5..2f5cfad047 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/vantage.py +++ b/pylabrobot/liquid_handling/backends/hamilton/vantage.py @@ -538,8 +538,6 @@ async def aspirate( self, ops: List[Aspiration], use_channels: List[int], - jet: Optional[List[bool]] = None, - blow_out: Optional[List[bool]] = None, hlcs: Optional[List[Optional[HamiltonLiquidClass]]] = None, type_of_aspiration: Optional[List[int]] = None, @@ -595,11 +593,6 @@ async def aspirate( x_positions, y_positions, channels_involved = \ self._ops_to_fw_positions(ops, use_channels) - if jet is None: - jet = [False]*len(ops) - if blow_out is None: - blow_out = [False]*len(ops) - self._assert_valid_resources([op.resource for op in ops]) well_bottoms = [op.resource.get_absolute_location().z + op.offset.z + \ @@ -614,6 +607,8 @@ async def aspirate( flow_rates = [op.flow_rate or 100 for op in ops] blow_out_air_volumes = [op.blow_out_air_volume or 0 for op in ops] + print(mix_speed) + return await self.pip_aspirate( x_position=x_positions, y_position=y_positions, @@ -864,8 +859,6 @@ async def drop_tips96( async def aspirate96( self, aspiration: Union[AspirationPlate, AspirationContainer], - jet: bool = False, - blow_out: bool = False, hlc: Optional[HamiltonLiquidClass] = None, type_of_aspiration: int = 0, @@ -877,7 +870,6 @@ async def aspirate96( immersion_depth: float = 0, surface_following_distance: float = 0, transport_air_volume: Optional[float] = None, - blow_out_air_volume: Optional[float] = None, pre_wetting_volume: float = 0, lld_mode: int = 0, lld_sensitivity: int = 4, @@ -893,19 +885,8 @@ async def aspirate96( tadm_algorithm_on_off: int = 0, recording_mode: int = 0, ): - """ Aspirate from a plate. - - Args: - jet: Whether to find a liquid class with "jet" mode. Only used on dispense. - blow_out: Whether to find a liquid class with "blow out" mode. Only used on dispense. Note - that this is called "empty" in the VENUS liquid editor, but "blow out" in the firmware - documentation. - """ # assert self.core96_head_installed, "96 head must be installed" - if jet is not None or blow_out is not None: - raise NotImplementedError("jet and blow out are not implemented for aspirate96 yet") - if hlc is not None: raise NotImplementedError("hlc is deprecated") @@ -924,11 +905,20 @@ async def aspirate96( liquid_height = position.z + (aspiration.liquid_height or 0) - transport_air_volume = transport_air_volume or 0 - blow_out_air_volume = blow_out_air_volume or 0 - flow_rate = aspiration.flow_rate or 250 - swap_speed = swap_speed or 100 - settling_time = settling_time or 5 + if transport_air_volume is None: + transport_air_volume = 0 + if aspiration.blow_out_air_volume is None: + blow_out_air_volume = 0.0 + else: + blow_out_air_volume = aspiration.blow_out_air_volume + if aspiration.flow_rate is None: + flow_rate = 250.0 + else: + flow_rate = aspiration.flow_rate + if swap_speed is None: + swap_speed = 100 + if settling_time is None: + settling_time = 5 return await self.core96_aspiration_of_liquid( x_position=round(position.x * 10), @@ -987,7 +977,6 @@ async def dispense96( cut_off_speed: float = 250.0, stop_back_volume: float = 0, transport_air_volume: Optional[float] = None, - blow_out_air_volume: Optional[float] = None, lld_mode: int = 0, lld_sensitivity: int = 4, side_touch_off_distance: float = 0, @@ -1036,14 +1025,24 @@ async def dispense96( liquid_height = position.z + (dispense.liquid_height or 0) + 10 - transport_air_volume = transport_air_volume or 0 - blow_out_air_volume = blow_out_air_volume or 0 - flow_rate = dispense.flow_rate or 250 - swap_speed = swap_speed or 100 - settling_time = settling_time or 5 - mix_speed = mix_speed or 100 - type_of_dispensing_mode = type_of_dispensing_mode or \ - _get_dispense_mode(jet=jet, empty=empty, blow_out=blow_out) + if transport_air_volume is None: + transport_air_volume = 0 + if dispense.blow_out_air_volume is None: + blow_out_air_volume = 0.0 + else: + blow_out_air_volume = dispense.blow_out_air_volume + if dispense.flow_rate is None: + flow_rate = 250.0 + else: + flow_rate = dispense.flow_rate + if swap_speed is None: + swap_speed = 100 + if settling_time is None: + settling_time = 5 + if mix_speed is None: + mix_speed = 100 + if type_of_dispensing_mode is None: + type_of_dispensing_mode = _get_dispense_mode(jet=jet, empty=empty, blow_out=blow_out) return await self.core96_dispensing_of_liquid( x_position=round(position.x * 10), diff --git a/pylabrobot/liquid_handling/backends/hamilton/vantage_tests.py b/pylabrobot/liquid_handling/backends/hamilton/vantage_tests.py index 47e4bb8bdd..9552d6c1b2 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/vantage_tests.py +++ b/pylabrobot/liquid_handling/backends/hamilton/vantage_tests.py @@ -1,15 +1,14 @@ -import unittest from typing import Any, List, Optional +import unittest from pylabrobot.liquid_handling import LiquidHandler +from pylabrobot.liquid_handling.liquid_classes.hamilton.vantage import ( + HighVolumeFilter_Water_DispenseSurface_Part, + HighVolumeFilter_Water_DispenseSurface_Empty, + HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty) from pylabrobot.liquid_handling.standard import Pickup from pylabrobot.resources import ( - HT, - LT, - PLT_CAR_L5AC_A00, - TIP_CAR_480_A00, - Coordinate, - Cor_96_wellplate_360ul_Fb, + Coordinate, TIP_CAR_480_A00, PLT_CAR_L5AC_A00, HT_L, LT_L, Cor_96_wellplate_360ul_Fb, ) from pylabrobot.resources.hamilton import VantageDeck @@ -17,118 +16,38 @@ Vantage, VantageFirmwareError, parse_vantage_fw_string, - vantage_response_string_to_error, + vantage_response_string_to_error ) -PICKUP_TIP_FORMAT = { - "xp": "[int]", - "yp": "[int]", - "tm": "[int]", - "tt": "[int]", - "tp": "[int]", - "tz": "[int]", - "th": "[int]", - "ba": "[int]", - "td": "[int]", -} - -DROP_TIP_FORMAT = { - "xp": "[int]", - "yp": "[int]", - "tm": "[int]", - "tp": "[int]", - "tz": "[int]", - "th": "[int]", - "te": "[int]", - "ts": "[int]", - "td": "[int]", -} + +PICKUP_TIP_FORMAT = {"xp": "[int]", "yp": "[int]", "tm": "[int]", "tt": "[int]", "tp": "[int]", + "tz": "[int]", "th": "[int]", "ba": "[int]", "td": "[int]"} + +DROP_TIP_FORMAT = {"xp": "[int]", "yp": "[int]", "tm": "[int]", "tp": "[int]", "tz": "[int]", + "th": "[int]", "te": "[int]", "ts": "[int]", "td": "[int]"} # "dj": "int" = side_touch_off_distance, only documented for dispense, but for some reason VoV also # sends it for aspirate. ASPIRATE_FORMAT = { - "at": "[int]", - "tm": "[int]", - "xp": "[int]", - "yp": "[int]", - "th": "[int]", - "te": "[int]", - "lp": "[int]", - "ch": "[int]", - "zl": "[int]", - "zx": "[int]", - "ip": "[int]", - "fp": "[int]", - "av": "[int]", - "as": "[int]", - "ta": "[int]", - "ba": "[int]", - "oa": "[int]", - "lm": "[int]", - "ll": "[int]", - "lv": "[int]", - "de": "[int]", - "wt": "[int]", - "mv": "[int]", - "mc": "[int]", - "mp": "[int]", - "ms": "[int]", - "gi": "[int]", - "gj": "[int]", - "gk": "[int]", - "zu": "[int]", - "zr": "[int]", - "mh": "[int]", - "zo": "[int]", - "po": "[int]", - "la": "[int]", - "lb": "[int]", - "lc": "[int]", - "id": "int", -} + "at": "[int]", "tm": "[int]", "xp": "[int]", "yp": "[int]", "th": "[int]", "te": "[int]", + "lp": "[int]", "ch": "[int]", "zl": "[int]", "zx": "[int]", "ip": "[int]", "fp": "[int]", + "av": "[int]", "as": "[int]", "ta": "[int]", "ba": "[int]", "oa": "[int]", "lm": "[int]", + "ll": "[int]", "lv": "[int]", "de": "[int]", "wt": "[int]", "mv": "[int]", "mc": "[int]", + "mp": "[int]", "ms": "[int]", "gi": "[int]", "gj": "[int]", "gk": "[int]", "zu": "[int]", + "zr": "[int]", "mh": "[int]", "zo": "[int]", "po": "[int]", "la": "[int]", + "lb": "[int]", "lc": "[int]", "id": "int" } DISPENSE_FORMAT = { - "dm": "[int]", - "tm": "[int]", - "xp": "[int]", - "yp": "[int]", - "zx": "[int]", - "lp": "[int]", - "zl": "[int]", - "ip": "[int]", - "fp": "[int]", - "th": "[int]", - "te": "[int]", - "dv": "[int]", - "ds": "[int]", - "ss": "[int]", - "rv": "[int]", - "ta": "[int]", - "ba": "[int]", - "lm": "[int]", - "zo": "[int]", - "ll": "[int]", - "lv": "[int]", - "de": "[int]", - "mv": "[int]", - "mc": "[int]", - "mp": "[int]", - "ms": "[int]", - "wt": "[int]", - "gi": "[int]", - "gj": "[int]", - "gk": "[int]", - "zu": "[int]", - "zr": "[int]", - "dj": "[int]", - "mh": "[int]", - "po": "[int]", - "la": "[int]", -} + "dm": "[int]", "tm": "[int]", "xp": "[int]", "yp": "[int]", "zx": "[int]", "lp": "[int]", + "zl": "[int]", "ip": "[int]", "fp": "[int]", "th": "[int]", "te": "[int]", "dv": "[int]", + "ds": "[int]", "ss": "[int]", "rv": "[int]", "ta": "[int]", "ba": "[int]", "lm": "[int]", + "zo": "[int]", "ll": "[int]", "lv": "[int]", "de": "[int]", "mv": "[int]", "mc": "[int]", + "mp": "[int]", "ms": "[int]", "wt": "[int]", "gi": "[int]", "gj": "[int]", "gk": "[int]", + "zu": "[int]", "zr": "[int]", "dj": "[int]", "mh": "[int]", "po": "[int]", "la": "[int]"} class TestVantageResponseParsing(unittest.TestCase): - """Test parsing of response from Hamilton.""" + """ Test parsing of response from Hamilton. """ def test_parse_response_params(self): parsed = parse_vantage_fw_string("A1PMDAid1111", None) @@ -137,7 +56,7 @@ def test_parse_response_params(self): parsed = parse_vantage_fw_string("A1PMDAid1111", {"id": "int"}) self.assertEqual(parsed, {"id": 1111}) - parsed = parse_vantage_fw_string('A1PMDAid1112rw"abc"', {"rw": "str"}) + parsed = parse_vantage_fw_string("A1PMDAid1112rw\"abc\"", {"rw": "str"}) self.assertEqual(parsed, {"id": 1112, "rw": "abc"}) parsed = parse_vantage_fw_string("A1PMDAid1112rw-21", {"rw": "int"}) @@ -158,59 +77,49 @@ def test_parse_response_params(self): parse_vantage_fw_string("A1PMDA", {"id": "int"}) def test_parse_error_response(self): - resp = 'I1AMRQid0000er4et"Slave not available"' + resp = "I1AMRQid0000er4et\"Slave not available\"" error = vantage_response_string_to_error(resp) - self.assertEqual( - error, - VantageFirmwareError(errors={"Cover": "Slave not available"}, raw_response=resp), - ) + self.assertEqual(error, VantageFirmwareError( + errors={"Cover": "Slave not available"}, + raw_response=resp)) - resp = 'I1AMLPid215er57et"S-Drive: Drive not initialized"' + resp = "I1AMLPid215er57et\"S-Drive: Drive not initialized\"" error = vantage_response_string_to_error(resp) - self.assertEqual( - error, - VantageFirmwareError( - errors={"Cover": "S-Drive: Drive not initialized"}, - raw_response=resp, - ), - ) + self.assertEqual(error, VantageFirmwareError( + errors={"Cover": "S-Drive: Drive not initialized"}, + raw_response=resp)) - resp = 'A1HMDAid239er99es"H070"' + resp = "A1HMDAid239er99es\"H070\"" error = vantage_response_string_to_error(resp) - self.assertEqual( - error, - VantageFirmwareError(errors={"Core 96": "No liquid level found"}, raw_response=resp), - ) + self.assertEqual(error, VantageFirmwareError( + errors={"Core 96": "No liquid level found"}, + raw_response=resp)) - resp = 'A1PMDAid262er99es"P170 P270 P370 P470 P570 P670 P770 P870"' + resp = "A1PMDAid262er99es\"P170 P270 P370 P470 P570 P670 P770 P870\"" error = vantage_response_string_to_error(resp) - self.assertEqual( - error, - VantageFirmwareError( - errors={ - "Pipetting channel 1": "No liquid level found", - "Pipetting channel 2": "No liquid level found", - "Pipetting channel 3": "No liquid level found", - "Pipetting channel 4": "No liquid level found", - "Pipetting channel 5": "No liquid level found", - "Pipetting channel 6": "No liquid level found", - "Pipetting channel 7": "No liquid level found", - "Pipetting channel 8": "No liquid level found", - }, - raw_response=resp, - ), - ) + self.assertEqual(error, VantageFirmwareError( + errors={ + "Pipetting channel 1": "No liquid level found", + "Pipetting channel 2": "No liquid level found", + "Pipetting channel 3": "No liquid level found", + "Pipetting channel 4": "No liquid level found", + "Pipetting channel 5": "No liquid level found", + "Pipetting channel 6": "No liquid level found", + "Pipetting channel 7": "No liquid level found", + "Pipetting channel 8": "No liquid level found", + }, + raw_response=resp)) class VantageCommandCatcher(Vantage): - """Mock backend for Vantage that catches commands and saves them instead of sending them to the - machine.""" + """ Mock backend for Vantage that catches commands and saves them instead of sending them to the + machine. """ def __init__(self): super().__init__() self.commands = [] - async def setup(self) -> None: # type: ignore + async def setup(self) -> None: self.setup_finished = True self._num_channels = 8 self.iswap_installed = True @@ -220,17 +129,14 @@ async def send_command( self, module: str, command: str, - auto_id: bool = True, tip_pattern: Optional[List[bool]] = None, write_timeout: Optional[int] = None, read_timeout: Optional[int] = None, - wait=True, + wait = True, fmt: Optional[Any] = None, - **kwargs, + **kwargs ): - cmd, _ = self._assemble_command( - module=module, command=command, auto_id=auto_id, tip_pattern=tip_pattern, **kwargs - ) + cmd, _ = self._assemble_command(module, command, tip_pattern, **kwargs) self.commands.append(cmd) async def stop(self): @@ -238,16 +144,17 @@ async def stop(self): class TestVantageLiquidHandlerCommands(unittest.IsolatedAsyncioTestCase): - """Test Vantage backend for liquid handling.""" + """ Test Vantage backend for liquid handling. """ async def asyncSetUp(self): + # pylint: disable=invalid-name self.mockVantage = VantageCommandCatcher() self.deck = VantageDeck(size=1.3) self.lh = LiquidHandler(self.mockVantage, deck=self.deck) self.tip_car = TIP_CAR_480_A00(name="tip carrier") - self.tip_car[0] = self.tip_rack = HT(name="tip_rack_01") - self.tip_car[1] = self.small_tip_rack = LT(name="tip_rack_02") + self.tip_car[0] = self.tip_rack = HT_L(name="tip_rack_01") + self.tip_car[1] = self.small_tip_rack = LT_L(name="tip_rack_02") self.deck.assign_child_resource(self.tip_car, rails=18) self.plt_car = PLT_CAR_L5AC_A00(name="plate carrier") @@ -263,7 +170,7 @@ async def asyncTearDown(self): await self.lh.stop() def _assert_command_in_command_buffer(self, cmd: str, should_be: bool, fmt: dict): - """Assert that the given command was sent to the backend. The ordering of the parameters is not + """ Assert that the given command was sent to the backend. The ordering of the parameters is not taken into account, but the values and formatting should match. The id parameter of the command is ignored. @@ -312,7 +219,8 @@ def _assert_command_in_command_buffer(self, cmd: str, should_be: bool, fmt: dict self.fail(f"Command {cmd} was found in sent commands: {self.mockVantage.commands}") def test_ops_to_fw_positions(self): - """Convert channel positions to firmware positions.""" + """ Convert channel positions to firmware positions. """ + # pylint: disable=protected-access tip_a1 = self.tip_rack.get_item("A1") tip_f1 = self.tip_rack.get_item("F1") tip = self.tip_rack.get_tip("A1") @@ -321,25 +229,21 @@ def test_ops_to_fw_positions(self): op2 = Pickup(resource=tip_f1, tip=tip, offset=Coordinate.zero()) self.assertEqual( self.mockVantage._ops_to_fw_positions((op1,), use_channels=[0]), - ([4329, 0], [1458, 0], [True, False]), + ([4329, 0], [1458, 0], [True, False]) ) self.assertEqual( self.mockVantage._ops_to_fw_positions((op1, op2), use_channels=[0, 1]), - ([4329, 4329, 0], [1458, 1008, 0], [True, True, False]), + ([4329, 4329, 0], [1458, 1008, 0], [True, True, False]) ) self.assertEqual( self.mockVantage._ops_to_fw_positions((op1, op2), use_channels=[1, 2]), - ( - [0, 4329, 4329, 0], - [0, 1458, 1008, 0], - [False, True, True, False], - ), + ([0, 4329, 4329, 0], [0, 1458, 1008, 0], [False, True, True, False]) ) def _assert_command_sent_once(self, cmd: str, fmt: dict): - """Assert that the given command was sent to the backend exactly once.""" + """ Assert that the given command was sent to the backend exactly once. """ self._assert_command_in_command_buffer(cmd, True, fmt) self._assert_command_in_command_buffer(cmd, False, fmt) @@ -351,66 +255,59 @@ async def test_tip_pickup_01(self): self._assert_command_sent_once( "A1PMTPid0012xp4329 4329 0&yp1458 1368 0&tm1 1 0&tt1 1&tp2266 2266&tz2166 2166&th2450 2450&" "te2450 2450&ba0 0&td1 1&", - PICKUP_TIP_FORMAT, - ) + PICKUP_TIP_FORMAT) async def test_tip_drop_01(self): - await self.test_tip_pickup_01() # pick up tips first + await self.test_tip_pickup_01() # pick up tips first await self.lh.drop_tips(self.tip_rack["A1", "B1"]) self._assert_command_sent_once( "A1PMTRid013xp04329 04329 0&yp1458 1368 0&tm1 1 0&tp1414 1414&tz1314 1314&th2450 2450&" "te2450 2450&ts0td0 0&", - DROP_TIP_FORMAT, - ) + DROP_TIP_FORMAT) async def test_small_tip_pickup(self): await self.lh.pick_up_tips(self.small_tip_rack["A1"]) self._assert_command_sent_once( "A1PMTPid0010xp4329 0&yp2418 0&tm1 0&tt1&tp2224&tz2164&th2450&te2450&ba0&td1&", - PICKUP_TIP_FORMAT, - ) + PICKUP_TIP_FORMAT) async def test_small_tip_drop(self): - await self.test_small_tip_pickup() # pick up tips first + await self.test_small_tip_pickup() # pick up tips first await self.lh.drop_tips(self.small_tip_rack["A1"]) self._assert_command_sent_once( "A1PMTRid0012xp4329 0&yp2418 0&tp2024&tz1924&th2450&te2450&tm1 0&ts0td0&", - DROP_TIP_FORMAT, - ) + DROP_TIP_FORMAT) async def test_aspirate(self): - await self.lh.pick_up_tips(self.tip_rack["A1"]) # pick up tips first - await self.lh.aspirate(self.plate["A1"], vols=[100]) + await self.lh.pick_up_tips(self.tip_rack["A1"]) # pick up tips first + hlc = HighVolumeFilter_Water_DispenseSurface_Part + corrected_volume = hlc.compute_corrected_volume(100) + await self.lh.aspirate(self.plate["A1"], vols=[corrected_volume], **hlc.make_asp_kwargs(1)) self._assert_command_sent_once( "A1PMDAid0248at0&tm1 0&xp05683 0&yp1457 0 &th2450&te2450&lp1990&" "ch000&zl1866&zx1866&ip0000&fp0000&av010830&as2500&ta000&ba00000&oa000&lm0&ll4&lv4&de0020&" - "wt10&mv00000&mc00&mp000&ms2500&gi000&gj0gk0zu0000&zr00000&mh0000&zo005&po0109&dj0la0&lb0&" + "wt10&mv00000&mc00&mp000&ms1200&gi000&gj0gk0zu0000&zr00000&mh0000&zo005&po0109&dj0la0&lb0&" "lc0&", - ASPIRATE_FORMAT, - ) + ASPIRATE_FORMAT) async def test_dispense(self): - await self.lh.pick_up_tips(self.tip_rack["A1"]) # pick up tips first - await self.lh.aspirate(self.plate["A1"], vols=[100]) - await self.lh.dispense( - self.plate["A2"], - vols=[100], - liquid_height=[5], - jet=[False], - blow_out=[True], - ) + await self.lh.pick_up_tips(self.tip_rack["A1"]) # pick up tips first + hlc = HighVolumeFilter_Water_DispenseSurface_Empty + corrected_volume = hlc.compute_corrected_volume(100) + await self.lh.aspirate(self.plate["A1"], vols=[corrected_volume], **hlc.make_asp_kwargs(1)) + await self.lh.dispense(self.plate["A2"], vols=[corrected_volume], liquid_height=[5], + jet=[False], blow_out=[True], **hlc.make_disp_kwargs(1)) self._assert_command_sent_once( "A1PMDDid0253dm3&tm1 0&xp05773 0&yp1457 0&zx1866&lp1990&zl1916&" "ip0000&fp0021&th2450&te2450&dv010830&ds1200&ss2500&rv000&ta050&ba00000&lm0&zo005&ll1&lv1&" - "de0010&mv00000&mc00&mp000&ms0010&wt00&gi000&gj0gk0zu0000&dj00zr00000&mh0000&po0050&la0&", - DISPENSE_FORMAT, - ) + "de0020&mv00000&mc00&mp000&ms1200&wt00&gi000&gj0gk0zu0000&dj00zr00000&mh0000&po0050&la0&", + DISPENSE_FORMAT) async def test_zero_volume_liquid_handling(self): - # just test that this does not throw an error - await self.lh.pick_up_tips(self.tip_rack["A1"]) # pick up tips first + # just test that this does not throw an error + await self.lh.pick_up_tips(self.tip_rack["A1"]) # pick up tips first await self.lh.aspirate(self.plate["A1"], vols=[0]) await self.lh.dispense(self.plate["A2"], vols=[0]) @@ -418,114 +315,46 @@ async def test_tip_pickup96(self): await self.lh.pick_up_tips96(self.tip_rack) self._assert_command_sent_once( "A1HMTPid0237xp04329yp1458tt01td0tz2164th2450te2450", - { - "xp": "int", - "yp": "int", - "tt": "int", - "td": "int", - "tz": "int", - "th": "int", - "te": "int", - }, - ) + {"xp": "int", "yp": "int", "tt": "int", "td": "int", "tz": "int", "th": "int", "te": "int"}) async def test_tip_drop96(self): await self.lh.pick_up_tips96(self.tip_rack) await self.lh.drop_tips96(self.tip_rack) self._assert_command_sent_once( "A1HMTRid0284xp04329yp1458tz2164th2450te2450", - { - "xp": "int", - "yp": "int", - "tz": "int", - "th": "int", - "te": "int", - }, - ) + {"xp": "int", "yp": "int", "tz": "int", "th": "int", "te": "int"}) async def test_aspirate96(self): await self.lh.pick_up_tips96(self.tip_rack) - await self.lh.aspirate96(self.plate, volume=100, jet=True, blow_out=True) + hlc = HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty + await self.lh.aspirate96(self.plate, volume=hlc.compute_corrected_volume(100), + **hlc.make_asp96_kwargs()) self._assert_command_sent_once( - "A1HMDAid0236at0xp05683yp1457th2450te2450lp1990zl1866zx1866ip000fp000av010720as2500ta050" + "A1HMDAid0236at0xp05683yp1457th2450te2450lp1990zl1866zx1866ip000fp000av010920as2500ta050" "ba004000oa00000lm0ll4de0020wt10mv00000mc00mp000ms2500zu0000zr00000mh000gj0gk0gi000" "cwFFFFFFFFFFFFFFFFFFFFFFFFpo0050", - { - "xp": "int", - "yp": "int", - "th": "int", - "te": "int", - "lp": "int", - "zl": "int", - "zx": "int", - "ip": "int", - "fp": "int", - "av": "int", - "as": "int", - "ta": "int", - "ba": "int", - "oa": "int", - "lm": "int", - "ll": "int", - "de": "int", - "wt": "int", - "mv": "int", - "mc": "int", - "mp": "int", - "zu": "int", - "zr": "int", - "mh": "int", - "gj": "int", - "gk": "int", - "gi": "int", - "cw": "hex", - "po": "int", - }, - ) + {"xp": "int", "yp": "int", "th": "int", "te": "int", "lp": "int", "zl": "int", "zx": "int", + "ip": "int", "fp": "int", "av": "int", "as": "int", "ta": "int", "ba": "int", "oa": "int", + "lm": "int", "ll": "int", "de": "int", "wt": "int", "mv": "int", "mc": "int", "mp": "int", + "zu": "int", "zr": "int", "mh": "int", "gj": "int", "gk": "int", "gi": "int", "cw": "hex", + "po": "int"}) async def test_dispense96(self): await self.lh.pick_up_tips96(self.tip_rack) - await self.lh.aspirate96(self.plate, volume=100, jet=True, blow_out=True) - await self.lh.dispense96(self.plate, volume=100, jet=True, blow_out=True) + hlc = HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty + await self.lh.aspirate96(self.plate, volume=hlc.compute_corrected_volume(100), + **hlc.make_asp96_kwargs()) + await self.lh.dispense96(self.plate, volume=hlc.compute_corrected_volume(100), + jet=True, blow_out=True, **hlc.make_disp96_kwargs()) self._assert_command_sent_once( - "A1HMDDid0238dm1xp05683yp1457th2450te2450lp1990zl1966zx1866ip000fp029dv010720ds4000ta050" + "A1HMDDid0238dm1xp05683yp1457th2450te2450lp1990zl1966zx1866ip000fp029dv10920ds4000ta050" "ba004000lm0ll4de0010wt00mv00000mc00mp000ms0010ss2500rv000zu0000dj00zr00000mh000gj0gk0gi000" "cwFFFFFFFFFFFFFFFFFFFFFFFFpo0050", - { - "xp": "int", - "yp": "int", - "th": "int", - "te": "int", - "lp": "int", - "zl": "int", - "zx": "int", - "ip": "int", - "fp": "int", - "dv": "int", - "ds": "int", - "ta": "int", - "ba": "int", - "lm": "int", - "ll": "int", - "de": "int", - "wt": "int", - "mv": "int", - "mc": "int", - "mp": "int", - "ms": "int", - "ss": "int", - "rv": "int", - "zu": "int", - "zr": "int", - "dj": "int", - "mh": "int", - "gj": "int", - "gk": "int", - "gi": "int", - "cw": "hex", - "po": "int", - }, - ) + {"xp": "int", "yp": "int", "th": "int", "te": "int", "lp": "int", "zl": "int", "zx": "int", + "ip": "int", "fp": "int", "dv": "int", "ds": "int", "ta": "int", "ba": "int", "lm": "int", + "ll": "int", "de": "int", "wt": "int", "mv": "int", "mc": "int", "mp": "int", "ms": "int", + "ss": "int", "rv": "int", "zu": "int", "zr": "int", "dj": "int", "mh": "int", "gj": "int", + "gk": "int", "gi": "int", "cw": "hex", "po": "int"}) async def test_zero_volume_liquid_handling96(self): # just test that this does not throw an error @@ -534,36 +363,15 @@ async def test_zero_volume_liquid_handling96(self): await self.lh.dispense96(self.plate, volume=0) async def test_move_plate(self): - self.plt_car[1].resource.unassign() - await self.lh.move_plate(self.plate, self.plt_car[1], pickup_distance_from_top=5.2 - 3.33) + await self.lh.move_plate(self.plate, self.plt_car[1], pickup_distance_from_top=5.2-3.33) # pickup self._assert_command_sent_once( "A1RMDGid0240xp6179yp1142zp1954yw81yo1310yg1245pt20zc0hd0te2840", - { - "xp": "int", - "yp": "int", - "zp": "int", - "yw": "int", - "yo": "int", - "yg": "int", - "pt": "int", - "zc": "int", - "hd": "int", - "te": "int", - }, - ) + {"xp": "int", "yp": "int", "zp": "int", "yw": "int", "yo": "int", "yg": "int", "pt": "int", + "zc": "int", "hd": "int", "te": "int"}) # release self._assert_command_sent_once( "A1RMDRid0242xp6179yp2102zp1954yo1310zc0hd0te2840", - { - "xp": "int", - "yp": "int", - "zp": "int", - "yo": "int", - "zc": "int", - "hd": "int", - "te": "int", - }, - ) + {"xp": "int", "yp": "int", "zp": "int", "yo": "int", "zc": "int", "hd": "int", "te": "int"}) diff --git a/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py b/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py index d9db91d43a..432172bd71 100644 --- a/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py +++ b/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py @@ -143,7 +143,7 @@ def make_asp96_kwargs(self) -> Dict[str, Any]: "swap_speed": self.aspiration_swap_speed, "settling_time": self.aspiration_settling_time, } - + def make_disp96_kwargs(self) -> Dict[str, Any]: return { "flow_rate": self.dispense_flow_rate, From c3a2f3f686222bb9dff26ca7cd50888278bb6b34 Mon Sep 17 00:00:00 2001 From: Rick Wierenga Date: Fri, 27 Sep 2024 11:07:16 -0700 Subject: [PATCH 15/18] cl --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2332f39b54..32afc2b7e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,6 +60,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). - `location` parameter of `assign_child_resource` is not optional (https://github.com/PyLabRobot/pylabrobot/pull/336) - `Resource.get_absolute_location` raises `NoLocationError` instead of `AssertionError` when absolute location is not defined (https://github.com/PyLabRobot/pylabrobot/pull/338) - `no_trash` and `no_teaching_rack` were renamed to `with_trash` and `with_teaching_rack` to avoid double negatives (https://github.com/PyLabRobot/pylabrobot/pull/347) +- Hamilton liquid classes are no longer automatically inferred on the backends (`STAR`/`Vantage`). Instead, they create kwargs with `make_(asp|disp)(96)?_kwargs` (https://github.com/PyLabRobot/pylabrobot/pull/248) + - This also applies to volume correction curves, which are now the users' responsibility. ### Added From b25200fc2a272fec4f126f35698dd2850610dedb Mon Sep 17 00:00:00 2001 From: Rick Wierenga Date: Tue, 25 Mar 2025 13:04:46 -0700 Subject: [PATCH 16/18] ruff format --- .../liquid_handling/backends/hamilton/STAR.py | 2480 ++++---- .../backends/hamilton/STAR_tests.py | 445 +- .../backends/hamilton/vantage.py | 1102 ++-- .../backends/hamilton/vantage_tests.py | 378 +- .../liquid_classes/hamilton/star.py | 5199 +++++++++++------ .../liquid_classes/hamilton/vantage.py | 5013 ++++++++++------ pylabrobot/liquid_handling/liquid_handler.py | 428 +- 7 files changed, 9569 insertions(+), 5476 deletions(-) diff --git a/pylabrobot/liquid_handling/backends/hamilton/STAR.py b/pylabrobot/liquid_handling/backends/hamilton/STAR.py index 80586e691c..cddedddb2a 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/STAR.py +++ b/pylabrobot/liquid_handling/backends/hamilton/STAR.py @@ -3,12 +3,12 @@ """ # pylint: disable=invalid-sequence-index, dangerous-default-value -from abc import ABCMeta import datetime import enum import functools import logging import re +from abc import ABCMeta from typing import Callable, Dict, List, Literal, Optional, Sequence, Type, TypeVar, Union, cast from pylabrobot import audio @@ -16,25 +16,25 @@ from pylabrobot.liquid_handling.errors import ChannelizedError from pylabrobot.liquid_handling.liquid_classes.hamilton import HamiltonLiquidClass from pylabrobot.liquid_handling.standard import ( - Pickup, - PickupTipRack, - Drop, - DropTipRack, Aspiration, - AspirationPlate, AspirationContainer, + AspirationPlate, Dispense, - DispensePlate, DispenseContainer, + DispensePlate, + Drop, + DropTipRack, GripDirection, - Move + Move, + Pickup, + PickupTipRack, ) from pylabrobot.resources import Carrier, Coordinate, Resource, TipRack, TipSpot, Well from pylabrobot.resources.errors import ( - TooLittleVolumeError, - TooLittleLiquidError, HasTipError, - NoTipError + NoTipError, + TooLittleLiquidError, + TooLittleVolumeError, ) from pylabrobot.resources.hamilton.hamilton_decks import STAR_SIZE_X, STARLET_SIZE_X from pylabrobot.resources.ml_star import HamiltonTip, TipDropMethod, TipPickupMethod, TipSize @@ -56,17 +56,19 @@ def need_iswap_parked(method: Callable): @functools.wraps(method) async def wrapper(self: "STAR", *args, **kwargs): if self.iswap_installed and not self.iswap_parked: - await self.park_iswap(minimum_traverse_height_at_beginning_of_a_command= - int(self._traversal_height * 10)) # pylint: disable=protected-access + await self.park_iswap( + minimum_traverse_height_at_beginning_of_a_command=int(self._traversal_height * 10) + ) # pylint: disable=protected-access - result = await method(self, *args, **kwargs) # pylint: disable=not-callable + result = await method(self, *args, **kwargs) # pylint: disable=not-callable return result + return wrapper def _fill_in_defaults(val: Optional[List[T]], default: List[T]) -> List[T]: - """ Util for converting an argument to the appropriate format for low level star methods. """ + """Util for converting an argument to the appropriate format for low level star methods.""" t = type(default[0]) # if the val is None, use the default. if val is None: @@ -81,7 +83,7 @@ def _fill_in_defaults(val: Optional[List[T]], default: List[T]) -> List[T]: val = [v if v is not None else d for v, d in zip(val, default)] # the values must be of the right type. automatically handle int and float. if t in [int, float]: - return [t(v) for v in val] # type: ignore + return [t(v) for v in val] # type: ignore if not all(isinstance(v, t) for v in val): raise ValueError(f"Value must be a list of {t}, but is {val}") # the value is ready to be used. @@ -89,7 +91,7 @@ def _fill_in_defaults(val: Optional[List[T]], default: List[T]) -> List[T]: def parse_star_fw_string(resp: str, fmt: str = "") -> dict: - """ Parse a machine command or response string according to a format string. + """Parse a machine command or response string according to a format string. The format contains names of parameters (always length 2), followed by an arbitrary number of the following, but always @@ -142,11 +144,7 @@ def parse_star_fw_string(resp: str, fmt: str = "") -> dict: def find_param(param): name, data = param[0:2], param[2:] - type_ = { - "#": "int", - "*": "hex", - "&": "str" - }[data[0]] + type_ = {"#": "int", "*": "hex", "&": "str"}[data[0]] # Build a regex to match this parameter. exp = { @@ -154,7 +152,7 @@ def find_param(param): "hex": r"[\da-fA-F ]", "str": ".", }[type_] - len_ = len(data.split(" ")[0]) # Get length of first block. + len_ = len(data.split(" ")[0]) # Get length of first block. regex = f"{name}((?:{exp}{ {len_} }" if param.endswith(" (n)"): @@ -202,7 +200,7 @@ def find_param(param): param += char prevchar = char if param != "": - find_param(param) # last parameter is not closed by loop. + find_param(param) # last parameter is not closed by loop. # If id not in fmt, add it. if "id" not in info: @@ -212,7 +210,7 @@ def find_param(param): class STARModuleError(Exception, metaclass=ABCMeta): - """ Base class for all Hamilton backend errors, raised by a single module. """ + """Base class for all Hamilton backend errors, raised by a single module.""" def __init__( self, @@ -231,14 +229,14 @@ def __repr__(self) -> str: class CommandSyntaxError(STARModuleError): - """ Command syntax error + """Command syntax error Code: 01 """ class HardwareError(STARModuleError): - """ Hardware error + """Hardware error Possible cause(s): drive blocked, low power etc. @@ -248,7 +246,7 @@ class HardwareError(STARModuleError): class CommandNotCompletedError(STARModuleError): - """ Command not completed + """Command not completed Possible cause(s): error in previous sequence (not executed) @@ -258,7 +256,7 @@ class CommandNotCompletedError(STARModuleError): class ClotDetectedError(STARModuleError): - """ Clot detected + """Clot detected Possible cause(s): LLD not interrupted @@ -268,7 +266,7 @@ class ClotDetectedError(STARModuleError): class BarcodeUnreadableError(STARModuleError): - """ Barcode unreadable + """Barcode unreadable Possible cause(s): bad or missing barcode @@ -278,7 +276,7 @@ class BarcodeUnreadableError(STARModuleError): class TipTooLittleVolumeError(STARModuleError): - """ Too little liquid + """Too little liquid Possible cause(s): 1. liquid surface is not detected, @@ -289,7 +287,7 @@ class TipTooLittleVolumeError(STARModuleError): class TipAlreadyFittedError(STARModuleError): - """ Tip already fitted + """Tip already fitted Possible cause(s): Repeated attempts to fit a tip or iSwap movement with tips @@ -299,7 +297,7 @@ class TipAlreadyFittedError(STARModuleError): class HamiltonNoTipError(STARModuleError): - """ No tips + """No tips Possible cause(s): command was started without fitting tip (tip was not fitted or fell off again) @@ -309,7 +307,7 @@ class HamiltonNoTipError(STARModuleError): class NoCarrierError(STARModuleError): - """ No carrier + """No carrier Possible cause(s): load command without carrier @@ -319,7 +317,7 @@ class NoCarrierError(STARModuleError): class NotCompletedError(STARModuleError): - """ Not completed + """Not completed Possible cause(s): Command in command buffer was aborted due to an error in a previous command, or command stack @@ -330,7 +328,7 @@ class NotCompletedError(STARModuleError): class DispenseWithPressureLLDError(STARModuleError): - """ Dispense with pressure LLD + """Dispense with pressure LLD Possible cause(s): dispense with pressure LLD is not permitted @@ -340,7 +338,7 @@ class DispenseWithPressureLLDError(STARModuleError): class NoTeachInSignalError(STARModuleError): - """ No Teach In Signal + """No Teach In Signal Possible cause(s): X-Movement to LLD reached maximum allowable position with- out detecting Teach in signal @@ -350,7 +348,7 @@ class NoTeachInSignalError(STARModuleError): class LoadingTrayError(STARModuleError): - """ Loading Tray error + """Loading Tray error Possible cause(s): position already occupied @@ -360,7 +358,7 @@ class LoadingTrayError(STARModuleError): class SequencedAspirationWithPressureLLDError(STARModuleError): - """ Sequenced aspiration with pressure LLD + """Sequenced aspiration with pressure LLD Possible cause(s): sequenced aspiration with pressure LLD is not permitted @@ -370,7 +368,7 @@ class SequencedAspirationWithPressureLLDError(STARModuleError): class NotAllowedParameterCombinationError(STARModuleError): - """ Not allowed parameter combination + """Not allowed parameter combination Possible cause(s): i.e. PLLD and dispense or wrong X-drive assignment @@ -390,7 +388,7 @@ class CoverCloseError(STARModuleError): class AspirationError(STARModuleError): - """ Aspiration error + """Aspiration error Possible cause(s): aspiration liquid stream error detected @@ -411,7 +409,7 @@ class WashFluidOrWasteError(STARModuleError): class IncubationError(STARModuleError): - """ Incubation error + """Incubation error Possible cause(s): incubator temperature out of limit @@ -431,7 +429,7 @@ class TADMMeasurementError(STARModuleError): class NoElementError(STARModuleError): - """ No element + """No element Possible cause(s): expected element not detected @@ -451,7 +449,7 @@ class ElementStillHoldingError(STARModuleError): class ElementLostError(STARModuleError): - """ Element lost + """Element lost Possible cause(s): expected element is missing (lost) @@ -492,7 +490,7 @@ class PositionNotReachableError(STARModuleError): class UnexpectedLLDError(STARModuleError): - """ unexpected LLD + """unexpected LLD Possible cause(s): liquid level is reached before LLD scanning is started (using PIP or XL channels) @@ -502,7 +500,7 @@ class UnexpectedLLDError(STARModuleError): class AreaAlreadyOccupiedError(STARModuleError): - """ area already occupied + """area already occupied Possible cause(s): Its impossible to occupy area because this area is already in use @@ -512,7 +510,7 @@ class AreaAlreadyOccupiedError(STARModuleError): class ImpossibleToOccupyAreaError(STARModuleError): - """ impossible to occupy area + """impossible to occupy area Possible cause(s): Area cant be occupied because is no solution for arm prepositioning @@ -554,7 +552,7 @@ class StopError(STARModuleError): class SlaveError(STARModuleError): - """ Slave error + """Slave error Possible cause(s): This error code indicates an error in one of slaves. (for error handling purpose using service @@ -692,11 +690,11 @@ class DelimiterError(STARModuleError): class UnknownHamiltonError(STARModuleError): - """ Unknown error """ + """Unknown error""" def _module_id_to_module_name(id_): - """ Convert a module ID to a module name. """ + """Convert a module ID to a module name.""" return { "C0": "Master", "X0": "X-drives", @@ -729,12 +727,12 @@ def _module_id_to_module_name(id_): "N0": "Nano dispenser", "D0": "384 dispensing head", "NP": "Nano disp. pressure controller", - "M1": "Reserved for module 1" + "M1": "Reserved for module 1", }.get(id_, "Unknown Module") def error_code_to_exception(code: int) -> Type[STARModuleError]: - """ Convert an error code to an exception. """ + """Convert an error code to an exception.""" codes = { 1: CommandSyntaxError, 2: HardwareError, @@ -783,7 +781,7 @@ def error_code_to_exception(code: int) -> Type[STARModuleError]: 110: BarcodeNotUniqueError, 111: BarcodeAlreadyUsedError, 112: KitLotExpiredError, - 113: DelimiterError + 113: DelimiterError, } if code in codes: return codes[code] @@ -791,10 +789,10 @@ def error_code_to_exception(code: int) -> Type[STARModuleError]: def trace_information_to_string(module_identifier: str, trace_information: int) -> str: - """ Convert a trace identifier to an error message. """ + """Convert a trace identifier to an error message.""" table = None - if module_identifier == "C0": # master + if module_identifier == "C0": # master table = { 10: "CAN error", 11: "Slave command time out", @@ -821,14 +819,29 @@ def trace_information_to_string(module_identifier: str, trace_information: int) 50: "XL channel task busy", 51: "Tube gripper task busy", 52: "Imaging channel task busy", - 53: "Robotic channel task busy" - } - elif module_identifier == "I0": # autoload - table = { - 36: "Hamilton will not run while the hood is open" + 53: "Robotic channel task busy", } - elif module_identifier in ["PX", "P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9", "PA", - "PB", "PC", "PD", "PE", "PF", "PG"]: + elif module_identifier == "I0": # autoload + table = {36: "Hamilton will not run while the hood is open"} + elif module_identifier in [ + "PX", + "P1", + "P2", + "P3", + "P4", + "P5", + "P6", + "P7", + "P8", + "P9", + "PA", + "PB", + "PC", + "PD", + "PE", + "PF", + "PG", + ]: table = { 0: "No error", 20: "No communication to EEPROM", @@ -839,7 +852,7 @@ def trace_information_to_string(module_identifier: str, trace_information: int) 36: "Stop during execution of command", 37: "Stop during execution of command", 40: "No parallel processes permitted (Two or more commands sent for the same control" - "process)", + "process)", 50: "Dispensing drive init. position not found", 51: "Dispensing drive not initialized", 52: "Dispensing drive movement error", @@ -854,7 +867,7 @@ def trace_information_to_string(module_identifier: str, trace_information: int) 63: "Z-drive limit stop not found", 70: "No liquid level found (possibly because no liquid was present)", 71: "Not enough liquid present (Immersion depth or surface following position possiby" - "below minimal access range)", + "below minimal access range)", 72: "Auto calibration at pressure (Sensor not possible)", 73: "No liquid level found with dual LLD", 74: "Liquid at a not allowed position detected", @@ -871,16 +884,16 @@ def trace_information_to_string(module_identifier: str, trace_information: int) 86: "ADC algorithm error", 87: "2nd phase of liquid nt found", 88: "Not enough liquid present (Immersion depth or surface following position possiby" - "below minimal access range)", + "below minimal access range)", 90: "Limit curve not resetable", 91: "Limit curve not programmable", 92: "Limit curve not found", 93: "Limit curve data incorrect", 94: "Not enough memory for limit curve", 95: "Invalid limit curve index", - 96: "Limit curve already stored" + 96: "Limit curve already stored", } - elif module_identifier == "H0": # Core 96 head + elif module_identifier == "H0": # Core 96 head table = { 20: "No communication to EEPROM", 30: "Unknown command", @@ -913,7 +926,7 @@ def trace_information_to_string(module_identifier: str, trace_information: int) 76: "Tip already picked up", 81: "Clot detected", } - elif module_identifier == "R0": # iswap + elif module_identifier == "R0": # iswap table = { 20: "No communication to EEPROM", 30: "Unknown command", @@ -944,15 +957,14 @@ def trace_information_to_string(module_identifier: str, trace_information: int) 83: "Wrist twist drive movement error: position counter over/underflow", 85: "Gripper drive: communication error to gripper DMS digital potentiometer", 86: "Gripper drive: Auto adjustment of DMS digital potentiometer not possible", - 89: - "Gripper drive movement error: drive locked or incremental sensor fault during gripping", + 89: "Gripper drive movement error: drive locked or incremental sensor fault during gripping", 90: "Gripper drive initialized failed", 91: "iSWAP not initialized. Call star.initialize_iswap().", 92: "Gripper drive movement error: drive locked or incremental sensor fault during release", 93: "Gripper drive movement error: position counter over/underflow", 94: "Plate not found", 96: "Plate not available", - 97: "Unexpected object found" + 97: "Unexpected object found", } if table is not None and trace_information in table: @@ -972,7 +984,7 @@ def star_firmware_string_to_error( error_code_dict: Dict[str, str], raw_response: str, ) -> STARFirmwareError: - """ Convert a firmware string to a STARFirmwareError. """ + """Convert a firmware string to a STARFirmwareError.""" errors = {} @@ -982,7 +994,7 @@ def star_firmware_string_to_error( # C0 module: error code / trace information error_code_str, trace_information_str = error.split("/") error_code, trace_information = int(error_code_str), int(trace_information_str) - if error_code == 0: # No error + if error_code == 0: # No error continue error_class = error_code_to_exception(error_code) elif module_id == "I0" and error == "36": @@ -993,11 +1005,14 @@ def star_firmware_string_to_error( error_class = UnknownHamiltonError trace_information = int(error) error_description = trace_information_to_string( - module_identifier=module_id, trace_information=trace_information) - errors[module_name] = error_class(message=error_description, - trace_information=trace_information, - raw_response=error, - raw_module=module_id) + module_identifier=module_id, trace_information=trace_information + ) + errors[module_name] = error_class( + message=error_description, + trace_information=trace_information, + raw_response=error, + raw_module=module_id, + ) # If the master error is a SlaveError, remove it from the errors dict. if isinstance(errors.get("Master"), SlaveError): @@ -1007,7 +1022,7 @@ def star_firmware_string_to_error( def convert_star_module_error_to_plr_error(error: STARModuleError) -> Optional[Exception]: - """ Convert an error returned by a specific STAR module to a Hamilton error. """ + """Convert an error returned by a specific STAR module to a Hamilton error.""" # TipAlreadyFittedError -> HasTipError if isinstance(error, TipAlreadyFittedError): return HasTipError() @@ -1029,13 +1044,15 @@ def convert_star_module_error_to_plr_error(error: STARModuleError) -> Optional[E def convert_star_firmware_error_to_plr_error(error: STARFirmwareError) -> Optional[Exception]: - """ Check if a STARFirmwareError can be converted to a native PLR error. If so, return it, else - return `None`. """ + """Check if a STARFirmwareError can be converted to a native PLR error. If so, return it, else + return `None`.""" # if all errors are channel errors, return a ChannelizedError if all(e.startswith("Pipetting channel ") for e in error.errors): + def _channel_to_int(channel: str) -> int: - return int(channel.split(" ")[-1]) - 1 # star is 1-indexed, plr is 0-indexed + return int(channel.split(" ")[-1]) - 1 # star is 1-indexed, plr is 0-indexed + errors = { _channel_to_int(module_name): convert_star_module_error_to_plr_error(error) or error for module_name, error in error.errors.items() @@ -1046,7 +1063,7 @@ def _channel_to_int(channel: str) -> int: def _dispensing_mode_for_op(empty: bool, jet: bool, blow_out: bool) -> int: - """ from docs: + """from docs: 0 = Partial volume in jet mode 1 = Blow out in jet mode, called "empty" in the VENUS liquid editor 2 = Partial volume at surface @@ -1075,7 +1092,7 @@ def __init__( read_timeout: int = 30, write_timeout: int = 30, ): - """ Create a new STAR interface. + """Create a new STAR interface. Args: device_address: the USB device address of the Hamilton STAR. Only useful if using more than @@ -1093,7 +1110,7 @@ def __init__( read_timeout=read_timeout, write_timeout=write_timeout, id_product=0x8000, - serial_number=serial_number + serial_number=serial_number, ) self.iswap_installed: Optional[bool] = None @@ -1110,18 +1127,18 @@ def __init__( @property def unsafe(self) -> "UnSafe": - """ Actions that have a higher risk of damaging the robot. Use with care! """ + """Actions that have a higher risk of damaging the robot. Use with care!""" return self._unsafe @property def num_channels(self) -> int: - """ The number of pipette channels present on the robot. """ + """The number of pipette channels present on the robot.""" if self._num_channels is None: raise RuntimeError("has not loaded num_channels, forgot to call `setup`?") return self._num_channels def set_minimum_traversal_height(self, traversal_height: float): - """ Set the minimum traversal height for the robot. + """Set the minimum traversal height for the robot. This refers to the bottom of the pipetting channel when no tip is present, or the bottom of the tip when a tip is present. This value will be used as the default value for the @@ -1139,7 +1156,7 @@ def module_id_length(self): @property def extended_conf(self) -> dict: - """ Extended configuration. """ + """Extended configuration.""" if self._extended_conf is None: raise RuntimeError("has not loaded extended_conf, forgot to call `setup`?") return self._extended_conf @@ -1153,14 +1170,14 @@ def core_parked(self) -> bool: return self._core_parked is True def get_id_from_fw_response(self, resp: str) -> Optional[int]: - """ Get the id from a firmware response. """ + """Get the id from a firmware response.""" parsed = parse_star_fw_string(resp, "id####") if "id" in parsed and parsed["id"] is not None: return int(parsed["id"]) return None def check_fw_string_error(self, resp: str): - """ Raise an error if the firmware response is an error response. + """Raise an error if the firmware response is an error response. Raises: ValueError: if the format string is incompatible with the response. @@ -1177,9 +1194,39 @@ def check_fw_string_error(self, resp: str): # named capturing groups to the regex. exp = r"er(?P[0-9]{2}/[0-9]{2})" - for module in ["X0", "I0", "W1", "W2", "T1", "T2", "R0", "P1", "P2", "P3", "P4", "P5", "P6", - "P7", "P8", "P9", "PA", "PB", "PC", "PD", "PE", "PF", "PG", "H0", "HW", "HU", - "HV", "N0", "D0", "NP", "M1"]: + for module in [ + "X0", + "I0", + "W1", + "W2", + "T1", + "T2", + "R0", + "P1", + "P2", + "P3", + "P4", + "P5", + "P6", + "P7", + "P8", + "P9", + "PA", + "PB", + "PC", + "PD", + "PE", + "PF", + "PG", + "H0", + "HW", + "HU", + "HV", + "N0", + "D0", + "NP", + "M1", + ]: exp += f" ?(?:{module}(?P<{module}>[0-9]{{2}}/[0-9]{{2}}))?" errors = re.search(exp, resp) else: @@ -1189,9 +1236,9 @@ def check_fw_string_error(self, resp: str): if errors is not None: # filter None elements - errors_dict = {k:v for k,v in errors.groupdict().items() if v is not None} + errors_dict = {k: v for k, v in errors.groupdict().items() if v is not None} # filter 00 and 00/00 elements, which mean no error. - errors_dict = {k:v for k,v in errors_dict.items() if v not in ["00", "00/00"]} + errors_dict = {k: v for k, v in errors_dict.items() if v not in ["00", "00/00"]} has_error = not (errors is None or len(errors_dict) == 0) if has_error: @@ -1206,17 +1253,18 @@ def check_fw_string_error(self, resp: str): # he[module_name].message += f" ({vp})" # pylint: disable=unnecessary-dict-index-lookup # pylint: disable=unnecessary-dict-index-lookup - he.errors[module_name].message += \ - " (call lh.backend.request_name_of_last_faulty_parameter)" + he.errors[ + module_name + ].message += " (call lh.backend.request_name_of_last_faulty_parameter)" raise he def _parse_response(self, resp: str, fmt: str) -> dict: - """ Parse a response from the machine. """ + """Parse a response from the machine.""" return parse_star_fw_string(resp, fmt) async def setup(self): - """ setup + """setup Creates a USB connection and finds read/write interfaces. """ @@ -1231,8 +1279,9 @@ async def setup(self): self._extended_conf = await self.request_extended_configuration() left_x_drive_configuration_byte_1 = bin(self.extended_conf["xl"]) - left_x_drive_configuration_byte_1 = left_x_drive_configuration_byte_1 + \ - "0" * (16 - len(left_x_drive_configuration_byte_1)) + left_x_drive_configuration_byte_1 = left_x_drive_configuration_byte_1 + "0" * ( + 16 - len(left_x_drive_configuration_byte_1) + ) left_x_drive_configuration_byte_1 = left_x_drive_configuration_byte_1[2:] configuration_data1 = bin(conf["kb"]).split("b")[-1].zfill(8) autoload_configuration_byte = configuration_data1[-3] @@ -1259,8 +1308,8 @@ async def setup(self): end_of_tip_deposit_process=1220, z_position_at_end_of_a_command=3600, tip_pattern=[True] * self.num_channels, - tip_type=4, # TODO: get from tip types - discarding_method=0 + tip_type=4, # TODO: get from tip types + discarding_method=0, ) if self.autoload_installed: @@ -1275,14 +1324,16 @@ async def setup(self): if not iswap_initialized: await self.initialize_iswap() - await self.park_iswap(minimum_traverse_height_at_beginning_of_a_command= - int(self._traversal_height * 10)) + await self.park_iswap( + minimum_traverse_height_at_beginning_of_a_command=int(self._traversal_height * 10) + ) if self.core96_head_installed: core96_head_initialized = await self.request_core_96_head_initialization_status() if not core96_head_initialized: await self.initialize_core_96_head( - z_position_at_the_command_end=int(self._traversal_height*10)) + z_position_at_the_command_end=int(self._traversal_height * 10) + ) # After setup, STAR will have thrown out anything mounted on the pipetting channels, including # the core grippers. @@ -1299,10 +1350,9 @@ async def pick_up_tips( minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, pickup_method: Optional[TipPickupMethod] = None, ): - """ Pick up tips from a resource. """ + """Pick up tips from a resource.""" - x_positions, y_positions, channels_involved = \ - self._ops_to_fw_positions(ops, use_channels) + x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) tip_spots = [op.resource for op in ops] tips = set(cast(HamiltonTip, tip_spot.get_tip()) for tip_spot in tip_spots) @@ -1312,7 +1362,7 @@ async def pick_up_tips( max_z = max(op.resource.get_absolute_location().z + op.offset.z for op in ops) max_total_tip_length = max(op.tip.total_tip_length for op in ops) - max_tip_length = max((op.tip.total_tip_length-op.tip.fitting_depth) for op in ops) + max_tip_length = max((op.tip.total_tip_length - op.tip.fitting_depth) for op in ops) # not sure why this is necessary, but it is according to log files and experiments if self._get_hamilton_tip([op.resource for op in ops]).tip_size == TipSize.LOW_VOLUME: @@ -1324,13 +1374,21 @@ async def pick_up_tips( if not isinstance(tip, HamiltonTip): raise TypeError("Tip type must be HamiltonTip.") - begin_tip_pick_up_process = round((max_z + max_total_tip_length)*10) \ - if begin_tip_pick_up_process is None else int(begin_tip_pick_up_process*10) - end_tip_pick_up_process = round((max_z + max_tip_length)*10) \ - if end_tip_pick_up_process is None else round(end_tip_pick_up_process*10) - minimum_traverse_height_at_beginning_of_a_command = round(self._traversal_height * 10) \ - if minimum_traverse_height_at_beginning_of_a_command is None \ + begin_tip_pick_up_process = ( + round((max_z + max_total_tip_length) * 10) + if begin_tip_pick_up_process is None + else int(begin_tip_pick_up_process * 10) + ) + end_tip_pick_up_process = ( + round((max_z + max_tip_length) * 10) + if end_tip_pick_up_process is None + else round(end_tip_pick_up_process * 10) + ) + minimum_traverse_height_at_beginning_of_a_command = ( + round(self._traversal_height * 10) + if minimum_traverse_height_at_beginning_of_a_command is None else round(minimum_traverse_height_at_beginning_of_a_command * 10) + ) pickup_method = pickup_method or tip.pickup_method try: @@ -1341,8 +1399,7 @@ async def pick_up_tips( tip_type_idx=ttti, begin_tip_pick_up_process=begin_tip_pick_up_process, end_tip_pick_up_process=end_tip_pick_up_process, - minimum_traverse_height_at_beginning_of_a_command=\ - minimum_traverse_height_at_beginning_of_a_command, + minimum_traverse_height_at_beginning_of_a_command=minimum_traverse_height_at_beginning_of_a_command, pickup_method=pickup_method, ) except STARFirmwareError as e: @@ -1360,7 +1417,7 @@ async def drop_tips( minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, z_position_at_end_of_a_command: Optional[float] = None, ): - """ Drop tips to a resource. + """Drop tips to a resource. Args: drop_method: The method to use for dropping tips. If None, the default method for dropping to @@ -1374,30 +1431,46 @@ async def drop_tips( else: drop_method = TipDropMethod.DROP - x_positions, y_positions, channels_involved = \ - self._ops_to_fw_positions(ops, use_channels) + x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) # get highest z position max_z = max(op.resource.get_absolute_location().z + op.offset.z for op in ops) if drop_method == TipDropMethod.PLACE_SHIFT: # magic values empirically found in https://github.com/PyLabRobot/pylabrobot/pull/63 - begin_tip_deposit_process = round((max_z+59.9)*10) \ - if begin_tip_deposit_process is None else round(begin_tip_deposit_process*10) - end_tip_deposit_process = round((max_z+49.9)*10) \ - if end_tip_deposit_process is None else round(end_tip_deposit_process*10) + begin_tip_deposit_process = ( + round((max_z + 59.9) * 10) + if begin_tip_deposit_process is None + else round(begin_tip_deposit_process * 10) + ) + end_tip_deposit_process = ( + round((max_z + 49.9) * 10) + if end_tip_deposit_process is None + else round(end_tip_deposit_process * 10) + ) else: max_total_tip_length = max(op.tip.total_tip_length for op in ops) - max_tip_length = max((op.tip.total_tip_length-op.tip.fitting_depth) for op in ops) - begin_tip_deposit_process=round((max_z + max_total_tip_length)*10) \ - if begin_tip_deposit_process is None else round(begin_tip_deposit_process*10) - end_tip_deposit_process=round((max_z + max_tip_length)*10) \ - if end_tip_deposit_process is None else round(end_tip_deposit_process*10) - - minimum_traverse_height_at_beginning_of_a_command = round(self._traversal_height * 10) \ - if minimum_traverse_height_at_beginning_of_a_command is None \ + max_tip_length = max((op.tip.total_tip_length - op.tip.fitting_depth) for op in ops) + begin_tip_deposit_process = ( + round((max_z + max_total_tip_length) * 10) + if begin_tip_deposit_process is None + else round(begin_tip_deposit_process * 10) + ) + end_tip_deposit_process = ( + round((max_z + max_tip_length) * 10) + if end_tip_deposit_process is None + else round(end_tip_deposit_process * 10) + ) + + minimum_traverse_height_at_beginning_of_a_command = ( + round(self._traversal_height * 10) + if minimum_traverse_height_at_beginning_of_a_command is None else round(minimum_traverse_height_at_beginning_of_a_command * 10) - z_position_at_end_of_a_command = round(self._traversal_height * 10) \ - if z_position_at_end_of_a_command is None else round(z_position_at_end_of_a_command * 10) + ) + z_position_at_end_of_a_command = ( + round(self._traversal_height * 10) + if z_position_at_end_of_a_command is None + else round(z_position_at_end_of_a_command * 10) + ) try: return await self.discard_tip( @@ -1406,10 +1479,9 @@ async def drop_tips( tip_pattern=channels_involved, begin_tip_deposit_process=begin_tip_deposit_process, end_tip_deposit_process=end_tip_deposit_process, - minimum_traverse_height_at_beginning_of_a_command=\ - minimum_traverse_height_at_beginning_of_a_command, + minimum_traverse_height_at_beginning_of_a_command=minimum_traverse_height_at_beginning_of_a_command, z_position_at_end_of_a_command=z_position_at_end_of_a_command, - discarding_method=drop_method + discarding_method=drop_method, ) except STARFirmwareError as e: if plr_e := convert_star_firmware_error_to_plr_error(e): @@ -1417,14 +1489,15 @@ async def drop_tips( raise e def _assert_valid_resources(self, resources: Sequence[Resource]) -> None: - """ Assert that resources are in a valid location for pipetting. """ + """Assert that resources are in a valid location for pipetting.""" for resource in resources: if resource.get_absolute_location().z < 100: raise ValueError( - f"Resource {resource} is too low: {resource.get_absolute_location().z} < 100") + f"Resource {resource} is too low: {resource.get_absolute_location().z} < 100" + ) class LLDMode(enum.Enum): - """ Liquid level detection mode. """ + """Liquid level detection mode.""" OFF = 0 GAMMA = 1 @@ -1460,7 +1533,6 @@ async def aspirate( mix_speed: Optional[List[float]] = None, mix_surface_following_distance: Optional[List[float]] = None, limit_curve_index: Optional[List[int]] = None, - use_2nd_section_aspiration: Optional[List[bool]] = None, retract_height_over_2nd_section_to_empty_tip: Optional[List[float]] = None, dispensation_speed_during_emptying_tip: Optional[List[float]] = None, @@ -1469,14 +1541,12 @@ async def aspirate( cup_upper_edge: Optional[List[float]] = None, ratio_liquid_rise_to_tip_deep_in: Optional[List[float]] = None, immersion_depth_2nd_section: Optional[List[float]] = None, - minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, min_z_endpos: Optional[float] = None, - hamilton_liquid_classes: Optional[List[Optional[HamiltonLiquidClass]]] = None, liquid_surfaces_no_lld: Optional[List[float]] = None, ): - """ Aspirate liquid from the specified channels. + """Aspirate liquid from the specified channels. For all parameters where `None` is the default value, STAR will use the default value, based on the aspirations. For all list parameters, the length of the list must be equal to the number of @@ -1540,67 +1610,75 @@ async def aspirate( if hamilton_liquid_classes is not None: raise NotImplementedError("Hamilton liquid classes are deprecated.") - x_positions, y_positions, channels_involved = \ - self._ops_to_fw_positions(ops, use_channels) + x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) n = len(ops) self._assert_valid_resources([op.resource for op in ops]) - well_bottoms = [op.resource.get_absolute_location().z + op.offset.z + \ - op.resource.material_z_thickness for op in ops] - liquid_surfaces_no_lld = liquid_surfaces_no_lld or [wb + (op.liquid_height or 0) - for wb, op in zip(well_bottoms, ops)] + well_bottoms = [ + op.resource.get_absolute_location().z + op.offset.z + op.resource.material_z_thickness + for op in ops + ] + liquid_surfaces_no_lld = liquid_surfaces_no_lld or [ + wb + (op.liquid_height or 0) for wb, op in zip(well_bottoms, ops) + ] if lld_search_height is None: lld_search_height = [ - (wb + op.resource.get_absolute_size_z() + (2.7 if isinstance(op.resource, Well) else 5)) # ? + ( + wb + op.resource.get_absolute_size_z() + (2.7 if isinstance(op.resource, Well) else 5) + ) # ? for wb, op in zip(well_bottoms, ops) ] else: lld_search_height = [(wb + sh) for wb, sh in zip(well_bottoms, lld_search_height)] - clot_detection_height = _fill_in_defaults(clot_detection_height, default=[0]*n) - pull_out_distance_transport_air = _fill_in_defaults(pull_out_distance_transport_air, [10]*n) - second_section_height = _fill_in_defaults(second_section_height, [3.2]*n) - second_section_ratio = _fill_in_defaults(second_section_ratio, [618.0]*n) + clot_detection_height = _fill_in_defaults(clot_detection_height, default=[0] * n) + pull_out_distance_transport_air = _fill_in_defaults(pull_out_distance_transport_air, [10] * n) + second_section_height = _fill_in_defaults(second_section_height, [3.2] * n) + second_section_ratio = _fill_in_defaults(second_section_ratio, [618.0] * n) minimum_height = _fill_in_defaults(minimum_height, well_bottoms) # TODO: I think minimum height should be the minimum height of the well - immersion_depth = _fill_in_defaults(immersion_depth, [0]*n) - immersion_depth_direction = _fill_in_defaults(immersion_depth_direction, [0]*n) - surface_following_distance = _fill_in_defaults(surface_following_distance, [0]*n) + immersion_depth = _fill_in_defaults(immersion_depth, [0] * n) + immersion_depth_direction = _fill_in_defaults(immersion_depth_direction, [0] * n) + surface_following_distance = _fill_in_defaults(surface_following_distance, [0] * n) flow_rates = [op.flow_rate or 100 for op in ops] - transport_air_volume = _fill_in_defaults(transport_air_volume, default=[0]*n) + transport_air_volume = _fill_in_defaults(transport_air_volume, default=[0] * n) blow_out_air_volumes = [op.blow_out_air_volume or 0 for op in ops] - pre_wetting_volume = _fill_in_defaults(pre_wetting_volume, [0]*n) - lld_mode = _fill_in_defaults(lld_mode, [self.__class__.LLDMode.OFF]*n) - gamma_lld_sensitivity = _fill_in_defaults(gamma_lld_sensitivity, [1]*n) - dp_lld_sensitivity = _fill_in_defaults(dp_lld_sensitivity, [1]*n) - aspirate_position_above_z_touch_off = \ - _fill_in_defaults(aspirate_position_above_z_touch_off, [0]*n) - detection_height_difference_for_dual_lld = \ - _fill_in_defaults(detection_height_difference_for_dual_lld, [0]*n) - swap_speed = _fill_in_defaults(swap_speed, default=[100]*n) - settling_time = _fill_in_defaults(settling_time, default=[0]*n) - mix_volume = _fill_in_defaults(mix_volume, [0]*n) - mix_cycles = _fill_in_defaults(mix_cycles, [0]*n) - mix_position_from_liquid_surface = \ - _fill_in_defaults(mix_position_from_liquid_surface, [0]*n) - mix_speed = _fill_in_defaults(mix_speed, [50]*n) - mix_surface_following_distance = \ - _fill_in_defaults(mix_surface_following_distance, [0]*n) - limit_curve_index = _fill_in_defaults(limit_curve_index, [0]*n) - - use_2nd_section_aspiration = _fill_in_defaults(use_2nd_section_aspiration, [False]*n) - retract_height_over_2nd_section_to_empty_tip = \ - _fill_in_defaults(retract_height_over_2nd_section_to_empty_tip, [0]*n) - dispensation_speed_during_emptying_tip = \ - _fill_in_defaults(dispensation_speed_during_emptying_tip, [50.0]*n) - dosing_drive_speed_during_2nd_section_search = \ - _fill_in_defaults(dosing_drive_speed_during_2nd_section_search, [50.0]*n) - z_drive_speed_during_2nd_section_search = \ - _fill_in_defaults(z_drive_speed_during_2nd_section_search, [30.0]*n) - cup_upper_edge = _fill_in_defaults(cup_upper_edge, [0]*n) - ratio_liquid_rise_to_tip_deep_in = _fill_in_defaults(ratio_liquid_rise_to_tip_deep_in, [0]*n) - immersion_depth_2nd_section = _fill_in_defaults(immersion_depth_2nd_section, [0]*n) + pre_wetting_volume = _fill_in_defaults(pre_wetting_volume, [0] * n) + lld_mode = _fill_in_defaults(lld_mode, [self.__class__.LLDMode.OFF] * n) + gamma_lld_sensitivity = _fill_in_defaults(gamma_lld_sensitivity, [1] * n) + dp_lld_sensitivity = _fill_in_defaults(dp_lld_sensitivity, [1] * n) + aspirate_position_above_z_touch_off = _fill_in_defaults( + aspirate_position_above_z_touch_off, [0] * n + ) + detection_height_difference_for_dual_lld = _fill_in_defaults( + detection_height_difference_for_dual_lld, [0] * n + ) + swap_speed = _fill_in_defaults(swap_speed, default=[100] * n) + settling_time = _fill_in_defaults(settling_time, default=[0] * n) + mix_volume = _fill_in_defaults(mix_volume, [0] * n) + mix_cycles = _fill_in_defaults(mix_cycles, [0] * n) + mix_position_from_liquid_surface = _fill_in_defaults(mix_position_from_liquid_surface, [0] * n) + mix_speed = _fill_in_defaults(mix_speed, [50] * n) + mix_surface_following_distance = _fill_in_defaults(mix_surface_following_distance, [0] * n) + limit_curve_index = _fill_in_defaults(limit_curve_index, [0] * n) + + use_2nd_section_aspiration = _fill_in_defaults(use_2nd_section_aspiration, [False] * n) + retract_height_over_2nd_section_to_empty_tip = _fill_in_defaults( + retract_height_over_2nd_section_to_empty_tip, [0] * n + ) + dispensation_speed_during_emptying_tip = _fill_in_defaults( + dispensation_speed_during_emptying_tip, [50.0] * n + ) + dosing_drive_speed_during_2nd_section_search = _fill_in_defaults( + dosing_drive_speed_during_2nd_section_search, [50.0] * n + ) + z_drive_speed_during_2nd_section_search = _fill_in_defaults( + z_drive_speed_during_2nd_section_search, [30.0] * n + ) + cup_upper_edge = _fill_in_defaults(cup_upper_edge, [0] * n) + ratio_liquid_rise_to_tip_deep_in = _fill_in_defaults(ratio_liquid_rise_to_tip_deep_in, [0] * n) + immersion_depth_2nd_section = _fill_in_defaults(immersion_depth_2nd_section, [0] * n) try: return await self.aspirate_pip( @@ -1608,7 +1686,6 @@ async def aspirate( tip_pattern=channels_involved, x_positions=x_positions, y_positions=y_positions, - aspiration_volumes=[round(op.volume * 10) for op in ops], lld_search_height=[round(lsh * 10) for lsh in lld_search_height], clot_detection_height=[round(cd * 10) for cd in clot_detection_height], @@ -1627,36 +1704,41 @@ async def aspirate( lld_mode=[mode.value for mode in lld_mode], gamma_lld_sensitivity=gamma_lld_sensitivity, dp_lld_sensitivity=dp_lld_sensitivity, - aspirate_position_above_z_touch_off=[round(ap * 10) - for ap in aspirate_position_above_z_touch_off], - detection_height_difference_for_dual_lld=[round(dh * 10) - for dh in detection_height_difference_for_dual_lld], + aspirate_position_above_z_touch_off=[ + round(ap * 10) for ap in aspirate_position_above_z_touch_off + ], + detection_height_difference_for_dual_lld=[ + round(dh * 10) for dh in detection_height_difference_for_dual_lld + ], swap_speed=[round(ss * 10) for ss in swap_speed], settling_time=[round(st * 10) for st in settling_time], mix_volume=[round(hv * 10) for hv in mix_volume], mix_cycles=mix_cycles, - mix_position_from_liquid_surface=[round(hp * 10) - for hp in mix_position_from_liquid_surface], + mix_position_from_liquid_surface=[ + round(hp * 10) for hp in mix_position_from_liquid_surface + ], mix_speed=[round(hs * 10) for hs in mix_speed], - mix_surface_following_distance=[round(hsd * 10) - for hsd in mix_surface_following_distance], + mix_surface_following_distance=[round(hsd * 10) for hsd in mix_surface_following_distance], limit_curve_index=limit_curve_index, - use_2nd_section_aspiration=use_2nd_section_aspiration, - retract_height_over_2nd_section_to_empty_tip=[round(rh * 10) - for rh in retract_height_over_2nd_section_to_empty_tip], - dispensation_speed_during_emptying_tip=[round(ds * 10) - for ds in dispensation_speed_during_emptying_tip], - dosing_drive_speed_during_2nd_section_search=[round(ds * 10) - for ds in dosing_drive_speed_during_2nd_section_search], - z_drive_speed_during_2nd_section_search=[round(zs * 10) - for zs in z_drive_speed_during_2nd_section_search], + retract_height_over_2nd_section_to_empty_tip=[ + round(rh * 10) for rh in retract_height_over_2nd_section_to_empty_tip + ], + dispensation_speed_during_emptying_tip=[ + round(ds * 10) for ds in dispensation_speed_during_emptying_tip + ], + dosing_drive_speed_during_2nd_section_search=[ + round(ds * 10) for ds in dosing_drive_speed_during_2nd_section_search + ], + z_drive_speed_during_2nd_section_search=[ + round(zs * 10) for zs in z_drive_speed_during_2nd_section_search + ], cup_upper_edge=[round(cue * 10) for cue in cup_upper_edge], ratio_liquid_rise_to_tip_deep_in=ratio_liquid_rise_to_tip_deep_in, - immersion_depth_2nd_section=[round(id_*10) for id_ in immersion_depth_2nd_section], - - minimum_traverse_height_at_beginning_of_a_command= - round((minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10), + immersion_depth_2nd_section=[round(id_ * 10) for id_ in immersion_depth_2nd_section], + minimum_traverse_height_at_beginning_of_a_command=round( + (minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10 + ), min_z_endpos=round((min_z_endpos or self._traversal_height) * 10), ) except STARFirmwareError as e: @@ -1668,7 +1750,6 @@ async def dispense( self, ops: List[Dispense], use_channels: List[int], - lld_search_height: Optional[List[float]] = None, liquid_surface_no_lld: Optional[List[float]] = None, dispensing_mode: Optional[List[int]] = None, @@ -1694,17 +1775,15 @@ async def dispense( mix_speed: Optional[List[float]] = None, mix_surface_following_distance: Optional[List[float]] = None, limit_curve_index: Optional[List[int]] = None, - minimum_traverse_height_at_beginning_of_a_command: Optional[int] = None, min_z_endpos: Optional[float] = None, side_touch_off_distance: float = 0, - hamilton_liquid_classes: Optional[List[Optional[HamiltonLiquidClass]]] = None, jet: Optional[List[bool]] = None, - blow_out: Optional[List[bool]] = None, # "empty" in the VENUS liquid editor - empty: Optional[List[bool]] = None, # truly "empty", does not exist in liquid editor, dm4 + blow_out: Optional[List[bool]] = None, # "empty" in the VENUS liquid editor + empty: Optional[List[bool]] = None, # truly "empty", does not exist in liquid editor, dm4 ): - """ Dispense liquid from the specified channels. + """Dispense liquid from the specified channels. For all parameters where `None` is the default value, STAR will use the default value, based on the dispenses. For all list parameters, the length of the list must be equal to the number of @@ -1763,8 +1842,7 @@ async def dispense( if hamilton_liquid_classes is not None: raise NotImplementedError("Hamilton liquid classes are deprecated.") - x_positions, y_positions, channels_involved = \ - self._ops_to_fw_positions(ops, use_channels) + x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) n = len(ops) @@ -1775,87 +1853,98 @@ async def dispense( if blow_out is None: blow_out = [False] * n - well_bottoms = [op.resource.get_absolute_location().z + op.offset.z + \ - op.resource.material_z_thickness for op in ops] - liquid_surfaces_no_lld = liquid_surface_no_lld or \ - [ls + (op.liquid_height or 0) for ls, op in zip(well_bottoms, ops)] + well_bottoms = [ + op.resource.get_absolute_location().z + op.offset.z + op.resource.material_z_thickness + for op in ops + ] + liquid_surfaces_no_lld = liquid_surface_no_lld or [ + ls + (op.liquid_height or 0) for ls, op in zip(well_bottoms, ops) + ] if lld_search_height is None: lld_search_height = [ - (wb + op.resource.get_absolute_size_z() + (2.7 if isinstance(op.resource, Well) else 5)) #? + ( + wb + op.resource.get_absolute_size_z() + (2.7 if isinstance(op.resource, Well) else 5) + ) # ? for wb, op in zip(well_bottoms, ops) ] else: lld_search_height = [wb + sh for wb, sh in zip(well_bottoms, lld_search_height)] - dispensing_modes = dispensing_mode or \ - [_dispensing_mode_for_op(empty=empty[i], jet=jet[i], blow_out=blow_out[i]) - for i in range(len(ops))] + dispensing_modes = dispensing_mode or [ + _dispensing_mode_for_op(empty=empty[i], jet=jet[i], blow_out=blow_out[i]) + for i in range(len(ops)) + ] dispense_volumes = [op.volume for op in ops] - pull_out_distance_transport_air = _fill_in_defaults(pull_out_distance_transport_air, [10.0]*n) - second_section_height = _fill_in_defaults(second_section_height, [3.2]*n) - second_section_ratio = _fill_in_defaults(second_section_ratio, [618.0]*n) + pull_out_distance_transport_air = _fill_in_defaults(pull_out_distance_transport_air, [10.0] * n) + second_section_height = _fill_in_defaults(second_section_height, [3.2] * n) + second_section_ratio = _fill_in_defaults(second_section_ratio, [618.0] * n) minimum_height = _fill_in_defaults(minimum_height, well_bottoms) - immersion_depth = _fill_in_defaults(immersion_depth, [0]*n) - immersion_depth_direction = _fill_in_defaults(immersion_depth_direction, [0]*n) - surface_following_distance = _fill_in_defaults(surface_following_distance, [0]*n) + immersion_depth = _fill_in_defaults(immersion_depth, [0] * n) + immersion_depth_direction = _fill_in_defaults(immersion_depth_direction, [0] * n) + surface_following_distance = _fill_in_defaults(surface_following_distance, [0] * n) flow_rates = [op.flow_rate or 120 for op in ops] - cut_off_speed = _fill_in_defaults(cut_off_speed, [5.0]*n) - stop_back_volume = _fill_in_defaults(stop_back_volume, default=[0]*n) - transport_air_volume = _fill_in_defaults(transport_air_volume, [0]*n) + cut_off_speed = _fill_in_defaults(cut_off_speed, [5.0] * n) + stop_back_volume = _fill_in_defaults(stop_back_volume, default=[0] * n) + transport_air_volume = _fill_in_defaults(transport_air_volume, [0] * n) blow_out_air_volumes = [op.blow_out_air_volume or 0 for op in ops] - lld_mode = _fill_in_defaults(lld_mode, [self.__class__.LLDMode.OFF]*n) - dispense_position_above_z_touch_off = _fill_in_defaults(dispense_position_above_z_touch_off, - default=[0]*n) - gamma_lld_sensitivity = _fill_in_defaults(gamma_lld_sensitivity, [1]*n) - dp_lld_sensitivity = _fill_in_defaults(dp_lld_sensitivity, [1]*n) - swap_speed = _fill_in_defaults(swap_speed, [10.0]*n) - settling_time = _fill_in_defaults(settling_time, [0]*n) - mix_volume = _fill_in_defaults(mix_volume, [0]*n) - mix_cycles = _fill_in_defaults(mix_cycles, [0]*n) - mix_position_from_liquid_surface = _fill_in_defaults(mix_position_from_liquid_surface, [0]*n) - mix_speed = _fill_in_defaults(mix_speed, [50.0]*n) - mix_surface_following_distance = _fill_in_defaults(mix_surface_following_distance, [0]*n) - limit_curve_index = _fill_in_defaults(limit_curve_index, [0]*n) + lld_mode = _fill_in_defaults(lld_mode, [self.__class__.LLDMode.OFF] * n) + dispense_position_above_z_touch_off = _fill_in_defaults( + dispense_position_above_z_touch_off, default=[0] * n + ) + gamma_lld_sensitivity = _fill_in_defaults(gamma_lld_sensitivity, [1] * n) + dp_lld_sensitivity = _fill_in_defaults(dp_lld_sensitivity, [1] * n) + swap_speed = _fill_in_defaults(swap_speed, [10.0] * n) + settling_time = _fill_in_defaults(settling_time, [0] * n) + mix_volume = _fill_in_defaults(mix_volume, [0] * n) + mix_cycles = _fill_in_defaults(mix_cycles, [0] * n) + mix_position_from_liquid_surface = _fill_in_defaults(mix_position_from_liquid_surface, [0] * n) + mix_speed = _fill_in_defaults(mix_speed, [50.0] * n) + mix_surface_following_distance = _fill_in_defaults(mix_surface_following_distance, [0] * n) + limit_curve_index = _fill_in_defaults(limit_curve_index, [0] * n) try: ret = await self.dispense_pip( tip_pattern=channels_involved, x_positions=x_positions, y_positions=y_positions, - dispensing_mode=dispensing_modes, - dispense_volumes=[round(op.volume*10) for op in ops], - lld_search_height=[round(lsh*10) for lsh in lld_search_height], - liquid_surface_no_lld=[round(ls*10) for ls in liquid_surfaces_no_lld], - pull_out_distance_transport_air=[round(po*10) for po in pull_out_distance_transport_air], - second_section_height=[round(sh*10) for sh in second_section_height], - second_section_ratio=[round(sr*10) for sr in second_section_ratio], - minimum_height=[round(mh*10) for mh in minimum_height], - immersion_depth=[round(id_*10) for id_ in immersion_depth], # [0, 0] + dispense_volumes=[round(op.volume * 10) for op in ops], + lld_search_height=[round(lsh * 10) for lsh in lld_search_height], + liquid_surface_no_lld=[round(ls * 10) for ls in liquid_surfaces_no_lld], + pull_out_distance_transport_air=[round(po * 10) for po in pull_out_distance_transport_air], + second_section_height=[round(sh * 10) for sh in second_section_height], + second_section_ratio=[round(sr * 10) for sr in second_section_ratio], + minimum_height=[round(mh * 10) for mh in minimum_height], + immersion_depth=[round(id_ * 10) for id_ in immersion_depth], # [0, 0] immersion_depth_direction=immersion_depth_direction, - surface_following_distance=[round(sfd*10) for sfd in surface_following_distance], - dispense_speed=[round(fr*10) for fr in flow_rates], - cut_off_speed=[round(cs*10) for cs in cut_off_speed], - stop_back_volume=[round(sbv*10) for sbv in stop_back_volume], - transport_air_volume=[round(tav*10) for tav in transport_air_volume], - blow_out_air_volume=[round(boa*10) for boa in blow_out_air_volumes], + surface_following_distance=[round(sfd * 10) for sfd in surface_following_distance], + dispense_speed=[round(fr * 10) for fr in flow_rates], + cut_off_speed=[round(cs * 10) for cs in cut_off_speed], + stop_back_volume=[round(sbv * 10) for sbv in stop_back_volume], + transport_air_volume=[round(tav * 10) for tav in transport_air_volume], + blow_out_air_volume=[round(boa * 10) for boa in blow_out_air_volumes], lld_mode=[mode.value for mode in lld_mode], - dispense_position_above_z_touch_off=[round(dp*10) - for dp in dispense_position_above_z_touch_off], + dispense_position_above_z_touch_off=[ + round(dp * 10) for dp in dispense_position_above_z_touch_off + ], gamma_lld_sensitivity=gamma_lld_sensitivity, dp_lld_sensitivity=dp_lld_sensitivity, - swap_speed=[round(ss*10) for ss in swap_speed], - settling_time=[round(st*10) for st in settling_time], - mix_volume=[round(mv*10) for mv in mix_volume], + swap_speed=[round(ss * 10) for ss in swap_speed], + settling_time=[round(st * 10) for st in settling_time], + mix_volume=[round(mv * 10) for mv in mix_volume], mix_cycles=mix_cycles, - mix_position_from_liquid_surface=[round(mp*10) for mp in mix_position_from_liquid_surface], - mix_speed=[round(ms*10) for ms in mix_speed], - mix_surface_following_distance=[round(msfd*10) for msfd in mix_surface_following_distance], + mix_position_from_liquid_surface=[ + round(mp * 10) for mp in mix_position_from_liquid_surface + ], + mix_speed=[round(ms * 10) for ms in mix_speed], + mix_surface_following_distance=[ + round(msfd * 10) for msfd in mix_surface_following_distance + ], limit_curve_index=limit_curve_index, - - minimum_traverse_height_at_beginning_of_a_command= - round((minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10), + minimum_traverse_height_at_beginning_of_a_command=round( + (minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10 + ), min_z_endpos=round((min_z_endpos or self._traversal_height) * 10), side_touch_off_distance=side_touch_off_distance, ) @@ -1874,14 +1963,14 @@ async def pick_up_tips96( minimum_height_command_end: Optional[float] = None, minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, ): - """ Pick up tips using the 96 head. """ + """Pick up tips using the 96 head.""" assert self.core96_head_installed, "96 head must be installed" tip_spot_a1 = pickup.resource.get_item("A1") tip_a1 = tip_spot_a1.get_tip() assert isinstance(tip_a1, HamiltonTip), "Tip type must be HamiltonTip." ttti = await self.get_or_assign_tip_type_index(tip_a1) position = tip_spot_a1.get_absolute_location() + tip_spot_a1.center() + pickup.offset - z_deposit_position += round(pickup.offset.z*10) + z_deposit_position += round(pickup.offset.z * 10) x_direction = 0 if position.x > 0 else 1 return await self.pick_up_tips_core96( @@ -1890,9 +1979,10 @@ async def pick_up_tips96( y_position=round(position.y * 10), tip_type_idx=ttti, tip_pickup_method=tip_pickup_method, - z_deposit_position=round(z_deposit_position*10), - minimum_traverse_height_at_beginning_of_a_command= - round((minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10), + z_deposit_position=round(z_deposit_position * 10), + minimum_traverse_height_at_beginning_of_a_command=round( + (minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10 + ), minimum_height_command_end=round((minimum_height_command_end or self._traversal_height) * 10), ) @@ -1903,7 +1993,7 @@ async def drop_tips96( minimum_height_command_end: Optional[float] = None, minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, ): - """ Drop tips from the 96 head. """ + """Drop tips from the 96 head.""" assert self.core96_head_installed, "96 head must be installed" if isinstance(drop.resource, TipRack): tip_a1 = drop.resource.get_item("A1") @@ -1916,21 +2006,20 @@ async def drop_tips96( x_position=abs(round(position.x * 10)), x_direction=x_direction, y_position=round(position.y * 10), - z_deposit_position=round(z_deposit_position*10), - minimum_traverse_height_at_beginning_of_a_command= - round((minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10), + z_deposit_position=round(z_deposit_position * 10), + minimum_traverse_height_at_beginning_of_a_command=round( + (minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10 + ), minimum_height_command_end=round((minimum_height_command_end or self._traversal_height) * 10), ) async def aspirate96( self, aspiration: Union[AspirationPlate, AspirationContainer], - use_lld: bool = False, liquid_height: float = 0, air_transport_retract_dist: float = 10, hlc: Optional[HamiltonLiquidClass] = None, - aspiration_type: int = 0, minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, minimal_end_height: Optional[float] = None, @@ -1953,7 +2042,7 @@ async def aspirate96( mix_speed: float = 120.0, limit_curve_index: int = 0, ): - """ Aspirate using the Core96 head. + """Aspirate using the Core96 head. Args: aspiration: The aspiration to perform. @@ -1998,8 +2087,12 @@ async def aspirate96( # get the first well and tip as representatives if isinstance(aspiration, AspirationPlate): top_left_well = aspiration.wells[0] - position = top_left_well.get_absolute_location() + top_left_well.center() + \ - Coordinate(z=top_left_well.material_z_thickness) + aspiration.offset + position = ( + top_left_well.get_absolute_location() + + top_left_well.center() + + Coordinate(z=top_left_well.material_z_thickness) + + aspiration.offset + ) else: position = aspiration.container.get_absolute_location(y="b") + aspiration.offset @@ -2022,28 +2115,30 @@ async def aspirate96( if mix_speed is None: mix_speed = 10.0 - channel_pattern = [True]*12*8 + channel_pattern = [True] * 12 * 8 return await self.aspirate_core_96( x_position=round(position.x * 10), x_direction=0, y_positions=round(position.y * 10), aspiration_type=aspiration_type, - - minimum_traverse_height_at_beginning_of_a_command= - round((minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10), + minimum_traverse_height_at_beginning_of_a_command=round( + (minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10 + ), minimal_end_height=round((minimal_end_height or self._traversal_height) * 10), - lld_search_height=round(lld_search_height*10), + lld_search_height=round(lld_search_height * 10), liquid_surface_at_function_without_lld=round(liquid_height * 10), - pull_out_distance_to_take_transport_air_in_function_without_lld= - round(air_transport_retract_dist * 10), - maximum_immersion_depth=round((maximum_immersion_depth or position.z)*10), + pull_out_distance_to_take_transport_air_in_function_without_lld=round( + air_transport_retract_dist * 10 + ), + maximum_immersion_depth=round((maximum_immersion_depth or position.z) * 10), tube_2nd_section_height_measured_from_zm=round(tube_2nd_section_height_measured_from_zm * 10), tube_2nd_section_ratio=round(tube_2nd_section_ratio * 10), immersion_depth=round(immersion_depth * 10), immersion_depth_direction=immersion_depth_direction, - liquid_surface_sink_distance_at_the_end_of_aspiration= - round(liquid_surface_sink_distance_at_the_end_of_aspiration*10), + liquid_surface_sink_distance_at_the_end_of_aspiration=round( + liquid_surface_sink_distance_at_the_end_of_aspiration * 10 + ), aspiration_volumes=round(aspiration.volume * 10), aspiration_speed=round(flow_rate * 10), transport_air_volume=round(transport_air_volume * 10), @@ -2051,14 +2146,12 @@ async def aspirate96( pre_wetting_volume=round(pre_wetting_volume * 10), lld_mode=int(use_lld), gamma_lld_sensitivity=gamma_lld_sensitivity, - swap_speed=round(swap_speed*10), + swap_speed=round(swap_speed * 10), settling_time=round(settling_time * 10), mix_volume=round(mix_volume * 10), mix_cycles=mix_cycles, - mix_position_from_liquid_surface= - round(mix_position_from_liquid_surface * 10), - surface_following_distance_during_mix= - round(surface_following_distance_during_mix * 10), + mix_position_from_liquid_surface=round(mix_position_from_liquid_surface * 10), + surface_following_distance_during_mix=round(surface_following_distance_during_mix * 10), mix_speed=round(mix_speed * 10), channel_pattern=channel_pattern, limit_curve_index=limit_curve_index, @@ -2073,12 +2166,10 @@ async def dispense96( empty: bool = False, blow_out: bool = False, hlc: Optional[HamiltonLiquidClass] = None, - liquid_height: float = 0, dispense_mode: Optional[int] = None, air_transport_retract_dist=10, use_lld: bool = False, - minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, minimal_end_height: Optional[float] = None, lld_search_height: float = 199.9, @@ -2101,7 +2192,7 @@ async def dispense96( cut_off_speed: float = 5.0, stop_back_volume: float = 0, ): - """ Dispense using the Core96 head. + """Dispense using the Core96 head. Args: dispense: The Dispense command to execute. @@ -2146,8 +2237,12 @@ async def dispense96( # get the first well and tip as representatives if isinstance(dispense, DispensePlate): top_left_well = dispense.wells[0] - position = top_left_well.get_absolute_location() + top_left_well.center() + \ - Coordinate(z=top_left_well.material_z_thickness) + dispense.offset + position = ( + top_left_well.get_absolute_location() + + top_left_well.center() + + Coordinate(z=top_left_well.material_z_thickness) + + dispense.offset + ) else: position = dispense.container.get_absolute_location(y="b") + dispense.offset @@ -2172,47 +2267,49 @@ async def dispense96( if mix_speed is None: mix_speed = 100 - channel_pattern = [True]*12*8 + channel_pattern = [True] * 12 * 8 ret = await self.dispense_core_96( dispensing_mode=dispense_mode, x_position=round(position.x * 10), x_direction=0, y_position=round(position.y * 10), - - minimum_traverse_height_at_beginning_of_a_command= - round((minimum_traverse_height_at_beginning_of_a_command or self._traversal_height)*10), - minimal_end_height=round((minimal_end_height or self._traversal_height)*10), - lld_search_height=round(lld_search_height*10), - liquid_surface_at_function_without_lld=round(liquid_height*10), - pull_out_distance_to_take_transport_air_in_function_without_lld= - round(air_transport_retract_dist*10), - maximum_immersion_depth=maximum_immersion_depth or round(position.z*10), - tube_2nd_section_height_measured_from_zm=round(tube_2nd_section_height_measured_from_zm*10), - tube_2nd_section_ratio=round(tube_2nd_section_ratio*10), - immersion_depth=round(immersion_depth*10), + minimum_traverse_height_at_beginning_of_a_command=round( + (minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10 + ), + minimal_end_height=round((minimal_end_height or self._traversal_height) * 10), + lld_search_height=round(lld_search_height * 10), + liquid_surface_at_function_without_lld=round(liquid_height * 10), + pull_out_distance_to_take_transport_air_in_function_without_lld=round( + air_transport_retract_dist * 10 + ), + maximum_immersion_depth=maximum_immersion_depth or round(position.z * 10), + tube_2nd_section_height_measured_from_zm=round(tube_2nd_section_height_measured_from_zm * 10), + tube_2nd_section_ratio=round(tube_2nd_section_ratio * 10), + immersion_depth=round(immersion_depth * 10), immersion_depth_direction=immersion_depth_direction, - liquid_surface_sink_distance_at_the_end_of_dispense= - round(liquid_surface_sink_distance_at_the_end_of_dispense*10), - dispense_volume=round(dispense.volume*10), - dispense_speed=round(flow_rate*10), - transport_air_volume=round(transport_air_volume*10), - blow_out_air_volume=round(blow_out_air_volume*10), + liquid_surface_sink_distance_at_the_end_of_dispense=round( + liquid_surface_sink_distance_at_the_end_of_dispense * 10 + ), + dispense_volume=round(dispense.volume * 10), + dispense_speed=round(flow_rate * 10), + transport_air_volume=round(transport_air_volume * 10), + blow_out_air_volume=round(blow_out_air_volume * 10), lld_mode=int(use_lld), gamma_lld_sensitivity=gamma_lld_sensitivity, - swap_speed=round(swap_speed*10), - settling_time=round(settling_time*10), - mixing_volume=round(mixing_volume*10), + swap_speed=round(swap_speed * 10), + settling_time=round(settling_time * 10), + mixing_volume=round(mixing_volume * 10), mixing_cycles=mixing_cycles, - mixing_position_from_liquid_surface=round(mixing_position_from_liquid_surface*10), - surface_following_distance_during_mixing=round(surface_following_distance_during_mixing*10), - mix_speed=round(mix_speed*10), + mixing_position_from_liquid_surface=round(mixing_position_from_liquid_surface * 10), + surface_following_distance_during_mixing=round(surface_following_distance_during_mixing * 10), + mix_speed=round(mix_speed * 10), channel_pattern=channel_pattern, limit_curve_index=limit_curve_index, tadm_algorithm=False, recording_mode=0, - cut_off_speed=round(cut_off_speed*10), - stop_back_volume=round(stop_back_volume*10), + cut_off_speed=round(cut_off_speed * 10), + stop_back_volume=round(stop_back_volume * 10), ) # Was this ever true? Just copied it over from pyhamilton. Could have something to do with @@ -2243,9 +2340,9 @@ async def iswap_pick_up_resource( collision_control_level: int = 0, acceleration_index_high_acc: int = 4, acceleration_index_low_acc: int = 1, - fold_up_sequence_at_the_end_of_process: bool = True + fold_up_sequence_at_the_end_of_process: bool = True, ): - """ Pick up a resource using iSWAP. + """Pick up a resource using iSWAP. Low level component of :meth:`move_resource` """ @@ -2274,17 +2371,18 @@ async def iswap_pick_up_resource( GripDirection.BACK: 3, GripDirection.LEFT: 4, }[grip_direction], - minimum_traverse_height_at_beginning_of_a_command= - round(minimum_traverse_height_at_beginning_of_a_command*10), - z_position_at_the_command_end=round(z_position_at_the_command_end*10), + minimum_traverse_height_at_beginning_of_a_command=round( + minimum_traverse_height_at_beginning_of_a_command * 10 + ), + z_position_at_the_command_end=round(z_position_at_the_command_end * 10), grip_strength=grip_strength, - open_gripper_position=round(plate_width*10) + 30, - plate_width=round(plate_width*10) - 33, - plate_width_tolerance=round(plate_width_tolerance*10), + open_gripper_position=round(plate_width * 10) + 30, + plate_width=round(plate_width * 10) - 33, + plate_width_tolerance=round(plate_width_tolerance * 10), collision_control_level=collision_control_level, acceleration_index_high_acc=acceleration_index_high_acc, acceleration_index_low_acc=acceleration_index_low_acc, - fold_up_sequence_at_the_end_of_process=fold_up_sequence_at_the_end_of_process + fold_up_sequence_at_the_end_of_process=fold_up_sequence_at_the_end_of_process, ) async def iswap_move_picked_up_resource( @@ -2295,9 +2393,9 @@ async def iswap_move_picked_up_resource( minimum_traverse_height_at_beginning_of_a_command: float = 284.0, collision_control_level: int = 1, acceleration_index_high_acc: int = 4, - acceleration_index_low_acc: int = 1 + acceleration_index_low_acc: int = 1, ): - """ After a resource is picked up, move it to a new location but don't release it yet. + """After a resource is picked up, move it to a new location but don't release it yet. Low level component of :meth:`move_resource` """ @@ -2318,11 +2416,12 @@ async def iswap_move_picked_up_resource( GripDirection.BACK: 3, GripDirection.LEFT: 4, }[grip_direction], - minimum_traverse_height_at_beginning_of_a_command= - round(minimum_traverse_height_at_beginning_of_a_command*10), + minimum_traverse_height_at_beginning_of_a_command=round( + minimum_traverse_height_at_beginning_of_a_command * 10 + ), collision_control_level=collision_control_level, acceleration_index_high_acc=acceleration_index_high_acc, - acceleration_index_low_acc=acceleration_index_low_acc + acceleration_index_low_acc=acceleration_index_low_acc, ) async def iswap_release_picked_up_resource( @@ -2337,7 +2436,7 @@ async def iswap_release_picked_up_resource( z_position_at_the_command_end: float = 284.0, collision_control_level: int = 0, ): - """ After a resource is picked up, release it at the specified location. + """After a resource is picked up, release it at the specified location. Low level component of :meth:`move_resource` Args: @@ -2353,10 +2452,12 @@ async def iswap_release_picked_up_resource( # Get center of source plate in absolute space. # The computation of the center has to be rotated so that the offset is in absolute space. - center_in_absolute_space = Coordinate(*matrix_vector_multiply_3x3( - resource.rotated(z=rotation).get_absolute_rotation().get_rotation_matrix(), - resource.center().vector() - )) + center_in_absolute_space = Coordinate( + *matrix_vector_multiply_3x3( + resource.rotated(z=rotation).get_absolute_rotation().get_rotation_matrix(), + resource.center().vector(), + ) + ) # This is when the resource is rotated (around its origin), but we also need to translate # so that the left front bottom corner of the plate is lfb in absolute space, not local. center_in_absolute_space += get_child_location(resource.rotated(z=rotation)) @@ -2385,10 +2486,11 @@ async def iswap_release_picked_up_resource( GripDirection.BACK: 3, GripDirection.LEFT: 4, }[grip_direction], - minimum_traverse_height_at_beginning_of_a_command= - round(minimum_traverse_height_at_beginning_of_a_command*10), - z_position_at_the_command_end=round(z_position_at_the_command_end*10), - open_gripper_position=round(plate_width*10) + 30, + minimum_traverse_height_at_beginning_of_a_command=round( + minimum_traverse_height_at_beginning_of_a_command * 10 + ), + z_position_at_the_command_end=round(z_position_at_the_command_end * 10), + open_gripper_position=round(plate_width * 10) + 30, collision_control_level=collision_control_level, ) @@ -2405,7 +2507,7 @@ async def core_pick_up_resource( channel_1: int = 7, channel_2: int = 8, ): - """ Pick up resource with CoRe gripper tool + """Pick up resource with CoRe gripper tool Low level component of :meth:`move_resource` Args: @@ -2425,7 +2527,7 @@ async def core_pick_up_resource( # Get center of source plate. Also gripping height and plate width. center = resource.get_absolute_location(x="c", y="c", z="b") + offset grip_height = center.z + resource.get_absolute_size_z() - pickup_distance_from_top - grip_width = resource.get_absolute_size_y() #grip width is y size of resource + grip_width = resource.get_absolute_size_y() # grip width is y size of resource if self.core_parked: await self.get_core(p1=channel_1, p2=channel_2) @@ -2434,16 +2536,18 @@ async def core_pick_up_resource( x_position=round(center.x * 10), x_direction=0, y_position=round(center.y * 10), - y_gripping_speed=round(y_gripping_speed*10), + y_gripping_speed=round(y_gripping_speed * 10), z_position=round(grip_height * 10), - z_speed=round(z_speed*10), - open_gripper_position=round(grip_width*10) + 30, - plate_width=round(grip_width*10) - 30, + z_speed=round(z_speed * 10), + open_gripper_position=round(grip_width * 10) + 30, + plate_width=round(grip_width * 10) - 30, grip_strength=grip_strength, - minimum_traverse_height_at_beginning_of_a_command= - round((minimum_traverse_height_at_beginning_of_a_command or self._traversal_height)*10), - minimum_z_position_at_the_command_end= - round((minimum_z_position_at_the_command_end or self._traversal_height)*10), + minimum_traverse_height_at_beginning_of_a_command=round( + (minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10 + ), + minimum_z_position_at_the_command_end=round( + (minimum_z_position_at_the_command_end or self._traversal_height) * 10 + ), ) async def core_move_picked_up_resource( @@ -2454,7 +2558,7 @@ async def core_move_picked_up_resource( acceleration_index: int = 4, z_speed: float = 50.0, ): - """ After a ressource is picked up, move it to a new location but don't release it yet. + """After a ressource is picked up, move it to a new location but don't release it yet. Low level component of :meth:`move_resource` Args: @@ -2477,9 +2581,10 @@ async def core_move_picked_up_resource( x_acceleration_index=acceleration_index, y_position=round(center.y * 10), z_position=round(center.z * 10), - z_speed=round(z_speed*10), - minimum_traverse_height_at_beginning_of_a_command= - round((minimum_traverse_height_at_beginning_of_a_command or self._traversal_height)*10), + z_speed=round(z_speed * 10), + minimum_traverse_height_at_beginning_of_a_command=round( + (minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10 + ), ) async def core_release_picked_up_resource( @@ -2490,9 +2595,9 @@ async def core_release_picked_up_resource( offset: Coordinate = Coordinate.zero(), minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, z_position_at_the_command_end: Optional[float] = None, - return_tool: bool = True + return_tool: bool = True, ): - """ Place resource with CoRe gripper tool + """Place resource with CoRe gripper tool Low level component of :meth:`move_resource` Args: @@ -2519,12 +2624,14 @@ async def core_release_picked_up_resource( z_position=round(grip_height * 10), z_press_on_distance=0, z_speed=500, - open_gripper_position=round(grip_width*10) + 30, - minimum_traverse_height_at_beginning_of_a_command= - round((minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10), - z_position_at_the_command_end= - round((z_position_at_the_command_end or self._traversal_height)*10), - return_tool=return_tool + open_gripper_position=round(grip_width * 10) + 30, + minimum_traverse_height_at_beginning_of_a_command=round( + (minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10 + ), + z_position_at_the_command_end=round( + (z_position_at_the_command_end or self._traversal_height) * 10 + ), + return_tool=return_tool, ) async def move_resource( @@ -2536,7 +2643,7 @@ async def move_resource( core_grip_strength: int = 15, return_core_gripper: bool = True, ): - """ Move a resource. + """Move a resource. Args: move: The move to perform. @@ -2584,17 +2691,18 @@ async def move_resource( resource=move.resource, grip_direction=move.get_direction, minimum_traverse_height_at_beginning_of_a_command=self._traversal_height, - # int(previous_location.z + move.resource.get_size_z() / 2) * 10, # "minimum" is a scam. + # int(previous_location.z + move.resource.get_size_z() / 2) * 10, # "minimum" is a scam. collision_control_level=1, acceleration_index_high_acc=4, - acceleration_index_low_acc=1) + acceleration_index_low_acc=1, + ) else: await self.core_move_picked_up_resource( location=location, resource=move.resource, minimum_traverse_height_at_beginning_of_a_command=self._traversal_height, - # int(previous_location.z + move.resource.get_size_z() / 2) * 10, - acceleration_index=4 + # int(previous_location.z + move.resource.get_size_z() / 2) * 10, + acceleration_index=4, ) previous_location = location @@ -2607,7 +2715,7 @@ async def move_resource( grip_direction=move.put_direction, pickup_distance_from_top=move.pickup_distance_from_top, minimum_traverse_height_at_beginning_of_a_command=self._traversal_height, - # int(previous_location.z + move.resource.get_size_z() / 2) * 10, # "minimum" is a scam. + # int(previous_location.z + move.resource.get_size_z() / 2) * 10, # "minimum" is a scam. z_position_at_the_command_end=self._traversal_height, ) else: @@ -2618,28 +2726,30 @@ async def move_resource( pickup_distance_from_top=move.pickup_distance_from_top, minimum_traverse_height_at_beginning_of_a_command=self._traversal_height, z_position_at_the_command_end=self._traversal_height, - # int(previous_location.z + move.resource.get_size_z() / 2) * 10, - return_tool=return_core_gripper + # int(previous_location.z + move.resource.get_size_z() / 2) * 10, + return_tool=return_core_gripper, ) async def prepare_for_manual_channel_operation(self, channel: int): - """ Prepare for manual operation. """ + """Prepare for manual operation.""" await self.position_max_free_y_for_n(pipetting_channel_index=channel + 1) - async def move_channel_x(self, channel: int, x: float): # pylint: disable=unused-argument - """ Move a channel in the x direction. """ + async def move_channel_x(self, channel: int, x: float): # pylint: disable=unused-argument + """Move a channel in the x direction.""" await self.position_left_x_arm_(round(x * 10)) async def move_channel_y(self, channel: int, y: float): - """ Move a channel in the y direction. """ + """Move a channel in the y direction.""" await self.position_single_pipetting_channel_in_y_direction( - pipetting_channel_index=channel + 1, y_position=round(y * 10)) + pipetting_channel_index=channel + 1, y_position=round(y * 10) + ) async def move_channel_z(self, channel: int, z: float): - """ Move a channel in the z direction. """ + """Move a channel in the z direction.""" await self.position_single_pipetting_channel_in_z_direction( - pipetting_channel_index=channel + 1, z_position=round(z*10)) + pipetting_channel_index=channel + 1, z_position=round(z * 10) + ) async def core_check_resource_exists_at_location_center( self, @@ -2650,37 +2760,38 @@ async def core_check_resource_exists_at_location_center( minimum_traverse_height_at_beginning_of_a_command: float = 275.0, z_position_at_the_command_end: float = 275.0, enable_recovery: bool = True, - audio_feedback: bool = True + audio_feedback: bool = True, ) -> bool: - """ Check existence of resource with CoRe gripper tool - a "Get plate using CO-RE gripper" + error handling - Which channels are used for resource check is dependent on which channels have been used for - `STAR.get_core(p1: int, p2: int)` which is a prerequisite for this check function. - - Args: - location: Location to check for resource - resource: Resource to check for. - gripper_y_margin = Distance between the front / back wall of the resource - and the grippers during "bumping" / checking - offset: Offset from resource position in mm. - minimum_traverse_height_at_beginning_of_a_command: Minimum traverse height at beginning of - a command [mm] (refers to all channels independent of tip pattern parameter 'tm'). - Must be between 0 and 360.0. - z_position_at_the_command_end: Minimum z-Position at end of a command [mm] (refers to - all channels independent of tip pattern parameter 'tm'). Must be between 0 and 360.0. - enable_recovery: if True will ask for user input if resource was not found - audio_feedback: enable controlling computer to emit different sounds when - finding/not finding the resource - - Returns: - True if resource was found, False if resource was not found - """ + """Check existence of resource with CoRe gripper tool + a "Get plate using CO-RE gripper" + error handling + Which channels are used for resource check is dependent on which channels have been used for + `STAR.get_core(p1: int, p2: int)` which is a prerequisite for this check function. + + Args: + location: Location to check for resource + resource: Resource to check for. + gripper_y_margin = Distance between the front / back wall of the resource + and the grippers during "bumping" / checking + offset: Offset from resource position in mm. + minimum_traverse_height_at_beginning_of_a_command: Minimum traverse height at beginning of + a command [mm] (refers to all channels independent of tip pattern parameter 'tm'). + Must be between 0 and 360.0. + z_position_at_the_command_end: Minimum z-Position at end of a command [mm] (refers to + all channels independent of tip pattern parameter 'tm'). Must be between 0 and 360.0. + enable_recovery: if True will ask for user input if resource was not found + audio_feedback: enable controlling computer to emit different sounds when + finding/not finding the resource + + Returns: + True if resource was found, False if resource was not found + """ center = location + resource.centers()[0] + offset - y_width_to_gripper_bump = resource.get_absolute_size_y() - gripper_y_margin*2 - assert 9 <= y_width_to_gripper_bump <= round(resource.get_absolute_size_y()), \ - f"width between channels must be between 9 and {resource.get_absolute_size_y()} mm" \ + y_width_to_gripper_bump = resource.get_absolute_size_y() - gripper_y_margin * 2 + assert 9 <= y_width_to_gripper_bump <= round(resource.get_absolute_size_y()), ( + f"width between channels must be between 9 and {resource.get_absolute_size_y()} mm" " (i.e. the minimal distance between channels and the max y size of the resource" + ) # Check if CoRe gripper currently in use cores_used = not self._core_parked @@ -2702,11 +2813,12 @@ async def core_check_resource_exists_at_location_center( y_gripping_speed=50, x_direction=0, z_speed=600, - grip_strength = 20, + grip_strength=20, # Enable mods of channel z position for check acceleration - minimum_traverse_height_at_beginning_of_a_command= - round(minimum_traverse_height_at_beginning_of_a_command*10), - minimum_z_position_at_the_command_end=round(z_position_at_the_command_end*10), + minimum_traverse_height_at_beginning_of_a_command=round( + minimum_traverse_height_at_beginning_of_a_command * 10 + ), + minimum_z_position_at_the_command_end=round(z_position_at_the_command_end * 10), ) except STARFirmwareError as exc: for module_error in exc.errors.values(): @@ -2718,18 +2830,23 @@ async def core_check_resource_exists_at_location_center( if audio_feedback: audio.play_not_found() if enable_recovery: - print(f"\nWARNING: Resource '{resource.name}' not found at center" \ - f" location {(center.x, center.y, center.z)} during check no {try_counter}.") - user_prompt = input("Have you checked resource is present?" \ - "\n [ yes ] -> machine will check location again" \ - "\n [ abort ] -> machine will abort run\n Answer:" - ) + print( + f"\nWARNING: Resource '{resource.name}' not found at center" + f" location {(center.x, center.y, center.z)} during check no {try_counter}." + ) + user_prompt = input( + "Have you checked resource is present?" + "\n [ yes ] -> machine will check location again" + "\n [ abort ] -> machine will abort run\n Answer:" + ) if user_prompt == "yes": try_counter += 1 elif user_prompt == "abort": - raise ValueError(f"Resource '{resource.name}' not found at center" \ - f" location {(center.x,center.y,center.z)}" \ - " & error not resolved -> aborted resource movement.") + raise ValueError( + f"Resource '{resource.name}' not found at center" + f" location {(center.x,center.y,center.z)}" + " & error not resolved -> aborted resource movement." + ) else: # Resource was not found return False @@ -2744,7 +2861,7 @@ async def core_check_resource_exists_at_location_center( # -------------- 3.2 System general commands -------------- async def pre_initialize_instrument(self): - """ Pre-initialize instrument """ + """Pre-initialize instrument""" return await self.send_command(module="C0", command="VI") async def define_tip_needle( @@ -2754,9 +2871,9 @@ async def define_tip_needle( tip_length: int, maximum_tip_volume: int, tip_size: TipSize, - pickup_method: TipPickupMethod + pickup_method: TipPickupMethod, ): - """ Tip/needle definition. + """Tip/needle definition. Args: tip_type_table_index: tip_table_index @@ -2785,13 +2902,13 @@ async def define_tip_needle( tl=f"{tip_length:04}", tv=f"{maximum_tip_volume:05}", tg=tip_size.value, - tu=pickup_method.value + tu=pickup_method.value, ) # -------------- 3.2.1 System query -------------- async def request_error_code(self): - """ Request error code + """Request error code Here the last saved error messages can be retrieved. The error buffer is automatically voided when a new command is started. All configured nodes are displayed. @@ -2805,7 +2922,7 @@ async def request_error_code(self): return await self.send_command(module="C0", command="RE") async def request_firmware_version(self): - """ Request firmware version + """Request firmware version Returns: TODO: Rfid0001rf1.0S 2009-06-24 A """ @@ -2813,7 +2930,7 @@ async def request_firmware_version(self): return await self.send_command(module="C0", command="RF") async def request_parameter_value(self): - """ Request parameter value + """Request parameter value Returns: TODO: Raid1111er00/00yg1200 """ @@ -2828,7 +2945,7 @@ class BoardType(enum.Enum): UNKNOWN = -1 async def request_electronic_board_type(self): - """ Request electronic board type + """Request electronic board type Returns: The board type. @@ -2844,7 +2961,7 @@ async def request_electronic_board_type(self): # TODO: parse response. async def request_supply_voltage(self): - """ Request supply voltage + """Request supply voltage Request supply voltage (for LDPB only) """ @@ -2852,19 +2969,19 @@ async def request_supply_voltage(self): return await self.send_command(module="C0", command="MU") async def request_instrument_initialization_status(self) -> bool: - """ Request instrument initialization status """ + """Request instrument initialization status""" resp = await self.send_command(module="C0", command="QW", fmt="qw#") return resp is not None and resp["qw"] == 1 async def request_autoload_initialization_status(self) -> bool: - """ Request autoload initialization status """ + """Request autoload initialization status""" resp = await self.send_command(module="I0", command="QW", fmt="qw#") return resp is not None and resp["qw"] == 1 async def request_name_of_last_faulty_parameter(self): - """ Request name of last faulty parameter + """Request name of last faulty parameter Returns: TODO: Name of last parameter with syntax error @@ -2877,7 +2994,7 @@ async def request_name_of_last_faulty_parameter(self): return await self.send_command(module="C0", command="VP", fmt="vp&&") async def request_master_status(self): - """ Request master status + """Request master status Returns: TODO: see page 19 (SFCO.0036) """ @@ -2885,7 +3002,7 @@ async def request_master_status(self): return await self.send_command(module="C0", command="RQ") async def request_number_of_presence_sensors_installed(self): - """ Request number of presence sensors installed + """Request number of presence sensors installed Returns: number of sensors installed (1...103) @@ -2895,7 +3012,7 @@ async def request_number_of_presence_sensors_installed(self): return resp["sr"] async def request_eeprom_data_correctness(self): - """ Request EEPROM data correctness + """Request EEPROM data correctness Returns: TODO: (SFCO.0149) """ @@ -2906,12 +3023,8 @@ async def request_eeprom_data_correctness(self): # -------------- 3.3.1 Volatile Settings -------------- - - async def set_single_step_mode( - self, - single_step_mode: bool = False - ): - """ Set Single step mode + async def set_single_step_mode(self, single_step_mode: bool = False): + """Set Single step mode Args: single_step_mode: Single Step Mode. Default False. @@ -2924,13 +3037,13 @@ async def set_single_step_mode( ) async def trigger_next_step(self): - """ Trigger next step (Single step mode) """ + """Trigger next step (Single step mode)""" # TODO: this command has no reply!!!! return await self.send_command(module="C0", command="NS") async def halt(self): - """ Halt + """Halt Intermediate sequences not yet carried out and the commands in the command stack are discarded. Sequence already in process is @@ -2940,7 +3053,7 @@ async def halt(self): return await self.send_command(module="C0", command="HD") async def save_all_cycle_counters(self): - """ Save all cycle counters + """Save all cycle counters Save all cycle counters of the instrument """ @@ -2948,7 +3061,7 @@ async def save_all_cycle_counters(self): return await self.send_command(module="C0", command="AZ") async def set_not_stop(self, non_stop): - """ Set not stop mode + """Set not stop mode Args: non_stop: True if non stop mode should be turned on after command is sent. @@ -2963,11 +3076,9 @@ async def set_not_stop(self, non_stop): # -------------- 3.3.2 Non volatile settings (stored in EEPROM) -------------- async def store_installation_data( - self, - date: datetime.datetime = datetime.datetime.now(), - serial_number: str = "0000" + self, date: datetime.datetime = datetime.datetime.now(), serial_number: str = "0000" ): - """ Store installation data + """Store installation data Args: date: installation date. @@ -2975,20 +3086,15 @@ async def store_installation_data( assert len(serial_number) == 4, "serial number must be 4 chars long" - return await self.send_command( - module="C0", - command="SI", - si=date, - sn=serial_number - ) + return await self.send_command(module="C0", command="SI", si=date, sn=serial_number) async def store_verification_data( self, verification_subject: int = 0, date: datetime.datetime = datetime.datetime.now(), - verification_status: bool = False + verification_status: bool = False, ): - """ Store verification data + """Store verification data Args: verification_subject: verification subject. Default 0. Must be between 0 and 24. @@ -3007,54 +3113,39 @@ async def store_verification_data( ) async def additional_time_stamp(self): - """ Additional time stamp """ + """Additional time stamp""" return await self.send_command(module="C0", command="AT") async def set_x_offset_x_axis_iswap(self, x_offset: int): - """ Set X-offset X-axis <-> iSWAP + """Set X-offset X-axis <-> iSWAP Args: x_offset: X-offset [0.1mm] """ - return await self.send_command( - module="C0", - command="AG", - x_offset=x_offset - ) + return await self.send_command(module="C0", command="AG", x_offset=x_offset) async def set_x_offset_x_axis_core_96_head(self, x_offset: int): - """ Set X-offset X-axis <-> CoRe 96 head + """Set X-offset X-axis <-> CoRe 96 head Args: x_offset: X-offset [0.1mm] """ - return await self.send_command( - module="C0", - command="AF", - x_offset=x_offset - ) + return await self.send_command(module="C0", command="AF", x_offset=x_offset) async def set_x_offset_x_axis_core_nano_pipettor_head(self, x_offset: int): - """ Set X-offset X-axis <-> CoRe 96 head + """Set X-offset X-axis <-> CoRe 96 head Args: x_offset: X-offset [0.1mm] """ - return await self.send_command( - module="C0", - command="AF", - x_offset=x_offset - ) + return await self.send_command(module="C0", command="AF", x_offset=x_offset) - async def save_download_date( - self, - date: datetime.datetime = datetime.datetime.now() - ): - """ Save Download date + async def save_download_date(self, date: datetime.datetime = datetime.datetime.now()): + """Save Download date Args: date: download date. Default now. @@ -3066,12 +3157,8 @@ async def save_download_date( ao=date, ) - async def save_technical_status_of_assemblies( - self, - processor_board: str, - power_supply: str - ): - """ Save technical status of assemblies + async def save_technical_status_of_assemblies(self, processor_board: str, power_supply: str): + """Save technical status of assemblies Args: processor_board: Processor board. Art.Nr./Rev./Ser.No. (000000/00/0000) @@ -3086,9 +3173,9 @@ async def save_technical_status_of_assemblies( async def set_instrument_configuration( self, - configuration_data_1: Optional[str] = None, # TODO: configuration byte - configuration_data_2: Optional[str] = None, # TODO: configuration byte - configuration_data_3: Optional[str] = None, # TODO: configuration byte + configuration_data_1: Optional[str] = None, # TODO: configuration byte + configuration_data_2: Optional[str] = None, # TODO: configuration byte + configuration_data_3: Optional[str] = None, # TODO: configuration byte instrument_size_in_slots_x_range: int = 54, auto_load_size_in_slots: int = 54, tip_waste_x_position: int = 13400, @@ -3106,9 +3193,9 @@ async def set_instrument_configuration( minimal_raster_pitch_of_robotic_channels: int = 360, pip_maximal_y_position: int = 6065, left_arm_minimal_y_position: int = 60, - right_arm_minimal_y_position: int = 60 + right_arm_minimal_y_position: int = 60, ): - """ Set instrument configuration + """Set instrument configuration Args: configuration_data_1: configuration data 1. @@ -3149,35 +3236,44 @@ async def set_instrument_configuration( and 9999. Default 60. """ - assert 1 <= instrument_size_in_slots_x_range <= 9, \ - "instrument_size_in_slots_x_range must be between 1 and 99" + assert ( + 1 <= instrument_size_in_slots_x_range <= 9 + ), "instrument_size_in_slots_x_range must be between 1 and 99" assert 1 <= auto_load_size_in_slots <= 54, "auto_load_size_in_slots must be between 1 and 54" assert 1000 <= tip_waste_x_position <= 25000, "tip_waste_x_position must be between 1 and 25000" - assert 0 <= right_x_drive_configuration_byte_1 <= 1, \ - "right_x_drive_configuration_byte_1 must be between 0 and 1" - assert 0 <= right_x_drive_configuration_byte_2 <= 1, \ - "right_x_drive_configuration_byte_2 must be between 0 and must1" - assert 0 <= minimal_iswap_collision_free_position <= 30000, \ - "minimal_iswap_collision_free_position must be between 0 and 30000" - assert 0 <= maximal_iswap_collision_free_position <= 30000, \ - "maximal_iswap_collision_free_position must be between 0 and 30000" + assert ( + 0 <= right_x_drive_configuration_byte_1 <= 1 + ), "right_x_drive_configuration_byte_1 must be between 0 and 1" + assert ( + 0 <= right_x_drive_configuration_byte_2 <= 1 + ), "right_x_drive_configuration_byte_2 must be between 0 and must1" + assert ( + 0 <= minimal_iswap_collision_free_position <= 30000 + ), "minimal_iswap_collision_free_position must be between 0 and 30000" + assert ( + 0 <= maximal_iswap_collision_free_position <= 30000 + ), "maximal_iswap_collision_free_position must be between 0 and 30000" assert 0 <= left_x_arm_width <= 9999, "left_x_arm_width must be between 0 and 9999" assert 0 <= right_x_arm_width <= 9999, "right_x_arm_width must be between 0 and 9999" assert 0 <= num_pip_channels <= 16, "num_pip_channels must be between 0 and 16" assert 0 <= num_xl_channels <= 8, "num_xl_channels must be between 0 and 8" assert 0 <= num_robotic_channels <= 8, "num_robotic_channels must be between 0 and 8" - assert 0 <= minimal_raster_pitch_of_pip_channels <= 999, \ - "minimal_raster_pitch_of_pip_channels must be between 0 and 999" - assert 0 <= minimal_raster_pitch_of_xl_channels <= 999, \ - "minimal_raster_pitch_of_xl_channels must be between 0 and 999" - assert 0 <= minimal_raster_pitch_of_robotic_channels <= 999, \ - "minimal_raster_pitch_of_robotic_channels must be between 0 and 999" - assert 0 <= pip_maximal_y_position <= 9999, \ - "pip_maximal_y_position must be between 0 and 9999" - assert 0 <= left_arm_minimal_y_position <= 9999, \ - "left_arm_minimal_y_position must be between 0 and 9999" - assert 0 <= right_arm_minimal_y_position <= 9999, \ - "right_arm_minimal_y_position must be between 0 and 9999" + assert ( + 0 <= minimal_raster_pitch_of_pip_channels <= 999 + ), "minimal_raster_pitch_of_pip_channels must be between 0 and 999" + assert ( + 0 <= minimal_raster_pitch_of_xl_channels <= 999 + ), "minimal_raster_pitch_of_xl_channels must be between 0 and 999" + assert ( + 0 <= minimal_raster_pitch_of_robotic_channels <= 999 + ), "minimal_raster_pitch_of_robotic_channels must be between 0 and 999" + assert 0 <= pip_maximal_y_position <= 9999, "pip_maximal_y_position must be between 0 and 9999" + assert ( + 0 <= left_arm_minimal_y_position <= 9999 + ), "left_arm_minimal_y_position must be between 0 and 9999" + assert ( + 0 <= right_arm_minimal_y_position <= 9999 + ), "right_arm_minimal_y_position must be between 0 and 9999" return await self.send_command( module="C0", @@ -3205,11 +3301,8 @@ async def set_instrument_configuration( yx=right_arm_minimal_y_position, ) - async def save_pip_channel_validation_status( - self, - validation_status: bool = False - ): - """ Save PIP channel validation status + async def save_pip_channel_validation_status(self, validation_status: bool = False): + """Save PIP channel validation status Args: validation_status: PIP channel validation status. Default False. @@ -3221,11 +3314,8 @@ async def save_pip_channel_validation_status( tq=validation_status, ) - async def save_xl_channel_validation_status( - self, - validation_status: bool = False - ): - """ Save XL channel validation status + async def save_xl_channel_validation_status(self, validation_status: bool = False): + """Save XL channel validation status Args: validation_status: XL channel validation status. Default False. @@ -3239,16 +3329,12 @@ async def save_xl_channel_validation_status( # TODO: response async def configure_node_names(self): - """ Configure node names """ + """Configure node names""" return await self.send_command(module="C0", command="AJ") - async def set_deck_data( - self, - data_index: int = 0, - data_stream: str = "0" - ): - """ set deck data + async def set_deck_data(self, data_index: int = 0, data_stream: str = "0"): + """set deck data Args: data_index: data index. Must be between 0 and 9. Default 0. @@ -3268,28 +3354,25 @@ async def set_deck_data( # -------------- 3.3.3 Settings query (stored in EEPROM) -------------- async def request_technical_status_of_assemblies(self): - """ Request Technical status of assemblies """ + """Request Technical status of assemblies""" # TODO: parse res return await self.send_command(module="C0", command="QT") async def request_installation_data(self): - """ Request installation data """ + """Request installation data""" # TODO: parse res return await self.send_command(module="C0", command="RI") async def request_download_date(self): - """ Request download date """ + """Request download date""" # TODO: parse res return await self.send_command(module="C0", command="RO") - async def request_verification_data( - self, - verification_subject: int = 0 - ): - """ Request download date + async def request_verification_data(self, verification_subject: int = 0): + """Request download date Args: verification_subject: verification subject. Must be between 0 and 24. Default 0. @@ -3298,51 +3381,50 @@ async def request_verification_data( assert 0 <= verification_subject <= 24, "verification_subject must be between 0 and 24" # TODO: parse results. - return await self.send_command( - module="C0", - command="RO", - vo = verification_subject - ) + return await self.send_command(module="C0", command="RO", vo=verification_subject) async def request_additional_timestamp_data(self): - """ Request additional timestamp data """ + """Request additional timestamp data""" # TODO: parse res return await self.send_command(module="C0", command="RS") async def request_pip_channel_validation_status(self): - """ Request PIP channel validation status """ + """Request PIP channel validation status""" # TODO: parse res return await self.send_command(module="C0", command="RJ") async def request_xl_channel_validation_status(self): - """ Request XL channel validation status """ + """Request XL channel validation status""" # TODO: parse res return await self.send_command(module="C0", command="UJ") async def request_machine_configuration(self): - """ Request machine configuration """ + """Request machine configuration""" # TODO: parse res return await self.send_command(module="C0", command="RM", fmt="kb**kp**") async def request_extended_configuration(self): - """ Request extended configuration """ + """Request extended configuration""" - return await self.send_command(module="C0", command="QM", - fmt="ka******ke********xt##xa##xw#####xl**xn**xr**xo**xm#####xx#####xu####xv####kc#kr#ys###"+\ - "kl###km###ym####yu####yx####") + return await self.send_command( + module="C0", + command="QM", + fmt="ka******ke********xt##xa##xw#####xl**xn**xr**xo**xm#####xx#####xu####xv####kc#kr#ys###" + + "kl###km###ym####yu####yx####", + ) async def request_node_names(self): - """ Request node names """ + """Request node names""" # TODO: parse res return await self.send_command(module="C0", command="RK") async def request_deck_data(self): - """ Request deck data """ + """Request deck data""" # TODO: parse res return await self.send_command(module="C0", command="VD") @@ -3351,11 +3433,8 @@ async def request_deck_data(self): # -------------- 3.4.1 Movements -------------- - async def position_left_x_arm_( - self, - x_position: int = 0 - ): - """ Position left X-Arm + async def position_left_x_arm_(self, x_position: int = 0): + """Position left X-Arm Collision risk! @@ -3371,11 +3450,8 @@ async def position_left_x_arm_( xs=f"{x_position:05}", ) - async def position_right_x_arm_( - self, - x_position: int = 0 - ): - """ Position right X-Arm + async def position_right_x_arm_(self, x_position: int = 0): + """Position right X-Arm Collision risk! @@ -3392,10 +3468,9 @@ async def position_right_x_arm_( ) async def move_left_x_arm_to_position_with_all_attached_components_in_z_safety_position( - self, - x_position: int = 0 + self, x_position: int = 0 ): - """ Move left X-arm to position with all attached components in Z-safety position + """Move left X-arm to position with all attached components in Z-safety position Args: x_position: X-Position [0.1mm]. Must be between 0 and 30000. Default 0. @@ -3410,10 +3485,9 @@ async def move_left_x_arm_to_position_with_all_attached_components_in_z_safety_p ) async def move_right_x_arm_to_position_with_all_attached_components_in_z_safety_position( - self, - x_position: int = 0 + self, x_position: int = 0 ): - """ Move right X-arm to position with all attached components in Z-safety position + """Move right X-arm to position with all attached components in Z-safety position Args: x_position: X-Position [0.1mm]. Must be between 0 and 30000. Default 0. @@ -3435,9 +3509,9 @@ async def occupy_and_provide_area_for_external_access( taken_area_left_margin: int = 0, taken_area_left_margin_direction: int = 0, taken_area_size: int = 0, - arm_preposition_mode_related_to_taken_areas: int = 0 + arm_preposition_mode_related_to_taken_areas: int = 0, ): - """ Occupy and provide area for external access + """Occupy and provide area for external access Args: taken_area_identification_number: taken area identification number. Must be between 0 and @@ -3450,14 +3524,17 @@ async def occupy_and_provide_area_for_external_access( 1) all arms left. 2) all arms right. """ - assert 0 <= taken_area_identification_number <= 9999, \ - "taken_area_identification_number must be between 0 and 9999" + assert ( + 0 <= taken_area_identification_number <= 9999 + ), "taken_area_identification_number must be between 0 and 9999" assert 0 <= taken_area_left_margin <= 99, "taken_area_left_margin must be between 0 and 99" - assert 0 <= taken_area_left_margin_direction <= 1, \ - "taken_area_left_margin_direction must be between 0 and 1" + assert ( + 0 <= taken_area_left_margin_direction <= 1 + ), "taken_area_left_margin_direction must be between 0 and 1" assert 0 <= taken_area_size <= 50000, "taken_area_size must be between 0 and 50000" - assert 0 <= arm_preposition_mode_related_to_taken_areas <= 2, \ - "arm_preposition_mode_related_to_taken_areas must be between 0 and 2" + assert ( + 0 <= arm_preposition_mode_related_to_taken_areas <= 2 + ), "arm_preposition_mode_related_to_taken_areas must be between 0 and 2" return await self.send_command( module="C0", @@ -3469,19 +3546,17 @@ async def occupy_and_provide_area_for_external_access( ap=arm_preposition_mode_related_to_taken_areas, ) - async def release_occupied_area( - self, - taken_area_identification_number: int = 0 - ): - """ Release occupied area + async def release_occupied_area(self, taken_area_identification_number: int = 0): + """Release occupied area Args: taken_area_identification_number: taken area identification number. Must be between 0 and 9999. Default 0. """ - assert 0 <= taken_area_identification_number <= 999, \ - "taken_area_identification_number must be between 0 and 9999" + assert ( + 0 <= taken_area_identification_number <= 999 + ), "taken_area_identification_number must be between 0 and 9999" return await self.send_command( module="C0", @@ -3490,34 +3565,34 @@ async def release_occupied_area( ) async def release_all_occupied_areas(self): - """ Release all occupied areas """ + """Release all occupied areas""" return await self.send_command(module="C0", command="BC") # -------------- 3.4.3 X-query -------------- async def request_left_x_arm_position(self): - """ Request left X-Arm position """ + """Request left X-Arm position""" return await self.send_command(module="C0", command="RX", fmt="rx#####") async def request_right_x_arm_position(self): - """ Request right X-Arm position """ + """Request right X-Arm position""" return await self.send_command(module="C0", command="QX", fmt="rx#####") async def request_maximal_ranges_of_x_drives(self): - """ Request maximal ranges of X drives """ + """Request maximal ranges of X drives""" return await self.send_command(module="C0", command="RU") async def request_present_wrap_size_of_installed_arms(self): - """ Request present wrap size of installed arms """ + """Request present wrap size of installed arms""" return await self.send_command(module="C0", command="UA") async def request_left_x_arm_last_collision_type(self): - """ Request left X-Arm last collision type (after error 27) + """Request left X-Arm last collision type (after error 27) Returns: False if present positions collide (not reachable), @@ -3528,7 +3603,7 @@ async def request_left_x_arm_last_collision_type(self): return resp["xq"] == 1 async def request_right_x_arm_last_collision_type(self) -> bool: - """ Request right X-Arm last collision type (after error 27) + """Request right X-Arm last collision type (after error 27) Returns: False if present positions collide (not reachable), @@ -3551,9 +3626,9 @@ async def initialize_pipetting_channels( z_position_at_end_of_a_command: int = 3600, tip_pattern: List[bool] = [True], tip_type: int = 16, - discarding_method: int = 1 + discarding_method: int = 1, ): - """ Initialize pipetting channels + """Initialize pipetting channels Initialize pipetting channels (discard tips) @@ -3575,12 +3650,15 @@ async def initialize_pipetting_channels( assert all(0 <= xp <= 25000 for xp in x_positions), "x_positions must be between 0 and 25000" assert all(0 <= yp <= 6500 for yp in y_positions), "y_positions must be between 0 and 6500" - assert 0 <= begin_of_tip_deposit_process <= 3600, \ - "begin_of_tip_deposit_process must be between 0 and 3600" - assert 0 <= end_of_tip_deposit_process <= 3600, \ - "end_of_tip_deposit_process must be between 0 and 3600" - assert 0 <= z_position_at_end_of_a_command <= 3600, \ - "z_position_at_end_of_a_command must be between 0 and 3600" + assert ( + 0 <= begin_of_tip_deposit_process <= 3600 + ), "begin_of_tip_deposit_process must be between 0 and 3600" + assert ( + 0 <= end_of_tip_deposit_process <= 3600 + ), "end_of_tip_deposit_process must be between 0 and 3600" + assert ( + 0 <= z_position_at_end_of_a_command <= 3600 + ), "z_position_at_end_of_a_command must be between 0 and 3600" assert 0 <= tip_type <= 99, "tip must be between 0 and 99" assert 0 <= discarding_method <= 1, "discarding_method must be between 0 and 1" @@ -3610,9 +3688,9 @@ async def pick_up_tip( begin_tip_pick_up_process: int = 0, end_tip_pick_up_process: int = 0, minimum_traverse_height_at_beginning_of_a_command: int = 3600, - pickup_method: TipPickupMethod = TipPickupMethod.OUT_OF_RACK + pickup_method: TipPickupMethod = TipPickupMethod.OUT_OF_RACK, ): - """ Tip Pick-up + """Tip Pick-up Args: x_positions: x positions [0.1mm]. Must be between 0 and 25000. Default 0. @@ -3631,12 +3709,15 @@ async def pick_up_tip( assert all(0 <= xp <= 25000 for xp in x_positions), "x_positions must be between 0 and 25000" assert all(0 <= yp <= 6500 for yp in y_positions), "y_positions must be between 0 and 6500" - assert 0 <= begin_tip_pick_up_process <= 3600, \ - "begin_tip_pick_up_process must be between 0 and 3600" - assert 0 <= end_tip_pick_up_process <= 3600, \ - "end_tip_pick_up_process must be between 0 and 3600" - assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ - "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert ( + 0 <= begin_tip_pick_up_process <= 3600 + ), "begin_tip_pick_up_process must be between 0 and 3600" + assert ( + 0 <= end_tip_pick_up_process <= 3600 + ), "end_tip_pick_up_process must be between 0 and 3600" + assert ( + 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 + ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" return await self.send_command( module="C0", @@ -3663,9 +3744,9 @@ async def discard_tip( end_tip_deposit_process: int = 0, minimum_traverse_height_at_beginning_of_a_command: int = 3600, z_position_at_end_of_a_command: int = 3600, - discarding_method: TipDropMethod = TipDropMethod.DROP + discarding_method: TipDropMethod = TipDropMethod.DROP, ): - """ discard tip + """discard tip Args: x_positions: x positions [0.1mm]. Must be between 0 and 25000. Default 0. @@ -3690,14 +3771,18 @@ async def discard_tip( assert all(0 <= xp <= 25000 for xp in x_positions), "x_positions must be between 0 and 25000" assert all(0 <= yp <= 6500 for yp in y_positions), "y_positions must be between 0 and 6500" - assert 0 <= begin_tip_deposit_process <= 3600, \ - "begin_tip_deposit_process must be between 0 and 3600" - assert 0 <= end_tip_deposit_process <= 3600, \ - "end_tip_deposit_process must be between 0 and 3600" - assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ - "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" - assert 0 <= z_position_at_end_of_a_command <= 3600, \ - "z_position_at_end_of_a_command must be between 0 and 3600" + assert ( + 0 <= begin_tip_deposit_process <= 3600 + ), "begin_tip_deposit_process must be between 0 and 3600" + assert ( + 0 <= end_tip_deposit_process <= 3600 + ), "end_tip_deposit_process must be between 0 and 3600" + assert ( + 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 + ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert ( + 0 <= z_position_at_end_of_a_command <= 3600 + ), "z_position_at_end_of_a_command must be between 0 and 3600" return await self.send_command( module="C0", @@ -3759,7 +3844,6 @@ async def aspirate_pip( limit_curve_index: List[int] = [0], tadm_algorithm: bool = False, recording_mode: int = 0, - # For second section aspiration only use_2nd_section_aspiration: List[bool] = [False], retract_height_over_2nd_section_to_empty_tip: List[int] = [60], @@ -3768,9 +3852,9 @@ async def aspirate_pip( z_drive_speed_during_2nd_section_search: List[int] = [215], cup_upper_edge: List[int] = [3600], ratio_liquid_rise_to_tip_deep_in: List[int] = [16246], - immersion_depth_2nd_section: List[int] = [30] + immersion_depth_2nd_section: List[int] = [30], ): - """ aspirate pip + """aspirate pip Aspiration of liquid using PIP. @@ -3860,75 +3944,100 @@ async def aspirate_pip( assert all(0 <= x <= 2 for x in aspiration_type), "aspiration_type must be between 0 and 2" assert all(0 <= xp <= 25000 for xp in x_positions), "x_positions must be between 0 and 25000" assert all(0 <= yp <= 6500 for yp in y_positions), "y_positions must be between 0 and 6500" - assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ - "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert ( + 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 + ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" assert 0 <= min_z_endpos <= 3600, "min_z_endpos must be between 0 and 3600" - assert all(0 <= x <= 3600 for x in lld_search_height), \ - "lld_search_height must be between 0 and 3600" - assert all(0 <= x <= 500 for x in clot_detection_height), \ - "clot_detection_height must be between 0 and 500" - assert all(0 <= x <= 3600 for x in liquid_surface_no_lld), \ - "liquid_surface_no_lld must be between 0 and 3600" - assert all(0 <= x <= 3600 for x in pull_out_distance_transport_air), \ - "pull_out_distance_transport_air must be between 0 and 3600" - assert all(0 <= x <= 3600 for x in second_section_height), \ - "second_section_height must be between 0 and 3600" - assert all(0 <= x <= 10000 for x in second_section_ratio), \ - "second_section_ratio must be between 0 and 10000" + assert all( + 0 <= x <= 3600 for x in lld_search_height + ), "lld_search_height must be between 0 and 3600" + assert all( + 0 <= x <= 500 for x in clot_detection_height + ), "clot_detection_height must be between 0 and 500" + assert all( + 0 <= x <= 3600 for x in liquid_surface_no_lld + ), "liquid_surface_no_lld must be between 0 and 3600" + assert all( + 0 <= x <= 3600 for x in pull_out_distance_transport_air + ), "pull_out_distance_transport_air must be between 0 and 3600" + assert all( + 0 <= x <= 3600 for x in second_section_height + ), "second_section_height must be between 0 and 3600" + assert all( + 0 <= x <= 10000 for x in second_section_ratio + ), "second_section_ratio must be between 0 and 10000" assert all(0 <= x <= 3600 for x in minimum_height), "minimum_height must be between 0 and 3600" - assert all(0 <= x <= 3600 for x in immersion_depth), \ - "immersion_depth must be between 0 and 3600" - assert all(0 <= x <= 1 for x in immersion_depth_direction), \ - "immersion_depth_direction must be between 0 and 1" - assert all(0 <= x <= 3600 for x in surface_following_distance), \ - "surface_following_distance must be between 0 and 3600" - assert all(0 <= x <= 12500 for x in aspiration_volumes), \ - "aspiration_volumes must be between 0 and 12500" - assert all(4 <= x <= 5000 for x in aspiration_speed), \ - "aspiration_speed must be between 4 and 5000" - assert all(0 <= x <= 500 for x in transport_air_volume), \ - "transport_air_volume must be between 0 and 500" - assert all(0 <= x <= 9999 for x in blow_out_air_volume), \ - "blow_out_air_volume must be between 0 and 9999" - assert all(0 <= x <= 999 for x in pre_wetting_volume), \ - "pre_wetting_volume must be between 0 and 999" + assert all( + 0 <= x <= 3600 for x in immersion_depth + ), "immersion_depth must be between 0 and 3600" + assert all( + 0 <= x <= 1 for x in immersion_depth_direction + ), "immersion_depth_direction must be between 0 and 1" + assert all( + 0 <= x <= 3600 for x in surface_following_distance + ), "surface_following_distance must be between 0 and 3600" + assert all( + 0 <= x <= 12500 for x in aspiration_volumes + ), "aspiration_volumes must be between 0 and 12500" + assert all( + 4 <= x <= 5000 for x in aspiration_speed + ), "aspiration_speed must be between 4 and 5000" + assert all( + 0 <= x <= 500 for x in transport_air_volume + ), "transport_air_volume must be between 0 and 500" + assert all( + 0 <= x <= 9999 for x in blow_out_air_volume + ), "blow_out_air_volume must be between 0 and 9999" + assert all( + 0 <= x <= 999 for x in pre_wetting_volume + ), "pre_wetting_volume must be between 0 and 999" assert all(0 <= x <= 4 for x in lld_mode), "lld_mode must be between 0 and 4" - assert all(1 <= x <= 4 for x in gamma_lld_sensitivity), \ - "gamma_lld_sensitivity must be between 1 and 4" - assert all(1 <= x <= 4 for x in dp_lld_sensitivity), \ - "dp_lld_sensitivity must be between 1 and 4" - assert all(0 <= x <= 100 for x in aspirate_position_above_z_touch_off), \ - "aspirate_position_above_z_touch_off must be between 0 and 100" - assert all(0 <= x <= 99 for x in detection_height_difference_for_dual_lld), \ - "detection_height_difference_for_dual_lld must be between 0 and 99" + assert all( + 1 <= x <= 4 for x in gamma_lld_sensitivity + ), "gamma_lld_sensitivity must be between 1 and 4" + assert all( + 1 <= x <= 4 for x in dp_lld_sensitivity + ), "dp_lld_sensitivity must be between 1 and 4" + assert all( + 0 <= x <= 100 for x in aspirate_position_above_z_touch_off + ), "aspirate_position_above_z_touch_off must be between 0 and 100" + assert all( + 0 <= x <= 99 for x in detection_height_difference_for_dual_lld + ), "detection_height_difference_for_dual_lld must be between 0 and 99" assert all(3 <= x <= 1600 for x in swap_speed), "swap_speed must be between 3 and 1600" assert all(0 <= x <= 99 for x in settling_time), "settling_time must be between 0 and 99" - assert all(0 <= x <= 12500 for x in mix_volume), \ - "mix_volume must be between 0 and 12500" - assert all(0 <= x <= 99 for x in mix_cycles), \ - "mix_cycles must be between 0 and 99" - assert all(0 <= x <= 900 for x in mix_position_from_liquid_surface), \ - "mix_position_from_liquid_surface must be between 0 and 900" - assert all(4 <= x <= 5000 for x in mix_speed), \ - "mix_speed must be between 4 and 5000" - assert all(0 <= x <= 3600 for x in mix_surface_following_distance), \ - "mix_surface_following_distance must be between 0 and 3600" - assert all(0 <= x <= 999 for x in limit_curve_index), \ - "limit_curve_index must be between 0 and 999" + assert all(0 <= x <= 12500 for x in mix_volume), "mix_volume must be between 0 and 12500" + assert all(0 <= x <= 99 for x in mix_cycles), "mix_cycles must be between 0 and 99" + assert all( + 0 <= x <= 900 for x in mix_position_from_liquid_surface + ), "mix_position_from_liquid_surface must be between 0 and 900" + assert all(4 <= x <= 5000 for x in mix_speed), "mix_speed must be between 4 and 5000" + assert all( + 0 <= x <= 3600 for x in mix_surface_following_distance + ), "mix_surface_following_distance must be between 0 and 3600" + assert all( + 0 <= x <= 999 for x in limit_curve_index + ), "limit_curve_index must be between 0 and 999" assert 0 <= recording_mode <= 2, "recording_mode must be between 0 and 2" - assert all(0 <= x <= 3600 for x in retract_height_over_2nd_section_to_empty_tip), \ - "retract_height_over_2nd_section_to_empty_tip must be between 0 and 3600" - assert all(4 <= x <= 5000 for x in dispensation_speed_during_emptying_tip), \ - "dispensation_speed_during_emptying_tip must be between 4 and 5000" - assert all(4 <= x <= 5000 for x in dosing_drive_speed_during_2nd_section_search), \ - "dosing_drive_speed_during_2nd_section_search must be between 4 and 5000" - assert all(3 <= x <= 1600 for x in z_drive_speed_during_2nd_section_search), \ - "z_drive_speed_during_2nd_section_search must be between 3 and 1600" + assert all( + 0 <= x <= 3600 for x in retract_height_over_2nd_section_to_empty_tip + ), "retract_height_over_2nd_section_to_empty_tip must be between 0 and 3600" + assert all( + 4 <= x <= 5000 for x in dispensation_speed_during_emptying_tip + ), "dispensation_speed_during_emptying_tip must be between 4 and 5000" + assert all( + 4 <= x <= 5000 for x in dosing_drive_speed_during_2nd_section_search + ), "dosing_drive_speed_during_2nd_section_search must be between 4 and 5000" + assert all( + 3 <= x <= 1600 for x in z_drive_speed_during_2nd_section_search + ), "z_drive_speed_during_2nd_section_search must be between 3 and 1600" assert all(0 <= x <= 3600 for x in cup_upper_edge), "cup_upper_edge must be between 0 and 3600" - assert all(0 <= x <= 5000 for x in ratio_liquid_rise_to_tip_deep_in), \ - "ratio_liquid_rise_to_tip_deep_in must be between 0 and 50000" - assert all(0 <= x <= 3600 for x in immersion_depth_2nd_section), \ - "immersion_depth_2nd_section must be between 0 and 3600" + assert all( + 0 <= x <= 5000 for x in ratio_liquid_rise_to_tip_deep_in + ), "ratio_liquid_rise_to_tip_deep_in must be between 0 and 50000" + assert all( + 0 <= x <= 3600 for x in immersion_depth_2nd_section + ), "immersion_depth_2nd_section must be between 0 and 3600" return await self.send_command( module="C0", @@ -3949,16 +4058,16 @@ async def aspirate_pip( zr=[f"{zr:05}" for zr in second_section_ratio], zx=[f"{zx:04}" for zx in minimum_height], ip=[f"{ip:04}" for ip in immersion_depth], - it=[f"{it}" for it in immersion_depth_direction], + it=[f"{it}" for it in immersion_depth_direction], fp=[f"{fp:04}" for fp in surface_following_distance], av=[f"{av:05}" for av in aspiration_volumes], as_=[f"{as_:04}" for as_ in aspiration_speed], ta=[f"{ta:03}" for ta in transport_air_volume], ba=[f"{ba:04}" for ba in blow_out_air_volume], oa=[f"{oa:03}" for oa in pre_wetting_volume], - lm=[f"{lm}" for lm in lld_mode], - ll=[f"{ll}" for ll in gamma_lld_sensitivity], - lv=[f"{lv}" for lv in dp_lld_sensitivity], + lm=[f"{lm}" for lm in lld_mode], + ll=[f"{ll}" for ll in gamma_lld_sensitivity], + lv=[f"{lv}" for lv in dp_lld_sensitivity], zo=[f"{zo:03}" for zo in aspirate_position_above_z_touch_off], ld=[f"{ld:02}" for ld in detection_height_difference_for_dual_lld], de=[f"{de:04}" for de in swap_speed], @@ -3971,7 +4080,6 @@ async def aspirate_pip( gi=[f"{gi:03}" for gi in limit_curve_index], gj=tadm_algorithm, gk=recording_mode, - lk=[1 if lk else 0 for lk in use_2nd_section_aspiration], ik=[f"{ik:04}" for ik in retract_height_over_2nd_section_to_empty_tip], sd=[f"{sd:04}" for sd in dispensation_speed_during_emptying_tip], @@ -3999,7 +4107,7 @@ async def dispense_pip( second_section_height: List[int] = [0], second_section_ratio: List[int] = [0], minimum_traverse_height_at_beginning_of_a_command: int = 3600, - min_z_endpos: int = 3600, # + min_z_endpos: int = 3600, # dispense_volumes: List[int] = [0], dispense_speed: List[int] = [500], cut_off_speed: List[int] = [250], @@ -4020,9 +4128,9 @@ async def dispense_pip( mix_surface_following_distance: List[int] = [0], limit_curve_index: List[int] = [0], tadm_algorithm: bool = False, - recording_mode: int = 0 + recording_mode: int = 0, ): - """ dispense pip + """dispense pip Dispensing of liquid using PIP. @@ -4095,56 +4203,74 @@ async def dispense_pip( assert all(0 <= x <= 4 for x in dispensing_mode), "dispensing_mode must be between 0 and 4" assert all(0 <= xp <= 25000 for xp in x_positions), "x_positions must be between 0 and 25000" assert all(0 <= yp <= 6500 for yp in y_positions), "y_positions must be between 0 and 6500" - assert any(0 <= x <= 3600 for x in minimum_height), \ - "minimum_height must be between 0 and 3600" - assert any(0 <= x <= 3600 for x in lld_search_height), \ - "lld_search_height must be between 0 and 3600" - assert any(0 <= x <= 3600 for x in liquid_surface_no_lld), \ - "liquid_surface_no_lld must be between 0 and 3600" - assert any(0 <= x <= 3600 for x in pull_out_distance_transport_air), \ - "pull_out_distance_transport_air must be between 0 and 3600" - assert any(0 <= x <= 3600 for x in immersion_depth), \ - "immersion_depth must be between 0 and 3600" - assert any(0 <= x <= 1 for x in immersion_depth_direction), \ - "immersion_depth_direction must be between 0 and 1" - assert any(0 <= x <= 3600 for x in surface_following_distance), \ - "surface_following_distance must be between 0 and 3600" - assert any(0 <= x <= 3600 for x in second_section_height), \ - "second_section_height must be between 0 and 3600" - assert any(0 <= x <= 10000 for x in second_section_ratio), \ - "second_section_ratio must be between 0 and 10000" - assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ - "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert any(0 <= x <= 3600 for x in minimum_height), "minimum_height must be between 0 and 3600" + assert any( + 0 <= x <= 3600 for x in lld_search_height + ), "lld_search_height must be between 0 and 3600" + assert any( + 0 <= x <= 3600 for x in liquid_surface_no_lld + ), "liquid_surface_no_lld must be between 0 and 3600" + assert any( + 0 <= x <= 3600 for x in pull_out_distance_transport_air + ), "pull_out_distance_transport_air must be between 0 and 3600" + assert any( + 0 <= x <= 3600 for x in immersion_depth + ), "immersion_depth must be between 0 and 3600" + assert any( + 0 <= x <= 1 for x in immersion_depth_direction + ), "immersion_depth_direction must be between 0 and 1" + assert any( + 0 <= x <= 3600 for x in surface_following_distance + ), "surface_following_distance must be between 0 and 3600" + assert any( + 0 <= x <= 3600 for x in second_section_height + ), "second_section_height must be between 0 and 3600" + assert any( + 0 <= x <= 10000 for x in second_section_ratio + ), "second_section_ratio must be between 0 and 10000" + assert ( + 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 + ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" assert 0 <= min_z_endpos <= 3600, "min_z_endpos must be between 0 and 3600" - assert any(0 <= x <= 12500 for x in dispense_volumes), \ - "dispense_volume must be between 0 and 12500" + assert any( + 0 <= x <= 12500 for x in dispense_volumes + ), "dispense_volume must be between 0 and 12500" assert any(4 <= x <= 5000 for x in dispense_speed), "dispense_speed must be between 4 and 5000" assert any(4 <= x <= 5000 for x in cut_off_speed), "cut_off_speed must be between 4 and 5000" - assert any(0 <= x <= 180 for x in stop_back_volume), \ - "stop_back_volume must be between 0 and 180" - assert any(0 <= x <= 500 for x in transport_air_volume), \ - "transport_air_volume must be between 0 and 500" - assert any(0 <= x <= 9999 for x in blow_out_air_volume), \ - "blow_out_air_volume must be between 0 and 9999" + assert any( + 0 <= x <= 180 for x in stop_back_volume + ), "stop_back_volume must be between 0 and 180" + assert any( + 0 <= x <= 500 for x in transport_air_volume + ), "transport_air_volume must be between 0 and 500" + assert any( + 0 <= x <= 9999 for x in blow_out_air_volume + ), "blow_out_air_volume must be between 0 and 9999" assert any(0 <= x <= 4 for x in lld_mode), "lld_mode must be between 0 and 4" assert 0 <= side_touch_off_distance <= 45, "side_touch_off_distance must be between 0 and 45" - assert any(0 <= x <= 100 for x in dispense_position_above_z_touch_off), \ - "dispense_position_above_z_touch_off must be between 0 and 100" - assert any(1 <= x <= 4 for x in gamma_lld_sensitivity), \ - "gamma_lld_sensitivity must be between 1 and 4" - assert any(1 <= x <= 4 for x in dp_lld_sensitivity), \ - "dp_lld_sensitivity must be between 1 and 4" + assert any( + 0 <= x <= 100 for x in dispense_position_above_z_touch_off + ), "dispense_position_above_z_touch_off must be between 0 and 100" + assert any( + 1 <= x <= 4 for x in gamma_lld_sensitivity + ), "gamma_lld_sensitivity must be between 1 and 4" + assert any( + 1 <= x <= 4 for x in dp_lld_sensitivity + ), "dp_lld_sensitivity must be between 1 and 4" assert any(3 <= x <= 1600 for x in swap_speed), "swap_speed must be between 3 and 1600" assert any(0 <= x <= 99 for x in settling_time), "settling_time must be between 0 and 99" assert any(0 <= x <= 12500 for x in mix_volume), "mix_volume must be between 0 and 12500" assert any(0 <= x <= 99 for x in mix_cycles), "mix_cycles must be between 0 and 99" - assert any(0 <= x <= 900 for x in mix_position_from_liquid_surface), \ - "mix_position_from_liquid_surface must be between 0 and 900" + assert any( + 0 <= x <= 900 for x in mix_position_from_liquid_surface + ), "mix_position_from_liquid_surface must be between 0 and 900" assert any(4 <= x <= 5000 for x in mix_speed), "mix_speed must be between 4 and 5000" - assert any(0 <= x <= 3600 for x in mix_surface_following_distance), \ - "mix_surface_following_distance must be between 0 and 3600" - assert any(0 <= x <= 999 for x in limit_curve_index), \ - "limit_curve_index must be between 0 and 999" + assert any( + 0 <= x <= 3600 for x in mix_surface_following_distance + ), "mix_surface_following_distance must be between 0 and 3600" + assert any( + 0 <= x <= 999 for x in limit_curve_index + ), "limit_curve_index must be between 0 and 999" assert 0 <= recording_mode <= 2, "recording_mode must be between 0 and 2" return await self.send_command( @@ -4174,7 +4300,7 @@ async def dispense_pip( ta=[f"{ta:03}" for ta in transport_air_volume], ba=[f"{ba:04}" for ba in blow_out_air_volume], lm=[f"{lm:01}" for lm in lld_mode], - dj=f"{side_touch_off_distance:02}", # + dj=f"{side_touch_off_distance:02}", # zo=[f"{zo:03}" for zo in dispense_position_above_z_touch_off], ll=[f"{ll:01}" for ll in gamma_lld_sensitivity], lv=[f"{lv:01}" for lv in dp_lld_sensitivity], @@ -4186,8 +4312,8 @@ async def dispense_pip( ms=[f"{ms:04}" for ms in mix_speed], mh=[f"{mh:04}" for mh in mix_surface_following_distance], gi=[f"{gi:03}" for gi in limit_curve_index], - gj=tadm_algorithm, # - gk=recording_mode, # + gj=tadm_algorithm, # + gk=recording_mode, # ) # TODO:(command:DA) Simultaneous aspiration & dispensation of liquid @@ -4200,7 +4326,7 @@ async def dispense_pip( @need_iswap_parked async def get_core(self, p1: int, p2: int): - """ Get CoRe gripper tool from wasteblock mount. """ + """Get CoRe gripper tool from wasteblock mount.""" if not 0 <= p1 < self.num_channels: raise ValueError(f"channel_1 must be between 0 and {self.num_channels - 1}") if not 1 <= p2 <= self.num_channels: @@ -4211,9 +4337,9 @@ async def get_core(self, p1: int, p2: int): # a resource on the robot deck and use deck.get_resource().get_absolute_location(). deck_size = self.deck.get_absolute_size_x() if deck_size == STARLET_SIZE_X: - xs = 7975 # 1360-797.5 = 562.5 + xs = 7975 # 1360-797.5 = 562.5 elif deck_size == STAR_SIZE_X: - xs = 13385 # 1900-1337.5 = 562.5, plus a manual adjustment of + 10 + xs = 13385 # 1900-1337.5 = 562.5, plus a manual adjustment of + 10 else: raise ValueError(f"Deck size {deck_size} not supported") @@ -4229,14 +4355,14 @@ async def get_core(self, p1: int, p2: int): tp=f"{2350 + self.core_adjustment.z:04}", tz=f"{2250 + self.core_adjustment.z:04}", th=round(self._traversal_height * 10), - tt="14" + tt="14", ) self._core_parked = False return command_output @need_iswap_parked async def put_core(self): - """ Put CoRe gripper tool at wasteblock mount. """ + """Put CoRe gripper tool at wasteblock mount.""" assert self.deck is not None, "must have deck defined to access CoRe grippers" deck_size = self.deck.get_absolute_size_x() if deck_size == STARLET_SIZE_X: @@ -4261,7 +4387,7 @@ async def put_core(self): return command_output async def core_open_gripper(self): - """ Open CoRe gripper tool. """ + """Open CoRe gripper tool.""" return await self.send_command(module="C0", command="ZO") @need_iswap_parked @@ -4279,7 +4405,7 @@ async def core_get_plate( minimum_traverse_height_at_beginning_of_a_command: int = 2750, minimum_z_position_at_the_command_end: int = 2750, ): - """ Get plate with CoRe gripper tool from wasteblock mount. """ + """Get plate with CoRe gripper tool from wasteblock mount.""" assert 0 <= x_position <= 30000, "x_position must be between 0 and 30000" assert 0 <= x_direction <= 1, "x_direction must be between 0 and 1" @@ -4290,10 +4416,12 @@ async def core_get_plate( assert 0 <= open_gripper_position <= 9999, "open_gripper_position must be between 0 and 9999" assert 0 <= plate_width <= 9999, "plate_width must be between 0 and 9999" assert 0 <= grip_strength <= 99, "grip_strength must be between 0 and 99" - assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ - "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" - assert 0 <= minimum_z_position_at_the_command_end <= 3600, \ - "minimum_z_position_at_the_command_end must be between 0 and 3600" + assert ( + 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 + ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert ( + 0 <= minimum_z_position_at_the_command_end <= 3600 + ), "minimum_z_position_at_the_command_end must be between 0 and 3600" command_output = await self.send_command( module="C0", @@ -4308,7 +4436,7 @@ async def core_get_plate( yg=f"{plate_width:04}", yw=f"{grip_strength:02}", th=f"{minimum_traverse_height_at_beginning_of_a_command:04}", - te=f"{minimum_z_position_at_the_command_end:04}" + te=f"{minimum_z_position_at_the_command_end:04}", ) return command_output @@ -4325,9 +4453,9 @@ async def core_put_plate( open_gripper_position: int = 0, minimum_traverse_height_at_beginning_of_a_command: int = 2750, z_position_at_the_command_end: int = 2750, - return_tool: bool = True + return_tool: bool = True, ): - """ Put plate with CoRe gripper tool and return to wasteblock mount. """ + """Put plate with CoRe gripper tool and return to wasteblock mount.""" assert 0 <= x_position <= 30000, "x_position must be between 0 and 30000" assert 0 <= x_direction <= 1, "x_direction must be between 0 and 1" @@ -4336,10 +4464,12 @@ async def core_put_plate( assert 0 <= z_press_on_distance <= 50, "z_press_on_distance must be between 0 and 999" assert 0 <= z_speed <= 1600, "z_speed must be between 0 and 1600" assert 0 <= open_gripper_position <= 9999, "open_gripper_position must be between 0 and 9999" - assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ - "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" - assert 0 <= z_position_at_the_command_end <= 3600, \ - "z_position_at_the_command_end must be between 0 and 3600" + assert ( + 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 + ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert ( + 0 <= z_position_at_the_command_end <= 3600 + ), "z_position_at_the_command_end must be between 0 and 3600" command_output = await self.send_command( module="C0", @@ -4352,7 +4482,7 @@ async def core_put_plate( zy=f"{z_speed:04}", yo=f"{open_gripper_position:04}", th=f"{minimum_traverse_height_at_beginning_of_a_command:04}", - te=f"{z_position_at_the_command_end:04}" + te=f"{z_position_at_the_command_end:04}", ) if return_tool: @@ -4371,7 +4501,7 @@ async def core_move_plate_to_position( z_speed: int = 500, minimum_traverse_height_at_beginning_of_a_command: int = 3600, ): - """ Move a plate with CoRe gripper tool. """ + """Move a plate with CoRe gripper tool.""" command_output = await self.send_command( module="C0", @@ -4382,7 +4512,7 @@ async def core_move_plate_to_position( yj=f"{y_position:04}", zj=f"{z_position:04}", zy=f"{z_speed:04}", - th=f"{minimum_traverse_height_at_beginning_of_a_command:04}" + th=f"{minimum_traverse_height_at_beginning_of_a_command:04}", ) return command_output @@ -4396,19 +4526,18 @@ async def core_move_plate_to_position( # TODO:(command:JZ) Position all pipetting channels in Z-direction async def position_single_pipetting_channel_in_y_direction( - self, - pipetting_channel_index: int, - y_position: int + self, pipetting_channel_index: int, y_position: int ): - """ Position single pipetting channel in Y-direction. + """Position single pipetting channel in Y-direction. Args: pipetting_channel_index: Index of pipetting channel. Must be between 1 and 16. y_position: y position [0.1mm]. Must be between 0 and 6500. """ - assert 1 <= pipetting_channel_index <= self.num_channels, \ - "pipetting_channel_index must be between 1 and self" + assert ( + 1 <= pipetting_channel_index <= self.num_channels + ), "pipetting_channel_index must be between 1 and self" assert 0 <= y_position <= 6500, "y_position must be between 0 and 6500" return await self.send_command( @@ -4419,11 +4548,9 @@ async def position_single_pipetting_channel_in_y_direction( ) async def position_single_pipetting_channel_in_z_direction( - self, - pipetting_channel_index: int, - z_position: int + self, pipetting_channel_index: int, z_position: int ): - """ Position single pipetting channel in Z-direction. + """Position single pipetting channel in Z-direction. Note that this refers to the point of the tip if a tip is mounted! @@ -4433,8 +4560,9 @@ async def position_single_pipetting_channel_in_z_direction( 3347 is the max. """ - assert 1 <= pipetting_channel_index <= self.num_channels, \ - "pipetting_channel_index must be between 1 and self.num_channels" + assert ( + 1 <= pipetting_channel_index <= self.num_channels + ), "pipetting_channel_index must be between 1 and self.num_channels" # docs say 3600, but empirically 3347 is the max assert 0 <= z_position <= 3347, "z_position must be between 0 and 3347" @@ -4446,19 +4574,18 @@ async def position_single_pipetting_channel_in_z_direction( ) async def search_for_teach_in_signal_using_pipetting_channel_n_in_x_direction( - self, - pipetting_channel_index: int, - x_position: int + self, pipetting_channel_index: int, x_position: int ): - """ Search for Teach in signal using pipetting channel n in X-direction. + """Search for Teach in signal using pipetting channel n in X-direction. Args: pipetting_channel_index: Index of pipetting channel. Must be between 1 and self.num_channels. x_position: x position [0.1mm]. Must be between 0 and 30000. """ - assert 1 <= pipetting_channel_index <= self.num_channels, \ - "pipetting_channel_index must be between 1 and self.num_channels" + assert ( + 1 <= pipetting_channel_index <= self.num_channels + ), "pipetting_channel_index must be between 1 and self.num_channels" assert 0 <= x_position <= 30000, "x_position must be between 0 and 30000" return await self.send_command( @@ -4469,7 +4596,7 @@ async def search_for_teach_in_signal_using_pipetting_channel_n_in_x_direction( ) async def spread_pip_channels(self): - """ Spread PIP channels """ + """Spread PIP channels""" return await self.send_command(module="C0", command="JE") @@ -4479,9 +4606,9 @@ async def move_all_pipetting_channels_to_defined_position( x_positions: int = 0, y_positions: int = 0, minimum_traverse_height_at_beginning_of_command: int = 3600, - z_endpos: int = 0 + z_endpos: int = 0, ): - """ Move all pipetting channels to defined position + """Move all pipetting channels to defined position Args: tip_pattern: Tip pattern (channels involved). Default True. @@ -4496,8 +4623,9 @@ async def move_all_pipetting_channels_to_defined_position( assert 0 <= x_positions <= 25000, "x_positions must be between 0 and 25000" assert 0 <= y_positions <= 6500, "y_positions must be between 0 and 6500" - assert 0 <= minimum_traverse_height_at_beginning_of_command <= 3600, \ - "minimum_traverse_height_at_beginning_of_command must be between 0 and 3600" + assert ( + 0 <= minimum_traverse_height_at_beginning_of_command <= 3600 + ), "minimum_traverse_height_at_beginning_of_command must be between 0 and 3600" assert 0 <= z_endpos <= 3600, "z_endpos must be between 0 and 3600" return await self.send_command( @@ -4512,18 +4640,16 @@ async def move_all_pipetting_channels_to_defined_position( # TODO:(command:JR): teach rack using pipetting channel n - async def position_max_free_y_for_n( - self, - pipetting_channel_index: int = 1 - ): - """ Position all pipetting channels so that there is maximum free Y range for channel n + async def position_max_free_y_for_n(self, pipetting_channel_index: int = 1): + """Position all pipetting channels so that there is maximum free Y range for channel n Args: pipetting_channel_index: Index of pipetting channel. Must be between 1 and 16. Default 1. """ - assert 1 <= pipetting_channel_index <= self.num_channels, \ - "pipetting_channel_index must be between 1 and self.num_channels" + assert ( + 1 <= pipetting_channel_index <= self.num_channels + ), "pipetting_channel_index must be between 1 and self.num_channels" return await self.send_command( module="C0", @@ -4532,7 +4658,7 @@ async def position_max_free_y_for_n( ) async def move_all_channels_in_z_safety(self): - """ Move all pipetting channels in Z-safety position """ + """Move all pipetting channels in Z-safety position""" return await self.send_command(module="C0", command="ZA") @@ -4540,11 +4666,8 @@ async def move_all_channels_in_z_safety(self): # TODO:(command:RY): Request Y-Positions of all pipetting channels - async def request_y_pos_channel_n( - self, - pipetting_channel_index: int = 1 - ): - """ Request Y-Position of Pipetting channel n + async def request_y_pos_channel_n(self, pipetting_channel_index: int = 1): + """Request Y-Position of Pipetting channel n Args: pipetting_channel_index: Index of pipetting channel. Must be between 1 and 16. Default 1. @@ -4561,11 +4684,8 @@ async def request_y_pos_channel_n( # TODO:(command:RZ): Request Z-Positions of all pipetting channels - async def request_z_pos_channel_n( - self, - pipetting_channel_index: int = 1 - ): - """ Request Z-Position of Pipetting channel n + async def request_z_pos_channel_n(self, pipetting_channel_index: int = 1): + """Request Z-Position of Pipetting channel n Args: pipetting_channel_index: Index of pipetting channel. Must be between 1 and 16. Default 1. @@ -4584,7 +4704,7 @@ async def request_z_pos_channel_n( ) async def request_tip_presence(self) -> List[int]: - """ Request query tip presence on each channel + """Request query tip presence on each channel Returns: 0 = no tip, 1 = Tip in gripper (for each channel) @@ -4594,7 +4714,7 @@ async def request_tip_presence(self) -> List[int]: return cast(List[int], resp.get("rt")) async def request_pip_height_last_lld(self): - """ Request PIP height of last LLD + """Request PIP height of last LLD Returns: LLD height of all channels @@ -4603,7 +4723,7 @@ async def request_pip_height_last_lld(self): return await self.send_command(module="C0", command="RL", fmt="lh#### (n)") async def request_tadm_status(self): - """ Request PIP height of last LLD + """Request PIP height of last LLD Returns: TADM channel status 0 = off, 1 = on @@ -4747,9 +4867,9 @@ async def initialize_core_96_head( x_direction: int = 1, y_position: int = 1103, z_deposit_position: int = 1890, - z_position_at_the_command_end: int = 2450 + z_position_at_the_command_end: int = 2450, ): - """ Initialize CoRe 96 Head + """Initialize CoRe 96 Head Initialize CoRe 96 Head. Dependent to configuration initialization change. @@ -4769,8 +4889,9 @@ async def initialize_core_96_head( assert 0 <= x_direction <= 1, "x_direction must be between 0 and 1" assert 1054 <= y_position <= 5743, "y_position must be between 1054 and 5743" assert 0 <= z_deposit_position <= 3425, "z_deposit_position must be between 0 and 3425" - assert 0 <= z_position_at_the_command_end <= 3425, \ - "z_position_at_the_command_end must be between 0 and 3425" + assert ( + 0 <= z_position_at_the_command_end <= 3425 + ), "z_position_at_the_command_end must be between 0 and 3425" return await self.send_command( module="C0", @@ -4783,14 +4904,14 @@ async def initialize_core_96_head( ) async def move_core_96_to_safe_position(self): - """ Move CoRe 96 Head to Z save position """ + """Move CoRe 96 Head to Z save position""" return await self.send_command(module="C0", command="EV") async def request_core_96_head_initialization_status(self) -> bool: # not available in the C0 docs, so get from module H0 itself instead response = await self.send_command(module="H0", command="QW", fmt="qw#") - return bool(response.get("qw", 0) == 1) # type? + return bool(response.get("qw", 0) == 1) # type? # -------------- 3.10.2 Tip handling using CoRe 96 Head -------------- @@ -4804,9 +4925,9 @@ async def pick_up_tips_core96( tip_pickup_method: int = 2, z_deposit_position: int = 3425, minimum_traverse_height_at_beginning_of_a_command: int = 3425, - minimum_height_command_end: int = 3425 + minimum_height_command_end: int = 3425, ): - """ Pick up tips with CoRe 96 head + """Pick up tips with CoRe 96 head Args: x_position: x position [0.1mm]. Must be between 0 and 30000. Default 0. @@ -4826,10 +4947,12 @@ async def pick_up_tips_core96( assert 0 <= x_direction <= 1, "x_direction must be between 0 and 1" assert 1080 <= y_position <= 5600, "y_position must be between 1080 and 5600" assert 0 <= z_deposit_position <= 3425, "z_deposit_position must be between 0 and 3425" - assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3425, \ - "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3425" - assert 0 <= minimum_height_command_end <= 3425, \ - "minimum_height_command_end must be between 0 and 3425" + assert ( + 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3425 + ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3425" + assert ( + 0 <= minimum_height_command_end <= 3425 + ), "minimum_height_command_end must be between 0 and 3425" return await self.send_command( module="C0", @@ -4852,9 +4975,9 @@ async def discard_tips_core96( y_position: int, z_deposit_position: int = 3425, minimum_traverse_height_at_beginning_of_a_command: int = 3425, - minimum_height_command_end: int = 3425 + minimum_height_command_end: int = 3425, ): - """ Drop tips with CoRe 96 head + """Drop tips with CoRe 96 head Args: x_position: x position [0.1mm]. Must be between 0 and 30000. Default 0. @@ -4874,10 +4997,12 @@ async def discard_tips_core96( assert 0 <= x_direction <= 1, "x_direction must be between 0 and 1" assert 1080 <= y_position <= 5600, "y_position must be between 1080 and 5600" assert 0 <= z_deposit_position <= 3425, "z_deposit_position must be between 0 and 3425" - assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3425, \ - "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3425" - assert 0 <= minimum_height_command_end <= 3425, \ - "minimum_height_command_end must be between 0 and 3425" + assert ( + 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3425 + ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3425" + assert ( + 0 <= minimum_height_command_end <= 3425 + ), "minimum_height_command_end must be between 0 and 3425" return await self.send_command( module="C0", @@ -4887,7 +5012,7 @@ async def discard_tips_core96( yh=f"{y_position:04}", za=f"{z_deposit_position:04}", zh=f"{minimum_traverse_height_at_beginning_of_a_command:04}", - ze=f"{minimum_height_command_end:04}" + ze=f"{minimum_height_command_end:04}", ) # -------------- 3.10.3 Liquid handling using CoRe 96 Head -------------- @@ -4927,9 +5052,9 @@ async def aspirate_core_96( channel_pattern: List[bool] = [True] * 96, limit_curve_index: int = 0, tadm_algorithm: bool = False, - recording_mode: int = 0 + recording_mode: int = 0, ): - """ aspirate CoRe 96 + """aspirate CoRe 96 Aspiration of liquid using CoRe 96 @@ -4990,24 +5115,31 @@ async def aspirate_core_96( assert 0 <= x_position <= 30000, "x_position must be between 0 and 30000" assert 0 <= x_direction <= 1, "x_direction must be between 0 and 1" assert 1080 <= y_positions <= 5600, "y_positions must be between 1080 and 5600" - assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3425, \ - "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3425" + assert ( + 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3425 + ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3425" assert 0 <= minimal_end_height <= 3425, "minimal_end_height must be between 0 and 3425" assert 0 <= lld_search_height <= 3425, "lld_search_height must be between 0 and 3425" - assert 0 <= liquid_surface_at_function_without_lld <= 3425, \ - "liquid_surface_at_function_without_lld must be between 0 and 3425" - assert 0 <= pull_out_distance_to_take_transport_air_in_function_without_lld <= 3425, \ - "pull_out_distance_to_take_transport_air_in_function_without_lld must be between 0 and 3425" - assert 0 <= maximum_immersion_depth <= 3425, \ - "maximum_immersion_depth must be between 0 and 3425" - assert 0 <= tube_2nd_section_height_measured_from_zm <= 3425, \ - "tube_2nd_section_height_measured_from_zm must be between 0 and 3425" - assert 0 <= tube_2nd_section_ratio <= 10000, \ - "tube_2nd_section_ratio must be between 0 and 10000" + assert ( + 0 <= liquid_surface_at_function_without_lld <= 3425 + ), "liquid_surface_at_function_without_lld must be between 0 and 3425" + assert ( + 0 <= pull_out_distance_to_take_transport_air_in_function_without_lld <= 3425 + ), "pull_out_distance_to_take_transport_air_in_function_without_lld must be between 0 and 3425" + assert ( + 0 <= maximum_immersion_depth <= 3425 + ), "maximum_immersion_depth must be between 0 and 3425" + assert ( + 0 <= tube_2nd_section_height_measured_from_zm <= 3425 + ), "tube_2nd_section_height_measured_from_zm must be between 0 and 3425" + assert ( + 0 <= tube_2nd_section_ratio <= 10000 + ), "tube_2nd_section_ratio must be between 0 and 10000" assert 0 <= immersion_depth <= 3600, "immersion_depth must be between 0 and 3600" assert 0 <= immersion_depth_direction <= 1, "immersion_depth_direction must be between 0 and 1" - assert 0 <= liquid_surface_sink_distance_at_the_end_of_aspiration <= 990, \ - "liquid_surface_sink_distance_at_the_end_of_aspiration must be between 0 and 990" + assert ( + 0 <= liquid_surface_sink_distance_at_the_end_of_aspiration <= 990 + ), "liquid_surface_sink_distance_at_the_end_of_aspiration must be between 0 and 990" assert 0 <= aspiration_volumes <= 11500, "aspiration_volumes must be between 0 and 11500" assert 3 <= aspiration_speed <= 5000, "aspiration_speed must be between 3 and 5000" assert 0 <= transport_air_volume <= 500, "transport_air_volume must be between 0 and 500" @@ -5019,12 +5151,13 @@ async def aspirate_core_96( assert 0 <= settling_time <= 99, "settling_time must be between 0 and 99" assert 0 <= mix_volume <= 11500, "mix_volume must be between 0 and 11500" assert 0 <= mix_cycles <= 99, "mix_cycles must be between 0 and 99" - assert 0 <= mix_position_from_liquid_surface <= 990, \ - "mix_position_from_liquid_surface must be between 0 and 990" - assert 0 <= surface_following_distance_during_mix <= 990, \ - "surface_following_distance_during_mix must be between 0 and 990" - assert 3 <= mix_speed <= 5000, \ - "mix_speed must be between 3 and 5000" + assert ( + 0 <= mix_position_from_liquid_surface <= 990 + ), "mix_position_from_liquid_surface must be between 0 and 990" + assert ( + 0 <= surface_following_distance_during_mix <= 990 + ), "surface_following_distance_during_mix must be between 0 and 990" + assert 3 <= mix_speed <= 5000, "mix_speed must be between 3 and 5000" assert 0 <= limit_curve_index <= 999, "limit_curve_index must be between 0 and 999" assert 0 <= recording_mode <= 2, "recording_mode must be between 0 and 2" @@ -5106,12 +5239,12 @@ async def dispense_core_96( mixing_position_from_liquid_surface: int = 250, surface_following_distance_during_mixing: int = 0, mix_speed: int = 1000, - channel_pattern: List[bool] = [True]*12*8, + channel_pattern: List[bool] = [True] * 12 * 8, limit_curve_index: int = 0, tadm_algorithm: bool = False, - recording_mode: int = 0 + recording_mode: int = 0, ): - """ dispense CoRe 96 + """dispense CoRe 96 Dispensing of liquid using CoRe 96 @@ -5174,23 +5307,30 @@ async def dispense_core_96( assert 0 <= x_position <= 30000, "x_position must be between 0 and 30000" assert 0 <= x_direction <= 1, "x_direction must be between 0 and 1" assert 1080 <= y_position <= 5600, "y_position must be between 1080 and 5600" - assert 0 <= maximum_immersion_depth <= 3425, \ - "maximum_immersion_depth must be between 0 and 3425" - assert 0 <= tube_2nd_section_height_measured_from_zm <= 3425, \ - "tube_2nd_section_height_measured_from_zm must be between 0 and 3425" - assert 0 <= tube_2nd_section_ratio <= 10000, \ - "tube_2nd_section_ratio must be between 0 and 10000" + assert ( + 0 <= maximum_immersion_depth <= 3425 + ), "maximum_immersion_depth must be between 0 and 3425" + assert ( + 0 <= tube_2nd_section_height_measured_from_zm <= 3425 + ), "tube_2nd_section_height_measured_from_zm must be between 0 and 3425" + assert ( + 0 <= tube_2nd_section_ratio <= 10000 + ), "tube_2nd_section_ratio must be between 0 and 10000" assert 0 <= lld_search_height <= 3425, "lld_search_height must be between 0 and 3425" - assert 0 <= liquid_surface_at_function_without_lld <= 3425, \ - "liquid_surface_at_function_without_lld must be between 0 and 3425" - assert 0 <= pull_out_distance_to_take_transport_air_in_function_without_lld <= 3425, \ - "pull_out_distance_to_take_transport_air_in_function_without_lld must be between 0 and 3425" + assert ( + 0 <= liquid_surface_at_function_without_lld <= 3425 + ), "liquid_surface_at_function_without_lld must be between 0 and 3425" + assert ( + 0 <= pull_out_distance_to_take_transport_air_in_function_without_lld <= 3425 + ), "pull_out_distance_to_take_transport_air_in_function_without_lld must be between 0 and 3425" assert 0 <= immersion_depth <= 3600, "immersion_depth must be between 0 and 3600" assert 0 <= immersion_depth_direction <= 1, "immersion_depth_direction must be between 0 and 1" - assert 0 <= liquid_surface_sink_distance_at_the_end_of_dispense <= 990, \ - "liquid_surface_sink_distance_at_the_end_of_dispense must be between 0 and 990" - assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3425, \ - "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3425" + assert ( + 0 <= liquid_surface_sink_distance_at_the_end_of_dispense <= 990 + ), "liquid_surface_sink_distance_at_the_end_of_dispense must be between 0 and 990" + assert ( + 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3425 + ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3425" assert 0 <= minimal_end_height <= 3425, "minimal_end_height must be between 0 and 3425" assert 0 <= dispense_volume <= 11500, "dispense_volume must be between 0 and 11500" assert 3 <= dispense_speed <= 5000, "dispense_speed must be between 3 and 5000" @@ -5205,10 +5345,12 @@ async def dispense_core_96( assert 0 <= settling_time <= 99, "settling_time must be between 0 and 99" assert 0 <= mixing_volume <= 11500, "mixing_volume must be between 0 and 11500" assert 0 <= mixing_cycles <= 99, "mixing_cycles must be between 0 and 99" - assert 0 <= mixing_position_from_liquid_surface <= 990, \ - "mixing_position_from_liquid_surface must be between 0 and 990" - assert 0 <= surface_following_distance_during_mixing <= 990, \ - "surface_following_distance_during_mixing must be between 0 and 990" + assert ( + 0 <= mixing_position_from_liquid_surface <= 990 + ), "mixing_position_from_liquid_surface must be between 0 and 990" + assert ( + 0 <= surface_following_distance_during_mixing <= 990 + ), "surface_following_distance_during_mixing must be between 0 and 990" assert 3 <= mix_speed <= 5000, "mix_speed must be between 3 and 5000" assert 0 <= limit_curve_index <= 999, "limit_curve_index must be between 0 and 999" assert 0 <= recording_mode <= 2, "recording_mode must be between 0 and 2" @@ -5267,9 +5409,9 @@ async def move_core_96_head_to_defined_position( x_direction: int = 0, y_position: int = 0, z_position: int = 0, - minimum_height_at_beginning_of_a_command: int = 3425 + minimum_height_at_beginning_of_a_command: int = 3425, ): - """ Move CoRe 96 Head to defined position + """Move CoRe 96 Head to defined position Args: dispensing_mode: Type of dispensing mode 0 = Partial volume in jet mode 1 = Blow out @@ -5289,8 +5431,9 @@ async def move_core_96_head_to_defined_position( assert 0 <= x_direction <= 1, "x_direction must be between 0 and 1" assert 1080 <= y_position <= 5600, "y_position must be between 1080 and 5600" assert 0 <= y_position <= 5600, "z_position must be between 0 and 5600" - assert 0 <= minimum_height_at_beginning_of_a_command <= 3425, \ - "minimum_height_at_beginning_of_a_command must be between 0 and 3425" + assert ( + 0 <= minimum_height_at_beginning_of_a_command <= 3425 + ), "minimum_height_at_beginning_of_a_command must be between 0 and 3425" return await self.send_command( module="C0", @@ -5311,7 +5454,7 @@ async def move_core_96_head_to_defined_position( # -------------- 3.10.6 Query CoRe 96 Head -------------- async def request_tip_presence_in_core_96_head(self): - """ Request Tip presence in CoRe 96 Head + """Request Tip presence in CoRe 96 Head Returns: qh: 0 = no tips, 1 = TipRack are picked up @@ -5320,7 +5463,7 @@ async def request_tip_presence_in_core_96_head(self): return await self.send_command(module="C0", command="QH", fmt="qh#") async def request_position_of_core_96_head(self): - """ Request position of CoRe 96 Head (A1 considered to tip length) + """Request position of CoRe 96 Head (A1 considered to tip length) Returns: xs: A1 X direction [0.1mm] @@ -5332,7 +5475,7 @@ async def request_position_of_core_96_head(self): return await self.send_command(module="C0", command="QI", fmt="xs#####xd#hy####za####") async def request_core_96_head_channel_tadm_status(self): - """ Request CoRe 96 Head channel TADM Status + """Request CoRe 96 Head channel TADM Status Returns: qx: TADM channel status 0 = off 1 = on @@ -5341,7 +5484,7 @@ async def request_core_96_head_channel_tadm_status(self): return await self.send_command(module="C0", command="VC", fmt="qx#") async def request_core_96_head_channel_tadm_error_status(self): - """ Request CoRe 96 Head channel TADM error status + """Request CoRe 96 Head channel TADM error status Returns: vb: error pattern 0 = no error @@ -5405,12 +5548,12 @@ async def request_core_96_head_channel_tadm_error_status(self): # -------------- 3.13.1 Initialization -------------- async def initialize_auto_load(self): - """ Initialize Auto load module """ + """Initialize Auto load module""" return await self.send_command(module="C0", command="II") async def move_auto_load_to_z_save_position(self): - """ Move auto load to Z save position """ + """Move auto load to Z save position""" return await self.send_command(module="C0", command="IV") @@ -5418,11 +5561,8 @@ async def move_auto_load_to_z_save_position(self): # TODO:(command:CI) Identify carrier (determine carrier type) - async def request_single_carrier_presence( - self, - carrier_position: int - ): - """ Request single carrier presence + async def request_single_carrier_presence(self, carrier_position: int): + """Request single carrier presence Args: carrier_position: Carrier position (slot number) @@ -5444,38 +5584,30 @@ async def request_single_carrier_presence( # Move autoload/scanner X-drive into slot number async def move_autoload_to_slot(self, slot_number: int): - """ Move autoload to specific slot/track position """ + """Move autoload to specific slot/track position""" assert 1 <= slot_number <= 54, "slot_number must be between 1 and 54" slot_no_as_safe_str = str(slot_number).zfill(2) - return await self.send_command( - module="I0", - command="XP", - xp=slot_no_as_safe_str - ) + return await self.send_command(module="I0", command="XP", xp=slot_no_as_safe_str) # Park autoload async def park_autoload(self): - """ Park autoload """ + """Park autoload""" # Identify max number of x positions for your liquid handler max_x_pos = str(self.extended_conf["xt"]).zfill(2) # Park autoload to max x position available - return await self.send_command( - module="I0", - command="XP", - xp=max_x_pos - ) + return await self.send_command(module="I0", command="XP", xp=max_x_pos) # TODO:(command:CA) Push out carrier to loading tray (after identification CI) async def unload_carrier(self, carrier: Carrier): - """ Use autoload to unload carrier. """ + """Use autoload to unload carrier.""" # Identify carrier end rail track_width = 22.5 - carrier_width = carrier.get_absolute_location().x - 100 + carrier.get_absolute_size_x() + carrier_width = carrier.get_absolute_location().x - 100 + carrier.get_absolute_size_x() carrier_end_rail = int(carrier_width / track_width) assert 1 <= carrier_end_rail <= 54, "carrier loading rail must be between 1 and 54" @@ -5496,19 +5628,18 @@ async def load_carrier( carrier: Carrier, barcode_reading: bool = False, barcode_reading_direction: Literal["horizontal", "vertical"] = "horizontal", - barcode_symbology: - Literal[ - "ISBT Standard", - "Code 128 (Subset B and C)", - "Code 39", - "Codebar", - "Code 2of5 Interleaved", - "UPC A/E", - "YESN/EAN 8", - "Code 93" - ] = "Code 128 (Subset B and C)", + barcode_symbology: Literal[ + "ISBT Standard", + "Code 128 (Subset B and C)", + "Code 39", + "Codebar", + "Code 2of5 Interleaved", + "UPC A/E", + "YESN/EAN 8", + "Code 93", + ] = "Code 128 (Subset B and C)", no_container_per_carrier: int = 5, - park_autoload_after: bool = True + park_autoload_after: bool = True, ): """ Use autoload to load carrier. @@ -5523,10 +5654,7 @@ async def load_carrier( park_autoload_after: Whether to park autoload after loading. Default True. """ - barcode_reading_direction_dict = { - "vertical": "0", - "horizontal": "1" - } + barcode_reading_direction_dict = {"vertical": "0", "horizontal": "1"} barcode_symbology_dict = { "ISBT Standard": "70", "Code 128 (Subset B and C)": "71", @@ -5539,7 +5667,7 @@ async def load_carrier( } # Identify carrier end rail track_width = 22.5 - carrier_width = carrier.get_absolute_location().x - 100 + carrier.get_absolute_size_x() + carrier_width = carrier.get_absolute_location().x - 100 + carrier.get_absolute_size_x() carrier_end_rail = int(carrier_width / track_width) assert 1 <= carrier_end_rail <= 54, "carrier loading rail must be between 1 and 54" @@ -5548,8 +5676,10 @@ async def load_carrier( carrier_end_rail_str = str(carrier_end_rail).zfill(2) if presence_check != 1: - raise ValueError(f"""No carrier found at position {carrier_end_rail}, - have you placed the carrier onto the correct autoload tray position?""") + raise ValueError( + f"""No carrier found at position {carrier_end_rail}, + have you placed the carrier onto the correct autoload tray position?""" + ) # Set carrier type for identification purposes await self.send_command(module="C0", command="CI", cp=carrier_end_rail_str) @@ -5559,38 +5689,28 @@ async def load_carrier( if barcode_reading: # Choose barcode symbology await self.send_command( - module="C0", - command="CB", - bt=barcode_symbology_dict[barcode_symbology] + module="C0", command="CB", bt=barcode_symbology_dict[barcode_symbology] ) # Load and read out barcodes resp = await self.send_command( module="C0", command="CL", bd=barcode_reading_direction_dict[barcode_reading_direction], - bp="0616", # Barcode reading direction (0 = vertical 1 = horizontal) - co="0960", # Distance between containers (pattern) [0.1 mm] - cf="380", # Width of reading window [0.1 mm] - cv="1281", # Carrier reading speed [0.1 mm]/s - cn=str(no_container_per_carrier).zfill(2), # No of containers (cups, plates) in a carrier - ) - else: # without barcoding - resp = await self.send_command( - module="C0", - command="CL", - cn="00" + bp="0616", # Barcode reading direction (0 = vertical 1 = horizontal) + co="0960", # Distance between containers (pattern) [0.1 mm] + cf="380", # Width of reading window [0.1 mm] + cv="1281", # Carrier reading speed [0.1 mm]/s + cn=str(no_container_per_carrier).zfill(2), # No of containers (cups, plates) in a carrier ) + else: # without barcoding + resp = await self.send_command(module="C0", command="CL", cn="00") if park_autoload_after: await self.park_autoload() return resp - async def set_loading_indicators( - self, - bit_pattern: List[bool], - blink_pattern: List[bool] - ): - """ Set loading indicators (LEDs) + async def set_loading_indicators(self, bit_pattern: List[bool], blink_pattern: List[bool]): + """Set loading indicators (LEDs) The docs here are a little weird because 2^54 < 7FFFFFFFFFFFFF. @@ -5606,14 +5726,11 @@ def pattern2hex(pattern: List[bool]) -> str: bit_string = "".join(["1" if x else "0" for x in pattern]) return hex(int(bit_string, base=2))[2:].upper().zfill(14) - bit_pattern_hex = pattern2hex(bit_pattern) + bit_pattern_hex = pattern2hex(bit_pattern) blink_pattern_hex = pattern2hex(blink_pattern) return await self.send_command( - module="C0", - command="CP", - cl=bit_pattern_hex, - cb=blink_pattern_hex + module="C0", command="CP", cl=bit_pattern_hex, cb=blink_pattern_hex ) # TODO:(command:CS) Check for presence of carriers on loading tray @@ -5626,9 +5743,9 @@ async def set_barcode_type( codebar: bool = True, code2_5: bool = True, UPC_AE: bool = True, - EAN8: bool = True + EAN8: bool = True, ): - """ Set bar code type: which types of barcodes will be scanned for. + """Set bar code type: which types of barcodes will be scanned for. Args: ISBT_Standard: ISBT_Standard. Default True. @@ -5650,19 +5767,12 @@ async def set_barcode_type( # Convert bit pattern to hex. bt_hex = hex(int(bt, base=2)) - return await self.send_command( - module="C0", - command="CB", - bt=bt_hex - ) + return await self.send_command(module="C0", command="CB", bt=bt_hex) # TODO:(command:CW) Unload carrier finally - async def set_carrier_monitoring( - self, - should_monitor: bool = False - ): - """ Set carrier monitoring + async def set_carrier_monitoring(self, should_monitor: bool = False): + """Set carrier monitoring Args: should_monitor: whether carrier should be monitored. @@ -5671,11 +5781,7 @@ async def set_carrier_monitoring( True if present, False otherwise """ - return await self.send_command( - module="C0", - command="CU", - cu=should_monitor - ) + return await self.send_command(module="C0", command="CU", cu=should_monitor) # TODO:(command:CN) Take out the carrier to identification position @@ -5684,7 +5790,7 @@ async def set_carrier_monitoring( # TODO:(command:RC) Query presence of carrier on deck async def request_auto_load_slot_position(self): - """ Request auto load slot position. + """Request auto load slot position. Returns: slot position (0..54) @@ -5708,11 +5814,8 @@ async def request_auto_load_slot_position(self): # -------------- 3.15 Pump unit commands -------------- - async def request_pump_settings( - self, - pump_station: int = 1 - ): - """ Set carrier monitoring + async def request_pump_settings(self, pump_station: int = 1): + """Set carrier monitoring Args: carrier_position: pump station number (1..3) @@ -5727,12 +5830,7 @@ async def request_pump_settings( assert 1 <= pump_station <= 3, "pump_station must be between 1 and 3" - return await self.send_command( - module="C0", - command="ET", - fmt="et#", - ep=pump_station - ) + return await self.send_command(module="C0", command="ET", fmt="et#", ep=pump_station) # -------------- 3.15.1 DC Wash commands (only for revision up to 01) -------------- @@ -5752,11 +5850,8 @@ async def request_pump_settings( # -------------- 3.15.3 Dual chamber pump unit only -------------- - async def initialize_dual_pump_station_valves( - self, - pump_station: int = 1 - ): - """ Initialize pump station valves (dual chamber only) + async def initialize_dual_pump_station_valves(self, pump_station: int = 1): + """Initialize pump station valves (dual chamber only) Args: carrier_position: pump station number (1..3) @@ -5764,11 +5859,7 @@ async def initialize_dual_pump_station_valves( assert 1 <= pump_station <= 3, "pump_station must be between 1 and 3" - return await self.send_command( - module="C0", - command="EJ", - ep=pump_station - ) + return await self.send_command(module="C0", command="EJ", ep=pump_station) async def fill_selected_dual_chamber( self, @@ -5776,9 +5867,9 @@ async def fill_selected_dual_chamber( drain_before_refill: bool = False, wash_fluid: int = 1, chamber: int = 2, - waste_chamber_suck_time_after_sensor_change: int = 0 + waste_chamber_suck_time_after_sensor_change: int = 0, ): - """ Initialize pump station valves (dual chamber only) + """Initialize pump station valves (dual chamber only) Args: carrier_position: pump station number (1..3) @@ -5797,12 +5888,7 @@ async def fill_selected_dual_chamber( # 1 = wash fluid 1 <-> chamber 1 # 2 = wash fluid 2 <-> chamber 1 # 3 = wash fluid 2 <-> chamber 2 - connection = { - (1, 2): 0, - (1, 1): 1, - (2, 1): 2, - (2, 2): 3 - }[wash_fluid, chamber] + connection = {(1, 2): 0, (1, 1): 1, (2, 1): 2, (2, 2): 3}[wash_fluid, chamber] return await self.send_command( module="C0", @@ -5811,16 +5897,13 @@ async def fill_selected_dual_chamber( ed=drain_before_refill, ek=connection, eu=f"{waste_chamber_suck_time_after_sensor_change:02}", - wait=False + wait=False, ) # TODO:(command:EK) Drain selected chamber - async def drain_dual_chamber_system( - self, - pump_station: int = 1 - ): - """ Drain system (dual chamber only) + async def drain_dual_chamber_system(self, pump_station: int = 1): + """Drain system (dual chamber only) Args: carrier_position: pump station number (1..3) @@ -5828,11 +5911,7 @@ async def drain_dual_chamber_system( assert 1 <= pump_station <= 3, "pump_station must be between 1 and 3" - return await self.send_command( - module="C0", - command="EL", - ep=pump_station - ) + return await self.send_command(module="C0", command="EL", ep=pump_station) # TODO:(command:QD) Request dual chamber pump station prime status @@ -5849,87 +5928,57 @@ async def drain_dual_chamber_system( # -------------- 3.17.1 Pre & Initialization commands -------------- async def initialize_iswap(self): - """ Initialize iSWAP (for standalone configuration only) """ + """Initialize iSWAP (for standalone configuration only)""" return await self.send_command(module="C0", command="FI") async def initialize_autoload(self): - """ Initialize autoload (for standalone configuration only) """ + """Initialize autoload (for standalone configuration only)""" return await self.send_command(module="C0", command="II") async def position_components_for_free_iswap_y_range(self): - """ Position all components so that there is maximum free Y range for iSWAP """ + """Position all components so that there is maximum free Y range for iSWAP""" return await self.send_command(module="C0", command="FY") - async def move_iswap_x_direction( - self, - step_size: int = 0, - direction: int = 0 - ): - """ Move iSWAP in X-direction + async def move_iswap_x_direction(self, step_size: int = 0, direction: int = 0): + """Move iSWAP in X-direction Args: step_size: X Step size [0.1mm] Between 0 and 999. Default 0. direction: X direction. 0 = positive 1 = negative """ - return await self.send_command( - module="C0", - command="GX", - gx=step_size, - xd=direction - ) + return await self.send_command(module="C0", command="GX", gx=step_size, xd=direction) - async def move_iswap_y_direction( - self, - step_size: int = 0, - direction: int = 0 - ): - """ Move iSWAP in Y-direction + async def move_iswap_y_direction(self, step_size: int = 0, direction: int = 0): + """Move iSWAP in Y-direction Args: step_size: Y Step size [0.1mm] Between 0 and 999. Default 0. direction: Y direction. 0 = positive 1 = negative """ - return await self.send_command( - module="C0", - command="GY", - gx=step_size, - xd=direction - ) + return await self.send_command(module="C0", command="GY", gx=step_size, xd=direction) - async def move_iswap_z_direction( - self, - step_size: int = 0, - direction: int = 0 - ): - """ Move iSWAP in Z-direction + async def move_iswap_z_direction(self, step_size: int = 0, direction: int = 0): + """Move iSWAP in Z-direction Args: step_size: Z Step size [0.1mm] Between 0 and 999. Default 0. direction: Z direction. 0 = positive 1 = negative """ - return await self.send_command( - module="C0", - command="GZ", - gx=step_size, - xd=direction - ) + return await self.send_command(module="C0", command="GZ", gx=step_size, xd=direction) async def open_not_initialized_gripper(self): - """ Open not initialized gripper """ + """Open not initialized gripper""" return await self.send_command(module="C0", command="GI") - async def iswap_open_gripper( - self, - open_position: int = 1320 - ): - """ Open gripper + async def iswap_open_gripper(self, open_position: int = 1320): + """Open gripper Args: open_position: Open position [0.1mm] (0.1 mm = 16 increments) The gripper moves to pos + 20. @@ -5938,19 +5987,12 @@ async def iswap_open_gripper( assert 0 <= open_position <= 9999, "open_position must be between 0 and 9999" - return await self.send_command( - module="C0", - command="GF", - go=f"{open_position:04}" - ) + return await self.send_command(module="C0", command="GF", go=f"{open_position:04}") async def iswap_close_gripper( - self, - grip_strength: int = 5, - plate_width: int = 0, - plate_width_tolerance: int = 0 + self, grip_strength: int = 5, plate_width: int = 0, plate_width_tolerance: int = 0 ): - """ Close gripper + """Close gripper The gripper should be at the position gb+gt+20 before sending this command. @@ -5962,20 +6004,13 @@ async def iswap_close_gripper( """ return await self.send_command( - module="C0", - command="GC", - gw=grip_strength, - gb=plate_width, - gt=plate_width_tolerance + module="C0", command="GC", gw=grip_strength, gb=plate_width, gt=plate_width_tolerance ) # -------------- 3.17.2 Stack handling commands CP -------------- - async def park_iswap( - self, - minimum_traverse_height_at_beginning_of_a_command: int = 2840 - ): - """ Close gripper + async def park_iswap(self, minimum_traverse_height_at_beginning_of_a_command: int = 2840): + """Close gripper The gripper should be at the position gb+gt+20 before sending this command. @@ -5984,13 +6019,12 @@ async def park_iswap( of a command [0.1mm]. Must be between 0 and 3600. Default 3600. """ - assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ - "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert ( + 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 + ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" command_output = await self.send_command( - module="C0", - command="PG", - th=minimum_traverse_height_at_beginning_of_a_command + module="C0", command="PG", th=minimum_traverse_height_at_beginning_of_a_command ) # Once the command has completed successfully, set _iswap_parked to True @@ -6015,9 +6049,9 @@ async def iswap_get_plate( collision_control_level: int = 1, acceleration_index_high_acc: int = 4, acceleration_index_low_acc: int = 1, - fold_up_sequence_at_the_end_of_process: bool = True + fold_up_sequence_at_the_end_of_process: bool = True, ): - """ Get plate using iswap. + """Get plate using iswap. Args: x_position: Plate center in X direction [0.1mm]. Must be between 0 and 30000. Default 0. @@ -6051,19 +6085,23 @@ async def iswap_get_plate( assert 0 <= z_position <= 3600, "z_position must be between 0 and 3600" assert 0 <= z_direction <= 1, "z_direction must be between 0 and 1" assert 1 <= grip_direction <= 4, "grip_direction must be between 1 and 4" - assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ - "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" - assert 0 <= z_position_at_the_command_end <= 3600, \ - "z_position_at_the_command_end must be between 0 and 3600" + assert ( + 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 + ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert ( + 0 <= z_position_at_the_command_end <= 3600 + ), "z_position_at_the_command_end must be between 0 and 3600" assert 1 <= grip_strength <= 9, "grip_strength must be between 1 and 9" assert 0 <= open_gripper_position <= 9999, "open_gripper_position must be between 0 and 9999" assert 0 <= plate_width <= 9999, "plate_width must be between 0 and 9999" assert 0 <= plate_width_tolerance <= 99, "plate_width_tolerance must be between 0 and 99" assert 0 <= collision_control_level <= 1, "collision_control_level must be between 0 and 1" - assert 0 <= acceleration_index_high_acc <= 4, \ - "acceleration_index_high_acc must be between 0 and 4" - assert 0 <= acceleration_index_low_acc <= 4, \ - "acceleration_index_low_acc must be between 0 and 4" + assert ( + 0 <= acceleration_index_high_acc <= 4 + ), "acceleration_index_high_acc must be between 0 and 4" + assert ( + 0 <= acceleration_index_low_acc <= 4 + ), "acceleration_index_low_acc must be between 0 and 4" command_output = await self.send_command( module="C0", @@ -6104,9 +6142,9 @@ async def iswap_put_plate( open_gripper_position: int = 860, collision_control_level: int = 1, acceleration_index_high_acc: int = 4, - acceleration_index_low_acc: int = 1 + acceleration_index_low_acc: int = 1, ): - """ put plate + """put plate Args: x_position: Plate center in X direction [0.1mm]. Must be between 0 and 30000. Default 0. @@ -6138,16 +6176,20 @@ async def iswap_put_plate( assert 0 <= z_position <= 3600, "z_position must be between 0 and 3600" assert 0 <= z_direction <= 1, "z_direction must be between 0 and 1" assert 1 <= grip_direction <= 4, "grip_direction must be between 1 and 4" - assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ - "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" - assert 0 <= z_position_at_the_command_end <= 3600, \ - "z_position_at_the_command_end must be between 0 and 3600" + assert ( + 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 + ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert ( + 0 <= z_position_at_the_command_end <= 3600 + ), "z_position_at_the_command_end must be between 0 and 3600" assert 0 <= open_gripper_position <= 9999, "open_gripper_position must be between 0 and 9999" assert 0 <= collision_control_level <= 1, "collision_control_level must be between 0 and 1" - assert 0 <= acceleration_index_high_acc <= 4, \ - "acceleration_index_high_acc must be between 0 and 4" - assert 0 <= acceleration_index_low_acc <= 4, \ - "acceleration_index_low_acc must be between 0 and 4" + assert ( + 0 <= acceleration_index_high_acc <= 4 + ), "acceleration_index_high_acc must be between 0 and 4" + assert ( + 0 <= acceleration_index_low_acc <= 4 + ), "acceleration_index_low_acc must be between 0 and 4" command_output = await self.send_command( module="C0", @@ -6175,10 +6217,10 @@ async def iswap_rotate( position: int = 33, gripper_velocity: int = 55_000, gripper_acceleration: int = 170, - gripper_protection: Literal[0,1,2,3,4,5,6,7] = 5, + gripper_protection: Literal[0, 1, 2, 3, 4, 5, 6, 7] = 5, wrist_velocity: int = 48_000, wrist_acceleration: int = 145, - wrist_protection: Literal[0,1,2,3,4,5,6,7] = 5, + wrist_protection: Literal[0, 1, 2, 3, 4, 5, 6, 7] = 5, ): """ Rotate the iswap to a predifined position. @@ -6215,9 +6257,9 @@ async def move_plate_to_position( minimum_traverse_height_at_beginning_of_a_command: int = 3600, collision_control_level: int = 1, acceleration_index_high_acc: int = 4, - acceleration_index_low_acc: int = 1 + acceleration_index_low_acc: int = 1, ): - """ Move plate to position. + """Move plate to position. Args: x_position: Plate center in X direction [0.1mm]. Must be between 0 and 30000. Default 0. @@ -6243,13 +6285,16 @@ async def move_plate_to_position( assert 0 <= z_position <= 3600, "z_position must be between 0 and 3600" assert 0 <= z_direction <= 1, "z_direction must be between 0 and 1" assert 1 <= grip_direction <= 4, "grip_direction must be between 1 and 4" - assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ - "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert ( + 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 + ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" assert 0 <= collision_control_level <= 1, "collision_control_level must be between 0 and 1" - assert 0 <= acceleration_index_high_acc <= 4, \ - "acceleration_index_high_acc must be between 0 and 4" - assert 0 <= acceleration_index_low_acc <= 4, \ - "acceleration_index_low_acc must be between 0 and 4" + assert ( + 0 <= acceleration_index_high_acc <= 4 + ), "acceleration_index_high_acc must be between 0 and 4" + assert ( + 0 <= acceleration_index_low_acc <= 4 + ), "acceleration_index_low_acc must be between 0 and 4" command_output = await self.send_command( module="C0", @@ -6263,7 +6308,7 @@ async def move_plate_to_position( gr=grip_direction, th=f"{minimum_traverse_height_at_beginning_of_a_command:04}", ga=collision_control_level, - xe=f"{acceleration_index_high_acc} {acceleration_index_low_acc}" + xe=f"{acceleration_index_high_acc} {acceleration_index_low_acc}", ) # Once the command has completed successfuly, set _iswap_parked to false self._iswap_parked = False @@ -6272,9 +6317,9 @@ async def move_plate_to_position( async def collapse_gripper_arm( self, minimum_traverse_height_at_beginning_of_a_command: int = 3600, - fold_up_sequence_at_the_end_of_process: bool = True + fold_up_sequence_at_the_end_of_process: bool = True, ): - """ Collapse gripper arm + """Collapse gripper arm Args: minimum_traverse_height_at_beginning_of_a_command: Minimum traverse height at beginning of a @@ -6283,8 +6328,9 @@ async def collapse_gripper_arm( fold_up_sequence_at_the_end_of_process: fold up sequence at the end of process. Default True. """ - assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ - "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert ( + 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 + ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" return await self.send_command( module="C0", @@ -6317,9 +6363,9 @@ async def prepare_iswap_teaching( minimum_traverse_height_at_beginning_of_a_command: int = 3600, collision_control_level: int = 1, acceleration_index_high_acc: int = 4, - acceleration_index_low_acc: int = 1 + acceleration_index_low_acc: int = 1, ): - """ Prepare iSWAP teaching + """Prepare iSWAP teaching Prepare for teaching with iSWAP @@ -6348,13 +6394,16 @@ async def prepare_iswap_teaching( assert 0 <= z_direction <= 1, "z_direction must be between 0 and 1" assert 0 <= location <= 1, "location must be between 0 and 1" assert 0 <= hotel_depth <= 3000, "hotel_depth must be between 0 and 3000" - assert 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600, \ - "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" + assert ( + 0 <= minimum_traverse_height_at_beginning_of_a_command <= 3600 + ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" assert 0 <= collision_control_level <= 1, "collision_control_level must be between 0 and 1" - assert 0 <= acceleration_index_high_acc <= 4, \ - "acceleration_index_high_acc must be between 0 and 4" - assert 0 <= acceleration_index_low_acc <= 4, \ - "acceleration_index_low_acc must be between 0 and 4" + assert ( + 0 <= acceleration_index_high_acc <= 4 + ), "acceleration_index_high_acc must be between 0 and 4" + assert ( + 0 <= acceleration_index_low_acc <= 4 + ), "acceleration_index_low_acc must be between 0 and 4" return await self.send_command( module="C0", @@ -6370,7 +6419,7 @@ async def prepare_iswap_teaching( gr=grip_direction, th=f"{minimum_traverse_height_at_beginning_of_a_command:04}", ga=collision_control_level, - xe=f"{acceleration_index_high_acc} {acceleration_index_low_acc}" + xe=f"{acceleration_index_high_acc} {acceleration_index_low_acc}", ) async def get_logic_iswap_position( @@ -6384,9 +6433,9 @@ async def get_logic_iswap_position( location: int = 0, hotel_depth: int = 1300, grip_direction: int = 1, - collision_control_level: int = 1 + collision_control_level: int = 1, ): - """ Get logic iSWAP position + """Get logic iSWAP position Args: x_position: Plate center in X direction [0.1mm]. Must be between 0 and 30000. Default 0. @@ -6432,7 +6481,7 @@ async def get_logic_iswap_position( # -------------- 3.17.6 iSWAP query -------------- async def request_iswap_in_parking_position(self): - """ Request iSWAP in parking position + """Request iSWAP in parking position Returns: 0 = gripper is not in parking position @@ -6442,7 +6491,7 @@ async def request_iswap_in_parking_position(self): return await self.send_command(module="C0", command="RG", fmt="rg#") async def request_plate_in_iswap(self) -> bool: - """ Request plate in iSWAP + """Request plate in iSWAP Returns: True if holding a plate, False otherwise. @@ -6452,7 +6501,7 @@ async def request_plate_in_iswap(self) -> bool: return resp is not None and resp["ph"] == 1 async def request_iswap_position(self): - """ Request iSWAP position ( grip center ) + """Request iSWAP position ( grip center ) Returns: xs: Hotel center in X direction [0.1mm] @@ -6466,7 +6515,7 @@ async def request_iswap_position(self): return await self.send_command(module="C0", command="QG", fmt="xs#####xd#yj####yd#zj####zd#") async def request_iswap_initialization_status(self) -> bool: - """ Request iSWAP initialization status + """Request iSWAP initialization status Returns: True if iSWAP is fully initialized @@ -6478,27 +6527,27 @@ async def request_iswap_initialization_status(self) -> bool: # -------------- 3.18 Cover and port control -------------- async def lock_cover(self): - """ Lock cover """ + """Lock cover""" return await self.send_command(module="C0", command="CO") async def unlock_cover(self): - """ Unlock cover """ + """Unlock cover""" return await self.send_command(module="C0", command="HO") async def disable_cover_control(self): - """ Disable cover control """ + """Disable cover control""" return await self.send_command(module="C0", command="CD") async def enable_cover_control(self): - """ Enable cover control """ + """Enable cover control""" return await self.send_command(module="C0", command="CE") async def set_cover_output(self, output: int = 0): - """ Set cover output + """Set cover output Args: output: 1 = cover lock; 2 = reserve out; 3 = reserve out. @@ -6508,7 +6557,7 @@ async def set_cover_output(self, output: int = 0): return await self.send_command(module="C0", command="OS", on=output) async def reset_output(self, output: int = 0): - """ Reset output + """Reset output Returns: output: 1 = cover lock; 2 = reserve out; 3 = reserve out. @@ -6518,7 +6567,7 @@ async def reset_output(self, output: int = 0): return await self.send_command(module="C0", command="QS", on=output, fmt="#") async def request_cover_open(self) -> bool: - """ Request cover open + """Request cover open Returns: True if the cover is open """ @@ -6526,7 +6575,6 @@ async def request_cover_open(self) -> bool: resp = await self.send_command(module="C0", command="QC", fmt="qc#") return bool(resp["qc"]) - # -------------- 4.0 Direct Device Integration -------------- # Communication occurs directly through STAR "TCC" connections, # i.e. firmware commands. This means devices can be seen as part @@ -6542,12 +6590,14 @@ async def check_type_is_hhs(self, device_number: int): firmware_version = await self.send_command(module=f"T{device_number}", command="RF") if "Heater Shaker" not in firmware_version: - raise ValueError(f"Device number {device_number} does not connect to a Hamilton" \ - f" Heater Shaker, found {firmware_version} instead." \ - f"Have you called the wrong device number?") + raise ValueError( + f"Device number {device_number} does not connect to a Hamilton" + f" Heater Shaker, found {firmware_version} instead." + f"Have you called the wrong device number?" + ) async def initialize_hhs(self, device_number: int) -> str: - """ Initialize Hamilton Heater Shaker (HHS) at specified TCC port + """Initialize Hamilton Heater Shaker (HHS) at specified TCC port Args: device_number: TCC connect number to the HHS @@ -6562,8 +6612,10 @@ async def initialize_hhs(self, device_number: int) -> str: try: await self.send_command(module=module_pointer, command="QU") except TimeoutError as exc: - error_message = f"No Hamilton Heater Shaker found at device_number {device_number}" \ + error_message = ( + f"No Hamilton Heater Shaker found at device_number {device_number}" f", have you checked your connections? Original error: {exc}" + ) raise ValueError(error_message) from exc await self.check_type_is_hhs(device_number) @@ -6583,36 +6635,32 @@ async def initialize_hhs(self, device_number: int) -> str: # -------------- 4.1.1 HHS Plate Lock -------------- async def open_plate_lock(self, device_number: int): - """ Open HHS plate lock """ + """Open HHS plate lock""" await self.check_type_is_hhs(device_number) return await self.send_command( module=f"T{device_number}", command="LP", - lp="0" # => open plate lock + lp="0", # => open plate lock ) async def close_plate_lock(self, device_number: int): - """ Close HHS plate lock """ + """Close HHS plate lock""" await self.check_type_is_hhs(device_number) return await self.send_command( - module = f"T{device_number}", + module=f"T{device_number}", command="LP", - lp="1" # => close plate lock + lp="1", # => close plate lock ) # -------------- 4.1.2 HHS Shaking -------------- async def start_shaking_at_hhs( - self, - device_number: int, - rpm: int, - rotation: int = 0, - plate_locked_during_shaking: bool = True + self, device_number: int, rpm: int, rotation: int = 0, plate_locked_during_shaking: bool = True ): - """ Start shaking of specified HHS + """Start shaking of specified HHS Args: rpm: round per minute @@ -6632,11 +6680,11 @@ async def start_shaking_at_hhs( command="SB", st=str(rotation), sv=str(rpm).zfill(4), - sr="00500" # ??? maybe shakingAccRamp rate? + sr="00500", # ??? maybe shakingAccRamp rate? ) async def stop_shaking_at_hhs(self, device_number: int): - """ Close HHS plate lock """ + """Close HHS plate lock""" await self.check_type_is_hhs(device_number) @@ -6649,7 +6697,7 @@ async def start_temperature_control_at_hhs( device_number: int, temp: Union[float, int], ): - """ Start temperature regulation of specified HHS """ + """Start temperature regulation of specified HHS""" await self.check_type_is_hhs(device_number) assert 0 < temp <= 105 @@ -6662,12 +6710,12 @@ async def start_temperature_control_at_hhs( return await self.send_command( module=f"T{device_number}", - command="TA", # temperature adjustment + command="TA", # temperature adjustment ta=safe_temp_str, ) async def get_temperature_at_hhs(self, device_number: int) -> dict: - """ Query current temperatures of both sensors of specified HHS + """Query current temperatures of both sensors of specified HHS Returns: Dictionary with keys "middle_T" and "edge_T" for the middle and edge temperature @@ -6676,12 +6724,12 @@ async def get_temperature_at_hhs(self, device_number: int) -> dict: await self.check_type_is_hhs(device_number) request_temperature = await self.send_command(module=f"T{device_number}", command="RT") - processed_t_info = [int(x)/10 for x in request_temperature.split("+")[-2:]] + processed_t_info = [int(x) / 10 for x in request_temperature.split("+")[-2:]] - return {"middle_T": processed_t_info[0],"edge_T": processed_t_info[-1]} + return {"middle_T": processed_t_info[0], "edge_T": processed_t_info[-1]} async def stop_temperature_control_at_hhs(self, device_number: int): - """ Stop temperature regulation of specified HHS """ + """Stop temperature regulation of specified HHS""" await self.check_type_is_hhs(device_number) @@ -6697,12 +6745,14 @@ async def check_type_is_hhc(self, device_number: int): firmware_version = await self.send_command(module=f"T{device_number}", command="RF") if "Hamilton Heater Cooler" not in firmware_version: - raise ValueError(f"Device number {device_number} does not connect to a Hamilton" \ - f" Heater-Cooler, found {firmware_version} instead." \ - f"Have you called the wrong device number?") + raise ValueError( + f"Device number {device_number} does not connect to a Hamilton" + f" Heater-Cooler, found {firmware_version} instead." + f"Have you called the wrong device number?" + ) async def initialize_hhc(self, device_number: int) -> str: - """ Initialize Hamilton Heater Cooler (HHC) at specified TCC port + """Initialize Hamilton Heater Cooler (HHC) at specified TCC port Args: device_number: TCC connect number to the HHC @@ -6714,8 +6764,10 @@ async def initialize_hhc(self, device_number: int) -> str: try: await self.send_command(module=module_pointer, command="QU") except TimeoutError as exc: - error_message = f"No Hamilton Heater Cooler found at device_number {device_number}" \ + error_message = ( + f"No Hamilton Heater Cooler found at device_number {device_number}" f", have you checked your connections? Original error: {exc}" + ) raise ValueError(error_message) from exc await self.check_type_is_hhc(device_number) @@ -6736,9 +6788,9 @@ async def initialize_hhc(self, device_number: int) -> str: async def start_temperature_control_at_hhc( self, device_number: int, - temp: Union[float, int], + temp: Union[float, int], ): - """ Start temperature regulation of specified HHC """ + """Start temperature regulation of specified HHC""" await self.check_type_is_hhc(device_number) assert 0 < temp <= 105 @@ -6751,24 +6803,24 @@ async def start_temperature_control_at_hhc( return await self.send_command( module=f"T{device_number}", - command="TA", # temperature adjustment + command="TA", # temperature adjustment ta=safe_temp_str, - tb="1800", # TODO: identify precise purpose? - tc="0020", # TODO: identify precise purpose? + tb="1800", # TODO: identify precise purpose? + tc="0020", # TODO: identify precise purpose? ) async def get_temperature_at_hhc(self, device_number: int) -> dict: - """ Query current temperatures of both sensors of specified HHC """ + """Query current temperatures of both sensors of specified HHC""" await self.check_type_is_hhc(device_number) request_temperature = await self.send_command(module=f"T{device_number}", command="RT") - processed_t_info = [int(x)/10 for x in request_temperature.split("+")[-2:]] + processed_t_info = [int(x) / 10 for x in request_temperature.split("+")[-2:]] - return {"middle_T": processed_t_info[0],"edge_T": processed_t_info[-1]} + return {"middle_T": processed_t_info[0], "edge_T": processed_t_info[-1]} async def query_whether_temperature_reached_at_hhc(self, device_number: int): - """ Stop temperature regulation of specified HHC """ + """Stop temperature regulation of specified HHC""" await self.check_type_is_hhc(device_number) query_current_control_status = await self.send_command( @@ -6778,13 +6830,13 @@ async def query_whether_temperature_reached_at_hhc(self, device_number: int): return query_current_control_status["qd"] == 0 async def stop_temperature_control_at_hhc(self, device_number: int): - """ Stop temperature regulation of specified HHC """ + """Stop temperature regulation of specified HHC""" await self.check_type_is_hhc(device_number) return await self.send_command(module=f"T{device_number}", command="TO") -# -------------- Extra - Probing labware with STAR - making STAR into a CMM -------------- + # -------------- Extra - Probing labware with STAR - making STAR into a CMM -------------- async def probe_z_height_using_channel( self, @@ -6797,9 +6849,9 @@ async def probe_z_height_using_channel( detection_drop: int = 2, post_detection_trajectory: Literal[0, 1] = 1, post_detection_dist: int = 100, - move_channels_to_save_pos_after: bool = False + move_channels_to_save_pos_after: bool = False, ) -> float: - """ Probes the Z-height using a specified channel on a liquid handling device. + """Probes the Z-height using a specified channel on a liquid handling device. Commands the liquid handler to perform a Liquid Level Detection (LLD) operation using the specified channel (this means only conductive materials can be probed!). @@ -6822,27 +6874,27 @@ async def probe_z_height_using_channel( float: The detected Z-height in mm. """ - assert 9320 <= lowest_immers_pos <= 31200, ( - "Lowest immersion position [increment] must be between 9320 and 31200" - ) - assert 9320 <= start_pos_lld_search <= 31200, ( - "Start position of LLD search [increment] must be between 9320 and 31200" - ) - assert 20 <= channel_speed <= 15000, ( - "LLD search speed [increment/second] must be between 20 and 15000" - ) - assert 5 <= channel_acceleration <= 150, ( - "Channel acceleration [increment] must be between 5 and 150" - ) - assert 0 <= detection_edge <= 1023, ( - "Edge steepness at capacitive LLD detection must be between 0 and 1023" - ) - assert 0 <= detection_drop <= 1023, ( - "Offset after capacitive LLD edge detection must be between 0 and 1023" - ) - assert 0 <= post_detection_dist <= 9999, ( - "Immersion depth after Liquid Level Detection [increment] must be between 0 and 9999" - ) + assert ( + 9320 <= lowest_immers_pos <= 31200 + ), "Lowest immersion position [increment] must be between 9320 and 31200" + assert ( + 9320 <= start_pos_lld_search <= 31200 + ), "Start position of LLD search [increment] must be between 9320 and 31200" + assert ( + 20 <= channel_speed <= 15000 + ), "LLD search speed [increment/second] must be between 20 and 15000" + assert ( + 5 <= channel_acceleration <= 150 + ), "Channel acceleration [increment] must be between 5 and 150" + assert ( + 0 <= detection_edge <= 1023 + ), "Edge steepness at capacitive LLD detection must be between 0 and 1023" + assert ( + 0 <= detection_drop <= 1023 + ), "Offset after capacitive LLD edge detection must be between 0 and 1023" + assert ( + 0 <= post_detection_dist <= 9999 + ), "Immersion depth after Liquid Level Detection [increment] must be between 0 and 9999" lowest_immers_pos_str = f"{lowest_immers_pos:05}" start_pos_lld_search_str = f"{start_pos_lld_search:05}" @@ -6855,20 +6907,20 @@ async def probe_z_height_using_channel( await self.send_command( module=f"P{channel_idx}", command="ZL", - zh=lowest_immers_pos_str, # Lowest immersion position [increment] - zc=start_pos_lld_search_str, # Start position of LLD search [increment] - zl=channel_speed_str, # Speed of channel movement - zr=channel_acc_str, # Acceleration [1000 increment/second^2] - gt=detection_edge_str, # Edge steepness at capacitive LLD detection - gl=detection_drop_str, # Offset after capacitive LLD edge detection - zj=post_detection_trajectory, # Movement of the channel after contacting surface - zi=post_detection_dist_str # Distance to move up after detection + zh=lowest_immers_pos_str, # Lowest immersion position [increment] + zc=start_pos_lld_search_str, # Start position of LLD search [increment] + zl=channel_speed_str, # Speed of channel movement + zr=channel_acc_str, # Acceleration [1000 increment/second^2] + gt=detection_edge_str, # Edge steepness at capacitive LLD detection + gl=detection_drop_str, # Offset after capacitive LLD edge detection + zj=post_detection_trajectory, # Movement of the channel after contacting surface + zi=post_detection_dist_str, # Distance to move up after detection ) if move_channels_to_save_pos_after: await self.move_all_channels_in_z_safety() get_llds = await self.request_pip_height_last_lld() - result_in_mm = float(get_llds["lh"][channel_idx-1] / 10) + result_in_mm = float(get_llds["lh"][channel_idx - 1] / 10) return result_in_mm @@ -6893,7 +6945,7 @@ async def put_in_hotel( hotel_center_z_direction: Literal[0, 1] = 0, clearance_height: int = 50, hotel_depth: int = 1_300, - grip_direction:GripDirection = GripDirection.FRONT, + grip_direction: GripDirection = GripDirection.FRONT, traverse_height_at_beginning: int = 3_600, z_position_at_end: int = 3_600, grip_strength: Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] = 5, @@ -6963,14 +7015,14 @@ async def get_from_hotel( hotel_center_z_direction: Literal[0, 1] = 0, clearance_height: int = 50, hotel_depth: int = 1_300, - grip_direction:GripDirection = GripDirection.FRONT, + grip_direction: GripDirection = GripDirection.FRONT, traverse_height_at_beginning: int = 3_600, z_position_at_end: int = 3_600, grip_strength: Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] = 5, open_gripper_position: int = 860, plate_width: int = 800, plate_width_tolerance: int = 20, - collision_control: Literal[0, 1]=1, + collision_control: Literal[0, 1] = 1, high_acceleration_index: Literal[1, 2, 3, 4] = 4, low_acceleration_index: Literal[1, 2, 3, 4] = 1, fold_up_at_end: bool = True, diff --git a/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py b/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py index 8a35469d36..a7303adba9 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py +++ b/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py @@ -1,36 +1,44 @@ -from typing import cast import unittest import unittest.mock +from typing import cast from pylabrobot.liquid_handling import LiquidHandler -from pylabrobot.liquid_handling.standard import Pickup, GripDirection from pylabrobot.liquid_handling.liquid_classes.hamilton.star import ( - StandardVolumeFilter_Water_DispenseSurface, + HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty, StandardVolumeFilter_Water_DispenseJet_Empty, - HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty) + StandardVolumeFilter_Water_DispenseSurface, +) +from pylabrobot.liquid_handling.standard import GripDirection, Pickup from pylabrobot.plate_reading import PlateReader from pylabrobot.plate_reading.plate_reader_tests import MockPlateReaderBackend from pylabrobot.resources import ( - Plate, Coordinate, Container, ResourceStack, Lid, - TIP_CAR_480_A00, TIP_CAR_288_C00, PLT_CAR_L5AC_A00, HT_P, HTF_L, Cor_96_wellplate_360ul_Fb, - no_volume_tracking + HT_P, + HTF_L, + PLT_CAR_L5AC_A00, + TIP_CAR_288_C00, + TIP_CAR_480_A00, + Container, + Coordinate, + Cor_96_wellplate_360ul_Fb, + Lid, + Plate, + ResourceStack, + no_volume_tracking, ) from pylabrobot.resources.hamilton import STARLetDeck from pylabrobot.resources.ml_star import STF_L - from tests.usb import MockDev, MockEndpoint from .STAR import ( STAR, - parse_star_fw_string, - STARFirmwareError, CommandSyntaxError, HamiltonNoTipError, HardwareError, - UnknownHamiltonError + STARFirmwareError, + UnknownHamiltonError, + parse_star_fw_string, ) - PICKUP_TIP_FORMAT = "xp##### (n)yp#### (n)tm# (n)tt##tp####tz####th####td#" DROP_TIP_FORMAT = "xp##### (n)yp#### (n)tm# (n)tp####tz####th####ti#" ASPIRATION_COMMAND_FORMAT = ( @@ -53,7 +61,7 @@ class TestSTARResponseParsing(unittest.TestCase): - """ Test parsing of response from Hamilton. """ + """Test parsing of response from Hamilton.""" def setUp(self): super().setUp() @@ -81,10 +89,10 @@ def test_parse_response_params(self): self.assertEqual(parsed, "") with self.assertRaises(ValueError): - parse_star_fw_string("C0QM", "id####") # pylint: disable=expression-not-assigned + parse_star_fw_string("C0QM", "id####") # pylint: disable=expression-not-assigned with self.assertRaises(ValueError): - parse_star_fw_string("C0RV", "") # pylint: disable=expression-not-assigned + parse_star_fw_string("C0RV", "") # pylint: disable=expression-not-assigned def test_parse_response_no_errors(self): parsed = parse_star_fw_string("C0QMid1111", "") @@ -138,7 +146,7 @@ def test_parse_slave_response_errors(self): class STARUSBCommsMocker(STAR): - """ Mocks PyUSB """ + """Mocks PyUSB""" async def setup(self, send_response: str): # type: ignore self.dev = MockDev(send_response) @@ -147,30 +155,30 @@ async def setup(self, send_response: str): # type: ignore class TestSTARUSBComms(unittest.IsolatedAsyncioTestCase): - """ Test that USB data is parsed correctly. """ + """Test that USB data is parsed correctly.""" async def test_send_command_correct_response(self): star = STARUSBCommsMocker() - await star.setup(send_response="C0QMid0001") # correct response + await star.setup(send_response="C0QMid0001") # correct response resp = await star.send_command("C0", command="QM", fmt="id####") self.assertEqual(resp, {"id": 1}) async def test_send_command_wrong_id(self): star = STARUSBCommsMocker(read_timeout=2, packet_read_timeout=1) - await star.setup(send_response="C0QMid0000") # wrong response + await star.setup(send_response="C0QMid0000") # wrong response with self.assertRaises(TimeoutError): await star.send_command("C0", command="QM") async def test_send_command_plaintext_response(self): star = STARUSBCommsMocker(read_timeout=2, packet_read_timeout=1) - await star.setup(send_response="this is plain text") # wrong response + await star.setup(send_response="this is plain text") # wrong response with self.assertRaises(TimeoutError): await star.send_command("C0", command="QM") class STARCommandCatcher(STAR): - """ Mock backend for star that catches commands and saves them instead of sending them to the - machine. """ + """Mock backend for star that catches commands and saves them instead of sending them to the + machine.""" def __init__(self): super().__init__() @@ -182,8 +190,16 @@ async def setup(self) -> None: self.core96_head_installed = True self._core_parked = True - async def send_command(self, module, command, tip_pattern=None, fmt="", # type: ignore - read_timeout=0, write_timeout=0, **kwargs): + async def send_command( + self, + module, + command, + tip_pattern=None, + fmt="", # type: ignore + read_timeout=0, + write_timeout=0, + **kwargs, + ): cmd, _ = self._assemble_command(module, command, tip_pattern, **kwargs) self.commands.append(cmd) @@ -192,7 +208,7 @@ async def stop(self): class TestSTARLiquidHandlerCommands(unittest.IsolatedAsyncioTestCase): - """ Test STAR backend for liquid handling. """ + """Test STAR backend for liquid handling.""" async def asyncSetUp(self): # pylint: disable=invalid-name @@ -207,22 +223,40 @@ async def asyncSetUp(self): self.plt_car = PLT_CAR_L5AC_A00(name="plate carrier") self.plt_car[0] = self.plate = Cor_96_wellplate_360ul_Fb(name="plate_01") - lid = Lid(name="plate_01_lid", size_x=self.plate.get_size_x(), size_y=self.plate.get_size_y(), - size_z=10, nesting_z_height=10) + lid = Lid( + name="plate_01_lid", + size_x=self.plate.get_size_x(), + size_y=self.plate.get_size_y(), + size_z=10, + nesting_z_height=10, + ) self.plate.assign_child_resource(lid) assert self.plate.lid is not None self.plt_car[1] = self.other_plate = Cor_96_wellplate_360ul_Fb(name="plate_02") - lid = Lid(name="plate_02_lid", size_x=self.other_plate.get_size_x(), - size_y=self.other_plate.get_size_y(), size_z=10, nesting_z_height=10) + lid = Lid( + name="plate_02_lid", + size_x=self.other_plate.get_size_x(), + size_y=self.other_plate.get_size_y(), + size_z=10, + nesting_z_height=10, + ) self.other_plate.assign_child_resource(lid) self.deck.assign_child_resource(self.plt_car, rails=9) class BlueBucket(Container): def __init__(self, name: str): - super().__init__(name, size_x=123, size_y=82, size_z=75, category="bucket", - max_volume=123 * 82 * 75, material_z_thickness=1) + super().__init__( + name, + size_x=123, + size_y=82, + size_z=75, + category="bucket", + max_volume=123 * 82 * 75, + material_z_thickness=1, + ) + self.bb = BlueBucket(name="blue bucket") - self.deck.assign_child_resource(self.bb, location=Coordinate(425, 141.5, 120-1)) + self.deck.assign_child_resource(self.bb, location=Coordinate(425, 141.5, 120 - 1)) self.maxDiff = None @@ -236,7 +270,7 @@ async def asyncTearDown(self): await self.lh.stop() def _assert_command_in_command_buffer(self, cmd: str, should_be: bool, fmt: str): - """ Assert that the given command was sent to the backend. The ordering of the parameters is not + """Assert that the given command was sent to the backend. The ordering of the parameters is not taken into account, but the values and formatting should match. The id parameter of the command is ignored. @@ -285,13 +319,14 @@ def _assert_command_in_command_buffer(self, cmd: str, should_be: bool, fmt: str) self.fail(f"Command {cmd} was found in sent commands: {self.mockSTAR.commands}") async def test_indictor_light(self): - """ Test the indicator light. """ - await self.mockSTAR.set_loading_indicators(bit_pattern=[True]*54, blink_pattern=[False]*54) - self._assert_command_sent_once("C0CPid0000cl3FFFFFFFFFFFFFcb00000000000000", - "cl**************cb**************") + """Test the indicator light.""" + await self.mockSTAR.set_loading_indicators(bit_pattern=[True] * 54, blink_pattern=[False] * 54) + self._assert_command_sent_once( + "C0CPid0000cl3FFFFFFFFFFFFFcb00000000000000", "cl**************cb**************" + ) def test_ops_to_fw_positions(self): - """ Convert channel positions to firmware positions. """ + """Convert channel positions to firmware positions.""" # pylint: disable=protected-access tip_a1 = self.tip_rack.get_item("A1") tip_f1 = self.tip_rack.get_item("F1") @@ -301,17 +336,17 @@ def test_ops_to_fw_positions(self): op2 = Pickup(resource=tip_f1, tip=tip, offset=Coordinate.zero()) self.assertEqual( self.mockSTAR._ops_to_fw_positions((op1,), use_channels=[0]), - ([1179, 0], [2418, 0], [True, False]) + ([1179, 0], [2418, 0], [True, False]), ) self.assertEqual( self.mockSTAR._ops_to_fw_positions((op1, op2), use_channels=[0, 1]), - ([1179, 1179, 0], [2418, 1968, 0], [True, True, False]) + ([1179, 1179, 0], [2418, 1968, 0], [True, True, False]), ) self.assertEqual( self.mockSTAR._ops_to_fw_positions((op1, op2), use_channels=[1, 2]), - ([0, 1179, 1179, 0], [0, 2418, 1968, 0], [False, True, True, False]) + ([0, 1179, 1179, 0], [0, 2418, 1968, 0], [False, True, True, False]), ) # check two operations on the same row, different column. @@ -319,7 +354,7 @@ def test_ops_to_fw_positions(self): op3 = Pickup(resource=tip_a2, tip=tip, offset=Coordinate.zero()) self.assertEqual( self.mockSTAR._ops_to_fw_positions((op1, op3), use_channels=[0, 1]), - ([1179, 1269, 0], [2418, 2418, 0], [True, True, False]) + ([1179, 1269, 0], [2418, 2418, 0], [True, True, False]), ) # A1, A2, B1, B2 @@ -329,7 +364,7 @@ def test_ops_to_fw_positions(self): op5 = Pickup(resource=tip_b2, tip=tip, offset=Coordinate.zero()) self.assertEqual( self.mockSTAR._ops_to_fw_positions((op1, op4, op3, op5), use_channels=[0, 1, 2, 3]), - ([1179, 1179, 1269, 1269, 0], [2418, 2328, 2418, 2328, 0], [True, True, True, True, False]) + ([1179, 1179, 1269, 1269, 0], [2418, 2328, 2418, 2328, 0], [True, True, True, True, False]), ) # make sure two operations on the same spot are not allowed @@ -337,7 +372,7 @@ def test_ops_to_fw_positions(self): self.mockSTAR._ops_to_fw_positions((op1, op1), use_channels=[0, 1]) def _assert_command_sent_once(self, cmd: str, fmt: str): - """ Assert that the given command was sent to the backend exactly once. """ + """Assert that the given command was sent to the backend exactly once.""" self._assert_command_in_command_buffer(cmd, True, fmt) self._assert_command_in_command_buffer(cmd, False, fmt) @@ -348,40 +383,50 @@ async def test_tip_pickup_01(self): await self.lh.pick_up_tips(self.tip_rack["A1", "B1"]) self._assert_command_sent_once( "C0TPid0000xp01179 01179 00000&yp2418 2328 0000tm1 1 0&tt01tp2244tz2164th2450td0", - PICKUP_TIP_FORMAT) + PICKUP_TIP_FORMAT, + ) async def test_tip_pickup_56(self): await self.lh.pick_up_tips(self.tip_rack["E1", "F1"], use_channels=[4, 5]) self._assert_command_sent_once( "C0TPid0000xp00000 00000 00000 00000 01179 01179 00000&yp0000 0000 0000 0000 2058 1968 " "0000&tm0 0 0 0 1 1 0 &tt01tp2244tz2164th2450td0", - PICKUP_TIP_FORMAT) + PICKUP_TIP_FORMAT, + ) async def test_tip_pickup_15(self): await self.lh.pick_up_tips(self.tip_rack["A1", "F1"], use_channels=[0, 4]) self._assert_command_sent_once( "C0TPid0000xp01179 00000 00000 00000 01179 00000&yp2418 0000 0000 0000 1968 0000 " "&tm1 0 0 0 1 0&tt01tp2244tz2164th2450td0", - PICKUP_TIP_FORMAT) + PICKUP_TIP_FORMAT, + ) async def test_tip_drop_56(self): - await self.test_tip_pickup_56() # pick up tips first + await self.test_tip_pickup_56() # pick up tips first await self.lh.drop_tips(self.tip_rack["E1", "F1"], use_channels=[4, 5]) self._assert_command_sent_once( "C0TRid0000xp00000 00000 00000 00000 01179 01179 00000&yp0000 0000 0000 0000 2058 1968 " - "0000&tm0 0 0 0 1 1 0&tp2244tz2164th2450ti1", DROP_TIP_FORMAT) + "0000&tm0 0 0 0 1 1 0&tp2244tz2164th2450ti1", + DROP_TIP_FORMAT, + ) async def test_aspirate56(self): self.maxDiff = None - await self.test_tip_pickup_56() # pick up tips first + await self.test_tip_pickup_56() # pick up tips first assert self.plate.lid is not None self.plate.lid.unassign() for well in self.plate.get_items(["A1", "B1"]): - well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction + well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction corrected_vol = self.hlc.compute_corrected_volume(100) - await self.lh.aspirate(self.plate["A1", "B1"], vols=[corrected_vol, corrected_vol], - use_channels=[4, 5], **self.hlc.make_asp_kwargs(2)) - self._assert_command_sent_once("C0ASid0004at0 0 0 0 0 0 0&tm0 0 0 0 1 1 0&xp00000 00000 00000 " + await self.lh.aspirate( + self.plate["A1", "B1"], + vols=[corrected_vol, corrected_vol], + use_channels=[4, 5], + **self.hlc.make_asp_kwargs(2), + ) + self._assert_command_sent_once( + "C0ASid0004at0 0 0 0 0 0 0&tm0 0 0 0 1 1 0&xp00000 00000 00000 " "00000 02983 02983 00000&yp0000 0000 0000 0000 1457 1367 0000&th2450te2450lp2000 2000 2000 " "2000 2000 2000 2000&ch000 000 000 000 000 000 000&zl1866 1866 1866 1866 1866 1866 1866&" "po0100 0100 0100 0100 0100 0100 0100&zu0032 0032 0032 0032 0032 0032 0032&zr06180 06180 " @@ -396,16 +441,18 @@ async def test_aspirate56(self): "ik0000 0000 0000 0000 0000 0000 0000&sd0500 0500 0500 0500 0500 0500 0500&se0500 0500 0500 " "0500 0500 0500 0500&sz0300 0300 0300 0300 0300 0300 0300&io0000 0000 0000 0000 0000 0000 0" "000&il00000 00000 00000 00000 00000 00000 00000&in0000 0000 0000 0000 0000 0000 0000&", - ASPIRATION_COMMAND_FORMAT) + ASPIRATION_COMMAND_FORMAT, + ) async def test_single_channel_aspiration(self): self.lh.update_head_state({0: self.tip_rack.get_tip("A1")}) assert self.plate.lid is not None self.plate.lid.unassign() well = self.plate.get_item("A1") - well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction - await self.lh.aspirate([well], vols=[self.hlc.compute_corrected_volume(100)], - **self.hlc.make_asp_kwargs(1)) + well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction + await self.lh.aspirate( + [well], vols=[self.hlc.compute_corrected_volume(100)], **self.hlc.make_asp_kwargs(1) + ) # This passes the test, but is not the real command. self._assert_command_sent_once( @@ -415,7 +462,8 @@ async def test_single_channel_aspiration(self): "ld00 00&de0020 0020&wt10 10&mv00000 00000&mc00 00&mp000 000&ms1000 1000&mh0000 0000&" "gi000 000&gj0gk0lk0 0&ik0000 0000&sd0500 0500&se0500 0500&sz0300 0300&io0000 0000&" "il00000 00000&in0000 0000&", - fmt=ASPIRATION_COMMAND_FORMAT) + fmt=ASPIRATION_COMMAND_FORMAT, + ) async def test_single_channel_aspiration_liquid_height(self): self.lh.update_head_state({0: self.tip_rack.get_tip("A1")}) @@ -423,9 +471,13 @@ async def test_single_channel_aspiration_liquid_height(self): assert self.plate.lid is not None self.plate.lid.unassign() well = self.plate.get_item("A1") - well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction - await self.lh.aspirate([well], vols=[self.hlc.compute_corrected_volume(100)], - liquid_height=[10], **self.hlc.make_asp_kwargs(1)) + well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction + await self.lh.aspirate( + [well], + vols=[self.hlc.compute_corrected_volume(100)], + liquid_height=[10], + **self.hlc.make_asp_kwargs(1), + ) # This passes the test, but is not the real command. self._assert_command_sent_once( @@ -435,7 +487,8 @@ async def test_single_channel_aspiration_liquid_height(self): "ld00 00&de0020 0020&wt10 10&mv00000 00000&mc00 00&mp000 000&ms1000 1000&mh0000 0000&" "gi000 000&gj0gk0lk0 0&ik0000 0000&sd0500 0500&se0500 0500&sz0300 0300&io0000 0000&" "il00000 00000&in0000 0000&", - fmt=ASPIRATION_COMMAND_FORMAT) + fmt=ASPIRATION_COMMAND_FORMAT, + ) async def test_multi_channel_aspiration(self): self.lh.update_head_state({0: self.tip_rack.get_tip("A1"), 1: self.tip_rack.get_tip("B1")}) @@ -444,10 +497,11 @@ async def test_multi_channel_aspiration(self): self.plate.lid.unassign() wells = self.plate.get_items("A1:B1") for well in wells: - well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction + well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction corrected_vol = self.hlc.compute_corrected_volume(100) - await self.lh.aspirate(self.plate["A1:B1"], vols=[corrected_vol]*2, - **self.hlc.make_asp_kwargs(2)) + await self.lh.aspirate( + self.plate["A1:B1"], vols=[corrected_vol] * 2, **self.hlc.make_asp_kwargs(2) + ) # This passes the test, but is not the real command. self._assert_command_sent_once( @@ -459,14 +513,20 @@ async def test_multi_channel_aspiration(self): "ms1000 1000 1000&mh0000 0000 0000&gi000 000 000&gj0gk0lk0 0 0&ik0000 0000 0000&sd0500 0500 " "0500&se0500 0500 0500&sz0300 0300 0300&io0000 0000 0000&il00000 00000 00000&in0000 0000 " "0000&", - fmt=ASPIRATION_COMMAND_FORMAT) + fmt=ASPIRATION_COMMAND_FORMAT, + ) async def test_aspirate_single_resource(self): self.lh.update_head_state({i: self.tip_rack.get_tip(i) for i in range(5)}) corrected_vol = self.hlc.compute_corrected_volume(10) with no_volume_tracking(): - await self.lh.aspirate([self.bb]*5,vols=[corrected_vol]*5, use_channels=[0,1,2,3,4], - liquid_height=[1]*5, **self.hlc.make_asp_kwargs(5)) + await self.lh.aspirate( + [self.bb] * 5, + vols=[corrected_vol] * 5, + use_channels=[0, 1, 2, 3, 4], + liquid_height=[1] * 5, + **self.hlc.make_asp_kwargs(5), + ) self._assert_command_sent_once( "C0ASid0002at0 0 0 0 0 0&tm1 1 1 1 1 0&xp04865 04865 04865 04865 04865 00000&yp2098 1962 " "1825 1688 1552 0000&th2450te2450lp2000 2000 2000 2000 2000 2000&ch000 000 000 000 000 000&" @@ -481,15 +541,22 @@ async def test_aspirate_single_resource(self): "0 0 0&ik0000 0000 0000 0000 0000 0000&sd0500 0500 0500 0500 0500 0500&se0500 0500 0500 0500 " "0500 0500&sz0300 0300 0300 0300 0300 0300&io0000 0000 0000 0000 0000 0000&il00000 00000 " "00000 00000 00000 00000&in0000 0000 0000 0000 0000 0000&", - fmt=ASPIRATION_COMMAND_FORMAT) + fmt=ASPIRATION_COMMAND_FORMAT, + ) async def test_dispense_single_resource(self): self.lh.update_head_state({i: self.tip_rack.get_tip(i) for i in range(5)}) hlc = StandardVolumeFilter_Water_DispenseJet_Empty corrected_vol = hlc.compute_corrected_volume(10) with no_volume_tracking(): - await self.lh.dispense([self.bb]*5, vols=[corrected_vol]*5, liquid_height=[1]*5, - jet=[True]*5, blow_out=[True]*5, **hlc.make_disp_kwargs(5)) + await self.lh.dispense( + [self.bb] * 5, + vols=[corrected_vol] * 5, + liquid_height=[1] * 5, + jet=[True] * 5, + blow_out=[True] * 5, + **hlc.make_disp_kwargs(5), + ) self._assert_command_sent_once( "C0DSid0002dm1 1 1 1 1 1&tm1 1 1 1 1 0&xp04865 04865 04865 04865 04865 00000&yp2098 1962 " "1825 1688 1552 0000&zx1200 1200 1200 1200 1200 1200&lp2000 2000 2000 2000 2000 2000&zl1210 " @@ -501,7 +568,8 @@ async def test_dispense_single_resource(self): "1 1 1&lv1 1 1 1 1 1&de0010 0010 0010 0010 0010 0010&wt00 00 00 00 00 00&mv00000 00000 00000 " "00000 00000 00000&mc00 00 00 00 00 00&mp000 000 000 000 000 000&ms0010 0010 0010 0010 0010 " "0010&mh0000 0000 0000 0000 0000 0000&gi000 000 000 000 000 000&gj0gk0", - fmt=DISPENSE_RESPONSE_FORMAT) + fmt=DISPENSE_RESPONSE_FORMAT, + ) async def test_single_channel_dispense(self): self.lh.update_head_state({0: self.tip_rack.get_tip("A1")}) @@ -510,15 +578,21 @@ async def test_single_channel_dispense(self): hlc = StandardVolumeFilter_Water_DispenseJet_Empty corrected_vol = hlc.compute_corrected_volume(100) with no_volume_tracking(): - await self.lh.dispense(self.plate["A1"], vols=[corrected_vol], jet=[True], blow_out=[True], - **hlc.make_disp_kwargs(1)) + await self.lh.dispense( + self.plate["A1"], + vols=[corrected_vol], + jet=[True], + blow_out=[True], + **hlc.make_disp_kwargs(1), + ) self._assert_command_sent_once( "C0DSid0002dm1 1&tm1 0&xp02983 00000&yp1457 0000&zx1866 1866&lp2000 2000&zl1866 1866&" "po0100 0100&ip0000 0000&it0 0&fp0000 0000&zu0032 0032&zr06180 06180&th2450te2450" "dv01072 01072&ds1800 1800&ss0050 0050&rv000 000&ta050 050&ba0300 03000&lm0 0&" "dj00zo000 000&ll1 1&lv1 1&de0010 0010&wt00 00&mv00000 00000&mc00 00&mp000 000&" "ms0010 0010&mh0000 0000&gi000 000&gj0gk0", - fmt=DISPENSE_RESPONSE_FORMAT) + fmt=DISPENSE_RESPONSE_FORMAT, + ) async def test_multi_channel_dispense(self): self.lh.update_head_state({0: self.tip_rack.get_tip("A1"), 1: self.tip_rack.get_tip("B1")}) @@ -528,8 +602,13 @@ async def test_multi_channel_dispense(self): hlc = StandardVolumeFilter_Water_DispenseJet_Empty corrected_vol = hlc.compute_corrected_volume(100) with no_volume_tracking(): - await self.lh.dispense(self.plate["A1:B1"], vols=[corrected_vol]*2, jet=[True]*2, - blow_out=[True]*2, **hlc.make_disp_kwargs(2)) + await self.lh.dispense( + self.plate["A1:B1"], + vols=[corrected_vol] * 2, + jet=[True] * 2, + blow_out=[True] * 2, + **hlc.make_disp_kwargs(2), + ) self._assert_command_sent_once( "C0DSid0002dm1 1 1&tm1 1 0&xp02983 02983 00000&yp1457 1367 0000&zx1866 1866 1866&lp2000 2000 " @@ -538,7 +617,8 @@ async def test_multi_channel_dispense(self): "ss0050 0050 0050&rv000 000 000&ta050 050 050&ba0300 0300 0300&lm0 0 0&dj00zo000 000 000&" "ll1 1 1&lv1 1 1&de0010 0010 0010&wt00 00 00&mv00000 00000 00000&mc00 00 00&mp000 000 000&" "ms0010 0010 0010&mh0000 0000 0000&gi000 000 000&gj0gk0", - fmt=DISPENSE_RESPONSE_FORMAT) + fmt=DISPENSE_RESPONSE_FORMAT, + ) async def test_zero_volume_liquid_handling(self): # just test that this does not throw an error @@ -553,26 +633,27 @@ async def test_core_96_tip_pickup(self): self._assert_command_sent_once( "C0EPid0208xs01179xd0yh2418tt01wu0za2164zh2450ze2450", - "xs#####xd#yh####tt##wu#za####zh####ze####") + "xs#####xd#yh####tt##wu#za####zh####ze####", + ) async def test_core_96_tip_drop(self): - await self.lh.pick_up_tips96(self.tip_rack) # pick up tips first + await self.lh.pick_up_tips96(self.tip_rack) # pick up tips first await self.lh.drop_tips96(self.tip_rack) self._assert_command_sent_once( - "C0ERid0213xs01179xd0yh2418za2164zh2450ze2450", - "xs#####xd#yh####za####zh####ze####") + "C0ERid0213xs01179xd0yh2418za2164zh2450ze2450", "xs#####xd#yh####za####zh####ze####" + ) async def test_core_96_tip_discard(self): - await self.lh.pick_up_tips96(self.tip_rack) # pick up tips first + await self.lh.pick_up_tips96(self.tip_rack) # pick up tips first await self.lh.discard_tips96() self._assert_command_sent_once( - "C0ERid0213xs02321xd1yh1103za2164zh2450ze2450", - "xs#####xd#yh####za####zh####ze####") + "C0ERid0213xs02321xd1yh1103za2164zh2450ze2450", "xs#####xd#yh####za####zh####ze####" + ) async def test_core_96_aspirate(self): - await self.lh.pick_up_tips96(self.tip_rack2) # pick up high volume tips + await self.lh.pick_up_tips96(self.tip_rack2) # pick up high volume tips # TODO: Hamilton liquid classes assert self.plate.lid is not None @@ -588,10 +669,11 @@ async def test_core_96_aspirate(self): "cwFFFFFFFFFFFFFFFFFFFFFFFFpp0100", "xs#####xd#yh####zh####ze####lz####zt####zm####iw###ix#fh###af#####ag####vt###" "bv#####wv#####cm#cs#bs####wh##hv#####hc##hp###hs####zv####zq#####mj###cj#cx#cr###" - "cw************************pp####") + "cw************************pp####", + ) async def test_core_96_dispense(self): - await self.lh.pick_up_tips96(self.tip_rack2) # pick up high volume tips + await self.lh.pick_up_tips96(self.tip_rack2) # pick up high volume tips if self.plate.lid is not None: self.plate.lid.unassign() hlc = HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty @@ -599,8 +681,9 @@ async def test_core_96_dispense(self): await self.lh.aspirate96(self.plate, corrected_volume, **hlc.make_asp96_kwargs()) with no_volume_tracking(): - await self.lh.dispense96(self.plate, corrected_volume, blow_out=True, - **hlc.make_disp96_kwargs()) + await self.lh.dispense96( + self.plate, corrected_volume, blow_out=True, **hlc.make_disp96_kwargs() + ) self._assert_command_sent_once( "C0EDid0001da3xs02983xd0yh1457zh2450ze2450lz1999zt1866zm1866iw000ix0fh000df01083dg1200vt050" @@ -608,7 +691,8 @@ async def test_core_96_dispense(self): "cwFFFFFFFFFFFFFFFFFFFFFFFFpp0100", "da#xs#####xd#yh##6#zh####ze####lz####zt####zm##6#iw###ix#fh###df#####dg####vt###" "bv#####cm#cs#bs####wh##hv#####hc##hp###hs####es####ev###zv####ej##zq#6###mj###cj#cx#cr###" - "cw************************pp####") + "cw************************pp####", + ) async def test_zero_volume_liquid_handling96(self): # just test that this does not throw an error @@ -619,22 +703,31 @@ async def test_zero_volume_liquid_handling96(self): await self.lh.dispense96(self.plate, 0) async def test_iswap(self): - await self.lh.move_plate(self.plate, self.plt_car[2], pickup_distance_from_top=13.2-3.33) + await self.lh.move_plate(self.plate, self.plt_car[2], pickup_distance_from_top=13.2 - 3.33) self._assert_command_sent_once( "C0PPid0011xs03479xd0yj1142yd0zj1874zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", - "xs#####xd#yj####yd#zj####zd#gr#th####te####gw#go####gb####gt##ga#gc#") + "xs#####xd#yj####yd#zj####zd#gr#th####te####gw#go####gb####gt##ga#gc#", + ) self._assert_command_sent_once( "C0PRid0012xs03479xd0yj3062yd0zj1874zd0th2450te2450gr1go1308ga0", - "xs#####xd#yj####yd#zj####zd#th####te####go####ga#") + "xs#####xd#yj####yd#zj####zd#th####te####go####ga#", + ) async def test_iswap_plate_reader(self): - plate_reader = PlateReader(name="plate_reader", backend=MockPlateReaderBackend(), - size_x=0, size_y=0, size_z=0) - self.lh.deck.assign_child_resource(plate_reader, - location=Coordinate(1000, 264.7, 200-3.03)) # 666: 00002 - - await self.lh.move_plate(self.plate, plate_reader, pickup_distance_from_top=8.2-3.33, - get_direction=GripDirection.FRONT, put_direction=GripDirection.LEFT) + plate_reader = PlateReader( + name="plate_reader", backend=MockPlateReaderBackend(), size_x=0, size_y=0, size_z=0 + ) + self.lh.deck.assign_child_resource( + plate_reader, location=Coordinate(1000, 264.7, 200 - 3.03) + ) # 666: 00002 + + await self.lh.move_plate( + self.plate, + plate_reader, + pickup_distance_from_top=8.2 - 3.33, + get_direction=GripDirection.FRONT, + put_direction=GripDirection.LEFT, + ) plate_origin_location = { "xs": "03479", "xd": "0", @@ -656,89 +749,107 @@ async def test_iswap_plate_reader(self): f"yj{plate_origin_location['yj']}yd{plate_origin_location['yd']}" f"zj{plate_origin_location['zj']}zd{plate_origin_location['zd']}" f"th2450te2450gw4gb1245go1308gt20gr1ga0gc1", - "xs#####xd#yj####yd#zj####zd#th####te####gw#gb####go####gt##gr#ga#gc#") + "xs#####xd#yj####yd#zj####zd#th####te####gw#gb####go####gt##gr#ga#gc#", + ) self._assert_command_sent_once( f"C0PRid0004xs{plate_reader_location['xs']}xd{plate_reader_location['xd']}" f"yj{plate_reader_location['yj']}yd{plate_reader_location['yd']}" f"zj{plate_reader_location['zj']}zd{plate_reader_location['zd']}" f"th2450te2450go1308gr4ga0", - "xs#####xd#yj####yd#zj####zd#th####te####go####gr#ga#") + "xs#####xd#yj####yd#zj####zd#th####te####go####gr#ga#", + ) assert self.plate.rotation.z == 270 self.assertAlmostEqual(self.plate.get_absolute_size_x(), 85.48, places=2) self.assertAlmostEqual(self.plate.get_absolute_size_y(), 127.76, places=2) - await self.lh.move_plate(plate_reader.get_plate(), self.plt_car[0], - pickup_distance_from_top=8.2-3.33, get_direction=GripDirection.LEFT, - put_direction=GripDirection.FRONT) + await self.lh.move_plate( + plate_reader.get_plate(), + self.plt_car[0], + pickup_distance_from_top=8.2 - 3.33, + get_direction=GripDirection.LEFT, + put_direction=GripDirection.FRONT, + ) self._assert_command_sent_once( f"C0PPid0005xs{plate_reader_location['xs']}xd{plate_reader_location['xd']}" f"yj{plate_reader_location['yj']}yd{plate_reader_location['yd']}" f"zj{plate_reader_location['zj']}zd{plate_reader_location['zd']}" f"gr4th2450te2450gw4go1308gb1245gt20ga0gc1", - "xs#####xd#yj####yd#zj####zd#gr#th####te####gw#go####gb####gt##ga#gc#") + "xs#####xd#yj####yd#zj####zd#gr#th####te####gw#go####gb####gt##ga#gc#", + ) self._assert_command_sent_once( f"C0PRid0006xs{plate_origin_location['xs']}xd{plate_origin_location['xd']}" f"yj{plate_origin_location['yj']}yd{plate_origin_location['yd']}" f"zj{plate_origin_location['zj']}zd{plate_origin_location['zd']}" f"th2450te2450gr1go1308ga0", - "xs#####xd#yj####yd#zj####zd#th####te####gr#go####ga#") + "xs#####xd#yj####yd#zj####zd#th####te####gr#go####ga#", + ) async def test_iswap_move_lid(self): assert self.plate.lid is not None and self.other_plate.lid is not None - self.other_plate.lid.unassign() # remove lid from plate + self.other_plate.lid.unassign() # remove lid from plate await self.lh.move_lid(self.plate.lid, self.other_plate) self._assert_command_sent_once( "C0PPid0002xs03479xd0yj1142yd0zj1950zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", - GET_PLATE_FMT) - self._assert_command_sent_once( # zj sent = 1849 - "C0PRid0003xs03479xd0yj2102yd0zj1950zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT) + GET_PLATE_FMT, + ) + self._assert_command_sent_once( # zj sent = 1849 + "C0PRid0003xs03479xd0yj2102yd0zj1950zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT + ) async def test_iswap_stacking_area(self): stacking_area = ResourceStack("stacking_area", direction="z") # for some reason it was like this at some point # self.lh.assign_resource(hotel, location=Coordinate(6, 414-63, 217.2 - 100)) # self.lh.deck.assign_child_resource(hotel, location=Coordinate(6, 414-63, 231.7 - 100 +4.5)) - self.lh.deck.assign_child_resource(stacking_area, location=Coordinate(6, 414, 226.2-3.33)) + self.lh.deck.assign_child_resource(stacking_area, location=Coordinate(6, 414, 226.2 - 3.33)) assert self.plate.lid is not None await self.lh.move_lid(self.plate.lid, stacking_area) self._assert_command_sent_once( "C0PPid0002xs03479xd0yj1142yd0zj1950zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", - GET_PLATE_FMT) + GET_PLATE_FMT, + ) self._assert_command_sent_once( - "C0PRid0003xs00699xd0yj4567yd0zj2305zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT) + "C0PRid0003xs00699xd0yj4567yd0zj2305zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT + ) # Move lids back (reverse order) await self.lh.move_lid(cast(Lid, stacking_area.get_top_item()), self.plate) self._assert_command_sent_once( "C0PPid0004xs00699xd0yj4567yd0zj2305zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", - GET_PLATE_FMT) + GET_PLATE_FMT, + ) self._assert_command_sent_once( - "C0PRid0005xs03479xd0yj1142yd0zj1950zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT) + "C0PRid0005xs03479xd0yj1142yd0zj1950zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT + ) async def test_iswap_stacking_area_2lids(self): # for some reason it was like this at some point # self.lh.assign_resource(hotel, location=Coordinate(6, 414-63, 217.2 - 100)) stacking_area = ResourceStack("stacking_area", direction="z") - self.lh.deck.assign_child_resource(stacking_area, location=Coordinate(6, 414, 226.2-3.33)) + self.lh.deck.assign_child_resource(stacking_area, location=Coordinate(6, 414, 226.2 - 3.33)) assert self.plate.lid is not None and self.other_plate.lid is not None await self.lh.move_lid(self.plate.lid, stacking_area) self._assert_command_sent_once( "C0PPid0002xs03479xd0yj1142yd0zj1950zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", - GET_PLATE_FMT) + GET_PLATE_FMT, + ) self._assert_command_sent_once( - "C0PRid0003xs00699xd0yj4567yd0zj2305zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT) + "C0PRid0003xs00699xd0yj4567yd0zj2305zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT + ) await self.lh.move_lid(self.other_plate.lid, stacking_area) self._assert_command_sent_once( "C0PPid0004xs03479xd0yj2102yd0zj1950zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", - GET_PLATE_FMT) + GET_PLATE_FMT, + ) self._assert_command_sent_once( - "C0PRid0005xs00699xd0yj4567yd0zj2405zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT) + "C0PRid0005xs00699xd0yj4567yd0zj2405zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT + ) # Move lids back (reverse order) top_item = stacking_area.get_top_item() @@ -746,43 +857,55 @@ async def test_iswap_stacking_area_2lids(self): await self.lh.move_lid(top_item, self.plate) self._assert_command_sent_once( "C0PPid0004xs00699xd0yj4567yd0zj2405zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", - GET_PLATE_FMT) + GET_PLATE_FMT, + ) self._assert_command_sent_once( - "C0PRid0005xs03479xd0yj1142yd0zj1950zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT) + "C0PRid0005xs03479xd0yj1142yd0zj1950zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT + ) top_item = stacking_area.get_top_item() assert isinstance(top_item, Lid) await self.lh.move_lid(top_item, self.other_plate) self._assert_command_sent_once( "C0PPid0004xs00699xd0yj4567yd0zj2305zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", - GET_PLATE_FMT) + GET_PLATE_FMT, + ) self._assert_command_sent_once( - "C0PRid0005xs03479xd0yj2102yd0zj1950zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT) + "C0PRid0005xs03479xd0yj2102yd0zj1950zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT + ) async def test_iswap_move_with_intermediate_locations(self): - await self.lh.move_plate(self.plate, self.plt_car[1], intermediate_locations=[ - self.plt_car[2].get_absolute_location() + Coordinate(50, 0, 50), - self.plt_car[3].get_absolute_location() + Coordinate(-50, 0, 50), - ]) + await self.lh.move_plate( + self.plate, + self.plt_car[1], + intermediate_locations=[ + self.plt_car[2].get_absolute_location() + Coordinate(50, 0, 50), + self.plt_car[3].get_absolute_location() + Coordinate(-50, 0, 50), + ], + ) self._assert_command_sent_once( "C0PPid0023xs03479xd0yj1142yd0zj1874zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", - GET_PLATE_FMT) + GET_PLATE_FMT, + ) self._assert_command_sent_once( - "C0PMid0024xs02979xd0yj4022yd0zj2432zd0gr1th2450ga1xe4 1", INTERMEDIATE_FMT) + "C0PMid0024xs02979xd0yj4022yd0zj2432zd0gr1th2450ga1xe4 1", INTERMEDIATE_FMT + ) self._assert_command_sent_once( - "C0PMid0025xs03979xd0yj3062yd0zj2432zd0gr1th2450ga1xe4 1", INTERMEDIATE_FMT) + "C0PMid0025xs03979xd0yj3062yd0zj2432zd0gr1th2450ga1xe4 1", INTERMEDIATE_FMT + ) self._assert_command_sent_once( - "C0PRid0026xs03479xd0yj2102yd0zj1874zd0th2450te2450gr1go1308ga0", - PUT_PLATE_FMT) + "C0PRid0026xs03479xd0yj2102yd0zj1874zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT + ) async def test_discard_tips(self): await self.lh.pick_up_tips(self.tip_rack["A1:H1"]) await self.lh.discard_tips() self._assert_command_sent_once( - "C0TRid0206xp08000 08000 08000 08000 08000 08000 08000 08000yp4050 3782 3514 3246 2978 2710 " - "2442 2174tp1970tz1870th2450te2450tm1 1 1 1 1 1 1 1ti0", - DROP_TIP_FORMAT) + "C0TRid0206xp08000 08000 08000 08000 08000 08000 08000 08000yp4050 3782 3514 3246 2978 2710 " + "2442 2174tp1970tz1870th2450te2450tm1 1 1 1 1 1 1 1ti0", + DROP_TIP_FORMAT, + ) async def test_portrait_tip_rack_handling(self): # Test with an alternative setup. @@ -799,16 +922,18 @@ async def test_portrait_tip_rack_handling(self): await lh.pick_up_tips(tr["A4:A1"]) self._assert_command_sent_once( - "C0TPid0035xp01360 01360 01360 01360 00000&yp1380 1290 1200 1110 0000&tm1 1 1 1 0&tt01tp2263tz" - "2163th2450td0", - PICKUP_TIP_FORMAT) + "C0TPid0035xp01360 01360 01360 01360 00000&yp1380 1290 1200 1110 0000&tm1 1 1 1 0&tt01tp2263tz" + "2163th2450td0", + PICKUP_TIP_FORMAT, + ) await lh.drop_tips(tr["A4:A1"]) self._assert_command_sent_once( - "C0TRid0036xp01360 01360 01360 01360 00000&yp1380 1290 1200 1110 0000&tm1 1 1 1 0&tp2263tz" - "2183th2450ti1", - DROP_TIP_FORMAT) + "C0TRid0036xp01360 01360 01360 01360 00000&yp1380 1290 1200 1110 0000&tm1 1 1 1 0&tp2263tz" + "2183th2450ti1", + DROP_TIP_FORMAT, + ) def test_serialize(self): serialized = LiquidHandler(backend=STAR(), deck=STARLetDeck()).serialize() @@ -817,17 +942,25 @@ def test_serialize(self): self.assertEqual(deserialized.backend.__class__.__name__, "STAR") async def test_move_core(self): - await self.lh.move_plate(self.plate, self.plt_car[1], pickup_distance_from_top=13-3.33, - use_arm="core") - self._assert_command_sent_once("C0ZTid0020xs07975xd0ya1240yb1065pa07pb08tp2350tz2250th2450tt14", - "xs#####xd#ya####yb####pa##pb##tp####tz####th####tt##") - self._assert_command_sent_once("C0ZPid0021xs03479xd0yj1142yv0050zj1876zy0500yo0885yg0825yw15" - "th2450te2450", - "xs#####xd#yj####yv####zj####zy####yo####yg####yw##th####te####") - self._assert_command_sent_once("C0ZRid0022xs03479xd0yj2102zj1876zi000zy0500yo0885th2450te2450", - "xs#####xd#yj####zj####zi###zy####yo####th####te####") - self._assert_command_sent_once("C0ZSid0023xs07975xd0ya1240yb1065tp2150tz2050th2450te2450", - "xs#####xd#ya####yb####tp####tz####th####te####") + await self.lh.move_plate( + self.plate, self.plt_car[1], pickup_distance_from_top=13 - 3.33, use_arm="core" + ) + self._assert_command_sent_once( + "C0ZTid0020xs07975xd0ya1240yb1065pa07pb08tp2350tz2250th2450tt14", + "xs#####xd#ya####yb####pa##pb##tp####tz####th####tt##", + ) + self._assert_command_sent_once( + "C0ZPid0021xs03479xd0yj1142yv0050zj1876zy0500yo0885yg0825yw15" "th2450te2450", + "xs#####xd#yj####yv####zj####zy####yo####yg####yw##th####te####", + ) + self._assert_command_sent_once( + "C0ZRid0022xs03479xd0yj2102zj1876zi000zy0500yo0885th2450te2450", + "xs#####xd#yj####zj####zi###zy####yo####th####te####", + ) + self._assert_command_sent_once( + "C0ZSid0023xs07975xd0ya1240yb1065tp2150tz2050th2450te2450", + "xs#####xd#ya####yb####tp####tz####th####te####", + ) async def test_iswap_pick_up_resource_grip_direction_changes_plate_width(self): size_x = 100 diff --git a/pylabrobot/liquid_handling/backends/hamilton/vantage.py b/pylabrobot/liquid_handling/backends/hamilton/vantage.py index 2f5cfad047..4b0cf7127a 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/vantage.py +++ b/pylabrobot/liquid_handling/backends/hamilton/vantage.py @@ -9,22 +9,21 @@ from pylabrobot.liquid_handling.backends.hamilton.base import HamiltonLiquidHandler from pylabrobot.liquid_handling.liquid_classes.hamilton import HamiltonLiquidClass from pylabrobot.liquid_handling.standard import ( - Pickup, - PickupTipRack, - Drop, - DropTipRack, Aspiration, - AspirationPlate, AspirationContainer, + AspirationPlate, Dispense, - DispensePlate, DispenseContainer, - Move + DispensePlate, + Drop, + DropTipRack, + Move, + Pickup, + PickupTipRack, ) from pylabrobot.resources import Coordinate, Resource, TipRack, Well from pylabrobot.resources.ml_star import HamiltonTip, TipPickupMethod, TipSize - if sys.version_info >= (3, 8): from typing import Literal else: @@ -32,7 +31,7 @@ def parse_vantage_fw_string(s: str, fmt: Optional[Dict[str, str]] = None) -> dict: - """ Parse a Vantage firmware string into a dict. + """Parse a Vantage firmware string into a dict. The identifier parameter (id) is added automatically. @@ -65,22 +64,22 @@ def parse_vantage_fw_string(s: str, fmt: Optional[Dict[str, str]] = None) -> dic for key, data_type in fmt.items(): if data_type == "int": - matches = re.findall(fr"{key}([-+]?\d+)", s) + matches = re.findall(rf"{key}([-+]?\d+)", s) if len(matches) != 1: raise ValueError(f"Expected exactly one match for {key} in {s}") parsed[key] = int(matches[0]) elif data_type == "str": - matches = re.findall(fr"{key}\"(.*)\"", s) + matches = re.findall(rf"{key}\"(.*)\"", s) if len(matches) != 1: raise ValueError(f"Expected exactly one match for {key} in {s}") parsed[key] = matches[0] elif data_type == "[int]": - matches = re.findall(fr"{key}((?:[-+]?[\d ]+)+)", s) + matches = re.findall(rf"{key}((?:[-+]?[\d ]+)+)", s) if len(matches) != 1: raise ValueError(f"Expected exactly one match for {key} in {s}") parsed[key] = [int(x) for x in matches[0].split()] elif data_type == "hex": - matches = re.findall(fr"{key}([0-9a-fA-F]+)", s) + matches = re.findall(rf"{key}([0-9a-fA-F]+)", s) if len(matches) != 1: raise ValueError(f"Expected exactly one match for {key} in {s}") parsed[key] = int(matches[0], 16) @@ -89,6 +88,7 @@ def parse_vantage_fw_string(s: str, fmt: Optional[Dict[str, str]] = None) -> dic return parsed + core96_errors = { 0: "No error", 21: "No communication to digital potentiometer", @@ -141,112 +141,112 @@ def parse_vantage_fw_string(s: str, fmt: Optional[Dict[str, str]] = None) -> dic } pip_errors = { - 22: "Drive controller message error", - 23: "EC drive controller setup not executed", - 25: "wrong Flash EPROM data", - 26: "Flash EPROM not programmable", - 27: "Flash EPROM not erasable", - 28: "Flash EPROM checksum error", - 29: "wrong FW loaded", - 30: "Undefined command", - 31: "Undefined parameter", - 32: "Parameter out of range", - 35: "Voltages out of range", - 36: "Stop during command execution", - 37: "Adjustment sensor didn't switch (no teach in signal)", - 38: "Movement interrupted by partner channel", - 39: "Angle alignment offset error", - 40: "No parallel processes on level 1 permitted", - 41: "No parallel processes on level 2 permitted", - 42: "No parallel processes on level 3 permitted", - 50: "D drive initialization failed", - 51: "D drive not initialized", - 52: "D drive movement error", - 53: "Maximum volume in tip reached", - 54: "D drive position out of permitted area", - 55: "Y drive initialization failed", - 56: "Y drive not initialized", - 57: "Y drive movement error", - 58: "Y drive position out of permitted area", - 59: "Divergance Y motion controller to linear encoder to heigh", - 60: "Z drive initialization failed", - 61: "Z drive not initialized", - 62: "Z drive movement error", - 63: "Z drive position out of permitted area", - 64: "Limit stop not found", - 65: "S drive initialization failed", - 66: "S drive not initialized", - 67: "S drive movement error", - 68: "S drive position out of permitted area", - 69: "Init. position adjustment error", - 70: "No liquid level found", - 71: "Not enough liquid present", - 74: "Liquid at a not allowed position detected", - 75: "No tip picked up", - 76: "Tip already picked up", - 77: "Tip not discarded", - 78: "Wrong tip detected", - 79: "Tip not correct squeezed", - 80: "Liquid not correctly aspirated", - 81: "Clot detected", - 82: "TADM measurement out of lower limit curve", - 83: "TADM measurement out of upper limit curve", - 84: "Not enough memory for TADM measurement", - 85: "Jet dispense pressure not reached", - 86: "ADC algorithm error", - 90: "Limit curve not resetable", - 91: "Limit curve not programmable", - 92: "Limit curve name not found", - 93: "Limit curve data incorrect", - 94: "Not enough memory for limit curve", - 95: "Not allowed limit curve index", - 96: "Limit curve already stored", + 22: "Drive controller message error", + 23: "EC drive controller setup not executed", + 25: "wrong Flash EPROM data", + 26: "Flash EPROM not programmable", + 27: "Flash EPROM not erasable", + 28: "Flash EPROM checksum error", + 29: "wrong FW loaded", + 30: "Undefined command", + 31: "Undefined parameter", + 32: "Parameter out of range", + 35: "Voltages out of range", + 36: "Stop during command execution", + 37: "Adjustment sensor didn't switch (no teach in signal)", + 38: "Movement interrupted by partner channel", + 39: "Angle alignment offset error", + 40: "No parallel processes on level 1 permitted", + 41: "No parallel processes on level 2 permitted", + 42: "No parallel processes on level 3 permitted", + 50: "D drive initialization failed", + 51: "D drive not initialized", + 52: "D drive movement error", + 53: "Maximum volume in tip reached", + 54: "D drive position out of permitted area", + 55: "Y drive initialization failed", + 56: "Y drive not initialized", + 57: "Y drive movement error", + 58: "Y drive position out of permitted area", + 59: "Divergance Y motion controller to linear encoder to heigh", + 60: "Z drive initialization failed", + 61: "Z drive not initialized", + 62: "Z drive movement error", + 63: "Z drive position out of permitted area", + 64: "Limit stop not found", + 65: "S drive initialization failed", + 66: "S drive not initialized", + 67: "S drive movement error", + 68: "S drive position out of permitted area", + 69: "Init. position adjustment error", + 70: "No liquid level found", + 71: "Not enough liquid present", + 74: "Liquid at a not allowed position detected", + 75: "No tip picked up", + 76: "Tip already picked up", + 77: "Tip not discarded", + 78: "Wrong tip detected", + 79: "Tip not correct squeezed", + 80: "Liquid not correctly aspirated", + 81: "Clot detected", + 82: "TADM measurement out of lower limit curve", + 83: "TADM measurement out of upper limit curve", + 84: "Not enough memory for TADM measurement", + 85: "Jet dispense pressure not reached", + 86: "ADC algorithm error", + 90: "Limit curve not resetable", + 91: "Limit curve not programmable", + 92: "Limit curve name not found", + 93: "Limit curve data incorrect", + 94: "Not enough memory for limit curve", + 95: "Not allowed limit curve index", + 96: "Limit curve already stored", } ipg_errors = { 0: "No error", - 22: "Drive controller message error", - 23: "EC drive controller setup not executed", - 25: "Wrong Flash EPROM data", - 26: "Flash EPROM not programmable", - 27: "Flash EPROM not erasable", - 28: "Flash EPROM checksum error", - 29: "Wrong FW loaded", - 30: "Undefined command", - 31: "Undefined parameter", - 32: "Parameter out of range", - 35: "Voltages out of range", - 36: "Stop during command execution", - 37: "Adjustment sensor didn't switch (no teach in signal)", - 39: "Angle alignment offset error", - 40: "No parallel processes on level 1 permitted", - 41: "No parallel processes on level 2 permitted", - 42: "No parallel processes on level 3 permitted", - 50: "Y Drive initialization failed", - 51: "Y Drive not initialized", - 52: "Y Drive movement error", - 53: "Y Drive position out of permitted area", - 54: "Diff. motion controller and lin. encoder counter too high", - 55: "Z Drive initialization failed", - 56: "Z Drive not initialized", - 57: "Z Drive movement error", - 58: "Z Drive position out of permitted area", - 59: "Z Drive limit stop not found", - 60: "Rotation Drive initialization failed", - 61: "Rotation Drive not initialized", - 62: "Rotation Drive movement error", - 63: "Rotation Drive position out of permitted area", - 65: "Wrist Twist Drive initialization failed", - 66: "Wrist Twist Drive not initialized", - 67: "Wrist Twist Drive movement error", - 68: "Wrist Twist Drive position out of permitted area", - 70: "Gripper Drive initialization failed", - 71: "Gripper Drive not initialized", - 72: "Gripper Drive movement error", - 73: "Gripper Drive position out of permitted area", - 80: "Plate not found", - 81: "Plate is still held", - 82: "No plate is held", + 22: "Drive controller message error", + 23: "EC drive controller setup not executed", + 25: "Wrong Flash EPROM data", + 26: "Flash EPROM not programmable", + 27: "Flash EPROM not erasable", + 28: "Flash EPROM checksum error", + 29: "Wrong FW loaded", + 30: "Undefined command", + 31: "Undefined parameter", + 32: "Parameter out of range", + 35: "Voltages out of range", + 36: "Stop during command execution", + 37: "Adjustment sensor didn't switch (no teach in signal)", + 39: "Angle alignment offset error", + 40: "No parallel processes on level 1 permitted", + 41: "No parallel processes on level 2 permitted", + 42: "No parallel processes on level 3 permitted", + 50: "Y Drive initialization failed", + 51: "Y Drive not initialized", + 52: "Y Drive movement error", + 53: "Y Drive position out of permitted area", + 54: "Diff. motion controller and lin. encoder counter too high", + 55: "Z Drive initialization failed", + 56: "Z Drive not initialized", + 57: "Z Drive movement error", + 58: "Z Drive position out of permitted area", + 59: "Z Drive limit stop not found", + 60: "Rotation Drive initialization failed", + 61: "Rotation Drive not initialized", + 62: "Rotation Drive movement error", + 63: "Rotation Drive position out of permitted area", + 65: "Wrist Twist Drive initialization failed", + 66: "Wrist Twist Drive not initialized", + 67: "Wrist Twist Drive movement error", + 68: "Wrist Twist Drive position out of permitted area", + 70: "Gripper Drive initialization failed", + 71: "Gripper Drive not initialized", + 72: "Gripper Drive movement error", + 73: "Gripper Drive position out of permitted area", + 80: "Plate not found", + 81: "Plate is still held", + 82: "No plate is held", } @@ -259,14 +259,16 @@ def __str__(self): return f"VantageFirmwareError(errors={self.errors}, raw_response={self.raw_response})" def __eq__(self, __value: object) -> bool: - return isinstance(__value, VantageFirmwareError) and \ - self.errors == __value.errors and \ - self.raw_response == __value.raw_response + return ( + isinstance(__value, VantageFirmwareError) + and self.errors == __value.errors + and self.raw_response == __value.raw_response + ) def vantage_response_string_to_error(string: str) -> VantageFirmwareError: - """ Convert a Vantage firmware response string to a VantageFirmwareError. Assumes that the - response is an error response. """ + """Convert a Vantage firmware response string to a VantageFirmwareError. Assumes that the + response is an error response.""" try: error_format = r"[A-Z0-9]{2}[0-9]{2}" @@ -295,15 +297,16 @@ def vantage_response_string_to_error(string: str) -> VantageFirmwareError: "A1HM": "Core 96", "A1RM": "IPG", "A1AM": "Arm", - "A1XM": "X-arm" + "A1XM": "X-arm", }.get(module_id, "Unknown module") error_string = parse_vantage_fw_string(string, {"et": "str"})["et"] errors = {modules: error_string} return VantageFirmwareError(errors, string) + def _get_dispense_mode(jet: bool, empty: bool, blow_out: bool) -> Literal[0, 1, 2, 3, 4]: - """ from docs: + """from docs: 0 = part in jet 1 = blow in jet (called "empty" in VENUS liquid editor) 2 = Part at surface @@ -320,7 +323,7 @@ def _get_dispense_mode(jet: bool, empty: bool, blow_out: bool) -> Literal[0, 1, class Vantage(HamiltonLiquidHandler): - """ A Hamilton Vantage liquid handler. """ + """A Hamilton Vantage liquid handler.""" def __init__( self, @@ -330,7 +333,7 @@ def __init__( read_timeout: int = 60, write_timeout: int = 30, ): - """ Create a new STAR interface. + """Create a new STAR interface. Args: device_address: the USB device address of the Hamilton Vantage. Only useful if using more than @@ -348,7 +351,8 @@ def __init__( read_timeout=read_timeout, write_timeout=write_timeout, id_product=0x8003, - serial_number=serial_number) + serial_number=serial_number, + ) self._iswap_parked: Optional[bool] = None self._num_channels: Optional[int] = None @@ -356,28 +360,28 @@ def __init__( @property def module_id_length(self) -> int: - return 4 + return 4 def get_id_from_fw_response(self, resp: str) -> Optional[int]: - """ Get the id from a firmware response. """ + """Get the id from a firmware response.""" parsed = parse_vantage_fw_string(resp, {"id": "int"}) if "id" in parsed and parsed["id"] is not None: return int(parsed["id"]) return None def check_fw_string_error(self, resp: str): - """ Raise an error if the firmware response is an error response. """ + """Raise an error if the firmware response is an error response.""" if "er" in resp and not "er0" in resp: error = vantage_response_string_to_error(resp) raise error def _parse_response(self, resp: str, fmt: Dict[str, str]) -> dict: - """ Parse a firmware response. """ + """Parse a firmware response.""" return parse_vantage_fw_string(resp, fmt) async def setup(self): - """ setup + """setup Creates a USB connection and finds read/write interfaces. """ @@ -396,14 +400,14 @@ async def setup(self): pip_channels_initialized = await self.pip_request_initialization_status() if not pip_channels_initialized or any(tip_presences): await self.pip_initialize( - x_position=[7095]*self.num_channels, + x_position=[7095] * self.num_channels, y_position=[3891, 3623, 3355, 3087, 2819, 2551, 2283, 2016], begin_z_deposit_position=[int(self._traversal_height * 10)] * self.num_channels, end_z_deposit_position=[1235] * self.num_channels, minimal_height_at_command_end=[int(self._traversal_height * 10)] * self.num_channels, - tip_pattern=[True]*self.num_channels, - tip_type=[1]*self.num_channels, - TODO_DI_2=70 + tip_pattern=[True] * self.num_channels, + tip_type=[1] * self.num_channels, + TODO_DI_2=70, ) loading_cover_initialized = await self.loading_cover_request_initialization_status() @@ -413,8 +417,8 @@ async def setup(self): core96_initialized = await self.core96_request_initialization_status() if not core96_initialized: await self.core96_initialize( - x_position=7347, # TODO: get trash location from deck. - y_position=2684, # TODO: get trash location from deck. + x_position=7347, # TODO: get trash location from deck. + y_position=2684, # TODO: get trash location from deck. minimal_traverse_height_at_begin_of_command=int(self._traversal_height * 10), minimal_height_at_command_end=int(self._traversal_height * 10), end_z_deposit_position=2420, @@ -428,13 +432,13 @@ async def setup(self): @property def num_channels(self) -> int: - """ The number of channels on the robot. """ + """The number of channels on the robot.""" if self._num_channels is None: raise RuntimeError("num_channels is not set.") return self._num_channels def set_minimum_traversal_height(self, traversal_height: float): - """ Set the minimum traversal height for the robot. + """Set the minimum traversal height for the robot. This refers to the bottom of the pipetting channel when no tip is present, or the bottom of the tip when a tip is present. This value will be used as the default value for the @@ -455,15 +459,14 @@ async def pick_up_tips( minimal_traverse_height_at_begin_of_command: Optional[List[float]] = None, minimal_height_at_command_end: Optional[List[float]] = None, ): - x_positions, y_positions, tip_pattern = \ - self._ops_to_fw_positions(ops, use_channels) + x_positions, y_positions, tip_pattern = self._ops_to_fw_positions(ops, use_channels) tips = [cast(HamiltonTip, op.resource.get_tip()) for op in ops] ttti = await self.get_ttti(tips) max_z = max(op.resource.get_absolute_location().z + op.offset.z for op in ops) max_total_tip_length = max(op.tip.total_tip_length for op in ops) - max_tip_length = max((op.tip.total_tip_length-op.tip.fitting_depth) for op in ops) + max_tip_length = max((op.tip.total_tip_length - op.tip.fitting_depth) for op in ops) # not sure why this is necessary, but it is according to log files and experiments if self._get_hamilton_tip([op.resource for op in ops]).tip_size == TipSize.LOW_VOLUME: @@ -477,16 +480,19 @@ async def pick_up_tips( y_position=y_positions, tip_pattern=tip_pattern, tip_type=ttti, - begin_z_deposit_position=[round((max_z + max_total_tip_length)*10)]*len(ops), - end_z_deposit_position=[round((max_z + max_tip_length)*10)]*len(ops), - minimal_traverse_height_at_begin_of_command= - [round(th*10) for th in minimal_traverse_height_at_begin_of_command or - [self._traversal_height]]*len(ops), - minimal_height_at_command_end= - [round(th*10) for th in minimal_height_at_command_end or - [self._traversal_height]]*len(ops), - tip_handling_method=[1 for _ in tips], # always appears to be 1 # tip.pickup_method.value - blow_out_air_volume=[0]*len(ops), # Why is this here? Who knows. + begin_z_deposit_position=[round((max_z + max_total_tip_length) * 10)] * len(ops), + end_z_deposit_position=[round((max_z + max_tip_length) * 10)] * len(ops), + minimal_traverse_height_at_begin_of_command=[ + round(th * 10) + for th in minimal_traverse_height_at_begin_of_command or [self._traversal_height] + ] + * len(ops), + minimal_height_at_command_end=[ + round(th * 10) for th in minimal_height_at_command_end or [self._traversal_height] + ] + * len(ops), + tip_handling_method=[1 for _ in tips], # always appears to be 1 # tip.pickup_method.value + blow_out_air_volume=[0] * len(ops), # Why is this here? Who knows. ) except Exception as e: raise e @@ -499,10 +505,9 @@ async def drop_tips( minimal_traverse_height_at_begin_of_command: Optional[List[float]] = None, minimal_height_at_command_end: Optional[List[float]] = None, ): - """ Drop tips to a resource. """ + """Drop tips to a resource.""" - x_positions, y_positions, channels_involved = \ - self._ops_to_fw_positions(ops, use_channels) + x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) max_z = max(op.resource.get_absolute_location().z + op.offset.z for op in ops) @@ -511,15 +516,18 @@ async def drop_tips( x_position=x_positions, y_position=y_positions, tip_pattern=channels_involved, - begin_z_deposit_position=[round((max_z+10)*10)]*len(ops), # +10 - end_z_deposit_position=[round(max_z*10)]*len(ops), - minimal_traverse_height_at_begin_of_command= - [round(th*10) for th in minimal_traverse_height_at_begin_of_command or - [self._traversal_height]]*len(ops), - minimal_height_at_command_end= - [round(th*10) for th in minimal_height_at_command_end or - [self._traversal_height]]*len(ops), - tip_handling_method=[0 for _ in ops], # Always appears to be 0, even in trash. + begin_z_deposit_position=[round((max_z + 10) * 10)] * len(ops), # +10 + end_z_deposit_position=[round(max_z * 10)] * len(ops), + minimal_traverse_height_at_begin_of_command=[ + round(th * 10) + for th in minimal_traverse_height_at_begin_of_command or [self._traversal_height] + ] + * len(ops), + minimal_height_at_command_end=[ + round(th * 10) for th in minimal_height_at_command_end or [self._traversal_height] + ] + * len(ops), + tip_handling_method=[0 for _ in ops], # Always appears to be 0, even in trash. # tip_handling_method=[TipDropMethod.DROP.value if isinstance(op.resource, TipSpot) \ # else TipDropMethod.PLACE_SHIFT.value for op in ops], TODO_TR_2=0, @@ -528,18 +536,18 @@ async def drop_tips( raise e def _assert_valid_resources(self, resources: Sequence[Resource]) -> None: - """ Assert that resources are in a valid location for pipetting. """ + """Assert that resources are in a valid location for pipetting.""" for resource in resources: if resource.get_absolute_location().z < 100: raise ValueError( - f"Resource {resource} is too low: {resource.get_absolute_location().z} < 100") + f"Resource {resource} is too low: {resource.get_absolute_location().z} < 100" + ) async def aspirate( self, ops: List[Aspiration], use_channels: List[int], hlcs: Optional[List[Optional[HamiltonLiquidClass]]] = None, - type_of_aspiration: Optional[List[int]] = None, minimal_traverse_height_at_begin_of_command: Optional[List[float]] = None, minimal_height_at_command_end: Optional[List[float]] = None, @@ -572,7 +580,7 @@ async def aspirate( limit_curve_index: Optional[List[int]] = None, recording_mode: int = 0, ): - """ Aspirate from (a) resource(s). + """Aspirate from (a) resource(s). See :meth:`pip_aspirate` (the firmware command) for parameter documentation. This method serves as a wrapper for that command, and will convert operations into the appropriate format. This @@ -590,19 +598,24 @@ async def aspirate( if hlcs is not None: raise NotImplementedError("hlcs is deprecated") - x_positions, y_positions, channels_involved = \ - self._ops_to_fw_positions(ops, use_channels) + x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) self._assert_valid_resources([op.resource for op in ops]) - well_bottoms = [op.resource.get_absolute_location().z + op.offset.z + \ - op.resource.material_z_thickness for op in ops] - liquid_surfaces_no_lld = liquid_surface_at_function_without_lld or [wb + (op.liquid_height or 0) - for wb, op in zip(well_bottoms, ops)] + well_bottoms = [ + op.resource.get_absolute_location().z + op.offset.z + op.resource.material_z_thickness + for op in ops + ] + liquid_surfaces_no_lld = liquid_surface_at_function_without_lld or [ + wb + (op.liquid_height or 0) for wb, op in zip(well_bottoms, ops) + ] # -1 compared to STAR? - lld_search_heights = lld_search_height or [wb + op.resource.get_absolute_size_z() + \ - (2.7-1 if isinstance(op.resource, Well) else 5) #? - for wb, op in zip(well_bottoms, ops)] + lld_search_heights = lld_search_height or [ + wb + + op.resource.get_absolute_size_z() + + (2.7 - 1 if isinstance(op.resource, Well) else 5) # ? + for wb, op in zip(well_bottoms, ops) + ] flow_rates = [op.flow_rate or 100 for op in ops] blow_out_air_volumes = [op.blow_out_air_volume or 0 for op in ops] @@ -612,51 +625,63 @@ async def aspirate( return await self.pip_aspirate( x_position=x_positions, y_position=y_positions, - type_of_aspiration=type_of_aspiration or [0]*len(ops), + type_of_aspiration=type_of_aspiration or [0] * len(ops), tip_pattern=channels_involved, - minimal_traverse_height_at_begin_of_command= - [round(th*10) for th in minimal_traverse_height_at_begin_of_command or - [self._traversal_height]]*len(ops), - minimal_height_at_command_end= - [round(th*10) for th in minimal_height_at_command_end or - [self._traversal_height]]*len(ops), - lld_search_height=[round(ls*10) for ls in lld_search_heights], - clot_detection_height=[round(cdh*10) for cdh in clot_detection_height or [0]*len(ops)], + minimal_traverse_height_at_begin_of_command=[ + round(th * 10) + for th in minimal_traverse_height_at_begin_of_command or [self._traversal_height] + ] + * len(ops), + minimal_height_at_command_end=[ + round(th * 10) for th in minimal_height_at_command_end or [self._traversal_height] + ] + * len(ops), + lld_search_height=[round(ls * 10) for ls in lld_search_heights], + clot_detection_height=[round(cdh * 10) for cdh in clot_detection_height or [0] * len(ops)], liquid_surface_at_function_without_lld=[round(lsn * 10) for lsn in liquid_surfaces_no_lld], - pull_out_distance_to_take_transport_air_in_function_without_lld=\ - [round(pod*10) for pod in pull_out_distance_to_take_transport_air_in_function_without_lld or - [10.9]*len(ops)], - tube_2nd_section_height_measured_from_zm= - [round(t2sh*10) for t2sh in tube_2nd_section_height_measured_from_zm or [0]*len(ops)], - tube_2nd_section_ratio=[round(t2sr*10) for t2sr in tube_2nd_section_ratio or [0]*len(ops)], + pull_out_distance_to_take_transport_air_in_function_without_lld=[ + round(pod * 10) + for pod in pull_out_distance_to_take_transport_air_in_function_without_lld + or [10.9] * len(ops) + ], + tube_2nd_section_height_measured_from_zm=[ + round(t2sh * 10) for t2sh in tube_2nd_section_height_measured_from_zm or [0] * len(ops) + ], + tube_2nd_section_ratio=[ + round(t2sr * 10) for t2sr in tube_2nd_section_ratio or [0] * len(ops) + ], minimum_height=[round(wb * 10) for wb in minimum_height or well_bottoms], - immersion_depth=[round(id_*10) for id_ in immersion_depth or [0]*len(ops)], - surface_following_distance=[round(sfd*10) for sfd in surface_following_distance or - [0]*len(ops)], - aspiration_volume=[round(op.volume*100) for op in ops], + immersion_depth=[round(id_ * 10) for id_ in immersion_depth or [0] * len(ops)], + surface_following_distance=[ + round(sfd * 10) for sfd in surface_following_distance or [0] * len(ops) + ], + aspiration_volume=[round(op.volume * 100) for op in ops], aspiration_speed=[round(fr * 10) for fr in flow_rates], - transport_air_volume=[round(tav*10) for tav in transport_air_volume or [0]*len(ops)], - blow_out_air_volume=[round(bav*100) for bav in blow_out_air_volumes], - pre_wetting_volume=[round(pwv*100) for pwv in pre_wetting_volume or [0]*len(ops)], - lld_mode=lld_mode or [0]*len(ops), - lld_sensitivity=lld_sensitivity or [4]*len(ops), - pressure_lld_sensitivity=pressure_lld_sensitivity or [4]*len(ops), - aspirate_position_above_z_touch_off= - [round(apz*10) for apz in aspirate_position_above_z_touch_off or [0.5]*len(ops)], - swap_speed=[round(ss*10) for ss in swap_speed or [2]*len(ops)], - settling_time=[round(st*10) for st in settling_time or [1]*len(ops)], - mix_volume=[round(mv*100) for mv in mix_volume or [0]*len(ops)], - mix_cycles=mix_cycles or [0]*len(ops), - mix_position_in_z_direction_from_liquid_surface= - [round(mp) for mp in mix_position_in_z_direction_from_liquid_surface or [0]*len(ops)], - mix_speed=[round(ms*10) for ms in mix_speed or [250]*len(ops)], - surface_following_distance_during_mixing= - [round(sfdm*10) for sfdm in surface_following_distance_during_mixing or [0]*len(ops)], - TODO_DA_5=TODO_DA_5 or [0]*len(ops), - capacitive_mad_supervision_on_off=capacitive_mad_supervision_on_off or [0]*len(ops), - pressure_mad_supervision_on_off=pressure_mad_supervision_on_off or [0]*len(ops), + transport_air_volume=[round(tav * 10) for tav in transport_air_volume or [0] * len(ops)], + blow_out_air_volume=[round(bav * 100) for bav in blow_out_air_volumes], + pre_wetting_volume=[round(pwv * 100) for pwv in pre_wetting_volume or [0] * len(ops)], + lld_mode=lld_mode or [0] * len(ops), + lld_sensitivity=lld_sensitivity or [4] * len(ops), + pressure_lld_sensitivity=pressure_lld_sensitivity or [4] * len(ops), + aspirate_position_above_z_touch_off=[ + round(apz * 10) for apz in aspirate_position_above_z_touch_off or [0.5] * len(ops) + ], + swap_speed=[round(ss * 10) for ss in swap_speed or [2] * len(ops)], + settling_time=[round(st * 10) for st in settling_time or [1] * len(ops)], + mix_volume=[round(mv * 100) for mv in mix_volume or [0] * len(ops)], + mix_cycles=mix_cycles or [0] * len(ops), + mix_position_in_z_direction_from_liquid_surface=[ + round(mp) for mp in mix_position_in_z_direction_from_liquid_surface or [0] * len(ops) + ], + mix_speed=[round(ms * 10) for ms in mix_speed or [250] * len(ops)], + surface_following_distance_during_mixing=[ + round(sfdm * 10) for sfdm in surface_following_distance_during_mixing or [0] * len(ops) + ], + TODO_DA_5=TODO_DA_5 or [0] * len(ops), + capacitive_mad_supervision_on_off=capacitive_mad_supervision_on_off or [0] * len(ops), + pressure_mad_supervision_on_off=pressure_mad_supervision_on_off or [0] * len(ops), tadm_algorithm_on_off=tadm_algorithm_on_off or 0, - limit_curve_index=limit_curve_index or [0]*len(ops), + limit_curve_index=limit_curve_index or [0] * len(ops), recording_mode=recording_mode or 0, ) @@ -664,12 +689,10 @@ async def dispense( self, ops: List[Dispense], use_channels: List[int], - jet: Optional[List[bool]] = None, - blow_out: Optional[List[bool]] = None, # "empty" in the VENUS liquid editor - empty: Optional[List[bool]] = None, # truly "empty", does not exist in liquid editor, dm4 + blow_out: Optional[List[bool]] = None, # "empty" in the VENUS liquid editor + empty: Optional[List[bool]] = None, # truly "empty", does not exist in liquid editor, dm4 hlcs: Optional[List[Optional[HamiltonLiquidClass]]] = None, - type_of_dispensing_mode: Optional[List[int]] = None, minimum_height: Optional[List[float]] = None, pull_out_distance_to_take_transport_air_in_function_without_lld: Optional[List[float]] = None, @@ -700,7 +723,7 @@ async def dispense( limit_curve_index: Optional[List[int]] = None, recording_mode: int = 0, ): - """ Dispense to (a) resource(s). + """Dispense to (a) resource(s). See :meth:`pip_dispense` (the firmware command) for parameter documentation. This method serves as a wrapper for that command, and will convert operations into the appropriate format. This @@ -724,81 +747,97 @@ async def dispense( if hlcs is not None: raise NotImplementedError("hlcs is deprecated") - x_positions, y_positions, channels_involved = \ - self._ops_to_fw_positions(ops, use_channels) + x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) if jet is None: - jet = [False]*len(ops) + jet = [False] * len(ops) if empty is None: - empty = [False]*len(ops) + empty = [False] * len(ops) if blow_out is None: - blow_out = [False]*len(ops) + blow_out = [False] * len(ops) self._assert_valid_resources([op.resource for op in ops]) - well_bottoms = [op.resource.get_absolute_location().z + op.offset.z + \ - op.resource.material_z_thickness for op in ops] - liquid_surfaces_no_lld = [wb + (op.liquid_height or 0) - for wb, op in zip(well_bottoms, ops)] + well_bottoms = [ + op.resource.get_absolute_location().z + op.offset.z + op.resource.material_z_thickness + for op in ops + ] + liquid_surfaces_no_lld = [wb + (op.liquid_height or 0) for wb, op in zip(well_bottoms, ops)] # -1 compared to STAR? - lld_search_heights = lld_search_height or [wb + op.resource.get_absolute_size_z() + \ - (2.7-1 if isinstance(op.resource, Well) else 5) #? - for wb, op in zip(well_bottoms, ops)] + lld_search_heights = lld_search_height or [ + wb + + op.resource.get_absolute_size_z() + + (2.7 - 1 if isinstance(op.resource, Well) else 5) # ? + for wb, op in zip(well_bottoms, ops) + ] flow_rates = [op.flow_rate or 100 for op in ops] blow_out_air_volumes = [op.blow_out_air_volume or 0 for op in ops] - type_of_dispensing_mode = type_of_dispensing_mode or \ - [_get_dispense_mode(jet=jet[i], empty=empty[i], blow_out=blow_out[i]) - for i in range(len(ops))] + type_of_dispensing_mode = type_of_dispensing_mode or [ + _get_dispense_mode(jet=jet[i], empty=empty[i], blow_out=blow_out[i]) for i in range(len(ops)) + ] return await self.pip_dispense( x_position=x_positions, y_position=y_positions, tip_pattern=channels_involved, type_of_dispensing_mode=type_of_dispensing_mode, - minimum_height=[round(wb*10) for wb in minimum_height or well_bottoms], - lld_search_height=[round(sh*10) for sh in lld_search_heights], - liquid_surface_at_function_without_lld=[round(ls*10) for ls in liquid_surfaces_no_lld], - pull_out_distance_to_take_transport_air_in_function_without_lld= - [round(pod*10) for pod in pull_out_distance_to_take_transport_air_in_function_without_lld or - [5.0]*len(ops)], - immersion_depth=[round(id*10) for id in immersion_depth or [0]*len(ops)], - surface_following_distance= - [round(sfd*10) for sfd in surface_following_distance or [2.1]*len(ops)], - tube_2nd_section_height_measured_from_zm= - [round(t2sh*10) for t2sh in tube_2nd_section_height_measured_from_zm or [0]*len(ops)], - tube_2nd_section_ratio=[round(t2sr*10) for t2sr in tube_2nd_section_ratio or [0]*len(ops)], - minimal_traverse_height_at_begin_of_command= - [round(mth*10) for mth in - minimal_traverse_height_at_begin_of_command or [self._traversal_height]*len(ops)], - minimal_height_at_command_end= - [round(mh*10) for mh in minimal_height_at_command_end or [self._traversal_height]*len(ops)], - dispense_volume=[round(op.volume*100) for op in ops], - dispense_speed=[round(fr*10) for fr in flow_rates], - cut_off_speed=[round(cs*10) for cs in cut_off_speed or [250]*len(ops)], - stop_back_volume=[round(sbv*100) for sbv in stop_back_volume or [0]*len(ops)], - transport_air_volume=[round(tav*10) for tav in transport_air_volume or [0]*len(ops)], - blow_out_air_volume=[round(boav*100) for boav in blow_out_air_volumes], - lld_mode=lld_mode or [0]*len(ops), - side_touch_off_distance=round(side_touch_off_distance*10), - dispense_position_above_z_touch_off= - [round(dpz*10) for dpz in dispense_position_above_z_touch_off or [0.5]*len(ops)], - lld_sensitivity=lld_sensitivity or [1]*len(ops), - pressure_lld_sensitivity=pressure_lld_sensitivity or [1]*len(ops), - swap_speed=[round(ss*10) for ss in swap_speed or [1]*len(ops)], - settling_time=[round(st*10) for st in settling_time or [0]*len(ops)], - mix_volume=[round(mv*100) for mv in mix_volume or [0]*len(ops)], - mix_cycles=mix_cycles or [0]*len(ops), - mix_position_in_z_direction_from_liquid_surface= - [round(mp) for mp in mix_position_in_z_direction_from_liquid_surface or [0]*len(ops)], - mix_speed=[round(ms*10) for ms in mix_speed or [1]*len(ops)], - surface_following_distance_during_mixing= - [round(sfdm*10) for sfdm in surface_following_distance_during_mixing or [0]*len(ops)], - TODO_DD_2=TODO_DD_2 or [0]*len(ops), + minimum_height=[round(wb * 10) for wb in minimum_height or well_bottoms], + lld_search_height=[round(sh * 10) for sh in lld_search_heights], + liquid_surface_at_function_without_lld=[round(ls * 10) for ls in liquid_surfaces_no_lld], + pull_out_distance_to_take_transport_air_in_function_without_lld=[ + round(pod * 10) + for pod in pull_out_distance_to_take_transport_air_in_function_without_lld + or [5.0] * len(ops) + ], + immersion_depth=[round(id * 10) for id in immersion_depth or [0] * len(ops)], + surface_following_distance=[ + round(sfd * 10) for sfd in surface_following_distance or [2.1] * len(ops) + ], + tube_2nd_section_height_measured_from_zm=[ + round(t2sh * 10) for t2sh in tube_2nd_section_height_measured_from_zm or [0] * len(ops) + ], + tube_2nd_section_ratio=[ + round(t2sr * 10) for t2sr in tube_2nd_section_ratio or [0] * len(ops) + ], + minimal_traverse_height_at_begin_of_command=[ + round(mth * 10) + for mth in minimal_traverse_height_at_begin_of_command + or [self._traversal_height] * len(ops) + ], + minimal_height_at_command_end=[ + round(mh * 10) + for mh in minimal_height_at_command_end or [self._traversal_height] * len(ops) + ], + dispense_volume=[round(op.volume * 100) for op in ops], + dispense_speed=[round(fr * 10) for fr in flow_rates], + cut_off_speed=[round(cs * 10) for cs in cut_off_speed or [250] * len(ops)], + stop_back_volume=[round(sbv * 100) for sbv in stop_back_volume or [0] * len(ops)], + transport_air_volume=[round(tav * 10) for tav in transport_air_volume or [0] * len(ops)], + blow_out_air_volume=[round(boav * 100) for boav in blow_out_air_volumes], + lld_mode=lld_mode or [0] * len(ops), + side_touch_off_distance=round(side_touch_off_distance * 10), + dispense_position_above_z_touch_off=[ + round(dpz * 10) for dpz in dispense_position_above_z_touch_off or [0.5] * len(ops) + ], + lld_sensitivity=lld_sensitivity or [1] * len(ops), + pressure_lld_sensitivity=pressure_lld_sensitivity or [1] * len(ops), + swap_speed=[round(ss * 10) for ss in swap_speed or [1] * len(ops)], + settling_time=[round(st * 10) for st in settling_time or [0] * len(ops)], + mix_volume=[round(mv * 100) for mv in mix_volume or [0] * len(ops)], + mix_cycles=mix_cycles or [0] * len(ops), + mix_position_in_z_direction_from_liquid_surface=[ + round(mp) for mp in mix_position_in_z_direction_from_liquid_surface or [0] * len(ops) + ], + mix_speed=[round(ms * 10) for ms in mix_speed or [1] * len(ops)], + surface_following_distance_during_mixing=[ + round(sfdm * 10) for sfdm in surface_following_distance_during_mixing or [0] * len(ops) + ], + TODO_DD_2=TODO_DD_2 or [0] * len(ops), tadm_algorithm_on_off=tadm_algorithm_on_off or 0, - limit_curve_index=limit_curve_index or [0]*len(ops), + limit_curve_index=limit_curve_index or [0] * len(ops), recording_mode=recording_mode or 0, ) @@ -808,7 +847,7 @@ async def pick_up_tips96( tip_handling_method: int = 0, z_deposit_position: float = 216.4, minimal_traverse_height_at_begin_of_command: Optional[float] = None, - minimal_height_at_command_end: Optional[float] = None + minimal_height_at_command_end: Optional[float] = None, ): # assert self.core96_head_installed, "96 head must be installed" tip_spot_a1 = pickup.resource.get_item("A1") @@ -824,10 +863,12 @@ async def pick_up_tips96( tip_type=ttti, tip_handling_method=tip_handling_method, z_deposit_position=round((z_deposit_position + offset_z) * 10), - minimal_traverse_height_at_begin_of_command= - round((minimal_traverse_height_at_begin_of_command or self._traversal_height) * 10), - minimal_height_at_command_end= - round((minimal_height_at_command_end or self._traversal_height)*10) + minimal_traverse_height_at_begin_of_command=round( + (minimal_traverse_height_at_begin_of_command or self._traversal_height) * 10 + ), + minimal_height_at_command_end=round( + (minimal_height_at_command_end or self._traversal_height) * 10 + ), ) async def drop_tips96( @@ -835,32 +876,34 @@ async def drop_tips96( drop: DropTipRack, z_deposit_position: float = 216.4, minimal_traverse_height_at_begin_of_command: Optional[float] = None, - minimal_height_at_command_end: Optional[float] = None + minimal_height_at_command_end: Optional[float] = None, ): # assert self.core96_head_installed, "96 head must be installed" if isinstance(drop.resource, TipRack): tip_spot_a1 = drop.resource.get_item("A1") position = tip_spot_a1.get_absolute_location() + tip_spot_a1.center() + drop.offset else: - raise NotImplementedError("Only TipRacks are supported for dropping tips on Vantage", - f"got {drop.resource}") + raise NotImplementedError( + "Only TipRacks are supported for dropping tips on Vantage", f"got {drop.resource}" + ) offset_z = drop.offset.z return await self.core96_tip_discard( x_position=round(position.x * 10), y_position=round(position.y * 10), z_deposit_position=round((z_deposit_position + offset_z) * 10), - minimal_traverse_height_at_begin_of_command= - round((minimal_traverse_height_at_begin_of_command or self._traversal_height) * 10), - minimal_height_at_command_end= - round((minimal_height_at_command_end or self._traversal_height)*10) + minimal_traverse_height_at_begin_of_command=round( + (minimal_traverse_height_at_begin_of_command or self._traversal_height) * 10 + ), + minimal_height_at_command_end=round( + (minimal_height_at_command_end or self._traversal_height) * 10 + ), ) async def aspirate96( self, aspiration: Union[AspirationPlate, AspirationContainer], hlc: Optional[HamiltonLiquidClass] = None, - type_of_aspiration: int = 0, minimal_traverse_height_at_begin_of_command: Optional[float] = None, minimal_height_at_command_end: Optional[float] = None, @@ -892,16 +935,23 @@ async def aspirate96( if isinstance(aspiration, AspirationPlate): top_left_well = aspiration.wells[0] - position = top_left_well.get_absolute_location() + top_left_well.center() + \ - aspiration.offset + Coordinate(z=top_left_well.material_z_thickness) + position = ( + top_left_well.get_absolute_location() + + top_left_well.center() + + aspiration.offset + + Coordinate(z=top_left_well.material_z_thickness) + ) # -1 compared to STAR? well_bottoms = position.z - lld_search_height = well_bottoms + top_left_well.get_absolute_size_z() + 2.7-1 + lld_search_height = well_bottoms + top_left_well.get_absolute_size_z() + 2.7 - 1 else: - position = aspiration.container.get_absolute_location(y="b") + aspiration.offset + \ - Coordinate(z=aspiration.container.material_z_thickness) + position = ( + aspiration.container.get_absolute_location(y="b") + + aspiration.offset + + Coordinate(z=aspiration.container.material_z_thickness) + ) bottom = position.z - lld_search_height = bottom + aspiration.container.get_absolute_size_z() + 2.7-1 + lld_search_height = bottom + aspiration.container.get_absolute_size_z() + 2.7 - 1 liquid_height = position.z + (aspiration.liquid_height or 0) @@ -924,34 +974,40 @@ async def aspirate96( x_position=round(position.x * 10), y_position=round(position.y * 10), type_of_aspiration=type_of_aspiration, - minimal_traverse_height_at_begin_of_command= - round((minimal_traverse_height_at_begin_of_command or self._traversal_height) * 10), - minimal_height_at_command_end= - round(minimal_height_at_command_end or self._traversal_height * 10), + minimal_traverse_height_at_begin_of_command=round( + (minimal_traverse_height_at_begin_of_command or self._traversal_height) * 10 + ), + minimal_height_at_command_end=round( + minimal_height_at_command_end or self._traversal_height * 10 + ), lld_search_height=round(lld_search_height * 10), liquid_surface_at_function_without_lld=round(liquid_height * 10), - pull_out_distance_to_take_transport_air_in_function_without_lld=\ - round(pull_out_distance_to_take_transport_air_in_function_without_lld*10), + pull_out_distance_to_take_transport_air_in_function_without_lld=round( + pull_out_distance_to_take_transport_air_in_function_without_lld * 10 + ), minimum_height=round(well_bottoms * 10), - tube_2nd_section_height_measured_from_zm=round(tube_2nd_section_height_measured_from_zm*10), - tube_2nd_section_ratio=round(tube_2nd_section_ratio*10), - immersion_depth=round(immersion_depth*10), - surface_following_distance=round(surface_following_distance*10), + tube_2nd_section_height_measured_from_zm=round(tube_2nd_section_height_measured_from_zm * 10), + tube_2nd_section_ratio=round(tube_2nd_section_ratio * 10), + immersion_depth=round(immersion_depth * 10), + surface_following_distance=round(surface_following_distance * 10), aspiration_volume=round(aspiration.volume * 100), aspiration_speed=round(flow_rate * 10), - transport_air_volume=round(transport_air_volume*10), - blow_out_air_volume=round(blow_out_air_volume*100), - pre_wetting_volume=round(pre_wetting_volume*100), + transport_air_volume=round(transport_air_volume * 10), + blow_out_air_volume=round(blow_out_air_volume * 100), + pre_wetting_volume=round(pre_wetting_volume * 100), lld_mode=lld_mode, lld_sensitivity=lld_sensitivity, - swap_speed=round(swap_speed*10), - settling_time=round(settling_time*10), - mix_volume=round(mix_volume*100), + swap_speed=round(swap_speed * 10), + settling_time=round(settling_time * 10), + mix_volume=round(mix_volume * 100), mix_cycles=mix_cycles, - mix_position_in_z_direction_from_liquid_surface=\ - round(mix_position_in_z_direction_from_liquid_surface*100), - surface_following_distance_during_mixing=round(surface_following_distance_during_mixing*100), - mix_speed=round(mix_speed*10), + mix_position_in_z_direction_from_liquid_surface=round( + mix_position_in_z_direction_from_liquid_surface * 100 + ), + surface_following_distance_during_mixing=round( + surface_following_distance_during_mixing * 100 + ), + mix_speed=round(mix_speed * 10), limit_curve_index=limit_curve_index, tadm_channel_pattern=tadm_channel_pattern, tadm_algorithm_on_off=tadm_algorithm_on_off, @@ -962,9 +1018,8 @@ async def dispense96( self, dispense: Union[DispensePlate, DispenseContainer], jet: bool = False, - blow_out: bool = False, # "empty" in the VENUS liquid editor - empty: bool = False, # truly "empty", does not exist in liquid editor, dm4 - + blow_out: bool = False, # "empty" in the VENUS liquid editor + empty: bool = False, # truly "empty", does not exist in liquid editor, dm4 hlc: Optional[HamiltonLiquidClass] = None, type_of_dispensing_mode: Optional[int] = None, tube_2nd_section_height_measured_from_zm: float = 0, @@ -992,7 +1047,7 @@ async def dispense96( tadm_algorithm_on_off: int = 0, recording_mode: int = 0, ): - """ Dispense to a plate using the 96 head. + """Dispense to a plate using the 96 head. Args: jet: whether to dispense in jet mode. @@ -1012,16 +1067,23 @@ async def dispense96( if isinstance(dispense, DispensePlate): top_left_well = dispense.wells[0] - position = top_left_well.get_absolute_location() + top_left_well.center() + \ - dispense.offset + Coordinate(z=top_left_well.material_z_thickness) + position = ( + top_left_well.get_absolute_location() + + top_left_well.center() + + dispense.offset + + Coordinate(z=top_left_well.material_z_thickness) + ) # -1 compared to STAR? well_bottoms = position.z - lld_search_height = well_bottoms + top_left_well.get_absolute_size_z() + 2.7-1 + lld_search_height = well_bottoms + top_left_well.get_absolute_size_z() + 2.7 - 1 else: - position = dispense.container.get_absolute_location(y="b") + dispense.offset + \ - Coordinate(z=dispense.container.material_z_thickness) + position = ( + dispense.container.get_absolute_location(y="b") + + dispense.offset + + Coordinate(z=dispense.container.material_z_thickness) + ) bottom = position.z - lld_search_height = bottom + dispense.container.get_absolute_size_z() + 2.7-1 + lld_search_height = bottom + dispense.container.get_absolute_size_z() + 2.7 - 1 liquid_height = position.z + (dispense.liquid_height or 0) + 10 @@ -1049,35 +1111,39 @@ async def dispense96( y_position=round(position.y * 10), type_of_dispensing_mode=type_of_dispensing_mode, minimum_height=round(well_bottoms * 10), - tube_2nd_section_height_measured_from_zm=round(tube_2nd_section_height_measured_from_zm*10), - tube_2nd_section_ratio=round(tube_2nd_section_ratio*10), + tube_2nd_section_height_measured_from_zm=round(tube_2nd_section_height_measured_from_zm * 10), + tube_2nd_section_ratio=round(tube_2nd_section_ratio * 10), lld_search_height=round(lld_search_height * 10), liquid_surface_at_function_without_lld=round(liquid_height * 10), - pull_out_distance_to_take_transport_air_in_function_without_lld=\ - round(pull_out_distance_to_take_transport_air_in_function_without_lld*10), - immersion_depth=round(immersion_depth*10), - surface_following_distance=round(surface_following_distance*10), - minimal_traverse_height_at_begin_of_command= - round((minimal_traverse_height_at_begin_of_command or self._traversal_height) * 10), - minimal_height_at_command_end= - round((minimal_height_at_command_end or self._traversal_height)*10), + pull_out_distance_to_take_transport_air_in_function_without_lld=round( + pull_out_distance_to_take_transport_air_in_function_without_lld * 10 + ), + immersion_depth=round(immersion_depth * 10), + surface_following_distance=round(surface_following_distance * 10), + minimal_traverse_height_at_begin_of_command=round( + (minimal_traverse_height_at_begin_of_command or self._traversal_height) * 10 + ), + minimal_height_at_command_end=round( + (minimal_height_at_command_end or self._traversal_height) * 10 + ), dispense_volume=round(dispense.volume * 100), dispense_speed=round(flow_rate * 10), cut_off_speed=round(cut_off_speed * 10), stop_back_volume=round(stop_back_volume * 100), - transport_air_volume=round(transport_air_volume*10), - blow_out_air_volume=round(blow_out_air_volume*100), + transport_air_volume=round(transport_air_volume * 10), + blow_out_air_volume=round(blow_out_air_volume * 100), lld_mode=lld_mode, lld_sensitivity=lld_sensitivity, - side_touch_off_distance=round(side_touch_off_distance*10), - swap_speed=round(swap_speed*10), - settling_time=round(settling_time*10), - mix_volume=round(mix_volume*10), + side_touch_off_distance=round(side_touch_off_distance * 10), + swap_speed=round(swap_speed * 10), + settling_time=round(settling_time * 10), + mix_volume=round(mix_volume * 10), mix_cycles=mix_cycles, - mix_position_in_z_direction_from_liquid_surface=\ - round(mix_position_in_z_direction_from_liquid_surface*10), - surface_following_distance_during_mixing=round(surface_following_distance_during_mixing*10), - mix_speed=round(mix_speed*10), + mix_position_in_z_direction_from_liquid_surface=round( + mix_position_in_z_direction_from_liquid_surface * 10 + ), + surface_following_distance_during_mixing=round(surface_following_distance_during_mixing * 10), + mix_speed=round(mix_speed * 10), limit_curve_index=limit_curve_index, tadm_channel_pattern=tadm_channel_pattern, tadm_algorithm_on_off=tadm_algorithm_on_off, @@ -1088,13 +1154,15 @@ async def move_resource(self, move: Move): await self.pick_up_resource( resource=move.resource, offset=move.resource_offset, - pickup_distance_from_top=move.pickup_distance_from_top) + pickup_distance_from_top=move.pickup_distance_from_top, + ) await self.release_picked_up_resource( resource=move.resource, destination=move.destination, offset=move.destination_offset, - pickup_distance_from_top=move.pickup_distance_from_top) + pickup_distance_from_top=move.pickup_distance_from_top, + ) async def pick_up_resource( self, @@ -1108,8 +1176,8 @@ async def pick_up_resource( hotel_depth: float = 0, minimal_height_at_command_end: float = 284.0, ): - """ Pick up a resource with the IPG. You probably want to use :meth:`move_resource`, which - allows you to pick up and move a resource with a single command. """ + """Pick up a resource with the IPG. You probably want to use :meth:`move_resource`, which + allows you to pick up and move a resource with a single command.""" center = resource.get_absolute_location() + resource.center() + offset grip_height = center.z + resource.get_absolute_size_z() - pickup_distance_from_top @@ -1120,18 +1188,19 @@ async def pick_up_resource( y_position=round(center.y * 10), z_position=round(grip_height * 10), grip_strength=grip_strength, - open_gripper_position=round(plate_width*10) + 32, + open_gripper_position=round(plate_width * 10) + 32, plate_width=round(plate_width * 10) - 33, - plate_width_tolerance=round(plate_width_tolerance*10), + plate_width_tolerance=round(plate_width_tolerance * 10), acceleration_index=acceleration_index, - z_clearance_height=round(z_clearance_height*10), - hotel_depth=round(hotel_depth*10), - minimal_height_at_command_end= - round((minimal_height_at_command_end or self._traversal_height) * 10), + z_clearance_height=round(z_clearance_height * 10), + hotel_depth=round(hotel_depth * 10), + minimal_height_at_command_end=round( + (minimal_height_at_command_end or self._traversal_height) * 10 + ), ) async def move_picked_up_resource(self): - """ Move a resource picked up with the IPG. See :meth:`pick_up_resource`. + """Move a resource picked up with the IPG. See :meth:`pick_up_resource`. You probably want to use :meth:`move_resource`, which allows you to pick up and move a resource with a single command. @@ -1148,9 +1217,9 @@ async def release_picked_up_resource( z_clearance_height: float = 0, press_on_distance: int = 5, hotel_depth: float = 0, - minimal_height_at_command_end: float = 284.0 + minimal_height_at_command_end: float = 284.0, ): - """ Release a resource picked up with the IPG. See :meth:`pick_up_resource`. + """Release a resource picked up with the IPG. See :meth:`pick_up_resource`. You probably want to use :meth:`move_resource`, which allows you to pick up and move a resource with a single command. @@ -1164,31 +1233,32 @@ async def release_picked_up_resource( x_position=round(center.x * 10), y_position=round(center.y * 10), z_position=round(grip_height * 10), - z_clearance_height=round(z_clearance_height*10), - open_gripper_position=round(plate_width*10) + 32, + z_clearance_height=round(z_clearance_height * 10), + open_gripper_position=round(plate_width * 10) + 32, press_on_distance=press_on_distance, - hotel_depth=round(hotel_depth*10), - minimal_height_at_command_end= - round((minimal_height_at_command_end or self._traversal_height) * 10), + hotel_depth=round(hotel_depth * 10), + minimal_height_at_command_end=round( + (minimal_height_at_command_end or self._traversal_height) * 10 + ), ) async def prepare_for_manual_channel_operation(self, channel: int): - """ Prepare the robot for manual operation. """ + """Prepare the robot for manual operation.""" - return await self.expose_channel_n(channel_index=channel + 1) # ? + return await self.expose_channel_n(channel_index=channel + 1) # ? - async def move_channel_x(self, channel: int, x: float): # pylint: disable=unused-argument - """ Move the specified channel to the specified x coordinate. """ + async def move_channel_x(self, channel: int, x: float): # pylint: disable=unused-argument + """Move the specified channel to the specified x coordinate.""" return await self.x_arm_move_to_x_position(round(x * 10)) async def move_channel_y(self, channel: int, y: float): - """ Move the specified channel to the specified y coordinate. """ + """Move the specified channel to the specified y coordinate.""" return await self.position_single_channel_in_y_direction(channel + 1, round(y * 10)) async def move_channel_z(self, channel: int, z: float): - """ Move the specified channel to the specified z coordinate. """ + """Move the specified channel to the specified z coordinate.""" return await self.position_single_channel_in_z_direction(channel + 1, round(z * 10)) @@ -1205,7 +1275,7 @@ async def set_led_color( uv: int, blink_interval: Optional[int] = None, ): - """ Set the LED color. + """Set the LED color. Args: mode: The mode of the LED. One of "on", "off", or "blink". @@ -1231,25 +1301,21 @@ async def set_led_color( "blink": 2, }[mode], os=intensity, - ok=blink_interval or 750, # default non zero value + ok=blink_interval or 750, # default non zero value ol=f"{white} {red} {green} {blue} {uv}", ) async def set_loading_cover(self, cover_open: bool): - """ Set the loading cover. + """Set the loading cover. Args: cover_open: Whether the cover should be open or closed. """ - return await self.send_command( - module="I1AM", - command="LP", - lp=not cover_open - ) + return await self.send_command(module="I1AM", command="LP", lp=not cover_open) async def loading_cover_request_initialization_status(self) -> bool: - """ Request the loading cover initialization status. + """Request the loading cover initialization status. This command was based on the STAR command (QW) and the VStarTranslator log. @@ -1257,15 +1323,11 @@ async def loading_cover_request_initialization_status(self) -> bool: True if the cover module is initialized, False otherwise. """ - resp = await self.send_command( - module="I1AM", - command="QW", - fmt={"qw": "int"} - ) + resp = await self.send_command(module="I1AM", command="QW", fmt={"qw": "int"}) return resp is not None and resp["qw"] == 1 async def loading_cover_initialize(self): - """ Initialize the loading cover. """ + """Initialize the loading cover.""" return await self.send_command( module="I1AM", @@ -1273,7 +1335,7 @@ async def loading_cover_initialize(self): ) async def arm_request_instrument_initialization_status(self) -> bool: - """ Request the instrument initialization status. + """Request the instrument initialization status. This command was based on the STAR command (QW) and the VStarTranslator log. A1AM corresponds to "arm". @@ -1286,12 +1348,12 @@ async def arm_request_instrument_initialization_status(self) -> bool: return resp is not None and resp["qw"] == 1 async def arm_pre_initialize(self): - """ Initialize the arm module. """ + """Initialize the arm module.""" return await self.send_command(module="A1AM", command="MI") async def pip_request_initialization_status(self) -> bool: - """ Request the pip initialization status. + """Request the pip initialization status. This command was based on the STAR command (QW) and the VStarTranslator log. A1PM corresponds to all pip channels together. @@ -1314,7 +1376,7 @@ async def pip_initialize( tip_type: Optional[List[int]] = None, TODO_DI_2: int = 0, ): - """ Initialize + """Initialize Args: x_position: X Position [0.1mm]. @@ -1383,9 +1445,9 @@ async def define_tip_needle( tip_length: int, maximum_tip_volume: int, tip_size: TipSize, - pickup_method: TipPickupMethod + pickup_method: TipPickupMethod, ): - """ Tip/needle definition. + """Tip/needle definition. Args: tip_type_table_index: tip_table_index @@ -1399,17 +1461,19 @@ async def define_tip_needle( """ if not 0 <= tip_type_table_index <= 99: - raise ValueError("tip_type_table_index must be between 0 and 99, but is " - f"{tip_type_table_index}") + raise ValueError( + "tip_type_table_index must be between 0 and 99, but is " f"{tip_type_table_index}" + ) if not 0 <= tip_type_table_index <= 99: - raise ValueError("tip_type_table_index must be between 0 and 99, but is " - f"{tip_type_table_index}") + raise ValueError( + "tip_type_table_index must be between 0 and 99, but is " f"{tip_type_table_index}" + ) if not 1 <= tip_length <= 1999: - raise ValueError("tip_length must be between 1 and 1999, but is " - f"{tip_length}") + raise ValueError("tip_length must be between 1 and 1999, but is " f"{tip_length}") if not 1 <= maximum_tip_volume <= 56000: - raise ValueError("maximum_tip_volume must be between 1 and 56000, but is " - f"{maximum_tip_volume}") + raise ValueError( + "maximum_tip_volume must be between 1 and 56000, but is " f"{maximum_tip_volume}" + ) return await self.send_command( module="A1AM", @@ -1419,7 +1483,7 @@ async def define_tip_needle( tl=f"{tip_length:04}", tv=f"{maximum_tip_volume:05}", tg=tip_size.value, - tu=pickup_method.value + tu=pickup_method.value, ) async def pip_aspirate( @@ -1464,7 +1528,7 @@ async def pip_aspirate( limit_curve_index: Optional[List[int]] = None, recording_mode: int = 0, ): - """ Aspiration of liquid + """Aspiration of liquid Args: type_of_aspiration: Type of aspiration (0 = simple 1 = sequence 2 = cup emptied). @@ -1556,10 +1620,13 @@ async def pip_aspirate( if pull_out_distance_to_take_transport_air_in_function_without_lld is None: pull_out_distance_to_take_transport_air_in_function_without_lld = [50] * self.num_channels - elif not all(0 <= x <= 3600 for x in - pull_out_distance_to_take_transport_air_in_function_without_lld): - raise ValueError("pull_out_distance_to_take_transport_air_in_function_without_lld must be " - "in range 0 to 3600") + elif not all( + 0 <= x <= 3600 for x in pull_out_distance_to_take_transport_air_in_function_without_lld + ): + raise ValueError( + "pull_out_distance_to_take_transport_air_in_function_without_lld must be " + "in range 0 to 3600" + ) if tube_2nd_section_height_measured_from_zm is None: tube_2nd_section_height_measured_from_zm = [0] * self.num_channels @@ -1785,7 +1852,7 @@ async def pip_dispense( limit_curve_index: Optional[List[int]] = None, recording_mode: int = 0, ): - """ Dispensing of liquid + """Dispensing of liquid Args: type_of_dispensing_mode: Type of dispensing mode 0 = part in jet 1 = blow in jet 2 = Part at @@ -1868,10 +1935,13 @@ async def pip_dispense( if pull_out_distance_to_take_transport_air_in_function_without_lld is None: pull_out_distance_to_take_transport_air_in_function_without_lld = [50] * self.num_channels - elif not all(0 <= x <= 3600 for x in - pull_out_distance_to_take_transport_air_in_function_without_lld): - raise ValueError("pull_out_distance_to_take_transport_air_in_function_without_lld must be " - "in range 0 to 3600") + elif not all( + 0 <= x <= 3600 for x in pull_out_distance_to_take_transport_air_in_function_without_lld + ): + raise ValueError( + "pull_out_distance_to_take_transport_air_in_function_without_lld must be " + "in range 0 to 3600" + ) if immersion_depth is None: immersion_depth = [0] * self.num_channels @@ -2024,7 +2094,7 @@ async def pip_dispense( zr=tube_2nd_section_ratio, th=minimal_traverse_height_at_begin_of_command, te=minimal_height_at_command_end, - dv=[f"{vol:04}" for vol in dispense_volume], # it appears at least 4 digits are needed + dv=[f"{vol:04}" for vol in dispense_volume], # it appears at least 4 digits are needed ds=dispense_speed, ss=cut_off_speed, rv=stop_back_volume, @@ -2095,7 +2165,7 @@ async def simultaneous_aspiration_dispensation_of_liquid( limit_curve_index: Optional[List[int]] = None, recording_mode: int = 0, ): - """ Simultaneous aspiration & dispensation of liquid + """Simultaneous aspiration & dispensation of liquid Args: type_of_aspiration: Type of aspiration (0 = simple 1 = sequence 2 = cup emptied). @@ -2206,10 +2276,13 @@ async def simultaneous_aspiration_dispensation_of_liquid( if pull_out_distance_to_take_transport_air_in_function_without_lld is None: pull_out_distance_to_take_transport_air_in_function_without_lld = [50] * self.num_channels - elif not all(0 <= x <= 3600 - for x in pull_out_distance_to_take_transport_air_in_function_without_lld): - raise ValueError("pull_out_distance_to_take_transport_air_in_function_without_lld must be " - "in range 0 to 3600") + elif not all( + 0 <= x <= 3600 for x in pull_out_distance_to_take_transport_air_in_function_without_lld + ): + raise ValueError( + "pull_out_distance_to_take_transport_air_in_function_without_lld must be " + "in range 0 to 3600" + ) if minimum_height is None: minimum_height = [3600] * self.num_channels @@ -2420,12 +2493,12 @@ async def dispense_on_fly( self, y_position: List[int], tip_pattern: Optional[List[bool]] = None, - first_shoot_x_pos: int = 0, #1 - dispense_on_fly_pos_command_end: int = 0, # 2 - x_acceleration_distance_before_first_shoot: int = 100, # 3 - space_between_shoots: int = 900, # 4 + first_shoot_x_pos: int = 0, # 1 + dispense_on_fly_pos_command_end: int = 0, # 2 + x_acceleration_distance_before_first_shoot: int = 100, # 3 + space_between_shoots: int = 900, # 4 x_speed: int = 270, - number_of_shoots: int = 1, # 5 + number_of_shoots: int = 1, # 5 minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, minimal_height_at_command_end: Optional[List[int]] = None, liquid_surface_at_function_without_lld: Optional[List[int]] = None, @@ -2438,7 +2511,7 @@ async def dispense_on_fly( limit_curve_index: Optional[List[int]] = None, recording_mode: int = 0, ): - """ Dispense on fly + """Dispense on fly Args: tip_pattern: Tip pattern (channels involved). [0 = not involved, 1 = involved]. @@ -2588,7 +2661,7 @@ async def nano_pulse_dispense( TODO_DB_11: Optional[List[int]] = None, TODO_DB_12: Optional[List[int]] = None, ): - """ Nano pulse dispense + """Nano pulse dispense Args: TODO_DB_0: (0). @@ -2738,7 +2811,7 @@ async def wash_tips( wash_cycles: int = 0, minimal_height_at_command_end: Optional[List[int]] = None, ): - """ Wash tips + """Wash tips Args: tip_pattern: Tip pattern (channels involved). [0 = not involved, 1 = involved]. @@ -2840,7 +2913,7 @@ async def pip_tip_pick_up( blow_out_air_volume: Optional[List[int]] = None, tip_handling_method: Optional[List[int]] = None, ): - """ Tip Pick up + """Tip Pick up Args: x_position: X Position [0.1mm]. @@ -2932,7 +3005,7 @@ async def pip_tip_discard( TODO_TR_2: int = 0, tip_handling_method: Optional[List[int]] = None, ): - """ Tip Discard + """Tip Discard Args: x_position: X Position [0.1mm]. @@ -3008,7 +3081,7 @@ async def search_for_teach_in_signal_in_x_direction( x_search_distance: int = 0, x_speed: int = 270, ): - """ Search for Teach in signal in X direction + """Search for Teach in signal in X direction Args: channel_index: Channel index. @@ -3037,7 +3110,7 @@ async def position_all_channels_in_y_direction( self, y_position: List[int], ): - """ Position all channels in Y direction + """Position all channels in Y direction Args: y_position: Y Position [0.1mm]. @@ -3058,7 +3131,7 @@ async def position_all_channels_in_z_direction( self, z_position: Optional[List[int]] = None, ): - """ Position all channels in Z direction + """Position all channels in Z direction Args: z_position: Z Position [0.1mm]. @@ -3080,7 +3153,7 @@ async def position_single_channel_in_y_direction( channel_index: int = 1, y_position: int = 3000, ): - """ Position single channel in Y direction + """Position single channel in Y direction Args: channel_index: Channel index. @@ -3105,7 +3178,7 @@ async def position_single_channel_in_z_direction( channel_index: int = 1, z_position: int = 0, ): - """ Position single channel in Z direction + """Position single channel in Z direction Args: channel_index: Channel index. @@ -3133,7 +3206,7 @@ async def move_to_defined_position( minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, z_position: Optional[List[int]] = None, ): - """ Move to defined position + """Move to defined position Args: tip_pattern: Tip pattern (channels involved). [0 = not involved, 1 = involved]. @@ -3185,7 +3258,7 @@ async def teach_rack_using_channel_n( gap_center_z_direction: int = 0, minimal_height_at_command_end: Optional[List[int]] = None, ): - """ Teach rack using channel n + """Teach rack using channel n Attention! Channels not involved must first be taken out of measurement range. @@ -3228,7 +3301,7 @@ async def expose_channel_n( self, channel_index: int = 1, ): - """ Expose channel n + """Expose channel n Args: channel_index: Channel index. @@ -3253,7 +3326,7 @@ async def calculates_check_sums_and_compares_them_with_the_value_saved_in_flash_ minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, first_pip_channel_node_no: int = 1, ): - """ Calculates check sums and compares them with the value saved in Flash EPROM + """Calculates check sums and compares them with the value saved in Flash EPROM Args: TODO_DC_0: (0). @@ -3318,7 +3391,7 @@ async def discard_core_gripper_tool( first_pip_channel_node_no: int = 1, minimal_height_at_command_end: Optional[List[int]] = None, ): - """ Discard CoRe gripper tool + """Discard CoRe gripper tool Args: gripper_tool_x_position: (0). @@ -3392,7 +3465,7 @@ async def grip_plate( minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, minimal_height_at_command_end: Optional[List[int]] = None, ): - """ Grip plate + """Grip plate Args: plate_center_x_direction: Plate center X direction [0.1mm]. @@ -3468,7 +3541,7 @@ async def put_plate( minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, minimal_height_at_command_end: Optional[List[int]] = None, ): - """ Put plate + """Put plate Args: plate_center_x_direction: Plate center X direction [0.1mm]. @@ -3531,7 +3604,7 @@ async def move_to_position( z_speed: int = 1287, minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, ): - """ Move to position + """Move to position Args: plate_center_x_direction: Plate center X direction [0.1mm]. @@ -3573,7 +3646,7 @@ async def release_object( self, first_pip_channel_node_no: int = 1, ): - """ Release object + """Release object Args: first_pip_channel_node_no: First (lower) pip. channel node no. (0 = disabled). @@ -3589,7 +3662,7 @@ async def release_object( ) async def set_any_parameter_within_this_module(self): - """ Set any parameter within this module """ + """Set any parameter within this module""" return await self.send_command( module="A1PM", @@ -3597,7 +3670,7 @@ async def set_any_parameter_within_this_module(self): ) async def request_y_positions_of_all_channels(self): - """ Request Y Positions of all channels """ + """Request Y Positions of all channels""" return await self.send_command( module="A1PM", @@ -3605,7 +3678,7 @@ async def request_y_positions_of_all_channels(self): ) async def request_y_position_of_channel_n(self, channel_index: int = 1): - """ Request Y Position of channel n """ + """Request Y Position of channel n""" return await self.send_command( module="A1PM", @@ -3614,7 +3687,7 @@ async def request_y_position_of_channel_n(self, channel_index: int = 1): ) async def request_z_positions_of_all_channels(self): - """ Request Z Positions of all channels """ + """Request Z Positions of all channels""" return await self.send_command( module="A1PM", @@ -3622,7 +3695,7 @@ async def request_z_positions_of_all_channels(self): ) async def request_z_position_of_channel_n(self, channel_index: int = 1): - """ Request Z Position of channel n """ + """Request Z Position of channel n""" return await self.send_command( module="A1PM", @@ -3631,14 +3704,14 @@ async def request_z_position_of_channel_n(self, channel_index: int = 1): ) async def query_tip_presence(self) -> List[bool]: - """ Query Tip presence """ + """Query Tip presence""" resp = await self.send_command(module="A1PM", command="QA", fmt={"rt": "[int]"}) presences_int = cast(List[int], resp["rt"]) return [bool(p) for p in presences_int] async def request_height_of_last_lld(self): - """ Request height of last LLD """ + """Request height of last LLD""" return await self.send_command( module="A1PM", @@ -3646,7 +3719,7 @@ async def request_height_of_last_lld(self): ) async def request_channel_dispense_on_fly_status(self): - """ Request channel dispense on fly status """ + """Request channel dispense on fly status""" return await self.send_command( module="A1PM", @@ -3654,7 +3727,7 @@ async def request_channel_dispense_on_fly_status(self): ) async def core96_request_initialization_status(self) -> bool: - """ Request CoRe96 initialization status + """Request CoRe96 initialization status This method is inferred from I1AM and A1AM commands ("QW"). @@ -3675,7 +3748,7 @@ async def core96_initialize( end_z_deposit_position: int = 0, tip_type: int = 4, ): - """ Initialize 96 head. + """Initialize 96 head. Args: x_position: X Position [0.1mm]. @@ -3756,7 +3829,7 @@ async def core96_aspiration_of_liquid( tadm_algorithm_on_off: int = 0, recording_mode: int = 0, ): - """ Aspiration of liquid using the 96 head. + """Aspiration of liquid using the 96 head. Args: type_of_aspiration: Type of aspiration (0 = simple 1 = sequence 2 = cup emptied). @@ -3819,8 +3892,10 @@ async def core96_aspiration_of_liquid( raise ValueError("liquid_surface_at_function_without_lld must be in range 0 to 3900") if not 0 <= pull_out_distance_to_take_transport_air_in_function_without_lld <= 3900: - raise ValueError("pull_out_distance_to_take_transport_air_in_function_without_lld must be in " - "range 0 to 3900") + raise ValueError( + "pull_out_distance_to_take_transport_air_in_function_without_lld must be in " + "range 0 to 3900" + ) if not 0 <= minimum_height <= 3900: raise ValueError("minimum_height must be in range 0 to 3900") @@ -3885,8 +3960,9 @@ async def core96_aspiration_of_liquid( if tadm_channel_pattern is None: tadm_channel_pattern = [True] * 96 elif not len(tadm_channel_pattern) < 24: - raise ValueError("tadm_channel_pattern must be of length 24, but is " - f"'{len(tadm_channel_pattern)}'") + raise ValueError( + "tadm_channel_pattern must be of length 24, but is " f"'{len(tadm_channel_pattern)}'" + ) tadm_channel_pattern_num = sum(2**i if tadm_channel_pattern[i] else 0 for i in range(96)) if not 0 <= tadm_algorithm_on_off <= 1: @@ -3967,7 +4043,7 @@ async def core96_dispensing_of_liquid( tadm_algorithm_on_off: int = 0, recording_mode: int = 0, ): - """ Dispensing of liquid using the 96 head. + """Dispensing of liquid using the 96 head. Args: type_of_dispensing_mode: Type of dispensing mode 0 = part in jet 1 = blow in jet 2 = Part at @@ -4037,8 +4113,10 @@ async def core96_dispensing_of_liquid( raise ValueError("liquid_surface_at_function_without_lld must be in range 0 to 3900") if not 0 <= pull_out_distance_to_take_transport_air_in_function_without_lld <= 3900: - raise ValueError("pull_out_distance_to_take_transport_air_in_function_without_lld must be in " - "range 0 to 3900") + raise ValueError( + "pull_out_distance_to_take_transport_air_in_function_without_lld must be in " + "range 0 to 3900" + ) if not -990 <= immersion_depth <= 990: raise ValueError("immersion_depth must be in range -990 to 990") @@ -4106,8 +4184,9 @@ async def core96_dispensing_of_liquid( if tadm_channel_pattern is None: tadm_channel_pattern = [True] * 96 elif not len(tadm_channel_pattern) < 24: - raise ValueError("tadm_channel_pattern must be of length 24, but is " - f"'{len(tadm_channel_pattern)}'") + raise ValueError( + "tadm_channel_pattern must be of length 24, but is " f"'{len(tadm_channel_pattern)}'" + ) tadm_channel_pattern_num = sum(2**i if tadm_channel_pattern[i] else 0 for i in range(96)) if not 0 <= tadm_algorithm_on_off <= 1: @@ -4164,7 +4243,7 @@ async def core96_tip_pick_up( minimal_traverse_height_at_begin_of_command: int = 3900, minimal_height_at_command_end: int = 3900, ): - """ Tip Pick up using the 96 head. + """Tip Pick up using the 96 head. Args: x_position: X Position [0.1mm]. @@ -4218,7 +4297,7 @@ async def core96_tip_discard( minimal_traverse_height_at_begin_of_command: int = 3900, minimal_height_at_command_end: int = 3900, ): - """ Tip Discard using the 96 head. + """Tip Discard using the 96 head. Args: x_position: X Position [0.1mm]. @@ -4261,7 +4340,7 @@ async def core96_move_to_defined_position( z_position: int = 0, minimal_traverse_height_at_begin_of_command: int = 3900, ): - """ Move to defined position using the 96 head. + """Move to defined position using the 96 head. Args: x_position: X Position [0.1mm]. @@ -4304,7 +4383,7 @@ async def core96_wash_tips( mix_cycles: int = 0, mix_speed: int = 2000, ): - """ Wash tips on the 96 head. + """Wash tips on the 96 head. Args: x_position: X Position [0.1mm]. @@ -4365,7 +4444,7 @@ async def core96_empty_washed_tips( liquid_surface_at_function_without_lld: int = 3900, minimal_height_at_command_end: int = 3900, ): - """ Empty washed tips (end of wash procedure only) on the 96 head. + """Empty washed tips (end of wash procedure only) on the 96 head. Args: liquid_surface_at_function_without_lld: Liquid surface at function without LLD [0.1mm]. @@ -4390,7 +4469,7 @@ async def core96_search_for_teach_in_signal_in_x_direction( x_search_distance: int = 0, x_speed: int = 50, ): - """ Search for Teach in signal in X direction on the 96 head. + """Search for Teach in signal in X direction on the 96 head. Args: x_search_distance: X search distance [0.1mm]. @@ -4411,7 +4490,7 @@ async def core96_search_for_teach_in_signal_in_x_direction( ) async def core96_set_any_parameter(self): - """ Set any parameter within the 96 head module. """ + """Set any parameter within the 96 head module.""" return await self.send_command( module="A1HM", @@ -4419,7 +4498,7 @@ async def core96_set_any_parameter(self): ) async def core96_query_tip_presence(self): - """ Query Tip presence on the 96 head. """ + """Query Tip presence on the 96 head.""" return await self.send_command( module="A1HM", @@ -4427,7 +4506,7 @@ async def core96_query_tip_presence(self): ) async def core96_request_position(self): - """ Request position of the 96 head. """ + """Request position of the 96 head.""" return await self.send_command( module="A1HM", @@ -4438,7 +4517,7 @@ async def core96_request_tadm_error_status( self, tadm_channel_pattern: Optional[List[bool]] = None, ): - """ Request TADM error status on the 96 head. + """Request TADM error status on the 96 head. Args: tadm_channel_pattern: TADM Channel pattern. @@ -4447,8 +4526,9 @@ async def core96_request_tadm_error_status( if tadm_channel_pattern is None: tadm_channel_pattern = [True] * 96 elif not len(tadm_channel_pattern) < 24: - raise ValueError("tadm_channel_pattern must be of length 24, but is " - f"'{len(tadm_channel_pattern)}'") + raise ValueError( + "tadm_channel_pattern must be of length 24, but is " f"'{len(tadm_channel_pattern)}'" + ) tadm_channel_pattern_num = sum(2**i if tadm_channel_pattern[i] else 0 for i in range(96)) return await self.send_command( @@ -4458,7 +4538,7 @@ async def core96_request_tadm_error_status( ) async def ipg_request_initialization_status(self) -> bool: - """ Request initialization status of IPG. + """Request initialization status of IPG. This command was based on the STAR command (QW) and the VStarTranslator log. A1AM corresponds to "arm". @@ -4467,15 +4547,11 @@ async def ipg_request_initialization_status(self) -> bool: True if the ipg module is initialized, False otherwise. """ - resp = await self.send_command( - module="A1RM", - command="QW", - fmt={"qw": "int"} - ) + resp = await self.send_command(module="A1RM", command="QW", fmt={"qw": "int"}) return resp is not None and resp["qw"] == 1 async def ipg_initialize(self): - """ Initialize IPG """ + """Initialize IPG""" return await self.send_command( module="A1RM", @@ -4483,7 +4559,7 @@ async def ipg_initialize(self): ) async def ipg_park(self): - """ Park IPG """ + """Park IPG""" return await self.send_command( module="A1RM", @@ -4491,7 +4567,7 @@ async def ipg_park(self): ) async def ipg_expose_channel_n(self): - """ Expose channel n """ + """Expose channel n""" return await self.send_command( module="A1RM", @@ -4499,7 +4575,7 @@ async def ipg_expose_channel_n(self): ) async def ipg_release_object(self): - """ Release object """ + """Release object""" return await self.send_command( module="A1RM", @@ -4511,7 +4587,7 @@ async def ipg_search_for_teach_in_signal_in_x_direction( x_search_distance: int = 0, x_speed: int = 50, ): - """ Search for Teach in signal in X direction + """Search for Teach in signal in X direction Args: x_search_distance: X search distance [0.1mm]. @@ -4545,7 +4621,7 @@ async def ipg_grip_plate( hotel_depth: int = 0, minimal_height_at_command_end: int = 3600, ): - """ Grip plate + """Grip plate Args: x_position: X Position [0.1mm]. @@ -4621,7 +4697,7 @@ async def ipg_put_plate( hotel_depth: int = 0, minimal_height_at_command_end: int = 3600, ): - """ Put plate + """Put plate Args: x_position: X Position [0.1mm]. @@ -4676,7 +4752,7 @@ async def ipg_prepare_gripper_orientation( grip_orientation: int = 32, minimal_traverse_height_at_begin_of_command: int = 3600, ): - """ Prepare gripper orientation + """Prepare gripper orientation Args: grip_orientation: Grip orientation. @@ -4704,7 +4780,7 @@ async def ipg_move_to_defined_position( z_position: int = 3600, minimal_traverse_height_at_begin_of_command: int = 3600, ): - """ Move to defined position + """Move to defined position Args: x_position: X Position [0.1mm]. @@ -4736,7 +4812,7 @@ async def ipg_move_to_defined_position( ) async def ipg_set_any_parameter_within_this_module(self): - """ Set any parameter within this module """ + """Set any parameter within this module""" return await self.send_command( module="A1RM", @@ -4744,17 +4820,13 @@ async def ipg_set_any_parameter_within_this_module(self): ) async def ipg_get_parking_status(self) -> bool: - """ Get parking status. Returns `True` if parked. """ + """Get parking status. Returns `True` if parked.""" - resp = await self.send_command( - module="A1RM", - command="RG", - fmt={"rg": "int"} - ) + resp = await self.send_command(module="A1RM", command="RG", fmt={"rg": "int"}) return resp is not None and resp["rg"] == 1 async def ipg_query_tip_presence(self): - """ Query Tip presence """ + """Query Tip presence""" return await self.send_command( module="A1RM", @@ -4762,7 +4834,7 @@ async def ipg_query_tip_presence(self): ) async def ipg_request_access_range(self, grip_orientation: int = 32): - """ Request access range + """Request access range Args: grip_orientation: Grip orientation. @@ -4778,7 +4850,7 @@ async def ipg_request_access_range(self, grip_orientation: int = 32): ) async def ipg_request_position(self, grip_orientation: int = 32): - """ Request position + """Request position Args: grip_orientation: Grip orientation. @@ -4794,7 +4866,7 @@ async def ipg_request_position(self, grip_orientation: int = 32): ) async def ipg_request_actual_angular_dimensions(self): - """ Request actual angular dimensions """ + """Request actual angular dimensions""" return await self.send_command( module="A1RM", @@ -4802,7 +4874,7 @@ async def ipg_request_actual_angular_dimensions(self): ) async def ipg_request_configuration(self): - """ Request configuration """ + """Request configuration""" return await self.send_command( module="A1RM", @@ -4810,7 +4882,7 @@ async def ipg_request_configuration(self): ) async def x_arm_initialize(self): - """ Initialize the x arm """ + """Initialize the x arm""" return await self.send_command(module="A1XM", command="XI") async def x_arm_move_to_x_position( @@ -4819,7 +4891,7 @@ async def x_arm_move_to_x_position( x_speed: int = 25000, TODO_XI_1: int = 1, ): - """ Move arm to X position + """Move arm to X position Args: x_position: X Position [0.1mm]. @@ -4844,7 +4916,7 @@ async def x_arm_move_to_x_position_with_all_attached_components_in_z_safety_posi x_speed: int = 25000, TODO_XA_1: int = 1, ): - """ Move arm to X position with all attached components in Z safety position + """Move arm to X position with all attached components in Z safety position Args: x_position: X Position [0.1mm]. @@ -4875,7 +4947,7 @@ async def x_arm_move_arm_relatively_in_x( x_speed: int = 25000, TODO_XS_1: int = 1, ): - """ Move arm relatively in X + """Move arm relatively in X Args: x_search_distance: X search distance [0.1mm]. @@ -4906,7 +4978,7 @@ async def x_arm_search_x_for_teach_signal( x_speed: int = 25000, TODO_XT_1: int = 1, ): - """ Search X for teach signal + """Search X for teach signal Args: x_search_distance: X search distance [0.1mm]. @@ -4935,7 +5007,7 @@ async def x_arm_set_x_drive_angle_of_alignment( self, TODO_XL_1: int = 1, ): - """ Set X drive angle of alignment + """Set X drive angle of alignment Args: TODO_XL_1: (0). @@ -4957,7 +5029,7 @@ async def x_arm_send_message_to_motion_controller( self, TODO_BD_1: str = "", ): - """ Send message to motion controller + """Send message to motion controller Args: TODO_BD_1: (0). @@ -4974,7 +5046,7 @@ async def x_arm_set_any_parameter_within_this_module( TODO_AA_1: int = 0, TODO_AA_2: int = 1, ): - """ Set any parameter within this module + """Set any parameter within this module Args: TODO_AA_1: (0). @@ -4989,12 +5061,12 @@ async def x_arm_set_any_parameter_within_this_module( ) async def x_arm_request_arm_x_position(self): - """ Request arm X position. This returns a list, of which the first value is one that can be - used with x_arm_move_to_x_position. """ + """Request arm X position. This returns a list, of which the first value is one that can be + used with x_arm_move_to_x_position.""" return await self.send_command(module="A1XM", command="RX") async def x_arm_request_error_code(self): - """ X arm request error code """ + """X arm request error code""" return await self.send_command(module="A1XM", command="RE") async def x_arm_request_x_drive_recorded_data( @@ -5002,7 +5074,7 @@ async def x_arm_request_x_drive_recorded_data( TODO_QL_1: int = 0, TODO_QL_2: int = 0, ): - """ Request X drive recorded data + """Request X drive recorded data Args: TODO_QL_1: (0). @@ -5017,16 +5089,18 @@ async def x_arm_request_x_drive_recorded_data( ) async def disco_mode(self): - """ Easter egg. """ + """Easter egg.""" for _ in range(69): r, g, b = random.randint(30, 100), random.randint(30, 100), random.randint(30, 100) await self.set_led_color("on", intensity=100, white=0, red=r, green=g, blue=b, uv=0) await asyncio.sleep(0.1) async def russian_roulette(self): - """ Dangerous easter egg. """ - sure = input("Are you sure you want to play Russian Roulette? This will turn on the uv-light " - "with a probability of 1/6. (yes/no) ") + """Dangerous easter egg.""" + sure = input( + "Are you sure you want to play Russian Roulette? This will turn on the uv-light " + "with a probability of 1/6. (yes/no) " + ) if sure.lower() != "yes": print("boring") return diff --git a/pylabrobot/liquid_handling/backends/hamilton/vantage_tests.py b/pylabrobot/liquid_handling/backends/hamilton/vantage_tests.py index 9552d6c1b2..53fa50e46f 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/vantage_tests.py +++ b/pylabrobot/liquid_handling/backends/hamilton/vantage_tests.py @@ -1,14 +1,20 @@ -from typing import Any, List, Optional import unittest +from typing import Any, List, Optional from pylabrobot.liquid_handling import LiquidHandler from pylabrobot.liquid_handling.liquid_classes.hamilton.vantage import ( - HighVolumeFilter_Water_DispenseSurface_Part, + HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty, HighVolumeFilter_Water_DispenseSurface_Empty, - HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty) + HighVolumeFilter_Water_DispenseSurface_Part, +) from pylabrobot.liquid_handling.standard import Pickup from pylabrobot.resources import ( - Coordinate, TIP_CAR_480_A00, PLT_CAR_L5AC_A00, HT_L, LT_L, Cor_96_wellplate_360ul_Fb, + HT_L, + LT_L, + PLT_CAR_L5AC_A00, + TIP_CAR_480_A00, + Coordinate, + Cor_96_wellplate_360ul_Fb, ) from pylabrobot.resources.hamilton import VantageDeck @@ -16,38 +22,118 @@ Vantage, VantageFirmwareError, parse_vantage_fw_string, - vantage_response_string_to_error + vantage_response_string_to_error, ) - -PICKUP_TIP_FORMAT = {"xp": "[int]", "yp": "[int]", "tm": "[int]", "tt": "[int]", "tp": "[int]", - "tz": "[int]", "th": "[int]", "ba": "[int]", "td": "[int]"} - -DROP_TIP_FORMAT = {"xp": "[int]", "yp": "[int]", "tm": "[int]", "tp": "[int]", "tz": "[int]", - "th": "[int]", "te": "[int]", "ts": "[int]", "td": "[int]"} +PICKUP_TIP_FORMAT = { + "xp": "[int]", + "yp": "[int]", + "tm": "[int]", + "tt": "[int]", + "tp": "[int]", + "tz": "[int]", + "th": "[int]", + "ba": "[int]", + "td": "[int]", +} + +DROP_TIP_FORMAT = { + "xp": "[int]", + "yp": "[int]", + "tm": "[int]", + "tp": "[int]", + "tz": "[int]", + "th": "[int]", + "te": "[int]", + "ts": "[int]", + "td": "[int]", +} # "dj": "int" = side_touch_off_distance, only documented for dispense, but for some reason VoV also # sends it for aspirate. ASPIRATE_FORMAT = { - "at": "[int]", "tm": "[int]", "xp": "[int]", "yp": "[int]", "th": "[int]", "te": "[int]", - "lp": "[int]", "ch": "[int]", "zl": "[int]", "zx": "[int]", "ip": "[int]", "fp": "[int]", - "av": "[int]", "as": "[int]", "ta": "[int]", "ba": "[int]", "oa": "[int]", "lm": "[int]", - "ll": "[int]", "lv": "[int]", "de": "[int]", "wt": "[int]", "mv": "[int]", "mc": "[int]", - "mp": "[int]", "ms": "[int]", "gi": "[int]", "gj": "[int]", "gk": "[int]", "zu": "[int]", - "zr": "[int]", "mh": "[int]", "zo": "[int]", "po": "[int]", "la": "[int]", - "lb": "[int]", "lc": "[int]", "id": "int" } + "at": "[int]", + "tm": "[int]", + "xp": "[int]", + "yp": "[int]", + "th": "[int]", + "te": "[int]", + "lp": "[int]", + "ch": "[int]", + "zl": "[int]", + "zx": "[int]", + "ip": "[int]", + "fp": "[int]", + "av": "[int]", + "as": "[int]", + "ta": "[int]", + "ba": "[int]", + "oa": "[int]", + "lm": "[int]", + "ll": "[int]", + "lv": "[int]", + "de": "[int]", + "wt": "[int]", + "mv": "[int]", + "mc": "[int]", + "mp": "[int]", + "ms": "[int]", + "gi": "[int]", + "gj": "[int]", + "gk": "[int]", + "zu": "[int]", + "zr": "[int]", + "mh": "[int]", + "zo": "[int]", + "po": "[int]", + "la": "[int]", + "lb": "[int]", + "lc": "[int]", + "id": "int", +} DISPENSE_FORMAT = { - "dm": "[int]", "tm": "[int]", "xp": "[int]", "yp": "[int]", "zx": "[int]", "lp": "[int]", - "zl": "[int]", "ip": "[int]", "fp": "[int]", "th": "[int]", "te": "[int]", "dv": "[int]", - "ds": "[int]", "ss": "[int]", "rv": "[int]", "ta": "[int]", "ba": "[int]", "lm": "[int]", - "zo": "[int]", "ll": "[int]", "lv": "[int]", "de": "[int]", "mv": "[int]", "mc": "[int]", - "mp": "[int]", "ms": "[int]", "wt": "[int]", "gi": "[int]", "gj": "[int]", "gk": "[int]", - "zu": "[int]", "zr": "[int]", "dj": "[int]", "mh": "[int]", "po": "[int]", "la": "[int]"} + "dm": "[int]", + "tm": "[int]", + "xp": "[int]", + "yp": "[int]", + "zx": "[int]", + "lp": "[int]", + "zl": "[int]", + "ip": "[int]", + "fp": "[int]", + "th": "[int]", + "te": "[int]", + "dv": "[int]", + "ds": "[int]", + "ss": "[int]", + "rv": "[int]", + "ta": "[int]", + "ba": "[int]", + "lm": "[int]", + "zo": "[int]", + "ll": "[int]", + "lv": "[int]", + "de": "[int]", + "mv": "[int]", + "mc": "[int]", + "mp": "[int]", + "ms": "[int]", + "wt": "[int]", + "gi": "[int]", + "gj": "[int]", + "gk": "[int]", + "zu": "[int]", + "zr": "[int]", + "dj": "[int]", + "mh": "[int]", + "po": "[int]", + "la": "[int]", +} class TestVantageResponseParsing(unittest.TestCase): - """ Test parsing of response from Hamilton. """ + """Test parsing of response from Hamilton.""" def test_parse_response_params(self): parsed = parse_vantage_fw_string("A1PMDAid1111", None) @@ -56,7 +142,7 @@ def test_parse_response_params(self): parsed = parse_vantage_fw_string("A1PMDAid1111", {"id": "int"}) self.assertEqual(parsed, {"id": 1111}) - parsed = parse_vantage_fw_string("A1PMDAid1112rw\"abc\"", {"rw": "str"}) + parsed = parse_vantage_fw_string('A1PMDAid1112rw"abc"', {"rw": "str"}) self.assertEqual(parsed, {"id": 1112, "rw": "abc"}) parsed = parse_vantage_fw_string("A1PMDAid1112rw-21", {"rw": "int"}) @@ -77,43 +163,48 @@ def test_parse_response_params(self): parse_vantage_fw_string("A1PMDA", {"id": "int"}) def test_parse_error_response(self): - resp = "I1AMRQid0000er4et\"Slave not available\"" + resp = 'I1AMRQid0000er4et"Slave not available"' error = vantage_response_string_to_error(resp) - self.assertEqual(error, VantageFirmwareError( - errors={"Cover": "Slave not available"}, - raw_response=resp)) + self.assertEqual( + error, VantageFirmwareError(errors={"Cover": "Slave not available"}, raw_response=resp) + ) - resp = "I1AMLPid215er57et\"S-Drive: Drive not initialized\"" + resp = 'I1AMLPid215er57et"S-Drive: Drive not initialized"' error = vantage_response_string_to_error(resp) - self.assertEqual(error, VantageFirmwareError( - errors={"Cover": "S-Drive: Drive not initialized"}, - raw_response=resp)) + self.assertEqual( + error, + VantageFirmwareError(errors={"Cover": "S-Drive: Drive not initialized"}, raw_response=resp), + ) - resp = "A1HMDAid239er99es\"H070\"" + resp = 'A1HMDAid239er99es"H070"' error = vantage_response_string_to_error(resp) - self.assertEqual(error, VantageFirmwareError( - errors={"Core 96": "No liquid level found"}, - raw_response=resp)) + self.assertEqual( + error, VantageFirmwareError(errors={"Core 96": "No liquid level found"}, raw_response=resp) + ) - resp = "A1PMDAid262er99es\"P170 P270 P370 P470 P570 P670 P770 P870\"" + resp = 'A1PMDAid262er99es"P170 P270 P370 P470 P570 P670 P770 P870"' error = vantage_response_string_to_error(resp) - self.assertEqual(error, VantageFirmwareError( - errors={ - "Pipetting channel 1": "No liquid level found", - "Pipetting channel 2": "No liquid level found", - "Pipetting channel 3": "No liquid level found", - "Pipetting channel 4": "No liquid level found", - "Pipetting channel 5": "No liquid level found", - "Pipetting channel 6": "No liquid level found", - "Pipetting channel 7": "No liquid level found", - "Pipetting channel 8": "No liquid level found", - }, - raw_response=resp)) + self.assertEqual( + error, + VantageFirmwareError( + errors={ + "Pipetting channel 1": "No liquid level found", + "Pipetting channel 2": "No liquid level found", + "Pipetting channel 3": "No liquid level found", + "Pipetting channel 4": "No liquid level found", + "Pipetting channel 5": "No liquid level found", + "Pipetting channel 6": "No liquid level found", + "Pipetting channel 7": "No liquid level found", + "Pipetting channel 8": "No liquid level found", + }, + raw_response=resp, + ), + ) class VantageCommandCatcher(Vantage): - """ Mock backend for Vantage that catches commands and saves them instead of sending them to the - machine. """ + """Mock backend for Vantage that catches commands and saves them instead of sending them to the + machine.""" def __init__(self): super().__init__() @@ -132,9 +223,9 @@ async def send_command( tip_pattern: Optional[List[bool]] = None, write_timeout: Optional[int] = None, read_timeout: Optional[int] = None, - wait = True, + wait=True, fmt: Optional[Any] = None, - **kwargs + **kwargs, ): cmd, _ = self._assemble_command(module, command, tip_pattern, **kwargs) self.commands.append(cmd) @@ -144,7 +235,7 @@ async def stop(self): class TestVantageLiquidHandlerCommands(unittest.IsolatedAsyncioTestCase): - """ Test Vantage backend for liquid handling. """ + """Test Vantage backend for liquid handling.""" async def asyncSetUp(self): # pylint: disable=invalid-name @@ -170,7 +261,7 @@ async def asyncTearDown(self): await self.lh.stop() def _assert_command_in_command_buffer(self, cmd: str, should_be: bool, fmt: dict): - """ Assert that the given command was sent to the backend. The ordering of the parameters is not + """Assert that the given command was sent to the backend. The ordering of the parameters is not taken into account, but the values and formatting should match. The id parameter of the command is ignored. @@ -219,7 +310,7 @@ def _assert_command_in_command_buffer(self, cmd: str, should_be: bool, fmt: dict self.fail(f"Command {cmd} was found in sent commands: {self.mockVantage.commands}") def test_ops_to_fw_positions(self): - """ Convert channel positions to firmware positions. """ + """Convert channel positions to firmware positions.""" # pylint: disable=protected-access tip_a1 = self.tip_rack.get_item("A1") tip_f1 = self.tip_rack.get_item("F1") @@ -229,21 +320,21 @@ def test_ops_to_fw_positions(self): op2 = Pickup(resource=tip_f1, tip=tip, offset=Coordinate.zero()) self.assertEqual( self.mockVantage._ops_to_fw_positions((op1,), use_channels=[0]), - ([4329, 0], [1458, 0], [True, False]) + ([4329, 0], [1458, 0], [True, False]), ) self.assertEqual( self.mockVantage._ops_to_fw_positions((op1, op2), use_channels=[0, 1]), - ([4329, 4329, 0], [1458, 1008, 0], [True, True, False]) + ([4329, 4329, 0], [1458, 1008, 0], [True, True, False]), ) self.assertEqual( self.mockVantage._ops_to_fw_positions((op1, op2), use_channels=[1, 2]), - ([0, 4329, 4329, 0], [0, 1458, 1008, 0], [False, True, True, False]) + ([0, 4329, 4329, 0], [0, 1458, 1008, 0], [False, True, True, False]), ) def _assert_command_sent_once(self, cmd: str, fmt: dict): - """ Assert that the given command was sent to the backend exactly once. """ + """Assert that the given command was sent to the backend exactly once.""" self._assert_command_in_command_buffer(cmd, True, fmt) self._assert_command_in_command_buffer(cmd, False, fmt) @@ -255,31 +346,34 @@ async def test_tip_pickup_01(self): self._assert_command_sent_once( "A1PMTPid0012xp4329 4329 0&yp1458 1368 0&tm1 1 0&tt1 1&tp2266 2266&tz2166 2166&th2450 2450&" "te2450 2450&ba0 0&td1 1&", - PICKUP_TIP_FORMAT) + PICKUP_TIP_FORMAT, + ) async def test_tip_drop_01(self): - await self.test_tip_pickup_01() # pick up tips first + await self.test_tip_pickup_01() # pick up tips first await self.lh.drop_tips(self.tip_rack["A1", "B1"]) self._assert_command_sent_once( "A1PMTRid013xp04329 04329 0&yp1458 1368 0&tm1 1 0&tp1414 1414&tz1314 1314&th2450 2450&" "te2450 2450&ts0td0 0&", - DROP_TIP_FORMAT) + DROP_TIP_FORMAT, + ) async def test_small_tip_pickup(self): await self.lh.pick_up_tips(self.small_tip_rack["A1"]) self._assert_command_sent_once( "A1PMTPid0010xp4329 0&yp2418 0&tm1 0&tt1&tp2224&tz2164&th2450&te2450&ba0&td1&", - PICKUP_TIP_FORMAT) + PICKUP_TIP_FORMAT, + ) async def test_small_tip_drop(self): - await self.test_small_tip_pickup() # pick up tips first + await self.test_small_tip_pickup() # pick up tips first await self.lh.drop_tips(self.small_tip_rack["A1"]) self._assert_command_sent_once( - "A1PMTRid0012xp4329 0&yp2418 0&tp2024&tz1924&th2450&te2450&tm1 0&ts0td0&", - DROP_TIP_FORMAT) + "A1PMTRid0012xp4329 0&yp2418 0&tp2024&tz1924&th2450&te2450&tm1 0&ts0td0&", DROP_TIP_FORMAT + ) async def test_aspirate(self): - await self.lh.pick_up_tips(self.tip_rack["A1"]) # pick up tips first + await self.lh.pick_up_tips(self.tip_rack["A1"]) # pick up tips first hlc = HighVolumeFilter_Water_DispenseSurface_Part corrected_volume = hlc.compute_corrected_volume(100) await self.lh.aspirate(self.plate["A1"], vols=[corrected_volume], **hlc.make_asp_kwargs(1)) @@ -289,25 +383,33 @@ async def test_aspirate(self): "ch000&zl1866&zx1866&ip0000&fp0000&av010830&as2500&ta000&ba00000&oa000&lm0&ll4&lv4&de0020&" "wt10&mv00000&mc00&mp000&ms1200&gi000&gj0gk0zu0000&zr00000&mh0000&zo005&po0109&dj0la0&lb0&" "lc0&", - ASPIRATE_FORMAT) + ASPIRATE_FORMAT, + ) async def test_dispense(self): - await self.lh.pick_up_tips(self.tip_rack["A1"]) # pick up tips first + await self.lh.pick_up_tips(self.tip_rack["A1"]) # pick up tips first hlc = HighVolumeFilter_Water_DispenseSurface_Empty corrected_volume = hlc.compute_corrected_volume(100) await self.lh.aspirate(self.plate["A1"], vols=[corrected_volume], **hlc.make_asp_kwargs(1)) - await self.lh.dispense(self.plate["A2"], vols=[corrected_volume], liquid_height=[5], - jet=[False], blow_out=[True], **hlc.make_disp_kwargs(1)) + await self.lh.dispense( + self.plate["A2"], + vols=[corrected_volume], + liquid_height=[5], + jet=[False], + blow_out=[True], + **hlc.make_disp_kwargs(1), + ) self._assert_command_sent_once( "A1PMDDid0253dm3&tm1 0&xp05773 0&yp1457 0&zx1866&lp1990&zl1916&" "ip0000&fp0021&th2450&te2450&dv010830&ds1200&ss2500&rv000&ta050&ba00000&lm0&zo005&ll1&lv1&" "de0020&mv00000&mc00&mp000&ms1200&wt00&gi000&gj0gk0zu0000&dj00zr00000&mh0000&po0050&la0&", - DISPENSE_FORMAT) + DISPENSE_FORMAT, + ) async def test_zero_volume_liquid_handling(self): - # just test that this does not throw an error - await self.lh.pick_up_tips(self.tip_rack["A1"]) # pick up tips first + # just test that this does not throw an error + await self.lh.pick_up_tips(self.tip_rack["A1"]) # pick up tips first await self.lh.aspirate(self.plate["A1"], vols=[0]) await self.lh.dispense(self.plate["A2"], vols=[0]) @@ -315,46 +417,112 @@ async def test_tip_pickup96(self): await self.lh.pick_up_tips96(self.tip_rack) self._assert_command_sent_once( "A1HMTPid0237xp04329yp1458tt01td0tz2164th2450te2450", - {"xp": "int", "yp": "int", "tt": "int", "td": "int", "tz": "int", "th": "int", "te": "int"}) + {"xp": "int", "yp": "int", "tt": "int", "td": "int", "tz": "int", "th": "int", "te": "int"}, + ) async def test_tip_drop96(self): await self.lh.pick_up_tips96(self.tip_rack) await self.lh.drop_tips96(self.tip_rack) self._assert_command_sent_once( "A1HMTRid0284xp04329yp1458tz2164th2450te2450", - {"xp": "int", "yp": "int", "tz": "int", "th": "int", "te": "int"}) + {"xp": "int", "yp": "int", "tz": "int", "th": "int", "te": "int"}, + ) async def test_aspirate96(self): await self.lh.pick_up_tips96(self.tip_rack) hlc = HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty - await self.lh.aspirate96(self.plate, volume=hlc.compute_corrected_volume(100), - **hlc.make_asp96_kwargs()) + await self.lh.aspirate96( + self.plate, volume=hlc.compute_corrected_volume(100), **hlc.make_asp96_kwargs() + ) self._assert_command_sent_once( "A1HMDAid0236at0xp05683yp1457th2450te2450lp1990zl1866zx1866ip000fp000av010920as2500ta050" "ba004000oa00000lm0ll4de0020wt10mv00000mc00mp000ms2500zu0000zr00000mh000gj0gk0gi000" "cwFFFFFFFFFFFFFFFFFFFFFFFFpo0050", - {"xp": "int", "yp": "int", "th": "int", "te": "int", "lp": "int", "zl": "int", "zx": "int", - "ip": "int", "fp": "int", "av": "int", "as": "int", "ta": "int", "ba": "int", "oa": "int", - "lm": "int", "ll": "int", "de": "int", "wt": "int", "mv": "int", "mc": "int", "mp": "int", - "zu": "int", "zr": "int", "mh": "int", "gj": "int", "gk": "int", "gi": "int", "cw": "hex", - "po": "int"}) + { + "xp": "int", + "yp": "int", + "th": "int", + "te": "int", + "lp": "int", + "zl": "int", + "zx": "int", + "ip": "int", + "fp": "int", + "av": "int", + "as": "int", + "ta": "int", + "ba": "int", + "oa": "int", + "lm": "int", + "ll": "int", + "de": "int", + "wt": "int", + "mv": "int", + "mc": "int", + "mp": "int", + "zu": "int", + "zr": "int", + "mh": "int", + "gj": "int", + "gk": "int", + "gi": "int", + "cw": "hex", + "po": "int", + }, + ) async def test_dispense96(self): await self.lh.pick_up_tips96(self.tip_rack) hlc = HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty - await self.lh.aspirate96(self.plate, volume=hlc.compute_corrected_volume(100), - **hlc.make_asp96_kwargs()) - await self.lh.dispense96(self.plate, volume=hlc.compute_corrected_volume(100), - jet=True, blow_out=True, **hlc.make_disp96_kwargs()) + await self.lh.aspirate96( + self.plate, volume=hlc.compute_corrected_volume(100), **hlc.make_asp96_kwargs() + ) + await self.lh.dispense96( + self.plate, + volume=hlc.compute_corrected_volume(100), + jet=True, + blow_out=True, + **hlc.make_disp96_kwargs(), + ) self._assert_command_sent_once( "A1HMDDid0238dm1xp05683yp1457th2450te2450lp1990zl1966zx1866ip000fp029dv10920ds4000ta050" "ba004000lm0ll4de0010wt00mv00000mc00mp000ms0010ss2500rv000zu0000dj00zr00000mh000gj0gk0gi000" "cwFFFFFFFFFFFFFFFFFFFFFFFFpo0050", - {"xp": "int", "yp": "int", "th": "int", "te": "int", "lp": "int", "zl": "int", "zx": "int", - "ip": "int", "fp": "int", "dv": "int", "ds": "int", "ta": "int", "ba": "int", "lm": "int", - "ll": "int", "de": "int", "wt": "int", "mv": "int", "mc": "int", "mp": "int", "ms": "int", - "ss": "int", "rv": "int", "zu": "int", "zr": "int", "dj": "int", "mh": "int", "gj": "int", - "gk": "int", "gi": "int", "cw": "hex", "po": "int"}) + { + "xp": "int", + "yp": "int", + "th": "int", + "te": "int", + "lp": "int", + "zl": "int", + "zx": "int", + "ip": "int", + "fp": "int", + "dv": "int", + "ds": "int", + "ta": "int", + "ba": "int", + "lm": "int", + "ll": "int", + "de": "int", + "wt": "int", + "mv": "int", + "mc": "int", + "mp": "int", + "ms": "int", + "ss": "int", + "rv": "int", + "zu": "int", + "zr": "int", + "dj": "int", + "mh": "int", + "gj": "int", + "gk": "int", + "gi": "int", + "cw": "hex", + "po": "int", + }, + ) async def test_zero_volume_liquid_handling96(self): # just test that this does not throw an error @@ -363,15 +531,27 @@ async def test_zero_volume_liquid_handling96(self): await self.lh.dispense96(self.plate, volume=0) async def test_move_plate(self): - await self.lh.move_plate(self.plate, self.plt_car[1], pickup_distance_from_top=5.2-3.33) + await self.lh.move_plate(self.plate, self.plt_car[1], pickup_distance_from_top=5.2 - 3.33) # pickup self._assert_command_sent_once( "A1RMDGid0240xp6179yp1142zp1954yw81yo1310yg1245pt20zc0hd0te2840", - {"xp": "int", "yp": "int", "zp": "int", "yw": "int", "yo": "int", "yg": "int", "pt": "int", - "zc": "int", "hd": "int", "te": "int"}) + { + "xp": "int", + "yp": "int", + "zp": "int", + "yw": "int", + "yo": "int", + "yg": "int", + "pt": "int", + "zc": "int", + "hd": "int", + "te": "int", + }, + ) # release self._assert_command_sent_once( "A1RMDRid0242xp6179yp2102zp1954yo1310zc0hd0te2840", - {"xp": "int", "yp": "int", "zp": "int", "yo": "int", "zc": "int", "hd": "int", "te": "int"}) + {"xp": "int", "yp": "int", "zp": "int", "yo": "int", "zc": "int", "hd": "int", "te": "int"}, + ) diff --git a/pylabrobot/liquid_handling/liquid_classes/hamilton/star.py b/pylabrobot/liquid_handling/liquid_classes/hamilton/star.py index acb955a926..a774d354ea 100644 --- a/pylabrobot/liquid_handling/liquid_classes/hamilton/star.py +++ b/pylabrobot/liquid_handling/liquid_classes/hamilton/star.py @@ -2,19 +2,29 @@ from typing import Dict, Tuple -from pylabrobot.resources.liquid import Liquid from pylabrobot.liquid_handling.liquid_classes.hamilton.base import HamiltonLiquidClass - +from pylabrobot.resources.liquid import Liquid star_mapping: Dict[Tuple[int, bool, bool, bool, Liquid, bool, bool], HamiltonLiquidClass] = {} + def get_star_liquid_class(**kwargs): raise NotImplementedError("Deprecated, use HamiltonLiquidClass directly") -star_mapping[(1000, False, False, False, Liquid.WATER, True, True)] = \ -_1000ulNeedleCRWater_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 520.0, 50.0: 61.2, 0.0: 0.0, 20.0: 22.5, 100.0: 113.0, 10.0: 11.1, 200.0: 214.0, 1000.0: 1032.0}, +star_mapping[(1000, False, False, False, Liquid.WATER, True, True)] = ( + _1000ulNeedleCRWater_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 520.0, + 50.0: 61.2, + 0.0: 0.0, + 20.0: 22.5, + 100.0: 113.0, + 10.0: 11.1, + 200.0: 214.0, + 1000.0: 1032.0, + }, aspiration_flow_rate=500.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=0.0, @@ -31,12 +41,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = \ -_1000ulNeedleCRWater_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = ( + _1000ulNeedleCRWater_DispenseJet_Part +) = HamiltonLiquidClass( curve={500.0: 520.0, 50.0: 62.2, 0.0: 0.0, 20.0: 32.0, 100.0: 115.5, 1000.0: 1032.0}, aspiration_flow_rate=500.0, aspiration_mix_flow_rate=500.0, @@ -54,13 +65,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # -star_mapping[(1000, False, False, False, Liquid.WATER, False, True)] = \ -_1000ulNeedleCRWater_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(1000, False, False, False, Liquid.WATER, False, True)] = ( + _1000ulNeedleCRWater_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={50.0: 59.0, 0.0: 0.0, 20.0: 25.9, 10.0: 12.9, 1000.0: 1000.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -78,13 +90,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # -star_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = \ -_1000ulNeedleCRWater_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = ( + _1000ulNeedleCRWater_DispenseSurface_Part +) = HamiltonLiquidClass( curve={50.0: 55.0, 0.0: 0.0, 20.0: 25.9, 10.0: 12.9, 1000.0: 1000.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -102,7 +115,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -120,9 +133,18 @@ def get_star_liquid_class(**kwargs): # 200 1.25 - 0.51 # 500 0.91 0.02 # 1000 0.66 - 0.46 -star_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = \ -_1000ulNeedle_Water_DispenseJet = HamiltonLiquidClass( - curve={500.0: 530.0, 50.0: 56.0, 0.0: 0.0, 100.0: 110.0, 20.0: 22.5, 1000.0: 1055.0, 200.0: 214.0}, +star_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = ( + _1000ulNeedle_Water_DispenseJet +) = HamiltonLiquidClass( + curve={ + 500.0: 530.0, + 50.0: 56.0, + 0.0: 0.0, + 100.0: 110.0, + 20.0: 22.5, + 1000.0: 1055.0, + 200.0: 214.0, + }, aspiration_flow_rate=500.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=0.0, @@ -139,7 +161,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=0.4, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -158,8 +180,9 @@ def get_star_liquid_class(**kwargs): # 20 10.12 - 4.66 # 50 3.79 - 1.18 # -star_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = \ -_1000ulNeedle_Water_DispenseSurface = HamiltonLiquidClass( +star_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = ( + _1000ulNeedle_Water_DispenseSurface +) = HamiltonLiquidClass( curve={50.0: 59.0, 0.0: 0.0, 20.0: 25.9, 1000.0: 1000.0}, aspiration_flow_rate=500.0, aspiration_mix_flow_rate=500.0, @@ -177,12 +200,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=0.4, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, False, False, Liquid.WATER, False, True)] = \ -_10ulNeedleCRWater_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(10, False, False, False, Liquid.WATER, False, True)] = ( + _10ulNeedleCRWater_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.7, 0.5: 0.5, 0.0: 0.0, 1.0: 1.2, 2.0: 2.4, 10.0: 11.4}, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, @@ -200,12 +224,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, False, False, Liquid.WATER, False, False)] = \ -_10ulNeedleCRWater_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(10, False, False, False, Liquid.WATER, False, False)] = ( + _10ulNeedleCRWater_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.7, 0.5: 0.5, 0.0: 0.0, 1.0: 1.2, 2.0: 2.4, 10.0: 11.4}, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, @@ -223,12 +248,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, True, Liquid.DMSO, True, False)] = \ -_150ul_Piercing_Tip_Filter_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.DMSO, True, False)] = ( + _150ul_Piercing_Tip_Filter_DMSO_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={150.0: 150.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=180.0, aspiration_mix_flow_rate=100.0, @@ -246,12 +272,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, True, Liquid.DMSO, True, True)] = \ -_150ul_Piercing_Tip_Filter_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.DMSO, True, True)] = ( + _150ul_Piercing_Tip_Filter_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={150.0: 154.0, 50.0: 52.9, 0.0: 0.0, 20.0: 21.8}, aspiration_flow_rate=180.0, aspiration_mix_flow_rate=100.0, @@ -269,12 +296,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, True, Liquid.DMSO, False, True)] = \ -_150ul_Piercing_Tip_Filter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.DMSO, False, True)] = ( + _150ul_Piercing_Tip_Filter_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={3.0: 4.5, 5.0: 6.5, 150.0: 155.0, 50.0: 53.7, 0.0: 0.0, 10.0: 12.0, 2.0: 3.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -292,7 +320,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -313,8 +341,9 @@ def get_star_liquid_class(**kwargs): # 100 1.67 -0.35 # 300 0.46 -0.61 # -star_mapping[(50, False, True, True, Liquid.ETHANOL, True, True)] = \ -_150ul_Piercing_Tip_Filter_Ethanol_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.ETHANOL, True, True)] = ( + _150ul_Piercing_Tip_Filter_Ethanol_DispenseJet_Empty +) = HamiltonLiquidClass( curve={150.0: 166.0, 50.0: 58.3, 0.0: 0.0, 20.0: 25.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=50.0, @@ -332,7 +361,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -354,8 +383,9 @@ def get_star_liquid_class(**kwargs): # 20 0.95 2.97 # 50 0.31 -0.10 # -star_mapping[(50, False, True, True, Liquid.ETHANOL, False, True)] = \ -_150ul_Piercing_Tip_Filter_Ethanol_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.ETHANOL, False, True)] = ( + _150ul_Piercing_Tip_Filter_Ethanol_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={3.0: 5.0, 5.0: 7.6, 150.0: 165.0, 50.0: 56.9, 0.0: 0.0, 10.0: 13.2, 2.0: 3.3}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -373,7 +403,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -396,8 +426,9 @@ def get_star_liquid_class(**kwargs): # 300 1.08 -0.87 # # -star_mapping[(50, False, True, True, Liquid.GLYCERIN80, False, True)] = \ -_150ul_Piercing_Tip_Filter_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.GLYCERIN80, False, True)] = ( + _150ul_Piercing_Tip_Filter_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={3.0: 4.5, 5.0: 7.2, 150.0: 167.5, 50.0: 60.0, 0.0: 0.0, 1.0: 2.7, 10.0: 13.0, 2.0: 2.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -415,7 +446,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -435,8 +466,9 @@ def get_star_liquid_class(**kwargs): # 100 0.81 0.99 # 300 1.00 0.65 # -star_mapping[(50, False, True, True, Liquid.SERUM, True, True)] = \ -_150ul_Piercing_Tip_Filter_Serum_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.SERUM, True, True)] = ( + _150ul_Piercing_Tip_Filter_Serum_DispenseJet_Empty +) = HamiltonLiquidClass( curve={150.0: 162.0, 50.0: 55.9, 0.0: 0.0, 20.0: 23.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -454,7 +486,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -477,8 +509,9 @@ def get_star_liquid_class(**kwargs): # 50 1.39 -0.12 # # -star_mapping[(50, False, True, True, Liquid.SERUM, False, True)] = \ -_150ul_Piercing_Tip_Filter_Serum_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.SERUM, False, True)] = ( + _150ul_Piercing_Tip_Filter_Serum_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={3.0: 3.4, 5.0: 5.9, 150.0: 161.5, 50.0: 56.2, 0.0: 0.0, 10.0: 11.6, 2.0: 2.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -496,12 +529,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, True, Liquid.WATER, True, False)] = \ -_150ul_Piercing_Tip_Filter_Water_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.WATER, True, False)] = ( + _150ul_Piercing_Tip_Filter_Water_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={150.0: 150.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -519,13 +553,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -star_mapping[(50, False, True, True, Liquid.WATER, True, True)] = \ -_150ul_Piercing_Tip_Filter_Water_DispenseJet_Empty = HamiltonLiquidClass( - curve={5.0: 6.6, 150.0: 159.1, 50.0: 55.0, 0.0: 0.0, 100.0: 107.0, 1.0: 1.6, 20.0: 22.9, 10.0: 12.2}, +star_mapping[(50, False, True, True, Liquid.WATER, True, True)] = ( + _150ul_Piercing_Tip_Filter_Water_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 5.0: 6.6, + 150.0: 159.1, + 50.0: 55.0, + 0.0: 0.0, + 100.0: 107.0, + 1.0: 1.6, + 20.0: 22.9, + 10.0: 12.2, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -542,12 +586,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, True, Liquid.WATER, False, True)] = \ -_150ul_Piercing_Tip_Filter_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.WATER, False, True)] = ( + _150ul_Piercing_Tip_Filter_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={3.0: 3.5, 5.0: 6.5, 150.0: 158.1, 50.0: 54.5, 0.0: 0.0, 1.0: 1.6, 10.0: 11.9, 2.0: 2.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -565,12 +610,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, False, Liquid.DMSO, True, True)] = \ -_250ul_Piercing_Tip_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.DMSO, True, True)] = ( + _250ul_Piercing_Tip_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={250.0: 255.5, 50.0: 52.9, 0.0: 0.0, 20.0: 21.8}, aspiration_flow_rate=180.0, aspiration_mix_flow_rate=100.0, @@ -588,12 +634,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, False, Liquid.DMSO, False, True)] = \ -_250ul_Piercing_Tip_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.DMSO, False, True)] = ( + _250ul_Piercing_Tip_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={3.0: 4.2, 5.0: 6.5, 250.0: 256.0, 50.0: 53.7, 0.0: 0.0, 10.0: 12.0, 2.0: 3.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -611,7 +658,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -632,8 +679,9 @@ def get_star_liquid_class(**kwargs): # 100 1.67 -0.35 # 300 0.46 -0.61 # -star_mapping[(50, False, True, False, Liquid.ETHANOL, True, True)] = \ -_250ul_Piercing_Tip_Ethanol_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.ETHANOL, True, True)] = ( + _250ul_Piercing_Tip_Ethanol_DispenseJet_Empty +) = HamiltonLiquidClass( curve={250.0: 270.2, 50.0: 59.2, 0.0: 0.0, 20.0: 27.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=50.0, @@ -651,7 +699,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -673,8 +721,9 @@ def get_star_liquid_class(**kwargs): # 20 0.95 2.97 # 50 0.31 -0.10 # -star_mapping[(50, False, True, False, Liquid.ETHANOL, False, True)] = \ -_250ul_Piercing_Tip_Ethanol_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.ETHANOL, False, True)] = ( + _250ul_Piercing_Tip_Ethanol_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={3.0: 5.0, 5.0: 9.6, 250.0: 270.5, 50.0: 58.0, 0.0: 0.0, 10.0: 14.8}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -692,7 +741,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -715,8 +764,9 @@ def get_star_liquid_class(**kwargs): # 300 1.08 -0.87 # # -star_mapping[(50, False, True, False, Liquid.GLYCERIN80, False, True)] = \ -_250ul_Piercing_Tip_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.GLYCERIN80, False, True)] = ( + _250ul_Piercing_Tip_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={3.0: 4.5, 5.0: 7.2, 250.0: 289.0, 50.0: 65.0, 0.0: 0.0, 1.0: 2.7, 10.0: 13.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -734,7 +784,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -754,8 +804,9 @@ def get_star_liquid_class(**kwargs): # 100 0.81 0.99 # 300 1.00 0.65 # -star_mapping[(50, False, True, False, Liquid.SERUM, True, True)] = \ -_250ul_Piercing_Tip_Serum_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.SERUM, True, True)] = ( + _250ul_Piercing_Tip_Serum_DispenseJet_Empty +) = HamiltonLiquidClass( curve={250.0: 265.0, 50.0: 56.4, 0.0: 0.0, 20.0: 23.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -773,7 +824,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -796,8 +847,9 @@ def get_star_liquid_class(**kwargs): # 50 1.39 -0.12 # # -star_mapping[(50, False, True, False, Liquid.SERUM, False, True)] = \ -_250ul_Piercing_Tip_Serum_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.SERUM, False, True)] = ( + _250ul_Piercing_Tip_Serum_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={3.0: 3.4, 5.0: 5.9, 250.0: 264.2, 50.0: 56.2, 0.0: 0.0, 10.0: 11.6}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -815,13 +867,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, False, Liquid.WATER, True, True)] = \ -_250ul_Piercing_Tip_Water_DispenseJet_Empty = HamiltonLiquidClass( - curve={5.0: 6.6, 250.0: 260.0, 50.0: 55.0, 0.0: 0.0, 100.0: 107.0, 1.0: 1.6, 20.0: 22.5, 10.0: 12.2}, +star_mapping[(50, False, True, False, Liquid.WATER, True, True)] = ( + _250ul_Piercing_Tip_Water_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 5.0: 6.6, + 250.0: 260.0, + 50.0: 55.0, + 0.0: 0.0, + 100.0: 107.0, + 1.0: 1.6, + 20.0: 22.5, + 10.0: 12.2, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -838,12 +900,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, False, Liquid.WATER, False, True)] = \ -_250ul_Piercing_Tip_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.WATER, False, True)] = ( + _250ul_Piercing_Tip_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={3.0: 4.0, 5.0: 6.5, 250.0: 259.0, 50.0: 55.1, 0.0: 0.0, 1.0: 1.6, 10.0: 12.6, 2.0: 2.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -861,7 +924,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -882,8 +945,9 @@ def get_star_liquid_class(**kwargs): # 100 1.04 0.05 # 300 0.63 -0.07 # -star_mapping[(300, False, False, False, Liquid.ACETONITRIL80WATER20, True, False)] = \ -_300ulNeedleAcetonitril80Water20DispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, False, False, Liquid.ACETONITRIL80WATER20, True, False)] = ( + _300ulNeedleAcetonitril80Water20DispenseJet +) = HamiltonLiquidClass( curve={300.0: 310.0, 50.0: 57.8, 0.0: 0.0, 100.0: 106.5, 20.0: 26.8, 10.0: 16.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=50.0, @@ -901,12 +965,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, False, False, Liquid.WATER, True, True)] = \ -_300ulNeedleCRWater_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, False, False, False, Liquid.WATER, True, True)] = ( + _300ulNeedleCRWater_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 313.0, 50.0: 53.5, 0.0: 0.0, 100.0: 104.0, 20.0: 22.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -924,12 +989,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, False, False, Liquid.WATER, True, False)] = \ -_300ulNeedleCRWater_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, False, False, False, Liquid.WATER, True, False)] = ( + _300ulNeedleCRWater_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 313.0, 50.0: 59.5, 0.0: 0.0, 100.0: 109.0, 20.0: 29.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -947,13 +1013,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(300, False, False, False, Liquid.WATER, False, True)] = \ -_300ulNeedleCRWater_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 308.4, 5.0: 6.8, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 2.3, 200.0: 205.8, 10.0: 11.7, 2.0: 3.0}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(300, False, False, False, Liquid.WATER, False, True)] = ( + _300ulNeedleCRWater_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 308.4, + 5.0: 6.8, + 50.0: 52.3, + 0.0: 0.0, + 100.0: 102.9, + 20.0: 22.3, + 1.0: 2.3, + 200.0: 205.8, + 10.0: 11.7, + 2.0: 3.0, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=1.0, @@ -970,13 +1048,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(300, False, False, False, Liquid.WATER, False, False)] = \ -_300ulNeedleCRWater_DispenseSurface_Part = HamiltonLiquidClass( - curve={300.0: 308.4, 5.0: 6.8, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 2.3, 200.0: 205.8, 10.0: 11.7, 2.0: 3.0}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(300, False, False, False, Liquid.WATER, False, False)] = ( + _300ulNeedleCRWater_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 300.0: 308.4, + 5.0: 6.8, + 50.0: 52.3, + 0.0: 0.0, + 100.0: 102.9, + 20.0: 22.3, + 1.0: 2.3, + 200.0: 205.8, + 10.0: 11.7, + 2.0: 3.0, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=1.0, @@ -993,7 +1083,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1013,8 +1103,9 @@ def get_star_liquid_class(**kwargs): # 100 0.55 -0.01 # 300 0.71 0.39 # -star_mapping[(300, False, False, False, Liquid.DIMETHYLSULFOXID, True, False)] = \ -_300ulNeedleDMSODispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, False, False, Liquid.DIMETHYLSULFOXID, True, False)] = ( + _300ulNeedleDMSODispenseJet +) = HamiltonLiquidClass( curve={300.0: 317.0, 50.0: 53.5, 0.0: 0.0, 100.0: 106.5, 20.0: 21.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -1032,7 +1123,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1053,8 +1144,9 @@ def get_star_liquid_class(**kwargs): # 50 1.32 -1.05 # # -star_mapping[(300, False, False, False, Liquid.DIMETHYLSULFOXID, False, False)] = \ -_300ulNeedleDMSODispenseSurface = HamiltonLiquidClass( +star_mapping[(300, False, False, False, Liquid.DIMETHYLSULFOXID, False, False)] = ( + _300ulNeedleDMSODispenseSurface +) = HamiltonLiquidClass( curve={5.0: 6.0, 50.0: 52.3, 0.0: 0.0, 20.0: 22.3, 10.0: 11.4, 2.0: 2.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -1072,7 +1164,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1093,8 +1185,9 @@ def get_star_liquid_class(**kwargs): # 100 1.67 -0.35 # 300 0.46 -0.61 # -star_mapping[(300, False, False, False, Liquid.ETHANOL, True, False)] = \ -_300ulNeedleEtOHDispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, False, False, Liquid.ETHANOL, True, False)] = ( + _300ulNeedleEtOHDispenseJet +) = HamiltonLiquidClass( curve={300.0: 317.0, 50.0: 57.8, 0.0: 0.0, 100.0: 109.0, 20.0: 25.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=50.0, @@ -1112,7 +1205,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1134,8 +1227,9 @@ def get_star_liquid_class(**kwargs): # 20 0.95 2.97 # 50 0.31 -0.10 # -star_mapping[(300, False, False, False, Liquid.ETHANOL, False, False)] = \ -_300ulNeedleEtOHDispenseSurface = HamiltonLiquidClass( +star_mapping[(300, False, False, False, Liquid.ETHANOL, False, False)] = ( + _300ulNeedleEtOHDispenseSurface +) = HamiltonLiquidClass( curve={5.0: 7.2, 50.0: 55.0, 0.0: 0.0, 20.0: 24.5, 10.0: 13.1}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -1153,7 +1247,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1176,9 +1270,20 @@ def get_star_liquid_class(**kwargs): # 300 1.08 -0.87 # # -star_mapping[(300, False, False, False, Liquid.GLYCERIN80, False, False)] = \ -_300ulNeedleGlycerin80DispenseSurface = HamiltonLiquidClass( - curve={300.0: 325.0, 5.0: 8.0, 50.0: 61.3, 0.0: 0.0, 100.0: 117.0, 20.0: 26.0, 1.0: 2.7, 10.0: 13.9, 2.0: 4.2}, +star_mapping[(300, False, False, False, Liquid.GLYCERIN80, False, False)] = ( + _300ulNeedleGlycerin80DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 325.0, + 5.0: 8.0, + 50.0: 61.3, + 0.0: 0.0, + 100.0: 117.0, + 20.0: 26.0, + 1.0: 2.7, + 10.0: 13.9, + 2.0: 4.2, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=5.0, @@ -1195,7 +1300,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1215,8 +1320,9 @@ def get_star_liquid_class(**kwargs): # 100 0.81 0.99 # 300 1.00 0.65 # -star_mapping[(300, False, False, False, Liquid.SERUM, True, False)] = \ -_300ulNeedleSerumDispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, False, False, Liquid.SERUM, True, False)] = ( + _300ulNeedleSerumDispenseJet +) = HamiltonLiquidClass( curve={300.0: 313.0, 50.0: 53.5, 0.0: 0.0, 100.0: 105.0, 20.0: 21.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -1234,7 +1340,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1257,8 +1363,9 @@ def get_star_liquid_class(**kwargs): # 50 1.39 -0.12 # # -star_mapping[(300, False, False, False, Liquid.SERUM, False, False)] = \ -_300ulNeedleSerumDispenseSurface = HamiltonLiquidClass( +star_mapping[(300, False, False, False, Liquid.SERUM, False, False)] = ( + _300ulNeedleSerumDispenseSurface +) = HamiltonLiquidClass( curve={5.0: 6.0, 50.0: 52.3, 0.0: 0.0, 20.0: 22.3, 1.0: 2.2, 10.0: 11.9, 2.0: 3.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -1276,7 +1383,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1296,8 +1403,9 @@ def get_star_liquid_class(**kwargs): # 100 0.81 0.99 # 300 1.00 0.65 # -star_mapping[(300, False, False, False, Liquid.SERUM, True, False)] = \ -_300ulNeedle_Serum_DispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, False, False, Liquid.SERUM, True, False)] = ( + _300ulNeedle_Serum_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 313.0, 50.0: 53.5, 0.0: 0.0, 100.0: 105.0, 20.0: 21.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -1315,7 +1423,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1338,8 +1446,9 @@ def get_star_liquid_class(**kwargs): # 50 1.39 -0.12 # # -star_mapping[(300, False, False, False, Liquid.SERUM, False, False)] = \ -_300ulNeedle_Serum_DispenseSurface = HamiltonLiquidClass( +star_mapping[(300, False, False, False, Liquid.SERUM, False, False)] = ( + _300ulNeedle_Serum_DispenseSurface +) = HamiltonLiquidClass( curve={300.0: 350.0, 5.0: 6.0, 50.0: 52.3, 0.0: 0.0, 20.0: 22.3, 1.0: 2.2, 10.0: 11.9, 2.0: 3.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -1357,7 +1466,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1378,8 +1487,9 @@ def get_star_liquid_class(**kwargs): # 200 0.16 0.55 # 300 0.17 0.35 # -star_mapping[(300, False, False, False, Liquid.WATER, True, False)] = \ -_300ulNeedle_Water_DispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, False, False, Liquid.WATER, True, False)] = ( + _300ulNeedle_Water_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 313.0, 50.0: 53.5, 0.0: 0.0, 100.0: 105.0, 20.0: 22.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -1397,7 +1507,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1419,9 +1529,21 @@ def get_star_liquid_class(**kwargs): # 20 0.63 0.73 # # -star_mapping[(300, False, False, False, Liquid.WATER, False, False)] = \ -_300ulNeedle_Water_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 308.4, 5.0: 6.5, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 1.1, 200.0: 205.8, 10.0: 12.0, 2.0: 2.1}, +star_mapping[(300, False, False, False, Liquid.WATER, False, False)] = ( + _300ulNeedle_Water_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 308.4, + 5.0: 6.5, + 50.0: 52.3, + 0.0: 0.0, + 100.0: 102.9, + 20.0: 22.3, + 1.0: 1.1, + 200.0: 205.8, + 10.0: 12.0, + 2.0: 2.1, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -1438,14 +1560,27 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=0.4, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # Liquid class for washing rocket tips with CO-RE 384 head in 96 DC wash station. -star_mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ -_300ul_RocketTip_384COREHead_96Washer_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 330.0, 5.0: 6.3, 0.5: 0.9, 50.0: 55.1, 0.0: 0.0, 1.0: 1.6, 20.0: 23.2, 100.0: 107.2, 2.0: 2.8, 10.0: 11.9, 200.0: 211.0}, +star_mapping[(300, True, True, False, Liquid.WATER, False, False)] = ( + _300ul_RocketTip_384COREHead_96Washer_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 330.0, + 5.0: 6.3, + 0.5: 0.9, + 50.0: 55.1, + 0.0: 0.0, + 1.0: 1.6, + 20.0: 23.2, + 100.0: 107.2, + 2.0: 2.8, + 10.0: 11.9, + 200.0: 211.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=150.0, aspiration_air_transport_volume=0.0, @@ -1462,13 +1597,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # Evaluation -star_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ -_300ul_RocketTip_384COREHead_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = ( + _300ul_RocketTip_384COREHead_DMSO_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 150.0: 150.0, 50.0: 50.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -1486,13 +1622,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=120.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # Evaluation -star_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ -_300ul_RocketTip_384COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = ( + _300ul_RocketTip_384COREHead_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 303.5, 0.0: 0.0, 100.0: 105.8, 200.0: 209.5, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -1510,13 +1647,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # Evaluation -star_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ -_300ul_RocketTip_384COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = ( + _300ul_RocketTip_384COREHead_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 308.0, 0.0: 0.0, 100.0: 105.5, 200.0: 209.0, 10.0: 12.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -1534,13 +1672,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # Evaluation -star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ -_300ul_RocketTip_384COREHead_Water_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( + _300ul_RocketTip_384COREHead_Water_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 309.0, 0.0: 0.0, 100.0: 106.5, 20.0: 22.3, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -1558,13 +1697,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=20.0 + dispense_stop_back_volume=20.0, ) # Evaluation -star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ -_300ul_RocketTip_384COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( + _300ul_RocketTip_384COREHead_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 309.0, 0.0: 0.0, 100.0: 106.5, 20.0: 22.3, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -1582,13 +1722,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # Evaluation -star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ -_300ul_RocketTip_384COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( + _300ul_RocketTip_384COREHead_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 314.3, 0.0: 0.0, 100.0: 109.0, 200.0: 214.7, 10.0: 12.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -1606,12 +1747,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(30, True, True, False, Liquid.DMSO, True, True)] = \ -_30ulTip_384COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(30, True, True, False, Liquid.DMSO, True, True)] = ( + _30ulTip_384COREHead_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={5.0: 5.0, 15.0: 15.3, 30.0: 30.7, 0.0: 0.0, 1.0: 1.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -1629,12 +1771,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(30, True, True, False, Liquid.DMSO, False, True)] = \ -_30ulTip_384COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(30, True, True, False, Liquid.DMSO, False, True)] = ( + _30ulTip_384COREHead_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 4.9, 15.0: 15.1, 30.0: 30.0, 0.0: 0.0, 1.0: 0.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -1652,12 +1795,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(30, True, True, False, Liquid.ETHANOL, True, True)] = \ -_30ulTip_384COREHead_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(30, True, True, False, Liquid.ETHANOL, True, True)] = ( + _30ulTip_384COREHead_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={5.0: 6.54, 15.0: 18.36, 30.0: 33.8, 0.0: 0.0, 1.0: 1.8}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -1675,12 +1819,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(30, True, True, False, Liquid.ETHANOL, False, True)] = \ -_30ulTip_384COREHead_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(30, True, True, False, Liquid.ETHANOL, False, True)] = ( + _30ulTip_384COREHead_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 6.2, 15.0: 16.9, 30.0: 33.1, 0.0: 0.0, 1.0: 1.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -1698,12 +1843,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(30, True, True, False, Liquid.GLYCERIN80, False, True)] = \ -_30ulTip_384COREHead_Glyzerin80_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(30, True, True, False, Liquid.GLYCERIN80, False, True)] = ( + _30ulTip_384COREHead_Glyzerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 6.3, 0.5: 0.9, 40.0: 44.0, 0.0: 0.0, 20.0: 22.2, 1.0: 1.6, 10.0: 11.9, 2.0: 2.8}, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=100.0, @@ -1721,12 +1867,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(30, True, True, False, Liquid.WATER, True, True)] = \ -_30ulTip_384COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(30, True, True, False, Liquid.WATER, True, True)] = ( + _30ulTip_384COREHead_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={5.0: 6.0, 15.0: 16.5, 30.0: 32.3, 0.0: 0.0, 1.0: 1.6}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -1744,12 +1891,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(30, True, True, False, Liquid.WATER, False, True)] = \ -_30ulTip_384COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(30, True, True, False, Liquid.WATER, False, True)] = ( + _30ulTip_384COREHead_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 15.0: 15.9, 30.0: 31.3, 0.0: 0.0, 1.0: 1.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -1767,12 +1915,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(30, True, True, False, Liquid.WATER, False, False)] = \ -_30ulTip_384COREWasher_DispenseSurface = HamiltonLiquidClass( +star_mapping[(30, True, True, False, Liquid.WATER, False, False)] = ( + _30ulTip_384COREWasher_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 6.3, 0.5: 0.9, 40.0: 44.0, 0.0: 0.0, 1.0: 1.6, 20.0: 22.2, 2.0: 2.8, 10.0: 11.9}, aspiration_flow_rate=10.0, aspiration_mix_flow_rate=30.0, @@ -1790,13 +1939,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(4000, False, True, False, Liquid.DMSO, True, False)] = \ -_4mlTF_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( - curve={3500.0: 3715.0, 500.0: 631.0, 2500.0: 2691.0, 1500.0: 1667.0, 4000.0: 4224.0, 3000.0: 3202.0, 0.0: 0.0, 2000.0: 2179.0, 100.0: 211.0, 1000.0: 1151.0}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(4000, False, True, False, Liquid.DMSO, True, False)] = ( + _4mlTF_DMSO_DispenseJet_Aliquot +) = HamiltonLiquidClass( + curve={ + 3500.0: 3715.0, + 500.0: 631.0, + 2500.0: 2691.0, + 1500.0: 1667.0, + 4000.0: 4224.0, + 3000.0: 3202.0, + 0.0: 0.0, + 2000.0: 2179.0, + 100.0: 211.0, + 1000.0: 1151.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -1813,13 +1974,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=20.0 -) - - -star_mapping[(4000, False, True, False, Liquid.DMSO, True, True)] = \ -_4mlTF_DMSO_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 540.0, 50.0: 61.5, 4000.0: 4102.0, 3000.0: 3083.0, 0.0: 0.0, 2000.0: 2070.0, 100.0: 116.5, 1000.0: 1060.0}, + dispense_stop_back_volume=20.0, +) + + +star_mapping[(4000, False, True, False, Liquid.DMSO, True, True)] = ( + _4mlTF_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 540.0, + 50.0: 61.5, + 4000.0: 4102.0, + 3000.0: 3083.0, + 0.0: 0.0, + 2000.0: 2070.0, + 100.0: 116.5, + 1000.0: 1060.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -1836,13 +2007,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(4000, False, True, False, Liquid.DMSO, False, True)] = \ -_4mlTF_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 536.5, 50.0: 62.3, 4000.0: 4128.0, 3000.0: 3109.0, 0.0: 0.0, 2000.0: 2069.0, 100.0: 116.6, 1000.0: 1054.0, 10.0: 15.5}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(4000, False, True, False, Liquid.DMSO, False, True)] = ( + _4mlTF_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 536.5, + 50.0: 62.3, + 4000.0: 4128.0, + 3000.0: 3109.0, + 0.0: 0.0, + 2000.0: 2069.0, + 100.0: 116.6, + 1000.0: 1054.0, + 10.0: 15.5, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -1859,14 +2041,27 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=500.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # First two times mixing with max volume. -star_mapping[(4000, False, True, False, Liquid.ETHANOL, True, False)] = \ -_4mlTF_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( - curve={300.0: 300.0, 3500.0: 3500.0, 500.0: 500.0, 2500.0: 2500.0, 1500.0: 1500.0, 4000.0: 4000.0, 3000.0: 3000.0, 0.0: 0.0, 2000.0: 2000.0, 100.0: 100.0, 1000.0: 1000.0}, +star_mapping[(4000, False, True, False, Liquid.ETHANOL, True, False)] = ( + _4mlTF_EtOH_DispenseJet_Aliquot +) = HamiltonLiquidClass( + curve={ + 300.0: 300.0, + 3500.0: 3500.0, + 500.0: 500.0, + 2500.0: 2500.0, + 1500.0: 1500.0, + 4000.0: 4000.0, + 3000.0: 3000.0, + 0.0: 0.0, + 2000.0: 2000.0, + 100.0: 100.0, + 1000.0: 1000.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=2000.0, aspiration_air_transport_volume=0.0, @@ -1883,13 +2078,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(4000, False, True, False, Liquid.ETHANOL, True, True)] = \ -_4mlTF_EtOH_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 563.0, 50.0: 72.0, 4000.0: 4215.0, 3000.0: 3190.0, 0.0: 0.0, 2000.0: 2178.0, 100.0: 127.5, 1000.0: 1095.0}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(4000, False, True, False, Liquid.ETHANOL, True, True)] = ( + _4mlTF_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 563.0, + 50.0: 72.0, + 4000.0: 4215.0, + 3000.0: 3190.0, + 0.0: 0.0, + 2000.0: 2178.0, + 100.0: 127.5, + 1000.0: 1095.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=30.0, @@ -1906,13 +2111,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=30.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(4000, False, True, False, Liquid.ETHANOL, False, True)] = \ -_4mlTF_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 555.0, 50.0: 68.0, 4000.0: 4177.0, 3000.0: 3174.0, 0.0: 0.0, 2000.0: 2151.0, 100.0: 123.5, 1000.0: 1085.0, 10.0: 18.6}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(4000, False, True, False, Liquid.ETHANOL, False, True)] = ( + _4mlTF_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 555.0, + 50.0: 68.0, + 4000.0: 4177.0, + 3000.0: 3174.0, + 0.0: 0.0, + 2000.0: 2151.0, + 100.0: 123.5, + 1000.0: 1085.0, + 10.0: 18.6, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=30.0, @@ -1929,13 +2145,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=30.0, dispense_settling_time=1.0, dispense_stop_flow_rate=30.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(4000, False, True, False, Liquid.GLYCERIN80, True, True)] = \ -_4mlTF_Glycerin80_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 599.0, 50.0: 89.0, 4000.0: 4223.0, 3000.0: 3211.0, 0.0: 0.0, 2000.0: 2195.0, 100.0: 140.0, 1000.0: 1159.0}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(4000, False, True, False, Liquid.GLYCERIN80, True, True)] = ( + _4mlTF_Glycerin80_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 599.0, + 50.0: 89.0, + 4000.0: 4223.0, + 3000.0: 3211.0, + 0.0: 0.0, + 2000.0: 2195.0, + 100.0: 140.0, + 1000.0: 1159.0, + }, aspiration_flow_rate=1200.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=30.0, @@ -1952,13 +2178,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(4000, False, True, False, Liquid.GLYCERIN80, False, True)] = \ -_4mlTF_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 555.0, 50.0: 71.0, 4000.0: 4135.0, 3000.0: 3122.0, 0.0: 0.0, 2000.0: 2101.0, 100.0: 129.0, 1000.0: 1083.0, 10.0: 16.0}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(4000, False, True, False, Liquid.GLYCERIN80, False, True)] = ( + _4mlTF_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 555.0, + 50.0: 71.0, + 4000.0: 4135.0, + 3000.0: 3122.0, + 0.0: 0.0, + 2000.0: 2101.0, + 100.0: 129.0, + 1000.0: 1083.0, + 10.0: 16.0, + }, aspiration_flow_rate=1000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=0.0, @@ -1975,12 +2212,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(4000, False, True, False, Liquid.WATER, True, False)] = \ -_4mlTF_Water_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(4000, False, True, False, Liquid.WATER, True, False)] = ( + _4mlTF_Water_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={4000.0: 4160.0, 3000.0: 3160.0, 0.0: 0.0, 2000.0: 2160.0, 100.0: 214.0, 1000.0: 1148.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, @@ -1998,13 +2236,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=20.0 -) - - -star_mapping[(4000, False, True, False, Liquid.WATER, True, True)] = \ -_4mlTF_Water_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 551.8, 50.0: 66.4, 4000.0: 4165.0, 3000.0: 3148.0, 0.0: 0.0, 2000.0: 2128.0, 100.0: 122.7, 1000.0: 1082.0}, + dispense_stop_back_volume=20.0, +) + + +star_mapping[(4000, False, True, False, Liquid.WATER, True, True)] = ( + _4mlTF_Water_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 551.8, + 50.0: 66.4, + 4000.0: 4165.0, + 3000.0: 3148.0, + 0.0: 0.0, + 2000.0: 2128.0, + 100.0: 122.7, + 1000.0: 1082.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2021,13 +2269,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(4000, False, True, False, Liquid.WATER, False, True)] = \ -_4mlTF_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 547.0, 50.0: 65.5, 4000.0: 4145.0, 3000.0: 3135.0, 0.0: 0.0, 2000.0: 2125.0, 100.0: 120.9, 1000.0: 1075.0, 10.0: 14.5}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(4000, False, True, False, Liquid.WATER, False, True)] = ( + _4mlTF_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 547.0, + 50.0: 65.5, + 4000.0: 4145.0, + 3000.0: 3135.0, + 0.0: 0.0, + 2000.0: 2125.0, + 100.0: 120.9, + 1000.0: 1075.0, + 10.0: 14.5, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2044,12 +2303,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=500.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ -_50ulTip_384COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = ( + _50ulTip_384COREHead_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 52.0, 0.0: 0.0, 20.0: 21.1, 10.0: 10.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2067,12 +2327,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = \ -_50ulTip_384COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = ( + _50ulTip_384COREHead_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.0, 50.0: 51.1, 30.0: 30.7, 0.0: 0.0, 1.0: 0.9, 10.0: 10.1}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2090,12 +2351,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = \ -_50ulTip_384COREHead_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = ( + _50ulTip_384COREHead_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={5.0: 6.54, 15.0: 18.36, 50.0: 53.0, 30.0: 33.8, 0.0: 0.0, 1.0: 1.8}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2113,12 +2375,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.ETHANOL, False, True)] = \ -_50ulTip_384COREHead_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.ETHANOL, False, True)] = ( + _50ulTip_384COREHead_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 6.2, 15.0: 16.9, 0.5: 1.0, 50.0: 54.0, 30.0: 33.1, 0.0: 0.0, 1.0: 1.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2136,12 +2399,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=6.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.GLYCERIN80, False, True)] = \ -_50ulTip_384COREHead_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.GLYCERIN80, False, True)] = ( + _50ulTip_384COREHead_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 0.5: 0.65, 50.0: 55.0, 0.0: 0.0, 30.0: 31.5, 1.0: 1.2, 10.0: 10.9}, aspiration_flow_rate=30.0, aspiration_mix_flow_rate=30.0, @@ -2159,12 +2423,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ -_50ulTip_384COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.WATER, True, True)] = ( + _50ulTip_384COREHead_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 53.6, 0.0: 0.0, 20.0: 22.4, 10.0: 11.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2182,12 +2447,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.WATER, False, True)] = \ -_50ulTip_384COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.WATER, False, True)] = ( + _50ulTip_384COREHead_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.5, 50.0: 52.2, 30.0: 31.5, 0.0: 0.0, 1.0: 1.2, 10.0: 11.3}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2205,13 +2471,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(50, True, True, False, Liquid.WATER, False, False)] = \ -_50ulTip_384COREWasher_DispenseSurface = HamiltonLiquidClass( - curve={5.0: 6.3, 0.5: 0.9, 50.0: 55.0, 40.0: 44.0, 0.0: 0.0, 20.0: 22.2, 1.0: 1.6, 10.0: 11.9, 2.0: 2.8}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(50, True, True, False, Liquid.WATER, False, False)] = ( + _50ulTip_384COREWasher_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 5.0: 6.3, + 0.5: 0.9, + 50.0: 55.0, + 40.0: 44.0, + 0.0: 0.0, + 20.0: 22.2, + 1.0: 1.6, + 10.0: 11.9, + 2.0: 2.8, + }, aspiration_flow_rate=20.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=0.0, @@ -2228,12 +2505,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ -_50ulTip_conductive_384COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = ( + _50ulTip_conductive_384COREHead_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={5.0: 5.2, 50.0: 50.6, 30.0: 30.4, 0.0: 0.0, 1.0: 0.9, 20.0: 21.1, 10.0: 9.3}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2251,12 +2529,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ -_50ulTip_conductive_384COREHead_DMSO_DispenseJet_Empty_below5ul = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = ( + _50ulTip_conductive_384COREHead_DMSO_DispenseJet_Empty_below5ul +) = HamiltonLiquidClass( curve={5.0: 5.2, 50.0: 50.6, 30.0: 30.4, 0.0: 0.0, 1.0: 0.9, 20.0: 21.1, 10.0: 9.3}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2274,12 +2553,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.DMSO, True, False)] = \ -_50ulTip_conductive_384COREHead_DMSO_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.DMSO, True, False)] = ( + _50ulTip_conductive_384COREHead_DMSO_DispenseJet_Part +) = HamiltonLiquidClass( curve={50.0: 50.0, 0.0: 0.0, 10.0: 10.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2297,13 +2577,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=5.0 -) - - -star_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = \ -_50ulTip_conductive_384COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( - curve={0.1: 0.05, 0.25: 0.1, 5.0: 4.95, 0.5: 0.22, 50.0: 50.0, 30.0: 30.6, 0.0: 0.0, 1.0: 0.74, 10.0: 9.95}, + dispense_stop_back_volume=5.0, +) + + +star_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = ( + _50ulTip_conductive_384COREHead_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 0.1: 0.05, + 0.25: 0.1, + 5.0: 4.95, + 0.5: 0.22, + 50.0: 50.0, + 30.0: 30.6, + 0.0: 0.0, + 1.0: 0.74, + 10.0: 9.95, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -2320,12 +2611,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = \ -_50ulTip_conductive_384COREHead_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = ( + _50ulTip_conductive_384COREHead_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={5.0: 6.85, 15.0: 18.36, 50.0: 54.3, 30.0: 33.6, 0.0: 0.0, 1.0: 1.5, 10.0: 12.1}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2343,12 +2635,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = \ -_50ulTip_conductive_384COREHead_EtOH_DispenseJet_Empty_below5ul = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = ( + _50ulTip_conductive_384COREHead_EtOH_DispenseJet_Empty_below5ul +) = HamiltonLiquidClass( curve={5.0: 6.85, 15.0: 18.36, 50.0: 54.3, 30.0: 33.6, 0.0: 0.0, 1.0: 1.5, 10.0: 12.1}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2366,12 +2659,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.ETHANOL, True, False)] = \ -_50ulTip_conductive_384COREHead_EtOH_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.ETHANOL, True, False)] = ( + _50ulTip_conductive_384COREHead_EtOH_DispenseJet_Part +) = HamiltonLiquidClass( curve={50.0: 50.0, 0.0: 0.0, 10.0: 10.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2389,13 +2683,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=2.0 -) - - -star_mapping[(50, True, True, False, Liquid.ETHANOL, False, True)] = \ -_50ulTip_conductive_384COREHead_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( - curve={0.25: 0.3, 5.0: 6.1, 0.5: 0.65, 15.0: 16.9, 50.0: 52.7, 30.0: 32.1, 0.0: 0.0, 1.0: 1.35, 10.0: 11.3}, + dispense_stop_back_volume=2.0, +) + + +star_mapping[(50, True, True, False, Liquid.ETHANOL, False, True)] = ( + _50ulTip_conductive_384COREHead_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 0.25: 0.3, + 5.0: 6.1, + 0.5: 0.65, + 15.0: 16.9, + 50.0: 52.7, + 30.0: 32.1, + 0.0: 0.0, + 1.0: 1.35, + 10.0: 11.3, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=2.0, @@ -2412,12 +2717,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=6.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.GLYCERIN80, False, True)] = \ -_50ulTip_conductive_384COREHead_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.GLYCERIN80, False, True)] = ( + _50ulTip_conductive_384COREHead_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={0.25: 0.05, 5.0: 5.5, 0.5: 0.3, 50.0: 51.9, 30.0: 31.8, 0.0: 0.0, 1.0: 1.0, 10.0: 10.9}, aspiration_flow_rate=30.0, aspiration_mix_flow_rate=30.0, @@ -2435,12 +2741,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ -_50ulTip_conductive_384COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.WATER, True, True)] = ( + _50ulTip_conductive_384COREHead_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={5.0: 5.67, 0.5: 0.27, 50.0: 51.9, 30.0: 31.5, 0.0: 0.0, 1.0: 1.06, 20.0: 20.0, 10.0: 10.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2458,12 +2765,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ -_50ulTip_conductive_384COREHead_Water_DispenseJet_Empty_below5ul = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.WATER, True, True)] = ( + _50ulTip_conductive_384COREHead_Water_DispenseJet_Empty_below5ul +) = HamiltonLiquidClass( curve={5.0: 5.67, 0.5: 0.27, 50.0: 51.9, 30.0: 31.5, 0.0: 0.0, 1.0: 1.06, 20.0: 20.0, 10.0: 10.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2481,12 +2789,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.WATER, True, False)] = \ -_50ulTip_conductive_384COREHead_Water_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.WATER, True, False)] = ( + _50ulTip_conductive_384COREHead_Water_DispenseJet_Part +) = HamiltonLiquidClass( curve={50.0: 50.0, 0.0: 0.0, 10.0: 10.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2504,13 +2813,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=2.0 -) - - -star_mapping[(50, True, True, False, Liquid.WATER, False, True)] = \ -_50ulTip_conductive_384COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={0.1: 0.1, 0.25: 0.15, 5.0: 5.6, 0.5: 0.45, 50.0: 51.0, 30.0: 31.0, 0.0: 0.0, 1.0: 0.98, 10.0: 10.7}, + dispense_stop_back_volume=2.0, +) + + +star_mapping[(50, True, True, False, Liquid.WATER, False, True)] = ( + _50ulTip_conductive_384COREHead_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 0.1: 0.1, + 0.25: 0.15, + 5.0: 5.6, + 0.5: 0.45, + 50.0: 51.0, + 30.0: 31.0, + 0.0: 0.0, + 1.0: 0.98, + 10.0: 10.7, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -2527,13 +2847,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(50, True, True, False, Liquid.WATER, False, False)] = \ -_50ulTip_conductive_384COREWasher_DispenseSurface = HamiltonLiquidClass( - curve={5.0: 6.3, 0.5: 0.9, 50.0: 55.0, 40.0: 44.0, 0.0: 0.0, 1.0: 1.6, 20.0: 22.2, 65.0: 65.0, 10.0: 11.9, 2.0: 2.8}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(50, True, True, False, Liquid.WATER, False, False)] = ( + _50ulTip_conductive_384COREWasher_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 5.0: 6.3, + 0.5: 0.9, + 50.0: 55.0, + 40.0: 44.0, + 0.0: 0.0, + 1.0: 1.6, + 20.0: 22.2, + 65.0: 65.0, + 10.0: 11.9, + 2.0: 2.8, + }, aspiration_flow_rate=20.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=0.0, @@ -2550,13 +2882,27 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(5000, False, True, False, Liquid.DMSO, True, False)] = \ -_5mlT_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( - curve={4500.0: 4606.0, 3500.0: 3591.0, 500.0: 525.0, 2500.0: 2576.0, 1500.0: 1559.0, 5000.0: 5114.0, 4000.0: 4099.0, 3000.0: 3083.0, 0.0: 0.0, 2000.0: 2068.0, 100.0: 105.0, 1000.0: 1044.0}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(5000, False, True, False, Liquid.DMSO, True, False)] = ( + _5mlT_DMSO_DispenseJet_Aliquot +) = HamiltonLiquidClass( + curve={ + 4500.0: 4606.0, + 3500.0: 3591.0, + 500.0: 525.0, + 2500.0: 2576.0, + 1500.0: 1559.0, + 5000.0: 5114.0, + 4000.0: 4099.0, + 3000.0: 3083.0, + 0.0: 0.0, + 2000.0: 2068.0, + 100.0: 105.0, + 1000.0: 1044.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=20.0, @@ -2573,13 +2919,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=20.0 -) - - -star_mapping[(5000, False, True, False, Liquid.DMSO, True, True)] = \ -_5mlT_DMSO_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 540.0, 50.0: 62.0, 5000.0: 5095.0, 4000.0: 4075.0, 0.0: 0.0, 3000.0: 3065.0, 100.0: 117.0, 2000.0: 2060.0, 1000.0: 1060.0}, + dispense_stop_back_volume=20.0, +) + + +star_mapping[(5000, False, True, False, Liquid.DMSO, True, True)] = ( + _5mlT_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 540.0, + 50.0: 62.0, + 5000.0: 5095.0, + 4000.0: 4075.0, + 0.0: 0.0, + 3000.0: 3065.0, + 100.0: 117.0, + 2000.0: 2060.0, + 1000.0: 1060.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2596,13 +2953,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(5000, False, True, False, Liquid.DMSO, False, True)] = \ -_5mlT_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 535.0, 50.0: 60.3, 5000.0: 5090.0, 4000.0: 4078.0, 0.0: 0.0, 3000.0: 3066.0, 100.0: 115.0, 2000.0: 2057.0, 10.0: 12.5, 1000.0: 1054.0}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(5000, False, True, False, Liquid.DMSO, False, True)] = ( + _5mlT_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 535.0, + 50.0: 60.3, + 5000.0: 5090.0, + 4000.0: 4078.0, + 0.0: 0.0, + 3000.0: 3066.0, + 100.0: 115.0, + 2000.0: 2057.0, + 10.0: 12.5, + 1000.0: 1054.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2619,14 +2988,29 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=500.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # First two times mixing with max volume. -star_mapping[(5000, False, True, False, Liquid.ETHANOL, True, False)] = \ -_5mlT_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( - curve={300.0: 312.0, 4500.0: 4573.0, 3500.0: 3560.0, 500.0: 519.0, 2500.0: 2551.0, 1500.0: 1542.0, 5000.0: 5081.0, 4000.0: 4066.0, 3000.0: 3056.0, 0.0: 0.0, 2000.0: 2047.0, 100.0: 104.0, 1000.0: 1033.0}, +star_mapping[(5000, False, True, False, Liquid.ETHANOL, True, False)] = ( + _5mlT_EtOH_DispenseJet_Aliquot +) = HamiltonLiquidClass( + curve={ + 300.0: 312.0, + 4500.0: 4573.0, + 3500.0: 3560.0, + 500.0: 519.0, + 2500.0: 2551.0, + 1500.0: 1542.0, + 5000.0: 5081.0, + 4000.0: 4066.0, + 3000.0: 3056.0, + 0.0: 0.0, + 2000.0: 2047.0, + 100.0: 104.0, + 1000.0: 1033.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=2000.0, aspiration_air_transport_volume=0.0, @@ -2643,13 +3027,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(5000, False, True, False, Liquid.ETHANOL, True, True)] = \ -_5mlT_EtOH_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 563.0, 50.0: 72.0, 5000.0: 5230.0, 4000.0: 4215.0, 0.0: 0.0, 3000.0: 3190.0, 100.0: 129.5, 2000.0: 2166.0, 1000.0: 1095.0}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(5000, False, True, False, Liquid.ETHANOL, True, True)] = ( + _5mlT_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 563.0, + 50.0: 72.0, + 5000.0: 5230.0, + 4000.0: 4215.0, + 0.0: 0.0, + 3000.0: 3190.0, + 100.0: 129.5, + 2000.0: 2166.0, + 1000.0: 1095.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=30.0, @@ -2666,13 +3061,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=30.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(5000, False, True, False, Liquid.ETHANOL, False, True)] = \ -_5mlT_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 555.0, 50.0: 68.0, 5000.0: 5204.0, 4000.0: 4200.0, 0.0: 0.0, 3000.0: 3180.0, 100.0: 123.5, 2000.0: 2160.0, 10.0: 22.0, 1000.0: 1085.0}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(5000, False, True, False, Liquid.ETHANOL, False, True)] = ( + _5mlT_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 555.0, + 50.0: 68.0, + 5000.0: 5204.0, + 4000.0: 4200.0, + 0.0: 0.0, + 3000.0: 3180.0, + 100.0: 123.5, + 2000.0: 2160.0, + 10.0: 22.0, + 1000.0: 1085.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=30.0, @@ -2689,13 +3096,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=30.0, dispense_settling_time=1.0, dispense_stop_flow_rate=30.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(5000, False, True, False, Liquid.GLYCERIN80, True, True)] = \ -_5mlT_Glycerin80_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 597.0, 50.0: 89.0, 5000.0: 5240.0, 4000.0: 4220.0, 0.0: 0.0, 3000.0: 3203.0, 100.0: 138.0, 2000.0: 2195.0, 1000.0: 1166.0}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(5000, False, True, False, Liquid.GLYCERIN80, True, True)] = ( + _5mlT_Glycerin80_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 597.0, + 50.0: 89.0, + 5000.0: 5240.0, + 4000.0: 4220.0, + 0.0: 0.0, + 3000.0: 3203.0, + 100.0: 138.0, + 2000.0: 2195.0, + 1000.0: 1166.0, + }, aspiration_flow_rate=1200.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=30.0, @@ -2712,13 +3130,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(5000, False, True, False, Liquid.GLYCERIN80, False, True)] = \ -_5mlT_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 555.0, 50.0: 71.0, 5000.0: 5135.0, 4000.0: 4115.0, 0.0: 0.0, 3000.0: 3127.0, 100.0: 127.0, 2000.0: 2115.0, 10.0: 15.5, 1000.0: 1075.0}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(5000, False, True, False, Liquid.GLYCERIN80, False, True)] = ( + _5mlT_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 555.0, + 50.0: 71.0, + 5000.0: 5135.0, + 4000.0: 4115.0, + 0.0: 0.0, + 3000.0: 3127.0, + 100.0: 127.0, + 2000.0: 2115.0, + 10.0: 15.5, + 1000.0: 1075.0, + }, aspiration_flow_rate=1000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=0.0, @@ -2735,13 +3165,22 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(5000, False, True, False, Liquid.WATER, True, False)] = \ -_5mlT_Water_DispenseJet_Aliquot = HamiltonLiquidClass( - curve={5000.0: 5030.0, 4000.0: 4040.0, 0.0: 0.0, 3000.0: 3050.0, 100.0: 104.0, 2000.0: 2050.0, 1000.0: 1040.0}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(5000, False, True, False, Liquid.WATER, True, False)] = ( + _5mlT_Water_DispenseJet_Aliquot +) = HamiltonLiquidClass( + curve={ + 5000.0: 5030.0, + 4000.0: 4040.0, + 0.0: 0.0, + 3000.0: 3050.0, + 100.0: 104.0, + 2000.0: 2050.0, + 1000.0: 1040.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2758,13 +3197,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=20.0 -) - - -star_mapping[(5000, False, True, False, Liquid.WATER, True, True)] = \ -_5mlT_Water_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 551.8, 50.0: 66.4, 5000.0: 5180.0, 4000.0: 4165.0, 0.0: 0.0, 3000.0: 3148.0, 100.0: 122.7, 2000.0: 2128.0, 1000.0: 1082.0}, + dispense_stop_back_volume=20.0, +) + + +star_mapping[(5000, False, True, False, Liquid.WATER, True, True)] = ( + _5mlT_Water_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 551.8, + 50.0: 66.4, + 5000.0: 5180.0, + 4000.0: 4165.0, + 0.0: 0.0, + 3000.0: 3148.0, + 100.0: 122.7, + 2000.0: 2128.0, + 1000.0: 1082.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2781,13 +3231,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(5000, False, True, False, Liquid.WATER, False, True)] = \ -_5mlT_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 547.0, 50.0: 65.5, 5000.0: 5145.0, 4000.0: 4145.0, 0.0: 0.0, 3000.0: 3130.0, 100.0: 120.9, 2000.0: 2125.0, 10.0: 15.1, 1000.0: 1075.0}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(5000, False, True, False, Liquid.WATER, False, True)] = ( + _5mlT_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 547.0, + 50.0: 65.5, + 5000.0: 5145.0, + 4000.0: 4145.0, + 0.0: 0.0, + 3000.0: 3130.0, + 100.0: 120.9, + 2000.0: 2125.0, + 10.0: 15.1, + 1000.0: 1075.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2804,14 +3266,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=500.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = \ -HighNeedle_Water_DispenseJet = HamiltonLiquidClass( - curve={500.0: 527.3, 50.0: 56.8, 0.0: 0.0, 100.0: 110.4, 20.0: 24.7, 1000.0: 1046.5, 200.0: 214.6, 10.0: 13.2}, +star_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = ( + HighNeedle_Water_DispenseJet +) = HamiltonLiquidClass( + curve={ + 500.0: 527.3, + 50.0: 56.8, + 0.0: 0.0, + 100.0: 110.4, + 20.0: 24.7, + 1000.0: 1046.5, + 200.0: 214.6, + 10.0: 13.2, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -2828,13 +3300,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=350.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, False, False, Liquid.WATER, True, True)] = \ -HighNeedle_Water_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 527.3, 50.0: 56.8, 0.0: 0.0, 100.0: 110.4, 20.0: 24.7, 1000.0: 1046.5, 200.0: 214.6, 10.0: 13.2}, +star_mapping[(1000, False, False, False, Liquid.WATER, True, True)] = ( + HighNeedle_Water_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 527.3, + 50.0: 56.8, + 0.0: 0.0, + 100.0: 110.4, + 20.0: 24.7, + 1000.0: 1046.5, + 200.0: 214.6, + 10.0: 13.2, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -2851,13 +3333,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=350.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = \ -HighNeedle_Water_DispenseJet_Part = HamiltonLiquidClass( - curve={500.0: 527.3, 50.0: 56.8, 0.0: 0.0, 100.0: 110.4, 20.0: 24.7, 1000.0: 1046.5, 200.0: 214.6, 10.0: 13.2}, +star_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = ( + HighNeedle_Water_DispenseJet_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 527.3, + 50.0: 56.8, + 0.0: 0.0, + 100.0: 110.4, + 20.0: 24.7, + 1000.0: 1046.5, + 200.0: 214.6, + 10.0: 13.2, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -2874,13 +3366,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=350.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 120 -star_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = \ -HighNeedle_Water_DispenseSurface = HamiltonLiquidClass( +star_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = ( + HighNeedle_Water_DispenseSurface +) = HamiltonLiquidClass( curve={50.0: 53.1, 0.0: 0.0, 20.0: 22.3, 1000.0: 1000.0, 10.0: 10.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, @@ -2898,12 +3391,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, False, False, Liquid.WATER, False, True)] = \ -HighNeedle_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(1000, False, False, False, Liquid.WATER, False, True)] = ( + HighNeedle_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={50.0: 53.1, 0.0: 0.0, 20.0: 22.3, 1000.0: 1000.0, 10.0: 10.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, @@ -2921,12 +3415,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = \ -HighNeedle_Water_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = ( + HighNeedle_Water_DispenseSurface_Part +) = HamiltonLiquidClass( curve={50.0: 53.1, 0.0: 0.0, 20.0: 22.3, 1000.0: 1000.0, 10.0: 10.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, @@ -2944,7 +3439,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -2963,8 +3458,9 @@ def get_star_liquid_class(**kwargs): # 100 0.32 0.54 # 500 0.13 -0.06 # 1000 0.11 0.17 -star_mapping[(1000, False, True, False, Liquid.ACETONITRIL80WATER20, True, False)] = \ -HighVolumeAcetonitril80Water20DispenseJet = HamiltonLiquidClass( +star_mapping[(1000, False, True, False, Liquid.ACETONITRIL80WATER20, True, False)] = ( + HighVolumeAcetonitril80Water20DispenseJet +) = HamiltonLiquidClass( curve={500.0: 514.5, 50.0: 57.5, 0.0: 0.0, 20.0: 25.0, 100.0: 110.5, 1000.0: 1020.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -2982,7 +3478,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -3001,9 +3497,18 @@ def get_star_liquid_class(**kwargs): # 200 0.22 0.71 # 500 0.14 0.01 # 1000 0.17 0.02 -star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, False)] = \ -HighVolumeAcetonitrilDispenseJet = HamiltonLiquidClass( - curve={500.0: 526.5, 250.0: 269.0, 50.0: 60.5, 0.0: 0.0, 20.0: 25.5, 100.0: 112.7, 1000.0: 1045.0}, +star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, False)] = ( + HighVolumeAcetonitrilDispenseJet +) = HamiltonLiquidClass( + curve={ + 500.0: 526.5, + 250.0: 269.0, + 50.0: 60.5, + 0.0: 0.0, + 20.0: 25.5, + 100.0: 112.7, + 1000.0: 1045.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -3020,13 +3525,22 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, True)] = \ -HighVolumeAcetonitrilDispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 526.5, 250.0: 269.0, 50.0: 60.5, 0.0: 0.0, 100.0: 112.7, 20.0: 25.5, 1000.0: 1045.0}, +star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, True)] = ( + HighVolumeAcetonitrilDispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 526.5, + 250.0: 269.0, + 50.0: 60.5, + 0.0: 0.0, + 100.0: 112.7, + 20.0: 25.5, + 1000.0: 1045.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -3043,13 +3557,22 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, False)] = \ -HighVolumeAcetonitrilDispenseJet_Part = HamiltonLiquidClass( - curve={500.0: 526.5, 250.0: 269.0, 50.0: 60.5, 0.0: 0.0, 100.0: 112.7, 20.0: 25.5, 1000.0: 1045.0}, +star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, False)] = ( + HighVolumeAcetonitrilDispenseJet_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 526.5, + 250.0: 269.0, + 50.0: 60.5, + 0.0: 0.0, + 100.0: 112.7, + 20.0: 25.5, + 1000.0: 1045.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -3066,7 +3589,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) @@ -3086,9 +3609,19 @@ def get_star_liquid_class(**kwargs): # 200 0.18 0.69 # 500 0.23 0.04 # 1000 0.22 0.05 -star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, False)] = \ -HighVolumeAcetonitrilDispenseSurface = HamiltonLiquidClass( - curve={500.0: 525.4, 250.0: 267.0, 50.0: 57.6, 0.0: 0.0, 20.0: 23.8, 100.0: 111.2, 10.0: 12.1, 1000.0: 1048.8}, +star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, False)] = ( + HighVolumeAcetonitrilDispenseSurface +) = HamiltonLiquidClass( + curve={ + 500.0: 525.4, + 250.0: 267.0, + 50.0: 57.6, + 0.0: 0.0, + 20.0: 23.8, + 100.0: 111.2, + 10.0: 12.1, + 1000.0: 1048.8, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=10.0, @@ -3105,13 +3638,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, True)] = \ -HighVolumeAcetonitrilDispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 525.4, 250.0: 267.0, 50.0: 57.6, 0.0: 0.0, 100.0: 111.2, 20.0: 23.8, 1000.0: 1048.8, 10.0: 12.1}, +star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, True)] = ( + HighVolumeAcetonitrilDispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 525.4, + 250.0: 267.0, + 50.0: 57.6, + 0.0: 0.0, + 100.0: 111.2, + 20.0: 23.8, + 1000.0: 1048.8, + 10.0: 12.1, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=10.0, @@ -3128,13 +3671,22 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, False)] = \ -HighVolumeAcetonitrilDispenseSurface_Part = HamiltonLiquidClass( - curve={500.0: 525.4, 250.0: 267.0, 50.0: 57.6, 0.0: 0.0, 100.0: 111.2, 20.0: 23.8, 1000.0: 1048.8}, +star_mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, False)] = ( + HighVolumeAcetonitrilDispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 525.4, + 250.0: 267.0, + 50.0: 57.6, + 0.0: 0.0, + 100.0: 111.2, + 20.0: 23.8, + 1000.0: 1048.8, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=10.0, @@ -3151,16 +3703,26 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # - Submerge depth: Aspiration 2.0mm # (bei Schaumbildung durch mischen/vorbenetzen evtl.5mm, LLD-Erkennung) # - Mischen 3-5 x 950µl, mix position 0.5mm, je nach Volumen im Tube -star_mapping[(1000, False, True, False, Liquid.BLOOD, True, False)] = \ -HighVolumeBloodDispenseJet = HamiltonLiquidClass( - curve={500.0: 536.3, 250.0: 275.6, 50.0: 59.8, 0.0: 0.0, 20.0: 26.2, 100.0: 115.3, 10.0: 12.2, 1000.0: 1061.6}, +star_mapping[(1000, False, True, False, Liquid.BLOOD, True, False)] = ( + HighVolumeBloodDispenseJet +) = HamiltonLiquidClass( + curve={ + 500.0: 536.3, + 250.0: 275.6, + 50.0: 59.8, + 0.0: 0.0, + 20.0: 26.2, + 100.0: 115.3, + 10.0: 12.2, + 1000.0: 1061.6, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3177,7 +3739,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=300.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -3198,8 +3760,9 @@ def get_star_liquid_class(**kwargs): # 100 0.23 0.93 # 200 0.15 0.41 # -star_mapping[(1000, False, True, False, Liquid.BRAINHOMOGENATE, True, False)] = \ -HighVolumeBrainHomogenateDispenseJet = HamiltonLiquidClass( +star_mapping[(1000, False, True, False, Liquid.BRAINHOMOGENATE, True, False)] = ( + HighVolumeBrainHomogenateDispenseJet +) = HamiltonLiquidClass( curve={50.0: 57.9, 0.0: 0.0, 20.0: 25.3, 100.0: 111.3, 10.0: 14.2, 200.0: 214.5, 1000.0: 1038.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -3217,7 +3780,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -3237,8 +3800,9 @@ def get_star_liquid_class(**kwargs): # # # -star_mapping[(1000, False, True, False, Liquid.CHLOROFORM, True, False)] = \ -HighVolumeChloroformDispenseJet = HamiltonLiquidClass( +star_mapping[(1000, False, True, False, Liquid.CHLOROFORM, True, False)] = ( + HighVolumeChloroformDispenseJet +) = HamiltonLiquidClass( curve={500.0: 520.5, 250.0: 269.0, 50.0: 62.9, 0.0: 0.0, 100.0: 116.3, 1000.0: 1030.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, @@ -3256,7 +3820,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -3277,9 +3841,20 @@ def get_star_liquid_class(**kwargs): # 100 ( 9 Aliquots) 0.25 -4.81 # # -star_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = \ -HighVolumeDMSOAliquotJet = HamiltonLiquidClass( - curve={500.0: 500.0, 250.0: 250.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 100.0: 100.0, 10.0: 10.0, 750.0: 750.0, 1000.0: 1000.0}, +star_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = ( + HighVolumeDMSOAliquotJet +) = HamiltonLiquidClass( + curve={ + 500.0: 500.0, + 250.0: 250.0, + 0.0: 0.0, + 30.0: 30.0, + 20.0: 20.0, + 100.0: 100.0, + 10.0: 10.0, + 750.0: 750.0, + 1000.0: 1000.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -3296,12 +3871,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -star_mapping[(1000, True, True, True, Liquid.DMSO, True, True)] = \ -HighVolumeFilter_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(1000, True, True, True, Liquid.DMSO, True, True)] = ( + HighVolumeFilter_96COREHead1000ul_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={500.0: 508.2, 0.0: 0.0, 20.0: 21.7, 100.0: 101.7, 1000.0: 1017.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -3319,12 +3895,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, True, True, True, Liquid.DMSO, False, True)] = \ -HighVolumeFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(1000, True, True, True, Liquid.DMSO, False, True)] = ( + HighVolumeFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={500.0: 512.5, 0.0: 0.0, 100.0: 105.8, 10.0: 12.7, 1000.0: 1024.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, @@ -3342,12 +3919,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, True, True, True, Liquid.WATER, True, True)] = \ -HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(1000, True, True, True, Liquid.WATER, True, True)] = ( + HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={500.0: 524.0, 0.0: 0.0, 20.0: 24.0, 100.0: 109.2, 1000.0: 1040.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -3365,12 +3943,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, True, True, True, Liquid.WATER, False, True)] = \ -HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(1000, True, True, True, Liquid.WATER, False, True)] = ( + HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={500.0: 522.0, 0.0: 0.0, 100.0: 108.3, 1000.0: 1034.0, 10.0: 12.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, @@ -3388,7 +3967,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -3409,9 +3988,20 @@ def get_star_liquid_class(**kwargs): # 100 ( 9 Aliquots) 0.25 -4.81 # # -star_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = \ -HighVolumeFilter_DMSO_AliquotDispenseJet_Part = HamiltonLiquidClass( - curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, +star_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = ( + HighVolumeFilter_DMSO_AliquotDispenseJet_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 500.0, + 250.0: 250.0, + 30.0: 30.0, + 0.0: 0.0, + 100.0: 100.0, + 20.0: 20.0, + 1000.0: 1000.0, + 750.0: 750.0, + 10.0: 10.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -3428,14 +4018,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = \ -HighVolumeFilter_DMSO_DispenseJet = HamiltonLiquidClass( - curve={5.0: 5.1, 500.0: 511.2, 250.0: 256.2, 50.0: 52.2, 0.0: 0.0, 20.0: 21.3, 100.0: 103.4, 10.0: 10.7, 1000.0: 1021.0}, +star_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = ( + HighVolumeFilter_DMSO_DispenseJet +) = HamiltonLiquidClass( + curve={ + 5.0: 5.1, + 500.0: 511.2, + 250.0: 256.2, + 50.0: 52.2, + 0.0: 0.0, + 20.0: 21.3, + 100.0: 103.4, + 10.0: 10.7, + 1000.0: 1021.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3452,13 +4053,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, True, Liquid.DMSO, True, True)] = \ -HighVolumeFilter_DMSO_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 511.2, 5.0: 5.1, 250.0: 256.2, 50.0: 52.2, 0.0: 0.0, 100.0: 103.4, 20.0: 21.3, 1000.0: 1021.0, 10.0: 10.7}, +star_mapping[(1000, False, True, True, Liquid.DMSO, True, True)] = ( + HighVolumeFilter_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 511.2, + 5.0: 5.1, + 250.0: 256.2, + 50.0: 52.2, + 0.0: 0.0, + 100.0: 103.4, + 20.0: 21.3, + 1000.0: 1021.0, + 10.0: 10.7, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3475,12 +4087,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = \ -HighVolumeFilter_DMSO_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = ( + HighVolumeFilter_DMSO_DispenseJet_Part +) = HamiltonLiquidClass( curve={500.0: 517.2, 0.0: 0.0, 100.0: 109.5, 20.0: 27.0, 1000.0: 1027.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -3498,14 +4111,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 120 -star_mapping[(1000, False, True, True, Liquid.DMSO, False, False)] = \ -HighVolumeFilter_DMSO_DispenseSurface = HamiltonLiquidClass( - curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 20.0: 22.8, 100.0: 105.8, 10.0: 12.1, 1000.0: 1024.5}, +star_mapping[(1000, False, True, True, Liquid.DMSO, False, False)] = ( + HighVolumeFilter_DMSO_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 500.0: 514.3, + 250.0: 259.0, + 50.0: 54.4, + 0.0: 0.0, + 20.0: 22.8, + 100.0: 105.8, + 10.0: 12.1, + 1000.0: 1024.5, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -3522,13 +4145,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, True, Liquid.DMSO, False, True)] = \ -HighVolumeFilter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 100.0: 105.8, 20.0: 22.8, 1000.0: 1024.5, 10.0: 12.1}, +star_mapping[(1000, False, True, True, Liquid.DMSO, False, True)] = ( + HighVolumeFilter_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 514.3, + 250.0: 259.0, + 50.0: 54.4, + 0.0: 0.0, + 100.0: 105.8, + 20.0: 22.8, + 1000.0: 1024.5, + 10.0: 12.1, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -3545,14 +4178,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # -star_mapping[(1000, False, True, True, Liquid.DMSO, False, False)] = \ -HighVolumeFilter_DMSO_DispenseSurface_Part = HamiltonLiquidClass( - curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 100.0: 105.8, 20.0: 22.8, 1000.0: 1024.5, 10.0: 12.1}, +star_mapping[(1000, False, True, True, Liquid.DMSO, False, False)] = ( + HighVolumeFilter_DMSO_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 514.3, + 250.0: 259.0, + 50.0: 54.4, + 0.0: 0.0, + 100.0: 105.8, + 20.0: 22.8, + 1000.0: 1024.5, + 10.0: 12.1, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -3569,14 +4212,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 250, Stop back volume = 0 -star_mapping[(1000, False, True, True, Liquid.ETHANOL, True, False)] = \ -HighVolumeFilter_EtOH_DispenseJet = HamiltonLiquidClass( - curve={500.0: 534.8, 250.0: 273.0, 50.0: 62.9, 0.0: 0.0, 20.0: 27.8, 100.0: 116.3, 10.0: 15.8, 1000.0: 1053.9}, +star_mapping[(1000, False, True, True, Liquid.ETHANOL, True, False)] = ( + HighVolumeFilter_EtOH_DispenseJet +) = HamiltonLiquidClass( + curve={ + 500.0: 534.8, + 250.0: 273.0, + 50.0: 62.9, + 0.0: 0.0, + 20.0: 27.8, + 100.0: 116.3, + 10.0: 15.8, + 1000.0: 1053.9, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3593,13 +4246,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, True, Liquid.ETHANOL, True, True)] = \ -HighVolumeFilter_EtOH_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 534.8, 250.0: 273.0, 50.0: 62.9, 0.0: 0.0, 100.0: 116.3, 20.0: 27.8, 1000.0: 1053.9, 10.0: 15.8}, +star_mapping[(1000, False, True, True, Liquid.ETHANOL, True, True)] = ( + HighVolumeFilter_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 534.8, + 250.0: 273.0, + 50.0: 62.9, + 0.0: 0.0, + 100.0: 116.3, + 20.0: 27.8, + 1000.0: 1053.9, + 10.0: 15.8, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3616,13 +4279,22 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, True, Liquid.ETHANOL, True, False)] = \ -HighVolumeFilter_EtOH_DispenseJet_Part = HamiltonLiquidClass( - curve={500.0: 534.8, 250.0: 273.0, 50.0: 62.9, 0.0: 0.0, 100.0: 116.3, 20.0: 27.8, 1000.0: 1053.9}, +star_mapping[(1000, False, True, True, Liquid.ETHANOL, True, False)] = ( + HighVolumeFilter_EtOH_DispenseJet_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 534.8, + 250.0: 273.0, + 50.0: 62.9, + 0.0: 0.0, + 100.0: 116.3, + 20.0: 27.8, + 1000.0: 1053.9, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3639,14 +4311,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=5.0 + dispense_stop_back_volume=5.0, ) # V1.1: Set mix flow rate to 120 -star_mapping[(1000, False, True, True, Liquid.ETHANOL, False, False)] = \ -HighVolumeFilter_EtOH_DispenseSurface = HamiltonLiquidClass( - curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 20.0: 27.6, 100.0: 114.0, 10.0: 15.7, 1000.0: 1044.3}, +star_mapping[(1000, False, True, True, Liquid.ETHANOL, False, False)] = ( + HighVolumeFilter_EtOH_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 500.0: 528.4, + 250.0: 269.2, + 50.0: 61.2, + 0.0: 0.0, + 20.0: 27.6, + 100.0: 114.0, + 10.0: 15.7, + 1000.0: 1044.3, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -3663,13 +4345,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, True, Liquid.ETHANOL, False, True)] = \ -HighVolumeFilter_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 100.0: 114.0, 20.0: 27.6, 1000.0: 1044.3, 10.0: 15.7}, +star_mapping[(1000, False, True, True, Liquid.ETHANOL, False, True)] = ( + HighVolumeFilter_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 528.4, + 250.0: 269.2, + 50.0: 61.2, + 0.0: 0.0, + 100.0: 114.0, + 20.0: 27.6, + 1000.0: 1044.3, + 10.0: 15.7, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -3686,13 +4378,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, True, Liquid.ETHANOL, False, False)] = \ -HighVolumeFilter_EtOH_DispenseSurface_Part = HamiltonLiquidClass( - curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 100.0: 114.0, 20.0: 27.6, 1000.0: 1044.3, 10.0: 15.7}, +star_mapping[(1000, False, True, True, Liquid.ETHANOL, False, False)] = ( + HighVolumeFilter_EtOH_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 528.4, + 250.0: 269.2, + 50.0: 61.2, + 0.0: 0.0, + 100.0: 114.0, + 20.0: 27.6, + 1000.0: 1044.3, + 10.0: 15.7, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -3709,14 +4411,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 200 -star_mapping[(1000, False, True, True, Liquid.GLYCERIN80, True, False)] = \ -HighVolumeFilter_Glycerin80_DispenseJet = HamiltonLiquidClass( - curve={500.0: 537.8, 250.0: 277.0, 50.0: 63.3, 0.0: 0.0, 20.0: 28.0, 100.0: 118.8, 10.0: 15.2, 1000.0: 1060.0}, +star_mapping[(1000, False, True, True, Liquid.GLYCERIN80, True, False)] = ( + HighVolumeFilter_Glycerin80_DispenseJet +) = HamiltonLiquidClass( + curve={ + 500.0: 537.8, + 250.0: 277.0, + 50.0: 63.3, + 0.0: 0.0, + 20.0: 28.0, + 100.0: 118.8, + 10.0: 15.2, + 1000.0: 1060.0, + }, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=5.0, @@ -3733,14 +4445,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 200 -star_mapping[(1000, False, True, True, Liquid.GLYCERIN80, True, True)] = \ -HighVolumeFilter_Glycerin80_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 537.8, 250.0: 277.0, 50.0: 63.3, 0.0: 0.0, 100.0: 118.8, 20.0: 28.0, 1000.0: 1060.0, 10.0: 15.2}, +star_mapping[(1000, False, True, True, Liquid.GLYCERIN80, True, True)] = ( + HighVolumeFilter_Glycerin80_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 537.8, + 250.0: 277.0, + 50.0: 63.3, + 0.0: 0.0, + 100.0: 118.8, + 20.0: 28.0, + 1000.0: 1060.0, + 10.0: 15.2, + }, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=5.0, @@ -3757,14 +4479,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 120 -star_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, False)] = \ -HighVolumeFilter_Glycerin80_DispenseSurface = HamiltonLiquidClass( - curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 20.0: 22.7, 100.0: 105.5, 10.0: 12.2, 1000.0: 1027.2}, +star_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, False)] = ( + HighVolumeFilter_Glycerin80_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 500.0: 513.5, + 250.0: 257.2, + 50.0: 55.0, + 0.0: 0.0, + 20.0: 22.7, + 100.0: 105.5, + 10.0: 12.2, + 1000.0: 1027.2, + }, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -3781,13 +4513,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, True)] = \ -HighVolumeFilter_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 100.0: 105.5, 20.0: 22.7, 1000.0: 1027.2, 10.0: 12.2}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, True)] = ( + HighVolumeFilter_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 513.5, + 250.0: 257.2, + 50.0: 55.0, + 0.0: 0.0, + 100.0: 105.5, + 20.0: 22.7, + 1000.0: 1027.2, + 10.0: 12.2, + }, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -3804,13 +4546,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, False)] = \ -HighVolumeFilter_Glycerin80_DispenseSurface_Part = HamiltonLiquidClass( - curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 100.0: 105.5, 20.0: 22.7, 1000.0: 1027.2, 10.0: 12.2}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, False)] = ( + HighVolumeFilter_Glycerin80_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 513.5, + 250.0: 257.2, + 50.0: 55.0, + 0.0: 0.0, + 100.0: 105.5, + 20.0: 22.7, + 1000.0: 1027.2, + 10.0: 12.2, + }, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -3827,14 +4579,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = \ -HighVolumeFilter_Serum_AliquotDispenseJet_Part = HamiltonLiquidClass( - curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, +star_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = ( + HighVolumeFilter_Serum_AliquotDispenseJet_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 500.0, + 250.0: 250.0, + 30.0: 30.0, + 0.0: 0.0, + 100.0: 100.0, + 20.0: 20.0, + 1000.0: 1000.0, + 750.0: 750.0, + 10.0: 10.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -3851,14 +4614,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=300.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = \ -HighVolumeFilter_Serum_AliquotJet = HamiltonLiquidClass( - curve={500.0: 500.0, 250.0: 250.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 100.0: 100.0, 10.0: 10.0, 750.0: 750.0, 1000.0: 1000.0}, +star_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = ( + HighVolumeFilter_Serum_AliquotJet +) = HamiltonLiquidClass( + curve={ + 500.0: 500.0, + 250.0: 250.0, + 0.0: 0.0, + 30.0: 30.0, + 20.0: 20.0, + 100.0: 100.0, + 10.0: 10.0, + 750.0: 750.0, + 1000.0: 1000.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -3875,14 +4649,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=300.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 250, Settling time = 0 -star_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = \ -HighVolumeFilter_Serum_DispenseJet = HamiltonLiquidClass( - curve={500.0: 525.3, 250.0: 266.6, 50.0: 57.9, 0.0: 0.0, 20.0: 24.2, 100.0: 111.3, 10.0: 12.2, 1000.0: 1038.6}, +star_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = ( + HighVolumeFilter_Serum_DispenseJet +) = HamiltonLiquidClass( + curve={ + 500.0: 525.3, + 250.0: 266.6, + 50.0: 57.9, + 0.0: 0.0, + 20.0: 24.2, + 100.0: 111.3, + 10.0: 12.2, + 1000.0: 1038.6, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3899,13 +4683,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, True, Liquid.SERUM, True, True)] = \ -HighVolumeFilter_Serum_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 525.3, 250.0: 266.6, 50.0: 57.9, 0.0: 0.0, 100.0: 111.3, 20.0: 24.2, 1000.0: 1038.6, 10.0: 12.2}, +star_mapping[(1000, False, True, True, Liquid.SERUM, True, True)] = ( + HighVolumeFilter_Serum_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 525.3, + 250.0: 266.6, + 50.0: 57.9, + 0.0: 0.0, + 100.0: 111.3, + 20.0: 24.2, + 1000.0: 1038.6, + 10.0: 12.2, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3922,12 +4716,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = \ -HighVolumeFilter_Serum_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = ( + HighVolumeFilter_Serum_DispenseJet_Part +) = HamiltonLiquidClass( curve={500.0: 525.3, 0.0: 0.0, 100.0: 111.3, 20.0: 27.3, 1000.0: 1046.6}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -3945,14 +4740,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 120 -star_mapping[(1000, False, True, True, Liquid.SERUM, False, False)] = \ -HighVolumeFilter_Serum_DispenseSurface = HamiltonLiquidClass( - curve={500.0: 517.5, 250.0: 261.9, 50.0: 55.9, 0.0: 0.0, 20.0: 23.2, 100.0: 108.2, 10.0: 11.8, 1000.0: 1026.7}, +star_mapping[(1000, False, True, True, Liquid.SERUM, False, False)] = ( + HighVolumeFilter_Serum_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 500.0: 517.5, + 250.0: 261.9, + 50.0: 55.9, + 0.0: 0.0, + 20.0: 23.2, + 100.0: 108.2, + 10.0: 11.8, + 1000.0: 1026.7, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -3969,13 +4774,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, True, Liquid.SERUM, False, True)] = \ -HighVolumeFilter_Serum_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 517.5, 250.0: 261.9, 50.0: 55.9, 0.0: 0.0, 100.0: 108.2, 20.0: 23.2, 1000.0: 1026.7, 10.0: 11.8}, +star_mapping[(1000, False, True, True, Liquid.SERUM, False, True)] = ( + HighVolumeFilter_Serum_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 517.5, + 250.0: 261.9, + 50.0: 55.9, + 0.0: 0.0, + 100.0: 108.2, + 20.0: 23.2, + 1000.0: 1026.7, + 10.0: 11.8, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -3992,12 +4807,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, True, Liquid.SERUM, False, False)] = \ -HighVolumeFilter_Serum_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(1000, False, True, True, Liquid.SERUM, False, False)] = ( + HighVolumeFilter_Serum_DispenseSurface_Part +) = HamiltonLiquidClass( curve={500.0: 523.5, 0.0: 0.0, 100.0: 111.2, 20.0: 23.2, 1000.0: 1038.7, 10.0: 11.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, @@ -4015,14 +4831,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = \ -HighVolumeFilter_Water_AliquotDispenseJet_Part = HamiltonLiquidClass( - curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, +star_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = ( + HighVolumeFilter_Water_AliquotDispenseJet_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 500.0, + 250.0: 250.0, + 30.0: 30.0, + 0.0: 0.0, + 100.0: 100.0, + 20.0: 20.0, + 1000.0: 1000.0, + 750.0: 750.0, + 10.0: 10.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -4039,14 +4866,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = \ -HighVolumeFilter_Water_AliquotJet = HamiltonLiquidClass( - curve={500.0: 500.0, 250.0: 250.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 100.0: 100.0, 10.0: 10.0, 750.0: 750.0, 1000.0: 1000.0}, +star_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = ( + HighVolumeFilter_Water_AliquotJet +) = HamiltonLiquidClass( + curve={ + 500.0: 500.0, + 250.0: 250.0, + 0.0: 0.0, + 30.0: 30.0, + 20.0: 20.0, + 100.0: 100.0, + 10.0: 10.0, + 750.0: 750.0, + 1000.0: 1000.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -4063,14 +4901,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = \ -HighVolumeFilter_Water_DispenseJet = HamiltonLiquidClass( - curve={500.0: 521.7, 50.0: 57.2, 0.0: 0.0, 20.0: 24.6, 100.0: 109.6, 10.0: 13.3, 200.0: 212.9, 1000.0: 1034.0}, +star_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = ( + HighVolumeFilter_Water_DispenseJet +) = HamiltonLiquidClass( + curve={ + 500.0: 521.7, + 50.0: 57.2, + 0.0: 0.0, + 20.0: 24.6, + 100.0: 109.6, + 10.0: 13.3, + 200.0: 212.9, + 1000.0: 1034.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4087,13 +4935,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, True, Liquid.WATER, True, True)] = \ -HighVolumeFilter_Water_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 521.7, 50.0: 57.2, 0.0: 0.0, 100.0: 109.6, 20.0: 24.6, 1000.0: 1034.0, 200.0: 212.9, 10.0: 13.3}, +star_mapping[(1000, False, True, True, Liquid.WATER, True, True)] = ( + HighVolumeFilter_Water_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 521.7, + 50.0: 57.2, + 0.0: 0.0, + 100.0: 109.6, + 20.0: 24.6, + 1000.0: 1034.0, + 200.0: 212.9, + 10.0: 13.3, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4110,13 +4968,22 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = \ -HighVolumeFilter_Water_DispenseJet_Part = HamiltonLiquidClass( - curve={500.0: 521.7, 50.0: 57.2, 0.0: 0.0, 100.0: 109.6, 20.0: 27.0, 1000.0: 1034.0, 200.0: 212.9}, +star_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = ( + HighVolumeFilter_Water_DispenseJet_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 521.7, + 50.0: 57.2, + 0.0: 0.0, + 100.0: 109.6, + 20.0: 27.0, + 1000.0: 1034.0, + 200.0: 212.9, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4133,14 +5000,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 120, Clot retract hight = 0 -star_mapping[(1000, False, True, True, Liquid.WATER, False, False)] = \ -HighVolumeFilter_Water_DispenseSurface = HamiltonLiquidClass( - curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 20.0: 23.9, 100.0: 108.3, 10.0: 12.5, 200.0: 211.0, 1000.0: 1028.5}, +star_mapping[(1000, False, True, True, Liquid.WATER, False, False)] = ( + HighVolumeFilter_Water_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 500.0: 518.3, + 50.0: 56.3, + 0.0: 0.0, + 20.0: 23.9, + 100.0: 108.3, + 10.0: 12.5, + 200.0: 211.0, + 1000.0: 1028.5, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -4157,13 +5034,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, True, Liquid.WATER, False, True)] = \ -HighVolumeFilter_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 20.0: 23.9, 100.0: 108.3, 10.0: 12.5, 200.0: 211.0, 1000.0: 1028.5}, +star_mapping[(1000, False, True, True, Liquid.WATER, False, True)] = ( + HighVolumeFilter_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 518.3, + 50.0: 56.3, + 0.0: 0.0, + 20.0: 23.9, + 100.0: 108.3, + 10.0: 12.5, + 200.0: 211.0, + 1000.0: 1028.5, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -4180,13 +5067,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, True, Liquid.WATER, False, False)] = \ -HighVolumeFilter_Water_DispenseSurface_Part = HamiltonLiquidClass( - curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 100.0: 108.3, 20.0: 23.9, 1000.0: 1028.5, 200.0: 211.0, 10.0: 12.7}, +star_mapping[(1000, False, True, True, Liquid.WATER, False, False)] = ( + HighVolumeFilter_Water_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 518.3, + 50.0: 56.3, + 0.0: 0.0, + 100.0: 108.3, + 20.0: 23.9, + 1000.0: 1028.5, + 200.0: 211.0, + 10.0: 12.7, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4203,7 +5100,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -4227,8 +5124,9 @@ def get_star_liquid_class(**kwargs): # 500 0.49 - 0.17 # 1000 0.55 0.712 # -star_mapping[(1000, False, True, False, Liquid.METHANOL, True, False)] = \ -HighVolumeMeOHDispenseJet = HamiltonLiquidClass( +star_mapping[(1000, False, True, False, Liquid.METHANOL, True, False)] = ( + HighVolumeMeOHDispenseJet +) = HamiltonLiquidClass( curve={500.0: 520.5, 250.0: 269.0, 50.0: 62.9, 0.0: 0.0, 100.0: 116.3, 1000.0: 1030.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, @@ -4246,7 +5144,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -4272,9 +5170,19 @@ def get_star_liquid_class(**kwargs): # 200 0.48 0.18 # 500 0.17 0.22 # 1000 0.75 0.29 -star_mapping[(1000, False, True, False, Liquid.METHANOL, False, False)] = \ -HighVolumeMeOHDispenseSurface = HamiltonLiquidClass( - curve={500.0: 518.0, 50.0: 61.3, 0.0: 0.0, 20.0: 29.3, 100.0: 111.0, 10.0: 19.3, 200.0: 215.0, 1000.0: 1030.0}, +star_mapping[(1000, False, True, False, Liquid.METHANOL, False, False)] = ( + HighVolumeMeOHDispenseSurface +) = HamiltonLiquidClass( + curve={ + 500.0: 518.0, + 50.0: 61.3, + 0.0: 0.0, + 20.0: 29.3, + 100.0: 111.0, + 10.0: 19.3, + 200.0: 215.0, + 1000.0: 1030.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=10.0, @@ -4291,7 +5199,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -4313,8 +5221,9 @@ def get_star_liquid_class(**kwargs): # 200 0.14 0.06 # 500 0.12 - 0.07 # 1000 0.16 0.08 -star_mapping[(1000, False, True, False, Liquid.METHANOL70WATER030, True, False)] = \ -HighVolumeMeOHH2ODispenseJet = HamiltonLiquidClass( +star_mapping[(1000, False, True, False, Liquid.METHANOL70WATER030, True, False)] = ( + HighVolumeMeOHH2ODispenseJet +) = HamiltonLiquidClass( curve={500.0: 528.5, 250.0: 269.0, 50.0: 60.5, 0.0: 0.0, 100.0: 114.3, 1000.0: 1050.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, @@ -4332,7 +5241,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -4352,9 +5261,19 @@ def get_star_liquid_class(**kwargs): # 20 2.85 2.92 # 200 0.14 0.59 # -star_mapping[(1000, False, True, False, Liquid.OCTANOL, True, False)] = \ -HighVolumeOctanol100DispenseJet = HamiltonLiquidClass( - curve={500.0: 537.8, 250.0: 277.0, 50.0: 63.3, 0.0: 0.0, 20.0: 28.0, 100.0: 118.8, 10.0: 15.2, 1000.0: 1060.0}, +star_mapping[(1000, False, True, False, Liquid.OCTANOL, True, False)] = ( + HighVolumeOctanol100DispenseJet +) = HamiltonLiquidClass( + curve={ + 500.0: 537.8, + 250.0: 277.0, + 50.0: 63.3, + 0.0: 0.0, + 20.0: 28.0, + 100.0: 118.8, + 10.0: 15.2, + 1000.0: 1060.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -4371,7 +5290,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -4392,9 +5311,19 @@ def get_star_liquid_class(**kwargs): # 200 0.30 1.30 # 500 0.31 0.01 # 1000 0.33 0.01 -star_mapping[(1000, False, True, False, Liquid.OCTANOL, False, False)] = \ -HighVolumeOctanol100DispenseSurface = HamiltonLiquidClass( - curve={500.0: 531.3, 250.0: 265.0, 50.0: 54.4, 0.0: 0.0, 20.0: 23.3, 100.0: 108.8, 10.0: 12.1, 1000.0: 1058.0}, +star_mapping[(1000, False, True, False, Liquid.OCTANOL, False, False)] = ( + HighVolumeOctanol100DispenseSurface +) = HamiltonLiquidClass( + curve={ + 500.0: 531.3, + 250.0: 265.0, + 50.0: 54.4, + 0.0: 0.0, + 20.0: 23.3, + 100.0: 108.8, + 10.0: 12.1, + 1000.0: 1058.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4411,12 +5340,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, True, True, False, Liquid.DMSO, True, False)] = \ -HighVolume_96COREHead1000ul_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(1000, True, True, False, Liquid.DMSO, True, False)] = ( + HighVolume_96COREHead1000ul_DMSO_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={500.0: 524.0, 0.0: 0.0, 100.0: 107.2, 20.0: 24.0, 1000.0: 1025.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -4434,12 +5364,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=20.0 + dispense_stop_back_volume=20.0, ) -star_mapping[(1000, True, True, False, Liquid.DMSO, True, True)] = \ -HighVolume_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(1000, True, True, False, Liquid.DMSO, True, True)] = ( + HighVolume_96COREHead1000ul_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={500.0: 508.2, 0.0: 0.0, 100.0: 101.7, 20.0: 21.7, 1000.0: 1017.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -4457,12 +5388,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, True, True, False, Liquid.DMSO, False, True)] = \ -HighVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(1000, True, True, False, Liquid.DMSO, False, True)] = ( + HighVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={500.0: 512.5, 0.0: 0.0, 100.0: 105.8, 1000.0: 1024.5, 10.0: 12.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, @@ -4480,13 +5412,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # to prevent drop's, mix 2x with e.g. 500ul -star_mapping[(1000, True, True, False, Liquid.ETHANOL, True, False)] = \ -HighVolume_96COREHead1000ul_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(1000, True, True, False, Liquid.ETHANOL, True, False)] = ( + HighVolume_96COREHead1000ul_EtOH_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 500.0: 500.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -4504,12 +5437,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -star_mapping[(1000, True, True, False, Liquid.ETHANOL, True, True)] = \ -HighVolume_96COREHead1000ul_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(1000, True, True, False, Liquid.ETHANOL, True, True)] = ( + HighVolume_96COREHead1000ul_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={500.0: 516.5, 0.0: 0.0, 100.0: 108.3, 20.0: 24.0, 1000.0: 1027.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -4527,13 +5461,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # to prevent drop's, mix 2x with e.g. 500ul -star_mapping[(1000, True, True, False, Liquid.ETHANOL, False, True)] = \ -HighVolume_96COREHead1000ul_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(1000, True, True, False, Liquid.ETHANOL, False, True)] = ( + HighVolume_96COREHead1000ul_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={500.0: 516.5, 0.0: 0.0, 100.0: 107.0, 1000.0: 1027.0, 10.0: 14.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=150.0, @@ -4551,12 +5486,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, True, True, False, Liquid.GLYCERIN80, False, True)] = \ -HighVolume_96COREHead1000ul_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(1000, True, True, False, Liquid.GLYCERIN80, False, True)] = ( + HighVolume_96COREHead1000ul_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={500.0: 522.0, 0.0: 0.0, 100.0: 115.3, 1000.0: 1034.0, 10.0: 12.5}, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, @@ -4574,12 +5510,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, True, True, False, Liquid.WATER, True, False)] = \ -HighVolume_96COREHead1000ul_Water_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(1000, True, True, False, Liquid.WATER, True, False)] = ( + HighVolume_96COREHead1000ul_Water_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={500.0: 524.0, 0.0: 0.0, 100.0: 107.2, 20.0: 24.0, 1000.0: 1025.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -4597,12 +5534,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -star_mapping[(1000, True, True, False, Liquid.WATER, True, True)] = \ -HighVolume_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(1000, True, True, False, Liquid.WATER, True, True)] = ( + HighVolume_96COREHead1000ul_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={500.0: 524.0, 0.0: 0.0, 100.0: 107.2, 20.0: 24.0, 1000.0: 1025.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -4620,12 +5558,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, True, True, False, Liquid.WATER, False, True)] = \ -HighVolume_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(1000, True, True, False, Liquid.WATER, False, True)] = ( + HighVolume_96COREHead1000ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={500.0: 522.0, 0.0: 0.0, 100.0: 108.3, 1000.0: 1034.0, 10.0: 12.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, @@ -4643,14 +5582,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # Liquid class for wash high volume tips with CO-RE 96 Head in CO-RE 96 Head Washer. -star_mapping[(1000, True, True, False, Liquid.WATER, False, False)] = \ -HighVolume_Core96Washer_DispenseSurface = HamiltonLiquidClass( - curve={500.0: 520.0, 50.0: 56.3, 0.0: 0.0, 100.0: 110.0, 20.0: 23.9, 1000.0: 1050.0, 200.0: 212.0, 10.0: 12.5}, +star_mapping[(1000, True, True, False, Liquid.WATER, False, False)] = ( + HighVolume_Core96Washer_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 500.0: 520.0, + 50.0: 56.3, + 0.0: 0.0, + 100.0: 110.0, + 20.0: 23.9, + 1000.0: 1050.0, + 200.0: 212.0, + 10.0: 12.5, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=220.0, aspiration_air_transport_volume=0.0, @@ -4667,7 +5616,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -4688,9 +5637,20 @@ def get_star_liquid_class(**kwargs): # 100 ( 9 Aliquots) 0.25 -4.81 # # -star_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = \ -HighVolume_DMSO_AliquotDispenseJet_Part = HamiltonLiquidClass( - curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, +star_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = ( + HighVolume_DMSO_AliquotDispenseJet_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 500.0, + 250.0: 250.0, + 30.0: 30.0, + 0.0: 0.0, + 100.0: 100.0, + 20.0: 20.0, + 1000.0: 1000.0, + 750.0: 750.0, + 10.0: 10.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -4707,14 +5667,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = \ -HighVolume_DMSO_DispenseJet = HamiltonLiquidClass( - curve={5.0: 5.1, 500.0: 511.2, 250.0: 256.2, 50.0: 52.2, 0.0: 0.0, 20.0: 21.3, 100.0: 103.4, 10.0: 10.7, 1000.0: 1021.0}, +star_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = ( + HighVolume_DMSO_DispenseJet +) = HamiltonLiquidClass( + curve={ + 5.0: 5.1, + 500.0: 511.2, + 250.0: 256.2, + 50.0: 52.2, + 0.0: 0.0, + 20.0: 21.3, + 100.0: 103.4, + 10.0: 10.7, + 1000.0: 1021.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4731,13 +5702,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, False, Liquid.DMSO, True, True)] = \ -HighVolume_DMSO_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 511.2, 5.0: 5.1, 250.0: 256.2, 50.0: 52.2, 0.0: 0.0, 100.0: 103.4, 20.0: 21.3, 1000.0: 1021.0, 10.0: 10.7}, +star_mapping[(1000, False, True, False, Liquid.DMSO, True, True)] = ( + HighVolume_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 511.2, + 5.0: 5.1, + 250.0: 256.2, + 50.0: 52.2, + 0.0: 0.0, + 100.0: 103.4, + 20.0: 21.3, + 1000.0: 1021.0, + 10.0: 10.7, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4754,12 +5736,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = \ -HighVolume_DMSO_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = ( + HighVolume_DMSO_DispenseJet_Part +) = HamiltonLiquidClass( curve={500.0: 520.2, 0.0: 0.0, 100.0: 112.0, 20.0: 27.0, 1000.0: 1031.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -4777,14 +5760,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=5.0 + dispense_stop_back_volume=5.0, ) # V1.1: Set mix flow rate to 120 -star_mapping[(1000, False, True, False, Liquid.DMSO, False, False)] = \ -HighVolume_DMSO_DispenseSurface = HamiltonLiquidClass( - curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 20.0: 22.8, 100.0: 105.8, 10.0: 12.1, 1000.0: 1024.5}, +star_mapping[(1000, False, True, False, Liquid.DMSO, False, False)] = ( + HighVolume_DMSO_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 500.0: 514.3, + 250.0: 259.0, + 50.0: 54.4, + 0.0: 0.0, + 20.0: 22.8, + 100.0: 105.8, + 10.0: 12.1, + 1000.0: 1024.5, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4801,13 +5794,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, False, Liquid.DMSO, False, True)] = \ -HighVolume_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 100.0: 105.8, 20.0: 22.8, 1000.0: 1024.5, 10.0: 12.1}, +star_mapping[(1000, False, True, False, Liquid.DMSO, False, True)] = ( + HighVolume_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 514.3, + 250.0: 259.0, + 50.0: 54.4, + 0.0: 0.0, + 100.0: 105.8, + 20.0: 22.8, + 1000.0: 1024.5, + 10.0: 12.1, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4824,13 +5827,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, False, Liquid.DMSO, False, False)] = \ -HighVolume_DMSO_DispenseSurface_Part = HamiltonLiquidClass( - curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 100.0: 105.8, 20.0: 22.8, 1000.0: 1024.5, 10.0: 12.4}, +star_mapping[(1000, False, True, False, Liquid.DMSO, False, False)] = ( + HighVolume_DMSO_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 514.3, + 250.0: 259.0, + 50.0: 54.4, + 0.0: 0.0, + 100.0: 105.8, + 20.0: 22.8, + 1000.0: 1024.5, + 10.0: 12.4, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4847,14 +5860,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set Stop back volume to 0 -star_mapping[(1000, False, True, False, Liquid.ETHANOL, True, False)] = \ -HighVolume_EtOH_DispenseJet = HamiltonLiquidClass( - curve={500.0: 534.8, 250.0: 273.0, 50.0: 62.9, 0.0: 0.0, 20.0: 27.8, 100.0: 116.3, 10.0: 15.8, 1000.0: 1053.9}, +star_mapping[(1000, False, True, False, Liquid.ETHANOL, True, False)] = ( + HighVolume_EtOH_DispenseJet +) = HamiltonLiquidClass( + curve={ + 500.0: 534.8, + 250.0: 273.0, + 50.0: 62.9, + 0.0: 0.0, + 20.0: 27.8, + 100.0: 116.3, + 10.0: 15.8, + 1000.0: 1053.9, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -4871,13 +5894,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, False, Liquid.ETHANOL, True, True)] = \ -HighVolume_EtOH_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 534.8, 250.0: 273.0, 50.0: 62.9, 0.0: 0.0, 100.0: 116.3, 20.0: 27.8, 1000.0: 1053.9, 10.0: 15.8}, +star_mapping[(1000, False, True, False, Liquid.ETHANOL, True, True)] = ( + HighVolume_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 534.8, + 250.0: 273.0, + 50.0: 62.9, + 0.0: 0.0, + 100.0: 116.3, + 20.0: 27.8, + 1000.0: 1053.9, + 10.0: 15.8, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -4894,12 +5927,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, False, Liquid.ETHANOL, True, False)] = \ -HighVolume_EtOH_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(1000, False, True, False, Liquid.ETHANOL, True, False)] = ( + HighVolume_EtOH_DispenseJet_Part +) = HamiltonLiquidClass( curve={500.0: 529.0, 50.0: 62.9, 0.0: 0.0, 100.0: 114.5, 20.0: 27.8, 1000.0: 1053.9}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, @@ -4917,13 +5951,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=5.0 + dispense_stop_back_volume=5.0, ) -star_mapping[(1000, False, True, False, Liquid.ETHANOL, False, False)] = \ -HighVolume_EtOH_DispenseSurface = HamiltonLiquidClass( - curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 100.0: 114.0, 20.0: 27.6, 1000.0: 1044.3, 10.0: 15.7}, +star_mapping[(1000, False, True, False, Liquid.ETHANOL, False, False)] = ( + HighVolume_EtOH_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 500.0: 528.4, + 250.0: 269.2, + 50.0: 61.2, + 0.0: 0.0, + 100.0: 114.0, + 20.0: 27.6, + 1000.0: 1044.3, + 10.0: 15.7, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -4940,13 +5984,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, False, Liquid.ETHANOL, False, True)] = \ -HighVolume_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 20.0: 27.6, 100.0: 114.0, 10.0: 15.7, 1000.0: 1044.3}, +star_mapping[(1000, False, True, False, Liquid.ETHANOL, False, True)] = ( + HighVolume_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 528.4, + 250.0: 269.2, + 50.0: 61.2, + 0.0: 0.0, + 20.0: 27.6, + 100.0: 114.0, + 10.0: 15.7, + 1000.0: 1044.3, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -4963,13 +6017,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, False, Liquid.ETHANOL, False, False)] = \ -HighVolume_EtOH_DispenseSurface_Part = HamiltonLiquidClass( - curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 100.0: 114.0, 20.0: 27.6, 1000.0: 1044.3, 10.0: 14.7}, +star_mapping[(1000, False, True, False, Liquid.ETHANOL, False, False)] = ( + HighVolume_EtOH_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 528.4, + 250.0: 269.2, + 50.0: 61.2, + 0.0: 0.0, + 100.0: 114.0, + 20.0: 27.6, + 1000.0: 1044.3, + 10.0: 14.7, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -4986,14 +6050,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 200 -star_mapping[(1000, False, True, False, Liquid.GLYCERIN80, True, False)] = \ -HighVolume_Glycerin80_DispenseJet = HamiltonLiquidClass( - curve={500.0: 537.8, 250.0: 277.0, 50.0: 63.3, 0.0: 0.0, 20.0: 28.0, 100.0: 118.8, 10.0: 15.2, 1000.0: 1060.0}, +star_mapping[(1000, False, True, False, Liquid.GLYCERIN80, True, False)] = ( + HighVolume_Glycerin80_DispenseJet +) = HamiltonLiquidClass( + curve={ + 500.0: 537.8, + 250.0: 277.0, + 50.0: 63.3, + 0.0: 0.0, + 20.0: 28.0, + 100.0: 118.8, + 10.0: 15.2, + 1000.0: 1060.0, + }, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=5.0, @@ -5010,13 +6084,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(1000, False, True, False, Liquid.GLYCERIN80, True, True)] = \ -HighVolume_Glycerin80_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 537.8, 250.0: 277.0, 50.0: 63.3, 0.0: 0.0, 100.0: 118.8, 20.0: 28.0, 1000.0: 1060.0, 10.0: 15.2}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(1000, False, True, False, Liquid.GLYCERIN80, True, True)] = ( + HighVolume_Glycerin80_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 537.8, + 250.0: 277.0, + 50.0: 63.3, + 0.0: 0.0, + 100.0: 118.8, + 20.0: 28.0, + 1000.0: 1060.0, + 10.0: 15.2, + }, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=5.0, @@ -5033,14 +6117,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 120 -star_mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, False)] = \ -HighVolume_Glycerin80_DispenseSurface = HamiltonLiquidClass( - curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 20.0: 22.7, 100.0: 105.5, 10.0: 12.2, 1000.0: 1027.2}, +star_mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, False)] = ( + HighVolume_Glycerin80_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 500.0: 513.5, + 250.0: 257.2, + 50.0: 55.0, + 0.0: 0.0, + 20.0: 22.7, + 100.0: 105.5, + 10.0: 12.2, + 1000.0: 1027.2, + }, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -5057,13 +6151,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, True)] = \ -HighVolume_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 100.0: 105.5, 20.0: 22.7, 1000.0: 1027.2, 10.0: 12.2}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, True)] = ( + HighVolume_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 513.5, + 250.0: 257.2, + 50.0: 55.0, + 0.0: 0.0, + 100.0: 105.5, + 20.0: 22.7, + 1000.0: 1027.2, + 10.0: 12.2, + }, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -5080,13 +6184,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, False)] = \ -HighVolume_Glycerin80_DispenseSurface_Part = HamiltonLiquidClass( - curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 100.0: 105.5, 20.0: 22.7, 1000.0: 1027.2, 10.0: 12.2}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, False)] = ( + HighVolume_Glycerin80_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 513.5, + 250.0: 257.2, + 50.0: 55.0, + 0.0: 0.0, + 100.0: 105.5, + 20.0: 22.7, + 1000.0: 1027.2, + 10.0: 12.2, + }, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -5103,14 +6217,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = \ -HighVolume_Serum_AliquotDispenseJet_Part = HamiltonLiquidClass( - curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, +star_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = ( + HighVolume_Serum_AliquotDispenseJet_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 500.0, + 250.0: 250.0, + 30.0: 30.0, + 0.0: 0.0, + 100.0: 100.0, + 20.0: 20.0, + 1000.0: 1000.0, + 750.0: 750.0, + 10.0: 10.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -5127,14 +6252,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=300.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = \ -HighVolume_Serum_AliquotJet = HamiltonLiquidClass( - curve={500.0: 500.0, 250.0: 250.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 100.0: 100.0, 10.0: 10.0, 750.0: 750.0, 1000.0: 1000.0}, +star_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = ( + HighVolume_Serum_AliquotJet +) = HamiltonLiquidClass( + curve={ + 500.0: 500.0, + 250.0: 250.0, + 0.0: 0.0, + 30.0: 30.0, + 20.0: 20.0, + 100.0: 100.0, + 10.0: 10.0, + 750.0: 750.0, + 1000.0: 1000.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -5151,14 +6287,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=300.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 250, settling time = 0 -star_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = \ -HighVolume_Serum_DispenseJet = HamiltonLiquidClass( - curve={500.0: 525.3, 250.0: 266.6, 50.0: 57.9, 0.0: 0.0, 20.0: 24.2, 100.0: 111.3, 10.0: 12.2, 1000.0: 1038.6}, +star_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = ( + HighVolume_Serum_DispenseJet +) = HamiltonLiquidClass( + curve={ + 500.0: 525.3, + 250.0: 266.6, + 50.0: 57.9, + 0.0: 0.0, + 20.0: 24.2, + 100.0: 111.3, + 10.0: 12.2, + 1000.0: 1038.6, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -5175,13 +6321,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, False, Liquid.SERUM, True, True)] = \ -HighVolume_Serum_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 525.3, 250.0: 266.6, 50.0: 57.9, 0.0: 0.0, 100.0: 111.3, 20.0: 24.2, 1000.0: 1038.6, 10.0: 12.2}, +star_mapping[(1000, False, True, False, Liquid.SERUM, True, True)] = ( + HighVolume_Serum_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 525.3, + 250.0: 266.6, + 50.0: 57.9, + 0.0: 0.0, + 100.0: 111.3, + 20.0: 24.2, + 1000.0: 1038.6, + 10.0: 12.2, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -5198,12 +6354,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = \ -HighVolume_Serum_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = ( + HighVolume_Serum_DispenseJet_Part +) = HamiltonLiquidClass( curve={500.0: 525.3, 0.0: 0.0, 100.0: 111.3, 20.0: 27.3, 1000.0: 1046.6}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -5221,14 +6378,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 120 -star_mapping[(1000, False, True, False, Liquid.SERUM, False, False)] = \ -HighVolume_Serum_DispenseSurface = HamiltonLiquidClass( - curve={500.0: 517.5, 250.0: 261.9, 50.0: 55.9, 0.0: 0.0, 20.0: 23.2, 100.0: 108.2, 10.0: 11.8, 1000.0: 1026.7}, +star_mapping[(1000, False, True, False, Liquid.SERUM, False, False)] = ( + HighVolume_Serum_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 500.0: 517.5, + 250.0: 261.9, + 50.0: 55.9, + 0.0: 0.0, + 20.0: 23.2, + 100.0: 108.2, + 10.0: 11.8, + 1000.0: 1026.7, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -5245,13 +6412,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, False, Liquid.SERUM, False, True)] = \ -HighVolume_Serum_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 517.5, 250.0: 261.9, 50.0: 55.9, 0.0: 0.0, 100.0: 108.2, 20.0: 23.2, 1000.0: 1026.7, 10.0: 11.8}, +star_mapping[(1000, False, True, False, Liquid.SERUM, False, True)] = ( + HighVolume_Serum_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 517.5, + 250.0: 261.9, + 50.0: 55.9, + 0.0: 0.0, + 100.0: 108.2, + 20.0: 23.2, + 1000.0: 1026.7, + 10.0: 11.8, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -5268,12 +6445,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, False, Liquid.SERUM, False, False)] = \ -HighVolume_Serum_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(1000, False, True, False, Liquid.SERUM, False, False)] = ( + HighVolume_Serum_DispenseSurface_Part +) = HamiltonLiquidClass( curve={50.0: 55.9, 0.0: 0.0, 100.0: 108.2, 20.0: 23.2, 1000.0: 1037.7, 10.0: 11.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, @@ -5291,14 +6469,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = \ -HighVolume_Water_AliquotDispenseJet_Part = HamiltonLiquidClass( - curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, +star_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = ( + HighVolume_Water_AliquotDispenseJet_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 500.0, + 250.0: 250.0, + 30.0: 30.0, + 0.0: 0.0, + 100.0: 100.0, + 20.0: 20.0, + 1000.0: 1000.0, + 750.0: 750.0, + 10.0: 10.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -5315,14 +6504,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = \ -HighVolume_Water_AliquotJet = HamiltonLiquidClass( - curve={500.0: 500.0, 250.0: 250.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 100.0: 100.0, 10.0: 10.0, 750.0: 750.0, 1000.0: 1000.0}, +star_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = ( + HighVolume_Water_AliquotJet +) = HamiltonLiquidClass( + curve={ + 500.0: 500.0, + 250.0: 250.0, + 0.0: 0.0, + 30.0: 30.0, + 20.0: 20.0, + 100.0: 100.0, + 10.0: 10.0, + 750.0: 750.0, + 1000.0: 1000.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -5339,14 +6539,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 250 -star_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = \ -HighVolume_Water_DispenseJet = HamiltonLiquidClass( - curve={500.0: 521.7, 50.0: 57.2, 0.0: 0.0, 20.0: 24.6, 100.0: 109.6, 10.0: 13.3, 200.0: 212.9, 1000.0: 1034.0}, +star_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = ( + HighVolume_Water_DispenseJet +) = HamiltonLiquidClass( + curve={ + 500.0: 521.7, + 50.0: 57.2, + 0.0: 0.0, + 20.0: 24.6, + 100.0: 109.6, + 10.0: 13.3, + 200.0: 212.9, + 1000.0: 1034.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -5363,13 +6573,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, False, Liquid.WATER, True, True)] = \ -HighVolume_Water_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 521.7, 50.0: 57.2, 0.0: 0.0, 100.0: 109.6, 20.0: 24.6, 1000.0: 1034.0, 200.0: 212.9, 10.0: 13.3}, +star_mapping[(1000, False, True, False, Liquid.WATER, True, True)] = ( + HighVolume_Water_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 521.7, + 50.0: 57.2, + 0.0: 0.0, + 100.0: 109.6, + 20.0: 24.6, + 1000.0: 1034.0, + 200.0: 212.9, + 10.0: 13.3, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -5386,12 +6606,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = \ -HighVolume_Water_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = ( + HighVolume_Water_DispenseJet_Part +) = HamiltonLiquidClass( curve={500.0: 521.7, 0.0: 0.0, 100.0: 109.6, 20.0: 26.9, 1000.0: 1040.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -5409,14 +6630,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=18.0 + dispense_stop_back_volume=18.0, ) # V1.1: Set mix flow rate to 120, clot retract height = 0 -star_mapping[(1000, False, True, False, Liquid.WATER, False, False)] = \ -HighVolume_Water_DispenseSurface = HamiltonLiquidClass( - curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 20.0: 23.9, 100.0: 108.3, 10.0: 12.5, 200.0: 211.0, 1000.0: 1028.5}, +star_mapping[(1000, False, True, False, Liquid.WATER, False, False)] = ( + HighVolume_Water_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 500.0: 518.3, + 50.0: 56.3, + 0.0: 0.0, + 20.0: 23.9, + 100.0: 108.3, + 10.0: 12.5, + 200.0: 211.0, + 1000.0: 1028.5, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -5433,13 +6664,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, False, Liquid.WATER, False, True)] = \ -HighVolume_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 100.0: 108.3, 20.0: 23.9, 1000.0: 1028.5, 200.0: 211.0, 10.0: 12.5}, +star_mapping[(1000, False, True, False, Liquid.WATER, False, True)] = ( + HighVolume_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 518.3, + 50.0: 56.3, + 0.0: 0.0, + 100.0: 108.3, + 20.0: 23.9, + 1000.0: 1028.5, + 200.0: 211.0, + 10.0: 12.5, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -5456,13 +6697,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(1000, False, True, False, Liquid.WATER, False, False)] = \ -HighVolume_Water_DispenseSurface_Part = HamiltonLiquidClass( - curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 100.0: 108.3, 20.0: 23.9, 1000.0: 1036.5, 200.0: 211.0, 10.0: 12.5}, +star_mapping[(1000, False, True, False, Liquid.WATER, False, False)] = ( + HighVolume_Water_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 518.3, + 50.0: 56.3, + 0.0: 0.0, + 100.0: 108.3, + 20.0: 23.9, + 1000.0: 1036.5, + 200.0: 211.0, + 10.0: 12.5, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -5479,7 +6730,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -5489,8 +6740,9 @@ def get_star_liquid_class(**kwargs): # - fix height from bottom between 0.5-0.7mm # - dispense mode jet empty tip # - also with higher DNA concentration -star_mapping[(10, False, False, False, Liquid.DNA_TRIS_EDTA, True, False)] = \ -LowNeedleDNADispenseJet = HamiltonLiquidClass( +star_mapping[(10, False, False, False, Liquid.DNA_TRIS_EDTA, True, False)] = ( + LowNeedleDNADispenseJet +) = HamiltonLiquidClass( curve={5.0: 5.7, 0.5: 1.0, 50.0: 53.0, 0.0: 0.0, 20.0: 22.1, 1.0: 1.5, 10.0: 10.8, 2.0: 2.7}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, @@ -5508,7 +6760,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.5 + dispense_stop_back_volume=0.5, ) @@ -5517,8 +6769,9 @@ def get_star_liquid_class(**kwargs): # - for Disp. in empty PCR-Plate/on empty Plate from 1µl up # - fix height from bottom between 0.5-0.7mm # - also with higher DNA concentration -star_mapping[(10, False, False, False, Liquid.DNA_TRIS_EDTA, False, False)] = \ -LowNeedleDNADispenseSurface = HamiltonLiquidClass( +star_mapping[(10, False, False, False, Liquid.DNA_TRIS_EDTA, False, False)] = ( + LowNeedleDNADispenseSurface +) = HamiltonLiquidClass( curve={5.0: 5.7, 0.5: 1.0, 50.0: 53.0, 0.0: 0.0, 20.0: 22.1, 1.0: 1.5, 10.0: 10.8, 2.0: 2.7}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, @@ -5536,14 +6789,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 60 -star_mapping[(10, False, False, False, Liquid.WATER, False, False)] = \ -LowNeedle_SysFlWater_DispenseSurface = HamiltonLiquidClass( - curve={35.0: 35.6, 60.0: 62.7, 50.0: 51.3, 40.0: 40.9, 30.0: 30.0, 0.0: 0.0, 31.0: 31.4, 32.0: 32.7}, +star_mapping[(10, False, False, False, Liquid.WATER, False, False)] = ( + LowNeedle_SysFlWater_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 35.0: 35.6, + 60.0: 62.7, + 50.0: 51.3, + 40.0: 40.9, + 30.0: 30.0, + 0.0: 0.0, + 31.0: 31.4, + 32.0: 32.7, + }, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, aspiration_air_transport_volume=0.0, @@ -5560,12 +6823,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, False, False, Liquid.WATER, True, False)] = \ -LowNeedle_Water_DispenseJet = HamiltonLiquidClass( +star_mapping[(10, False, False, False, Liquid.WATER, True, False)] = ( + LowNeedle_Water_DispenseJet +) = HamiltonLiquidClass( curve={50.0: 52.7, 30.0: 31.7, 0.0: 0.0, 20.0: 20.5, 10.0: 10.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -5583,12 +6847,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, False, False, Liquid.WATER, True, True)] = \ -LowNeedle_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(10, False, False, False, Liquid.WATER, True, True)] = ( + LowNeedle_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={70.0: 70.0, 50.0: 52.7, 30.0: 31.7, 0.0: 0.0, 20.0: 20.5, 10.0: 10.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -5606,12 +6871,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, False, False, Liquid.WATER, True, False)] = \ -LowNeedle_Water_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(10, False, False, False, Liquid.WATER, True, False)] = ( + LowNeedle_Water_DispenseJet_Part +) = HamiltonLiquidClass( curve={70.0: 70.0, 50.0: 52.7, 30.0: 31.7, 0.0: 0.0, 20.0: 20.5, 10.0: 10.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -5629,13 +6895,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 60 -star_mapping[(10, False, False, False, Liquid.WATER, False, False)] = \ -LowNeedle_Water_DispenseSurface = HamiltonLiquidClass( +star_mapping[(10, False, False, False, Liquid.WATER, False, False)] = ( + LowNeedle_Water_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 5.0, 0.5: 0.5, 50.0: 50.0, 0.0: 0.0, 20.0: 20.5, 1.0: 1.0, 10.0: 10.0, 2.0: 2.0}, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, @@ -5653,13 +6920,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(10, False, False, False, Liquid.WATER, False, True)] = \ -LowNeedle_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={5.0: 5.0, 0.5: 0.5, 70.0: 70.0, 50.0: 50.0, 0.0: 0.0, 20.0: 20.5, 1.0: 1.0, 10.0: 10.0, 2.0: 2.0}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(10, False, False, False, Liquid.WATER, False, True)] = ( + LowNeedle_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 5.0: 5.0, + 0.5: 0.5, + 70.0: 70.0, + 50.0: 50.0, + 0.0: 0.0, + 20.0: 20.5, + 1.0: 1.0, + 10.0: 10.0, + 2.0: 2.0, + }, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, aspiration_air_transport_volume=0.0, @@ -5676,13 +6954,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(10, False, False, False, Liquid.WATER, False, False)] = \ -LowNeedle_Water_DispenseSurface_Part = HamiltonLiquidClass( - curve={5.0: 5.0, 0.5: 0.5, 70.0: 70.0, 50.0: 50.0, 0.0: 0.0, 20.0: 20.5, 1.0: 1.0, 10.0: 10.0, 2.0: 2.0}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(10, False, False, False, Liquid.WATER, False, False)] = ( + LowNeedle_Water_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 5.0: 5.0, + 0.5: 0.5, + 70.0: 70.0, + 50.0: 50.0, + 0.0: 0.0, + 20.0: 20.5, + 1.0: 1.0, + 10.0: 10.0, + 2.0: 2.0, + }, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, aspiration_air_transport_volume=0.0, @@ -5699,12 +6988,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, True, True, True, Liquid.DMSO, False, True)] = \ -LowVolumeFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(10, True, True, True, Liquid.DMSO, False, True)] = ( + LowVolumeFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.3, 0.0: 0.0, 1.0: 0.8, 10.0: 10.0}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -5722,12 +7012,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, True, True, True, Liquid.WATER, False, True)] = \ -LowVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(10, True, True, True, Liquid.WATER, False, True)] = ( + LowVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.8, 0.0: 0.0, 1.0: 1.0, 10.0: 10.0}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -5745,12 +7036,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, True, True, True, Liquid.DMSO, False, True)] = \ -LowVolumeFilter_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(10, True, True, True, Liquid.DMSO, False, True)] = ( + LowVolumeFilter_96COREHead_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.1, 0.0: 0.0, 1.0: 0.8, 10.0: 10.0}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -5768,12 +7060,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, True, True, True, Liquid.DMSO, False, False)] = \ -LowVolumeFilter_96COREHead_DMSO_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(10, True, True, True, Liquid.DMSO, False, False)] = ( + LowVolumeFilter_96COREHead_DMSO_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.7, 0.0: 0.0, 1.0: 1.5, 10.0: 10.3}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -5791,12 +7084,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, True, True, True, Liquid.WATER, False, True)] = \ -LowVolumeFilter_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(10, True, True, True, Liquid.WATER, False, True)] = ( + LowVolumeFilter_96COREHead_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 0.0: 0.0, 1.0: 1.2, 10.0: 10.0}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -5814,12 +7108,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, True, True, True, Liquid.WATER, False, False)] = \ -LowVolumeFilter_96COREHead_Water_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(10, True, True, True, Liquid.WATER, False, False)] = ( + LowVolumeFilter_96COREHead_Water_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.8, 0.0: 0.0, 1.0: 1.5, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5837,13 +7132,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 75 -star_mapping[(10, False, True, True, Liquid.DMSO, False, False)] = \ -LowVolumeFilter_DMSO_DispenseSurface = HamiltonLiquidClass( +star_mapping[(10, False, True, True, Liquid.DMSO, False, False)] = ( + LowVolumeFilter_DMSO_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.5: 0.8, 15.0: 16.4, 0.0: 0.0, 1.0: 1.4, 2.0: 2.6, 10.0: 11.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5861,12 +7157,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=56.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, True, True, Liquid.DMSO, False, True)] = \ -LowVolumeFilter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(10, False, True, True, Liquid.DMSO, False, True)] = ( + LowVolumeFilter_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 10.0, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5884,12 +7181,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, True, True, Liquid.DMSO, False, False)] = \ -LowVolumeFilter_DMSO_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(10, False, True, True, Liquid.DMSO, False, False)] = ( + LowVolumeFilter_DMSO_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.4, 10.0: 10.0, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5907,13 +7205,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 75 -star_mapping[(10, False, True, True, Liquid.ETHANOL, False, False)] = \ -LowVolumeFilter_EtOH_DispenseSurface = HamiltonLiquidClass( +star_mapping[(10, False, True, True, Liquid.ETHANOL, False, False)] = ( + LowVolumeFilter_EtOH_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 8.4, 0.5: 1.9, 0.0: 0.0, 1.0: 2.7, 2.0: 4.1, 10.0: 13.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5931,12 +7230,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, True, True, Liquid.ETHANOL, False, True)] = \ -LowVolumeFilter_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(10, False, True, True, Liquid.ETHANOL, False, True)] = ( + LowVolumeFilter_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 6.6, 0.0: 0.0, 1.0: 1.8, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5954,12 +7254,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, True, True, Liquid.ETHANOL, False, False)] = \ -LowVolumeFilter_EtOH_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(10, False, True, True, Liquid.ETHANOL, False, False)] = ( + LowVolumeFilter_EtOH_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 6.4, 0.0: 0.0, 1.0: 1.8, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5977,13 +7278,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 10 -star_mapping[(10, False, True, True, Liquid.GLYCERIN, False, False)] = \ -LowVolumeFilter_Glycerin_DispenseSurface = HamiltonLiquidClass( +star_mapping[(10, False, True, True, Liquid.GLYCERIN, False, False)] = ( + LowVolumeFilter_Glycerin_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 6.5, 0.5: 1.4, 15.0: 17.0, 0.0: 0.0, 1.0: 2.0, 2.0: 3.2, 10.0: 11.8}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, @@ -6001,12 +7303,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, True, True, Liquid.GLYCERIN80, False, True)] = \ -LowVolumeFilter_Glycerin_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(10, False, True, True, Liquid.GLYCERIN80, False, True)] = ( + LowVolumeFilter_Glycerin_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 6.5, 0.0: 0.0, 1.0: 0.6, 10.0: 10.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, @@ -6024,13 +7327,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 75 -star_mapping[(10, False, True, True, Liquid.WATER, False, False)] = \ -LowVolumeFilter_Water_DispenseSurface = HamiltonLiquidClass( +star_mapping[(10, False, True, True, Liquid.WATER, False, False)] = ( + LowVolumeFilter_Water_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 6.0, 0.5: 0.8, 15.0: 16.7, 0.0: 0.0, 1.0: 1.4, 2.0: 2.6, 10.0: 11.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -6048,12 +7352,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=56.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, True, True, Liquid.WATER, False, True)] = \ -LowVolumeFilter_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(10, False, True, True, Liquid.WATER, False, True)] = ( + LowVolumeFilter_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 6.0, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 10.0, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -6071,12 +7376,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, True, True, Liquid.WATER, False, False)] = \ -LowVolumeFilter_Water_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(10, False, True, True, Liquid.WATER, False, False)] = ( + LowVolumeFilter_Water_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.2, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -6094,7 +7400,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -6115,8 +7421,9 @@ def get_star_liquid_class(**kwargs): # 5.0 1.08 -1.29 # 10.0 0.62 0.53 # -star_mapping[(10, False, True, False, Liquid.PLASMA, False, False)] = \ -LowVolumePlasmaDispenseSurface = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.PLASMA, False, False)] = ( + LowVolumePlasmaDispenseSurface +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 11.5, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -6134,12 +7441,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, True, False, Liquid.PLASMA, False, True)] = \ -LowVolumePlasmaDispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.PLASMA, False, True)] = ( + LowVolumePlasmaDispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 0.5: 0.2, 0.0: 0.0, 1.0: 0.9, 10.0: 11.3, 2.0: 2.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -6157,12 +7465,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, True, False, Liquid.PLASMA, False, False)] = \ -LowVolumePlasmaDispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.PLASMA, False, False)] = ( + LowVolumePlasmaDispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.3, 10.0: 11.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -6180,7 +7489,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -6201,8 +7510,9 @@ def get_star_liquid_class(**kwargs): # 5.0 1.08 -1.29 # 10.0 0.62 0.53 # -star_mapping[(10, False, True, False, Liquid.SERUM, False, False)] = \ -LowVolumeSerumDispenseSurface = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.SERUM, False, False)] = ( + LowVolumeSerumDispenseSurface +) = HamiltonLiquidClass( curve={5.0: 5.6, 0.5: 0.2, 0.0: 0.0, 1.0: 0.9, 10.0: 11.3, 2.0: 2.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -6220,12 +7530,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, True, False, Liquid.SERUM, False, True)] = \ -LowVolumeSerumDispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.SERUM, False, True)] = ( + LowVolumeSerumDispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 0.5: 0.2, 0.0: 0.0, 1.0: 0.9, 10.0: 11.3, 2.0: 2.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -6243,12 +7554,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, True, False, Liquid.SERUM, False, False)] = \ -LowVolumeSerumDispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.SERUM, False, False)] = ( + LowVolumeSerumDispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.3, 10.0: 11.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -6266,12 +7578,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, True, True, False, Liquid.DMSO, False, True)] = \ -LowVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(10, True, True, False, Liquid.DMSO, False, True)] = ( + LowVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.3, 0.0: 0.0, 1.0: 0.8, 10.0: 10.6}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -6289,12 +7602,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, True, True, False, Liquid.WATER, False, True)] = \ -LowVolume_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(10, True, True, False, Liquid.WATER, False, True)] = ( + LowVolume_96COREHead1000ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.8, 0.0: 0.0, 1.0: 1.0, 10.0: 11.2}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -6312,12 +7626,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, True, True, False, Liquid.DMSO, False, True)] = \ -LowVolume_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(10, True, True, False, Liquid.DMSO, False, True)] = ( + LowVolume_96COREHead_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.1, 0.0: 0.0, 1.0: 0.8, 10.0: 10.3}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -6335,12 +7650,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, True, True, False, Liquid.DMSO, False, False)] = \ -LowVolume_96COREHead_DMSO_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(10, True, True, False, Liquid.DMSO, False, False)] = ( + LowVolume_96COREHead_DMSO_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.5, 10.0: 11.0}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -6358,12 +7674,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, True, True, False, Liquid.WATER, False, True)] = \ -LowVolume_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(10, True, True, False, Liquid.WATER, False, True)] = ( + LowVolume_96COREHead_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.8, 0.0: 0.0, 1.0: 1.3, 10.0: 11.1}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -6381,12 +7698,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, True, True, False, Liquid.WATER, False, False)] = \ -LowVolume_96COREHead_Water_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(10, True, True, False, Liquid.WATER, False, False)] = ( + LowVolume_96COREHead_Water_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.7, 0.0: 0.0, 1.0: 1.4, 10.0: 10.8}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -6404,13 +7722,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # Liquid class for wash low volume tips with CO-RE 96 Head in CO-RE 96 Head Washer. -star_mapping[(10, True, True, False, Liquid.WATER, False, False)] = \ -LowVolume_Core96Washer_DispenseSurface = HamiltonLiquidClass( +star_mapping[(10, True, True, False, Liquid.WATER, False, False)] = ( + LowVolume_Core96Washer_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 6.0, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 15.0, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=150.0, @@ -6428,13 +7747,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=56.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 75 -star_mapping[(10, False, True, False, Liquid.DMSO, False, False)] = \ -LowVolume_DMSO_DispenseSurface = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.DMSO, False, False)] = ( + LowVolume_DMSO_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 5.9, 15.0: 16.4, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 11.2, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -6452,12 +7772,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=56.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, True, False, Liquid.DMSO, False, True)] = \ -LowVolume_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.DMSO, False, True)] = ( + LowVolume_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 11.2, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -6475,12 +7796,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, True, False, Liquid.DMSO, False, False)] = \ -LowVolume_DMSO_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.DMSO, False, False)] = ( + LowVolume_DMSO_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.4, 10.0: 11.2, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -6498,13 +7820,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 75 -star_mapping[(10, False, True, False, Liquid.ETHANOL, False, False)] = \ -LowVolume_EtOH_DispenseSurface = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.ETHANOL, False, False)] = ( + LowVolume_EtOH_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 8.4, 0.5: 1.9, 0.0: 0.0, 1.0: 2.7, 10.0: 13.0, 2.0: 4.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -6522,12 +7845,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, True, False, Liquid.ETHANOL, False, True)] = \ -LowVolume_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.ETHANOL, False, True)] = ( + LowVolume_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 7.3, 0.0: 0.0, 1.0: 2.4, 10.0: 13.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -6545,12 +7869,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, True, False, Liquid.ETHANOL, False, False)] = \ -LowVolume_EtOH_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.ETHANOL, False, False)] = ( + LowVolume_EtOH_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 7.0, 0.0: 0.0, 1.0: 2.4, 10.0: 13.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -6568,13 +7893,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 10 -star_mapping[(10, False, True, False, Liquid.GLYCERIN, False, False)] = \ -LowVolume_Glycerin_DispenseSurface = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.GLYCERIN, False, False)] = ( + LowVolume_Glycerin_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 6.5, 15.0: 17.0, 0.5: 1.4, 0.0: 0.0, 1.0: 2.0, 10.0: 11.8, 2.0: 3.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, @@ -6592,13 +7918,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 75 -star_mapping[(10, False, True, False, Liquid.WATER, False, False)] = \ -LowVolume_Water_DispenseSurface = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.WATER, False, False)] = ( + LowVolume_Water_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 6.0, 15.0: 16.7, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 11.5, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -6616,12 +7943,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=56.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, True, True, False, Liquid.WATER, False, False)] = \ -LowVolume_Water_DispenseSurface96Head = HamiltonLiquidClass( +star_mapping[(10, True, True, False, Liquid.WATER, False, False)] = ( + LowVolume_Water_DispenseSurface96Head +) = HamiltonLiquidClass( curve={5.0: 6.0, 0.0: 0.0, 1.0: 1.0, 10.0: 11.5}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -6639,12 +7967,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, True, True, False, Liquid.WATER, False, True)] = \ -LowVolume_Water_DispenseSurfaceEmpty96Head = HamiltonLiquidClass( +star_mapping[(10, True, True, False, Liquid.WATER, False, True)] = ( + LowVolume_Water_DispenseSurfaceEmpty96Head +) = HamiltonLiquidClass( curve={5.0: 6.0, 0.0: 0.0, 1.0: 1.0, 10.0: 10.9}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -6662,12 +7991,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, True, True, False, Liquid.WATER, False, False)] = \ -LowVolume_Water_DispenseSurfacePart96Head = HamiltonLiquidClass( +star_mapping[(10, True, True, False, Liquid.WATER, False, False)] = ( + LowVolume_Water_DispenseSurfacePart96Head +) = HamiltonLiquidClass( curve={5.0: 6.0, 0.0: 0.0, 1.0: 1.0, 10.0: 10.9}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -6685,12 +8015,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, True, False, Liquid.WATER, False, True)] = \ -LowVolume_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.WATER, False, True)] = ( + LowVolume_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 6.0, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 11.5, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -6708,12 +8039,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(10, False, True, False, Liquid.WATER, False, False)] = \ -LowVolume_Water_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(10, False, True, False, Liquid.WATER, False, False)] = ( + LowVolume_Water_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.2, 10.0: 11.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -6731,7 +8063,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -6747,8 +8079,9 @@ def get_star_liquid_class(**kwargs): # 12 x 20ul = approximately 19.2 ul # 4 x 50 ul = approximately 48.1 ul # 2 x 100 ul = approximately 95.3 ul -star_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = \ -SlimTipFilter_96COREHead1000ul_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = ( + SlimTipFilter_96COREHead1000ul_DMSO_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, @@ -6766,12 +8099,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=18.0 + dispense_stop_back_volume=18.0, ) -star_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = \ -SlimTipFilter_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = ( + SlimTipFilter_96COREHead1000ul_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 312.3, 50.0: 55.3, 0.0: 0.0, 100.0: 107.7, 20.0: 22.4, 200.0: 210.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6789,12 +8123,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = \ -SlimTipFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = ( + SlimTipFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 311.9, 50.0: 54.1, 0.0: 0.0, 100.0: 107.5, 20.0: 22.5, 10.0: 11.1, 200.0: 209.4}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6812,7 +8147,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -6829,8 +8164,9 @@ def get_star_liquid_class(**kwargs): # 4 x 50 ul = approximately 48.9 ul # 2 x 100 ul = approximately 97.2 ul # -star_mapping[(300, True, True, True, Liquid.WATER, True, False)] = \ -SlimTipFilter_96COREHead1000ul_Water_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.WATER, True, False)] = ( + SlimTipFilter_96COREHead1000ul_Water_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, @@ -6848,12 +8184,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -star_mapping[(300, True, True, True, Liquid.WATER, True, True)] = \ -SlimTipFilter_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.WATER, True, True)] = ( + SlimTipFilter_96COREHead1000ul_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 317.0, 50.0: 55.8, 0.0: 0.0, 100.0: 109.4, 20.0: 22.7, 200.0: 213.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6871,12 +8208,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, True, Liquid.WATER, False, True)] = \ -SlimTipFilter_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.WATER, False, True)] = ( + SlimTipFilter_96COREHead1000ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 318.7, 50.0: 54.9, 0.0: 0.0, 100.0: 110.4, 10.0: 11.7, 200.0: 210.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6894,7 +8232,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -6911,8 +8249,9 @@ def get_star_liquid_class(**kwargs): # 4 x 50 ul = approximately 48.3 ul # 2 x 100 ul = approximately 95.7 ul # -star_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = \ -SlimTipFilter_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = ( + SlimTipFilter_DMSO_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6930,12 +8269,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=18.0 + dispense_stop_back_volume=18.0, ) -star_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = \ -SlimTipFilter_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = ( + SlimTipFilter_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 309.5, 50.0: 54.4, 0.0: 0.0, 100.0: 106.4, 20.0: 22.1, 200.0: 208.2}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6953,13 +8293,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = \ -SlimTipFilter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 309.7, 5.0: 5.6, 50.0: 53.8, 0.0: 0.0, 100.0: 105.4, 20.0: 22.2, 10.0: 11.3, 200.0: 207.5}, +star_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = ( + SlimTipFilter_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 309.7, + 5.0: 5.6, + 50.0: 53.8, + 0.0: 0.0, + 100.0: 105.4, + 20.0: 22.2, + 10.0: 11.3, + 200.0: 207.5, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=1.0, @@ -6976,7 +8326,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -6992,8 +8342,9 @@ def get_star_liquid_class(**kwargs): # 12 x 20ul = approximately 21.3 ul # 4 x 50 ul = approximately 54.3 ul # 2 x 100 ul = approximately 105.2 ul -star_mapping[(300, True, True, True, Liquid.ETHANOL, True, False)] = \ -SlimTipFilter_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.ETHANOL, True, False)] = ( + SlimTipFilter_EtOH_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -7011,12 +8362,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -star_mapping[(300, True, True, True, Liquid.ETHANOL, True, True)] = \ -SlimTipFilter_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.ETHANOL, True, True)] = ( + SlimTipFilter_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 320.4, 50.0: 57.2, 0.0: 0.0, 100.0: 110.5, 20.0: 24.5, 200.0: 215.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -7034,12 +8386,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, True, Liquid.ETHANOL, False, True)] = \ -SlimTipFilter_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.ETHANOL, False, True)] = ( + SlimTipFilter_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 313.9, 50.0: 55.4, 0.0: 0.0, 100.0: 107.7, 20.0: 23.2, 10.0: 12.4, 200.0: 210.6}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -7057,12 +8410,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, True, Liquid.GLYCERIN80, False, True)] = \ -SlimTipFilter_Glycerin_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.GLYCERIN80, False, True)] = ( + SlimTipFilter_Glycerin_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 312.0, 50.0: 55.0, 0.0: 0.0, 100.0: 107.8, 20.0: 22.9, 10.0: 11.8, 200.0: 210.0}, aspiration_flow_rate=30.0, aspiration_mix_flow_rate=30.0, @@ -7080,7 +8434,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=2.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -7096,8 +8450,9 @@ def get_star_liquid_class(**kwargs): # 12 x 20ul = approximately 19.6 ul # 4 x 50 ul = approximately 49.2 ul # 2 x 100 ul = approximately 97.5 ul -star_mapping[(300, True, True, True, Liquid.WATER, True, False)] = \ -SlimTipFilter_Water_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.WATER, True, False)] = ( + SlimTipFilter_Water_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, @@ -7115,12 +8470,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -star_mapping[(300, True, True, True, Liquid.WATER, True, True)] = \ -SlimTipFilter_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.WATER, True, True)] = ( + SlimTipFilter_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 317.2, 50.0: 55.6, 0.0: 0.0, 100.0: 108.6, 20.0: 22.6, 200.0: 212.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -7138,13 +8494,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, True, Liquid.WATER, False, True)] = \ -SlimTipFilter_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 314.1, 5.0: 6.2, 50.0: 54.7, 0.0: 0.0, 100.0: 108.0, 20.0: 22.7, 10.0: 11.9, 200.0: 211.3}, +star_mapping[(300, True, True, True, Liquid.WATER, False, True)] = ( + SlimTipFilter_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 314.1, + 5.0: 6.2, + 50.0: 54.7, + 0.0: 0.0, + 100.0: 108.0, + 20.0: 22.7, + 10.0: 11.9, + 200.0: 211.3, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -7161,7 +8527,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -7177,8 +8543,9 @@ def get_star_liquid_class(**kwargs): # 12 x 20ul = approximately 19.2 ul # 4 x 50 ul = approximately 48.1 ul # 2 x 100 ul = approximately 95.3 ul -star_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ -SlimTip_96COREHead1000ul_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = ( + SlimTip_96COREHead1000ul_DMSO_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, @@ -7196,12 +8563,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=18.0 + dispense_stop_back_volume=18.0, ) -star_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ -SlimTip_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = ( + SlimTip_96COREHead1000ul_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 313.8, 50.0: 55.8, 0.0: 0.0, 100.0: 109.2, 20.0: 23.1, 200.0: 212.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -7219,12 +8587,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ -SlimTip_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = ( + SlimTip_96COREHead1000ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 312.9, 50.0: 54.1, 0.0: 0.0, 20.0: 22.5, 100.0: 108.8, 200.0: 210.9, 10.0: 11.1}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -7242,7 +8611,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -7258,8 +8627,9 @@ def get_star_liquid_class(**kwargs): # 12 x 20ul = approximately 21.8 ul # 4 x 50 ul = approximately 53.6 ul # 2 x 100 ul = approximately 105.2 ul -star_mapping[(300, True, True, False, Liquid.ETHANOL, True, False)] = \ -SlimTip_96COREHead1000ul_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.ETHANOL, True, False)] = ( + SlimTip_96COREHead1000ul_EtOH_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -7277,12 +8647,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=80.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -star_mapping[(300, True, True, False, Liquid.ETHANOL, True, True)] = \ -SlimTip_96COREHead1000ul_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.ETHANOL, True, True)] = ( + SlimTip_96COREHead1000ul_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 326.2, 50.0: 58.8, 0.0: 0.0, 100.0: 112.7, 20.0: 25.0, 200.0: 218.2}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -7300,12 +8671,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.ETHANOL, False, True)] = \ -SlimTip_96COREHead1000ul_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.ETHANOL, False, True)] = ( + SlimTip_96COREHead1000ul_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 320.3, 50.0: 56.7, 0.0: 0.0, 100.0: 109.5, 10.0: 12.4, 200.0: 213.9}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -7323,12 +8695,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=2.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.GLYCERIN80, False, True)] = \ -SlimTip_96COREHead1000ul_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.GLYCERIN80, False, True)] = ( + SlimTip_96COREHead1000ul_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 319.3, 50.0: 58.2, 0.0: 0.0, 100.0: 112.1, 20.0: 23.9, 10.0: 12.1, 200.0: 216.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -7346,7 +8719,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=2.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -7363,8 +8736,9 @@ def get_star_liquid_class(**kwargs): # 4 x 50 ul = approximately 48.9 ul # 2 x 100 ul = approximately 97.2 ul # -star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ -SlimTip_96COREHead1000ul_Water_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( + SlimTip_96COREHead1000ul_Water_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, @@ -7382,12 +8756,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ -SlimTip_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( + SlimTip_96COREHead1000ul_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 315.0, 50.0: 55.5, 0.0: 0.0, 100.0: 107.2, 20.0: 22.8, 200.0: 211.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -7405,12 +8780,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ -SlimTip_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( + SlimTip_96COREHead1000ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 322.7, 50.0: 56.4, 0.0: 0.0, 100.0: 110.4, 10.0: 11.9, 200.0: 215.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -7428,7 +8804,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -7445,8 +8821,9 @@ def get_star_liquid_class(**kwargs): # 4 x 50 ul = approximately 48.3 ul # 2 x 100 ul = approximately 95.7 ul # -star_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ -SlimTip_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = ( + SlimTip_DMSO_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -7464,12 +8841,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=18.0 + dispense_stop_back_volume=18.0, ) -star_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ -SlimTip_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = ( + SlimTip_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 309.5, 50.0: 54.7, 0.0: 0.0, 100.0: 107.2, 20.0: 22.5, 200.0: 209.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -7487,13 +8865,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ -SlimTip_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 310.2, 5.0: 5.6, 50.0: 54.1, 0.0: 0.0, 100.0: 106.2, 20.0: 22.5, 10.0: 11.3, 200.0: 208.7}, +star_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = ( + SlimTip_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 310.2, + 5.0: 5.6, + 50.0: 54.1, + 0.0: 0.0, + 100.0: 106.2, + 20.0: 22.5, + 10.0: 11.3, + 200.0: 208.7, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=1.0, @@ -7510,7 +8898,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -7526,8 +8914,9 @@ def get_star_liquid_class(**kwargs): # 12 x 20ul = approximately 21.3 ul # 4 x 50 ul = approximately 54.3 ul # 2 x 100 ul = approximately 105.2 ul -star_mapping[(300, True, True, False, Liquid.ETHANOL, True, False)] = \ -SlimTip_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.ETHANOL, True, False)] = ( + SlimTip_EtOH_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -7545,12 +8934,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -star_mapping[(300, True, True, False, Liquid.ETHANOL, True, True)] = \ -SlimTip_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.ETHANOL, True, True)] = ( + SlimTip_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 323.4, 50.0: 57.2, 0.0: 0.0, 100.0: 110.5, 20.0: 24.7, 200.0: 211.9}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -7568,13 +8958,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.ETHANOL, False, True)] = \ -SlimTip_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 312.9, 5.0: 6.2, 50.0: 55.4, 0.0: 0.0, 100.0: 107.7, 20.0: 23.2, 10.0: 11.9, 200.0: 210.6}, +star_mapping[(300, True, True, False, Liquid.ETHANOL, False, True)] = ( + SlimTip_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 312.9, + 5.0: 6.2, + 50.0: 55.4, + 0.0: 0.0, + 100.0: 107.7, + 20.0: 23.2, + 10.0: 11.9, + 200.0: 210.6, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=2.0, @@ -7591,13 +8991,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(300, True, True, False, Liquid.GLYCERIN80, False, True)] = \ -SlimTip_Glycerin_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 313.3, 5.0: 6.0, 50.0: 55.7, 0.0: 0.0, 100.0: 107.8, 20.0: 22.9, 10.0: 11.5, 200.0: 210.0}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(300, True, True, False, Liquid.GLYCERIN80, False, True)] = ( + SlimTip_Glycerin_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 313.3, + 5.0: 6.0, + 50.0: 55.7, + 0.0: 0.0, + 100.0: 107.8, + 20.0: 22.9, + 10.0: 11.5, + 200.0: 210.0, + }, aspiration_flow_rate=30.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=0.0, @@ -7614,7 +9024,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=2.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -7630,8 +9040,9 @@ def get_star_liquid_class(**kwargs): # 12 x 20ul = approximately 19.6 ul # 4 x 50 ul = approximately 50.0 ul # 2 x 100 ul = approximately 98.4 ul -star_mapping[(300, True, True, False, Liquid.SERUM, True, False)] = \ -SlimTip_Serum_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.SERUM, True, False)] = ( + SlimTip_Serum_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -7649,12 +9060,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -star_mapping[(300, True, True, False, Liquid.SERUM, True, True)] = \ -SlimTip_Serum_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.SERUM, True, True)] = ( + SlimTip_Serum_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 321.5, 50.0: 56.0, 0.0: 0.0, 100.0: 109.7, 20.0: 22.8, 200.0: 215.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -7672,13 +9084,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.SERUM, False, True)] = \ -SlimTip_Serum_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 320.2, 5.0: 5.5, 50.0: 55.4, 0.0: 0.0, 20.0: 22.6, 100.0: 109.7, 200.0: 214.9, 10.0: 11.3}, +star_mapping[(300, True, True, False, Liquid.SERUM, False, True)] = ( + SlimTip_Serum_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 320.2, + 5.0: 5.5, + 50.0: 55.4, + 0.0: 0.0, + 20.0: 22.6, + 100.0: 109.7, + 200.0: 214.9, + 10.0: 11.3, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=1.0, @@ -7695,7 +9117,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -7711,8 +9133,9 @@ def get_star_liquid_class(**kwargs): # 12 x 20ul = approximately 19.6 ul # 4 x 50 ul = approximately 49.2 ul # 2 x 100 ul = approximately 97.5 ul -star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ -SlimTip_Water_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( + SlimTip_Water_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, @@ -7730,12 +9153,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ -SlimTip_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( + SlimTip_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 317.2, 50.0: 55.6, 0.0: 0.0, 20.0: 22.6, 100.0: 108.6, 200.0: 212.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -7753,13 +9177,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ -SlimTip_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 317.1, 5.0: 6.2, 50.0: 55.1, 0.0: 0.0, 100.0: 108.0, 20.0: 22.9, 10.0: 11.9, 200.0: 213.0}, +star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( + SlimTip_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 317.1, + 5.0: 6.2, + 50.0: 55.1, + 0.0: 0.0, + 100.0: 108.0, + 20.0: 22.9, + 10.0: 11.9, + 200.0: 213.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -7776,14 +9210,15 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 80 # V1.2: Stop back volume = 0 (previous value: 15) -star_mapping[(300, False, False, False, Liquid.WATER, True, False)] = \ -StandardNeedle_Water_DispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, False, False, Liquid.WATER, True, False)] = ( + StandardNeedle_Water_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 311.2, 50.0: 51.3, 0.0: 0.0, 100.0: 103.4, 20.0: 19.5}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, @@ -7801,12 +9236,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, False, False, Liquid.WATER, True, True)] = \ -StandardNeedle_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, False, False, False, Liquid.WATER, True, True)] = ( + StandardNeedle_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 311.2, 50.0: 51.3, 0.0: 0.0, 100.0: 103.4, 20.0: 19.5}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, @@ -7824,12 +9260,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, False, False, Liquid.WATER, True, False)] = \ -StandardNeedle_Water_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, False, False, False, Liquid.WATER, True, False)] = ( + StandardNeedle_Water_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 311.2, 50.0: 51.3, 0.0: 0.0, 100.0: 103.4, 20.0: 19.5}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, @@ -7847,13 +9284,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(300, False, False, False, Liquid.WATER, False, False)] = \ -StandardNeedle_Water_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 308.4, 5.0: 6.5, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 1.1, 200.0: 205.8, 10.0: 12.0, 2.0: 2.1}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(300, False, False, False, Liquid.WATER, False, False)] = ( + StandardNeedle_Water_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 308.4, + 5.0: 6.5, + 50.0: 52.3, + 0.0: 0.0, + 100.0: 102.9, + 20.0: 22.3, + 1.0: 1.1, + 200.0: 205.8, + 10.0: 12.0, + 2.0: 2.1, + }, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=0.0, @@ -7870,13 +9319,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(300, False, False, False, Liquid.WATER, False, True)] = \ -StandardNeedle_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 308.4, 5.0: 6.5, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 1.1, 200.0: 205.8, 10.0: 12.0, 2.0: 2.1}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(300, False, False, False, Liquid.WATER, False, True)] = ( + StandardNeedle_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 308.4, + 5.0: 6.5, + 50.0: 52.3, + 0.0: 0.0, + 100.0: 102.9, + 20.0: 22.3, + 1.0: 1.1, + 200.0: 205.8, + 10.0: 12.0, + 2.0: 2.1, + }, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=0.0, @@ -7893,13 +9354,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(300, False, False, False, Liquid.WATER, False, False)] = \ -StandardNeedle_Water_DispenseSurface_Part = HamiltonLiquidClass( - curve={300.0: 308.4, 5.0: 6.5, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 1.1, 200.0: 205.8, 10.0: 12.0, 2.0: 2.1}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(300, False, False, False, Liquid.WATER, False, False)] = ( + StandardNeedle_Water_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 300.0: 308.4, + 5.0: 6.5, + 50.0: 52.3, + 0.0: 0.0, + 100.0: 102.9, + 20.0: 22.3, + 1.0: 1.1, + 200.0: 205.8, + 10.0: 12.0, + 2.0: 2.1, + }, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=0.0, @@ -7916,7 +9389,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -7940,8 +9413,9 @@ def get_star_liquid_class(**kwargs): # 200 0.16 0.55 # 300 0.17 0.35 # -star_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, False)] = \ -StandardVolumeAcetonitrilDispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, False)] = ( + StandardVolumeAcetonitrilDispenseJet +) = HamiltonLiquidClass( curve={300.0: 326.2, 50.0: 57.3, 0.0: 0.0, 100.0: 111.5, 20.0: 24.6, 200.0: 217.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7959,12 +9433,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, True)] = \ -StandardVolumeAcetonitrilDispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, True)] = ( + StandardVolumeAcetonitrilDispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 326.2, 50.0: 57.3, 0.0: 0.0, 100.0: 111.5, 20.0: 24.6, 200.0: 217.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7982,12 +9457,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, False)] = \ -StandardVolumeAcetonitrilDispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, False)] = ( + StandardVolumeAcetonitrilDispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 321.2, 50.0: 57.3, 0.0: 0.0, 100.0: 110.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8005,7 +9481,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) @@ -8029,9 +9505,21 @@ def get_star_liquid_class(**kwargs): # 200 0.65 0.65 # 300 0.21 0.88 # -star_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, False)] = \ -StandardVolumeAcetonitrilDispenseSurface = HamiltonLiquidClass( - curve={300.0: 328.0, 5.0: 6.8, 50.0: 58.5, 0.0: 0.0, 100.0: 112.7, 20.0: 24.8, 1.0: 1.3, 200.0: 220.0, 10.0: 13.0, 2.0: 3.0}, +star_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, False)] = ( + StandardVolumeAcetonitrilDispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 328.0, + 5.0: 6.8, + 50.0: 58.5, + 0.0: 0.0, + 100.0: 112.7, + 20.0: 24.8, + 1.0: 1.3, + 200.0: 220.0, + 10.0: 13.0, + 2.0: 3.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=10.0, @@ -8048,13 +9536,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, True)] = \ -StandardVolumeAcetonitrilDispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 328.0, 5.0: 6.8, 50.0: 58.5, 0.0: 0.0, 100.0: 112.7, 20.0: 24.8, 1.0: 1.3, 200.0: 220.0, 10.0: 13.0, 2.0: 3.0}, +star_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, True)] = ( + StandardVolumeAcetonitrilDispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 328.0, + 5.0: 6.8, + 50.0: 58.5, + 0.0: 0.0, + 100.0: 112.7, + 20.0: 24.8, + 1.0: 1.3, + 200.0: 220.0, + 10.0: 13.0, + 2.0: 3.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=10.0, @@ -8071,12 +9571,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, False)] = \ -StandardVolumeAcetonitrilDispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, False)] = ( + StandardVolumeAcetonitrilDispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 328.0, 5.0: 7.3, 0.0: 0.0, 100.0: 112.7, 10.0: 13.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8094,7 +9595,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -8114,8 +9615,9 @@ def get_star_liquid_class(**kwargs): # 20 (12 Aliquots) 2.53 -2.97 # 50 ( 4 Aliquots) 0.84 -2.57 # -star_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = \ -StandardVolumeDMSOAliquotJet = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = ( + StandardVolumeDMSOAliquotJet +) = HamiltonLiquidClass( curve={350.0: 350.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8133,7 +9635,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=0.3, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) @@ -8154,8 +9656,9 @@ def get_star_liquid_class(**kwargs): # 200 0.53 0.08 # 300 0.54 0.22 # -star_mapping[(300, False, True, False, Liquid.ETHANOL, False, False)] = \ -StandardVolumeEtOHDispenseSurface = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.ETHANOL, False, False)] = ( + StandardVolumeEtOHDispenseSurface +) = HamiltonLiquidClass( curve={300.0: 309.2, 50.0: 54.8, 0.0: 0.0, 100.0: 106.5, 20.0: 23.7, 200.0: 208.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=50.0, @@ -8173,12 +9676,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=0.4, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.ETHANOL, False, True)] = \ -StandardVolumeEtOHDispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.ETHANOL, False, True)] = ( + StandardVolumeEtOHDispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 309.2, 50.0: 54.8, 0.0: 0.0, 100.0: 106.5, 20.0: 23.7, 200.0: 208.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=50.0, @@ -8196,12 +9700,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.ETHANOL, False, False)] = \ -StandardVolumeEtOHDispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.ETHANOL, False, False)] = ( + StandardVolumeEtOHDispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 315.2, 0.0: 0.0, 100.0: 108.5, 20.0: 23.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=50.0, @@ -8219,12 +9724,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = \ -StandardVolumeFilter_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = ( + StandardVolumeFilter_96COREHead1000ul_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 302.5, 0.0: 0.0, 100.0: 101.0, 20.0: 20.4, 200.0: 201.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8242,12 +9748,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = \ -StandardVolumeFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = ( + StandardVolumeFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 306.0, 0.0: 0.0, 100.0: 104.3, 200.0: 205.0, 10.0: 12.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8265,12 +9772,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, True, Liquid.WATER, True, True)] = \ -StandardVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.WATER, True, True)] = ( + StandardVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8288,12 +9796,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, True, Liquid.WATER, False, True)] = \ -StandardVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.WATER, False, True)] = ( + StandardVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 210.0, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8311,12 +9820,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = \ -StandardVolumeFilter_96COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = ( + StandardVolumeFilter_96COREHead_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 303.5, 0.0: 0.0, 100.0: 101.8, 10.0: 10.2, 200.0: 200.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8334,12 +9844,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = \ -StandardVolumeFilter_96COREHead_DMSO_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = ( + StandardVolumeFilter_96COREHead_DMSO_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 305.0, 0.0: 0.0, 100.0: 103.6, 10.0: 11.5, 200.0: 206.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8357,12 +9868,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -star_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = \ -StandardVolumeFilter_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = ( + StandardVolumeFilter_96COREHead_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 303.0, 0.0: 0.0, 100.0: 101.3, 10.0: 10.6, 200.0: 202.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8380,12 +9892,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, True, Liquid.DMSO, False, False)] = \ -StandardVolumeFilter_96COREHead_DMSO_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.DMSO, False, False)] = ( + StandardVolumeFilter_96COREHead_DMSO_DispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 303.0, 0.0: 0.0, 100.0: 101.3, 10.0: 10.1, 200.0: 202.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8403,12 +9916,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, True, Liquid.WATER, True, True)] = \ -StandardVolumeFilter_96COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.WATER, True, True)] = ( + StandardVolumeFilter_96COREHead_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 309.0, 0.0: 0.0, 20.0: 22.3, 100.0: 104.2, 10.0: 11.9, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8426,12 +9940,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, True, Liquid.WATER, True, False)] = \ -StandardVolumeFilter_96COREHead_Water_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.WATER, True, False)] = ( + StandardVolumeFilter_96COREHead_Water_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 309.0, 0.0: 0.0, 20.0: 22.3, 100.0: 104.2, 10.0: 11.9, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8449,12 +9964,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -star_mapping[(300, True, True, True, Liquid.WATER, False, True)] = \ -StandardVolumeFilter_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.WATER, False, True)] = ( + StandardVolumeFilter_96COREHead_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 306.3, 0.0: 0.0, 100.0: 104.5, 10.0: 11.9, 200.0: 205.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8472,12 +9988,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, True, Liquid.WATER, False, False)] = \ -StandardVolumeFilter_96COREHead_Water_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(300, True, True, True, Liquid.WATER, False, False)] = ( + StandardVolumeFilter_96COREHead_Water_DispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 304.0, 0.0: 0.0, 100.0: 105.3, 10.0: 11.9, 200.0: 205.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8495,7 +10012,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -8515,8 +10032,9 @@ def get_star_liquid_class(**kwargs): # 20 (12 Aliquots) 2.53 -2.97 # 50 ( 4 Aliquots) 0.84 -2.57 # -star_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = \ -StandardVolumeFilter_DMSO_AliquotDispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = ( + StandardVolumeFilter_DMSO_AliquotDispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8534,13 +10052,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = \ -StandardVolumeFilter_DMSO_DispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = ( + StandardVolumeFilter_DMSO_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 304.6, 50.0: 51.1, 0.0: 0.0, 20.0: 20.7, 100.0: 101.8, 200.0: 203.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8558,12 +10077,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, True, Liquid.DMSO, True, True)] = \ -StandardVolumeFilter_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.DMSO, True, True)] = ( + StandardVolumeFilter_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 304.6, 50.0: 51.1, 0.0: 0.0, 100.0: 101.8, 20.0: 20.7, 200.0: 203.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8581,12 +10101,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = \ -StandardVolumeFilter_DMSO_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = ( + StandardVolumeFilter_DMSO_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 315.6, 0.0: 0.0, 100.0: 112.8, 20.0: 29.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8604,13 +10125,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0 -) - - -star_mapping[(300, False, True, True, Liquid.DMSO, False, False)] = \ -StandardVolumeFilter_DMSO_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 308.8, 5.0: 6.6, 50.0: 52.9, 0.0: 0.0, 1.0: 1.8, 20.0: 22.1, 100.0: 103.8, 2.0: 3.0, 10.0: 11.9, 200.0: 205.0}, + dispense_stop_back_volume=10.0, +) + + +star_mapping[(300, False, True, True, Liquid.DMSO, False, False)] = ( + StandardVolumeFilter_DMSO_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 308.8, + 5.0: 6.6, + 50.0: 52.9, + 0.0: 0.0, + 1.0: 1.8, + 20.0: 22.1, + 100.0: 103.8, + 2.0: 3.0, + 10.0: 11.9, + 200.0: 205.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -8627,13 +10160,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(300, False, True, True, Liquid.DMSO, False, True)] = \ -StandardVolumeFilter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 308.8, 5.0: 6.6, 50.0: 52.9, 0.0: 0.0, 1.0: 1.8, 20.0: 22.1, 100.0: 103.8, 2.0: 3.0, 10.0: 11.9, 200.0: 205.0}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(300, False, True, True, Liquid.DMSO, False, True)] = ( + StandardVolumeFilter_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 308.8, + 5.0: 6.6, + 50.0: 52.9, + 0.0: 0.0, + 1.0: 1.8, + 20.0: 22.1, + 100.0: 103.8, + 2.0: 3.0, + 10.0: 11.9, + 200.0: 205.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -8650,12 +10195,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, True, Liquid.DMSO, False, False)] = \ -StandardVolumeFilter_DMSO_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.DMSO, False, False)] = ( + StandardVolumeFilter_DMSO_DispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 306.8, 5.0: 6.4, 50.0: 52.9, 0.0: 0.0, 100.0: 103.8, 20.0: 22.1, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -8673,13 +10219,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 100, Stop back volume=0 -star_mapping[(300, False, True, True, Liquid.ETHANOL, True, False)] = \ -StandardVolumeFilter_EtOH_DispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.ETHANOL, True, False)] = ( + StandardVolumeFilter_EtOH_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 310.2, 50.0: 55.8, 0.0: 0.0, 20.0: 24.6, 100.0: 107.5, 200.0: 209.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8697,12 +10244,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, True, Liquid.ETHANOL, True, True)] = \ -StandardVolumeFilter_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.ETHANOL, True, True)] = ( + StandardVolumeFilter_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 310.2, 50.0: 55.8, 0.0: 0.0, 100.0: 107.5, 20.0: 24.6, 200.0: 209.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8720,12 +10268,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, True, Liquid.ETHANOL, True, False)] = \ -StandardVolumeFilter_EtOH_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.ETHANOL, True, False)] = ( + StandardVolumeFilter_EtOH_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 317.2, 0.0: 0.0, 100.0: 110.5, 20.0: 25.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8743,13 +10292,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=5.0 + dispense_stop_back_volume=5.0, ) # V1.1: Set mix flow rate to 20, dispense settling time=0, Stop back volume=0 -star_mapping[(300, False, True, True, Liquid.GLYCERIN, True, False)] = \ -StandardVolumeFilter_Glycerin_DispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.GLYCERIN, True, False)] = ( + StandardVolumeFilter_Glycerin_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 309.0, 50.0: 53.6, 0.0: 0.0, 20.0: 22.3, 100.0: 104.9, 200.0: 207.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=20.0, @@ -8767,13 +10317,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 20, dispense settling time=0, Stop back volume=0 -star_mapping[(300, False, True, True, Liquid.GLYCERIN80, True, True)] = \ -StandardVolumeFilter_Glycerin_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.GLYCERIN80, True, True)] = ( + StandardVolumeFilter_Glycerin_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 309.0, 50.0: 53.6, 0.0: 0.0, 100.0: 104.9, 20.0: 22.3, 200.0: 207.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=20.0, @@ -8791,14 +10342,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 10 -star_mapping[(300, False, True, True, Liquid.GLYCERIN, False, False)] = \ -StandardVolumeFilter_Glycerin_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 307.9, 5.0: 6.5, 50.0: 53.6, 0.0: 0.0, 20.0: 22.5, 100.0: 105.7, 2.0: 3.2, 10.0: 12.0, 200.0: 207.0}, +star_mapping[(300, False, True, True, Liquid.GLYCERIN, False, False)] = ( + StandardVolumeFilter_Glycerin_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 307.9, + 5.0: 6.5, + 50.0: 53.6, + 0.0: 0.0, + 20.0: 22.5, + 100.0: 105.7, + 2.0: 3.2, + 10.0: 12.0, + 200.0: 207.0, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -8815,13 +10377,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(300, False, True, True, Liquid.GLYCERIN80, False, True)] = \ -StandardVolumeFilter_Glycerin_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 307.9, 5.0: 6.5, 50.0: 53.6, 0.0: 0.0, 100.0: 105.7, 20.0: 22.5, 200.0: 207.0, 10.0: 12.0, 2.0: 3.2}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(300, False, True, True, Liquid.GLYCERIN80, False, True)] = ( + StandardVolumeFilter_Glycerin_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 307.9, + 5.0: 6.5, + 50.0: 53.6, + 0.0: 0.0, + 100.0: 105.7, + 20.0: 22.5, + 200.0: 207.0, + 10.0: 12.0, + 2.0: 3.2, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -8838,12 +10411,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, True, Liquid.GLYCERIN80, False, False)] = \ -StandardVolumeFilter_Glycerin_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.GLYCERIN80, False, False)] = ( + StandardVolumeFilter_Glycerin_DispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 307.9, 5.0: 6.1, 0.0: 0.0, 100.0: 104.7, 200.0: 207.0, 10.0: 11.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, @@ -8861,13 +10435,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = \ -StandardVolumeFilter_Serum_AliquotDispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = ( + StandardVolumeFilter_Serum_AliquotDispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8885,13 +10460,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = \ -StandardVolumeFilter_Serum_AliquotJet = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = ( + StandardVolumeFilter_Serum_AliquotJet +) = HamiltonLiquidClass( curve={300.0: 300.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8909,13 +10485,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = \ -StandardVolumeFilter_Serum_DispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = ( + StandardVolumeFilter_Serum_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 20.0: 23.2, 100.0: 108.1, 200.0: 212.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8933,12 +10510,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, True, Liquid.SERUM, True, True)] = \ -StandardVolumeFilter_Serum_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.SERUM, True, True)] = ( + StandardVolumeFilter_Serum_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 100.0: 108.1, 20.0: 23.2, 200.0: 212.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8956,12 +10534,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = \ -StandardVolumeFilter_Serum_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = ( + StandardVolumeFilter_Serum_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 315.2, 0.0: 0.0, 100.0: 111.5, 20.0: 29.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8979,13 +10558,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=5.0 + dispense_stop_back_volume=5.0, ) -star_mapping[(300, False, True, True, Liquid.SERUM, False, False)] = \ -StandardVolumeFilter_Serum_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 313.4, 5.0: 6.3, 50.0: 54.9, 0.0: 0.0, 20.0: 23.0, 100.0: 107.1, 2.0: 2.6, 10.0: 12.0, 200.0: 210.5}, +star_mapping[(300, False, True, True, Liquid.SERUM, False, False)] = ( + StandardVolumeFilter_Serum_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 313.4, + 5.0: 6.3, + 50.0: 54.9, + 0.0: 0.0, + 20.0: 23.0, + 100.0: 107.1, + 2.0: 2.6, + 10.0: 12.0, + 200.0: 210.5, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -9002,12 +10592,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, True, Liquid.SERUM, False, False)] = \ -StandardVolumeFilter_Serum_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.SERUM, False, False)] = ( + StandardVolumeFilter_Serum_DispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 313.4, 0.0: 0.0, 100.0: 109.1, 10.0: 12.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -9025,13 +10616,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, True, Liquid.WATER, True, False)] = \ -StandardVolumeFilter_Water_AliquotDispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.WATER, True, False)] = ( + StandardVolumeFilter_Water_AliquotDispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9049,13 +10641,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, True, Liquid.WATER, True, False)] = \ -StandardVolumeFilter_Water_AliquotJet = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.WATER, True, False)] = ( + StandardVolumeFilter_Water_AliquotJet +) = HamiltonLiquidClass( curve={300.0: 300.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9073,13 +10666,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=0.3, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, True, Liquid.WATER, True, False)] = \ -StandardVolumeFilter_Water_DispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.WATER, True, False)] = ( + StandardVolumeFilter_Water_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 313.5, 50.0: 55.1, 0.0: 0.0, 20.0: 23.2, 100.0: 107.2, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9097,12 +10691,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, True, Liquid.WATER, True, True)] = \ -StandardVolumeFilter_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.WATER, True, True)] = ( + StandardVolumeFilter_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 313.5, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9120,12 +10715,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, True, Liquid.WATER, True, False)] = \ -StandardVolumeFilter_Water_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, True, Liquid.WATER, True, False)] = ( + StandardVolumeFilter_Water_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 110.2, 20.0: 27.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9143,14 +10739,27 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, True, Liquid.WATER, False, False)] = \ -StandardVolumeFilter_Water_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 313.5, 5.0: 6.3, 0.5: 0.9, 50.0: 55.1, 0.0: 0.0, 1.0: 1.6, 20.0: 23.2, 100.0: 107.2, 2.0: 2.8, 10.0: 11.9, 200.0: 211.0}, +star_mapping[(300, False, True, True, Liquid.WATER, False, False)] = ( + StandardVolumeFilter_Water_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 313.5, + 5.0: 6.3, + 0.5: 0.9, + 50.0: 55.1, + 0.0: 0.0, + 1.0: 1.6, + 20.0: 23.2, + 100.0: 107.2, + 2.0: 2.8, + 10.0: 11.9, + 200.0: 211.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -9167,13 +10776,26 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, True, Liquid.WATER, False, True)] = \ -StandardVolumeFilter_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 313.5, 5.0: 6.3, 0.5: 0.9, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 1.0: 1.6, 200.0: 211.0, 10.0: 11.9, 2.0: 2.8}, +star_mapping[(300, False, True, True, Liquid.WATER, False, True)] = ( + StandardVolumeFilter_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 313.5, + 5.0: 6.3, + 0.5: 0.9, + 50.0: 55.1, + 0.0: 0.0, + 100.0: 107.2, + 20.0: 23.2, + 1.0: 1.6, + 200.0: 211.0, + 10.0: 11.9, + 2.0: 2.8, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -9190,13 +10812,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, True, Liquid.WATER, False, False)] = \ -StandardVolumeFilter_Water_DispenseSurface_Part = HamiltonLiquidClass( - curve={300.0: 313.5, 5.0: 6.5, 50.0: 55.1, 0.0: 0.0, 20.0: 23.2, 100.0: 107.2, 10.0: 11.9, 200.0: 211.0}, +star_mapping[(300, False, True, True, Liquid.WATER, False, False)] = ( + StandardVolumeFilter_Water_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 300.0: 313.5, + 5.0: 6.5, + 50.0: 55.1, + 0.0: 0.0, + 20.0: 23.2, + 100.0: 107.2, + 10.0: 11.9, + 200.0: 211.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -9213,7 +10845,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -9238,8 +10870,9 @@ def get_star_liquid_class(**kwargs): # 200 0.56 0.07 # 300 0.54 1.12 # -star_mapping[(300, False, True, False, Liquid.METHANOL, True, False)] = \ -StandardVolumeMeOHDispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.METHANOL, True, False)] = ( + StandardVolumeMeOHDispenseJet +) = HamiltonLiquidClass( curve={300.0: 336.0, 50.0: 63.0, 0.0: 0.0, 100.0: 119.5, 20.0: 28.3, 200.0: 230.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=30.0, @@ -9257,7 +10890,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -9284,9 +10917,19 @@ def get_star_liquid_class(**kwargs): # 200 0.51 0.59 # 300 0.81 0.22 # -star_mapping[(300, False, True, False, Liquid.METHANOL, False, False)] = \ -StandardVolumeMeOHDispenseSurface = HamiltonLiquidClass( - curve={300.0: 310.2, 5.0: 8.0, 50.0: 55.8, 0.0: 0.0, 100.0: 107.5, 20.0: 24.6, 200.0: 209.2, 10.0: 14.0}, +star_mapping[(300, False, True, False, Liquid.METHANOL, False, False)] = ( + StandardVolumeMeOHDispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 310.2, + 5.0: 8.0, + 50.0: 55.8, + 0.0: 0.0, + 100.0: 107.5, + 20.0: 24.6, + 200.0: 209.2, + 10.0: 14.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=10.0, @@ -9303,7 +10946,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -9324,8 +10967,9 @@ def get_star_liquid_class(**kwargs): # 200 0.29 0.17 # 300 0.16 0.80 # -star_mapping[(300, False, True, False, Liquid.OCTANOL, True, False)] = \ -StandardVolumeOctanol100DispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.OCTANOL, True, False)] = ( + StandardVolumeOctanol100DispenseJet +) = HamiltonLiquidClass( curve={300.0: 319.3, 50.0: 56.6, 0.0: 0.0, 100.0: 109.9, 20.0: 23.8, 200.0: 216.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9343,7 +10987,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -9368,9 +11012,21 @@ def get_star_liquid_class(**kwargs): # 200 0.02 0.12 # 300 0.11 0.29 # -star_mapping[(300, False, True, False, Liquid.OCTANOL, False, False)] = \ -StandardVolumeOctanol100DispenseSurface = HamiltonLiquidClass( - curve={300.0: 315.0, 5.0: 6.6, 50.0: 55.9, 0.0: 0.0, 100.0: 106.8, 20.0: 22.1, 1.0: 0.8, 200.0: 212.0, 10.0: 12.6, 2.0: 3.7}, +star_mapping[(300, False, True, False, Liquid.OCTANOL, False, False)] = ( + StandardVolumeOctanol100DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 315.0, + 5.0: 6.6, + 50.0: 55.9, + 0.0: 0.0, + 100.0: 106.8, + 20.0: 22.1, + 1.0: 0.8, + 200.0: 212.0, + 10.0: 12.6, + 2.0: 3.7, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -9387,7 +11043,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -9406,9 +11062,20 @@ def get_star_liquid_class(**kwargs): # 10 1.99 4.39 # # -star_mapping[(300, False, True, False, Liquid.PBS_BUFFER, False, False)] = \ -StandardVolumePBSDispenseSurface = HamiltonLiquidClass( - curve={300.0: 313.5, 5.0: 7.5, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 1.0: 2.6, 200.0: 211.0, 10.0: 12.8}, +star_mapping[(300, False, True, False, Liquid.PBS_BUFFER, False, False)] = ( + StandardVolumePBSDispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 313.5, + 5.0: 7.5, + 50.0: 55.1, + 0.0: 0.0, + 100.0: 107.2, + 20.0: 23.2, + 1.0: 2.6, + 200.0: 211.0, + 10.0: 12.8, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -9425,7 +11092,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -9445,8 +11112,9 @@ def get_star_liquid_class(**kwargs): # 100 0.08 1.09 # 200 0.09 0.91 # -star_mapping[(300, False, True, False, Liquid.PLASMA, True, False)] = \ -StandardVolumePlasmaDispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.PLASMA, True, False)] = ( + StandardVolumePlasmaDispenseJet +) = HamiltonLiquidClass( curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 100.0: 108.1, 20.0: 23.2, 200.0: 212.1, 10.0: 12.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -9464,12 +11132,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.PLASMA, True, True)] = \ -StandardVolumePlasmaDispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.PLASMA, True, True)] = ( + StandardVolumePlasmaDispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 20.0: 23.2, 100.0: 108.1, 200.0: 212.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9487,12 +11156,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.PLASMA, True, False)] = \ -StandardVolumePlasmaDispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.PLASMA, True, False)] = ( + StandardVolumePlasmaDispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 315.2, 0.0: 0.0, 20.0: 29.2, 100.0: 111.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9510,7 +11180,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=5.0 + dispense_stop_back_volume=5.0, ) @@ -9531,9 +11201,20 @@ def get_star_liquid_class(**kwargs): # 60 0.55 2.06 # # -star_mapping[(300, False, True, False, Liquid.PLASMA, False, False)] = \ -StandardVolumePlasmaDispenseSurface = HamiltonLiquidClass( - curve={300.0: 313.4, 5.0: 6.3, 50.0: 54.9, 0.0: 0.0, 100.0: 107.1, 20.0: 23.0, 200.0: 210.5, 10.0: 12.0, 2.0: 2.6}, +star_mapping[(300, False, True, False, Liquid.PLASMA, False, False)] = ( + StandardVolumePlasmaDispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 313.4, + 5.0: 6.3, + 50.0: 54.9, + 0.0: 0.0, + 100.0: 107.1, + 20.0: 23.0, + 200.0: 210.5, + 10.0: 12.0, + 2.0: 2.6, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -9550,13 +11231,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.PLASMA, False, True)] = \ -StandardVolumePlasmaDispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 313.4, 5.0: 6.3, 50.0: 54.9, 0.0: 0.0, 20.0: 23.0, 100.0: 107.1, 2.0: 2.6, 10.0: 12.0, 200.0: 210.5}, +star_mapping[(300, False, True, False, Liquid.PLASMA, False, True)] = ( + StandardVolumePlasmaDispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 313.4, + 5.0: 6.3, + 50.0: 54.9, + 0.0: 0.0, + 20.0: 23.0, + 100.0: 107.1, + 2.0: 2.6, + 10.0: 12.0, + 200.0: 210.5, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -9573,12 +11265,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.PLASMA, False, False)] = \ -StandardVolumePlasmaDispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.PLASMA, False, False)] = ( + StandardVolumePlasmaDispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 313.4, 5.0: 6.8, 0.0: 0.0, 100.0: 109.1, 10.0: 12.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -9596,12 +11289,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ -StandardVolume_96COREHead1000ul_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = ( + StandardVolume_96COREHead1000ul_DMSO_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 150.0: 150.0, 50.0: 50.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9619,12 +11313,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=20.0 + dispense_stop_back_volume=20.0, ) -star_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ -StandardVolume_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = ( + StandardVolume_96COREHead1000ul_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 302.5, 0.0: 0.0, 100.0: 101.0, 20.0: 20.4, 200.0: 201.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9642,12 +11337,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ -StandardVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = ( + StandardVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 306.0, 0.0: 0.0, 100.0: 104.3, 200.0: 205.0, 10.0: 12.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9665,12 +11361,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ -StandardVolume_96COREHead1000ul_Water_DispenseJet_Aliquot = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( + StandardVolume_96COREHead1000ul_Water_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 150.0: 150.0, 50.0: 50.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9688,12 +11385,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ -StandardVolume_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( + StandardVolume_96COREHead1000ul_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 200.0: 207.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9711,12 +11409,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ -StandardVolume_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( + StandardVolume_96COREHead1000ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 210.0, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9734,12 +11433,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ -StandardVolume_96COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = ( + StandardVolume_96COREHead_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 303.5, 0.0: 0.0, 100.0: 101.8, 10.0: 10.2, 200.0: 200.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9757,12 +11457,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ -StandardVolume_96COREHead_DMSO_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = ( + StandardVolume_96COREHead_DMSO_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 306.0, 0.0: 0.0, 100.0: 105.6, 10.0: 12.2, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9780,12 +11481,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -star_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ -StandardVolume_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = ( + StandardVolume_96COREHead_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 303.0, 0.0: 0.0, 100.0: 101.3, 10.0: 10.6, 200.0: 202.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9803,12 +11505,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.DMSO, False, False)] = \ -StandardVolume_96COREHead_DMSO_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.DMSO, False, False)] = ( + StandardVolume_96COREHead_DMSO_DispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 303.0, 0.0: 0.0, 100.0: 101.3, 10.0: 10.1, 200.0: 202.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9826,12 +11529,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ -StandardVolume_96COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( + StandardVolume_96COREHead_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 309.0, 0.0: 0.0, 20.0: 22.3, 100.0: 104.2, 10.0: 11.9, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9849,12 +11553,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ -StandardVolume_96COREHead_Water_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( + StandardVolume_96COREHead_Water_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 309.0, 0.0: 0.0, 20.0: 22.3, 100.0: 104.2, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9872,12 +11577,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ -StandardVolume_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( + StandardVolume_96COREHead_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 306.3, 0.0: 0.0, 100.0: 104.5, 10.0: 11.9, 200.0: 205.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9895,12 +11601,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ -StandardVolume_96COREHead_Water_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, False, False)] = ( + StandardVolume_96COREHead_Water_DispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 304.0, 0.0: 0.0, 100.0: 105.3, 10.0: 11.9, 200.0: 205.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9918,14 +11625,27 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # Liquid class for wash standard volume tips with CO-RE 96 Head in CO-RE 96 Head Washer. -star_mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ -StandardVolume_Core96Washer_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 330.0, 5.0: 6.3, 0.5: 0.9, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 1.0: 1.6, 200.0: 211.0, 10.0: 11.9, 2.0: 2.8}, +star_mapping[(300, True, True, False, Liquid.WATER, False, False)] = ( + StandardVolume_Core96Washer_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 330.0, + 5.0: 6.3, + 0.5: 0.9, + 50.0: 55.1, + 0.0: 0.0, + 100.0: 107.2, + 20.0: 23.2, + 1.0: 1.6, + 200.0: 211.0, + 10.0: 11.9, + 2.0: 2.8, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=150.0, aspiration_air_transport_volume=0.0, @@ -9942,7 +11662,7 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -9962,8 +11682,9 @@ def get_star_liquid_class(**kwargs): # 20 (12 Aliquots) 2.53 -2.97 # 50 ( 4 Aliquots) 0.84 -2.57 # -star_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = \ -StandardVolume_DMSO_AliquotDispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = ( + StandardVolume_DMSO_AliquotDispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9981,13 +11702,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = \ -StandardVolume_DMSO_DispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = ( + StandardVolume_DMSO_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 304.6, 350.0: 355.2, 50.0: 51.1, 0.0: 0.0, 100.0: 101.8, 20.0: 20.7, 200.0: 203.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10005,12 +11727,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.DMSO, True, True)] = \ -StandardVolume_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.DMSO, True, True)] = ( + StandardVolume_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 304.6, 50.0: 51.1, 0.0: 0.0, 20.0: 20.7, 100.0: 101.8, 200.0: 203.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10028,12 +11751,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = \ -StandardVolume_DMSO_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = ( + StandardVolume_DMSO_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 320.0, 0.0: 0.0, 20.0: 30.5, 100.0: 116.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10051,13 +11775,26 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 -) - - -star_mapping[(300, False, True, False, Liquid.DMSO, False, False)] = \ -StandardVolume_DMSO_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 308.8, 5.0: 6.6, 50.0: 52.9, 350.0: 360.5, 0.0: 0.0, 1.0: 1.8, 20.0: 22.1, 100.0: 103.8, 2.0: 3.0, 10.0: 11.9, 200.0: 205.0}, + dispense_stop_back_volume=10.0, +) + + +star_mapping[(300, False, True, False, Liquid.DMSO, False, False)] = ( + StandardVolume_DMSO_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 308.8, + 5.0: 6.6, + 50.0: 52.9, + 350.0: 360.5, + 0.0: 0.0, + 1.0: 1.8, + 20.0: 22.1, + 100.0: 103.8, + 2.0: 3.0, + 10.0: 11.9, + 200.0: 205.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -10074,13 +11811,25 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(300, False, True, False, Liquid.DMSO, False, True)] = \ -StandardVolume_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 308.8, 5.0: 6.6, 50.0: 52.9, 0.0: 0.0, 1.0: 1.8, 20.0: 22.1, 100.0: 103.8, 2.0: 3.0, 10.0: 11.9, 200.0: 205.0}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(300, False, True, False, Liquid.DMSO, False, True)] = ( + StandardVolume_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 308.8, + 5.0: 6.6, + 50.0: 52.9, + 0.0: 0.0, + 1.0: 1.8, + 20.0: 22.1, + 100.0: 103.8, + 2.0: 3.0, + 10.0: 11.9, + 200.0: 205.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -10097,13 +11846,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.DMSO, False, False)] = \ -StandardVolume_DMSO_DispenseSurface_Part = HamiltonLiquidClass( - curve={300.0: 308.8, 5.0: 6.4, 50.0: 52.9, 0.0: 0.0, 20.0: 22.1, 100.0: 103.8, 10.0: 11.9, 200.0: 205.0}, +star_mapping[(300, False, True, False, Liquid.DMSO, False, False)] = ( + StandardVolume_DMSO_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 300.0: 308.8, + 5.0: 6.4, + 50.0: 52.9, + 0.0: 0.0, + 20.0: 22.1, + 100.0: 103.8, + 10.0: 11.9, + 200.0: 205.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -10120,13 +11879,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 100, stop back volume = 0 -star_mapping[(300, False, True, False, Liquid.ETHANOL, True, False)] = \ -StandardVolume_EtOH_DispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.ETHANOL, True, False)] = ( + StandardVolume_EtOH_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 310.2, 350.0: 360.5, 50.0: 55.8, 0.0: 0.0, 100.0: 107.5, 20.0: 24.6, 200.0: 209.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10144,12 +11904,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.ETHANOL, True, True)] = \ -StandardVolume_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.ETHANOL, True, True)] = ( + StandardVolume_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 310.2, 50.0: 55.8, 0.0: 0.0, 20.0: 24.6, 100.0: 107.5, 200.0: 209.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10167,12 +11928,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.ETHANOL, True, False)] = \ -StandardVolume_EtOH_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.ETHANOL, True, False)] = ( + StandardVolume_EtOH_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 317.2, 0.0: 0.0, 20.0: 25.6, 100.0: 110.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10190,13 +11952,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=5.0 + dispense_stop_back_volume=5.0, ) # V1.1: Set mix flow rate to 20, dispense settling time=0, stop back volume = 0 -star_mapping[(300, False, True, False, Liquid.GLYCERIN, True, False)] = \ -StandardVolume_Glycerin_DispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.GLYCERIN, True, False)] = ( + StandardVolume_Glycerin_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 309.0, 350.0: 360.0, 50.0: 53.6, 0.0: 0.0, 100.0: 104.9, 20.0: 22.3, 200.0: 207.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=20.0, @@ -10214,13 +11977,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 20, dispense settling time=0, stop back volume = 0 -star_mapping[(300, False, True, False, Liquid.GLYCERIN80, True, True)] = \ -StandardVolume_Glycerin_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.GLYCERIN80, True, True)] = ( + StandardVolume_Glycerin_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 309.0, 50.0: 53.6, 0.0: 0.0, 100.0: 104.9, 20.0: 22.3, 200.0: 207.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=20.0, @@ -10238,14 +12002,26 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 10 -star_mapping[(300, False, True, False, Liquid.GLYCERIN, False, False)] = \ -StandardVolume_Glycerin_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 307.9, 5.0: 6.5, 350.0: 358.4, 50.0: 53.6, 0.0: 0.0, 100.0: 105.7, 20.0: 22.5, 200.0: 207.0, 10.0: 12.0, 2.0: 3.2}, +star_mapping[(300, False, True, False, Liquid.GLYCERIN, False, False)] = ( + StandardVolume_Glycerin_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 307.9, + 5.0: 6.5, + 350.0: 358.4, + 50.0: 53.6, + 0.0: 0.0, + 100.0: 105.7, + 20.0: 22.5, + 200.0: 207.0, + 10.0: 12.0, + 2.0: 3.2, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -10262,13 +12038,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(300, False, True, False, Liquid.GLYCERIN80, False, True)] = \ -StandardVolume_Glycerin_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 307.9, 5.0: 6.5, 50.0: 53.6, 0.0: 0.0, 100.0: 105.7, 20.0: 22.5, 200.0: 207.0, 10.0: 12.0, 2.0: 3.2}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(300, False, True, False, Liquid.GLYCERIN80, False, True)] = ( + StandardVolume_Glycerin_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 307.9, + 5.0: 6.5, + 50.0: 53.6, + 0.0: 0.0, + 100.0: 105.7, + 20.0: 22.5, + 200.0: 207.0, + 10.0: 12.0, + 2.0: 3.2, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -10285,13 +12072,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 -) - - -star_mapping[(300, False, True, False, Liquid.GLYCERIN80, False, False)] = \ -StandardVolume_Glycerin_DispenseSurface_Part = HamiltonLiquidClass( - curve={300.0: 307.9, 5.0: 6.2, 50.0: 53.6, 0.0: 0.0, 100.0: 105.7, 20.0: 22.5, 200.0: 207.0, 10.0: 12.0}, + dispense_stop_back_volume=0.0, +) + + +star_mapping[(300, False, True, False, Liquid.GLYCERIN80, False, False)] = ( + StandardVolume_Glycerin_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 300.0: 307.9, + 5.0: 6.2, + 50.0: 53.6, + 0.0: 0.0, + 100.0: 105.7, + 20.0: 22.5, + 200.0: 207.0, + 10.0: 12.0, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -10308,13 +12105,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = \ -StandardVolume_Serum_AliquotDispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = ( + StandardVolume_Serum_AliquotDispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10332,13 +12130,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = \ -StandardVolume_Serum_AliquotJet = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = ( + StandardVolume_Serum_AliquotJet +) = HamiltonLiquidClass( curve={350.0: 350.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10356,13 +12155,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = \ -StandardVolume_Serum_DispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = ( + StandardVolume_Serum_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 100.0: 108.1, 20.0: 23.2, 200.0: 212.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10380,12 +12180,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.SERUM, True, True)] = \ -StandardVolume_Serum_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.SERUM, True, True)] = ( + StandardVolume_Serum_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 20.0: 23.2, 100.0: 108.1, 200.0: 212.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10403,12 +12204,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = \ -StandardVolume_Serum_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = ( + StandardVolume_Serum_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 315.2, 0.0: 0.0, 20.0: 29.2, 100.0: 111.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10426,13 +12228,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=5.0 + dispense_stop_back_volume=5.0, ) -star_mapping[(300, False, True, False, Liquid.SERUM, False, False)] = \ -StandardVolume_Serum_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 313.4, 5.0: 6.3, 50.0: 54.9, 0.0: 0.0, 20.0: 23.0, 100.0: 107.1, 2.0: 2.6, 10.0: 12.0, 200.0: 210.5}, +star_mapping[(300, False, True, False, Liquid.SERUM, False, False)] = ( + StandardVolume_Serum_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 313.4, + 5.0: 6.3, + 50.0: 54.9, + 0.0: 0.0, + 20.0: 23.0, + 100.0: 107.1, + 2.0: 2.6, + 10.0: 12.0, + 200.0: 210.5, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -10449,13 +12262,24 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.SERUM, False, True)] = \ -StandardVolume_Serum_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 313.4, 5.0: 6.3, 50.0: 54.9, 0.0: 0.0, 20.0: 23.0, 100.0: 107.1, 2.0: 2.6, 10.0: 12.0, 200.0: 210.5}, +star_mapping[(300, False, True, False, Liquid.SERUM, False, True)] = ( + StandardVolume_Serum_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 313.4, + 5.0: 6.3, + 50.0: 54.9, + 0.0: 0.0, + 20.0: 23.0, + 100.0: 107.1, + 2.0: 2.6, + 10.0: 12.0, + 200.0: 210.5, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -10472,12 +12296,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.SERUM, False, False)] = \ -StandardVolume_Serum_DispenseSurface_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.SERUM, False, False)] = ( + StandardVolume_Serum_DispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 313.4, 5.0: 6.8, 0.0: 0.0, 100.0: 109.1, 10.0: 12.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10495,13 +12320,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, False, Liquid.WATER, True, False)] = \ -StandardVolume_Water_AliquotDispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.WATER, True, False)] = ( + StandardVolume_Water_AliquotDispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10519,13 +12345,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, False, Liquid.WATER, True, False)] = \ -StandardVolume_Water_AliquotJet = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.WATER, True, False)] = ( + StandardVolume_Water_AliquotJet +) = HamiltonLiquidClass( curve={350.0: 350.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10543,13 +12370,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=0.3, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, False, Liquid.WATER, True, False)] = \ -StandardVolume_Water_DispenseJet = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.WATER, True, False)] = ( + StandardVolume_Water_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 313.5, 350.0: 364.3, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10567,12 +12395,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ -StandardVolume_Water_DispenseJetEmpty96Head = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( + StandardVolume_Water_DispenseJetEmpty96Head +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 205.3, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10590,12 +12419,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ -StandardVolume_Water_DispenseJetPart96Head = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( + StandardVolume_Water_DispenseJetPart96Head +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 205.3, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10613,12 +12443,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.WATER, True, True)] = \ -StandardVolume_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.WATER, True, True)] = ( + StandardVolume_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 313.5, 50.0: 55.1, 0.0: 0.0, 20.0: 23.2, 100.0: 107.2, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10636,12 +12467,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.WATER, True, False)] = \ -StandardVolume_Water_DispenseJet_Part = HamiltonLiquidClass( +star_mapping[(300, False, True, False, Liquid.WATER, True, False)] = ( + StandardVolume_Water_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 20.0: 28.2, 100.0: 111.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10659,14 +12491,28 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -star_mapping[(300, False, True, False, Liquid.WATER, False, False)] = \ -StandardVolume_Water_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 313.5, 5.0: 6.3, 0.5: 0.9, 350.0: 364.3, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 1.0: 1.6, 200.0: 211.0, 10.0: 11.9, 2.0: 2.8}, +star_mapping[(300, False, True, False, Liquid.WATER, False, False)] = ( + StandardVolume_Water_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 313.5, + 5.0: 6.3, + 0.5: 0.9, + 350.0: 364.3, + 50.0: 55.1, + 0.0: 0.0, + 100.0: 107.2, + 20.0: 23.2, + 1.0: 1.6, + 200.0: 211.0, + 10.0: 11.9, + 2.0: 2.8, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10683,12 +12529,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ -StandardVolume_Water_DispenseSurface96Head = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, False, False)] = ( + StandardVolume_Water_DispenseSurface96Head +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10706,12 +12553,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ -StandardVolume_Water_DispenseSurfaceEmpty96Head = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( + StandardVolume_Water_DispenseSurfaceEmpty96Head +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 205.7, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10729,12 +12577,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ -StandardVolume_Water_DispenseSurfacePart96Head = HamiltonLiquidClass( +star_mapping[(300, True, True, False, Liquid.WATER, False, False)] = ( + StandardVolume_Water_DispenseSurfacePart96Head +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 205.7, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10752,13 +12601,26 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.WATER, False, True)] = \ -StandardVolume_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 313.5, 5.0: 6.3, 0.5: 0.9, 50.0: 55.1, 0.0: 0.0, 1.0: 1.6, 20.0: 23.2, 100.0: 107.2, 2.0: 2.8, 10.0: 11.9, 200.0: 211.0}, +star_mapping[(300, False, True, False, Liquid.WATER, False, True)] = ( + StandardVolume_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 313.5, + 5.0: 6.3, + 0.5: 0.9, + 50.0: 55.1, + 0.0: 0.0, + 1.0: 1.6, + 20.0: 23.2, + 100.0: 107.2, + 2.0: 2.8, + 10.0: 11.9, + 200.0: 211.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -10775,13 +12637,23 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(300, False, True, False, Liquid.WATER, False, False)] = \ -StandardVolume_Water_DispenseSurface_Part = HamiltonLiquidClass( - curve={300.0: 313.5, 5.0: 6.8, 50.0: 55.1, 0.0: 0.0, 20.0: 23.2, 100.0: 107.2, 10.0: 12.3, 200.0: 211.0}, +star_mapping[(300, False, True, False, Liquid.WATER, False, False)] = ( + StandardVolume_Water_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 300.0: 313.5, + 5.0: 6.8, + 50.0: 55.1, + 0.0: 0.0, + 20.0: 23.2, + 100.0: 107.2, + 10.0: 12.3, + 200.0: 211.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -10798,12 +12670,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, True, Liquid.DMSO, True, True)] = \ -Tip_50ulFilter_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, True, Liquid.DMSO, True, True)] = ( + Tip_50ulFilter_96COREHead1000ul_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 52.1, 30.0: 31.7, 0.0: 0.0, 20.0: 21.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10821,12 +12694,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, True, Liquid.DMSO, False, True)] = \ -Tip_50ulFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, True, Liquid.DMSO, False, True)] = ( + Tip_50ulFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.4, 50.0: 52.1, 30.0: 31.5, 0.0: 0.0, 1.0: 0.7, 10.0: 10.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10844,12 +12718,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, True, Liquid.WATER, True, True)] = \ -Tip_50ulFilter_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, True, Liquid.WATER, True, True)] = ( + Tip_50ulFilter_96COREHead1000ul_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 54.2, 30.0: 33.2, 0.0: 0.0, 20.0: 22.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10867,12 +12742,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, True, Liquid.WATER, False, True)] = \ -Tip_50ulFilter_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, True, Liquid.WATER, False, True)] = ( + Tip_50ulFilter_96COREHead1000ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 50.0: 53.6, 30.0: 32.6, 0.0: 0.0, 1.0: 0.8, 10.0: 11.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10890,12 +12766,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, True, Liquid.DMSO, True, True)] = \ -Tip_50ulFilter_96COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, True, Liquid.DMSO, True, True)] = ( + Tip_50ulFilter_96COREHead_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 51.4, 0.0: 0.0, 30.0: 31.3, 20.0: 21.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10913,12 +12790,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, True, Liquid.DMSO, False, True)] = \ -Tip_50ulFilter_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, True, Liquid.DMSO, False, True)] = ( + Tip_50ulFilter_96COREHead_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 50.0: 51.1, 0.0: 0.0, 30.0: 31.0, 1.0: 0.8, 10.0: 10.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10936,12 +12814,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, True, Liquid.WATER, True, True)] = \ -Tip_50ulFilter_96COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, True, Liquid.WATER, True, True)] = ( + Tip_50ulFilter_96COREHead_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 54.0, 30.0: 33.0, 0.0: 0.0, 20.0: 22.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10959,12 +12838,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, True, Liquid.WATER, False, True)] = \ -Tip_50ulFilter_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, True, Liquid.WATER, False, True)] = ( + Tip_50ulFilter_96COREHead_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 50.0: 53.5, 30.0: 32.9, 0.0: 0.0, 1.0: 0.8, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10982,12 +12862,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, True, Liquid.DMSO, True, True)] = \ -Tip_50ulFilter_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.DMSO, True, True)] = ( + Tip_50ulFilter_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 52.5, 0.0: 0.0, 30.0: 31.4, 20.0: 21.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11005,12 +12886,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, True, Liquid.DMSO, False, True)] = \ -Tip_50ulFilter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.DMSO, False, True)] = ( + Tip_50ulFilter_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.5, 50.0: 52.6, 0.0: 0.0, 30.0: 32.0, 1.0: 0.7, 10.0: 11.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -11028,12 +12910,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, True, Liquid.ETHANOL, True, True)] = \ -Tip_50ulFilter_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.ETHANOL, True, True)] = ( + Tip_50ulFilter_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 57.5, 0.0: 0.0, 30.0: 35.8, 20.0: 24.4}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -11051,12 +12934,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, True, Liquid.ETHANOL, False, True)] = \ -Tip_50ulFilter_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.ETHANOL, False, True)] = ( + Tip_50ulFilter_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 6.5, 50.0: 54.1, 0.0: 0.0, 30.0: 33.8, 1.0: 1.9, 10.0: 12.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -11074,12 +12958,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, True, Liquid.GLYCERIN80, False, True)] = \ -Tip_50ulFilter_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.GLYCERIN80, False, True)] = ( + Tip_50ulFilter_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.5, 50.0: 57.0, 0.0: 0.0, 30.0: 35.9, 1.0: 0.6, 10.0: 12.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -11097,12 +12982,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, True, Liquid.SERUM, True, True)] = \ -Tip_50ulFilter_Serum_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.SERUM, True, True)] = ( + Tip_50ulFilter_Serum_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 54.6, 30.0: 33.5, 0.0: 0.0, 20.0: 22.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11120,12 +13006,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, True, Liquid.SERUM, False, True)] = \ -Tip_50ulFilter_Serum_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.SERUM, False, True)] = ( + Tip_50ulFilter_Serum_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.7, 50.0: 54.9, 30.0: 33.0, 0.0: 0.0, 1.0: 0.7, 10.0: 11.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -11143,12 +13030,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, True, Liquid.WATER, True, True)] = \ -Tip_50ulFilter_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.WATER, True, True)] = ( + Tip_50ulFilter_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 54.0, 30.0: 33.6, 0.0: 0.0, 20.0: 22.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11166,12 +13054,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, True, Liquid.WATER, False, True)] = \ -Tip_50ulFilter_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, True, Liquid.WATER, False, True)] = ( + Tip_50ulFilter_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.7, 50.0: 54.2, 30.0: 33.1, 0.0: 0.0, 1.0: 0.65, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -11189,12 +13078,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ -Tip_50ul_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = ( + Tip_50ul_96COREHead1000ul_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 52.1, 30.0: 31.7, 0.0: 0.0, 20.0: 21.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11212,12 +13102,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = \ -Tip_50ul_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = ( + Tip_50ul_96COREHead1000ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.4, 50.0: 52.1, 30.0: 31.5, 0.0: 0.0, 1.0: 0.7, 10.0: 10.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -11235,12 +13126,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ -Tip_50ul_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.WATER, True, True)] = ( + Tip_50ul_96COREHead1000ul_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 52.8, 0.0: 0.0, 30.0: 33.2, 20.0: 22.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11258,12 +13150,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.WATER, False, True)] = \ -Tip_50ul_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.WATER, False, True)] = ( + Tip_50ul_96COREHead1000ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.8, 50.0: 53.6, 30.0: 32.6, 0.0: 0.0, 1.0: 0.8, 10.0: 11.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -11281,12 +13174,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=3.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ -Tip_50ul_96COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = ( + Tip_50ul_96COREHead_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 51.4, 30.0: 31.3, 0.0: 0.0, 20.0: 21.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11304,12 +13198,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = \ -Tip_50ul_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = ( + Tip_50ul_96COREHead_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 50.0: 52.1, 30.0: 31.6, 0.0: 0.0, 1.0: 0.8, 10.0: 11.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -11327,12 +13222,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ -Tip_50ul_96COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.WATER, True, True)] = ( + Tip_50ul_96COREHead_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 54.1, 0.0: 0.0, 30.0: 33.0, 20.0: 22.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11350,12 +13246,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, True, True, False, Liquid.WATER, False, True)] = \ -Tip_50ul_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.WATER, False, True)] = ( + Tip_50ul_96COREHead_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 50.0: 53.6, 30.0: 32.9, 0.0: 0.0, 1.0: 0.7, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -11373,13 +13270,14 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # Liquid class for wash 50ul tips with CO-RE 96 Head in CO-RE 96 Head Washer. -star_mapping[(50, True, True, False, Liquid.WATER, False, False)] = \ -Tip_50ul_Core96Washer_DispenseSurface = HamiltonLiquidClass( +star_mapping[(50, True, True, False, Liquid.WATER, False, False)] = ( + Tip_50ul_Core96Washer_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 5.7, 50.0: 54.2, 30.0: 33.2, 0.0: 0.0, 1.0: 0.5, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -11397,12 +13295,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, False, Liquid.DMSO, True, True)] = \ -Tip_50ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.DMSO, True, True)] = ( + Tip_50ul_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 52.5, 30.0: 32.2, 0.0: 0.0, 20.0: 21.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11420,12 +13319,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, False, Liquid.DMSO, False, True)] = \ -Tip_50ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.DMSO, False, True)] = ( + Tip_50ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 50.0: 52.6, 30.0: 32.1, 0.0: 0.0, 1.0: 0.7, 10.0: 11.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -11443,12 +13343,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, False, Liquid.ETHANOL, True, True)] = \ -Tip_50ul_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.ETHANOL, True, True)] = ( + Tip_50ul_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 58.4, 0.0: 0.0, 30.0: 36.0, 20.0: 24.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -11466,12 +13367,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, False, Liquid.ETHANOL, False, True)] = \ -Tip_50ul_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.ETHANOL, False, True)] = ( + Tip_50ul_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 6.7, 50.0: 54.1, 0.0: 0.0, 30.0: 33.7, 1.0: 2.1, 10.0: 12.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -11489,12 +13391,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, False, Liquid.GLYCERIN80, False, True)] = \ -Tip_50ul_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.GLYCERIN80, False, True)] = ( + Tip_50ul_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.7, 50.0: 59.4, 0.0: 0.0, 30.0: 36.0, 1.0: 0.3, 10.0: 11.8}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -11512,12 +13415,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, False, Liquid.SERUM, True, True)] = \ -Tip_50ul_Serum_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.SERUM, True, True)] = ( + Tip_50ul_Serum_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 54.6, 30.0: 33.5, 0.0: 0.0, 20.0: 22.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11535,12 +13439,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, False, Liquid.SERUM, False, True)] = \ -Tip_50ul_Serum_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.SERUM, False, True)] = ( + Tip_50ul_Serum_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.7, 50.0: 54.9, 30.0: 33.0, 0.0: 0.0, 1.0: 0.7, 10.0: 11.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -11558,12 +13463,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, False, Liquid.WATER, True, True)] = \ -Tip_50ul_Water_DispenseJet_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.WATER, True, True)] = ( + Tip_50ul_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 54.0, 30.0: 33.5, 0.0: 0.0, 20.0: 22.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -11581,12 +13487,13 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -star_mapping[(50, False, True, False, Liquid.WATER, False, True)] = \ -Tip_50ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +star_mapping[(50, False, True, False, Liquid.WATER, False, True)] = ( + Tip_50ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.7, 50.0: 54.2, 30.0: 33.2, 0.0: 0.0, 1.0: 0.7, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -11604,5 +13511,5 @@ def get_star_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) diff --git a/pylabrobot/liquid_handling/liquid_classes/hamilton/vantage.py b/pylabrobot/liquid_handling/liquid_classes/hamilton/vantage.py index 6d0dd1926c..812efb6b25 100644 --- a/pylabrobot/liquid_handling/liquid_classes/hamilton/vantage.py +++ b/pylabrobot/liquid_handling/liquid_classes/hamilton/vantage.py @@ -2,18 +2,29 @@ from typing import Dict, Tuple -from pylabrobot.resources.liquid import Liquid from pylabrobot.liquid_handling.liquid_classes.hamilton.base import HamiltonLiquidClass - +from pylabrobot.resources.liquid import Liquid vantage_mapping: Dict[Tuple[int, bool, bool, bool, Liquid, bool, bool], HamiltonLiquidClass] = {} + def get_vantage_liquid_class(**kwargs): raise NotImplementedError("deprecated") -vantage_mapping[(1000, False, False, False, Liquid.WATER, True, True)] = \ -_1000ulNeedleCRWater_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 520.0, 50.0: 61.2, 0.0: 0.0, 20.0: 22.5, 100.0: 113.0, 10.0: 11.1, 200.0: 214.0, 1000.0: 1032.0}, + +vantage_mapping[(1000, False, False, False, Liquid.WATER, True, True)] = ( + _1000ulNeedleCRWater_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 520.0, + 50.0: 61.2, + 0.0: 0.0, + 20.0: 22.5, + 100.0: 113.0, + 10.0: 11.1, + 200.0: 214.0, + 1000.0: 1032.0, + }, aspiration_flow_rate=500.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=0.0, @@ -30,12 +41,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = \ -_1000ulNeedleCRWater_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = ( + _1000ulNeedleCRWater_DispenseJet_Part +) = HamiltonLiquidClass( curve={500.0: 520.0, 50.0: 62.2, 0.0: 0.0, 20.0: 32.0, 100.0: 115.5, 1000.0: 1032.0}, aspiration_flow_rate=500.0, aspiration_mix_flow_rate=500.0, @@ -53,13 +65,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # -vantage_mapping[(1000, False, False, False, Liquid.WATER, False, True)] = \ -_1000ulNeedleCRWater_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(1000, False, False, False, Liquid.WATER, False, True)] = ( + _1000ulNeedleCRWater_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={50.0: 59.0, 0.0: 0.0, 20.0: 25.9, 10.0: 12.9, 1000.0: 1000.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -77,13 +90,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # -vantage_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = \ -_1000ulNeedleCRWater_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = ( + _1000ulNeedleCRWater_DispenseSurface_Part +) = HamiltonLiquidClass( curve={50.0: 55.0, 0.0: 0.0, 20.0: 25.9, 10.0: 12.9, 1000.0: 1000.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -101,7 +115,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -119,9 +133,18 @@ def get_vantage_liquid_class(**kwargs): # 200 1.25 - 0.51 # 500 0.91 0.02 # 1000 0.66 - 0.46 -vantage_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = \ -_1000ulNeedle_Water_DispenseJet = HamiltonLiquidClass( - curve={500.0: 530.0, 50.0: 56.0, 0.0: 0.0, 100.0: 110.0, 20.0: 22.5, 1000.0: 1055.0, 200.0: 214.0}, +vantage_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = ( + _1000ulNeedle_Water_DispenseJet +) = HamiltonLiquidClass( + curve={ + 500.0: 530.0, + 50.0: 56.0, + 0.0: 0.0, + 100.0: 110.0, + 20.0: 22.5, + 1000.0: 1055.0, + 200.0: 214.0, + }, aspiration_flow_rate=500.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=0.0, @@ -138,7 +161,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=0.4, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -157,8 +180,9 @@ def get_vantage_liquid_class(**kwargs): # 20 10.12 - 4.66 # 50 3.79 - 1.18 # -vantage_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = \ -_1000ulNeedle_Water_DispenseSurface = HamiltonLiquidClass( +vantage_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = ( + _1000ulNeedle_Water_DispenseSurface +) = HamiltonLiquidClass( curve={50.0: 59.0, 0.0: 0.0, 20.0: 25.9, 1000.0: 1000.0}, aspiration_flow_rate=500.0, aspiration_mix_flow_rate=500.0, @@ -176,12 +200,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=0.4, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, False, False, Liquid.WATER, False, True)] = \ -_10ulNeedleCRWater_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(10, False, False, False, Liquid.WATER, False, True)] = ( + _10ulNeedleCRWater_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.7, 0.5: 0.5, 0.0: 0.0, 1.0: 1.2, 2.0: 2.4, 10.0: 11.4}, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, @@ -199,12 +224,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, False, False, Liquid.WATER, False, False)] = \ -_10ulNeedleCRWater_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(10, False, False, False, Liquid.WATER, False, False)] = ( + _10ulNeedleCRWater_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.7, 0.5: 0.5, 0.0: 0.0, 1.0: 1.2, 2.0: 2.4, 10.0: 11.4}, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, @@ -222,12 +248,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, True, Liquid.DMSO, True, False)] = \ -_150ul_Piercing_Tip_Filter_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.DMSO, True, False)] = ( + _150ul_Piercing_Tip_Filter_DMSO_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={150.0: 150.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=180.0, aspiration_mix_flow_rate=100.0, @@ -245,12 +272,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, True, Liquid.DMSO, True, True)] = \ -_150ul_Piercing_Tip_Filter_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.DMSO, True, True)] = ( + _150ul_Piercing_Tip_Filter_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={150.0: 154.0, 50.0: 52.9, 0.0: 0.0, 20.0: 21.8}, aspiration_flow_rate=180.0, aspiration_mix_flow_rate=100.0, @@ -268,12 +296,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, True, Liquid.DMSO, False, True)] = \ -_150ul_Piercing_Tip_Filter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.DMSO, False, True)] = ( + _150ul_Piercing_Tip_Filter_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={3.0: 4.5, 5.0: 6.5, 150.0: 155.0, 50.0: 53.7, 0.0: 0.0, 10.0: 12.0, 2.0: 3.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -291,7 +320,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -312,8 +341,9 @@ def get_vantage_liquid_class(**kwargs): # 100 1.67 -0.35 # 300 0.46 -0.61 # -vantage_mapping[(50, False, True, True, Liquid.ETHANOL, True, True)] = \ -_150ul_Piercing_Tip_Filter_Ethanol_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.ETHANOL, True, True)] = ( + _150ul_Piercing_Tip_Filter_Ethanol_DispenseJet_Empty +) = HamiltonLiquidClass( curve={150.0: 166.0, 50.0: 58.3, 0.0: 0.0, 20.0: 25.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=50.0, @@ -331,7 +361,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -353,8 +383,9 @@ def get_vantage_liquid_class(**kwargs): # 20 0.95 2.97 # 50 0.31 -0.10 # -vantage_mapping[(50, False, True, True, Liquid.ETHANOL, False, True)] = \ -_150ul_Piercing_Tip_Filter_Ethanol_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.ETHANOL, False, True)] = ( + _150ul_Piercing_Tip_Filter_Ethanol_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={3.0: 5.0, 5.0: 7.6, 150.0: 165.0, 50.0: 56.9, 0.0: 0.0, 10.0: 13.2, 2.0: 3.3}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -372,7 +403,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -395,8 +426,9 @@ def get_vantage_liquid_class(**kwargs): # 300 1.08 -0.87 # # -vantage_mapping[(50, False, True, True, Liquid.GLYCERIN80, False, True)] = \ -_150ul_Piercing_Tip_Filter_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.GLYCERIN80, False, True)] = ( + _150ul_Piercing_Tip_Filter_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={3.0: 4.5, 5.0: 7.2, 150.0: 167.5, 50.0: 60.0, 0.0: 0.0, 1.0: 2.7, 10.0: 13.0, 2.0: 2.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -414,7 +446,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -434,8 +466,9 @@ def get_vantage_liquid_class(**kwargs): # 100 0.81 0.99 # 300 1.00 0.65 # -vantage_mapping[(50, False, True, True, Liquid.SERUM, True, True)] = \ -_150ul_Piercing_Tip_Filter_Serum_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.SERUM, True, True)] = ( + _150ul_Piercing_Tip_Filter_Serum_DispenseJet_Empty +) = HamiltonLiquidClass( curve={150.0: 162.0, 50.0: 55.9, 0.0: 0.0, 20.0: 23.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -453,7 +486,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -476,8 +509,9 @@ def get_vantage_liquid_class(**kwargs): # 50 1.39 -0.12 # # -vantage_mapping[(50, False, True, True, Liquid.SERUM, False, True)] = \ -_150ul_Piercing_Tip_Filter_Serum_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.SERUM, False, True)] = ( + _150ul_Piercing_Tip_Filter_Serum_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={3.0: 3.4, 5.0: 5.9, 150.0: 161.5, 50.0: 56.2, 0.0: 0.0, 10.0: 11.6, 2.0: 2.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -495,12 +529,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, True, Liquid.WATER, True, False)] = \ -_150ul_Piercing_Tip_Filter_Water_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.WATER, True, False)] = ( + _150ul_Piercing_Tip_Filter_Water_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={150.0: 150.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -518,13 +553,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -vantage_mapping[(50, False, True, True, Liquid.WATER, True, True)] = \ -_150ul_Piercing_Tip_Filter_Water_DispenseJet_Empty = HamiltonLiquidClass( - curve={5.0: 6.6, 150.0: 159.1, 50.0: 55.0, 0.0: 0.0, 100.0: 107.0, 1.0: 1.6, 20.0: 22.9, 10.0: 12.2}, +vantage_mapping[(50, False, True, True, Liquid.WATER, True, True)] = ( + _150ul_Piercing_Tip_Filter_Water_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 5.0: 6.6, + 150.0: 159.1, + 50.0: 55.0, + 0.0: 0.0, + 100.0: 107.0, + 1.0: 1.6, + 20.0: 22.9, + 10.0: 12.2, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -541,12 +586,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, True, Liquid.WATER, False, True)] = \ -_150ul_Piercing_Tip_Filter_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.WATER, False, True)] = ( + _150ul_Piercing_Tip_Filter_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={3.0: 3.5, 5.0: 6.5, 150.0: 158.1, 50.0: 54.5, 0.0: 0.0, 1.0: 1.6, 10.0: 11.9, 2.0: 2.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -564,12 +610,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, False, Liquid.DMSO, True, True)] = \ -_250ul_Piercing_Tip_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.DMSO, True, True)] = ( + _250ul_Piercing_Tip_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={250.0: 255.5, 50.0: 52.9, 0.0: 0.0, 20.0: 21.8}, aspiration_flow_rate=180.0, aspiration_mix_flow_rate=100.0, @@ -587,12 +634,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, False, Liquid.DMSO, False, True)] = \ -_250ul_Piercing_Tip_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.DMSO, False, True)] = ( + _250ul_Piercing_Tip_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={3.0: 4.2, 5.0: 6.5, 250.0: 256.0, 50.0: 53.7, 0.0: 0.0, 10.0: 12.0, 2.0: 3.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -610,7 +658,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -631,8 +679,9 @@ def get_vantage_liquid_class(**kwargs): # 100 1.67 -0.35 # 300 0.46 -0.61 # -vantage_mapping[(50, False, True, False, Liquid.ETHANOL, True, True)] = \ -_250ul_Piercing_Tip_Ethanol_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.ETHANOL, True, True)] = ( + _250ul_Piercing_Tip_Ethanol_DispenseJet_Empty +) = HamiltonLiquidClass( curve={250.0: 270.2, 50.0: 59.2, 0.0: 0.0, 20.0: 27.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=50.0, @@ -650,7 +699,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -672,8 +721,9 @@ def get_vantage_liquid_class(**kwargs): # 20 0.95 2.97 # 50 0.31 -0.10 # -vantage_mapping[(50, False, True, False, Liquid.ETHANOL, False, True)] = \ -_250ul_Piercing_Tip_Ethanol_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.ETHANOL, False, True)] = ( + _250ul_Piercing_Tip_Ethanol_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={3.0: 5.0, 5.0: 9.6, 250.0: 270.5, 50.0: 58.0, 0.0: 0.0, 10.0: 14.8}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -691,7 +741,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -714,8 +764,9 @@ def get_vantage_liquid_class(**kwargs): # 300 1.08 -0.87 # # -vantage_mapping[(50, False, True, False, Liquid.GLYCERIN80, False, True)] = \ -_250ul_Piercing_Tip_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.GLYCERIN80, False, True)] = ( + _250ul_Piercing_Tip_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={3.0: 4.5, 5.0: 7.2, 250.0: 289.0, 50.0: 65.0, 0.0: 0.0, 1.0: 2.7, 10.0: 13.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -733,7 +784,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -753,8 +804,9 @@ def get_vantage_liquid_class(**kwargs): # 100 0.81 0.99 # 300 1.00 0.65 # -vantage_mapping[(50, False, True, False, Liquid.SERUM, True, True)] = \ -_250ul_Piercing_Tip_Serum_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.SERUM, True, True)] = ( + _250ul_Piercing_Tip_Serum_DispenseJet_Empty +) = HamiltonLiquidClass( curve={250.0: 265.0, 50.0: 56.4, 0.0: 0.0, 20.0: 23.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -772,7 +824,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -795,8 +847,9 @@ def get_vantage_liquid_class(**kwargs): # 50 1.39 -0.12 # # -vantage_mapping[(50, False, True, False, Liquid.SERUM, False, True)] = \ -_250ul_Piercing_Tip_Serum_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.SERUM, False, True)] = ( + _250ul_Piercing_Tip_Serum_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={3.0: 3.4, 5.0: 5.9, 250.0: 264.2, 50.0: 56.2, 0.0: 0.0, 10.0: 11.6}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -814,13 +867,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, False, Liquid.WATER, True, True)] = \ -_250ul_Piercing_Tip_Water_DispenseJet_Empty = HamiltonLiquidClass( - curve={5.0: 6.6, 250.0: 260.0, 50.0: 55.0, 0.0: 0.0, 100.0: 107.0, 1.0: 1.6, 20.0: 22.5, 10.0: 12.2}, +vantage_mapping[(50, False, True, False, Liquid.WATER, True, True)] = ( + _250ul_Piercing_Tip_Water_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 5.0: 6.6, + 250.0: 260.0, + 50.0: 55.0, + 0.0: 0.0, + 100.0: 107.0, + 1.0: 1.6, + 20.0: 22.5, + 10.0: 12.2, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -837,12 +900,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, False, Liquid.WATER, False, True)] = \ -_250ul_Piercing_Tip_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.WATER, False, True)] = ( + _250ul_Piercing_Tip_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={3.0: 4.0, 5.0: 6.5, 250.0: 259.0, 50.0: 55.1, 0.0: 0.0, 1.0: 1.6, 10.0: 12.6, 2.0: 2.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -860,7 +924,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -881,8 +945,9 @@ def get_vantage_liquid_class(**kwargs): # 100 1.04 0.05 # 300 0.63 -0.07 # -vantage_mapping[(300, False, False, False, Liquid.ACETONITRIL80WATER20, True, False)] = \ -_300ulNeedleAcetonitril80Water20DispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, False, False, Liquid.ACETONITRIL80WATER20, True, False)] = ( + _300ulNeedleAcetonitril80Water20DispenseJet +) = HamiltonLiquidClass( curve={300.0: 310.0, 50.0: 57.8, 0.0: 0.0, 100.0: 106.5, 20.0: 26.8, 10.0: 16.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=50.0, @@ -900,12 +965,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, False, False, Liquid.WATER, True, True)] = \ -_300ulNeedleCRWater_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, False, False, False, Liquid.WATER, True, True)] = ( + _300ulNeedleCRWater_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 313.0, 50.0: 53.5, 0.0: 0.0, 100.0: 104.0, 20.0: 22.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -923,12 +989,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, False, False, Liquid.WATER, True, False)] = \ -_300ulNeedleCRWater_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, False, False, Liquid.WATER, True, False)] = ( + _300ulNeedleCRWater_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 313.0, 50.0: 59.5, 0.0: 0.0, 100.0: 109.0, 20.0: 29.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -946,13 +1013,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(300, False, False, False, Liquid.WATER, False, True)] = \ -_300ulNeedleCRWater_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 308.4, 5.0: 6.8, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 2.3, 200.0: 205.8, 10.0: 11.7, 2.0: 3.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(300, False, False, False, Liquid.WATER, False, True)] = ( + _300ulNeedleCRWater_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 308.4, + 5.0: 6.8, + 50.0: 52.3, + 0.0: 0.0, + 100.0: 102.9, + 20.0: 22.3, + 1.0: 2.3, + 200.0: 205.8, + 10.0: 11.7, + 2.0: 3.0, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=1.0, @@ -969,13 +1048,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(300, False, False, False, Liquid.WATER, False, False)] = \ -_300ulNeedleCRWater_DispenseSurface_Part = HamiltonLiquidClass( - curve={300.0: 308.4, 5.0: 6.8, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 2.3, 200.0: 205.8, 10.0: 11.7, 2.0: 3.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(300, False, False, False, Liquid.WATER, False, False)] = ( + _300ulNeedleCRWater_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 300.0: 308.4, + 5.0: 6.8, + 50.0: 52.3, + 0.0: 0.0, + 100.0: 102.9, + 20.0: 22.3, + 1.0: 2.3, + 200.0: 205.8, + 10.0: 11.7, + 2.0: 3.0, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=1.0, @@ -992,7 +1083,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1012,8 +1103,9 @@ def get_vantage_liquid_class(**kwargs): # 100 0.55 -0.01 # 300 0.71 0.39 # -vantage_mapping[(300, False, False, False, Liquid.DIMETHYLSULFOXID, True, False)] = \ -_300ulNeedleDMSODispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, False, False, Liquid.DIMETHYLSULFOXID, True, False)] = ( + _300ulNeedleDMSODispenseJet +) = HamiltonLiquidClass( curve={300.0: 317.0, 50.0: 53.5, 0.0: 0.0, 100.0: 106.5, 20.0: 21.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -1031,7 +1123,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1052,8 +1144,9 @@ def get_vantage_liquid_class(**kwargs): # 50 1.32 -1.05 # # -vantage_mapping[(300, False, False, False, Liquid.DIMETHYLSULFOXID, False, False)] = \ -_300ulNeedleDMSODispenseSurface = HamiltonLiquidClass( +vantage_mapping[(300, False, False, False, Liquid.DIMETHYLSULFOXID, False, False)] = ( + _300ulNeedleDMSODispenseSurface +) = HamiltonLiquidClass( curve={5.0: 6.0, 50.0: 52.3, 0.0: 0.0, 20.0: 22.3, 10.0: 11.4, 2.0: 2.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -1071,7 +1164,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1092,8 +1185,9 @@ def get_vantage_liquid_class(**kwargs): # 100 1.67 -0.35 # 300 0.46 -0.61 # -vantage_mapping[(300, False, False, False, Liquid.ETHANOL, True, False)] = \ -_300ulNeedleEtOHDispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, False, False, Liquid.ETHANOL, True, False)] = ( + _300ulNeedleEtOHDispenseJet +) = HamiltonLiquidClass( curve={300.0: 317.0, 50.0: 57.8, 0.0: 0.0, 100.0: 109.0, 20.0: 25.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=50.0, @@ -1111,7 +1205,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1133,8 +1227,9 @@ def get_vantage_liquid_class(**kwargs): # 20 0.95 2.97 # 50 0.31 -0.10 # -vantage_mapping[(300, False, False, False, Liquid.ETHANOL, False, False)] = \ -_300ulNeedleEtOHDispenseSurface = HamiltonLiquidClass( +vantage_mapping[(300, False, False, False, Liquid.ETHANOL, False, False)] = ( + _300ulNeedleEtOHDispenseSurface +) = HamiltonLiquidClass( curve={5.0: 7.2, 50.0: 55.0, 0.0: 0.0, 20.0: 24.5, 10.0: 13.1}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -1152,7 +1247,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1175,9 +1270,20 @@ def get_vantage_liquid_class(**kwargs): # 300 1.08 -0.87 # # -vantage_mapping[(300, False, False, False, Liquid.GLYCERIN80, False, False)] = \ -_300ulNeedleGlycerin80DispenseSurface = HamiltonLiquidClass( - curve={300.0: 325.0, 5.0: 8.0, 50.0: 61.3, 0.0: 0.0, 100.0: 117.0, 20.0: 26.0, 1.0: 2.7, 10.0: 13.9, 2.0: 4.2}, +vantage_mapping[(300, False, False, False, Liquid.GLYCERIN80, False, False)] = ( + _300ulNeedleGlycerin80DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 325.0, + 5.0: 8.0, + 50.0: 61.3, + 0.0: 0.0, + 100.0: 117.0, + 20.0: 26.0, + 1.0: 2.7, + 10.0: 13.9, + 2.0: 4.2, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=5.0, @@ -1194,7 +1300,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1214,8 +1320,9 @@ def get_vantage_liquid_class(**kwargs): # 100 0.81 0.99 # 300 1.00 0.65 # -vantage_mapping[(300, False, False, False, Liquid.SERUM, True, False)] = \ -_300ulNeedleSerumDispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, False, False, Liquid.SERUM, True, False)] = ( + _300ulNeedleSerumDispenseJet +) = HamiltonLiquidClass( curve={300.0: 313.0, 50.0: 53.5, 0.0: 0.0, 100.0: 105.0, 20.0: 21.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -1233,7 +1340,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1256,8 +1363,9 @@ def get_vantage_liquid_class(**kwargs): # 50 1.39 -0.12 # # -vantage_mapping[(300, False, False, False, Liquid.SERUM, False, False)] = \ -_300ulNeedleSerumDispenseSurface = HamiltonLiquidClass( +vantage_mapping[(300, False, False, False, Liquid.SERUM, False, False)] = ( + _300ulNeedleSerumDispenseSurface +) = HamiltonLiquidClass( curve={5.0: 6.0, 50.0: 52.3, 0.0: 0.0, 20.0: 22.3, 1.0: 2.2, 10.0: 11.9, 2.0: 3.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -1275,7 +1383,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1295,8 +1403,9 @@ def get_vantage_liquid_class(**kwargs): # 100 0.81 0.99 # 300 1.00 0.65 # -vantage_mapping[(300, False, False, False, Liquid.SERUM, True, False)] = \ -_300ulNeedle_Serum_DispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, False, False, Liquid.SERUM, True, False)] = ( + _300ulNeedle_Serum_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 313.0, 50.0: 53.5, 0.0: 0.0, 100.0: 105.0, 20.0: 21.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -1314,7 +1423,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1337,8 +1446,9 @@ def get_vantage_liquid_class(**kwargs): # 50 1.39 -0.12 # # -vantage_mapping[(300, False, False, False, Liquid.SERUM, False, False)] = \ -_300ulNeedle_Serum_DispenseSurface = HamiltonLiquidClass( +vantage_mapping[(300, False, False, False, Liquid.SERUM, False, False)] = ( + _300ulNeedle_Serum_DispenseSurface +) = HamiltonLiquidClass( curve={300.0: 350.0, 5.0: 6.0, 50.0: 52.3, 0.0: 0.0, 20.0: 22.3, 1.0: 2.2, 10.0: 11.9, 2.0: 3.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -1356,7 +1466,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1377,8 +1487,9 @@ def get_vantage_liquid_class(**kwargs): # 200 0.16 0.55 # 300 0.17 0.35 # -vantage_mapping[(300, False, False, False, Liquid.WATER, True, False)] = \ -_300ulNeedle_Water_DispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, False, False, Liquid.WATER, True, False)] = ( + _300ulNeedle_Water_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 313.0, 50.0: 53.5, 0.0: 0.0, 100.0: 105.0, 20.0: 22.3}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -1396,7 +1507,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -1418,9 +1529,21 @@ def get_vantage_liquid_class(**kwargs): # 20 0.63 0.73 # # -vantage_mapping[(300, False, False, False, Liquid.WATER, False, False)] = \ -_300ulNeedle_Water_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 308.4, 5.0: 6.5, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 1.1, 200.0: 205.8, 10.0: 12.0, 2.0: 2.1}, +vantage_mapping[(300, False, False, False, Liquid.WATER, False, False)] = ( + _300ulNeedle_Water_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 308.4, + 5.0: 6.5, + 50.0: 52.3, + 0.0: 0.0, + 100.0: 102.9, + 20.0: 22.3, + 1.0: 1.1, + 200.0: 205.8, + 10.0: 12.0, + 2.0: 2.1, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, aspiration_air_transport_volume=0.0, @@ -1437,13 +1560,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=0.4, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # Evaluation -vantage_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ -_300ul_RocketTip_384COREHead_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = ( + _300ul_RocketTip_384COREHead_DMSO_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 150.0: 150.0, 50.0: 50.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -1461,13 +1585,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=120.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # Evaluation -vantage_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ -_300ul_RocketTip_384COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = ( + _300ul_RocketTip_384COREHead_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 303.5, 0.0: 0.0, 100.0: 105.8, 200.0: 209.5, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -1485,13 +1610,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # Evaluation -vantage_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ -_300ul_RocketTip_384COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = ( + _300ul_RocketTip_384COREHead_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 308.0, 0.0: 0.0, 100.0: 105.5, 200.0: 209.0, 10.0: 12.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -1509,13 +1635,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # Evaluation -vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ -_300ul_RocketTip_384COREHead_Water_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( + _300ul_RocketTip_384COREHead_Water_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 309.0, 0.0: 0.0, 100.0: 106.5, 20.0: 22.3, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -1533,13 +1660,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=20.0 + dispense_stop_back_volume=20.0, ) # Evaluation -vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ -_300ul_RocketTip_384COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( + _300ul_RocketTip_384COREHead_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 309.0, 0.0: 0.0, 100.0: 106.5, 20.0: 22.3, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -1557,13 +1685,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # Evaluation -vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ -_300ul_RocketTip_384COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( + _300ul_RocketTip_384COREHead_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 314.3, 0.0: 0.0, 100.0: 109.0, 200.0: 214.7, 10.0: 12.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -1581,12 +1710,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(30, True, True, False, Liquid.DMSO, True, True)] = \ -_30ulTip_384COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(30, True, True, False, Liquid.DMSO, True, True)] = ( + _30ulTip_384COREHead_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={5.0: 5.0, 15.0: 15.3, 30.0: 30.7, 0.0: 0.0, 1.0: 1.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -1604,12 +1734,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(30, True, True, False, Liquid.DMSO, False, True)] = \ -_30ulTip_384COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(30, True, True, False, Liquid.DMSO, False, True)] = ( + _30ulTip_384COREHead_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 4.9, 15.0: 15.1, 30.0: 30.0, 0.0: 0.0, 1.0: 0.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -1627,12 +1758,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(30, True, True, False, Liquid.ETHANOL, True, True)] = \ -_30ulTip_384COREHead_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(30, True, True, False, Liquid.ETHANOL, True, True)] = ( + _30ulTip_384COREHead_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={5.0: 6.54, 15.0: 18.36, 30.0: 33.8, 0.0: 0.0, 1.0: 1.8}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -1650,12 +1782,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(30, True, True, False, Liquid.ETHANOL, False, True)] = \ -_30ulTip_384COREHead_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(30, True, True, False, Liquid.ETHANOL, False, True)] = ( + _30ulTip_384COREHead_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 6.2, 15.0: 16.9, 30.0: 33.1, 0.0: 0.0, 1.0: 1.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -1673,12 +1806,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(30, True, True, False, Liquid.GLYCERIN80, False, True)] = \ -_30ulTip_384COREHead_Glyzerin80_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(30, True, True, False, Liquid.GLYCERIN80, False, True)] = ( + _30ulTip_384COREHead_Glyzerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 6.3, 0.5: 0.9, 40.0: 44.0, 0.0: 0.0, 20.0: 22.2, 1.0: 1.6, 10.0: 11.9, 2.0: 2.8}, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=100.0, @@ -1696,12 +1830,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(30, True, True, False, Liquid.WATER, True, True)] = \ -_30ulTip_384COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(30, True, True, False, Liquid.WATER, True, True)] = ( + _30ulTip_384COREHead_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={5.0: 6.0, 15.0: 16.5, 30.0: 32.3, 0.0: 0.0, 1.0: 1.6}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -1719,12 +1854,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(30, True, True, False, Liquid.WATER, False, True)] = \ -_30ulTip_384COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(30, True, True, False, Liquid.WATER, False, True)] = ( + _30ulTip_384COREHead_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 15.0: 15.9, 30.0: 31.3, 0.0: 0.0, 1.0: 1.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -1742,12 +1878,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(30, True, True, False, Liquid.WATER, False, False)] = \ -_30ulTip_384COREWasher_DispenseSurface = HamiltonLiquidClass( +vantage_mapping[(30, True, True, False, Liquid.WATER, False, False)] = ( + _30ulTip_384COREWasher_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 6.3, 0.5: 0.9, 40.0: 44.0, 0.0: 0.0, 1.0: 1.6, 20.0: 22.2, 2.0: 2.8, 10.0: 11.9}, aspiration_flow_rate=10.0, aspiration_mix_flow_rate=30.0, @@ -1765,13 +1902,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(4000, False, True, False, Liquid.DMSO, True, False)] = \ -_4mlTF_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( - curve={3500.0: 3715.0, 500.0: 631.0, 2500.0: 2691.0, 1500.0: 1667.0, 4000.0: 4224.0, 3000.0: 3202.0, 0.0: 0.0, 2000.0: 2179.0, 100.0: 211.0, 1000.0: 1151.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(4000, False, True, False, Liquid.DMSO, True, False)] = ( + _4mlTF_DMSO_DispenseJet_Aliquot +) = HamiltonLiquidClass( + curve={ + 3500.0: 3715.0, + 500.0: 631.0, + 2500.0: 2691.0, + 1500.0: 1667.0, + 4000.0: 4224.0, + 3000.0: 3202.0, + 0.0: 0.0, + 2000.0: 2179.0, + 100.0: 211.0, + 1000.0: 1151.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -1788,13 +1937,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=20.0 -) - - -vantage_mapping[(4000, False, True, False, Liquid.DMSO, True, True)] = \ -_4mlTF_DMSO_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 540.0, 50.0: 61.5, 4000.0: 4102.0, 3000.0: 3083.0, 0.0: 0.0, 2000.0: 2070.0, 100.0: 116.5, 1000.0: 1060.0}, + dispense_stop_back_volume=20.0, +) + + +vantage_mapping[(4000, False, True, False, Liquid.DMSO, True, True)] = ( + _4mlTF_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 540.0, + 50.0: 61.5, + 4000.0: 4102.0, + 3000.0: 3083.0, + 0.0: 0.0, + 2000.0: 2070.0, + 100.0: 116.5, + 1000.0: 1060.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -1811,13 +1970,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(4000, False, True, False, Liquid.DMSO, False, True)] = \ -_4mlTF_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 536.5, 50.0: 62.3, 4000.0: 4128.0, 3000.0: 3109.0, 0.0: 0.0, 2000.0: 2069.0, 100.0: 116.6, 1000.0: 1054.0, 10.0: 15.5}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(4000, False, True, False, Liquid.DMSO, False, True)] = ( + _4mlTF_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 536.5, + 50.0: 62.3, + 4000.0: 4128.0, + 3000.0: 3109.0, + 0.0: 0.0, + 2000.0: 2069.0, + 100.0: 116.6, + 1000.0: 1054.0, + 10.0: 15.5, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -1834,14 +2004,27 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=500.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # First two times mixing with max volume. -vantage_mapping[(4000, False, True, False, Liquid.ETHANOL, True, False)] = \ -_4mlTF_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( - curve={300.0: 300.0, 3500.0: 3500.0, 500.0: 500.0, 2500.0: 2500.0, 1500.0: 1500.0, 4000.0: 4000.0, 3000.0: 3000.0, 0.0: 0.0, 2000.0: 2000.0, 100.0: 100.0, 1000.0: 1000.0}, +vantage_mapping[(4000, False, True, False, Liquid.ETHANOL, True, False)] = ( + _4mlTF_EtOH_DispenseJet_Aliquot +) = HamiltonLiquidClass( + curve={ + 300.0: 300.0, + 3500.0: 3500.0, + 500.0: 500.0, + 2500.0: 2500.0, + 1500.0: 1500.0, + 4000.0: 4000.0, + 3000.0: 3000.0, + 0.0: 0.0, + 2000.0: 2000.0, + 100.0: 100.0, + 1000.0: 1000.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=2000.0, aspiration_air_transport_volume=0.0, @@ -1858,13 +2041,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(4000, False, True, False, Liquid.ETHANOL, True, True)] = \ -_4mlTF_EtOH_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 563.0, 50.0: 72.0, 4000.0: 4215.0, 3000.0: 3190.0, 0.0: 0.0, 2000.0: 2178.0, 100.0: 127.5, 1000.0: 1095.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(4000, False, True, False, Liquid.ETHANOL, True, True)] = ( + _4mlTF_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 563.0, + 50.0: 72.0, + 4000.0: 4215.0, + 3000.0: 3190.0, + 0.0: 0.0, + 2000.0: 2178.0, + 100.0: 127.5, + 1000.0: 1095.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=30.0, @@ -1881,13 +2074,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=30.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(4000, False, True, False, Liquid.ETHANOL, False, True)] = \ -_4mlTF_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 555.0, 50.0: 68.0, 4000.0: 4177.0, 3000.0: 3174.0, 0.0: 0.0, 2000.0: 2151.0, 100.0: 123.5, 1000.0: 1085.0, 10.0: 18.6}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(4000, False, True, False, Liquid.ETHANOL, False, True)] = ( + _4mlTF_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 555.0, + 50.0: 68.0, + 4000.0: 4177.0, + 3000.0: 3174.0, + 0.0: 0.0, + 2000.0: 2151.0, + 100.0: 123.5, + 1000.0: 1085.0, + 10.0: 18.6, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=30.0, @@ -1904,13 +2108,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=30.0, dispense_settling_time=1.0, dispense_stop_flow_rate=30.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(4000, False, True, False, Liquid.GLYCERIN80, True, True)] = \ -_4mlTF_Glycerin80_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 599.0, 50.0: 89.0, 4000.0: 4223.0, 3000.0: 3211.0, 0.0: 0.0, 2000.0: 2195.0, 100.0: 140.0, 1000.0: 1159.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(4000, False, True, False, Liquid.GLYCERIN80, True, True)] = ( + _4mlTF_Glycerin80_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 599.0, + 50.0: 89.0, + 4000.0: 4223.0, + 3000.0: 3211.0, + 0.0: 0.0, + 2000.0: 2195.0, + 100.0: 140.0, + 1000.0: 1159.0, + }, aspiration_flow_rate=1200.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=30.0, @@ -1927,13 +2141,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(4000, False, True, False, Liquid.GLYCERIN80, False, True)] = \ -_4mlTF_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 555.0, 50.0: 71.0, 4000.0: 4135.0, 3000.0: 3122.0, 0.0: 0.0, 2000.0: 2101.0, 100.0: 129.0, 1000.0: 1083.0, 10.0: 16.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(4000, False, True, False, Liquid.GLYCERIN80, False, True)] = ( + _4mlTF_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 555.0, + 50.0: 71.0, + 4000.0: 4135.0, + 3000.0: 3122.0, + 0.0: 0.0, + 2000.0: 2101.0, + 100.0: 129.0, + 1000.0: 1083.0, + 10.0: 16.0, + }, aspiration_flow_rate=1000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=0.0, @@ -1950,12 +2175,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(4000, False, True, False, Liquid.WATER, True, False)] = \ -_4mlTF_Water_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(4000, False, True, False, Liquid.WATER, True, False)] = ( + _4mlTF_Water_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={4000.0: 4160.0, 3000.0: 3160.0, 0.0: 0.0, 2000.0: 2160.0, 100.0: 214.0, 1000.0: 1148.0}, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, @@ -1973,13 +2199,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=20.0 -) - - -vantage_mapping[(4000, False, True, False, Liquid.WATER, True, True)] = \ -_4mlTF_Water_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 551.8, 50.0: 66.4, 4000.0: 4165.0, 3000.0: 3148.0, 0.0: 0.0, 2000.0: 2128.0, 100.0: 122.7, 1000.0: 1082.0}, + dispense_stop_back_volume=20.0, +) + + +vantage_mapping[(4000, False, True, False, Liquid.WATER, True, True)] = ( + _4mlTF_Water_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 551.8, + 50.0: 66.4, + 4000.0: 4165.0, + 3000.0: 3148.0, + 0.0: 0.0, + 2000.0: 2128.0, + 100.0: 122.7, + 1000.0: 1082.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -1996,13 +2232,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(4000, False, True, False, Liquid.WATER, False, True)] = \ -_4mlTF_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 547.0, 50.0: 65.5, 4000.0: 4145.0, 3000.0: 3135.0, 0.0: 0.0, 2000.0: 2125.0, 100.0: 120.9, 1000.0: 1075.0, 10.0: 14.5}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(4000, False, True, False, Liquid.WATER, False, True)] = ( + _4mlTF_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 547.0, + 50.0: 65.5, + 4000.0: 4145.0, + 3000.0: 3135.0, + 0.0: 0.0, + 2000.0: 2125.0, + 100.0: 120.9, + 1000.0: 1075.0, + 10.0: 14.5, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2019,12 +2266,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=500.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ -_50ulTip_384COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = ( + _50ulTip_384COREHead_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 52.0, 0.0: 0.0, 20.0: 21.1, 10.0: 10.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2042,12 +2290,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = \ -_50ulTip_384COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = ( + _50ulTip_384COREHead_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.0, 50.0: 51.1, 30.0: 30.7, 0.0: 0.0, 1.0: 0.9, 10.0: 10.1}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2065,12 +2314,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = \ -_50ulTip_384COREHead_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = ( + _50ulTip_384COREHead_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={5.0: 6.54, 15.0: 18.36, 50.0: 53.0, 30.0: 33.8, 0.0: 0.0, 1.0: 1.8}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2088,12 +2338,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.ETHANOL, False, True)] = \ -_50ulTip_384COREHead_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.ETHANOL, False, True)] = ( + _50ulTip_384COREHead_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 6.2, 15.0: 16.9, 0.5: 1.0, 50.0: 54.0, 30.0: 33.1, 0.0: 0.0, 1.0: 1.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2111,12 +2362,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=6.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.GLYCERIN80, False, True)] = \ -_50ulTip_384COREHead_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.GLYCERIN80, False, True)] = ( + _50ulTip_384COREHead_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 0.5: 0.65, 50.0: 55.0, 0.0: 0.0, 30.0: 31.5, 1.0: 1.2, 10.0: 10.9}, aspiration_flow_rate=30.0, aspiration_mix_flow_rate=30.0, @@ -2134,12 +2386,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ -_50ulTip_384COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.WATER, True, True)] = ( + _50ulTip_384COREHead_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 53.6, 0.0: 0.0, 20.0: 22.4, 10.0: 11.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2157,12 +2410,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.WATER, False, True)] = \ -_50ulTip_384COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.WATER, False, True)] = ( + _50ulTip_384COREHead_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.5, 50.0: 52.2, 30.0: 31.5, 0.0: 0.0, 1.0: 1.2, 10.0: 11.3}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2180,13 +2434,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(50, True, True, False, Liquid.WATER, False, False)] = \ -_50ulTip_384COREWasher_DispenseSurface = HamiltonLiquidClass( - curve={5.0: 6.3, 0.5: 0.9, 50.0: 55.0, 40.0: 44.0, 0.0: 0.0, 20.0: 22.2, 1.0: 1.6, 10.0: 11.9, 2.0: 2.8}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(50, True, True, False, Liquid.WATER, False, False)] = ( + _50ulTip_384COREWasher_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 5.0: 6.3, + 0.5: 0.9, + 50.0: 55.0, + 40.0: 44.0, + 0.0: 0.0, + 20.0: 22.2, + 1.0: 1.6, + 10.0: 11.9, + 2.0: 2.8, + }, aspiration_flow_rate=20.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=0.0, @@ -2203,12 +2468,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ -_50ulTip_conductive_384COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = ( + _50ulTip_conductive_384COREHead_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={5.0: 5.2, 50.0: 50.6, 30.0: 30.4, 0.0: 0.0, 1.0: 0.9, 20.0: 21.1, 10.0: 9.3}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2226,12 +2492,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ -_50ulTip_conductive_384COREHead_DMSO_DispenseJet_Empty_below5ul = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = ( + _50ulTip_conductive_384COREHead_DMSO_DispenseJet_Empty_below5ul +) = HamiltonLiquidClass( curve={5.0: 5.2, 50.0: 50.6, 30.0: 30.4, 0.0: 0.0, 1.0: 0.9, 20.0: 21.1, 10.0: 9.3}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2249,12 +2516,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.DMSO, True, False)] = \ -_50ulTip_conductive_384COREHead_DMSO_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.DMSO, True, False)] = ( + _50ulTip_conductive_384COREHead_DMSO_DispenseJet_Part +) = HamiltonLiquidClass( curve={50.0: 50.0, 0.0: 0.0, 10.0: 10.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2272,13 +2540,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=5.0 -) - - -vantage_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = \ -_50ulTip_conductive_384COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( - curve={0.1: 0.05, 0.25: 0.1, 5.0: 4.95, 0.5: 0.22, 50.0: 50.0, 30.0: 30.6, 0.0: 0.0, 1.0: 0.74, 10.0: 9.95}, + dispense_stop_back_volume=5.0, +) + + +vantage_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = ( + _50ulTip_conductive_384COREHead_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 0.1: 0.05, + 0.25: 0.1, + 5.0: 4.95, + 0.5: 0.22, + 50.0: 50.0, + 30.0: 30.6, + 0.0: 0.0, + 1.0: 0.74, + 10.0: 9.95, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -2295,12 +2574,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = \ -_50ulTip_conductive_384COREHead_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = ( + _50ulTip_conductive_384COREHead_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={5.0: 6.85, 15.0: 18.36, 50.0: 54.3, 30.0: 33.6, 0.0: 0.0, 1.0: 1.5, 10.0: 12.1}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2318,12 +2598,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = \ -_50ulTip_conductive_384COREHead_EtOH_DispenseJet_Empty_below5ul = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = ( + _50ulTip_conductive_384COREHead_EtOH_DispenseJet_Empty_below5ul +) = HamiltonLiquidClass( curve={5.0: 6.85, 15.0: 18.36, 50.0: 54.3, 30.0: 33.6, 0.0: 0.0, 1.0: 1.5, 10.0: 12.1}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2341,12 +2622,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.ETHANOL, True, False)] = \ -_50ulTip_conductive_384COREHead_EtOH_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.ETHANOL, True, False)] = ( + _50ulTip_conductive_384COREHead_EtOH_DispenseJet_Part +) = HamiltonLiquidClass( curve={50.0: 50.0, 0.0: 0.0, 10.0: 10.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2364,13 +2646,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=2.0 -) - - -vantage_mapping[(50, True, True, False, Liquid.ETHANOL, False, True)] = \ -_50ulTip_conductive_384COREHead_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( - curve={0.25: 0.3, 5.0: 6.1, 0.5: 0.65, 15.0: 16.9, 50.0: 52.7, 30.0: 32.1, 0.0: 0.0, 1.0: 1.35, 10.0: 11.3}, + dispense_stop_back_volume=2.0, +) + + +vantage_mapping[(50, True, True, False, Liquid.ETHANOL, False, True)] = ( + _50ulTip_conductive_384COREHead_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 0.25: 0.3, + 5.0: 6.1, + 0.5: 0.65, + 15.0: 16.9, + 50.0: 52.7, + 30.0: 32.1, + 0.0: 0.0, + 1.0: 1.35, + 10.0: 11.3, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=2.0, @@ -2387,12 +2680,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=6.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.GLYCERIN80, False, True)] = \ -_50ulTip_conductive_384COREHead_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.GLYCERIN80, False, True)] = ( + _50ulTip_conductive_384COREHead_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={0.25: 0.05, 5.0: 5.5, 0.5: 0.3, 50.0: 51.9, 30.0: 31.8, 0.0: 0.0, 1.0: 1.0, 10.0: 10.9}, aspiration_flow_rate=30.0, aspiration_mix_flow_rate=30.0, @@ -2410,12 +2704,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ -_50ulTip_conductive_384COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.WATER, True, True)] = ( + _50ulTip_conductive_384COREHead_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={5.0: 5.67, 0.5: 0.27, 50.0: 51.9, 30.0: 31.5, 0.0: 0.0, 1.0: 1.06, 20.0: 20.0, 10.0: 10.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2433,12 +2728,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ -_50ulTip_conductive_384COREHead_Water_DispenseJet_Empty_below5ul = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.WATER, True, True)] = ( + _50ulTip_conductive_384COREHead_Water_DispenseJet_Empty_below5ul +) = HamiltonLiquidClass( curve={5.0: 5.67, 0.5: 0.27, 50.0: 51.9, 30.0: 31.5, 0.0: 0.0, 1.0: 1.06, 20.0: 20.0, 10.0: 10.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2456,12 +2752,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.WATER, True, False)] = \ -_50ulTip_conductive_384COREHead_Water_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.WATER, True, False)] = ( + _50ulTip_conductive_384COREHead_Water_DispenseJet_Part +) = HamiltonLiquidClass( curve={50.0: 50.0, 0.0: 0.0, 10.0: 10.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, @@ -2479,13 +2776,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=2.0 -) - - -vantage_mapping[(50, True, True, False, Liquid.WATER, False, True)] = \ -_50ulTip_conductive_384COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={0.1: 0.1, 0.25: 0.15, 5.0: 5.6, 0.5: 0.45, 50.0: 51.0, 30.0: 31.0, 0.0: 0.0, 1.0: 0.98, 10.0: 10.7}, + dispense_stop_back_volume=2.0, +) + + +vantage_mapping[(50, True, True, False, Liquid.WATER, False, True)] = ( + _50ulTip_conductive_384COREHead_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 0.1: 0.1, + 0.25: 0.15, + 5.0: 5.6, + 0.5: 0.45, + 50.0: 51.0, + 30.0: 31.0, + 0.0: 0.0, + 1.0: 0.98, + 10.0: 10.7, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -2502,13 +2810,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(50, True, True, False, Liquid.WATER, False, False)] = \ -_50ulTip_conductive_384COREWasher_DispenseSurface = HamiltonLiquidClass( - curve={5.0: 6.3, 0.5: 0.9, 50.0: 55.0, 40.0: 44.0, 0.0: 0.0, 1.0: 1.6, 20.0: 22.2, 65.0: 65.0, 10.0: 11.9, 2.0: 2.8}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(50, True, True, False, Liquid.WATER, False, False)] = ( + _50ulTip_conductive_384COREWasher_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 5.0: 6.3, + 0.5: 0.9, + 50.0: 55.0, + 40.0: 44.0, + 0.0: 0.0, + 1.0: 1.6, + 20.0: 22.2, + 65.0: 65.0, + 10.0: 11.9, + 2.0: 2.8, + }, aspiration_flow_rate=20.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=0.0, @@ -2525,13 +2845,27 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=100.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(5000, False, True, False, Liquid.DMSO, True, False)] = \ -_5mlT_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( - curve={4500.0: 4606.0, 3500.0: 3591.0, 500.0: 525.0, 2500.0: 2576.0, 1500.0: 1559.0, 5000.0: 5114.0, 4000.0: 4099.0, 3000.0: 3083.0, 0.0: 0.0, 2000.0: 2068.0, 100.0: 105.0, 1000.0: 1044.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(5000, False, True, False, Liquid.DMSO, True, False)] = ( + _5mlT_DMSO_DispenseJet_Aliquot +) = HamiltonLiquidClass( + curve={ + 4500.0: 4606.0, + 3500.0: 3591.0, + 500.0: 525.0, + 2500.0: 2576.0, + 1500.0: 1559.0, + 5000.0: 5114.0, + 4000.0: 4099.0, + 3000.0: 3083.0, + 0.0: 0.0, + 2000.0: 2068.0, + 100.0: 105.0, + 1000.0: 1044.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=20.0, @@ -2548,13 +2882,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=20.0 -) - - -vantage_mapping[(5000, False, True, False, Liquid.DMSO, True, True)] = \ -_5mlT_DMSO_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 540.0, 50.0: 62.0, 5000.0: 5095.0, 4000.0: 4075.0, 0.0: 0.0, 3000.0: 3065.0, 100.0: 117.0, 2000.0: 2060.0, 1000.0: 1060.0}, + dispense_stop_back_volume=20.0, +) + + +vantage_mapping[(5000, False, True, False, Liquid.DMSO, True, True)] = ( + _5mlT_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 540.0, + 50.0: 62.0, + 5000.0: 5095.0, + 4000.0: 4075.0, + 0.0: 0.0, + 3000.0: 3065.0, + 100.0: 117.0, + 2000.0: 2060.0, + 1000.0: 1060.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2571,13 +2916,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(5000, False, True, False, Liquid.DMSO, False, True)] = \ -_5mlT_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 535.0, 50.0: 60.3, 5000.0: 5090.0, 4000.0: 4078.0, 0.0: 0.0, 3000.0: 3066.0, 100.0: 115.0, 2000.0: 2057.0, 10.0: 12.5, 1000.0: 1054.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(5000, False, True, False, Liquid.DMSO, False, True)] = ( + _5mlT_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 535.0, + 50.0: 60.3, + 5000.0: 5090.0, + 4000.0: 4078.0, + 0.0: 0.0, + 3000.0: 3066.0, + 100.0: 115.0, + 2000.0: 2057.0, + 10.0: 12.5, + 1000.0: 1054.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2594,14 +2951,29 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=500.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # First two times mixing with max volume. -vantage_mapping[(5000, False, True, False, Liquid.ETHANOL, True, False)] = \ -_5mlT_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( - curve={300.0: 312.0, 4500.0: 4573.0, 3500.0: 3560.0, 500.0: 519.0, 2500.0: 2551.0, 1500.0: 1542.0, 5000.0: 5081.0, 4000.0: 4066.0, 3000.0: 3056.0, 0.0: 0.0, 2000.0: 2047.0, 100.0: 104.0, 1000.0: 1033.0}, +vantage_mapping[(5000, False, True, False, Liquid.ETHANOL, True, False)] = ( + _5mlT_EtOH_DispenseJet_Aliquot +) = HamiltonLiquidClass( + curve={ + 300.0: 312.0, + 4500.0: 4573.0, + 3500.0: 3560.0, + 500.0: 519.0, + 2500.0: 2551.0, + 1500.0: 1542.0, + 5000.0: 5081.0, + 4000.0: 4066.0, + 3000.0: 3056.0, + 0.0: 0.0, + 2000.0: 2047.0, + 100.0: 104.0, + 1000.0: 1033.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=2000.0, aspiration_air_transport_volume=0.0, @@ -2618,13 +2990,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(5000, False, True, False, Liquid.ETHANOL, True, True)] = \ -_5mlT_EtOH_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 563.0, 50.0: 72.0, 5000.0: 5230.0, 4000.0: 4215.0, 0.0: 0.0, 3000.0: 3190.0, 100.0: 129.5, 2000.0: 2166.0, 1000.0: 1095.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(5000, False, True, False, Liquid.ETHANOL, True, True)] = ( + _5mlT_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 563.0, + 50.0: 72.0, + 5000.0: 5230.0, + 4000.0: 4215.0, + 0.0: 0.0, + 3000.0: 3190.0, + 100.0: 129.5, + 2000.0: 2166.0, + 1000.0: 1095.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=30.0, @@ -2641,13 +3024,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=30.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(5000, False, True, False, Liquid.ETHANOL, False, True)] = \ -_5mlT_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 555.0, 50.0: 68.0, 5000.0: 5204.0, 4000.0: 4200.0, 0.0: 0.0, 3000.0: 3180.0, 100.0: 123.5, 2000.0: 2160.0, 10.0: 22.0, 1000.0: 1085.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(5000, False, True, False, Liquid.ETHANOL, False, True)] = ( + _5mlT_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 555.0, + 50.0: 68.0, + 5000.0: 5204.0, + 4000.0: 4200.0, + 0.0: 0.0, + 3000.0: 3180.0, + 100.0: 123.5, + 2000.0: 2160.0, + 10.0: 22.0, + 1000.0: 1085.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=30.0, @@ -2664,13 +3059,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=30.0, dispense_settling_time=1.0, dispense_stop_flow_rate=30.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(5000, False, True, False, Liquid.GLYCERIN80, True, True)] = \ -_5mlT_Glycerin80_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 597.0, 50.0: 89.0, 5000.0: 5240.0, 4000.0: 4220.0, 0.0: 0.0, 3000.0: 3203.0, 100.0: 138.0, 2000.0: 2195.0, 1000.0: 1166.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(5000, False, True, False, Liquid.GLYCERIN80, True, True)] = ( + _5mlT_Glycerin80_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 597.0, + 50.0: 89.0, + 5000.0: 5240.0, + 4000.0: 4220.0, + 0.0: 0.0, + 3000.0: 3203.0, + 100.0: 138.0, + 2000.0: 2195.0, + 1000.0: 1166.0, + }, aspiration_flow_rate=1200.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=30.0, @@ -2687,13 +3093,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(5000, False, True, False, Liquid.GLYCERIN80, False, True)] = \ -_5mlT_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 555.0, 50.0: 71.0, 5000.0: 5135.0, 4000.0: 4115.0, 0.0: 0.0, 3000.0: 3127.0, 100.0: 127.0, 2000.0: 2115.0, 10.0: 15.5, 1000.0: 1075.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(5000, False, True, False, Liquid.GLYCERIN80, False, True)] = ( + _5mlT_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 555.0, + 50.0: 71.0, + 5000.0: 5135.0, + 4000.0: 4115.0, + 0.0: 0.0, + 3000.0: 3127.0, + 100.0: 127.0, + 2000.0: 2115.0, + 10.0: 15.5, + 1000.0: 1075.0, + }, aspiration_flow_rate=1000.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=0.0, @@ -2710,13 +3128,22 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(5000, False, True, False, Liquid.WATER, True, False)] = \ -_5mlT_Water_DispenseJet_Aliquot = HamiltonLiquidClass( - curve={5000.0: 5030.0, 4000.0: 4040.0, 0.0: 0.0, 3000.0: 3050.0, 100.0: 104.0, 2000.0: 2050.0, 1000.0: 1040.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(5000, False, True, False, Liquid.WATER, True, False)] = ( + _5mlT_Water_DispenseJet_Aliquot +) = HamiltonLiquidClass( + curve={ + 5000.0: 5030.0, + 4000.0: 4040.0, + 0.0: 0.0, + 3000.0: 3050.0, + 100.0: 104.0, + 2000.0: 2050.0, + 1000.0: 1040.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2733,13 +3160,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=20.0 -) - - -vantage_mapping[(5000, False, True, False, Liquid.WATER, True, True)] = \ -_5mlT_Water_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 551.8, 50.0: 66.4, 5000.0: 5180.0, 4000.0: 4165.0, 0.0: 0.0, 3000.0: 3148.0, 100.0: 122.7, 2000.0: 2128.0, 1000.0: 1082.0}, + dispense_stop_back_volume=20.0, +) + + +vantage_mapping[(5000, False, True, False, Liquid.WATER, True, True)] = ( + _5mlT_Water_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 551.8, + 50.0: 66.4, + 5000.0: 5180.0, + 4000.0: 4165.0, + 0.0: 0.0, + 3000.0: 3148.0, + 100.0: 122.7, + 2000.0: 2128.0, + 1000.0: 1082.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2756,13 +3194,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(5000, False, True, False, Liquid.WATER, False, True)] = \ -_5mlT_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 547.0, 50.0: 65.5, 5000.0: 5145.0, 4000.0: 4145.0, 0.0: 0.0, 3000.0: 3130.0, 100.0: 120.9, 2000.0: 2125.0, 10.0: 15.1, 1000.0: 1075.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(5000, False, True, False, Liquid.WATER, False, True)] = ( + _5mlT_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 547.0, + 50.0: 65.5, + 5000.0: 5145.0, + 4000.0: 4145.0, + 0.0: 0.0, + 3000.0: 3130.0, + 100.0: 120.9, + 2000.0: 2125.0, + 10.0: 15.1, + 1000.0: 1075.0, + }, aspiration_flow_rate=2000.0, aspiration_mix_flow_rate=500.0, aspiration_air_transport_volume=20.0, @@ -2779,14 +3229,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=500.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 250 -vantage_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = \ -HighNeedle_Water_DispenseJet = HamiltonLiquidClass( - curve={500.0: 527.3, 50.0: 56.8, 0.0: 0.0, 100.0: 110.4, 20.0: 24.7, 1000.0: 1046.5, 200.0: 214.6, 10.0: 13.2}, +vantage_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = ( + HighNeedle_Water_DispenseJet +) = HamiltonLiquidClass( + curve={ + 500.0: 527.3, + 50.0: 56.8, + 0.0: 0.0, + 100.0: 110.4, + 20.0: 24.7, + 1000.0: 1046.5, + 200.0: 214.6, + 10.0: 13.2, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -2803,13 +3263,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=350.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, False, False, Liquid.WATER, True, True)] = \ -HighNeedle_Water_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 527.3, 50.0: 56.8, 0.0: 0.0, 100.0: 110.4, 20.0: 24.7, 1000.0: 1046.5, 200.0: 214.6, 10.0: 13.2}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, False, False, Liquid.WATER, True, True)] = ( + HighNeedle_Water_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 527.3, + 50.0: 56.8, + 0.0: 0.0, + 100.0: 110.4, + 20.0: 24.7, + 1000.0: 1046.5, + 200.0: 214.6, + 10.0: 13.2, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -2826,13 +3296,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=350.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = \ -HighNeedle_Water_DispenseJet_Part = HamiltonLiquidClass( - curve={500.0: 527.3, 50.0: 56.8, 0.0: 0.0, 100.0: 110.4, 20.0: 24.7, 1000.0: 1046.5, 200.0: 214.6, 10.0: 13.2}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, False, False, Liquid.WATER, True, False)] = ( + HighNeedle_Water_DispenseJet_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 527.3, + 50.0: 56.8, + 0.0: 0.0, + 100.0: 110.4, + 20.0: 24.7, + 1000.0: 1046.5, + 200.0: 214.6, + 10.0: 13.2, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -2849,13 +3329,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=350.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 120 -vantage_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = \ -HighNeedle_Water_DispenseSurface = HamiltonLiquidClass( +vantage_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = ( + HighNeedle_Water_DispenseSurface +) = HamiltonLiquidClass( curve={50.0: 53.1, 0.0: 0.0, 20.0: 22.3, 1000.0: 1000.0, 10.0: 10.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, @@ -2873,12 +3354,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(1000, False, False, False, Liquid.WATER, False, True)] = \ -HighNeedle_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(1000, False, False, False, Liquid.WATER, False, True)] = ( + HighNeedle_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={50.0: 53.1, 0.0: 0.0, 20.0: 22.3, 1000.0: 1000.0, 10.0: 10.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, @@ -2896,12 +3378,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = \ -HighNeedle_Water_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(1000, False, False, False, Liquid.WATER, False, False)] = ( + HighNeedle_Water_DispenseSurface_Part +) = HamiltonLiquidClass( curve={50.0: 53.1, 0.0: 0.0, 20.0: 22.3, 1000.0: 1000.0, 10.0: 10.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, @@ -2919,13 +3402,22 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, True)] = \ -HighVolumeAcetonitrilDispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 526.5, 250.0: 269.0, 50.0: 60.5, 0.0: 0.0, 100.0: 112.7, 20.0: 25.5, 1000.0: 1045.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, True)] = ( + HighVolumeAcetonitrilDispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 526.5, + 250.0: 269.0, + 50.0: 60.5, + 0.0: 0.0, + 100.0: 112.7, + 20.0: 25.5, + 1000.0: 1045.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -2942,13 +3434,22 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, False)] = \ -HighVolumeAcetonitrilDispenseJet_Part = HamiltonLiquidClass( - curve={500.0: 526.5, 250.0: 269.0, 50.0: 60.5, 0.0: 0.0, 100.0: 112.7, 20.0: 25.5, 1000.0: 1045.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, False)] = ( + HighVolumeAcetonitrilDispenseJet_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 526.5, + 250.0: 269.0, + 50.0: 60.5, + 0.0: 0.0, + 100.0: 112.7, + 20.0: 25.5, + 1000.0: 1045.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=10.0, @@ -2965,13 +3466,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0 -) - - -vantage_mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, True)] = \ -HighVolumeAcetonitrilDispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 525.4, 250.0: 267.0, 50.0: 57.6, 0.0: 0.0, 100.0: 111.2, 20.0: 23.8, 1000.0: 1048.8, 10.0: 12.1}, + dispense_stop_back_volume=10.0, +) + + +vantage_mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, True)] = ( + HighVolumeAcetonitrilDispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 525.4, + 250.0: 267.0, + 50.0: 57.6, + 0.0: 0.0, + 100.0: 111.2, + 20.0: 23.8, + 1000.0: 1048.8, + 10.0: 12.1, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=10.0, @@ -2988,13 +3499,22 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, False)] = \ -HighVolumeAcetonitrilDispenseSurface_Part = HamiltonLiquidClass( - curve={500.0: 525.4, 250.0: 267.0, 50.0: 57.6, 0.0: 0.0, 100.0: 111.2, 20.0: 23.8, 1000.0: 1048.8}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, False)] = ( + HighVolumeAcetonitrilDispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 525.4, + 250.0: 267.0, + 50.0: 57.6, + 0.0: 0.0, + 100.0: 111.2, + 20.0: 23.8, + 1000.0: 1048.8, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=10.0, @@ -3011,16 +3531,26 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # - Submerge depth: Aspiration 2.0mm # (bei Schaumbildung durch mischen/vorbenetzen evtl.5mm, LLD-Erkennung) # - Mischen 3-5 x 950µl, mix position 0.5mm, je nach Volumen im Tube -vantage_mapping[(1000, False, True, False, Liquid.BLOOD, True, False)] = \ -HighVolumeBloodDispenseJet = HamiltonLiquidClass( - curve={500.0: 536.3, 250.0: 275.6, 50.0: 59.8, 0.0: 0.0, 20.0: 26.2, 100.0: 115.3, 10.0: 12.2, 1000.0: 1061.6}, +vantage_mapping[(1000, False, True, False, Liquid.BLOOD, True, False)] = ( + HighVolumeBloodDispenseJet +) = HamiltonLiquidClass( + curve={ + 500.0: 536.3, + 250.0: 275.6, + 50.0: 59.8, + 0.0: 0.0, + 20.0: 26.2, + 100.0: 115.3, + 10.0: 12.2, + 1000.0: 1061.6, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3037,12 +3567,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=300.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(1000, True, True, True, Liquid.DMSO, True, True)] = \ -HighVolumeFilter_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(1000, True, True, True, Liquid.DMSO, True, True)] = ( + HighVolumeFilter_96COREHead1000ul_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={500.0: 508.2, 0.0: 0.0, 20.0: 21.7, 100.0: 101.7, 1000.0: 1017.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -3060,12 +3591,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(1000, True, True, True, Liquid.DMSO, False, True)] = \ -HighVolumeFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(1000, True, True, True, Liquid.DMSO, False, True)] = ( + HighVolumeFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={500.0: 512.5, 0.0: 0.0, 100.0: 105.8, 10.0: 12.7, 1000.0: 1024.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, @@ -3083,12 +3615,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(1000, True, True, True, Liquid.WATER, True, True)] = \ -HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(1000, True, True, True, Liquid.WATER, True, True)] = ( + HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={500.0: 524.0, 0.0: 0.0, 20.0: 24.0, 100.0: 109.2, 1000.0: 1040.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -3106,12 +3639,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(1000, True, True, True, Liquid.WATER, False, True)] = \ -HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(1000, True, True, True, Liquid.WATER, False, True)] = ( + HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={500.0: 522.0, 0.0: 0.0, 100.0: 108.3, 1000.0: 1034.0, 10.0: 12.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, @@ -3129,7 +3663,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -3150,9 +3684,20 @@ def get_vantage_liquid_class(**kwargs): # 100 ( 9 Aliquots) 0.25 -4.81 # # -vantage_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = \ -HighVolumeFilter_DMSO_AliquotDispenseJet_Part = HamiltonLiquidClass( - curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, +vantage_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = ( + HighVolumeFilter_DMSO_AliquotDispenseJet_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 500.0, + 250.0: 250.0, + 30.0: 30.0, + 0.0: 0.0, + 100.0: 100.0, + 20.0: 20.0, + 1000.0: 1000.0, + 750.0: 750.0, + 10.0: 10.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -3169,14 +3714,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 250 -vantage_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = \ -HighVolumeFilter_DMSO_DispenseJet = HamiltonLiquidClass( - curve={5.0: 5.1, 500.0: 511.2, 250.0: 256.2, 50.0: 52.2, 0.0: 0.0, 20.0: 21.3, 100.0: 103.4, 10.0: 10.7, 1000.0: 1021.0}, +vantage_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = ( + HighVolumeFilter_DMSO_DispenseJet +) = HamiltonLiquidClass( + curve={ + 5.0: 5.1, + 500.0: 511.2, + 250.0: 256.2, + 50.0: 52.2, + 0.0: 0.0, + 20.0: 21.3, + 100.0: 103.4, + 10.0: 10.7, + 1000.0: 1021.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3193,13 +3749,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, True, Liquid.DMSO, True, True)] = \ -HighVolumeFilter_DMSO_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 511.2, 5.0: 5.1, 250.0: 256.2, 50.0: 52.2, 0.0: 0.0, 100.0: 103.4, 20.0: 21.3, 1000.0: 1021.0, 10.0: 10.7}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, True, Liquid.DMSO, True, True)] = ( + HighVolumeFilter_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 511.2, + 5.0: 5.1, + 250.0: 256.2, + 50.0: 52.2, + 0.0: 0.0, + 100.0: 103.4, + 20.0: 21.3, + 1000.0: 1021.0, + 10.0: 10.7, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3216,12 +3783,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = \ -HighVolumeFilter_DMSO_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = ( + HighVolumeFilter_DMSO_DispenseJet_Part +) = HamiltonLiquidClass( curve={500.0: 517.2, 0.0: 0.0, 100.0: 109.5, 20.0: 27.0, 1000.0: 1027.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -3239,14 +3807,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 120 -vantage_mapping[(1000, False, True, True, Liquid.DMSO, False, False)] = \ -HighVolumeFilter_DMSO_DispenseSurface = HamiltonLiquidClass( - curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 20.0: 22.8, 100.0: 105.8, 10.0: 12.1, 1000.0: 1024.5}, +vantage_mapping[(1000, False, True, True, Liquid.DMSO, False, False)] = ( + HighVolumeFilter_DMSO_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 500.0: 514.3, + 250.0: 259.0, + 50.0: 54.4, + 0.0: 0.0, + 20.0: 22.8, + 100.0: 105.8, + 10.0: 12.1, + 1000.0: 1024.5, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -3263,13 +3841,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, True, Liquid.DMSO, False, True)] = \ -HighVolumeFilter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 100.0: 105.8, 20.0: 22.8, 1000.0: 1024.5, 10.0: 12.1}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, True, Liquid.DMSO, False, True)] = ( + HighVolumeFilter_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 514.3, + 250.0: 259.0, + 50.0: 54.4, + 0.0: 0.0, + 100.0: 105.8, + 20.0: 22.8, + 1000.0: 1024.5, + 10.0: 12.1, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -3286,14 +3874,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # -vantage_mapping[(1000, False, True, True, Liquid.DMSO, False, False)] = \ -HighVolumeFilter_DMSO_DispenseSurface_Part = HamiltonLiquidClass( - curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 100.0: 105.8, 20.0: 22.8, 1000.0: 1024.5, 10.0: 12.1}, +vantage_mapping[(1000, False, True, True, Liquid.DMSO, False, False)] = ( + HighVolumeFilter_DMSO_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 514.3, + 250.0: 259.0, + 50.0: 54.4, + 0.0: 0.0, + 100.0: 105.8, + 20.0: 22.8, + 1000.0: 1024.5, + 10.0: 12.1, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -3310,14 +3908,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 250, Stop back volume = 0 -vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, True, False)] = \ -HighVolumeFilter_EtOH_DispenseJet = HamiltonLiquidClass( - curve={500.0: 534.8, 250.0: 273.0, 50.0: 62.9, 0.0: 0.0, 20.0: 27.8, 100.0: 116.3, 10.0: 15.8, 1000.0: 1053.9}, +vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, True, False)] = ( + HighVolumeFilter_EtOH_DispenseJet +) = HamiltonLiquidClass( + curve={ + 500.0: 534.8, + 250.0: 273.0, + 50.0: 62.9, + 0.0: 0.0, + 20.0: 27.8, + 100.0: 116.3, + 10.0: 15.8, + 1000.0: 1053.9, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3334,13 +3942,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, True, True)] = \ -HighVolumeFilter_EtOH_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 534.8, 250.0: 273.0, 50.0: 62.9, 0.0: 0.0, 100.0: 116.3, 20.0: 27.8, 1000.0: 1053.9, 10.0: 15.8}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, True, True)] = ( + HighVolumeFilter_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 534.8, + 250.0: 273.0, + 50.0: 62.9, + 0.0: 0.0, + 100.0: 116.3, + 20.0: 27.8, + 1000.0: 1053.9, + 10.0: 15.8, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3357,13 +3975,22 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, True, False)] = \ -HighVolumeFilter_EtOH_DispenseJet_Part = HamiltonLiquidClass( - curve={500.0: 534.8, 250.0: 273.0, 50.0: 62.9, 0.0: 0.0, 100.0: 116.3, 20.0: 27.8, 1000.0: 1053.9}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, True, False)] = ( + HighVolumeFilter_EtOH_DispenseJet_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 534.8, + 250.0: 273.0, + 50.0: 62.9, + 0.0: 0.0, + 100.0: 116.3, + 20.0: 27.8, + 1000.0: 1053.9, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3380,14 +4007,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=5.0 + dispense_stop_back_volume=5.0, ) # V1.1: Set mix flow rate to 120 -vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, False, False)] = \ -HighVolumeFilter_EtOH_DispenseSurface = HamiltonLiquidClass( - curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 20.0: 27.6, 100.0: 114.0, 10.0: 15.7, 1000.0: 1044.3}, +vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, False, False)] = ( + HighVolumeFilter_EtOH_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 500.0: 528.4, + 250.0: 269.2, + 50.0: 61.2, + 0.0: 0.0, + 20.0: 27.6, + 100.0: 114.0, + 10.0: 15.7, + 1000.0: 1044.3, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -3404,13 +4041,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, False, True)] = \ -HighVolumeFilter_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 100.0: 114.0, 20.0: 27.6, 1000.0: 1044.3, 10.0: 15.7}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, False, True)] = ( + HighVolumeFilter_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 528.4, + 250.0: 269.2, + 50.0: 61.2, + 0.0: 0.0, + 100.0: 114.0, + 20.0: 27.6, + 1000.0: 1044.3, + 10.0: 15.7, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -3427,13 +4074,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, False, False)] = \ -HighVolumeFilter_EtOH_DispenseSurface_Part = HamiltonLiquidClass( - curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 100.0: 114.0, 20.0: 27.6, 1000.0: 1044.3, 10.0: 15.7}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, True, Liquid.ETHANOL, False, False)] = ( + HighVolumeFilter_EtOH_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 528.4, + 250.0: 269.2, + 50.0: 61.2, + 0.0: 0.0, + 100.0: 114.0, + 20.0: 27.6, + 1000.0: 1044.3, + 10.0: 15.7, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -3450,14 +4107,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 200 -vantage_mapping[(1000, False, True, True, Liquid.GLYCERIN80, True, False)] = \ -HighVolumeFilter_Glycerin80_DispenseJet = HamiltonLiquidClass( - curve={500.0: 537.8, 250.0: 277.0, 50.0: 63.3, 0.0: 0.0, 20.0: 28.0, 100.0: 118.8, 10.0: 15.2, 1000.0: 1060.0}, +vantage_mapping[(1000, False, True, True, Liquid.GLYCERIN80, True, False)] = ( + HighVolumeFilter_Glycerin80_DispenseJet +) = HamiltonLiquidClass( + curve={ + 500.0: 537.8, + 250.0: 277.0, + 50.0: 63.3, + 0.0: 0.0, + 20.0: 28.0, + 100.0: 118.8, + 10.0: 15.2, + 1000.0: 1060.0, + }, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=5.0, @@ -3474,14 +4141,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 200 -vantage_mapping[(1000, False, True, True, Liquid.GLYCERIN80, True, True)] = \ -HighVolumeFilter_Glycerin80_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 537.8, 250.0: 277.0, 50.0: 63.3, 0.0: 0.0, 100.0: 118.8, 20.0: 28.0, 1000.0: 1060.0, 10.0: 15.2}, +vantage_mapping[(1000, False, True, True, Liquid.GLYCERIN80, True, True)] = ( + HighVolumeFilter_Glycerin80_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 537.8, + 250.0: 277.0, + 50.0: 63.3, + 0.0: 0.0, + 100.0: 118.8, + 20.0: 28.0, + 1000.0: 1060.0, + 10.0: 15.2, + }, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=5.0, @@ -3498,14 +4175,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 120 -vantage_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, False)] = \ -HighVolumeFilter_Glycerin80_DispenseSurface = HamiltonLiquidClass( - curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 20.0: 22.7, 100.0: 105.5, 10.0: 12.2, 1000.0: 1027.2}, +vantage_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, False)] = ( + HighVolumeFilter_Glycerin80_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 500.0: 513.5, + 250.0: 257.2, + 50.0: 55.0, + 0.0: 0.0, + 20.0: 22.7, + 100.0: 105.5, + 10.0: 12.2, + 1000.0: 1027.2, + }, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -3522,13 +4209,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, True)] = \ -HighVolumeFilter_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 100.0: 105.5, 20.0: 22.7, 1000.0: 1027.2, 10.0: 12.2}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, True)] = ( + HighVolumeFilter_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 513.5, + 250.0: 257.2, + 50.0: 55.0, + 0.0: 0.0, + 100.0: 105.5, + 20.0: 22.7, + 1000.0: 1027.2, + 10.0: 12.2, + }, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -3545,13 +4242,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, False)] = \ -HighVolumeFilter_Glycerin80_DispenseSurface_Part = HamiltonLiquidClass( - curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 100.0: 105.5, 20.0: 22.7, 1000.0: 1027.2, 10.0: 12.2}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, False)] = ( + HighVolumeFilter_Glycerin80_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 513.5, + 250.0: 257.2, + 50.0: 55.0, + 0.0: 0.0, + 100.0: 105.5, + 20.0: 22.7, + 1000.0: 1027.2, + 10.0: 12.2, + }, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -3568,14 +4275,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 250 -vantage_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = \ -HighVolumeFilter_Serum_AliquotDispenseJet_Part = HamiltonLiquidClass( - curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, +vantage_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = ( + HighVolumeFilter_Serum_AliquotDispenseJet_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 500.0, + 250.0: 250.0, + 30.0: 30.0, + 0.0: 0.0, + 100.0: 100.0, + 20.0: 20.0, + 1000.0: 1000.0, + 750.0: 750.0, + 10.0: 10.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -3592,14 +4310,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=300.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 250 -vantage_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = \ -HighVolumeFilter_Serum_AliquotJet = HamiltonLiquidClass( - curve={500.0: 500.0, 250.0: 250.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 100.0: 100.0, 10.0: 10.0, 750.0: 750.0, 1000.0: 1000.0}, +vantage_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = ( + HighVolumeFilter_Serum_AliquotJet +) = HamiltonLiquidClass( + curve={ + 500.0: 500.0, + 250.0: 250.0, + 0.0: 0.0, + 30.0: 30.0, + 20.0: 20.0, + 100.0: 100.0, + 10.0: 10.0, + 750.0: 750.0, + 1000.0: 1000.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -3616,14 +4345,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=300.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 250, Settling time = 0 -vantage_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = \ -HighVolumeFilter_Serum_DispenseJet = HamiltonLiquidClass( - curve={500.0: 525.3, 250.0: 266.6, 50.0: 57.9, 0.0: 0.0, 20.0: 24.2, 100.0: 111.3, 10.0: 12.2, 1000.0: 1038.6}, +vantage_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = ( + HighVolumeFilter_Serum_DispenseJet +) = HamiltonLiquidClass( + curve={ + 500.0: 525.3, + 250.0: 266.6, + 50.0: 57.9, + 0.0: 0.0, + 20.0: 24.2, + 100.0: 111.3, + 10.0: 12.2, + 1000.0: 1038.6, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3640,13 +4379,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, True, Liquid.SERUM, True, True)] = \ -HighVolumeFilter_Serum_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 525.3, 250.0: 266.6, 50.0: 57.9, 0.0: 0.0, 100.0: 111.3, 20.0: 24.2, 1000.0: 1038.6, 10.0: 12.2}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, True, Liquid.SERUM, True, True)] = ( + HighVolumeFilter_Serum_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 525.3, + 250.0: 266.6, + 50.0: 57.9, + 0.0: 0.0, + 100.0: 111.3, + 20.0: 24.2, + 1000.0: 1038.6, + 10.0: 12.2, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3663,12 +4412,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = \ -HighVolumeFilter_Serum_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = ( + HighVolumeFilter_Serum_DispenseJet_Part +) = HamiltonLiquidClass( curve={500.0: 525.3, 0.0: 0.0, 100.0: 111.3, 20.0: 27.3, 1000.0: 1046.6}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -3686,14 +4436,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 120 -vantage_mapping[(1000, False, True, True, Liquid.SERUM, False, False)] = \ -HighVolumeFilter_Serum_DispenseSurface = HamiltonLiquidClass( - curve={500.0: 517.5, 250.0: 261.9, 50.0: 55.9, 0.0: 0.0, 20.0: 23.2, 100.0: 108.2, 10.0: 11.8, 1000.0: 1026.7}, +vantage_mapping[(1000, False, True, True, Liquid.SERUM, False, False)] = ( + HighVolumeFilter_Serum_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 500.0: 517.5, + 250.0: 261.9, + 50.0: 55.9, + 0.0: 0.0, + 20.0: 23.2, + 100.0: 108.2, + 10.0: 11.8, + 1000.0: 1026.7, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -3710,13 +4470,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, True, Liquid.SERUM, False, True)] = \ -HighVolumeFilter_Serum_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 517.5, 250.0: 261.9, 50.0: 55.9, 0.0: 0.0, 100.0: 108.2, 20.0: 23.2, 1000.0: 1026.7, 10.0: 11.8}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, True, Liquid.SERUM, False, True)] = ( + HighVolumeFilter_Serum_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 517.5, + 250.0: 261.9, + 50.0: 55.9, + 0.0: 0.0, + 100.0: 108.2, + 20.0: 23.2, + 1000.0: 1026.7, + 10.0: 11.8, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -3733,12 +4503,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(1000, False, True, True, Liquid.SERUM, False, False)] = \ -HighVolumeFilter_Serum_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(1000, False, True, True, Liquid.SERUM, False, False)] = ( + HighVolumeFilter_Serum_DispenseSurface_Part +) = HamiltonLiquidClass( curve={500.0: 523.5, 0.0: 0.0, 100.0: 111.2, 20.0: 23.2, 1000.0: 1038.7, 10.0: 11.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, @@ -3756,14 +4527,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 250 -vantage_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = \ -HighVolumeFilter_Water_AliquotDispenseJet_Part = HamiltonLiquidClass( - curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, +vantage_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = ( + HighVolumeFilter_Water_AliquotDispenseJet_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 500.0, + 250.0: 250.0, + 30.0: 30.0, + 0.0: 0.0, + 100.0: 100.0, + 20.0: 20.0, + 1000.0: 1000.0, + 750.0: 750.0, + 10.0: 10.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -3780,14 +4562,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 250 -vantage_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = \ -HighVolumeFilter_Water_AliquotJet = HamiltonLiquidClass( - curve={500.0: 500.0, 250.0: 250.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 100.0: 100.0, 10.0: 10.0, 750.0: 750.0, 1000.0: 1000.0}, +vantage_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = ( + HighVolumeFilter_Water_AliquotJet +) = HamiltonLiquidClass( + curve={ + 500.0: 500.0, + 250.0: 250.0, + 0.0: 0.0, + 30.0: 30.0, + 20.0: 20.0, + 100.0: 100.0, + 10.0: 10.0, + 750.0: 750.0, + 1000.0: 1000.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -3804,14 +4597,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 250 -vantage_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = \ -HighVolumeFilter_Water_DispenseJet = HamiltonLiquidClass( - curve={500.0: 521.7, 50.0: 57.2, 0.0: 0.0, 20.0: 24.6, 100.0: 109.6, 10.0: 13.3, 200.0: 212.9, 1000.0: 1034.0}, +vantage_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = ( + HighVolumeFilter_Water_DispenseJet +) = HamiltonLiquidClass( + curve={ + 500.0: 521.7, + 50.0: 57.2, + 0.0: 0.0, + 20.0: 24.6, + 100.0: 109.6, + 10.0: 13.3, + 200.0: 212.9, + 1000.0: 1034.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3828,13 +4631,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, True, Liquid.WATER, True, True)] = \ -HighVolumeFilter_Water_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 521.7, 50.0: 57.2, 0.0: 0.0, 100.0: 109.6, 20.0: 24.6, 1000.0: 1034.0, 200.0: 212.9, 10.0: 13.3}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, True, Liquid.WATER, True, True)] = ( + HighVolumeFilter_Water_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 521.7, + 50.0: 57.2, + 0.0: 0.0, + 100.0: 109.6, + 20.0: 24.6, + 1000.0: 1034.0, + 200.0: 212.9, + 10.0: 13.3, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3851,13 +4664,22 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = \ -HighVolumeFilter_Water_DispenseJet_Part = HamiltonLiquidClass( - curve={500.0: 521.7, 50.0: 57.2, 0.0: 0.0, 100.0: 109.6, 20.0: 27.0, 1000.0: 1034.0, 200.0: 212.9}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, True, Liquid.WATER, True, False)] = ( + HighVolumeFilter_Water_DispenseJet_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 521.7, + 50.0: 57.2, + 0.0: 0.0, + 100.0: 109.6, + 20.0: 27.0, + 1000.0: 1034.0, + 200.0: 212.9, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -3874,14 +4696,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 120, Clot retract hight = 0 -vantage_mapping[(1000, False, True, True, Liquid.WATER, False, False)] = \ -HighVolumeFilter_Water_DispenseSurface = HamiltonLiquidClass( - curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 20.0: 23.9, 100.0: 108.3, 10.0: 12.5, 200.0: 211.0, 1000.0: 1028.5}, +vantage_mapping[(1000, False, True, True, Liquid.WATER, False, False)] = ( + HighVolumeFilter_Water_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 500.0: 518.3, + 50.0: 56.3, + 0.0: 0.0, + 20.0: 23.9, + 100.0: 108.3, + 10.0: 12.5, + 200.0: 211.0, + 1000.0: 1028.5, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -3898,13 +4730,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, True, Liquid.WATER, False, True)] = \ -HighVolumeFilter_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 20.0: 23.9, 100.0: 108.3, 10.0: 12.5, 200.0: 211.0, 1000.0: 1028.5}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, True, Liquid.WATER, False, True)] = ( + HighVolumeFilter_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 518.3, + 50.0: 56.3, + 0.0: 0.0, + 20.0: 23.9, + 100.0: 108.3, + 10.0: 12.5, + 200.0: 211.0, + 1000.0: 1028.5, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -3921,13 +4763,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, True, Liquid.WATER, False, False)] = \ -HighVolumeFilter_Water_DispenseSurface_Part = HamiltonLiquidClass( - curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 100.0: 108.3, 20.0: 23.9, 1000.0: 1028.5, 200.0: 211.0, 10.0: 12.7}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, True, Liquid.WATER, False, False)] = ( + HighVolumeFilter_Water_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 518.3, + 50.0: 56.3, + 0.0: 0.0, + 100.0: 108.3, + 20.0: 23.9, + 1000.0: 1028.5, + 200.0: 211.0, + 10.0: 12.7, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -3944,12 +4796,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(1000, True, True, False, Liquid.DMSO, True, False)] = \ -HighVolume_96COREHead1000ul_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(1000, True, True, False, Liquid.DMSO, True, False)] = ( + HighVolume_96COREHead1000ul_DMSO_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={500.0: 524.0, 0.0: 0.0, 100.0: 107.2, 20.0: 24.0, 1000.0: 1025.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -3967,12 +4820,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=20.0 + dispense_stop_back_volume=20.0, ) -vantage_mapping[(1000, True, True, False, Liquid.DMSO, True, True)] = \ -HighVolume_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(1000, True, True, False, Liquid.DMSO, True, True)] = ( + HighVolume_96COREHead1000ul_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={500.0: 508.2, 0.0: 0.0, 100.0: 101.7, 20.0: 21.7, 1000.0: 1017.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -3990,12 +4844,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(1000, True, True, False, Liquid.DMSO, False, True)] = \ -HighVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(1000, True, True, False, Liquid.DMSO, False, True)] = ( + HighVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={500.0: 512.5, 0.0: 0.0, 100.0: 105.8, 1000.0: 1024.5, 10.0: 12.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, @@ -4013,13 +4868,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # to prevent drop's, mix 2x with e.g. 500ul -vantage_mapping[(1000, True, True, False, Liquid.ETHANOL, True, False)] = \ -HighVolume_96COREHead1000ul_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(1000, True, True, False, Liquid.ETHANOL, True, False)] = ( + HighVolume_96COREHead1000ul_EtOH_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 500.0: 500.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -4037,12 +4893,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=400.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -vantage_mapping[(1000, True, True, False, Liquid.ETHANOL, True, True)] = \ -HighVolume_96COREHead1000ul_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(1000, True, True, False, Liquid.ETHANOL, True, True)] = ( + HighVolume_96COREHead1000ul_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={500.0: 516.5, 0.0: 0.0, 100.0: 108.3, 20.0: 24.0, 1000.0: 1027.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -4060,13 +4917,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # to prevent drop's, mix 2x with e.g. 500ul -vantage_mapping[(1000, True, True, False, Liquid.ETHANOL, False, True)] = \ -HighVolume_96COREHead1000ul_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(1000, True, True, False, Liquid.ETHANOL, False, True)] = ( + HighVolume_96COREHead1000ul_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={500.0: 516.5, 0.0: 0.0, 100.0: 107.0, 1000.0: 1027.0, 10.0: 14.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=150.0, @@ -4084,12 +4942,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(1000, True, True, False, Liquid.GLYCERIN80, False, True)] = \ -HighVolume_96COREHead1000ul_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(1000, True, True, False, Liquid.GLYCERIN80, False, True)] = ( + HighVolume_96COREHead1000ul_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={500.0: 522.0, 0.0: 0.0, 100.0: 115.3, 1000.0: 1034.0, 10.0: 12.5}, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, @@ -4107,12 +4966,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(1000, True, True, False, Liquid.WATER, True, False)] = \ -HighVolume_96COREHead1000ul_Water_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(1000, True, True, False, Liquid.WATER, True, False)] = ( + HighVolume_96COREHead1000ul_Water_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={500.0: 524.0, 0.0: 0.0, 100.0: 107.2, 20.0: 24.0, 1000.0: 1025.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -4130,12 +4990,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -vantage_mapping[(1000, True, True, False, Liquid.WATER, True, True)] = \ -HighVolume_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(1000, True, True, False, Liquid.WATER, True, True)] = ( + HighVolume_96COREHead1000ul_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={500.0: 524.0, 0.0: 0.0, 100.0: 107.2, 20.0: 24.0, 1000.0: 1025.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -4153,12 +5014,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(1000, True, True, False, Liquid.WATER, False, True)] = \ -HighVolume_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(1000, True, True, False, Liquid.WATER, False, True)] = ( + HighVolume_96COREHead1000ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={500.0: 522.0, 0.0: 0.0, 100.0: 108.3, 1000.0: 1034.0, 10.0: 12.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, @@ -4176,14 +5038,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # Liquid class for wash high volume tips with CO-RE 96 Head in CO-RE 96 Head Washer. -vantage_mapping[(1000, True, True, False, Liquid.WATER, False, False)] = \ -HighVolume_Core96Washer_DispenseSurface = HamiltonLiquidClass( - curve={500.0: 520.0, 50.0: 56.3, 0.0: 0.0, 100.0: 110.0, 20.0: 23.9, 1000.0: 1050.0, 200.0: 212.0, 10.0: 12.5}, +vantage_mapping[(1000, True, True, False, Liquid.WATER, False, False)] = ( + HighVolume_Core96Washer_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 500.0: 520.0, + 50.0: 56.3, + 0.0: 0.0, + 100.0: 110.0, + 20.0: 23.9, + 1000.0: 1050.0, + 200.0: 212.0, + 10.0: 12.5, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=220.0, aspiration_air_transport_volume=0.0, @@ -4200,7 +5072,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -4221,9 +5093,20 @@ def get_vantage_liquid_class(**kwargs): # 100 ( 9 Aliquots) 0.25 -4.81 # # -vantage_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = \ -HighVolume_DMSO_AliquotDispenseJet_Part = HamiltonLiquidClass( - curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, +vantage_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = ( + HighVolume_DMSO_AliquotDispenseJet_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 500.0, + 250.0: 250.0, + 30.0: 30.0, + 0.0: 0.0, + 100.0: 100.0, + 20.0: 20.0, + 1000.0: 1000.0, + 750.0: 750.0, + 10.0: 10.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -4240,13 +5123,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 -) - - -vantage_mapping[(1000, False, True, False, Liquid.DMSO, True, True)] = \ -HighVolume_DMSO_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 511.2, 5.0: 5.1, 250.0: 256.2, 50.0: 52.2, 0.0: 0.0, 100.0: 103.4, 20.0: 21.3, 1000.0: 1021.0, 10.0: 10.7}, + dispense_stop_back_volume=10.0, +) + + +vantage_mapping[(1000, False, True, False, Liquid.DMSO, True, True)] = ( + HighVolume_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 511.2, + 5.0: 5.1, + 250.0: 256.2, + 50.0: 52.2, + 0.0: 0.0, + 100.0: 103.4, + 20.0: 21.3, + 1000.0: 1021.0, + 10.0: 10.7, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4263,12 +5157,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = \ -HighVolume_DMSO_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = ( + HighVolume_DMSO_DispenseJet_Part +) = HamiltonLiquidClass( curve={500.0: 520.2, 0.0: 0.0, 100.0: 112.0, 20.0: 27.0, 1000.0: 1031.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -4286,13 +5181,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=5.0 -) - - -vantage_mapping[(1000, False, True, False, Liquid.DMSO, False, True)] = \ -HighVolume_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 100.0: 105.8, 20.0: 22.8, 1000.0: 1024.5, 10.0: 12.1}, + dispense_stop_back_volume=5.0, +) + + +vantage_mapping[(1000, False, True, False, Liquid.DMSO, False, True)] = ( + HighVolume_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 514.3, + 250.0: 259.0, + 50.0: 54.4, + 0.0: 0.0, + 100.0: 105.8, + 20.0: 22.8, + 1000.0: 1024.5, + 10.0: 12.1, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4309,13 +5214,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, False, Liquid.DMSO, False, False)] = \ -HighVolume_DMSO_DispenseSurface_Part = HamiltonLiquidClass( - curve={500.0: 514.3, 250.0: 259.0, 50.0: 54.4, 0.0: 0.0, 100.0: 105.8, 20.0: 22.8, 1000.0: 1024.5, 10.0: 12.4}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, False, Liquid.DMSO, False, False)] = ( + HighVolume_DMSO_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 514.3, + 250.0: 259.0, + 50.0: 54.4, + 0.0: 0.0, + 100.0: 105.8, + 20.0: 22.8, + 1000.0: 1024.5, + 10.0: 12.4, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4332,13 +5247,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, False, Liquid.ETHANOL, True, True)] = \ -HighVolume_EtOH_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 534.8, 250.0: 273.0, 50.0: 62.9, 0.0: 0.0, 100.0: 116.3, 20.0: 27.8, 1000.0: 1053.9, 10.0: 15.8}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, False, Liquid.ETHANOL, True, True)] = ( + HighVolume_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 534.8, + 250.0: 273.0, + 50.0: 62.9, + 0.0: 0.0, + 100.0: 116.3, + 20.0: 27.8, + 1000.0: 1053.9, + 10.0: 15.8, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -4355,12 +5280,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(1000, False, True, False, Liquid.ETHANOL, True, False)] = \ -HighVolume_EtOH_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(1000, False, True, False, Liquid.ETHANOL, True, False)] = ( + HighVolume_EtOH_DispenseJet_Part +) = HamiltonLiquidClass( curve={500.0: 529.0, 50.0: 62.9, 0.0: 0.0, 100.0: 114.5, 20.0: 27.8, 1000.0: 1053.9}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, @@ -4378,13 +5304,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=5.0 -) - - -vantage_mapping[(1000, False, True, False, Liquid.ETHANOL, False, True)] = \ -HighVolume_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 20.0: 27.6, 100.0: 114.0, 10.0: 15.7, 1000.0: 1044.3}, + dispense_stop_back_volume=5.0, +) + + +vantage_mapping[(1000, False, True, False, Liquid.ETHANOL, False, True)] = ( + HighVolume_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 528.4, + 250.0: 269.2, + 50.0: 61.2, + 0.0: 0.0, + 20.0: 27.6, + 100.0: 114.0, + 10.0: 15.7, + 1000.0: 1044.3, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -4401,13 +5337,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, False, Liquid.ETHANOL, False, False)] = \ -HighVolume_EtOH_DispenseSurface_Part = HamiltonLiquidClass( - curve={500.0: 528.4, 250.0: 269.2, 50.0: 61.2, 0.0: 0.0, 100.0: 114.0, 20.0: 27.6, 1000.0: 1044.3, 10.0: 14.7}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, False, Liquid.ETHANOL, False, False)] = ( + HighVolume_EtOH_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 528.4, + 250.0: 269.2, + 50.0: 61.2, + 0.0: 0.0, + 100.0: 114.0, + 20.0: 27.6, + 1000.0: 1044.3, + 10.0: 14.7, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -4424,13 +5370,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, False, Liquid.GLYCERIN80, True, True)] = \ -HighVolume_Glycerin80_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 537.8, 250.0: 277.0, 50.0: 63.3, 0.0: 0.0, 100.0: 118.8, 20.0: 28.0, 1000.0: 1060.0, 10.0: 15.2}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, False, Liquid.GLYCERIN80, True, True)] = ( + HighVolume_Glycerin80_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 537.8, + 250.0: 277.0, + 50.0: 63.3, + 0.0: 0.0, + 100.0: 118.8, + 20.0: 28.0, + 1000.0: 1060.0, + 10.0: 15.2, + }, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, aspiration_air_transport_volume=5.0, @@ -4447,13 +5403,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, True)] = \ -HighVolume_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 100.0: 105.5, 20.0: 22.7, 1000.0: 1027.2, 10.0: 12.2}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, True)] = ( + HighVolume_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 513.5, + 250.0: 257.2, + 50.0: 55.0, + 0.0: 0.0, + 100.0: 105.5, + 20.0: 22.7, + 1000.0: 1027.2, + 10.0: 12.2, + }, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4470,13 +5436,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, False)] = \ -HighVolume_Glycerin80_DispenseSurface_Part = HamiltonLiquidClass( - curve={500.0: 513.5, 250.0: 257.2, 50.0: 55.0, 0.0: 0.0, 100.0: 105.5, 20.0: 22.7, 1000.0: 1027.2, 10.0: 12.2}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, False)] = ( + HighVolume_Glycerin80_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 513.5, + 250.0: 257.2, + 50.0: 55.0, + 0.0: 0.0, + 100.0: 105.5, + 20.0: 22.7, + 1000.0: 1027.2, + 10.0: 12.2, + }, aspiration_flow_rate=150.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4493,14 +5469,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 250 -vantage_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = \ -HighVolume_Serum_AliquotDispenseJet_Part = HamiltonLiquidClass( - curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, +vantage_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = ( + HighVolume_Serum_AliquotDispenseJet_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 500.0, + 250.0: 250.0, + 30.0: 30.0, + 0.0: 0.0, + 100.0: 100.0, + 20.0: 20.0, + 1000.0: 1000.0, + 750.0: 750.0, + 10.0: 10.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -4517,13 +5504,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=300.0, - dispense_stop_back_volume=10.0 -) - - -vantage_mapping[(1000, False, True, False, Liquid.SERUM, True, True)] = \ -HighVolume_Serum_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 525.3, 250.0: 266.6, 50.0: 57.9, 0.0: 0.0, 100.0: 111.3, 20.0: 24.2, 1000.0: 1038.6, 10.0: 12.2}, + dispense_stop_back_volume=10.0, +) + + +vantage_mapping[(1000, False, True, False, Liquid.SERUM, True, True)] = ( + HighVolume_Serum_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 525.3, + 250.0: 266.6, + 50.0: 57.9, + 0.0: 0.0, + 100.0: 111.3, + 20.0: 24.2, + 1000.0: 1038.6, + 10.0: 12.2, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4540,12 +5537,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = \ -HighVolume_Serum_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = ( + HighVolume_Serum_DispenseJet_Part +) = HamiltonLiquidClass( curve={500.0: 525.3, 0.0: 0.0, 100.0: 111.3, 20.0: 27.3, 1000.0: 1046.6}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -4563,13 +5561,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0 -) - - -vantage_mapping[(1000, False, True, False, Liquid.SERUM, False, True)] = \ -HighVolume_Serum_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 517.5, 250.0: 261.9, 50.0: 55.9, 0.0: 0.0, 100.0: 108.2, 20.0: 23.2, 1000.0: 1026.7, 10.0: 11.8}, + dispense_stop_back_volume=10.0, +) + + +vantage_mapping[(1000, False, True, False, Liquid.SERUM, False, True)] = ( + HighVolume_Serum_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 517.5, + 250.0: 261.9, + 50.0: 55.9, + 0.0: 0.0, + 100.0: 108.2, + 20.0: 23.2, + 1000.0: 1026.7, + 10.0: 11.8, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -4586,12 +5594,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(1000, False, True, False, Liquid.SERUM, False, False)] = \ -HighVolume_Serum_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(1000, False, True, False, Liquid.SERUM, False, False)] = ( + HighVolume_Serum_DispenseSurface_Part +) = HamiltonLiquidClass( curve={50.0: 55.9, 0.0: 0.0, 100.0: 108.2, 20.0: 23.2, 1000.0: 1037.7, 10.0: 11.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, @@ -4609,14 +5618,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 250 -vantage_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = \ -HighVolume_Water_AliquotDispenseJet_Part = HamiltonLiquidClass( - curve={500.0: 500.0, 250.0: 250.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0, 1000.0: 1000.0, 750.0: 750.0, 10.0: 10.0}, +vantage_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = ( + HighVolume_Water_AliquotDispenseJet_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 500.0, + 250.0: 250.0, + 30.0: 30.0, + 0.0: 0.0, + 100.0: 100.0, + 20.0: 20.0, + 1000.0: 1000.0, + 750.0: 750.0, + 10.0: 10.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -4633,13 +5653,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 -) - - -vantage_mapping[(1000, False, True, False, Liquid.WATER, True, True)] = \ -HighVolume_Water_DispenseJet_Empty = HamiltonLiquidClass( - curve={500.0: 521.7, 50.0: 57.2, 0.0: 0.0, 100.0: 109.6, 20.0: 24.6, 1000.0: 1034.0, 200.0: 212.9, 10.0: 13.3}, + dispense_stop_back_volume=10.0, +) + + +vantage_mapping[(1000, False, True, False, Liquid.WATER, True, True)] = ( + HighVolume_Water_DispenseJet_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 521.7, + 50.0: 57.2, + 0.0: 0.0, + 100.0: 109.6, + 20.0: 24.6, + 1000.0: 1034.0, + 200.0: 212.9, + 10.0: 13.3, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=5.0, @@ -4656,12 +5686,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = \ -HighVolume_Water_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(1000, False, True, False, Liquid.WATER, True, False)] = ( + HighVolume_Water_DispenseJet_Part +) = HamiltonLiquidClass( curve={500.0: 521.7, 0.0: 0.0, 100.0: 109.6, 20.0: 26.9, 1000.0: 1040.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -4679,13 +5710,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=18.0 -) - - -vantage_mapping[(1000, False, True, False, Liquid.WATER, False, True)] = \ -HighVolume_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 100.0: 108.3, 20.0: 23.9, 1000.0: 1028.5, 200.0: 211.0, 10.0: 12.5}, + dispense_stop_back_volume=18.0, +) + + +vantage_mapping[(1000, False, True, False, Liquid.WATER, False, True)] = ( + HighVolume_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 500.0: 518.3, + 50.0: 56.3, + 0.0: 0.0, + 100.0: 108.3, + 20.0: 23.9, + 1000.0: 1028.5, + 200.0: 211.0, + 10.0: 12.5, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=5.0, @@ -4702,13 +5743,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(1000, False, True, False, Liquid.WATER, False, False)] = \ -HighVolume_Water_DispenseSurface_Part = HamiltonLiquidClass( - curve={500.0: 518.3, 50.0: 56.3, 0.0: 0.0, 100.0: 108.3, 20.0: 23.9, 1000.0: 1036.5, 200.0: 211.0, 10.0: 12.5}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(1000, False, True, False, Liquid.WATER, False, False)] = ( + HighVolume_Water_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 500.0: 518.3, + 50.0: 56.3, + 0.0: 0.0, + 100.0: 108.3, + 20.0: 23.9, + 1000.0: 1036.5, + 200.0: 211.0, + 10.0: 12.5, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=120.0, aspiration_air_transport_volume=0.0, @@ -4725,7 +5776,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -4735,8 +5786,9 @@ def get_vantage_liquid_class(**kwargs): # - fix height from bottom between 0.5-0.7mm # - dispense mode jet empty tip # - also with higher DNA concentration -vantage_mapping[(10, False, False, False, Liquid.DNA_TRIS_EDTA, True, False)] = \ -LowNeedleDNADispenseJet = HamiltonLiquidClass( +vantage_mapping[(10, False, False, False, Liquid.DNA_TRIS_EDTA, True, False)] = ( + LowNeedleDNADispenseJet +) = HamiltonLiquidClass( curve={5.0: 5.7, 0.5: 1.0, 50.0: 53.0, 0.0: 0.0, 20.0: 22.1, 1.0: 1.5, 10.0: 10.8, 2.0: 2.7}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, @@ -4754,7 +5806,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.5 + dispense_stop_back_volume=0.5, ) @@ -4763,8 +5815,9 @@ def get_vantage_liquid_class(**kwargs): # - for Disp. in empty PCR-Plate/on empty Plate from 1µl up # - fix height from bottom between 0.5-0.7mm # - also with higher DNA concentration -vantage_mapping[(10, False, False, False, Liquid.DNA_TRIS_EDTA, False, False)] = \ -LowNeedleDNADispenseSurface = HamiltonLiquidClass( +vantage_mapping[(10, False, False, False, Liquid.DNA_TRIS_EDTA, False, False)] = ( + LowNeedleDNADispenseSurface +) = HamiltonLiquidClass( curve={5.0: 5.7, 0.5: 1.0, 50.0: 53.0, 0.0: 0.0, 20.0: 22.1, 1.0: 1.5, 10.0: 10.8, 2.0: 2.7}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, @@ -4782,14 +5835,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 60 -vantage_mapping[(10, False, False, False, Liquid.WATER, False, False)] = \ -LowNeedle_SysFlWater_DispenseSurface = HamiltonLiquidClass( - curve={35.0: 35.6, 60.0: 62.7, 50.0: 51.3, 40.0: 40.9, 30.0: 30.0, 0.0: 0.0, 31.0: 31.4, 32.0: 32.7}, +vantage_mapping[(10, False, False, False, Liquid.WATER, False, False)] = ( + LowNeedle_SysFlWater_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 35.0: 35.6, + 60.0: 62.7, + 50.0: 51.3, + 40.0: 40.9, + 30.0: 30.0, + 0.0: 0.0, + 31.0: 31.4, + 32.0: 32.7, + }, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, aspiration_air_transport_volume=0.0, @@ -4806,12 +5869,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, False, False, Liquid.WATER, True, False)] = \ -LowNeedle_Water_DispenseJet = HamiltonLiquidClass( +vantage_mapping[(10, False, False, False, Liquid.WATER, True, False)] = ( + LowNeedle_Water_DispenseJet +) = HamiltonLiquidClass( curve={50.0: 52.7, 30.0: 31.7, 0.0: 0.0, 20.0: 20.5, 10.0: 10.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -4829,12 +5893,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, False, False, Liquid.WATER, True, True)] = \ -LowNeedle_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(10, False, False, False, Liquid.WATER, True, True)] = ( + LowNeedle_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={70.0: 70.0, 50.0: 52.7, 30.0: 31.7, 0.0: 0.0, 20.0: 20.5, 10.0: 10.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -4852,12 +5917,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, False, False, Liquid.WATER, True, False)] = \ -LowNeedle_Water_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(10, False, False, False, Liquid.WATER, True, False)] = ( + LowNeedle_Water_DispenseJet_Part +) = HamiltonLiquidClass( curve={70.0: 70.0, 50.0: 52.7, 30.0: 31.7, 0.0: 0.0, 20.0: 20.5, 10.0: 10.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -4875,13 +5941,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 60 -vantage_mapping[(10, False, False, False, Liquid.WATER, False, False)] = \ -LowNeedle_Water_DispenseSurface = HamiltonLiquidClass( +vantage_mapping[(10, False, False, False, Liquid.WATER, False, False)] = ( + LowNeedle_Water_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 5.0, 0.5: 0.5, 50.0: 50.0, 0.0: 0.0, 20.0: 20.5, 1.0: 1.0, 10.0: 10.0, 2.0: 2.0}, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, @@ -4899,13 +5966,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(10, False, False, False, Liquid.WATER, False, True)] = \ -LowNeedle_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={5.0: 5.0, 0.5: 0.5, 70.0: 70.0, 50.0: 50.0, 0.0: 0.0, 20.0: 20.5, 1.0: 1.0, 10.0: 10.0, 2.0: 2.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(10, False, False, False, Liquid.WATER, False, True)] = ( + LowNeedle_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 5.0: 5.0, + 0.5: 0.5, + 70.0: 70.0, + 50.0: 50.0, + 0.0: 0.0, + 20.0: 20.5, + 1.0: 1.0, + 10.0: 10.0, + 2.0: 2.0, + }, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, aspiration_air_transport_volume=0.0, @@ -4922,13 +6000,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(10, False, False, False, Liquid.WATER, False, False)] = \ -LowNeedle_Water_DispenseSurface_Part = HamiltonLiquidClass( - curve={5.0: 5.0, 0.5: 0.5, 70.0: 70.0, 50.0: 50.0, 0.0: 0.0, 20.0: 20.5, 1.0: 1.0, 10.0: 10.0, 2.0: 2.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(10, False, False, False, Liquid.WATER, False, False)] = ( + LowNeedle_Water_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 5.0: 5.0, + 0.5: 0.5, + 70.0: 70.0, + 50.0: 50.0, + 0.0: 0.0, + 20.0: 20.5, + 1.0: 1.0, + 10.0: 10.0, + 2.0: 2.0, + }, aspiration_flow_rate=60.0, aspiration_mix_flow_rate=60.0, aspiration_air_transport_volume=0.0, @@ -4945,12 +6034,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, True, True, True, Liquid.DMSO, False, True)] = \ -LowVolumeFilter_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(10, True, True, True, Liquid.DMSO, False, True)] = ( + LowVolumeFilter_96COREHead_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.1, 0.0: 0.0, 1.0: 0.8, 10.0: 10.0}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -4968,12 +6058,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, True, True, True, Liquid.DMSO, False, False)] = \ -LowVolumeFilter_96COREHead_DMSO_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(10, True, True, True, Liquid.DMSO, False, False)] = ( + LowVolumeFilter_96COREHead_DMSO_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.7, 0.0: 0.0, 1.0: 1.5, 10.0: 10.3}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -4991,12 +6082,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, True, True, True, Liquid.WATER, False, True)] = \ -LowVolumeFilter_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(10, True, True, True, Liquid.WATER, False, True)] = ( + LowVolumeFilter_96COREHead_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 0.0: 0.0, 1.0: 1.2, 10.0: 10.0}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -5014,12 +6106,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, True, True, True, Liquid.WATER, False, False)] = \ -LowVolumeFilter_96COREHead_Water_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(10, True, True, True, Liquid.WATER, False, False)] = ( + LowVolumeFilter_96COREHead_Water_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.8, 0.0: 0.0, 1.0: 1.5, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5037,13 +6130,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 75 -vantage_mapping[(10, False, True, True, Liquid.DMSO, False, False)] = \ -LowVolumeFilter_DMSO_DispenseSurface = HamiltonLiquidClass( +vantage_mapping[(10, False, True, True, Liquid.DMSO, False, False)] = ( + LowVolumeFilter_DMSO_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.5: 0.8, 15.0: 16.4, 0.0: 0.0, 1.0: 1.4, 2.0: 2.6, 10.0: 11.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5061,12 +6155,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=56.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, True, True, Liquid.DMSO, False, True)] = \ -LowVolumeFilter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(10, False, True, True, Liquid.DMSO, False, True)] = ( + LowVolumeFilter_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 10.0, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5084,12 +6179,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, True, True, Liquid.DMSO, False, False)] = \ -LowVolumeFilter_DMSO_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(10, False, True, True, Liquid.DMSO, False, False)] = ( + LowVolumeFilter_DMSO_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.4, 10.0: 10.0, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5107,13 +6203,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 75 -vantage_mapping[(10, False, True, True, Liquid.ETHANOL, False, False)] = \ -LowVolumeFilter_EtOH_DispenseSurface = HamiltonLiquidClass( +vantage_mapping[(10, False, True, True, Liquid.ETHANOL, False, False)] = ( + LowVolumeFilter_EtOH_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 8.4, 0.5: 1.9, 0.0: 0.0, 1.0: 2.7, 2.0: 4.1, 10.0: 13.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5131,12 +6228,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, True, True, Liquid.ETHANOL, False, True)] = \ -LowVolumeFilter_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(10, False, True, True, Liquid.ETHANOL, False, True)] = ( + LowVolumeFilter_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 6.6, 0.0: 0.0, 1.0: 1.8, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5154,12 +6252,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, True, True, Liquid.ETHANOL, False, False)] = \ -LowVolumeFilter_EtOH_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(10, False, True, True, Liquid.ETHANOL, False, False)] = ( + LowVolumeFilter_EtOH_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 6.4, 0.0: 0.0, 1.0: 1.8, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5177,13 +6276,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 10 -vantage_mapping[(10, False, True, True, Liquid.GLYCERIN, False, False)] = \ -LowVolumeFilter_Glycerin_DispenseSurface = HamiltonLiquidClass( +vantage_mapping[(10, False, True, True, Liquid.GLYCERIN, False, False)] = ( + LowVolumeFilter_Glycerin_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 6.5, 0.5: 1.4, 15.0: 17.0, 0.0: 0.0, 1.0: 2.0, 2.0: 3.2, 10.0: 11.8}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, @@ -5201,12 +6301,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, True, True, Liquid.GLYCERIN80, False, True)] = \ -LowVolumeFilter_Glycerin_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(10, False, True, True, Liquid.GLYCERIN80, False, True)] = ( + LowVolumeFilter_Glycerin_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 6.5, 0.0: 0.0, 1.0: 0.6, 10.0: 10.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, @@ -5224,13 +6325,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 75 -vantage_mapping[(10, False, True, True, Liquid.WATER, False, False)] = \ -LowVolumeFilter_Water_DispenseSurface = HamiltonLiquidClass( +vantage_mapping[(10, False, True, True, Liquid.WATER, False, False)] = ( + LowVolumeFilter_Water_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 6.0, 0.5: 0.8, 15.0: 16.7, 0.0: 0.0, 1.0: 1.4, 2.0: 2.6, 10.0: 11.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5248,12 +6350,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=56.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, True, True, Liquid.WATER, False, True)] = \ -LowVolumeFilter_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(10, False, True, True, Liquid.WATER, False, True)] = ( + LowVolumeFilter_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 6.0, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 10.0, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5271,12 +6374,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, True, True, Liquid.WATER, False, False)] = \ -LowVolumeFilter_Water_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(10, False, True, True, Liquid.WATER, False, False)] = ( + LowVolumeFilter_Water_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.2, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5294,7 +6398,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -5315,8 +6419,9 @@ def get_vantage_liquid_class(**kwargs): # 5.0 1.08 -1.29 # 10.0 0.62 0.53 # -vantage_mapping[(10, False, True, False, Liquid.PLASMA, False, False)] = \ -LowVolumePlasmaDispenseSurface = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.PLASMA, False, False)] = ( + LowVolumePlasmaDispenseSurface +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 11.5, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -5334,12 +6439,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, True, False, Liquid.PLASMA, False, True)] = \ -LowVolumePlasmaDispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.PLASMA, False, True)] = ( + LowVolumePlasmaDispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 0.5: 0.2, 0.0: 0.0, 1.0: 0.9, 10.0: 11.3, 2.0: 2.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -5357,12 +6463,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, True, False, Liquid.PLASMA, False, False)] = \ -LowVolumePlasmaDispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.PLASMA, False, False)] = ( + LowVolumePlasmaDispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.3, 10.0: 11.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -5380,7 +6487,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -5401,8 +6508,9 @@ def get_vantage_liquid_class(**kwargs): # 5.0 1.08 -1.29 # 10.0 0.62 0.53 # -vantage_mapping[(10, False, True, False, Liquid.SERUM, False, False)] = \ -LowVolumeSerumDispenseSurface = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.SERUM, False, False)] = ( + LowVolumeSerumDispenseSurface +) = HamiltonLiquidClass( curve={5.0: 5.6, 0.5: 0.2, 0.0: 0.0, 1.0: 0.9, 10.0: 11.3, 2.0: 2.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -5420,12 +6528,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, True, False, Liquid.SERUM, False, True)] = \ -LowVolumeSerumDispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.SERUM, False, True)] = ( + LowVolumeSerumDispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 0.5: 0.2, 0.0: 0.0, 1.0: 0.9, 10.0: 11.3, 2.0: 2.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -5443,12 +6552,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, True, False, Liquid.SERUM, False, False)] = \ -LowVolumeSerumDispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.SERUM, False, False)] = ( + LowVolumeSerumDispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.3, 10.0: 11.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -5466,12 +6576,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, True, True, False, Liquid.DMSO, False, True)] = \ -LowVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(10, True, True, False, Liquid.DMSO, False, True)] = ( + LowVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.3, 0.0: 0.0, 1.0: 0.8, 10.0: 10.6}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -5489,12 +6600,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, True, True, False, Liquid.WATER, False, True)] = \ -LowVolume_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(10, True, True, False, Liquid.WATER, False, True)] = ( + LowVolume_96COREHead1000ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.8, 0.0: 0.0, 1.0: 1.0, 10.0: 11.2}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -5512,12 +6624,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, True, True, False, Liquid.DMSO, False, True)] = \ -LowVolume_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(10, True, True, False, Liquid.DMSO, False, True)] = ( + LowVolume_96COREHead_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.1, 0.0: 0.0, 1.0: 0.8, 10.0: 10.3}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -5535,12 +6648,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, True, True, False, Liquid.DMSO, False, False)] = \ -LowVolume_96COREHead_DMSO_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(10, True, True, False, Liquid.DMSO, False, False)] = ( + LowVolume_96COREHead_DMSO_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.5, 10.0: 11.0}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -5558,12 +6672,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, True, True, False, Liquid.WATER, False, True)] = \ -LowVolume_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(10, True, True, False, Liquid.WATER, False, True)] = ( + LowVolume_96COREHead_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.8, 0.0: 0.0, 1.0: 1.3, 10.0: 11.1}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -5581,12 +6696,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, True, True, False, Liquid.WATER, False, False)] = \ -LowVolume_96COREHead_Water_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(10, True, True, False, Liquid.WATER, False, False)] = ( + LowVolume_96COREHead_Water_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.7, 0.0: 0.0, 1.0: 1.4, 10.0: 10.8}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -5604,13 +6720,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # Liquid class for wash low volume tips with CO-RE 96 Head in CO-RE 96 Head Washer. -vantage_mapping[(10, True, True, False, Liquid.WATER, False, False)] = \ -LowVolume_Core96Washer_DispenseSurface = HamiltonLiquidClass( +vantage_mapping[(10, True, True, False, Liquid.WATER, False, False)] = ( + LowVolume_Core96Washer_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 6.0, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 15.0, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=150.0, @@ -5628,13 +6745,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=56.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 75 -vantage_mapping[(10, False, True, False, Liquid.DMSO, False, False)] = \ -LowVolume_DMSO_DispenseSurface = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.DMSO, False, False)] = ( + LowVolume_DMSO_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 5.9, 15.0: 16.4, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 11.2, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5652,12 +6770,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=56.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, True, False, Liquid.DMSO, False, True)] = \ -LowVolume_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.DMSO, False, True)] = ( + LowVolume_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 11.2, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5675,12 +6794,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, True, False, Liquid.DMSO, False, False)] = \ -LowVolume_DMSO_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.DMSO, False, False)] = ( + LowVolume_DMSO_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.4, 10.0: 11.2, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5698,13 +6818,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 75 -vantage_mapping[(10, False, True, False, Liquid.ETHANOL, False, False)] = \ -LowVolume_EtOH_DispenseSurface = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.ETHANOL, False, False)] = ( + LowVolume_EtOH_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 8.4, 0.5: 1.9, 0.0: 0.0, 1.0: 2.7, 10.0: 13.0, 2.0: 4.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5722,12 +6843,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, True, False, Liquid.ETHANOL, False, True)] = \ -LowVolume_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.ETHANOL, False, True)] = ( + LowVolume_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 7.3, 0.0: 0.0, 1.0: 2.4, 10.0: 13.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5745,12 +6867,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, True, False, Liquid.ETHANOL, False, False)] = \ -LowVolume_EtOH_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.ETHANOL, False, False)] = ( + LowVolume_EtOH_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 7.0, 0.0: 0.0, 1.0: 2.4, 10.0: 13.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5768,13 +6891,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 10 -vantage_mapping[(10, False, True, False, Liquid.GLYCERIN, False, False)] = \ -LowVolume_Glycerin_DispenseSurface = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.GLYCERIN, False, False)] = ( + LowVolume_Glycerin_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 6.5, 15.0: 17.0, 0.5: 1.4, 0.0: 0.0, 1.0: 2.0, 10.0: 11.8, 2.0: 3.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, @@ -5792,13 +6916,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 75 -vantage_mapping[(10, False, True, False, Liquid.WATER, False, False)] = \ -LowVolume_Water_DispenseSurface = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.WATER, False, False)] = ( + LowVolume_Water_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 6.0, 15.0: 16.7, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 11.5, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5816,12 +6941,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=56.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, True, True, False, Liquid.WATER, False, False)] = \ -LowVolume_Water_DispenseSurface96Head = HamiltonLiquidClass( +vantage_mapping[(10, True, True, False, Liquid.WATER, False, False)] = ( + LowVolume_Water_DispenseSurface96Head +) = HamiltonLiquidClass( curve={5.0: 6.0, 0.0: 0.0, 1.0: 1.0, 10.0: 11.5}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -5839,12 +6965,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, True, True, False, Liquid.WATER, False, True)] = \ -LowVolume_Water_DispenseSurfaceEmpty96Head = HamiltonLiquidClass( +vantage_mapping[(10, True, True, False, Liquid.WATER, False, True)] = ( + LowVolume_Water_DispenseSurfaceEmpty96Head +) = HamiltonLiquidClass( curve={5.0: 6.0, 0.0: 0.0, 1.0: 1.0, 10.0: 10.9}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -5862,12 +6989,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, True, True, False, Liquid.WATER, False, False)] = \ -LowVolume_Water_DispenseSurfacePart96Head = HamiltonLiquidClass( +vantage_mapping[(10, True, True, False, Liquid.WATER, False, False)] = ( + LowVolume_Water_DispenseSurfacePart96Head +) = HamiltonLiquidClass( curve={5.0: 6.0, 0.0: 0.0, 1.0: 1.0, 10.0: 10.9}, aspiration_flow_rate=25.0, aspiration_mix_flow_rate=25.0, @@ -5885,12 +7013,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=25.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, True, False, Liquid.WATER, False, True)] = \ -LowVolume_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.WATER, False, True)] = ( + LowVolume_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 6.0, 0.5: 0.8, 0.0: 0.0, 1.0: 1.4, 10.0: 11.5, 2.0: 2.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5908,12 +7037,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(10, False, True, False, Liquid.WATER, False, False)] = \ -LowVolume_Water_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(10, False, True, False, Liquid.WATER, False, False)] = ( + LowVolume_Water_DispenseSurface_Part +) = HamiltonLiquidClass( curve={5.0: 5.9, 0.0: 0.0, 1.0: 1.2, 10.0: 11.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -5931,7 +7061,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -5947,8 +7077,9 @@ def get_vantage_liquid_class(**kwargs): # 12 x 20ul = approximately 19.2 ul # 4 x 50 ul = approximately 48.1 ul # 2 x 100 ul = approximately 95.3 ul -vantage_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = \ -SlimTipFilter_96COREHead1000ul_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = ( + SlimTipFilter_96COREHead1000ul_DMSO_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, @@ -5966,12 +7097,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=18.0 + dispense_stop_back_volume=18.0, ) -vantage_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = \ -SlimTipFilter_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = ( + SlimTipFilter_96COREHead1000ul_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 312.3, 50.0: 55.3, 0.0: 0.0, 100.0: 107.7, 20.0: 22.4, 200.0: 210.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -5989,12 +7121,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = \ -SlimTipFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = ( + SlimTipFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 311.9, 50.0: 54.1, 0.0: 0.0, 100.0: 107.5, 20.0: 22.5, 10.0: 11.1, 200.0: 209.4}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6012,7 +7145,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -6029,8 +7162,9 @@ def get_vantage_liquid_class(**kwargs): # 4 x 50 ul = approximately 48.9 ul # 2 x 100 ul = approximately 97.2 ul # -vantage_mapping[(300, True, True, True, Liquid.WATER, True, False)] = \ -SlimTipFilter_96COREHead1000ul_Water_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.WATER, True, False)] = ( + SlimTipFilter_96COREHead1000ul_Water_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, @@ -6048,12 +7182,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -vantage_mapping[(300, True, True, True, Liquid.WATER, True, True)] = \ -SlimTipFilter_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.WATER, True, True)] = ( + SlimTipFilter_96COREHead1000ul_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 317.0, 50.0: 55.8, 0.0: 0.0, 100.0: 109.4, 20.0: 22.7, 200.0: 213.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6071,12 +7206,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, True, Liquid.WATER, False, True)] = \ -SlimTipFilter_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.WATER, False, True)] = ( + SlimTipFilter_96COREHead1000ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 318.7, 50.0: 54.9, 0.0: 0.0, 100.0: 110.4, 10.0: 11.7, 200.0: 210.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6094,7 +7230,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -6111,8 +7247,9 @@ def get_vantage_liquid_class(**kwargs): # 4 x 50 ul = approximately 48.3 ul # 2 x 100 ul = approximately 95.7 ul # -vantage_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = \ -SlimTipFilter_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = ( + SlimTipFilter_DMSO_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6130,12 +7267,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=18.0 + dispense_stop_back_volume=18.0, ) -vantage_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = \ -SlimTipFilter_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = ( + SlimTipFilter_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 309.5, 50.0: 54.4, 0.0: 0.0, 100.0: 106.4, 20.0: 22.1, 200.0: 208.2}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6153,13 +7291,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = \ -SlimTipFilter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 309.7, 5.0: 5.6, 50.0: 53.8, 0.0: 0.0, 100.0: 105.4, 20.0: 22.2, 10.0: 11.3, 200.0: 207.5}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = ( + SlimTipFilter_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 309.7, + 5.0: 5.6, + 50.0: 53.8, + 0.0: 0.0, + 100.0: 105.4, + 20.0: 22.2, + 10.0: 11.3, + 200.0: 207.5, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=1.0, @@ -6176,7 +7324,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -6192,8 +7340,9 @@ def get_vantage_liquid_class(**kwargs): # 12 x 20ul = approximately 21.3 ul # 4 x 50 ul = approximately 54.3 ul # 2 x 100 ul = approximately 105.2 ul -vantage_mapping[(300, True, True, True, Liquid.ETHANOL, True, False)] = \ -SlimTipFilter_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.ETHANOL, True, False)] = ( + SlimTipFilter_EtOH_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6211,12 +7360,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -vantage_mapping[(300, True, True, True, Liquid.ETHANOL, True, True)] = \ -SlimTipFilter_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.ETHANOL, True, True)] = ( + SlimTipFilter_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 320.4, 50.0: 57.2, 0.0: 0.0, 100.0: 110.5, 20.0: 24.5, 200.0: 215.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6234,12 +7384,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, True, Liquid.ETHANOL, False, True)] = \ -SlimTipFilter_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.ETHANOL, False, True)] = ( + SlimTipFilter_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 313.9, 50.0: 55.4, 0.0: 0.0, 100.0: 107.7, 20.0: 23.2, 10.0: 12.4, 200.0: 210.6}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6257,12 +7408,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, True, Liquid.GLYCERIN80, False, True)] = \ -SlimTipFilter_Glycerin_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.GLYCERIN80, False, True)] = ( + SlimTipFilter_Glycerin_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 312.0, 50.0: 55.0, 0.0: 0.0, 100.0: 107.8, 20.0: 22.9, 10.0: 11.8, 200.0: 210.0}, aspiration_flow_rate=30.0, aspiration_mix_flow_rate=30.0, @@ -6280,7 +7432,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=2.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -6296,8 +7448,9 @@ def get_vantage_liquid_class(**kwargs): # 12 x 20ul = approximately 19.6 ul # 4 x 50 ul = approximately 49.2 ul # 2 x 100 ul = approximately 97.5 ul -vantage_mapping[(300, True, True, True, Liquid.WATER, True, False)] = \ -SlimTipFilter_Water_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.WATER, True, False)] = ( + SlimTipFilter_Water_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, @@ -6315,12 +7468,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -vantage_mapping[(300, True, True, True, Liquid.WATER, True, True)] = \ -SlimTipFilter_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.WATER, True, True)] = ( + SlimTipFilter_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 317.2, 50.0: 55.6, 0.0: 0.0, 100.0: 108.6, 20.0: 22.6, 200.0: 212.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6338,13 +7492,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(300, True, True, True, Liquid.WATER, False, True)] = \ -SlimTipFilter_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 314.1, 5.0: 6.2, 50.0: 54.7, 0.0: 0.0, 100.0: 108.0, 20.0: 22.7, 10.0: 11.9, 200.0: 211.3}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(300, True, True, True, Liquid.WATER, False, True)] = ( + SlimTipFilter_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 314.1, + 5.0: 6.2, + 50.0: 54.7, + 0.0: 0.0, + 100.0: 108.0, + 20.0: 22.7, + 10.0: 11.9, + 200.0: 211.3, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -6361,7 +7525,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -6377,8 +7541,9 @@ def get_vantage_liquid_class(**kwargs): # 12 x 20ul = approximately 19.2 ul # 4 x 50 ul = approximately 48.1 ul # 2 x 100 ul = approximately 95.3 ul -vantage_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ -SlimTip_96COREHead1000ul_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = ( + SlimTip_96COREHead1000ul_DMSO_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, @@ -6396,12 +7561,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=18.0 + dispense_stop_back_volume=18.0, ) -vantage_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ -SlimTip_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = ( + SlimTip_96COREHead1000ul_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 313.8, 50.0: 55.8, 0.0: 0.0, 100.0: 109.2, 20.0: 23.1, 200.0: 212.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6419,12 +7585,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ -SlimTip_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = ( + SlimTip_96COREHead1000ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 312.9, 50.0: 54.1, 0.0: 0.0, 20.0: 22.5, 100.0: 108.8, 200.0: 210.9, 10.0: 11.1}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6442,7 +7609,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -6458,8 +7625,9 @@ def get_vantage_liquid_class(**kwargs): # 12 x 20ul = approximately 21.8 ul # 4 x 50 ul = approximately 53.6 ul # 2 x 100 ul = approximately 105.2 ul -vantage_mapping[(300, True, True, False, Liquid.ETHANOL, True, False)] = \ -SlimTip_96COREHead1000ul_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.ETHANOL, True, False)] = ( + SlimTip_96COREHead1000ul_EtOH_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6477,12 +7645,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=80.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -vantage_mapping[(300, True, True, False, Liquid.ETHANOL, True, True)] = \ -SlimTip_96COREHead1000ul_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.ETHANOL, True, True)] = ( + SlimTip_96COREHead1000ul_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 326.2, 50.0: 58.8, 0.0: 0.0, 100.0: 112.7, 20.0: 25.0, 200.0: 218.2}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6500,12 +7669,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, False, Liquid.ETHANOL, False, True)] = \ -SlimTip_96COREHead1000ul_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.ETHANOL, False, True)] = ( + SlimTip_96COREHead1000ul_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 320.3, 50.0: 56.7, 0.0: 0.0, 100.0: 109.5, 10.0: 12.4, 200.0: 213.9}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6523,12 +7693,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=2.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, False, Liquid.GLYCERIN80, False, True)] = \ -SlimTip_96COREHead1000ul_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.GLYCERIN80, False, True)] = ( + SlimTip_96COREHead1000ul_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 319.3, 50.0: 58.2, 0.0: 0.0, 100.0: 112.1, 20.0: 23.9, 10.0: 12.1, 200.0: 216.9}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -6546,7 +7717,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=2.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -6563,8 +7734,9 @@ def get_vantage_liquid_class(**kwargs): # 4 x 50 ul = approximately 48.9 ul # 2 x 100 ul = approximately 97.2 ul # -vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ -SlimTip_96COREHead1000ul_Water_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( + SlimTip_96COREHead1000ul_Water_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, @@ -6582,12 +7754,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ -SlimTip_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( + SlimTip_96COREHead1000ul_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 315.0, 50.0: 55.5, 0.0: 0.0, 100.0: 107.2, 20.0: 22.8, 200.0: 211.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6605,12 +7778,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ -SlimTip_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( + SlimTip_96COREHead1000ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 322.7, 50.0: 56.4, 0.0: 0.0, 100.0: 110.4, 10.0: 11.9, 200.0: 215.5}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6628,7 +7802,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -6645,8 +7819,9 @@ def get_vantage_liquid_class(**kwargs): # 4 x 50 ul = approximately 48.3 ul # 2 x 100 ul = approximately 95.7 ul # -vantage_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ -SlimTip_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = ( + SlimTip_DMSO_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6664,12 +7839,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=18.0 + dispense_stop_back_volume=18.0, ) -vantage_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ -SlimTip_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = ( + SlimTip_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 309.5, 50.0: 54.7, 0.0: 0.0, 100.0: 107.2, 20.0: 22.5, 200.0: 209.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6687,13 +7863,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ -SlimTip_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 310.2, 5.0: 5.6, 50.0: 54.1, 0.0: 0.0, 100.0: 106.2, 20.0: 22.5, 10.0: 11.3, 200.0: 208.7}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = ( + SlimTip_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 310.2, + 5.0: 5.6, + 50.0: 54.1, + 0.0: 0.0, + 100.0: 106.2, + 20.0: 22.5, + 10.0: 11.3, + 200.0: 208.7, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=1.0, @@ -6710,7 +7896,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -6726,8 +7912,9 @@ def get_vantage_liquid_class(**kwargs): # 12 x 20ul = approximately 21.3 ul # 4 x 50 ul = approximately 54.3 ul # 2 x 100 ul = approximately 105.2 ul -vantage_mapping[(300, True, True, False, Liquid.ETHANOL, True, False)] = \ -SlimTip_EtOH_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.ETHANOL, True, False)] = ( + SlimTip_EtOH_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6745,12 +7932,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -vantage_mapping[(300, True, True, False, Liquid.ETHANOL, True, True)] = \ -SlimTip_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.ETHANOL, True, True)] = ( + SlimTip_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 323.4, 50.0: 57.2, 0.0: 0.0, 100.0: 110.5, 20.0: 24.7, 200.0: 211.9}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6768,13 +7956,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(300, True, True, False, Liquid.ETHANOL, False, True)] = \ -SlimTip_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 312.9, 5.0: 6.2, 50.0: 55.4, 0.0: 0.0, 100.0: 107.7, 20.0: 23.2, 10.0: 11.9, 200.0: 210.6}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(300, True, True, False, Liquid.ETHANOL, False, True)] = ( + SlimTip_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 312.9, + 5.0: 6.2, + 50.0: 55.4, + 0.0: 0.0, + 100.0: 107.7, + 20.0: 23.2, + 10.0: 11.9, + 200.0: 210.6, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=2.0, @@ -6791,13 +7989,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(300, True, True, False, Liquid.GLYCERIN80, False, True)] = \ -SlimTip_Glycerin_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 313.3, 5.0: 6.0, 50.0: 55.7, 0.0: 0.0, 100.0: 107.8, 20.0: 22.9, 10.0: 11.5, 200.0: 210.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(300, True, True, False, Liquid.GLYCERIN80, False, True)] = ( + SlimTip_Glycerin_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 313.3, + 5.0: 6.0, + 50.0: 55.7, + 0.0: 0.0, + 100.0: 107.8, + 20.0: 22.9, + 10.0: 11.5, + 200.0: 210.0, + }, aspiration_flow_rate=30.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=0.0, @@ -6814,7 +8022,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=2.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -6830,8 +8038,9 @@ def get_vantage_liquid_class(**kwargs): # 12 x 20ul = approximately 19.6 ul # 4 x 50 ul = approximately 50.0 ul # 2 x 100 ul = approximately 98.4 ul -vantage_mapping[(300, True, True, False, Liquid.SERUM, True, False)] = \ -SlimTip_Serum_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.SERUM, True, False)] = ( + SlimTip_Serum_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6849,12 +8058,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -vantage_mapping[(300, True, True, False, Liquid.SERUM, True, True)] = \ -SlimTip_Serum_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.SERUM, True, True)] = ( + SlimTip_Serum_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 321.5, 50.0: 56.0, 0.0: 0.0, 100.0: 109.7, 20.0: 22.8, 200.0: 215.7}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6872,13 +8082,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(300, True, True, False, Liquid.SERUM, False, True)] = \ -SlimTip_Serum_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 320.2, 5.0: 5.5, 50.0: 55.4, 0.0: 0.0, 20.0: 22.6, 100.0: 109.7, 200.0: 214.9, 10.0: 11.3}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(300, True, True, False, Liquid.SERUM, False, True)] = ( + SlimTip_Serum_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 320.2, + 5.0: 5.5, + 50.0: 55.4, + 0.0: 0.0, + 20.0: 22.6, + 100.0: 109.7, + 200.0: 214.9, + 10.0: 11.3, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=1.0, @@ -6895,7 +8115,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -6911,8 +8131,9 @@ def get_vantage_liquid_class(**kwargs): # 12 x 20ul = approximately 19.6 ul # 4 x 50 ul = approximately 49.2 ul # 2 x 100 ul = approximately 97.5 ul -vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ -SlimTip_Water_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( + SlimTip_Water_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 50.0: 50.0, 30.0: 30.0, 0.0: 0.0, 100.0: 100.0, 20.0: 20.0}, aspiration_flow_rate=200.0, aspiration_mix_flow_rate=200.0, @@ -6930,12 +8151,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ -SlimTip_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( + SlimTip_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 317.2, 50.0: 55.6, 0.0: 0.0, 20.0: 22.6, 100.0: 108.6, 200.0: 212.8}, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, @@ -6953,13 +8175,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ -SlimTip_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 317.1, 5.0: 6.2, 50.0: 55.1, 0.0: 0.0, 100.0: 108.0, 20.0: 22.9, 10.0: 11.9, 200.0: 213.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( + SlimTip_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 317.1, + 5.0: 6.2, + 50.0: 55.1, + 0.0: 0.0, + 100.0: 108.0, + 20.0: 22.9, + 10.0: 11.9, + 200.0: 213.0, + }, aspiration_flow_rate=250.0, aspiration_mix_flow_rate=250.0, aspiration_air_transport_volume=0.0, @@ -6976,14 +8208,15 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 80 # V1.2: Stop back volume = 0 (previous value: 15) -vantage_mapping[(300, False, False, False, Liquid.WATER, True, False)] = \ -StandardNeedle_Water_DispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, False, False, Liquid.WATER, True, False)] = ( + StandardNeedle_Water_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 311.2, 50.0: 51.3, 0.0: 0.0, 100.0: 103.4, 20.0: 19.5}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, @@ -7001,12 +8234,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, False, False, Liquid.WATER, True, True)] = \ -StandardNeedle_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, False, False, False, Liquid.WATER, True, True)] = ( + StandardNeedle_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 311.2, 50.0: 51.3, 0.0: 0.0, 100.0: 103.4, 20.0: 19.5}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, @@ -7024,12 +8258,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, False, False, Liquid.WATER, True, False)] = \ -StandardNeedle_Water_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, False, False, Liquid.WATER, True, False)] = ( + StandardNeedle_Water_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 311.2, 50.0: 51.3, 0.0: 0.0, 100.0: 103.4, 20.0: 19.5}, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, @@ -7047,13 +8282,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(300, False, False, False, Liquid.WATER, False, False)] = \ -StandardNeedle_Water_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 308.4, 5.0: 6.5, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 1.1, 200.0: 205.8, 10.0: 12.0, 2.0: 2.1}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(300, False, False, False, Liquid.WATER, False, False)] = ( + StandardNeedle_Water_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 308.4, + 5.0: 6.5, + 50.0: 52.3, + 0.0: 0.0, + 100.0: 102.9, + 20.0: 22.3, + 1.0: 1.1, + 200.0: 205.8, + 10.0: 12.0, + 2.0: 2.1, + }, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=0.0, @@ -7070,13 +8317,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(300, False, False, False, Liquid.WATER, False, True)] = \ -StandardNeedle_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 308.4, 5.0: 6.5, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 1.1, 200.0: 205.8, 10.0: 12.0, 2.0: 2.1}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(300, False, False, False, Liquid.WATER, False, True)] = ( + StandardNeedle_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 308.4, + 5.0: 6.5, + 50.0: 52.3, + 0.0: 0.0, + 100.0: 102.9, + 20.0: 22.3, + 1.0: 1.1, + 200.0: 205.8, + 10.0: 12.0, + 2.0: 2.1, + }, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=0.0, @@ -7093,13 +8352,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(300, False, False, False, Liquid.WATER, False, False)] = \ -StandardNeedle_Water_DispenseSurface_Part = HamiltonLiquidClass( - curve={300.0: 308.4, 5.0: 6.5, 50.0: 52.3, 0.0: 0.0, 100.0: 102.9, 20.0: 22.3, 1.0: 1.1, 200.0: 205.8, 10.0: 12.0, 2.0: 2.1}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(300, False, False, False, Liquid.WATER, False, False)] = ( + StandardNeedle_Water_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 300.0: 308.4, + 5.0: 6.5, + 50.0: 52.3, + 0.0: 0.0, + 100.0: 102.9, + 20.0: 22.3, + 1.0: 1.1, + 200.0: 205.8, + 10.0: 12.0, + 2.0: 2.1, + }, aspiration_flow_rate=80.0, aspiration_mix_flow_rate=80.0, aspiration_air_transport_volume=0.0, @@ -7116,7 +8387,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -7140,8 +8411,9 @@ def get_vantage_liquid_class(**kwargs): # 200 0.16 0.55 # 300 0.17 0.35 # -vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, False)] = \ -StandardVolumeAcetonitrilDispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, False)] = ( + StandardVolumeAcetonitrilDispenseJet +) = HamiltonLiquidClass( curve={300.0: 326.2, 50.0: 57.3, 0.0: 0.0, 100.0: 111.5, 20.0: 24.6, 200.0: 217.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7159,12 +8431,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, True)] = \ -StandardVolumeAcetonitrilDispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, True)] = ( + StandardVolumeAcetonitrilDispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 326.2, 50.0: 57.3, 0.0: 0.0, 100.0: 111.5, 20.0: 24.6, 200.0: 217.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7182,12 +8455,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, False)] = \ -StandardVolumeAcetonitrilDispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, True, False)] = ( + StandardVolumeAcetonitrilDispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 321.2, 50.0: 57.3, 0.0: 0.0, 100.0: 110.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7205,7 +8479,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) @@ -7229,9 +8503,21 @@ def get_vantage_liquid_class(**kwargs): # 200 0.65 0.65 # 300 0.21 0.88 # -vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, False)] = \ -StandardVolumeAcetonitrilDispenseSurface = HamiltonLiquidClass( - curve={300.0: 328.0, 5.0: 6.8, 50.0: 58.5, 0.0: 0.0, 100.0: 112.7, 20.0: 24.8, 1.0: 1.3, 200.0: 220.0, 10.0: 13.0, 2.0: 3.0}, +vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, False)] = ( + StandardVolumeAcetonitrilDispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 328.0, + 5.0: 6.8, + 50.0: 58.5, + 0.0: 0.0, + 100.0: 112.7, + 20.0: 24.8, + 1.0: 1.3, + 200.0: 220.0, + 10.0: 13.0, + 2.0: 3.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=10.0, @@ -7248,13 +8534,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, True)] = \ -StandardVolumeAcetonitrilDispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 328.0, 5.0: 6.8, 50.0: 58.5, 0.0: 0.0, 100.0: 112.7, 20.0: 24.8, 1.0: 1.3, 200.0: 220.0, 10.0: 13.0, 2.0: 3.0}, +vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, True)] = ( + StandardVolumeAcetonitrilDispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 328.0, + 5.0: 6.8, + 50.0: 58.5, + 0.0: 0.0, + 100.0: 112.7, + 20.0: 24.8, + 1.0: 1.3, + 200.0: 220.0, + 10.0: 13.0, + 2.0: 3.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=10.0, @@ -7271,12 +8569,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, False)] = \ -StandardVolumeAcetonitrilDispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.ACETONITRILE, False, False)] = ( + StandardVolumeAcetonitrilDispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 328.0, 5.0: 7.3, 0.0: 0.0, 100.0: 112.7, 10.0: 13.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7294,7 +8593,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -7314,8 +8613,9 @@ def get_vantage_liquid_class(**kwargs): # 20 (12 Aliquots) 2.53 -2.97 # 50 ( 4 Aliquots) 0.84 -2.57 # -vantage_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = \ -StandardVolumeDMSOAliquotJet = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = ( + StandardVolumeDMSOAliquotJet +) = HamiltonLiquidClass( curve={350.0: 350.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7333,7 +8633,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=0.3, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) @@ -7354,8 +8654,9 @@ def get_vantage_liquid_class(**kwargs): # 200 0.53 0.08 # 300 0.54 0.22 # -vantage_mapping[(300, False, True, False, Liquid.ETHANOL, False, False)] = \ -StandardVolumeEtOHDispenseSurface = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.ETHANOL, False, False)] = ( + StandardVolumeEtOHDispenseSurface +) = HamiltonLiquidClass( curve={300.0: 309.2, 50.0: 54.8, 0.0: 0.0, 100.0: 106.5, 20.0: 23.7, 200.0: 208.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=50.0, @@ -7373,12 +8674,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=0.4, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.ETHANOL, False, True)] = \ -StandardVolumeEtOHDispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.ETHANOL, False, True)] = ( + StandardVolumeEtOHDispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 309.2, 50.0: 54.8, 0.0: 0.0, 100.0: 106.5, 20.0: 23.7, 200.0: 208.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=50.0, @@ -7396,12 +8698,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.ETHANOL, False, False)] = \ -StandardVolumeEtOHDispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.ETHANOL, False, False)] = ( + StandardVolumeEtOHDispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 315.2, 0.0: 0.0, 100.0: 108.5, 20.0: 23.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=50.0, @@ -7419,12 +8722,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = \ -StandardVolumeFilter_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = ( + StandardVolumeFilter_96COREHead1000ul_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 302.5, 0.0: 0.0, 100.0: 101.0, 20.0: 20.4, 200.0: 201.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7442,12 +8746,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = \ -StandardVolumeFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = ( + StandardVolumeFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 306.0, 0.0: 0.0, 100.0: 104.3, 200.0: 205.0, 10.0: 12.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7465,12 +8770,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, True, Liquid.WATER, True, True)] = \ -StandardVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.WATER, True, True)] = ( + StandardVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7488,12 +8794,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, True, Liquid.WATER, False, True)] = \ -StandardVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.WATER, False, True)] = ( + StandardVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 210.0, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7511,12 +8818,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = \ -StandardVolumeFilter_96COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.DMSO, True, True)] = ( + StandardVolumeFilter_96COREHead_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 303.5, 0.0: 0.0, 100.0: 101.8, 10.0: 10.2, 200.0: 200.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7534,12 +8842,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = \ -StandardVolumeFilter_96COREHead_DMSO_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.DMSO, True, False)] = ( + StandardVolumeFilter_96COREHead_DMSO_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 305.0, 0.0: 0.0, 100.0: 103.6, 10.0: 11.5, 200.0: 206.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7557,12 +8866,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -vantage_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = \ -StandardVolumeFilter_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.DMSO, False, True)] = ( + StandardVolumeFilter_96COREHead_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 303.0, 0.0: 0.0, 100.0: 101.3, 10.0: 10.6, 200.0: 202.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7580,12 +8890,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, True, Liquid.DMSO, False, False)] = \ -StandardVolumeFilter_96COREHead_DMSO_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.DMSO, False, False)] = ( + StandardVolumeFilter_96COREHead_DMSO_DispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 303.0, 0.0: 0.0, 100.0: 101.3, 10.0: 10.1, 200.0: 202.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7603,12 +8914,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, True, Liquid.WATER, True, True)] = \ -StandardVolumeFilter_96COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.WATER, True, True)] = ( + StandardVolumeFilter_96COREHead_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 309.0, 0.0: 0.0, 20.0: 22.3, 100.0: 104.2, 10.0: 11.9, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7626,12 +8938,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, True, Liquid.WATER, True, False)] = \ -StandardVolumeFilter_96COREHead_Water_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.WATER, True, False)] = ( + StandardVolumeFilter_96COREHead_Water_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 309.0, 0.0: 0.0, 20.0: 22.3, 100.0: 104.2, 10.0: 11.9, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7649,12 +8962,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -vantage_mapping[(300, True, True, True, Liquid.WATER, False, True)] = \ -StandardVolumeFilter_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.WATER, False, True)] = ( + StandardVolumeFilter_96COREHead_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 306.3, 0.0: 0.0, 100.0: 104.5, 10.0: 11.9, 200.0: 205.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7672,12 +8986,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, True, Liquid.WATER, False, False)] = \ -StandardVolumeFilter_96COREHead_Water_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(300, True, True, True, Liquid.WATER, False, False)] = ( + StandardVolumeFilter_96COREHead_Water_DispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 304.0, 0.0: 0.0, 100.0: 105.3, 10.0: 11.9, 200.0: 205.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7695,7 +9010,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -7715,8 +9030,9 @@ def get_vantage_liquid_class(**kwargs): # 20 (12 Aliquots) 2.53 -2.97 # 50 ( 4 Aliquots) 0.84 -2.57 # -vantage_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = \ -StandardVolumeFilter_DMSO_AliquotDispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = ( + StandardVolumeFilter_DMSO_AliquotDispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7734,13 +9050,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = \ -StandardVolumeFilter_DMSO_DispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = ( + StandardVolumeFilter_DMSO_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 304.6, 50.0: 51.1, 0.0: 0.0, 20.0: 20.7, 100.0: 101.8, 200.0: 203.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7758,12 +9075,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, True, Liquid.DMSO, True, True)] = \ -StandardVolumeFilter_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.DMSO, True, True)] = ( + StandardVolumeFilter_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 304.6, 50.0: 51.1, 0.0: 0.0, 100.0: 101.8, 20.0: 20.7, 200.0: 203.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7781,12 +9099,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = \ -StandardVolumeFilter_DMSO_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.DMSO, True, False)] = ( + StandardVolumeFilter_DMSO_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 315.6, 0.0: 0.0, 100.0: 112.8, 20.0: 29.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7804,13 +9123,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0 -) - - -vantage_mapping[(300, False, True, True, Liquid.DMSO, False, False)] = \ -StandardVolumeFilter_DMSO_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 308.8, 5.0: 6.6, 50.0: 52.9, 0.0: 0.0, 1.0: 1.8, 20.0: 22.1, 100.0: 103.8, 2.0: 3.0, 10.0: 11.9, 200.0: 205.0}, + dispense_stop_back_volume=10.0, +) + + +vantage_mapping[(300, False, True, True, Liquid.DMSO, False, False)] = ( + StandardVolumeFilter_DMSO_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 308.8, + 5.0: 6.6, + 50.0: 52.9, + 0.0: 0.0, + 1.0: 1.8, + 20.0: 22.1, + 100.0: 103.8, + 2.0: 3.0, + 10.0: 11.9, + 200.0: 205.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -7827,13 +9158,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(300, False, True, True, Liquid.DMSO, False, True)] = \ -StandardVolumeFilter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 308.8, 5.0: 6.6, 50.0: 52.9, 0.0: 0.0, 1.0: 1.8, 20.0: 22.1, 100.0: 103.8, 2.0: 3.0, 10.0: 11.9, 200.0: 205.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(300, False, True, True, Liquid.DMSO, False, True)] = ( + StandardVolumeFilter_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 308.8, + 5.0: 6.6, + 50.0: 52.9, + 0.0: 0.0, + 1.0: 1.8, + 20.0: 22.1, + 100.0: 103.8, + 2.0: 3.0, + 10.0: 11.9, + 200.0: 205.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -7850,12 +9193,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, True, Liquid.DMSO, False, False)] = \ -StandardVolumeFilter_DMSO_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.DMSO, False, False)] = ( + StandardVolumeFilter_DMSO_DispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 306.8, 5.0: 6.4, 50.0: 52.9, 0.0: 0.0, 100.0: 103.8, 20.0: 22.1, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -7873,13 +9217,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 100, Stop back volume=0 -vantage_mapping[(300, False, True, True, Liquid.ETHANOL, True, False)] = \ -StandardVolumeFilter_EtOH_DispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.ETHANOL, True, False)] = ( + StandardVolumeFilter_EtOH_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 310.2, 50.0: 55.8, 0.0: 0.0, 20.0: 24.6, 100.0: 107.5, 200.0: 209.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7897,12 +9242,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, True, Liquid.ETHANOL, True, True)] = \ -StandardVolumeFilter_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.ETHANOL, True, True)] = ( + StandardVolumeFilter_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 310.2, 50.0: 55.8, 0.0: 0.0, 100.0: 107.5, 20.0: 24.6, 200.0: 209.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7920,12 +9266,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, True, Liquid.ETHANOL, True, False)] = \ -StandardVolumeFilter_EtOH_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.ETHANOL, True, False)] = ( + StandardVolumeFilter_EtOH_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 317.2, 0.0: 0.0, 100.0: 110.5, 20.0: 25.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -7943,13 +9290,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=5.0 + dispense_stop_back_volume=5.0, ) # V1.1: Set mix flow rate to 20, dispense settling time=0, Stop back volume=0 -vantage_mapping[(300, False, True, True, Liquid.GLYCERIN, True, False)] = \ -StandardVolumeFilter_Glycerin_DispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.GLYCERIN, True, False)] = ( + StandardVolumeFilter_Glycerin_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 309.0, 50.0: 53.6, 0.0: 0.0, 20.0: 22.3, 100.0: 104.9, 200.0: 207.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=20.0, @@ -7967,13 +9315,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 20, dispense settling time=0, Stop back volume=0 -vantage_mapping[(300, False, True, True, Liquid.GLYCERIN80, True, True)] = \ -StandardVolumeFilter_Glycerin_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.GLYCERIN80, True, True)] = ( + StandardVolumeFilter_Glycerin_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 309.0, 50.0: 53.6, 0.0: 0.0, 100.0: 104.9, 20.0: 22.3, 200.0: 207.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=20.0, @@ -7991,14 +9340,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 10 -vantage_mapping[(300, False, True, True, Liquid.GLYCERIN, False, False)] = \ -StandardVolumeFilter_Glycerin_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 307.9, 5.0: 6.5, 50.0: 53.6, 0.0: 0.0, 20.0: 22.5, 100.0: 105.7, 2.0: 3.2, 10.0: 12.0, 200.0: 207.0}, +vantage_mapping[(300, False, True, True, Liquid.GLYCERIN, False, False)] = ( + StandardVolumeFilter_Glycerin_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 307.9, + 5.0: 6.5, + 50.0: 53.6, + 0.0: 0.0, + 20.0: 22.5, + 100.0: 105.7, + 2.0: 3.2, + 10.0: 12.0, + 200.0: 207.0, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -8015,13 +9375,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(300, False, True, True, Liquid.GLYCERIN80, False, True)] = \ -StandardVolumeFilter_Glycerin_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 307.9, 5.0: 6.5, 50.0: 53.6, 0.0: 0.0, 100.0: 105.7, 20.0: 22.5, 200.0: 207.0, 10.0: 12.0, 2.0: 3.2}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(300, False, True, True, Liquid.GLYCERIN80, False, True)] = ( + StandardVolumeFilter_Glycerin_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 307.9, + 5.0: 6.5, + 50.0: 53.6, + 0.0: 0.0, + 100.0: 105.7, + 20.0: 22.5, + 200.0: 207.0, + 10.0: 12.0, + 2.0: 3.2, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -8038,12 +9409,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, True, Liquid.GLYCERIN80, False, False)] = \ -StandardVolumeFilter_Glycerin_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.GLYCERIN80, False, False)] = ( + StandardVolumeFilter_Glycerin_DispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 307.9, 5.0: 6.1, 0.0: 0.0, 100.0: 104.7, 200.0: 207.0, 10.0: 11.5}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, @@ -8061,13 +9433,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = \ -StandardVolumeFilter_Serum_AliquotDispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = ( + StandardVolumeFilter_Serum_AliquotDispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8085,13 +9458,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = \ -StandardVolumeFilter_Serum_AliquotJet = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = ( + StandardVolumeFilter_Serum_AliquotJet +) = HamiltonLiquidClass( curve={300.0: 300.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8109,13 +9483,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = \ -StandardVolumeFilter_Serum_DispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = ( + StandardVolumeFilter_Serum_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 20.0: 23.2, 100.0: 108.1, 200.0: 212.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8133,12 +9508,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, True, Liquid.SERUM, True, True)] = \ -StandardVolumeFilter_Serum_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.SERUM, True, True)] = ( + StandardVolumeFilter_Serum_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 100.0: 108.1, 20.0: 23.2, 200.0: 212.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8156,12 +9532,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = \ -StandardVolumeFilter_Serum_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.SERUM, True, False)] = ( + StandardVolumeFilter_Serum_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 315.2, 0.0: 0.0, 100.0: 111.5, 20.0: 29.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8179,13 +9556,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=5.0 + dispense_stop_back_volume=5.0, ) -vantage_mapping[(300, False, True, True, Liquid.SERUM, False, False)] = \ -StandardVolumeFilter_Serum_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 313.4, 5.0: 6.3, 50.0: 54.9, 0.0: 0.0, 20.0: 23.0, 100.0: 107.1, 2.0: 2.6, 10.0: 12.0, 200.0: 210.5}, +vantage_mapping[(300, False, True, True, Liquid.SERUM, False, False)] = ( + StandardVolumeFilter_Serum_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 313.4, + 5.0: 6.3, + 50.0: 54.9, + 0.0: 0.0, + 20.0: 23.0, + 100.0: 107.1, + 2.0: 2.6, + 10.0: 12.0, + 200.0: 210.5, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -8202,12 +9590,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, True, Liquid.SERUM, False, False)] = \ -StandardVolumeFilter_Serum_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.SERUM, False, False)] = ( + StandardVolumeFilter_Serum_DispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 313.4, 0.0: 0.0, 100.0: 109.1, 10.0: 12.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -8225,13 +9614,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, True, Liquid.WATER, True, False)] = \ -StandardVolumeFilter_Water_AliquotDispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.WATER, True, False)] = ( + StandardVolumeFilter_Water_AliquotDispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8249,13 +9639,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, True, Liquid.WATER, True, False)] = \ -StandardVolumeFilter_Water_AliquotJet = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.WATER, True, False)] = ( + StandardVolumeFilter_Water_AliquotJet +) = HamiltonLiquidClass( curve={300.0: 300.0, 0.0: 0.0, 30.0: 30.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8273,13 +9664,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=0.3, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, True, Liquid.WATER, True, False)] = \ -StandardVolumeFilter_Water_DispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.WATER, True, False)] = ( + StandardVolumeFilter_Water_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 313.5, 50.0: 55.1, 0.0: 0.0, 20.0: 23.2, 100.0: 107.2, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8297,12 +9689,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, True, Liquid.WATER, True, True)] = \ -StandardVolumeFilter_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.WATER, True, True)] = ( + StandardVolumeFilter_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 313.5, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8320,12 +9713,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, True, Liquid.WATER, True, False)] = \ -StandardVolumeFilter_Water_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, True, Liquid.WATER, True, False)] = ( + StandardVolumeFilter_Water_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 110.2, 20.0: 27.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8343,14 +9737,27 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, True, Liquid.WATER, False, False)] = \ -StandardVolumeFilter_Water_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 313.5, 5.0: 6.3, 0.5: 0.9, 50.0: 55.1, 0.0: 0.0, 1.0: 1.6, 20.0: 23.2, 100.0: 107.2, 2.0: 2.8, 10.0: 11.9, 200.0: 211.0}, +vantage_mapping[(300, False, True, True, Liquid.WATER, False, False)] = ( + StandardVolumeFilter_Water_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 313.5, + 5.0: 6.3, + 0.5: 0.9, + 50.0: 55.1, + 0.0: 0.0, + 1.0: 1.6, + 20.0: 23.2, + 100.0: 107.2, + 2.0: 2.8, + 10.0: 11.9, + 200.0: 211.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -8367,13 +9774,26 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, True, Liquid.WATER, False, True)] = \ -StandardVolumeFilter_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 313.5, 5.0: 6.3, 0.5: 0.9, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 1.0: 1.6, 200.0: 211.0, 10.0: 11.9, 2.0: 2.8}, +vantage_mapping[(300, False, True, True, Liquid.WATER, False, True)] = ( + StandardVolumeFilter_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 313.5, + 5.0: 6.3, + 0.5: 0.9, + 50.0: 55.1, + 0.0: 0.0, + 100.0: 107.2, + 20.0: 23.2, + 1.0: 1.6, + 200.0: 211.0, + 10.0: 11.9, + 2.0: 2.8, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -8390,13 +9810,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, True, Liquid.WATER, False, False)] = \ -StandardVolumeFilter_Water_DispenseSurface_Part = HamiltonLiquidClass( - curve={300.0: 313.5, 5.0: 6.5, 50.0: 55.1, 0.0: 0.0, 20.0: 23.2, 100.0: 107.2, 10.0: 11.9, 200.0: 211.0}, +vantage_mapping[(300, False, True, True, Liquid.WATER, False, False)] = ( + StandardVolumeFilter_Water_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 300.0: 313.5, + 5.0: 6.5, + 50.0: 55.1, + 0.0: 0.0, + 20.0: 23.2, + 100.0: 107.2, + 10.0: 11.9, + 200.0: 211.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -8413,7 +9843,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -8438,8 +9868,9 @@ def get_vantage_liquid_class(**kwargs): # 200 0.56 0.07 # 300 0.54 1.12 # -vantage_mapping[(300, False, True, False, Liquid.METHANOL, True, False)] = \ -StandardVolumeMeOHDispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.METHANOL, True, False)] = ( + StandardVolumeMeOHDispenseJet +) = HamiltonLiquidClass( curve={300.0: 336.0, 50.0: 63.0, 0.0: 0.0, 100.0: 119.5, 20.0: 28.3, 200.0: 230.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=30.0, @@ -8457,7 +9888,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -8484,9 +9915,19 @@ def get_vantage_liquid_class(**kwargs): # 200 0.51 0.59 # 300 0.81 0.22 # -vantage_mapping[(300, False, True, False, Liquid.METHANOL, False, False)] = \ -StandardVolumeMeOHDispenseSurface = HamiltonLiquidClass( - curve={300.0: 310.2, 5.0: 8.0, 50.0: 55.8, 0.0: 0.0, 100.0: 107.5, 20.0: 24.6, 200.0: 209.2, 10.0: 14.0}, +vantage_mapping[(300, False, True, False, Liquid.METHANOL, False, False)] = ( + StandardVolumeMeOHDispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 310.2, + 5.0: 8.0, + 50.0: 55.8, + 0.0: 0.0, + 100.0: 107.5, + 20.0: 24.6, + 200.0: 209.2, + 10.0: 14.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=30.0, aspiration_air_transport_volume=10.0, @@ -8503,7 +9944,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -8524,8 +9965,9 @@ def get_vantage_liquid_class(**kwargs): # 200 0.29 0.17 # 300 0.16 0.80 # -vantage_mapping[(300, False, True, False, Liquid.OCTANOL, True, False)] = \ -StandardVolumeOctanol100DispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.OCTANOL, True, False)] = ( + StandardVolumeOctanol100DispenseJet +) = HamiltonLiquidClass( curve={300.0: 319.3, 50.0: 56.6, 0.0: 0.0, 100.0: 109.9, 20.0: 23.8, 200.0: 216.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8543,7 +9985,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -8568,9 +10010,21 @@ def get_vantage_liquid_class(**kwargs): # 200 0.02 0.12 # 300 0.11 0.29 # -vantage_mapping[(300, False, True, False, Liquid.OCTANOL, False, False)] = \ -StandardVolumeOctanol100DispenseSurface = HamiltonLiquidClass( - curve={300.0: 315.0, 5.0: 6.6, 50.0: 55.9, 0.0: 0.0, 100.0: 106.8, 20.0: 22.1, 1.0: 0.8, 200.0: 212.0, 10.0: 12.6, 2.0: 3.7}, +vantage_mapping[(300, False, True, False, Liquid.OCTANOL, False, False)] = ( + StandardVolumeOctanol100DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 315.0, + 5.0: 6.6, + 50.0: 55.9, + 0.0: 0.0, + 100.0: 106.8, + 20.0: 22.1, + 1.0: 0.8, + 200.0: 212.0, + 10.0: 12.6, + 2.0: 3.7, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -8587,7 +10041,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -8606,9 +10060,20 @@ def get_vantage_liquid_class(**kwargs): # 10 1.99 4.39 # # -vantage_mapping[(300, False, True, False, Liquid.PBS_BUFFER, False, False)] = \ -StandardVolumePBSDispenseSurface = HamiltonLiquidClass( - curve={300.0: 313.5, 5.0: 7.5, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 1.0: 2.6, 200.0: 211.0, 10.0: 12.8}, +vantage_mapping[(300, False, True, False, Liquid.PBS_BUFFER, False, False)] = ( + StandardVolumePBSDispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 313.5, + 5.0: 7.5, + 50.0: 55.1, + 0.0: 0.0, + 100.0: 107.2, + 20.0: 23.2, + 1.0: 2.6, + 200.0: 211.0, + 10.0: 12.8, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -8625,7 +10090,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -8645,8 +10110,9 @@ def get_vantage_liquid_class(**kwargs): # 100 0.08 1.09 # 200 0.09 0.91 # -vantage_mapping[(300, False, True, False, Liquid.PLASMA, True, False)] = \ -StandardVolumePlasmaDispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.PLASMA, True, False)] = ( + StandardVolumePlasmaDispenseJet +) = HamiltonLiquidClass( curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 100.0: 108.1, 20.0: 23.2, 200.0: 212.1, 10.0: 12.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -8664,12 +10130,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.PLASMA, True, True)] = \ -StandardVolumePlasmaDispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.PLASMA, True, True)] = ( + StandardVolumePlasmaDispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 20.0: 23.2, 100.0: 108.1, 200.0: 212.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8687,12 +10154,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.PLASMA, True, False)] = \ -StandardVolumePlasmaDispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.PLASMA, True, False)] = ( + StandardVolumePlasmaDispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 315.2, 0.0: 0.0, 20.0: 29.2, 100.0: 111.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8710,7 +10178,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=5.0 + dispense_stop_back_volume=5.0, ) @@ -8731,9 +10199,20 @@ def get_vantage_liquid_class(**kwargs): # 60 0.55 2.06 # # -vantage_mapping[(300, False, True, False, Liquid.PLASMA, False, False)] = \ -StandardVolumePlasmaDispenseSurface = HamiltonLiquidClass( - curve={300.0: 313.4, 5.0: 6.3, 50.0: 54.9, 0.0: 0.0, 100.0: 107.1, 20.0: 23.0, 200.0: 210.5, 10.0: 12.0, 2.0: 2.6}, +vantage_mapping[(300, False, True, False, Liquid.PLASMA, False, False)] = ( + StandardVolumePlasmaDispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 313.4, + 5.0: 6.3, + 50.0: 54.9, + 0.0: 0.0, + 100.0: 107.1, + 20.0: 23.0, + 200.0: 210.5, + 10.0: 12.0, + 2.0: 2.6, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -8750,13 +10229,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.PLASMA, False, True)] = \ -StandardVolumePlasmaDispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 313.4, 5.0: 6.3, 50.0: 54.9, 0.0: 0.0, 20.0: 23.0, 100.0: 107.1, 2.0: 2.6, 10.0: 12.0, 200.0: 210.5}, +vantage_mapping[(300, False, True, False, Liquid.PLASMA, False, True)] = ( + StandardVolumePlasmaDispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 313.4, + 5.0: 6.3, + 50.0: 54.9, + 0.0: 0.0, + 20.0: 23.0, + 100.0: 107.1, + 2.0: 2.6, + 10.0: 12.0, + 200.0: 210.5, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -8773,12 +10263,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.PLASMA, False, False)] = \ -StandardVolumePlasmaDispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.PLASMA, False, False)] = ( + StandardVolumePlasmaDispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 313.4, 5.0: 6.8, 0.0: 0.0, 100.0: 109.1, 10.0: 12.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -8796,12 +10287,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ -StandardVolume_96COREHead1000ul_DMSO_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = ( + StandardVolume_96COREHead1000ul_DMSO_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 150.0: 150.0, 50.0: 50.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8819,12 +10311,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=20.0 + dispense_stop_back_volume=20.0, ) -vantage_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ -StandardVolume_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = ( + StandardVolume_96COREHead1000ul_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 302.5, 0.0: 0.0, 100.0: 101.0, 20.0: 20.4, 200.0: 201.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8842,12 +10335,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ -StandardVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = ( + StandardVolume_96COREHead1000ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 306.0, 0.0: 0.0, 100.0: 104.3, 200.0: 205.0, 10.0: 12.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8865,12 +10359,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ -StandardVolume_96COREHead1000ul_Water_DispenseJet_Aliquot = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( + StandardVolume_96COREHead1000ul_Water_DispenseJet_Aliquot +) = HamiltonLiquidClass( curve={300.0: 300.0, 150.0: 150.0, 50.0: 50.0, 0.0: 0.0, 20.0: 20.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8888,12 +10383,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ -StandardVolume_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( + StandardVolume_96COREHead1000ul_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 200.0: 207.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8911,12 +10407,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ -StandardVolume_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( + StandardVolume_96COREHead1000ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 210.0, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8934,12 +10431,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ -StandardVolume_96COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.DMSO, True, True)] = ( + StandardVolume_96COREHead_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 303.5, 0.0: 0.0, 100.0: 101.8, 10.0: 10.2, 200.0: 200.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8957,12 +10455,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ -StandardVolume_96COREHead_DMSO_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.DMSO, True, False)] = ( + StandardVolume_96COREHead_DMSO_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 306.0, 0.0: 0.0, 100.0: 105.6, 10.0: 12.2, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -8980,12 +10479,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -vantage_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ -StandardVolume_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.DMSO, False, True)] = ( + StandardVolume_96COREHead_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 303.0, 0.0: 0.0, 100.0: 101.3, 10.0: 10.6, 200.0: 202.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9003,12 +10503,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, False, Liquid.DMSO, False, False)] = \ -StandardVolume_96COREHead_DMSO_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.DMSO, False, False)] = ( + StandardVolume_96COREHead_DMSO_DispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 303.0, 0.0: 0.0, 100.0: 101.3, 10.0: 10.1, 200.0: 202.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9026,12 +10527,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ -StandardVolume_96COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( + StandardVolume_96COREHead_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 309.0, 0.0: 0.0, 20.0: 22.3, 100.0: 104.2, 10.0: 11.9, 200.0: 207.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9049,12 +10551,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ -StandardVolume_96COREHead_Water_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( + StandardVolume_96COREHead_Water_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 309.0, 0.0: 0.0, 20.0: 22.3, 100.0: 104.2, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9072,12 +10575,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) -vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ -StandardVolume_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( + StandardVolume_96COREHead_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={300.0: 306.3, 0.0: 0.0, 100.0: 104.5, 10.0: 11.9, 200.0: 205.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9095,12 +10599,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ -StandardVolume_96COREHead_Water_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, False, False)] = ( + StandardVolume_96COREHead_Water_DispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 304.0, 0.0: 0.0, 100.0: 105.3, 10.0: 11.9, 200.0: 205.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9118,14 +10623,27 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # Liquid class for wash standard volume tips with CO-RE 96 Head in CO-RE 96 Head Washer. -vantage_mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ -StandardVolume_Core96Washer_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 330.0, 5.0: 6.3, 0.5: 0.9, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 1.0: 1.6, 200.0: 211.0, 10.0: 11.9, 2.0: 2.8}, +vantage_mapping[(300, True, True, False, Liquid.WATER, False, False)] = ( + StandardVolume_Core96Washer_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 330.0, + 5.0: 6.3, + 0.5: 0.9, + 50.0: 55.1, + 0.0: 0.0, + 100.0: 107.2, + 20.0: 23.2, + 1.0: 1.6, + 200.0: 211.0, + 10.0: 11.9, + 2.0: 2.8, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=150.0, aspiration_air_transport_volume=0.0, @@ -9142,7 +10660,7 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=5.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) @@ -9162,8 +10680,9 @@ def get_vantage_liquid_class(**kwargs): # 20 (12 Aliquots) 2.53 -2.97 # 50 ( 4 Aliquots) 0.84 -2.57 # -vantage_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = \ -StandardVolume_DMSO_AliquotDispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = ( + StandardVolume_DMSO_AliquotDispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9181,13 +10700,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = \ -StandardVolume_DMSO_DispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = ( + StandardVolume_DMSO_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 304.6, 350.0: 355.2, 50.0: 51.1, 0.0: 0.0, 100.0: 101.8, 20.0: 20.7, 200.0: 203.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9205,12 +10725,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.DMSO, True, True)] = \ -StandardVolume_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.DMSO, True, True)] = ( + StandardVolume_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 304.6, 50.0: 51.1, 0.0: 0.0, 20.0: 20.7, 100.0: 101.8, 200.0: 203.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9228,12 +10749,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = \ -StandardVolume_DMSO_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.DMSO, True, False)] = ( + StandardVolume_DMSO_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 320.0, 0.0: 0.0, 20.0: 30.5, 100.0: 116.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9251,13 +10773,26 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 -) - - -vantage_mapping[(300, False, True, False, Liquid.DMSO, False, False)] = \ -StandardVolume_DMSO_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 308.8, 5.0: 6.6, 50.0: 52.9, 350.0: 360.5, 0.0: 0.0, 1.0: 1.8, 20.0: 22.1, 100.0: 103.8, 2.0: 3.0, 10.0: 11.9, 200.0: 205.0}, + dispense_stop_back_volume=10.0, +) + + +vantage_mapping[(300, False, True, False, Liquid.DMSO, False, False)] = ( + StandardVolume_DMSO_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 308.8, + 5.0: 6.6, + 50.0: 52.9, + 350.0: 360.5, + 0.0: 0.0, + 1.0: 1.8, + 20.0: 22.1, + 100.0: 103.8, + 2.0: 3.0, + 10.0: 11.9, + 200.0: 205.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -9274,13 +10809,25 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(300, False, True, False, Liquid.DMSO, False, True)] = \ -StandardVolume_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 308.8, 5.0: 6.6, 50.0: 52.9, 0.0: 0.0, 1.0: 1.8, 20.0: 22.1, 100.0: 103.8, 2.0: 3.0, 10.0: 11.9, 200.0: 205.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(300, False, True, False, Liquid.DMSO, False, True)] = ( + StandardVolume_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 308.8, + 5.0: 6.6, + 50.0: 52.9, + 0.0: 0.0, + 1.0: 1.8, + 20.0: 22.1, + 100.0: 103.8, + 2.0: 3.0, + 10.0: 11.9, + 200.0: 205.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -9297,13 +10844,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.DMSO, False, False)] = \ -StandardVolume_DMSO_DispenseSurface_Part = HamiltonLiquidClass( - curve={300.0: 308.8, 5.0: 6.4, 50.0: 52.9, 0.0: 0.0, 20.0: 22.1, 100.0: 103.8, 10.0: 11.9, 200.0: 205.0}, +vantage_mapping[(300, False, True, False, Liquid.DMSO, False, False)] = ( + StandardVolume_DMSO_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 300.0: 308.8, + 5.0: 6.4, + 50.0: 52.9, + 0.0: 0.0, + 20.0: 22.1, + 100.0: 103.8, + 10.0: 11.9, + 200.0: 205.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=0.0, @@ -9320,13 +10877,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 100, stop back volume = 0 -vantage_mapping[(300, False, True, False, Liquid.ETHANOL, True, False)] = \ -StandardVolume_EtOH_DispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.ETHANOL, True, False)] = ( + StandardVolume_EtOH_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 310.2, 350.0: 360.5, 50.0: 55.8, 0.0: 0.0, 100.0: 107.5, 20.0: 24.6, 200.0: 209.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9344,12 +10902,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.ETHANOL, True, True)] = \ -StandardVolume_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.ETHANOL, True, True)] = ( + StandardVolume_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 310.2, 50.0: 55.8, 0.0: 0.0, 20.0: 24.6, 100.0: 107.5, 200.0: 209.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9367,12 +10926,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.ETHANOL, True, False)] = \ -StandardVolume_EtOH_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.ETHANOL, True, False)] = ( + StandardVolume_EtOH_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 317.2, 0.0: 0.0, 20.0: 25.6, 100.0: 110.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9390,13 +10950,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=5.0 + dispense_stop_back_volume=5.0, ) # V1.1: Set mix flow rate to 20, dispense settling time=0, stop back volume = 0 -vantage_mapping[(300, False, True, False, Liquid.GLYCERIN, True, False)] = \ -StandardVolume_Glycerin_DispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.GLYCERIN, True, False)] = ( + StandardVolume_Glycerin_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 309.0, 350.0: 360.0, 50.0: 53.6, 0.0: 0.0, 100.0: 104.9, 20.0: 22.3, 200.0: 207.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=20.0, @@ -9414,13 +10975,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 20, dispense settling time=0, stop back volume = 0 -vantage_mapping[(300, False, True, False, Liquid.GLYCERIN80, True, True)] = \ -StandardVolume_Glycerin_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.GLYCERIN80, True, True)] = ( + StandardVolume_Glycerin_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 309.0, 50.0: 53.6, 0.0: 0.0, 100.0: 104.9, 20.0: 22.3, 200.0: 207.2}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=20.0, @@ -9438,14 +11000,26 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=20.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 10 -vantage_mapping[(300, False, True, False, Liquid.GLYCERIN, False, False)] = \ -StandardVolume_Glycerin_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 307.9, 5.0: 6.5, 350.0: 358.4, 50.0: 53.6, 0.0: 0.0, 100.0: 105.7, 20.0: 22.5, 200.0: 207.0, 10.0: 12.0, 2.0: 3.2}, +vantage_mapping[(300, False, True, False, Liquid.GLYCERIN, False, False)] = ( + StandardVolume_Glycerin_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 307.9, + 5.0: 6.5, + 350.0: 358.4, + 50.0: 53.6, + 0.0: 0.0, + 100.0: 105.7, + 20.0: 22.5, + 200.0: 207.0, + 10.0: 12.0, + 2.0: 3.2, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -9462,13 +11036,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(300, False, True, False, Liquid.GLYCERIN80, False, True)] = \ -StandardVolume_Glycerin_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 307.9, 5.0: 6.5, 50.0: 53.6, 0.0: 0.0, 100.0: 105.7, 20.0: 22.5, 200.0: 207.0, 10.0: 12.0, 2.0: 3.2}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(300, False, True, False, Liquid.GLYCERIN80, False, True)] = ( + StandardVolume_Glycerin_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 307.9, + 5.0: 6.5, + 50.0: 53.6, + 0.0: 0.0, + 100.0: 105.7, + 20.0: 22.5, + 200.0: 207.0, + 10.0: 12.0, + 2.0: 3.2, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -9485,13 +11070,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 -) - - -vantage_mapping[(300, False, True, False, Liquid.GLYCERIN80, False, False)] = \ -StandardVolume_Glycerin_DispenseSurface_Part = HamiltonLiquidClass( - curve={300.0: 307.9, 5.0: 6.2, 50.0: 53.6, 0.0: 0.0, 100.0: 105.7, 20.0: 22.5, 200.0: 207.0, 10.0: 12.0}, + dispense_stop_back_volume=0.0, +) + + +vantage_mapping[(300, False, True, False, Liquid.GLYCERIN80, False, False)] = ( + StandardVolume_Glycerin_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 300.0: 307.9, + 5.0: 6.2, + 50.0: 53.6, + 0.0: 0.0, + 100.0: 105.7, + 20.0: 22.5, + 200.0: 207.0, + 10.0: 12.0, + }, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=10.0, aspiration_air_transport_volume=0.0, @@ -9508,13 +11103,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=2.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = \ -StandardVolume_Serum_AliquotDispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = ( + StandardVolume_Serum_AliquotDispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9532,13 +11128,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = \ -StandardVolume_Serum_AliquotJet = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = ( + StandardVolume_Serum_AliquotJet +) = HamiltonLiquidClass( curve={350.0: 350.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9556,13 +11153,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=250.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = \ -StandardVolume_Serum_DispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = ( + StandardVolume_Serum_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 100.0: 108.1, 20.0: 23.2, 200.0: 212.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9580,12 +11178,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.SERUM, True, True)] = \ -StandardVolume_Serum_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.SERUM, True, True)] = ( + StandardVolume_Serum_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 315.2, 50.0: 55.6, 0.0: 0.0, 20.0: 23.2, 100.0: 108.1, 200.0: 212.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9603,12 +11202,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = \ -StandardVolume_Serum_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.SERUM, True, False)] = ( + StandardVolume_Serum_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 315.2, 0.0: 0.0, 20.0: 29.2, 100.0: 111.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9626,13 +11226,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=5.0 + dispense_stop_back_volume=5.0, ) -vantage_mapping[(300, False, True, False, Liquid.SERUM, False, False)] = \ -StandardVolume_Serum_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 313.4, 5.0: 6.3, 50.0: 54.9, 0.0: 0.0, 20.0: 23.0, 100.0: 107.1, 2.0: 2.6, 10.0: 12.0, 200.0: 210.5}, +vantage_mapping[(300, False, True, False, Liquid.SERUM, False, False)] = ( + StandardVolume_Serum_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 313.4, + 5.0: 6.3, + 50.0: 54.9, + 0.0: 0.0, + 20.0: 23.0, + 100.0: 107.1, + 2.0: 2.6, + 10.0: 12.0, + 200.0: 210.5, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -9649,13 +11260,24 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.SERUM, False, True)] = \ -StandardVolume_Serum_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 313.4, 5.0: 6.3, 50.0: 54.9, 0.0: 0.0, 20.0: 23.0, 100.0: 107.1, 2.0: 2.6, 10.0: 12.0, 200.0: 210.5}, +vantage_mapping[(300, False, True, False, Liquid.SERUM, False, True)] = ( + StandardVolume_Serum_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 313.4, + 5.0: 6.3, + 50.0: 54.9, + 0.0: 0.0, + 20.0: 23.0, + 100.0: 107.1, + 2.0: 2.6, + 10.0: 12.0, + 200.0: 210.5, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, aspiration_air_transport_volume=5.0, @@ -9672,12 +11294,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.SERUM, False, False)] = \ -StandardVolume_Serum_DispenseSurface_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.SERUM, False, False)] = ( + StandardVolume_Serum_DispenseSurface_Part +) = HamiltonLiquidClass( curve={300.0: 313.4, 5.0: 6.8, 0.0: 0.0, 100.0: 109.1, 10.0: 12.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -9695,13 +11318,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=10.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, False, Liquid.WATER, True, False)] = \ -StandardVolume_Water_AliquotDispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.WATER, True, False)] = ( + StandardVolume_Water_AliquotDispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 300.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9719,13 +11343,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, False, Liquid.WATER, True, False)] = \ -StandardVolume_Water_AliquotJet = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.WATER, True, False)] = ( + StandardVolume_Water_AliquotJet +) = HamiltonLiquidClass( curve={350.0: 350.0, 30.0: 30.0, 0.0: 0.0, 20.0: 20.0, 10.0: 10.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9743,13 +11368,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=0.3, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, False, Liquid.WATER, True, False)] = \ -StandardVolume_Water_DispenseJet = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.WATER, True, False)] = ( + StandardVolume_Water_DispenseJet +) = HamiltonLiquidClass( curve={300.0: 313.5, 350.0: 364.3, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9767,12 +11393,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ -StandardVolume_Water_DispenseJetEmpty96Head = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, True, True)] = ( + StandardVolume_Water_DispenseJetEmpty96Head +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 205.3, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9790,12 +11417,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ -StandardVolume_Water_DispenseJetPart96Head = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, True, False)] = ( + StandardVolume_Water_DispenseJetPart96Head +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 205.3, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9813,12 +11441,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.WATER, True, True)] = \ -StandardVolume_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.WATER, True, True)] = ( + StandardVolume_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={300.0: 313.5, 50.0: 55.1, 0.0: 0.0, 20.0: 23.2, 100.0: 107.2, 200.0: 211.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9836,12 +11465,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.WATER, True, False)] = \ -StandardVolume_Water_DispenseJet_Part = HamiltonLiquidClass( +vantage_mapping[(300, False, True, False, Liquid.WATER, True, False)] = ( + StandardVolume_Water_DispenseJet_Part +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 20.0: 28.2, 100.0: 111.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9859,14 +11489,28 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=150.0, - dispense_stop_back_volume=10.0 + dispense_stop_back_volume=10.0, ) # V1.1: Set mix flow rate to 100 -vantage_mapping[(300, False, True, False, Liquid.WATER, False, False)] = \ -StandardVolume_Water_DispenseSurface = HamiltonLiquidClass( - curve={300.0: 313.5, 5.0: 6.3, 0.5: 0.9, 350.0: 364.3, 50.0: 55.1, 0.0: 0.0, 100.0: 107.2, 20.0: 23.2, 1.0: 1.6, 200.0: 211.0, 10.0: 11.9, 2.0: 2.8}, +vantage_mapping[(300, False, True, False, Liquid.WATER, False, False)] = ( + StandardVolume_Water_DispenseSurface +) = HamiltonLiquidClass( + curve={ + 300.0: 313.5, + 5.0: 6.3, + 0.5: 0.9, + 350.0: 364.3, + 50.0: 55.1, + 0.0: 0.0, + 100.0: 107.2, + 20.0: 23.2, + 1.0: 1.6, + 200.0: 211.0, + 10.0: 11.9, + 2.0: 2.8, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -9883,12 +11527,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ -StandardVolume_Water_DispenseSurface96Head = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, False, False)] = ( + StandardVolume_Water_DispenseSurface96Head +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9906,12 +11551,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ -StandardVolume_Water_DispenseSurfaceEmpty96Head = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, False, True)] = ( + StandardVolume_Water_DispenseSurfaceEmpty96Head +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 205.7, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9929,12 +11575,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ -StandardVolume_Water_DispenseSurfacePart96Head = HamiltonLiquidClass( +vantage_mapping[(300, True, True, False, Liquid.WATER, False, False)] = ( + StandardVolume_Water_DispenseSurfacePart96Head +) = HamiltonLiquidClass( curve={300.0: 313.5, 0.0: 0.0, 100.0: 107.2, 200.0: 205.7, 10.0: 11.9}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -9952,13 +11599,26 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.WATER, False, True)] = \ -StandardVolume_Water_DispenseSurface_Empty = HamiltonLiquidClass( - curve={300.0: 313.5, 5.0: 6.3, 0.5: 0.9, 50.0: 55.1, 0.0: 0.0, 1.0: 1.6, 20.0: 23.2, 100.0: 107.2, 2.0: 2.8, 10.0: 11.9, 200.0: 211.0}, +vantage_mapping[(300, False, True, False, Liquid.WATER, False, True)] = ( + StandardVolume_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( + curve={ + 300.0: 313.5, + 5.0: 6.3, + 0.5: 0.9, + 50.0: 55.1, + 0.0: 0.0, + 1.0: 1.6, + 20.0: 23.2, + 100.0: 107.2, + 2.0: 2.8, + 10.0: 11.9, + 200.0: 211.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=5.0, @@ -9975,13 +11635,23 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(300, False, True, False, Liquid.WATER, False, False)] = \ -StandardVolume_Water_DispenseSurface_Part = HamiltonLiquidClass( - curve={300.0: 313.5, 5.0: 6.8, 50.0: 55.1, 0.0: 0.0, 20.0: 23.2, 100.0: 107.2, 10.0: 12.3, 200.0: 211.0}, +vantage_mapping[(300, False, True, False, Liquid.WATER, False, False)] = ( + StandardVolume_Water_DispenseSurface_Part +) = HamiltonLiquidClass( + curve={ + 300.0: 313.5, + 5.0: 6.8, + 50.0: 55.1, + 0.0: 0.0, + 20.0: 23.2, + 100.0: 107.2, + 10.0: 12.3, + 200.0: 211.0, + }, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, aspiration_air_transport_volume=0.0, @@ -9998,12 +11668,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=1.0, dispense_stop_flow_rate=5.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, True, Liquid.DMSO, True, True)] = \ -Tip_50ulFilter_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, True, Liquid.DMSO, True, True)] = ( + Tip_50ulFilter_96COREHead1000ul_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 52.1, 30.0: 31.7, 0.0: 0.0, 20.0: 21.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10021,12 +11692,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, True, Liquid.DMSO, False, True)] = \ -Tip_50ulFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, True, Liquid.DMSO, False, True)] = ( + Tip_50ulFilter_96COREHead1000ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.4, 50.0: 52.1, 30.0: 31.5, 0.0: 0.0, 1.0: 0.7, 10.0: 10.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10044,12 +11716,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, True, Liquid.WATER, True, True)] = \ -Tip_50ulFilter_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, True, Liquid.WATER, True, True)] = ( + Tip_50ulFilter_96COREHead1000ul_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 54.2, 30.0: 33.2, 0.0: 0.0, 20.0: 22.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10067,12 +11740,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, True, Liquid.WATER, False, True)] = \ -Tip_50ulFilter_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, True, Liquid.WATER, False, True)] = ( + Tip_50ulFilter_96COREHead1000ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 50.0: 53.6, 30.0: 32.6, 0.0: 0.0, 1.0: 0.8, 10.0: 11.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10090,12 +11764,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, True, Liquid.DMSO, True, True)] = \ -Tip_50ulFilter_96COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, True, Liquid.DMSO, True, True)] = ( + Tip_50ulFilter_96COREHead_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 51.4, 0.0: 0.0, 30.0: 31.3, 20.0: 21.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10113,12 +11788,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, True, Liquid.DMSO, False, True)] = \ -Tip_50ulFilter_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, True, Liquid.DMSO, False, True)] = ( + Tip_50ulFilter_96COREHead_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 50.0: 51.1, 0.0: 0.0, 30.0: 31.0, 1.0: 0.8, 10.0: 10.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10136,12 +11812,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, True, Liquid.WATER, True, True)] = \ -Tip_50ulFilter_96COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, True, Liquid.WATER, True, True)] = ( + Tip_50ulFilter_96COREHead_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 54.0, 30.0: 33.0, 0.0: 0.0, 20.0: 22.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10159,12 +11836,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, True, Liquid.WATER, False, True)] = \ -Tip_50ulFilter_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, True, Liquid.WATER, False, True)] = ( + Tip_50ulFilter_96COREHead_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 50.0: 53.5, 30.0: 32.9, 0.0: 0.0, 1.0: 0.8, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10182,12 +11860,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, True, Liquid.DMSO, True, True)] = \ -Tip_50ulFilter_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.DMSO, True, True)] = ( + Tip_50ulFilter_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 52.5, 0.0: 0.0, 30.0: 31.4, 20.0: 21.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10205,12 +11884,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, True, Liquid.DMSO, False, True)] = \ -Tip_50ulFilter_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.DMSO, False, True)] = ( + Tip_50ulFilter_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.5, 50.0: 52.6, 0.0: 0.0, 30.0: 32.0, 1.0: 0.7, 10.0: 11.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10228,12 +11908,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, True, Liquid.ETHANOL, True, True)] = \ -Tip_50ulFilter_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.ETHANOL, True, True)] = ( + Tip_50ulFilter_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 57.5, 0.0: 0.0, 30.0: 35.8, 20.0: 24.4}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -10251,12 +11932,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, True, Liquid.ETHANOL, False, True)] = \ -Tip_50ulFilter_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.ETHANOL, False, True)] = ( + Tip_50ulFilter_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 6.5, 50.0: 54.1, 0.0: 0.0, 30.0: 33.8, 1.0: 1.9, 10.0: 12.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10274,12 +11956,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, True, Liquid.GLYCERIN80, False, True)] = \ -Tip_50ulFilter_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.GLYCERIN80, False, True)] = ( + Tip_50ulFilter_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.5, 50.0: 57.0, 0.0: 0.0, 30.0: 35.9, 1.0: 0.6, 10.0: 12.0}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -10297,12 +11980,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, True, Liquid.SERUM, True, True)] = \ -Tip_50ulFilter_Serum_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.SERUM, True, True)] = ( + Tip_50ulFilter_Serum_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 54.6, 30.0: 33.5, 0.0: 0.0, 20.0: 22.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10320,12 +12004,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, True, Liquid.SERUM, False, True)] = \ -Tip_50ulFilter_Serum_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.SERUM, False, True)] = ( + Tip_50ulFilter_Serum_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.7, 50.0: 54.9, 30.0: 33.0, 0.0: 0.0, 1.0: 0.7, 10.0: 11.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10343,12 +12028,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, True, Liquid.WATER, True, True)] = \ -Tip_50ulFilter_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.WATER, True, True)] = ( + Tip_50ulFilter_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 54.0, 30.0: 33.6, 0.0: 0.0, 20.0: 22.7}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10366,12 +12052,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, True, Liquid.WATER, False, True)] = \ -Tip_50ulFilter_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, True, Liquid.WATER, False, True)] = ( + Tip_50ulFilter_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.7, 50.0: 54.2, 30.0: 33.1, 0.0: 0.0, 1.0: 0.65, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10389,12 +12076,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ -Tip_50ul_96COREHead1000ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = ( + Tip_50ul_96COREHead1000ul_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 52.1, 30.0: 31.7, 0.0: 0.0, 20.0: 21.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10412,12 +12100,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = \ -Tip_50ul_96COREHead1000ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = ( + Tip_50ul_96COREHead1000ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.4, 50.0: 52.1, 30.0: 31.5, 0.0: 0.0, 1.0: 0.7, 10.0: 10.8}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10435,12 +12124,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ -Tip_50ul_96COREHead1000ul_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.WATER, True, True)] = ( + Tip_50ul_96COREHead1000ul_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 52.8, 0.0: 0.0, 30.0: 33.2, 20.0: 22.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10458,12 +12148,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.WATER, False, True)] = \ -Tip_50ul_96COREHead1000ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.WATER, False, True)] = ( + Tip_50ul_96COREHead1000ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.8, 50.0: 53.6, 30.0: 32.6, 0.0: 0.0, 1.0: 0.8, 10.0: 11.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10481,12 +12172,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=3.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ -Tip_50ul_96COREHead_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.DMSO, True, True)] = ( + Tip_50ul_96COREHead_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 51.4, 30.0: 31.3, 0.0: 0.0, 20.0: 21.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10504,12 +12196,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = \ -Tip_50ul_96COREHead_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.DMSO, False, True)] = ( + Tip_50ul_96COREHead_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 50.0: 52.1, 30.0: 31.6, 0.0: 0.0, 1.0: 0.8, 10.0: 11.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10527,12 +12220,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.5, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ -Tip_50ul_96COREHead_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.WATER, True, True)] = ( + Tip_50ul_96COREHead_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 54.1, 0.0: 0.0, 30.0: 33.0, 20.0: 22.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10550,12 +12244,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, True, True, False, Liquid.WATER, False, True)] = \ -Tip_50ul_96COREHead_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.WATER, False, True)] = ( + Tip_50ul_96COREHead_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 50.0: 53.6, 30.0: 32.9, 0.0: 0.0, 1.0: 0.7, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10573,13 +12268,14 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) # Liquid class for wash 50ul tips with CO-RE 96 Head in CO-RE 96 Head Washer. -vantage_mapping[(50, True, True, False, Liquid.WATER, False, False)] = \ -Tip_50ul_Core96Washer_DispenseSurface = HamiltonLiquidClass( +vantage_mapping[(50, True, True, False, Liquid.WATER, False, False)] = ( + Tip_50ul_Core96Washer_DispenseSurface +) = HamiltonLiquidClass( curve={5.0: 5.7, 50.0: 54.2, 30.0: 33.2, 0.0: 0.0, 1.0: 0.5, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10597,12 +12293,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, False, Liquid.DMSO, True, True)] = \ -Tip_50ul_DMSO_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.DMSO, True, True)] = ( + Tip_50ul_DMSO_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 52.5, 30.0: 32.2, 0.0: 0.0, 20.0: 21.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10620,12 +12317,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=200.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, False, Liquid.DMSO, False, True)] = \ -Tip_50ul_DMSO_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.DMSO, False, True)] = ( + Tip_50ul_DMSO_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.6, 50.0: 52.6, 30.0: 32.1, 0.0: 0.0, 1.0: 0.7, 10.0: 11.0}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10643,12 +12341,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, False, Liquid.ETHANOL, True, True)] = \ -Tip_50ul_EtOH_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.ETHANOL, True, True)] = ( + Tip_50ul_EtOH_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 58.4, 0.0: 0.0, 30.0: 36.0, 20.0: 24.2}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -10666,12 +12365,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=4.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, False, Liquid.ETHANOL, False, True)] = \ -Tip_50ul_EtOH_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.ETHANOL, False, True)] = ( + Tip_50ul_EtOH_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 6.7, 50.0: 54.1, 0.0: 0.0, 30.0: 33.7, 1.0: 2.1, 10.0: 12.1}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10689,12 +12389,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=50.0, dispense_settling_time=0.5, dispense_stop_flow_rate=50.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, False, Liquid.GLYCERIN80, False, True)] = \ -Tip_50ul_Glycerin80_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.GLYCERIN80, False, True)] = ( + Tip_50ul_Glycerin80_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.7, 50.0: 59.4, 0.0: 0.0, 30.0: 36.0, 1.0: 0.3, 10.0: 11.8}, aspiration_flow_rate=50.0, aspiration_mix_flow_rate=50.0, @@ -10712,12 +12413,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=2.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, False, Liquid.SERUM, True, True)] = \ -Tip_50ul_Serum_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.SERUM, True, True)] = ( + Tip_50ul_Serum_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 54.6, 30.0: 33.5, 0.0: 0.0, 20.0: 22.6}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10735,12 +12437,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, False, Liquid.SERUM, False, True)] = \ -Tip_50ul_Serum_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.SERUM, False, True)] = ( + Tip_50ul_Serum_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.7, 50.0: 54.9, 30.0: 33.0, 0.0: 0.0, 1.0: 0.7, 10.0: 11.3}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10758,12 +12461,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, False, Liquid.WATER, True, True)] = \ -Tip_50ul_Water_DispenseJet_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.WATER, True, True)] = ( + Tip_50ul_Water_DispenseJet_Empty +) = HamiltonLiquidClass( curve={50.0: 54.0, 30.0: 33.5, 0.0: 0.0, 20.0: 22.5}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=100.0, @@ -10781,12 +12485,13 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=1.0, dispense_settling_time=0.0, dispense_stop_flow_rate=100.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) -vantage_mapping[(50, False, True, False, Liquid.WATER, False, True)] = \ -Tip_50ul_Water_DispenseSurface_Empty = HamiltonLiquidClass( +vantage_mapping[(50, False, True, False, Liquid.WATER, False, True)] = ( + Tip_50ul_Water_DispenseSurface_Empty +) = HamiltonLiquidClass( curve={5.0: 5.7, 50.0: 54.2, 30.0: 33.2, 0.0: 0.0, 1.0: 0.7, 10.0: 11.4}, aspiration_flow_rate=100.0, aspiration_mix_flow_rate=75.0, @@ -10804,5 +12509,5 @@ def get_vantage_liquid_class(**kwargs): dispense_swap_speed=2.0, dispense_settling_time=0.0, dispense_stop_flow_rate=1.0, - dispense_stop_back_volume=0.0 + dispense_stop_back_volume=0.0, ) diff --git a/pylabrobot/liquid_handling/liquid_handler.py b/pylabrobot/liquid_handling/liquid_handler.py index 0fd8b3d94b..5f6cb61969 100644 --- a/pylabrobot/liquid_handling/liquid_handler.py +++ b/pylabrobot/liquid_handling/liquid_handler.py @@ -8,70 +8,72 @@ import json import logging import threading -from typing import Any, Callable, Dict, Union, Optional, List, Sequence, Set, Tuple, Protocol, cast import warnings +from typing import Any, Callable, Dict, List, Optional, Protocol, Sequence, Set, Tuple, Union, cast -from pylabrobot.machines.machine import Machine, need_setup_finished -from pylabrobot.liquid_handling.strictness import Strictness, get_strictness from pylabrobot.liquid_handling.errors import ChannelizedError -from pylabrobot.resources.errors import HasTipError +from pylabrobot.liquid_handling.strictness import Strictness, get_strictness +from pylabrobot.machines.machine import Machine, need_setup_finished from pylabrobot.plate_reading import PlateReader -from pylabrobot.resources.errors import CrossContaminationError from pylabrobot.resources import ( + CarrierSite, Container, - Deck, - Resource, - ResourceStack, Coordinate, - CarrierSite, - PlateCarrierSite, + Deck, Lid, MFXModule, Plate, PlateAdapter, + PlateCarrierSite, + Resource, + ResourceStack, Tip, TipRack, TipSpot, - Trash, - Well, TipTracker, + Trash, VolumeTracker, + Well, + does_cross_contamination_tracking, does_tip_tracking, does_volume_tracking, - does_cross_contamination_tracking ) +from pylabrobot.resources.errors import CrossContaminationError, HasTipError from pylabrobot.resources.liquid import Liquid from pylabrobot.tilting.tilter import Tilter from .backends import LiquidHandlerBackend from .standard import ( - Pickup, - PickupTipRack, - Drop, - DropTipRack, Aspiration, - AspirationPlate, AspirationContainer, + AspirationPlate, Dispense, - DispensePlate, DispenseContainer, + DispensePlate, + Drop, + DropTipRack, + GripDirection, Move, - GripDirection + Pickup, + PickupTipRack, ) - logger = logging.getLogger("pylabrobot") + def check_contaminated(liquid_history_tip, liquid_history_well): """Helper function used to check if adding a liquid to the container - would result in cross contamination""" + would result in cross contamination""" return not liquid_history_tip.issubset(liquid_history_well) and len(liquid_history_tip) > 0 + def check_updatable(src_tracker: VolumeTracker, dest_tracker: VolumeTracker): """Helper function used to check if it is possible to update the - liquid_history of src based on contents of dst""" - return not src_tracker.is_cross_contamination_tracking_disabled and \ - not dest_tracker.is_cross_contamination_tracking_disabled + liquid_history of src based on contents of dst""" + return ( + not src_tracker.is_cross_contamination_tracking_disabled + and not dest_tracker.is_cross_contamination_tracking_disabled + ) class BlowOutVolumeError(Exception): @@ -100,7 +102,7 @@ class LiquidHandler(Machine): } def __init__(self, backend: LiquidHandlerBackend, deck: Deck): - """ Initialize a LiquidHandler. + """Initialize a LiquidHandler. Args: backend: Backend to use. @@ -116,7 +118,7 @@ def __init__(self, backend: LiquidHandlerBackend, deck: Deck): category="liquid_handler", ) - self.backend: LiquidHandlerBackend = backend # fix type + self.backend: LiquidHandlerBackend = backend # fix type self._callbacks: Dict[str, OperationCallback] = {} self.deck = deck @@ -135,7 +137,7 @@ def __init__(self, backend: LiquidHandlerBackend, deck: Deck): super().assign_child_resource(deck, location=deck.location or Coordinate.zero()) async def setup(self, **backend_kwargs): - """ Prepare the robot for use. """ + """Prepare the robot for use.""" if self.setup_finished: raise RuntimeError("The setup has already finished. See `LiquidHandler.stop`.") @@ -151,22 +153,22 @@ async def setup(self, **backend_kwargs): self._send_assigned_resource_to_backend(resource) def serialize_state(self) -> Dict[str, Any]: - """ Serialize the state of this liquid handler. Use :meth:`~Resource.serialize_all_states` to - serialize the state of the liquid handler and all children (the deck). """ + """Serialize the state of this liquid handler. Use :meth:`~Resource.serialize_all_states` to + serialize the state of the liquid handler and all children (the deck).""" head_state = {channel: tracker.serialize() for channel, tracker in self.head.items()} return {"head_state": head_state} def load_state(self, state: Dict[str, Any]): - """ Load the liquid handler state from a file. Use :meth:`~Resource.load_all_state` to load the - state of the liquid handler and all children (the deck). """ + """Load the liquid handler state from a file. Use :meth:`~Resource.load_all_state` to load the + state of the liquid handler and all children (the deck).""" head_state = state["head_state"] for channel, tracker_state in head_state.items(): self.head[channel].load_state(tracker_state) def update_head_state(self, state: Dict[int, Optional[Tip]]): - """ Update the state of the liquid handler head. + """Update the state of the liquid handler head. All keys in `state` must be valid channels. Channels for which no key is specified will keep their current state. @@ -183,12 +185,12 @@ def update_head_state(self, state: Dict[int, Optional[Tip]]): if self.head[channel].has_tip: self.head[channel].remove_tip() else: - if self.head[channel].has_tip: # remove tip so we can update the head. + if self.head[channel].has_tip: # remove tip so we can update the head. self.head[channel].remove_tip() self.head[channel].add_tip(tip) def clear_head_state(self): - """ Clear the state of the liquid handler head. """ + """Clear the state of the liquid handler head.""" self.update_head_state({c: None for c in self.head.keys()}) @@ -204,22 +206,22 @@ def callback(*args, **kwargs): t.join() def _send_assigned_resource_to_backend(self, resource: Resource): - """ This method is called when a resource is assigned to the deck, and passes this information - to the backend. """ + """This method is called when a resource is assigned to the deck, and passes this information + to the backend.""" self._run_async_in_thread(self.backend.assigned_resource_callback, resource) def _send_unassigned_resource_to_backend(self, resource: Resource): - """ This method is called when a resource is unassigned from the deck, and passes this - information to the backend. """ + """This method is called when a resource is unassigned from the deck, and passes this + information to the backend.""" self._run_async_in_thread(self.backend.unassigned_resource_callback, resource.name) def summary(self): - """ Prints a string summary of the deck layout. """ + """Prints a string summary of the deck layout.""" print(self.deck.summary()) def _assert_positions_unique(self, positions: List[str]): - """ Returns whether all items in `positions` are unique where they are not `None`. + """Returns whether all items in `positions` are unique where they are not `None`. Args: positions: List of positions. @@ -230,7 +232,7 @@ def _assert_positions_unique(self, positions: List[str]): raise ValueError("Positions must be unique.") def _assert_resources_exist(self, resources: Sequence[Resource]): - """ Checks that each resource in `resources` is assigned to the deck. + """Checks that each resource in `resources` is assigned to the deck. Args: resources: List of resources. @@ -248,12 +250,9 @@ def _assert_resources_exist(self, resources: Sequence[Resource]): raise ValueError(f"Resource {resource} is not assigned to the deck.") def _check_args( - self, - method: Callable, - backend_kwargs: Dict[str, Any], - default: Set[str] + self, method: Callable, backend_kwargs: Dict[str, Any], default: Set[str] ) -> Set[str]: - """ Checks that the arguments to `method` are valid. + """Checks that the arguments to `method` are valid. Args: method: Method to check. @@ -270,10 +269,16 @@ def _check_args( sig = inspect.signature(method) args = {arg: param for arg, param in sig.parameters.items() if arg not in default_args} - vars_keyword = {arg for arg, param in sig.parameters.items() # **kwargs - if param.kind == inspect.Parameter.VAR_KEYWORD} - args = {arg: param for arg, param in args.items() # keep only *args and **kwargs - if param.kind not in {inspect.Parameter.VAR_POSITIONAL, inspect.Parameter.VAR_KEYWORD}} + vars_keyword = { + arg + for arg, param in sig.parameters.items() # **kwargs + if param.kind == inspect.Parameter.VAR_KEYWORD + } + args = { + arg: param + for arg, param in args.items() # keep only *args and **kwargs + if param.kind not in {inspect.Parameter.VAR_POSITIONAL, inspect.Parameter.VAR_KEYWORD} + } non_default = {arg for arg, param in args.items() if param.default == inspect.Parameter.empty} strictness = get_strictness() @@ -285,7 +290,7 @@ def _check_args( raise TypeError(f"Missing arguments to backend.{method.__name__}: {missing}") if len(vars_keyword) > 0: - return set() # no extra arguments if the method accepts **kwargs + return set() # no extra arguments if the method accepts **kwargs extra = backend_kws - set(args.keys()) if len(extra) > 0 and len(vars_keyword) == 0: @@ -299,7 +304,7 @@ def _check_args( return extra def _make_sure_channels_exist(self, channels: List[int]): - """ Checks that the channels exist. """ + """Checks that the channels exist.""" invalid_channels = [c for c in channels if c not in self.head] if not len(invalid_channels) == 0: raise ValueError(f"Invalid channels: {invalid_channels}") @@ -310,9 +315,9 @@ async def pick_up_tips( tip_spots: List[TipSpot], use_channels: Optional[List[int]] = None, offsets: Optional[List[Coordinate]] = None, - **backend_kwargs + **backend_kwargs, ): - """ Pick up tips from a resource. + """Pick up tips from a resource. Examples: Pick up all tips in the first column. @@ -374,12 +379,15 @@ async def pick_up_tips( # checks self._assert_resources_exist(tip_spots) self._make_sure_channels_exist(use_channels) - assert len(tip_spots) == len(offsets) == len(use_channels), \ - "Number of tips and offsets and use_channels must be equal." + assert ( + len(tip_spots) == len(offsets) == len(use_channels) + ), "Number of tips and offsets and use_channels must be equal." # create operations - pickups = [Pickup(resource=tip_spot, offset=offset, tip=tip) - for tip_spot, offset, tip in zip(tip_spots, offsets, tips)] + pickups = [ + Pickup(resource=tip_spot, offset=offset, tip=tip) + for tip_spot, offset, tip in zip(tip_spots, offsets, tips) + ] # queue operations on the trackers for channel, op in zip(use_channels, pickups): @@ -390,8 +398,9 @@ async def pick_up_tips( self.head[channel].add_tip(op.tip, origin=op.resource, commit=False) # fix the backend kwargs - extras = self._check_args(self.backend.pick_up_tips, backend_kwargs, - default={"ops", "use_channels"}) + extras = self._check_args( + self.backend.pick_up_tips, backend_kwargs, default={"ops", "use_channels"} + ) for extra in extras: del backend_kwargs[extra] @@ -430,9 +439,9 @@ async def drop_tips( use_channels: Optional[List[int]] = None, offsets: Optional[List[Coordinate]] = None, allow_nonzero_volume: bool = False, - **backend_kwargs + **backend_kwargs, ): - """ Drop tips to a resource. + """Drop tips to a resource. Examples: Dropping tips to the first column. @@ -497,23 +506,30 @@ async def drop_tips( # checks self._assert_resources_exist(tip_spots) self._make_sure_channels_exist(use_channels) - assert len(tip_spots) == len(offsets) == len(use_channels) == len(tips), \ - "Number of channels and offsets and use_channels and tips must be equal." + assert ( + len(tip_spots) == len(offsets) == len(use_channels) == len(tips) + ), "Number of channels and offsets and use_channels and tips must be equal." # create operations - drops = [Drop(resource=tip_spot, offset=offset, tip=tip) - for tip_spot, tip, offset in zip(tip_spots, tips, offsets)] + drops = [ + Drop(resource=tip_spot, offset=offset, tip=tip) + for tip_spot, tip, offset in zip(tip_spots, tips, offsets) + ] # queue operations on the trackers for channel, op in zip(use_channels, drops): - if does_tip_tracking() and isinstance(op.resource, TipSpot) and \ - not op.resource.tracker.is_disabled: + if ( + does_tip_tracking() + and isinstance(op.resource, TipSpot) + and not op.resource.tracker.is_disabled + ): op.resource.tracker.add_tip(op.tip, commit=False) self.head[channel].remove_tip() # fix the backend kwargs - extras = self._check_args(self.backend.drop_tips, backend_kwargs, - default={"ops", "use_channels"}) + extras = self._check_args( + self.backend.drop_tips, backend_kwargs, default={"ops", "use_channels"} + ) for extra in extras: del backend_kwargs[extra] @@ -531,8 +547,11 @@ async def drop_tips( # commit or rollback the state trackers for channel, op, success in zip(use_channels, drops, successes): - if does_tip_tracking() and isinstance(op.resource, TipSpot) and \ - not op.resource.tracker.is_disabled: + if ( + does_tip_tracking() + and isinstance(op.resource, TipSpot) + and not op.resource.tracker.is_disabled + ): (op.resource.tracker.commit if success else op.resource.tracker.rollback)() (self.head[channel].commit if success else self.head[channel].rollback)() @@ -547,7 +566,7 @@ async def drop_tips( ) async def return_tips(self, use_channels: Optional[list[int]] = None, **backend_kwargs): - """ Return all tips that are currently picked up to their original place. + """Return all tips that are currently picked up to their original place. Examples: Return the tips on the head to the tip rack where they were picked up: @@ -584,9 +603,9 @@ async def discard_tips( self, use_channels: Optional[List[int]] = None, allow_nonzero_volume: bool = True, - **backend_kwargs + **backend_kwargs, ): - """ Permanently discard tips in the trash. + """Permanently discard tips in the trash. Examples: Discarding the tips on channels 1 and 2: @@ -613,17 +632,18 @@ async def discard_tips( raise RuntimeError("No tips have been picked up and no channels were specified.") trash = self.deck.get_trash_area() - offsets = [c - trash.center() for c in reversed(trash.centers(yn=n))] # offset is wrt center + offsets = [c - trash.center() for c in reversed(trash.centers(yn=n))] # offset is wrt center return await self.drop_tips( - tip_spots=[trash]*n, - use_channels=use_channels, - offsets=offsets, - allow_nonzero_volume=allow_nonzero_volume, - **backend_kwargs) + tip_spots=[trash] * n, + use_channels=use_channels, + offsets=offsets, + allow_nonzero_volume=allow_nonzero_volume, + **backend_kwargs, + ) def _check_containers(self, resources: Sequence[Resource]): - """ Checks that all resources are containers. """ + """Checks that all resources are containers.""" not_containers = [r for r in resources if not isinstance(r, Container)] if len(not_containers) > 0: raise TypeError(f"Resources must be `Container`s, got {not_containers}") @@ -638,9 +658,9 @@ async def aspirate( offsets: Optional[List[Coordinate]] = None, liquid_height: Optional[List[Optional[float]]] = None, blow_out_air_volume: Optional[List[Optional[float]]] = None, - **backend_kwargs + **backend_kwargs, ): - """ Aspirate liquid from the specified wells. + """Aspirate liquid from the specified wells. Examples: Aspirate a constant amount of liquid from the first column: @@ -725,8 +745,8 @@ async def aspirate( n = len(use_channels) resources = [resource] * len(use_channels) centers = list(reversed(resource.centers(yn=n, zn=0))) - centers = [c - resource.center() for c in centers] # offset is wrt center - offsets = [c + o for c, o in zip(centers, offsets)] # user-defined + centers = [c - resource.center() for c in centers] # offset is wrt center + offsets = [c + o for c, o in zip(centers, offsets)] # user-defined # liquid(s) for each channel. If volume tracking is disabled, use None as the liquid. liquids: List[List[Tuple[Optional[Liquid], float]]] = [] @@ -737,11 +757,21 @@ async def aspirate( liquids.append(r.tracker.get_liquids(top_volume=vol)) # create operations - aspirations = [Aspiration(resource=r, volume=v, offset=o, flow_rate=fr, liquid_height=lh, tip=t, - blow_out_air_volume=bav, liquids=lvs) - for r, v, o, fr, lh, t, bav, lvs in - zip(resources, vols, offsets, flow_rates, liquid_height, tips, - blow_out_air_volume, liquids)] + aspirations = [ + Aspiration( + resource=r, + volume=v, + offset=o, + flow_rate=fr, + liquid_height=lh, + tip=t, + blow_out_air_volume=bav, + liquids=lvs, + ) + for r, v, o, fr, lh, t, bav, lvs in zip( + resources, vols, offsets, flow_rates, liquid_height, tips, blow_out_air_volume, liquids + ) + ] # queue the operations on the resource (source) and mounted tips (destination) trackers for op in aspirations: @@ -754,13 +784,15 @@ async def aspirate( if check_contaminated(op.tip.tracker.liquid_history, op.resource.tracker.liquid_history): raise CrossContaminationError( f"Attempting to aspirate {next(reversed(op.liquids))[0]} with a tip contaminated " - f"with {op.tip.tracker.liquid_history}.") + f"with {op.tip.tracker.liquid_history}." + ) for liquid, volume in reversed(op.liquids): op.tip.tracker.add_liquid(liquid=liquid, volume=volume) - extras = self._check_args(self.backend.aspirate, backend_kwargs, - default={"ops", "use_channels"}) + extras = self._check_args( + self.backend.aspirate, backend_kwargs, default={"ops", "use_channels"} + ) for extra in extras: del backend_kwargs[extra] @@ -803,9 +835,9 @@ async def dispense( offsets: Optional[List[Coordinate]] = None, liquid_height: Optional[List[Optional[float]]] = None, blow_out_air_volume: Optional[List[Optional[float]]] = None, - **backend_kwargs + **backend_kwargs, ): - """ Dispense liquid to the specified channels. + """Dispense liquid to the specified channels. Examples: Dispense a constant amount of liquid to the first column: @@ -885,8 +917,8 @@ async def dispense( n = len(use_channels) resources = [resource] * len(use_channels) centers = list(reversed(resource.centers(yn=n, zn=0))) - centers = [c - resource.center() for c in centers] # offset is wrt center - offsets = [c + o for c, o in zip(centers, offsets)] # user-defined + centers = [c - resource.center() for c in centers] # offset is wrt center + offsets = [c + o for c, o in zip(centers, offsets)] # user-defined tips = [self.head[channel].get_tip() for channel in use_channels] @@ -908,17 +940,28 @@ async def dispense( # liquid(s) for each channel. If volume tracking is disabled, use None as the liquid. if does_volume_tracking(): - liquids = [c.get_tip().tracker.get_liquids(top_volume=vol) - for c, vol in zip(self.head.values(), vols)] + liquids = [ + c.get_tip().tracker.get_liquids(top_volume=vol) for c, vol in zip(self.head.values(), vols) + ] else: liquids = [[(None, vol)] for vol in vols] # create operations - dispenses = [Dispense(resource=r, volume=v, offset=o, flow_rate=fr, liquid_height=lh, tip=t, - liquids=lvs, blow_out_air_volume=bav) - for r, v, o, fr, lh, t, bav, lvs in - zip(resources, vols, offsets, flow_rates, liquid_height, tips, - blow_out_air_volume, liquids)] + dispenses = [ + Dispense( + resource=r, + volume=v, + offset=o, + flow_rate=fr, + liquid_height=lh, + tip=t, + liquids=lvs, + blow_out_air_volume=bav, + ) + for r, v, o, fr, lh, t, bav, lvs in zip( + resources, vols, offsets, flow_rates, liquid_height, tips, blow_out_air_volume, liquids + ) + ] # queue the operations on the resource (source) and mounted tips (destination) trackers for op in dispenses: @@ -933,8 +976,9 @@ async def dispense( op.tip.tracker.remove_liquid(op.volume) # fix the backend kwargs - extras = self._check_args(self.backend.dispense, backend_kwargs, - default={"ops", "use_channels"}) + extras = self._check_args( + self.backend.dispense, backend_kwargs, default={"ops", "use_channels"} + ) for extra in extras: del backend_kwargs[extra] @@ -979,7 +1023,7 @@ async def transfer( target_vols: Optional[List[float]] = None, aspiration_flow_rate: Optional[float] = None, dispense_flow_rates: Optional[Union[float, List[Optional[float]]]] = None, - **backend_kwargs + **backend_kwargs, ): """Transfer liquid from one well to another. @@ -1034,21 +1078,20 @@ async def transfer( target_vols = [source_vol * r / sum(ratios) for r in ratios] await self.aspirate( - resources=[source], - vols=[sum(target_vols)], - flow_rates=aspiration_flow_rate, - **backend_kwargs) + resources=[source], vols=[sum(target_vols)], flow_rates=aspiration_flow_rate, **backend_kwargs + ) for target, vol in zip(targets, target_vols): await self.dispense( resources=[target], vols=[vol], flow_rates=dispense_flow_rates, use_channels=[0], - **backend_kwargs) + **backend_kwargs, + ) @contextlib.contextmanager def use_channels(self, channels: List[int]): - """ Temporarily use the specified channels as a default argument to `use_channels`. + """Temporarily use the specified channels as a default argument to `use_channels`. Examples: Use channel index 2 for all liquid handling operations inside the context: @@ -1076,12 +1119,9 @@ def use_channels(self, channels: List[int]): self._default_use_channels = None async def pick_up_tips96( - self, - tip_rack: TipRack, - offset: Coordinate = Coordinate.zero(), - **backend_kwargs + self, tip_rack: TipRack, offset: Coordinate = Coordinate.zero(), **backend_kwargs ): - """ Pick up tips using the 96 head. This will pick up 96 tips. + """Pick up tips using the 96 head. This will pick up 96 tips. Examples: Pick up tips from a 96-tip tiprack: @@ -1113,10 +1153,7 @@ async def pick_up_tips96( pickup_operation = PickupTipRack(resource=tip_rack, offset=offset) try: - await self.backend.pick_up_tips96( - pickup=pickup_operation, - **backend_kwargs - ) + await self.backend.pick_up_tips96(pickup=pickup_operation, **backend_kwargs) except Exception as error: # pylint: disable=broad-except for i, tip_spot in enumerate(tip_rack.get_all_items()): if does_tip_tracking() and not tip_spot.tracker.is_disabled: @@ -1147,9 +1184,9 @@ async def drop_tips96( resource: Union[TipRack, Trash], offset: Coordinate = Coordinate.zero(), allow_nonzero_volume: bool = False, - **backend_kwargs + **backend_kwargs, ): - """ Drop tips using the 96 head. This will drop 96 tips. + """Drop tips using the 96 head. This will drop 96 tips. Examples: Drop tips to a 96-tip tiprack: @@ -1192,10 +1229,7 @@ async def drop_tips96( drop_operation = DropTipRack(resource=resource, offset=offset) try: - await self.backend.drop_tips96( - drop=drop_operation, - **backend_kwargs - ) + await self.backend.drop_tips96(drop=drop_operation, **backend_kwargs) except Exception as e: # pylint: disable=broad-except for i in range(96): if isinstance(resource, TipRack): @@ -1226,9 +1260,9 @@ async def drop_tips96( ) def _get_96_head_origin_tip_rack(self) -> Optional[TipRack]: - """ Get the tip rack where the tips on the 96 head were picked up. If no tips were picked up, + """Get the tip rack where the tips on the 96 head were picked up. If no tips were picked up, return `None`. If different tip racks were found for different tips on the head, raise a - RuntimeError. """ + RuntimeError.""" tip_spot = self.head96[0].get_tip_origin() if tip_spot is None: @@ -1247,7 +1281,7 @@ def _get_96_head_origin_tip_rack(self) -> Optional[TipRack]: return tip_rack async def return_tips96(self, allow_nonzero_volume: bool = False, **backend_kwargs): - """ Return the tips on the 96 head to the tip rack where they were picked up. + """Return the tips on the 96 head to the tip rack where they were picked up. Examples: Return the tips on the 96 head to the tip rack where they were picked up: @@ -1263,12 +1297,11 @@ async def return_tips96(self, allow_nonzero_volume: bool = False, **backend_kwar if tip_rack is None: raise RuntimeError("No tips have been picked up with the 96 head") return await self.drop_tips96( - tip_rack, - allow_nonzero_volume=allow_nonzero_volume, - **backend_kwargs) + tip_rack, allow_nonzero_volume=allow_nonzero_volume, **backend_kwargs + ) async def discard_tips96(self, allow_nonzero_volume: bool = True, **backend_kwargs): - """ Permanently discard tips from the 96 head in the trash. This method only works when this + """Permanently discard tips from the 96 head in the trash. This method only works when this LiquidHandler is configured with a deck that implements the `get_trash_area96` method. Otherwise, an `ImplementationError` will be raised. @@ -1288,9 +1321,8 @@ async def discard_tips96(self, allow_nonzero_volume: bool = True, **backend_kwar """ return await self.drop_tips96( - self.deck.get_trash_area96(), - allow_nonzero_volume=allow_nonzero_volume, - **backend_kwargs) + self.deck.get_trash_area96(), allow_nonzero_volume=allow_nonzero_volume, **backend_kwargs + ) async def aspirate96( self, @@ -1299,9 +1331,9 @@ async def aspirate96( offset: Coordinate = Coordinate.zero(), flow_rate: Optional[float] = None, blow_out_air_volume: Optional[float] = None, - **backend_kwargs + **backend_kwargs, ): - """ Aspirate from all wells in a plate or from a container of a sufficient size. + """Aspirate from all wells in a plate or from a container of a sufficient size. Examples: Aspirate an entire 96 well plate or a container of sufficient size: @@ -1321,8 +1353,10 @@ async def aspirate96( backend_kwargs: Additional keyword arguments for the backend, optional. """ - if not (isinstance(resource, (Plate, Container)) or \ - (isinstance(resource, list) and all(isinstance(w, Well) for w in resource))): + if not ( + isinstance(resource, (Plate, Container)) + or (isinstance(resource, list) and all(isinstance(w, Well) for w in resource)) + ): raise TypeError(f"Resource must be a Plate, Container, or list of Wells, got {resource}") extras = self._check_args(self.backend.aspirate96, backend_kwargs, default={"aspiration"}) @@ -1339,8 +1373,9 @@ async def aspirate96( blow_out_air_volume = float(blow_out_air_volume) if blow_out_air_volume is not None else None if isinstance(resource, Container): - if resource.get_absolute_size_x() < 108.0 or \ - resource.get_absolute_size_y() < 70.0: # TODO: analyze as attr + if ( + resource.get_absolute_size_x() < 108.0 or resource.get_absolute_size_y() < 70.0 + ): # TODO: analyze as attr raise ValueError("Container too small to accommodate 96 head") for channel in self.head96.values(): @@ -1351,7 +1386,7 @@ async def aspirate96( liquids = [(None, volume)] all_liquids.append(liquids) else: - liquids = resource.tracker.remove_liquid(volume=volume) # type: ignore + liquids = resource.tracker.remove_liquid(volume=volume) # type: ignore all_liquids.append(liquids) for liquid, vol in reversed(liquids): @@ -1365,7 +1400,7 @@ async def aspirate96( tips=tips, liquid_height=None, blow_out_air_volume=blow_out_air_volume, - liquids=cast(List[List[Tuple[Optional[Liquid], float]]], all_liquids) # stupid + liquids=cast(List[List[Tuple[Optional[Liquid], float]]], all_liquids), # stupid ) else: if isinstance(resource, Plate): @@ -1391,7 +1426,7 @@ async def aspirate96( liquids = [(None, volume)] all_liquids.append(liquids) else: - liquids = well.tracker.remove_liquid(volume=volume) # type: ignore + liquids = well.tracker.remove_liquid(volume=volume) # type: ignore all_liquids.append(liquids) for liquid, vol in reversed(liquids): @@ -1405,7 +1440,7 @@ async def aspirate96( tips=tips, liquid_height=None, blow_out_air_volume=blow_out_air_volume, - liquids=cast(List[List[Tuple[Optional[Liquid], float]]], all_liquids) # stupid + liquids=cast(List[List[Tuple[Optional[Liquid], float]]], all_liquids), # stupid ) try: @@ -1442,9 +1477,9 @@ async def dispense96( offset: Coordinate = Coordinate.zero(), flow_rate: Optional[float] = None, blow_out_air_volume: Optional[float] = None, - **backend_kwargs + **backend_kwargs, ): - """ Dispense to all wells in a plate. + """Dispense to all wells in a plate. Examples: Dispense an entire 96 well plate: @@ -1463,8 +1498,10 @@ async def dispense96( backend_kwargs: Additional keyword arguments for the backend, optional. """ - if not (isinstance(resource, (Plate, Container)) or \ - (isinstance(resource, list) and all(isinstance(w, Well) for w in resource))): + if not ( + isinstance(resource, (Plate, Container)) + or (isinstance(resource, list) and all(isinstance(w, Well) for w in resource)) + ): raise TypeError(f"Resource must be a Plate, Container, or list of Wells, got {resource}") extras = self._check_args(self.backend.dispense96, backend_kwargs, default={"dispense"}) @@ -1481,8 +1518,9 @@ async def dispense96( blow_out_air_volume = float(blow_out_air_volume) if blow_out_air_volume is not None else None if isinstance(resource, Container): - if resource.get_absolute_size_x() < 108.0 or \ - resource.get_absolute_size_y() < 70.0: # TODO: analyze as attr + if ( + resource.get_absolute_size_x() < 108.0 or resource.get_absolute_size_y() < 70.0 + ): # TODO: analyze as attr raise ValueError("Container too small to accommodate 96 head") for channel in self.head96.values(): @@ -1493,7 +1531,7 @@ async def dispense96( liquids = [(None, volume)] all_liquids.append(liquids) else: - liquids = resource.tracker.remove_liquid(volume=volume) # type: ignore + liquids = resource.tracker.remove_liquid(volume=volume) # type: ignore all_liquids.append(liquids) for liquid, vol in reversed(liquids): @@ -1507,7 +1545,7 @@ async def dispense96( tips=tips, liquid_height=None, blow_out_air_volume=blow_out_air_volume, - liquids=cast(List[List[Tuple[Optional[Liquid], float]]], all_liquids) # stupid + liquids=cast(List[List[Tuple[Optional[Liquid], float]]], all_liquids), # stupid ) else: if isinstance(resource, Plate): @@ -1578,13 +1616,13 @@ async def dispense96( async def stamp( self, - source: Plate, # TODO + source: Plate, # TODO target: Plate, volume: float, aspiration_flow_rate: Optional[float] = None, dispense_flow_rate: Optional[float] = None, ): - """ Stamp (aspiration and dispense) one plate onto another. + """Stamp (aspiration and dispense) one plate onto another. Args: source: the source plate @@ -1596,17 +1634,13 @@ async def stamp( will be used. """ - assert (source.num_items_x, source.num_items_y) == (target.num_items_x, target.num_items_y), \ - "Source and target plates must be the same shape" + assert (source.num_items_x, source.num_items_y) == ( + target.num_items_x, + target.num_items_y, + ), "Source and target plates must be the same shape" - await self.aspirate96( - resource=source, - volume=volume, - flow_rate=aspiration_flow_rate) - await self.dispense96( - resource=source, - volume=volume, - flow_rate=dispense_flow_rate) + await self.aspirate96(resource=source, volume=volume, flow_rate=aspiration_flow_rate) + await self.dispense96(resource=source, volume=volume, flow_rate=dispense_flow_rate) async def move_resource( self, @@ -1618,9 +1652,9 @@ async def move_resource( pickup_distance_from_top: float = 0, get_direction: GripDirection = GripDirection.FRONT, put_direction: GripDirection = GripDirection.FRONT, - **backend_kwargs + **backend_kwargs, ): - """ Move a resource to a new location. + """Move a resource to a new location. Has convenience methods :meth:`move_plate` and :meth:`move_lid`. @@ -1684,10 +1718,10 @@ async def move_lid( destination_offset: Coordinate = Coordinate.zero(), get_direction: GripDirection = GripDirection.FRONT, put_direction: GripDirection = GripDirection.FRONT, - pickup_distance_from_top: float = 5.7-3.33, - **backend_kwargs + pickup_distance_from_top: float = 5.7 - 3.33, + **backend_kwargs, ): - """ Move a lid to a new location. + """Move a lid to a new location. A convenience method for :meth:`move_resource`. @@ -1716,7 +1750,8 @@ async def move_lid( to_location = Coordinate( x=to_location.x, y=to_location.y, - z=to_location.z + to.get_absolute_size_z() - lid.nesting_z_height) + z=to_location.z + to.get_absolute_size_z() - lid.nesting_z_height, + ) elif isinstance(to, ResourceStack): assert to.direction == "z", "Only ResourceStacks with direction 'z' are currently supported" to_location = to.get_absolute_location(z="top") @@ -1734,12 +1769,13 @@ async def move_lid( destination_offset=destination_offset, get_direction=get_direction, put_direction=put_direction, - **backend_kwargs) + **backend_kwargs, + ) lid.unassign() if isinstance(to, Coordinate): self.deck.assign_child_resource(lid, location=to_location) - elif isinstance(to, ResourceStack): # manage its own resources + elif isinstance(to, ResourceStack): # manage its own resources to.assign_child_resource(lid) elif isinstance(to, Plate): to.assign_child_resource(resource=lid) @@ -1755,10 +1791,10 @@ async def move_plate( destination_offset: Coordinate = Coordinate.zero(), put_direction: GripDirection = GripDirection.FRONT, get_direction: GripDirection = GripDirection.FRONT, - pickup_distance_from_top: float = 13.2-3.33, - **backend_kwargs + pickup_distance_from_top: float = 13.2 - 3.33, + **backend_kwargs, ): - """ Move a plate to a new location. + """Move a plate to a new location. A convenience method for :meth:`move_resource`. @@ -1800,8 +1836,11 @@ async def move_plate( elif isinstance(to, PlateCarrierSite): to_location = to.get_absolute_location() # Sanity check for equal well clearances / dz - well_dz_set = {round(well.location.z, 2) for well in plate.get_all_children() - if well.category == "well" and well.location is not None} + well_dz_set = { + round(well.location.z, 2) + for well in plate.get_all_children() + if well.category == "well" and well.location is not None + } assert len(well_dz_set) == 1, "All wells must have the same dz" well_dz = well_dz_set.pop() # Plate "sinking" logic based on well dz to pedestal relationship @@ -1828,19 +1867,20 @@ async def move_plate( destination_offset=destination_offset, get_direction=get_direction, put_direction=put_direction, - **backend_kwargs) + **backend_kwargs, + ) # Some of the code below should probably be moved to `move_resource` so that is can be shared # with the `move_lid` convenience method. plate.unassign() if isinstance(to, Coordinate): - to_location -= self.deck.location # passed as an absolute location, but stored as relative + to_location -= self.deck.location # passed as an absolute location, but stored as relative self.deck.assign_child_resource(plate, location=to_location) - elif isinstance(to, PlateCarrierSite): # .zero() resources + elif isinstance(to, PlateCarrierSite): # .zero() resources to.assign_child_resource(plate) - elif isinstance(to, CarrierSite): # .zero() resources + elif isinstance(to, CarrierSite): # .zero() resources to.assign_child_resource(plate) - elif isinstance(to, (ResourceStack, PlateReader)): # manage its own resources + elif isinstance(to, (ResourceStack, PlateReader)): # manage its own resources if isinstance(to, ResourceStack) and to.direction != "z": raise ValueError("Only ResourceStacks with direction 'z' are currently supported") to.assign_child_resource(plate) @@ -1877,7 +1917,7 @@ def callbacks(self): @classmethod def deserialize(cls, data: dict, allow_marshal: bool = False) -> LiquidHandler: - """ Deserialize a liquid handler from a dictionary. + """Deserialize a liquid handler from a dictionary. Args: data: A dictionary representation of the liquid handler. @@ -1890,7 +1930,7 @@ def deserialize(cls, data: dict, allow_marshal: bool = False) -> LiquidHandler: @classmethod def load(cls, path: str) -> LiquidHandler: - """ Load a liquid handler from a file. + """Load a liquid handler from a file. Args: path: The path to the file to load from. @@ -1907,9 +1947,11 @@ def assign_child_resource( location: Coordinate, reassign: bool = True, ): - """ Not implement on LiquidHandler, since the deck is managed by the :attr:`deck` attribute. """ - raise NotImplementedError("Cannot assign child resource to liquid handler. Use " - "lh.deck.assign_child_resource() instead.") + """Not implement on LiquidHandler, since the deck is managed by the :attr:`deck` attribute.""" + raise NotImplementedError( + "Cannot assign child resource to liquid handler. Use " + "lh.deck.assign_child_resource() instead." + ) class OperationCallback(Protocol): From b0b76e3adce00d57e338fecaf80690540d1f10e3 Mon Sep 17 00:00:00 2001 From: Rick Wierenga Date: Tue, 25 Mar 2025 13:17:17 -0700 Subject: [PATCH 17/18] restore --- .../liquid_handling/backends/hamilton/STAR.py | 1953 ++++++++++++----- .../backends/hamilton/STAR_tests.py | 1297 ++++++----- .../backends/hamilton/vantage.py | 380 ++-- .../backends/hamilton/vantage_tests.py | 108 +- pylabrobot/liquid_handling/liquid_handler.py | 894 +++++--- 5 files changed, 3165 insertions(+), 1467 deletions(-) diff --git a/pylabrobot/liquid_handling/backends/hamilton/STAR.py b/pylabrobot/liquid_handling/backends/hamilton/STAR.py index cddedddb2a..0c8e403a5e 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/STAR.py +++ b/pylabrobot/liquid_handling/backends/hamilton/STAR.py @@ -1,45 +1,79 @@ -""" -This file defines interfaces for all supported Hamilton liquid handling robots. -""" -# pylint: disable=invalid-sequence-index, dangerous-default-value - import datetime import enum import functools import logging import re from abc import ABCMeta -from typing import Callable, Dict, List, Literal, Optional, Sequence, Type, TypeVar, Union, cast +from contextlib import asynccontextmanager, contextmanager +from typing import ( + Callable, + Dict, + List, + Literal, + Optional, + Sequence, + Type, + TypeVar, + Union, + cast, +) from pylabrobot import audio -from pylabrobot.liquid_handling.backends.hamilton.base import HamiltonLiquidHandler +from pylabrobot.liquid_handling.backends.hamilton.base import ( + HamiltonLiquidHandler, +) from pylabrobot.liquid_handling.errors import ChannelizedError -from pylabrobot.liquid_handling.liquid_classes.hamilton import HamiltonLiquidClass +from pylabrobot.liquid_handling.liquid_classes.hamilton import ( + HamiltonLiquidClass, + get_star_liquid_class, +) from pylabrobot.liquid_handling.standard import ( - Aspiration, - AspirationContainer, - AspirationPlate, - Dispense, - DispenseContainer, - DispensePlate, Drop, DropTipRack, GripDirection, - Move, + MultiHeadAspirationContainer, + MultiHeadAspirationPlate, + MultiHeadDispenseContainer, + MultiHeadDispensePlate, Pickup, PickupTipRack, + ResourceDrop, + ResourceMove, + ResourcePickup, + SingleChannelAspiration, + SingleChannelDispense, +) +from pylabrobot.liquid_handling.utils import ( + get_tight_single_resource_liquid_op_offsets, + get_wide_single_resource_liquid_op_offsets, +) +from pylabrobot.resources import ( + Carrier, + Coordinate, + Resource, + TipRack, + TipSpot, + Well, ) -from pylabrobot.resources import Carrier, Coordinate, Resource, TipRack, TipSpot, Well from pylabrobot.resources.errors import ( HasTipError, NoTipError, TooLittleLiquidError, TooLittleVolumeError, ) -from pylabrobot.resources.hamilton.hamilton_decks import STAR_SIZE_X, STARLET_SIZE_X -from pylabrobot.resources.ml_star import HamiltonTip, TipDropMethod, TipPickupMethod, TipSize -from pylabrobot.resources.utils import get_child_location -from pylabrobot.utils.linalg import matrix_vector_multiply_3x3 +from pylabrobot.resources.hamilton import ( + HamiltonTip, + TipDropMethod, + TipPickupMethod, + TipSize, +) +from pylabrobot.resources.hamilton.hamilton_decks import ( + STAR_SIZE_X, + STARLET_SIZE_X, +) +from pylabrobot.resources.liquid import Liquid +from pylabrobot.resources.rotation import Rotation +from pylabrobot.resources.trash import Trash T = TypeVar("T") @@ -57,10 +91,10 @@ def need_iswap_parked(method: Callable): async def wrapper(self: "STAR", *args, **kwargs): if self.iswap_installed and not self.iswap_parked: await self.park_iswap( - minimum_traverse_height_at_beginning_of_a_command=int(self._traversal_height * 10) - ) # pylint: disable=protected-access + minimum_traverse_height_at_beginning_of_a_command=int(self._iswap_traversal_height * 10) + ) - result = await method(self, *args, **kwargs) # pylint: disable=not-callable + result = await method(self, *args, **kwargs) return result @@ -993,7 +1027,10 @@ def star_firmware_string_to_error( if "/" in error: # C0 module: error code / trace information error_code_str, trace_information_str = error.split("/") - error_code, trace_information = int(error_code_str), int(trace_information_str) + error_code, trace_information = ( + int(error_code_str), + int(trace_information_str), + ) if error_code == 0: # No error continue error_class = error_code_to_exception(error_code) @@ -1021,7 +1058,9 @@ def star_firmware_string_to_error( return STARFirmwareError(errors=errors, raw_response=raw_response) -def convert_star_module_error_to_plr_error(error: STARModuleError) -> Optional[Exception]: +def convert_star_module_error_to_plr_error( + error: STARModuleError, +) -> Optional[Exception]: """Convert an error returned by a specific STAR module to a Hamilton error.""" # TipAlreadyFittedError -> HasTipError if isinstance(error, TipAlreadyFittedError): @@ -1043,7 +1082,9 @@ def convert_star_module_error_to_plr_error(error: STARModuleError) -> Optional[E return None -def convert_star_firmware_error_to_plr_error(error: STARFirmwareError) -> Optional[Exception]: +def convert_star_firmware_error_to_plr_error( + error: STARFirmwareError, +) -> Optional[Exception]: """Check if a STARFirmwareError can be converted to a native PLR error. If so, return it, else return `None`.""" @@ -1121,10 +1162,13 @@ def __init__( self._num_channels: Optional[int] = None self._core_parked: Optional[bool] = None self._extended_conf: Optional[dict] = None - self._traversal_height: float = 245.0 + self._channel_traversal_height: float = 245.0 + self._iswap_traversal_height: float = 284.0 self.core_adjustment = Coordinate.zero() self._unsafe = UnSafe(self) + self._iswap_version: Optional[str] = None # loaded lazily + @property def unsafe(self) -> "UnSafe": """Actions that have a higher risk of damaging the robot. Use with care!""" @@ -1138,7 +1182,13 @@ def num_channels(self) -> int: return self._num_channels def set_minimum_traversal_height(self, traversal_height: float): - """Set the minimum traversal height for the robot. + raise NotImplementedError( + "set_minimum_traversal_height is depricated. use set_minimum_channel_traversal_height or " + "set_minimum_iswap_traversal_height instead." + ) + + def set_minimum_channel_traversal_height(self, traversal_height: float): + """Set the minimum traversal height for the pip channels. This refers to the bottom of the pipetting channel when no tip is present, or the bottom of the tip when a tip is present. This value will be used as the default value for the @@ -1148,7 +1198,24 @@ def set_minimum_traversal_height(self, traversal_height: float): assert 0 < traversal_height < 285, "Traversal height must be between 0 and 285 mm" - self._traversal_height = traversal_height + self._channel_traversal_height = traversal_height + + def set_minimum_iswap_traversal_height(self, traversal_height: float): + """Set the minimum traversal height for the iswap.""" + + assert 0 < traversal_height < 285, "Traversal height must be between 0 and 285 mm" + + self._iswap_traversal_height = traversal_height + + @contextmanager + def iswap_minimum_traversal_height(self, traversal_height: float): + orig = self._iswap_traversal_height + self._iswap_traversal_height = traversal_height + try: + yield + except Exception as e: + self._iswap_traversal_height = orig + raise e @property def module_id_length(self): @@ -1169,6 +1236,17 @@ def iswap_parked(self) -> bool: def core_parked(self) -> bool: return self._core_parked is True + async def get_iswap_version(self) -> str: + """Lazily load the iSWAP version. Use cached value if available.""" + if self._iswap_version is None: + self._iswap_version = await self.request_iswap_version() + return self._iswap_version + + async def request_pip_channel_version(self, channel: int) -> str: + return cast( + str, (await self.send_command(STAR.channel_id(channel), "RF", fmt="rf" + "&" * 17))["rf"] + ) + def get_id_from_fw_response(self, resp: str) -> Optional[int]: """Get the id from a firmware response.""" parsed = parse_star_fw_string(resp, "id####") @@ -1250,9 +1328,8 @@ def check_fw_string_error(self, resp: str): # temp. disabled until we figure out how to handle async in parse response (the # background thread does not have an event loop, and I'm not sure if it should.) # vp = await self.send_command(module=error.raw_module, command="VP", fmt="vp&&")["vp"] - # he[module_name].message += f" ({vp})" # pylint: disable=unnecessary-dict-index-lookup + # he[module_name].message += f" ({vp})" - # pylint: disable=unnecessary-dict-index-lookup he.errors[ module_name ].message += " (call lh.backend.request_name_of_last_faulty_parameter)" @@ -1263,14 +1340,24 @@ def _parse_response(self, resp: str, fmt: str) -> dict: """Parse a response from the machine.""" return parse_star_fw_string(resp, fmt) - async def setup(self): - """setup + async def setup( + self, + skip_autoload=False, + skip_iswap=False, + skip_core96_head=False, + ): + """Creates a USB connection and finds read/write interfaces. - Creates a USB connection and finds read/write interfaces. + Args: + skip_autoload: if True, skip initializing the autoload module, if applicable. + skip_iswap: if True, skip initializing the iSWAP module, if applicable. + skip_core96_head: if True, skip initializing the CoRe 96 head module, if applicable. """ await super().setup() + self.id_ = 0 + tip_presences = await self.request_tip_presence() self._num_channels = len(tip_presences) @@ -1284,7 +1371,7 @@ async def setup(self): ) left_x_drive_configuration_byte_1 = left_x_drive_configuration_byte_1[2:] configuration_data1 = bin(conf["kb"]).split("b")[-1].zfill(8) - autoload_configuration_byte = configuration_data1[-3] + autoload_configuration_byte = configuration_data1[-4] # Identify installations self.autoload_installed = autoload_configuration_byte == "1" self.core96_head_installed = left_x_drive_configuration_byte_1[2] == "1" @@ -1304,7 +1391,7 @@ async def setup(self): await self.initialize_pipetting_channels( x_positions=[self.extended_conf["xw"]], # Tip eject waste X position. y_positions=y_positions, - begin_of_tip_deposit_process=int(self._traversal_height * 10), + begin_of_tip_deposit_process=int(self._channel_traversal_height * 10), end_of_tip_deposit_process=1220, z_position_at_end_of_a_command=3600, tip_pattern=[True] * self.num_channels, @@ -1312,27 +1399,28 @@ async def setup(self): discarding_method=0, ) - if self.autoload_installed: + if self.autoload_installed and not skip_autoload: autoload_initialized = await self.request_autoload_initialization_status() if not autoload_initialized: await self.initialize_autoload() await self.park_autoload() - if self.iswap_installed: + if self.iswap_installed and not skip_iswap: iswap_initialized = await self.request_iswap_initialization_status() if not iswap_initialized: await self.initialize_iswap() await self.park_iswap( - minimum_traverse_height_at_beginning_of_a_command=int(self._traversal_height * 10) + minimum_traverse_height_at_beginning_of_a_command=int(self._iswap_traversal_height * 10) ) - if self.core96_head_installed: + if self.core96_head_installed and not skip_core96_head: core96_head_initialized = await self.request_core_96_head_initialization_status() if not core96_head_initialized: await self.initialize_core_96_head( - z_position_at_the_command_end=int(self._traversal_height * 10) + trash96=self.deck.get_trash_area96(), + z_position_at_the_command_end=self._channel_traversal_height, ) # After setup, STAR will have thrown out anything mounted on the pipetting channels, including @@ -1385,7 +1473,7 @@ async def pick_up_tips( else round(end_tip_pick_up_process * 10) ) minimum_traverse_height_at_beginning_of_a_command = ( - round(self._traversal_height * 10) + round(self._channel_traversal_height * 10) if minimum_traverse_height_at_beginning_of_a_command is None else round(minimum_traverse_height_at_beginning_of_a_command * 10) ) @@ -1462,12 +1550,12 @@ async def drop_tips( ) minimum_traverse_height_at_beginning_of_a_command = ( - round(self._traversal_height * 10) + round(self._channel_traversal_height * 10) if minimum_traverse_height_at_beginning_of_a_command is None else round(minimum_traverse_height_at_beginning_of_a_command * 10) ) z_position_at_end_of_a_command = ( - round(self._traversal_height * 10) + round(self._channel_traversal_height * 10) if z_position_at_end_of_a_command is None else round(z_position_at_end_of_a_command * 10) ) @@ -1507,8 +1595,10 @@ class LLDMode(enum.Enum): async def aspirate( self, - ops: List[Aspiration], + ops: List[SingleChannelAspiration], use_channels: List[int], + jet: Optional[List[bool]] = None, + blow_out: Optional[List[bool]] = None, lld_search_height: Optional[List[float]] = None, clot_detection_height: Optional[List[float]] = None, pull_out_distance_transport_air: Optional[List[float]] = None, @@ -1555,6 +1645,9 @@ async def aspirate( Args: ops: The aspiration operations to perform. use_channels: The channels to use for the operations. + jet: whether to search for a jet liquid class. Only used on dispense. Default is False. + blow_out: whether to blow out air. Only used on dispense. Note that in the VENUS Liquid + Editor, this is called "empty". Default is False. lld_search_height: The height to start searching for the liquid level when using LLD. clot_detection_height: Unknown, but probably the height to search for clots when doing LLD. @@ -1603,19 +1696,49 @@ async def aspirate( starting an aspiration. min_z_endpos: The minimum height to move to, this is the end of aspiration. + hamilton_liquid_classes: Override the default liquid classes. See + pylabrobot/liquid_handling/liquid_classes/hamilton/star.py liquid_surface_no_lld: Liquid surface at function without LLD [mm]. Must be between 0 and 360. Defaults to well bottom + liquid height. Should use absolute z. """ - if hamilton_liquid_classes is not None: - raise NotImplementedError("Hamilton liquid classes are deprecated.") - x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) n = len(ops) + if jet is None: + jet = [False] * n + if blow_out is None: + blow_out = [False] * n + + if hamilton_liquid_classes is None: + hamilton_liquid_classes = [] + for i, op in enumerate(ops): + liquid = Liquid.WATER # default to WATER + # [-1][0]: get last liquid in well, [0] is indexing into the tuple + if len(op.liquids) > 0 and op.liquids[-1][0] is not None: + liquid = op.liquids[-1][0] + + hamilton_liquid_classes.append( + get_star_liquid_class( + tip_volume=op.tip.maximal_volume, + is_core=False, + is_tip=True, + has_filter=op.tip.has_filter, + liquid=liquid, + jet=jet[i], + blow_out=blow_out[i], + ) + ) + self._assert_valid_resources([op.resource for op in ops]) + # correct volumes using the liquid class + volumes = [ + hlc.compute_corrected_volume(op.volume) if hlc is not None else op.volume + for op, hlc in zip(ops, hamilton_liquid_classes) + ] + well_bottoms = [ op.resource.get_absolute_location().z + op.offset.z + op.resource.material_z_thickness for op in ops @@ -1632,7 +1755,13 @@ async def aspirate( ] else: lld_search_height = [(wb + sh) for wb, sh in zip(well_bottoms, lld_search_height)] - clot_detection_height = _fill_in_defaults(clot_detection_height, default=[0] * n) + clot_detection_height = _fill_in_defaults( + clot_detection_height, + default=[ + hlc.aspiration_clot_retract_height if hlc is not None else 0 + for hlc in hamilton_liquid_classes + ], + ) pull_out_distance_transport_air = _fill_in_defaults(pull_out_distance_transport_air, [10] * n) second_section_height = _fill_in_defaults(second_section_height, [3.2] * n) second_section_ratio = _fill_in_defaults(second_section_ratio, [618.0] * n) @@ -1641,9 +1770,21 @@ async def aspirate( immersion_depth = _fill_in_defaults(immersion_depth, [0] * n) immersion_depth_direction = _fill_in_defaults(immersion_depth_direction, [0] * n) surface_following_distance = _fill_in_defaults(surface_following_distance, [0] * n) - flow_rates = [op.flow_rate or 100 for op in ops] - transport_air_volume = _fill_in_defaults(transport_air_volume, default=[0] * n) - blow_out_air_volumes = [op.blow_out_air_volume or 0 for op in ops] + flow_rates = [ + op.flow_rate or (hlc.aspiration_flow_rate if hlc is not None else 100) + for op, hlc in zip(ops, hamilton_liquid_classes) + ] + transport_air_volume = _fill_in_defaults( + transport_air_volume, + default=[ + hlc.aspiration_air_transport_volume if hlc is not None else 0 + for hlc in hamilton_liquid_classes + ], + ) + blow_out_air_volumes = [ + (op.blow_out_air_volume or (hlc.aspiration_blow_out_volume if hlc is not None else 0)) + for op, hlc in zip(ops, hamilton_liquid_classes) + ] pre_wetting_volume = _fill_in_defaults(pre_wetting_volume, [0] * n) lld_mode = _fill_in_defaults(lld_mode, [self.__class__.LLDMode.OFF] * n) gamma_lld_sensitivity = _fill_in_defaults(gamma_lld_sensitivity, [1] * n) @@ -1654,12 +1795,27 @@ async def aspirate( detection_height_difference_for_dual_lld = _fill_in_defaults( detection_height_difference_for_dual_lld, [0] * n ) - swap_speed = _fill_in_defaults(swap_speed, default=[100] * n) - settling_time = _fill_in_defaults(settling_time, default=[0] * n) + swap_speed = _fill_in_defaults( + swap_speed, + default=[ + hlc.aspiration_swap_speed if hlc is not None else 100 for hlc in hamilton_liquid_classes + ], + ) + settling_time = _fill_in_defaults( + settling_time, + default=[ + hlc.aspiration_settling_time if hlc is not None else 0 for hlc in hamilton_liquid_classes + ], + ) mix_volume = _fill_in_defaults(mix_volume, [0] * n) mix_cycles = _fill_in_defaults(mix_cycles, [0] * n) mix_position_from_liquid_surface = _fill_in_defaults(mix_position_from_liquid_surface, [0] * n) - mix_speed = _fill_in_defaults(mix_speed, [50] * n) + mix_speed = _fill_in_defaults( + mix_speed, + default=[ + hlc.aspiration_mix_flow_rate if hlc is not None else 50.0 for hlc in hamilton_liquid_classes + ], + ) mix_surface_following_distance = _fill_in_defaults(mix_surface_following_distance, [0] * n) limit_curve_index = _fill_in_defaults(limit_curve_index, [0] * n) @@ -1686,7 +1842,7 @@ async def aspirate( tip_pattern=channels_involved, x_positions=x_positions, y_positions=y_positions, - aspiration_volumes=[round(op.volume * 10) for op in ops], + aspiration_volumes=[round(vol * 10) for vol in volumes], lld_search_height=[round(lsh * 10) for lsh in lld_search_height], clot_detection_height=[round(cd * 10) for cd in clot_detection_height], liquid_surface_no_lld=[round(ls * 10) for ls in liquid_surfaces_no_lld], @@ -1737,9 +1893,9 @@ async def aspirate( ratio_liquid_rise_to_tip_deep_in=ratio_liquid_rise_to_tip_deep_in, immersion_depth_2nd_section=[round(id_ * 10) for id_ in immersion_depth_2nd_section], minimum_traverse_height_at_beginning_of_a_command=round( - (minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10 + (minimum_traverse_height_at_beginning_of_a_command or self._channel_traversal_height) * 10 ), - min_z_endpos=round((min_z_endpos or self._traversal_height) * 10), + min_z_endpos=round((min_z_endpos or self._channel_traversal_height) * 10), ) except STARFirmwareError as e: if plr_e := convert_star_firmware_error_to_plr_error(e): @@ -1748,7 +1904,7 @@ async def aspirate( async def dispense( self, - ops: List[Dispense], + ops: List[SingleChannelDispense], use_channels: List[int], lld_search_height: Optional[List[float]] = None, liquid_surface_no_lld: Optional[List[float]] = None, @@ -1839,9 +1995,6 @@ async def dispense( documentation. Dispense mode 4. """ - if hamilton_liquid_classes is not None: - raise NotImplementedError("Hamilton liquid classes are deprecated.") - x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) n = len(ops) @@ -1853,6 +2006,32 @@ async def dispense( if blow_out is None: blow_out = [False] * n + if hamilton_liquid_classes is None: + hamilton_liquid_classes = [] + for i, op in enumerate(ops): + liquid = Liquid.WATER # default to WATER + # [-1][0]: get last liquid in tip, [0] is indexing into the tuple + if len(op.liquids) > 0 and op.liquids[-1][0] is not None: + liquid = op.liquids[-1][0] + + hamilton_liquid_classes.append( + get_star_liquid_class( + tip_volume=op.tip.maximal_volume, + is_core=False, + is_tip=True, + has_filter=op.tip.has_filter, + liquid=liquid, + jet=jet[i], + blow_out=blow_out[i], + ) + ) + + # correct volumes using the liquid class + volumes = [ + hlc.compute_corrected_volume(op.volume) if hlc is not None else op.volume + for op, hlc in zip(ops, hamilton_liquid_classes) + ] + well_bottoms = [ op.resource.get_absolute_location().z + op.offset.z + op.resource.material_z_thickness for op in ops @@ -1875,7 +2054,6 @@ async def dispense( for i in range(len(ops)) ] - dispense_volumes = [op.volume for op in ops] pull_out_distance_transport_air = _fill_in_defaults(pull_out_distance_transport_air, [10.0] * n) second_section_height = _fill_in_defaults(second_section_height, [3.2] * n) second_section_ratio = _fill_in_defaults(second_section_ratio, [618.0] * n) @@ -1883,23 +2061,55 @@ async def dispense( immersion_depth = _fill_in_defaults(immersion_depth, [0] * n) immersion_depth_direction = _fill_in_defaults(immersion_depth_direction, [0] * n) surface_following_distance = _fill_in_defaults(surface_following_distance, [0] * n) - flow_rates = [op.flow_rate or 120 for op in ops] + flow_rates = [ + op.flow_rate or (hlc.dispense_flow_rate if hlc is not None else 120) + for op, hlc in zip(ops, hamilton_liquid_classes) + ] cut_off_speed = _fill_in_defaults(cut_off_speed, [5.0] * n) - stop_back_volume = _fill_in_defaults(stop_back_volume, default=[0] * n) - transport_air_volume = _fill_in_defaults(transport_air_volume, [0] * n) - blow_out_air_volumes = [op.blow_out_air_volume or 0 for op in ops] + stop_back_volume = _fill_in_defaults( + stop_back_volume, + default=[ + hlc.dispense_stop_back_volume if hlc is not None else 0 for hlc in hamilton_liquid_classes + ], + ) + transport_air_volume = _fill_in_defaults( + transport_air_volume, + default=[ + hlc.dispense_air_transport_volume if hlc is not None else 0 + for hlc in hamilton_liquid_classes + ], + ) + blow_out_air_volumes = [ + (op.blow_out_air_volume or (hlc.dispense_blow_out_volume if hlc is not None else 0)) + for op, hlc in zip(ops, hamilton_liquid_classes) + ] lld_mode = _fill_in_defaults(lld_mode, [self.__class__.LLDMode.OFF] * n) dispense_position_above_z_touch_off = _fill_in_defaults( dispense_position_above_z_touch_off, default=[0] * n ) gamma_lld_sensitivity = _fill_in_defaults(gamma_lld_sensitivity, [1] * n) dp_lld_sensitivity = _fill_in_defaults(dp_lld_sensitivity, [1] * n) - swap_speed = _fill_in_defaults(swap_speed, [10.0] * n) - settling_time = _fill_in_defaults(settling_time, [0] * n) + swap_speed = _fill_in_defaults( + swap_speed, + default=[ + hlc.dispense_swap_speed if hlc is not None else 10.0 for hlc in hamilton_liquid_classes + ], + ) + settling_time = _fill_in_defaults( + settling_time, + default=[ + hlc.dispense_settling_time if hlc is not None else 0 for hlc in hamilton_liquid_classes + ], + ) mix_volume = _fill_in_defaults(mix_volume, [0] * n) mix_cycles = _fill_in_defaults(mix_cycles, [0] * n) mix_position_from_liquid_surface = _fill_in_defaults(mix_position_from_liquid_surface, [0] * n) - mix_speed = _fill_in_defaults(mix_speed, [50.0] * n) + mix_speed = _fill_in_defaults( + mix_speed, + default=[ + hlc.dispense_mix_flow_rate if hlc is not None else 50.0 for hlc in hamilton_liquid_classes + ], + ) mix_surface_following_distance = _fill_in_defaults(mix_surface_following_distance, [0] * n) limit_curve_index = _fill_in_defaults(limit_curve_index, [0] * n) @@ -1909,7 +2119,7 @@ async def dispense( x_positions=x_positions, y_positions=y_positions, dispensing_mode=dispensing_modes, - dispense_volumes=[round(op.volume * 10) for op in ops], + dispense_volumes=[round(vol * 10) for vol in volumes], lld_search_height=[round(lsh * 10) for lsh in lld_search_height], liquid_surface_no_lld=[round(ls * 10) for ls in liquid_surfaces_no_lld], pull_out_distance_transport_air=[round(po * 10) for po in pull_out_distance_transport_air], @@ -1943,9 +2153,9 @@ async def dispense( ], limit_curve_index=limit_curve_index, minimum_traverse_height_at_beginning_of_a_command=round( - (minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10 + (minimum_traverse_height_at_beginning_of_a_command or self._channel_traversal_height) * 10 ), - min_z_endpos=round((min_z_endpos or self._traversal_height) * 10), + min_z_endpos=round((min_z_endpos or self._channel_traversal_height) * 10), side_touch_off_distance=side_touch_off_distance, ) except STARFirmwareError as e: @@ -1981,9 +2191,11 @@ async def pick_up_tips96( tip_pickup_method=tip_pickup_method, z_deposit_position=round(z_deposit_position * 10), minimum_traverse_height_at_beginning_of_a_command=round( - (minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10 + (minimum_traverse_height_at_beginning_of_a_command or self._channel_traversal_height) * 10 + ), + minimum_height_command_end=round( + (minimum_height_command_end or self._channel_traversal_height) * 10 ), - minimum_height_command_end=round((minimum_height_command_end or self._traversal_height) * 10), ) async def drop_tips96( @@ -1999,7 +2211,7 @@ async def drop_tips96( tip_a1 = drop.resource.get_item("A1") position = tip_a1.get_absolute_location() + tip_a1.center() + drop.offset else: - position = drop.resource.get_absolute_location() + drop.offset + position = self._position_96_head_in_resource(drop.resource) + drop.offset x_direction = 0 if position.x > 0 else 1 return await self.discard_tips_core96( @@ -2008,14 +2220,18 @@ async def drop_tips96( y_position=round(position.y * 10), z_deposit_position=round(z_deposit_position * 10), minimum_traverse_height_at_beginning_of_a_command=round( - (minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10 + (minimum_traverse_height_at_beginning_of_a_command or self._channel_traversal_height) * 10 + ), + minimum_height_command_end=round( + (minimum_height_command_end or self._channel_traversal_height) * 10 ), - minimum_height_command_end=round((minimum_height_command_end or self._traversal_height) * 10), ) async def aspirate96( self, - aspiration: Union[AspirationPlate, AspirationContainer], + aspiration: Union[MultiHeadAspirationPlate, MultiHeadAspirationContainer], + jet: bool = False, + blow_out: bool = False, use_lld: bool = False, liquid_height: float = 0, air_transport_retract_dist: float = 10, @@ -2039,7 +2255,7 @@ async def aspirate96( mix_cycles: int = 0, mix_position_from_liquid_surface: float = 0, surface_following_distance_during_mix: float = 0, - mix_speed: float = 120.0, + speed_of_mix: float = 120.0, limit_curve_index: int = 0, ): """Aspirate using the Core96 head. @@ -2047,6 +2263,13 @@ async def aspirate96( Args: aspiration: The aspiration to perform. + jet: Whether to search for a jet liquid class. Only used on dispense. + blow_out: Whether to use "blow out" dispense mode. Only used on dispense. Note that this is + labelled as "empty" in the VENUS liquid editor, but "blow out" in the firmware + documentation. + hlc: The Hamiltonian liquid class to use. If `None`, the liquid class will be determined + automatically. + use_lld: If True, use gamma liquid level detection. If False, use liquid height. liquid_height: The height of the liquid above the bottom of the well, in millimeters. air_transport_retract_dist: The distance to retract after aspirating, in millimeters. @@ -2075,17 +2298,14 @@ async def aspirate96( liquid surface. surface_following_distance_during_mix: The distance to follow the liquid surface during mix. - mix_speed: The speed of mix. + speed_of_mix: The speed of mix. limit_curve_index: The index of the limit curve to use. """ - if hlc is not None: - raise NotImplementedError("Hamilton liquid classes are deprecated.") - assert self.core96_head_installed, "96 head must be installed" # get the first well and tip as representatives - if isinstance(aspiration, AspirationPlate): + if isinstance(aspiration, MultiHeadAspirationPlate): top_left_well = aspiration.wells[0] position = ( top_left_well.get_absolute_location() @@ -2096,36 +2316,66 @@ async def aspirate96( else: position = aspiration.container.get_absolute_location(y="b") + aspiration.offset + tip = aspiration.tips[0] + liquid_height = position.z + liquid_height - if transport_air_volume is None: - transport_air_volume = 0 - if aspiration.blow_out_air_volume is None: - blow_out_air_volume = 0.0 - else: - blow_out_air_volume = aspiration.blow_out_air_volume - if aspiration.flow_rate is None: - flow_rate = 250.0 + liquid_to_be_aspirated = Liquid.WATER + if len(aspiration.liquids[0]) > 0 and aspiration.liquids[0][0][0] is not None: + # [channel][liquid][PyLabRobot.resources.liquid.Liquid] + liquid_to_be_aspirated = aspiration.liquids[0][0][0] + hlc = hlc or get_star_liquid_class( + tip_volume=tip.maximal_volume, + is_core=True, + is_tip=True, + has_filter=tip.has_filter, + # get last liquid in pipette, first to be dispensed + liquid=liquid_to_be_aspirated, + jet=jet, + blow_out=blow_out, # see comment in method docstring + ) + + if hlc is not None: + volume = hlc.compute_corrected_volume(aspiration.volume) else: - flow_rate = aspiration.flow_rate - if swap_speed is None: - swap_speed = 100 - if settling_time is None: - settling_time = 0.5 - if mix_speed is None: - mix_speed = 10.0 + volume = aspiration.volume + + # Get better default values from the HLC if available + transport_air_volume = transport_air_volume or ( + hlc.aspiration_air_transport_volume if hlc is not None else 0 + ) + blow_out_air_volume = aspiration.blow_out_air_volume or ( + hlc.aspiration_blow_out_volume if hlc is not None else 0 + ) + flow_rate = aspiration.flow_rate or (hlc.aspiration_flow_rate if hlc is not None else 250) + swap_speed = swap_speed or (hlc.aspiration_swap_speed if hlc is not None else 100) + settling_time = settling_time or (hlc.aspiration_settling_time if hlc is not None else 0.5) + speed_of_mix = speed_of_mix or (hlc.aspiration_mix_flow_rate if hlc is not None else 10.0) channel_pattern = [True] * 12 * 8 + # Was this ever true? Just copied it over from pyhamilton. Could have something to do with + # the liquid classes and whether blow_out mode is enabled. + # # Unfortunately, `blow_out_air_volume` does not work correctly, so instead we aspirate air + # # manually. + # if blow_out_air_volume is not None and blow_out_air_volume > 0: + # await self.aspirate_core_96( + # x_position=int(position.x * 10), + # y_positions=int(position.y * 10), + # lld_mode=0, + # liquid_surface_at_function_without_lld=int((liquid_height + 30) * 10), + # aspiration_volumes=int(blow_out_air_volume * 10) + # ) + return await self.aspirate_core_96( x_position=round(position.x * 10), x_direction=0, y_positions=round(position.y * 10), aspiration_type=aspiration_type, minimum_traverse_height_at_beginning_of_a_command=round( - (minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10 + (minimum_traverse_height_at_beginning_of_a_command or self._channel_traversal_height) * 10 ), - minimal_end_height=round((minimal_end_height or self._traversal_height) * 10), + minimal_end_height=round((minimal_end_height or self._channel_traversal_height) * 10), lld_search_height=round(lld_search_height * 10), liquid_surface_at_function_without_lld=round(liquid_height * 10), pull_out_distance_to_take_transport_air_in_function_without_lld=round( @@ -2139,7 +2389,7 @@ async def aspirate96( liquid_surface_sink_distance_at_the_end_of_aspiration=round( liquid_surface_sink_distance_at_the_end_of_aspiration * 10 ), - aspiration_volumes=round(aspiration.volume * 10), + aspiration_volumes=round(volume * 10), aspiration_speed=round(flow_rate * 10), transport_air_volume=round(transport_air_volume * 10), blow_out_air_volume=round(blow_out_air_volume * 10), @@ -2152,7 +2402,7 @@ async def aspirate96( mix_cycles=mix_cycles, mix_position_from_liquid_surface=round(mix_position_from_liquid_surface * 10), surface_following_distance_during_mix=round(surface_following_distance_during_mix * 10), - mix_speed=round(mix_speed * 10), + speed_of_mix=round(speed_of_mix * 10), channel_pattern=channel_pattern, limit_curve_index=limit_curve_index, tadm_algorithm=False, @@ -2161,7 +2411,7 @@ async def aspirate96( async def dispense96( self, - dispense: Union[DispensePlate, DispenseContainer], + dispense: Union[MultiHeadDispensePlate, MultiHeadDispenseContainer], jet: bool = False, empty: bool = False, blow_out: bool = False, @@ -2187,7 +2437,7 @@ async def dispense96( mixing_cycles: int = 0, mixing_position_from_liquid_surface: float = 0, surface_following_distance_during_mixing: float = 0, - mix_speed: float = 120.0, + speed_of_mixing: float = 120.0, limit_curve_index: int = 0, cut_off_speed: float = 5.0, stop_back_volume: float = 0, @@ -2223,19 +2473,16 @@ async def dispense96( mixing_cycles: Mixing cycles. mixing_position_from_liquid_surface: Mixing position from liquid surface, in mm. surface_following_distance_during_mixing: Surface following distance during mixing, in mm. - mix_speed: Speed of mixing, in ul/s. + speed_of_mixing: Speed of mixing, in ul/s. limit_curve_index: Limit curve index. cut_off_speed: Unknown. stop_back_volume: Unknown. """ - if hlc is not None: - raise NotImplementedError("Hamilton liquid classes are deprecated.") - assert self.core96_head_installed, "96 head must be installed" # get the first well and tip as representatives - if isinstance(dispense, DispensePlate): + if isinstance(dispense, MultiHeadDispensePlate): top_left_well = dispense.wells[0] position = ( top_left_well.get_absolute_location() @@ -2245,27 +2492,42 @@ async def dispense96( ) else: position = dispense.container.get_absolute_location(y="b") + dispense.offset + tip = dispense.tips[0] liquid_height = position.z + liquid_height dispense_mode = _dispensing_mode_for_op(empty=empty, jet=jet, blow_out=blow_out) - if transport_air_volume is None: - transport_air_volume = 0 - if dispense.blow_out_air_volume is None: - blow_out_air_volume = 0.0 - else: - blow_out_air_volume = dispense.blow_out_air_volume - if dispense.flow_rate is None: - flow_rate = 120.0 + liquid_to_be_dispensed = Liquid.WATER # default to water. + if len(dispense.liquids[0]) > 0 and dispense.liquids[0][-1][0] is not None: + # [channel][liquid][PyLabRobot.resources.liquid.Liquid] + liquid_to_be_dispensed = dispense.liquids[0][-1][0] + hlc = hlc or get_star_liquid_class( + tip_volume=tip.maximal_volume, + is_core=True, + is_tip=True, + has_filter=tip.has_filter, + # get last liquid in pipette, first to be dispensed + liquid=liquid_to_be_dispensed, + jet=jet, + blow_out=blow_out, # see comment in method docstring + ) + + if hlc is not None: + volume = hlc.compute_corrected_volume(dispense.volume) else: - flow_rate = dispense.flow_rate - if swap_speed is None: - swap_speed = 100 - if settling_time is None: - settling_time = 5 - if mix_speed is None: - mix_speed = 100 + volume = dispense.volume + + transport_air_volume = transport_air_volume or ( + hlc.dispense_air_transport_volume if hlc is not None else 0 + ) + blow_out_air_volume = dispense.blow_out_air_volume or ( + hlc.dispense_blow_out_volume if hlc is not None else 0 + ) + flow_rate = dispense.flow_rate or (hlc.dispense_flow_rate if hlc is not None else 120) + swap_speed = swap_speed or (hlc.dispense_swap_speed if hlc is not None else 100) + settling_time = settling_time or (hlc.dispense_settling_time if hlc is not None else 5) + speed_of_mixing = speed_of_mixing or (hlc.dispense_mix_flow_rate if hlc is not None else 100) channel_pattern = [True] * 12 * 8 @@ -2275,9 +2537,9 @@ async def dispense96( x_direction=0, y_position=round(position.y * 10), minimum_traverse_height_at_beginning_of_a_command=round( - (minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10 + (minimum_traverse_height_at_beginning_of_a_command or self._channel_traversal_height) * 10 ), - minimal_end_height=round((minimal_end_height or self._traversal_height) * 10), + minimal_end_height=round((minimal_end_height or self._channel_traversal_height) * 10), lld_search_height=round(lld_search_height * 10), liquid_surface_at_function_without_lld=round(liquid_height * 10), pull_out_distance_to_take_transport_air_in_function_without_lld=round( @@ -2291,7 +2553,7 @@ async def dispense96( liquid_surface_sink_distance_at_the_end_of_dispense=round( liquid_surface_sink_distance_at_the_end_of_dispense * 10 ), - dispense_volume=round(dispense.volume * 10), + dispense_volume=round(volume * 10), dispense_speed=round(flow_rate * 10), transport_air_volume=round(transport_air_volume * 10), blow_out_air_volume=round(blow_out_air_volume * 10), @@ -2303,7 +2565,7 @@ async def dispense96( mixing_cycles=mixing_cycles, mixing_position_from_liquid_surface=round(mixing_position_from_liquid_surface * 10), surface_following_distance_during_mixing=round(surface_following_distance_during_mixing * 10), - mix_speed=round(mix_speed * 10), + speed_of_mixing=round(speed_of_mixing * 10), channel_pattern=channel_pattern, limit_curve_index=limit_curve_index, tadm_algorithm=False, @@ -2327,64 +2589,6 @@ async def dispense96( return ret - async def iswap_pick_up_resource( - self, - resource: Resource, - grip_direction: GripDirection, - pickup_distance_from_top: float, - offset: Coordinate = Coordinate.zero(), - minimum_traverse_height_at_beginning_of_a_command: float = 284.0, - z_position_at_the_command_end: float = 284.0, - grip_strength: int = 4, - plate_width_tolerance: float = 2.0, - collision_control_level: int = 0, - acceleration_index_high_acc: int = 4, - acceleration_index_low_acc: int = 1, - fold_up_sequence_at_the_end_of_process: bool = True, - ): - """Pick up a resource using iSWAP. - Low level component of :meth:`move_resource` - """ - - assert self.iswap_installed, "iswap must be installed" - - # Get center of source plate. Also gripping height and plate width. - center = resource.get_absolute_location(x="c", y="c", z="b") + offset - grip_height = center.z + resource.get_absolute_size_z() - pickup_distance_from_top - if grip_direction in (GripDirection.FRONT, GripDirection.BACK): - plate_width = resource.get_absolute_size_x() - elif grip_direction in (GripDirection.RIGHT, GripDirection.LEFT): - plate_width = resource.get_absolute_size_y() - else: - raise ValueError("Invalid grip direction") - - await self.iswap_get_plate( - x_position=round(center.x * 10), - x_direction=0, - y_position=round(center.y * 10), - y_direction=0, - z_position=round(grip_height * 10), - z_direction=0, - grip_direction={ - GripDirection.FRONT: 1, - GripDirection.RIGHT: 2, - GripDirection.BACK: 3, - GripDirection.LEFT: 4, - }[grip_direction], - minimum_traverse_height_at_beginning_of_a_command=round( - minimum_traverse_height_at_beginning_of_a_command * 10 - ), - z_position_at_the_command_end=round(z_position_at_the_command_end * 10), - grip_strength=grip_strength, - open_gripper_position=round(plate_width * 10) + 30, - plate_width=round(plate_width * 10) - 33, - plate_width_tolerance=round(plate_width_tolerance * 10), - collision_control_level=collision_control_level, - acceleration_index_high_acc=acceleration_index_high_acc, - acceleration_index_low_acc=acceleration_index_low_acc, - fold_up_sequence_at_the_end_of_process=fold_up_sequence_at_the_end_of_process, - ) - async def iswap_move_picked_up_resource( self, location: Coordinate, @@ -2424,76 +2628,6 @@ async def iswap_move_picked_up_resource( acceleration_index_low_acc=acceleration_index_low_acc, ) - async def iswap_release_picked_up_resource( - self, - location: Coordinate, - resource: Resource, - rotation: int, - offset: Coordinate, - grip_direction: GripDirection, - pickup_distance_from_top: float, - minimum_traverse_height_at_beginning_of_a_command: float = 284.0, - z_position_at_the_command_end: float = 284.0, - collision_control_level: int = 0, - ): - """After a resource is picked up, release it at the specified location. - Low level component of :meth:`move_resource` - - Args: - location: The location to release the resource (bottom front left corner). - resource: The resource to release. - rotation: The rotation of the resource's final orientation wrt the pickup orientation. - offset: offset for location - grip_direction: The direction of the iswap arm on release. - pickup_distance_from_top: How far from the top the resource was picked up. - """ - - assert self.iswap_installed, "iswap must be installed" - - # Get center of source plate in absolute space. - # The computation of the center has to be rotated so that the offset is in absolute space. - center_in_absolute_space = Coordinate( - *matrix_vector_multiply_3x3( - resource.rotated(z=rotation).get_absolute_rotation().get_rotation_matrix(), - resource.center().vector(), - ) - ) - # This is when the resource is rotated (around its origin), but we also need to translate - # so that the left front bottom corner of the plate is lfb in absolute space, not local. - center_in_absolute_space += get_child_location(resource.rotated(z=rotation)) - - center = location + center_in_absolute_space + offset - grip_height = center.z + resource.get_absolute_size_z() - pickup_distance_from_top - # grip_direction here is the put_direction. We use `rotation` to cancel it out and get the - # original grip direction. Hack. - if grip_direction in (GripDirection.FRONT, GripDirection.BACK): - plate_width = resource.rotated(z=rotation).get_absolute_size_x() - elif grip_direction in (GripDirection.RIGHT, GripDirection.LEFT): - plate_width = resource.rotated(z=rotation).get_absolute_size_y() - else: - raise ValueError("Invalid grip direction") - - await self.iswap_put_plate( - x_position=round(center.x * 10), - x_direction=0, - y_position=round(center.y * 10), - y_direction=0, - z_position=round(grip_height * 10), - z_direction=0, - grip_direction={ - GripDirection.FRONT: 1, - GripDirection.RIGHT: 2, - GripDirection.BACK: 3, - GripDirection.LEFT: 4, - }[grip_direction], - minimum_traverse_height_at_beginning_of_a_command=round( - minimum_traverse_height_at_beginning_of_a_command * 10 - ), - z_position_at_the_command_end=round(z_position_at_the_command_end * 10), - open_gripper_position=round(plate_width * 10) + 30, - collision_control_level=collision_control_level, - ) - async def core_pick_up_resource( self, resource: Resource, @@ -2543,10 +2677,10 @@ async def core_pick_up_resource( plate_width=round(grip_width * 10) - 30, grip_strength=grip_strength, minimum_traverse_height_at_beginning_of_a_command=round( - (minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10 + (minimum_traverse_height_at_beginning_of_a_command or self._iswap_traversal_height) * 10 ), minimum_z_position_at_the_command_end=round( - (minimum_z_position_at_the_command_end or self._traversal_height) * 10 + (minimum_z_position_at_the_command_end or self._iswap_traversal_height) * 10 ), ) @@ -2583,7 +2717,7 @@ async def core_move_picked_up_resource( z_position=round(center.z * 10), z_speed=round(z_speed * 10), minimum_traverse_height_at_beginning_of_a_command=round( - (minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10 + (minimum_traverse_height_at_beginning_of_a_command or self._iswap_traversal_height) * 10 ), ) @@ -2592,7 +2726,6 @@ async def core_release_picked_up_resource( location: Coordinate, resource: Resource, pickup_distance_from_top: float, - offset: Coordinate = Coordinate.zero(), minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, z_position_at_the_command_end: Optional[float] = None, return_tool: bool = True, @@ -2613,134 +2746,323 @@ async def core_release_picked_up_resource( """ # Get center of destination location. Also gripping height and plate width. - center = location + resource.center() + offset - grip_height = center.z + resource.get_absolute_size_z() - pickup_distance_from_top + grip_height = location.z + resource.get_absolute_size_z() - pickup_distance_from_top grip_width = resource.get_absolute_size_y() await self.core_put_plate( - x_position=round(center.x * 10), + x_position=round(location.x * 10), x_direction=0, - y_position=round(center.y * 10), + y_position=round(location.y * 10), z_position=round(grip_height * 10), z_press_on_distance=0, z_speed=500, open_gripper_position=round(grip_width * 10) + 30, minimum_traverse_height_at_beginning_of_a_command=round( - (minimum_traverse_height_at_beginning_of_a_command or self._traversal_height) * 10 + (minimum_traverse_height_at_beginning_of_a_command or self._iswap_traversal_height) * 10 ), z_position_at_the_command_end=round( - (z_position_at_the_command_end or self._traversal_height) * 10 + (z_position_at_the_command_end or self._iswap_traversal_height) * 10 ), return_tool=return_tool, ) - async def move_resource( + async def pick_up_resource( self, - move: Move, + pickup: ResourcePickup, use_arm: Literal["iswap", "core"] = "iswap", channel_1: int = 7, channel_2: int = 8, + iswap_grip_strength: int = 4, core_grip_strength: int = 15, - return_core_gripper: bool = True, + minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, + z_position_at_the_command_end: Optional[float] = None, + plate_width_tolerance: float = 2.0, + open_gripper_position: Optional[float] = None, + hotel_depth=160.0, + hotel_clearance_height=7.5, + high_speed=False, + plate_width: Optional[float] = None, + use_unsafe_hotel: bool = False, + iswap_collision_control_level: int = 0, + iswap_fold_up_sequence_at_the_end_of_process: bool = True, ): - """Move a resource. + if use_arm == "iswap": + assert ( + pickup.resource.get_absolute_rotation().x == 0 + and pickup.resource.get_absolute_rotation().y == 0 + ) + assert pickup.resource.get_absolute_rotation().z % 90 == 0 + if plate_width is None: + if pickup.direction in (GripDirection.FRONT, GripDirection.BACK): + plate_width = pickup.resource.get_absolute_size_x() + else: + plate_width = pickup.resource.get_absolute_size_y() - Args: - move: The move to perform. - use_arm: Which arm to use. Either "iswap" or "core". - channel_1: The first channel to use with the core arm. Only used if `use_arm` is "core". - channel_2: The second channel to use with the core arm. Only used if `use_arm` is "core". - core_grip_strength: The grip strength to use with the core arm. Only used if `use_arm` is - "core". - return_core_gripper: Whether to return the core gripper to the home position after the move. - Only used if `use_arm` is "core". - """ + center_in_absolute_space = pickup.resource.center().rotated( + pickup.resource.get_absolute_rotation() + ) + x, y, z = ( + pickup.resource.get_absolute_location("l", "f", "t") + + center_in_absolute_space + + pickup.offset + ) + z -= pickup.pickup_distance_from_top + + traverse_height_at_beginning = ( + minimum_traverse_height_at_beginning_of_a_command or self._iswap_traversal_height + ) + z_position_at_the_command_end = z_position_at_the_command_end or self._iswap_traversal_height + + if open_gripper_position is None: + if use_unsafe_hotel: + open_gripper_position = plate_width + 5 + else: + open_gripper_position = plate_width + 3 + + if use_unsafe_hotel: + await self.unsafe.get_from_hotel( + hotel_center_x_coord=round(abs(x) * 10), + hotel_center_y_coord=round(abs(y) * 10), + # hotel_center_z_coord=int((z * 10)+0.5), # use sensible rounding (.5 goes up) + hotel_center_z_coord=round(abs(z) * 10), + hotel_center_x_direction=0 if x >= 0 else 1, + hotel_center_y_direction=0 if y >= 0 else 1, + hotel_center_z_direction=0 if z >= 0 else 1, + clearance_height=round(hotel_clearance_height * 10), + hotel_depth=round(hotel_depth * 10), + grip_direction=pickup.direction, + open_gripper_position=round(open_gripper_position * 10), + traverse_height_at_beginning=round(traverse_height_at_beginning * 10), + z_position_at_end=round(z_position_at_the_command_end * 10), + high_acceleration_index=4 if high_speed else 1, + low_acceleration_index=1, + plate_width=round(plate_width * 10), + plate_width_tolerance=round(plate_width_tolerance * 10), + ) + else: + await self.iswap_get_plate( + x_position=round(x * 10), + y_position=round(y * 10), + z_position=round(z * 10), + x_direction=0 if x >= 0 else 1, + y_direction=0 if y >= 0 else 1, + z_direction=0 if z >= 0 else 1, + grip_direction={ + GripDirection.FRONT: 1, + GripDirection.RIGHT: 2, + GripDirection.BACK: 3, + GripDirection.LEFT: 4, + }[pickup.direction], + minimum_traverse_height_at_beginning_of_a_command=round( + traverse_height_at_beginning * 10 + ), + z_position_at_the_command_end=round(z_position_at_the_command_end * 10), + grip_strength=iswap_grip_strength, + open_gripper_position=round(open_gripper_position * 10), + plate_width=round(plate_width * 10) - 33, + plate_width_tolerance=round(plate_width_tolerance * 10), + collision_control_level=iswap_collision_control_level, + acceleration_index_high_acc=4 if high_speed else 1, + acceleration_index_low_acc=1, + fold_up_sequence_at_the_end_of_process=iswap_fold_up_sequence_at_the_end_of_process, + ) + elif use_arm == "core": + if use_unsafe_hotel: + raise ValueError("Cannot use iswap hotel mode with core grippers") - if not use_arm in {"iswap", "core"}: + await self.core_pick_up_resource( + resource=pickup.resource, + pickup_distance_from_top=pickup.pickup_distance_from_top, + offset=pickup.offset, + minimum_traverse_height_at_beginning_of_a_command=self._iswap_traversal_height, + minimum_z_position_at_the_command_end=self._iswap_traversal_height, + channel_1=channel_1, + channel_2=channel_2, + grip_strength=core_grip_strength, + ) + else: raise ValueError(f"use_arm must be either 'iswap' or 'core', not {use_arm}") + async def move_picked_up_resource( + self, move: ResourceMove, use_arm: Literal["iswap", "core"] = "iswap" + ): if use_arm == "iswap": - await self.iswap_pick_up_resource( + await self.iswap_move_picked_up_resource( + location=move.location, resource=move.resource, - grip_direction=move.get_direction, - pickup_distance_from_top=move.pickup_distance_from_top, - offset=move.resource_offset, - minimum_traverse_height_at_beginning_of_a_command=self._traversal_height, - z_position_at_the_command_end=self._traversal_height, + grip_direction=move.gripped_direction, + minimum_traverse_height_at_beginning_of_a_command=self._iswap_traversal_height, + collision_control_level=1, + acceleration_index_high_acc=4, + acceleration_index_low_acc=1, ) else: - await self.core_pick_up_resource( + await self.core_move_picked_up_resource( + location=move.location, resource=move.resource, - pickup_distance_from_top=move.pickup_distance_from_top, - offset=move.resource_offset, - minimum_traverse_height_at_beginning_of_a_command=self._traversal_height, - minimum_z_position_at_the_command_end=self._traversal_height, - channel_1=channel_1, - channel_2=channel_2, - grip_strength=core_grip_strength, + minimum_traverse_height_at_beginning_of_a_command=self._iswap_traversal_height, + acceleration_index=4, ) - previous_location = move.resource.get_absolute_location() + move.resource_offset - minimum_traverse_height = 284.0 - previous_location.z = minimum_traverse_height - move.resource.get_absolute_size_z() / 2 - - for location in move.intermediate_locations: - if use_arm == "iswap": - await self.iswap_move_picked_up_resource( - location=location, - resource=move.resource, - grip_direction=move.get_direction, - minimum_traverse_height_at_beginning_of_a_command=self._traversal_height, - # int(previous_location.z + move.resource.get_size_z() / 2) * 10, # "minimum" is a scam. - collision_control_level=1, - acceleration_index_high_acc=4, - acceleration_index_low_acc=1, + async def drop_resource( + self, + drop: ResourceDrop, + use_arm: Literal["iswap", "core"] = "iswap", + return_core_gripper: bool = True, + minimum_traverse_height_at_beginning_of_a_command: Optional[float] = None, + z_position_at_the_command_end: Optional[float] = None, + open_gripper_position: Optional[float] = None, + hotel_depth=160.0, + hotel_clearance_height=7.5, + hotel_high_speed=False, + use_unsafe_hotel: bool = False, + iswap_collision_control_level: int = 0, + ): + # Get center of source plate in absolute space. + # The computation of the center has to be rotated so that the offset is in absolute space. + # center_in_absolute_space will be the vector pointing from the destination origin to the + # center of the moved the resource after drop. + # This means that the center vector has to be rotated from the child local space by the + # new child absolute rotation. The moved resource's rotation will be the original child + # rotation plus the rotation applied by the movement. + # The resource is moved by drop.rotation + # The new resource absolute location is + # drop.resource.get_absolute_rotation().z + drop.rotation + center_in_absolute_space = drop.resource.center().rotated( + Rotation(z=drop.resource.get_absolute_rotation().z + drop.rotation) + ) + x, y, z = drop.destination + center_in_absolute_space + drop.offset + + if use_arm == "iswap": + traversal_height_start = ( + minimum_traverse_height_at_beginning_of_a_command or self._iswap_traversal_height + ) + z_position_at_the_command_end = z_position_at_the_command_end or self._iswap_traversal_height + assert ( + drop.resource.get_absolute_rotation().x == 0 + and drop.resource.get_absolute_rotation().y == 0 + ) + assert drop.resource.get_absolute_rotation().z % 90 == 0 + + # Use the pickup direction to determine how wide the plate is gripped. + # Note that the plate is still in the original orientation at this point, + # so get_absolute_size_{x,y}() will return the size of the plate in the original orientation. + if ( + drop.pickup_direction == GripDirection.FRONT or drop.pickup_direction == GripDirection.BACK + ): + plate_width = drop.resource.get_absolute_size_x() + elif ( + drop.pickup_direction == GripDirection.RIGHT or drop.pickup_direction == GripDirection.LEFT + ): + plate_width = drop.resource.get_absolute_size_y() + else: + raise ValueError("Invalid grip direction") + + z = z + drop.resource.get_absolute_size_z() - drop.pickup_distance_from_top + + if open_gripper_position is None: + if use_unsafe_hotel: + open_gripper_position = plate_width + 5 + else: + open_gripper_position = plate_width + 3 + + if use_unsafe_hotel: + # hotel: down forward down. + # down to level of the destination + the clearance height (so clearance height can be subtracted) + # hotel_depth is forward. + # clearance height is second down. + + await self.unsafe.put_in_hotel( + hotel_center_x_coord=round(abs(x) * 10), + hotel_center_y_coord=round(abs(y) * 10), + hotel_center_z_coord=round(abs(z) * 10), + hotel_center_x_direction=0 if x >= 0 else 1, + hotel_center_y_direction=0 if y >= 0 else 1, + hotel_center_z_direction=0 if z >= 0 else 1, + clearance_height=round(hotel_clearance_height * 10), + hotel_depth=round(hotel_depth * 10), + grip_direction=drop.drop_direction, + open_gripper_position=round(open_gripper_position * 10), + traverse_height_at_beginning=round(traversal_height_start * 10), + z_position_at_end=round(z_position_at_the_command_end * 10), + high_acceleration_index=4 if hotel_high_speed else 1, + low_acceleration_index=1, ) else: - await self.core_move_picked_up_resource( - location=location, - resource=move.resource, - minimum_traverse_height_at_beginning_of_a_command=self._traversal_height, - # int(previous_location.z + move.resource.get_size_z() / 2) * 10, - acceleration_index=4, + await self.iswap_put_plate( + x_position=round(abs(x) * 10), + y_position=round(abs(y) * 10), + z_position=round(abs(z) * 10), + x_direction=0 if x >= 0 else 1, + y_direction=0 if y >= 0 else 1, + z_direction=0 if z >= 0 else 1, + grip_direction={ + GripDirection.FRONT: 1, + GripDirection.RIGHT: 2, + GripDirection.BACK: 3, + GripDirection.LEFT: 4, + }[drop.drop_direction], + minimum_traverse_height_at_beginning_of_a_command=round(traversal_height_start * 10), + z_position_at_the_command_end=round(z_position_at_the_command_end * 10), + open_gripper_position=round(open_gripper_position * 10), + collision_control_level=iswap_collision_control_level, ) - previous_location = location + elif use_arm == "core": + if use_unsafe_hotel: + raise ValueError("Cannot use iswap hotel mode with core grippers") - if use_arm == "iswap": - await self.iswap_release_picked_up_resource( - location=move.destination, - resource=move.resource, - rotation=move.rotation, - offset=move.destination_offset, - grip_direction=move.put_direction, - pickup_distance_from_top=move.pickup_distance_from_top, - minimum_traverse_height_at_beginning_of_a_command=self._traversal_height, - # int(previous_location.z + move.resource.get_size_z() / 2) * 10, # "minimum" is a scam. - z_position_at_the_command_end=self._traversal_height, - ) - else: await self.core_release_picked_up_resource( - location=move.destination, - resource=move.resource, - offset=move.destination_offset, - pickup_distance_from_top=move.pickup_distance_from_top, - minimum_traverse_height_at_beginning_of_a_command=self._traversal_height, - z_position_at_the_command_end=self._traversal_height, + location=Coordinate(x, y, z), + resource=drop.resource, + pickup_distance_from_top=drop.pickup_distance_from_top, + minimum_traverse_height_at_beginning_of_a_command=self._iswap_traversal_height, + z_position_at_the_command_end=self._iswap_traversal_height, # int(previous_location.z + move.resource.get_size_z() / 2) * 10, return_tool=return_core_gripper, ) + else: + raise ValueError(f"use_arm must be either 'iswap' or 'core', not {use_arm}") async def prepare_for_manual_channel_operation(self, channel: int): """Prepare for manual operation.""" - await self.position_max_free_y_for_n(pipetting_channel_index=channel + 1) + await self.position_max_free_y_for_n(pipetting_channel_index=channel) - async def move_channel_x(self, channel: int, x: float): # pylint: disable=unused-argument + async def move_channel_x(self, channel: int, x: float): """Move a channel in the x direction.""" await self.position_left_x_arm_(round(x * 10)) + @need_iswap_parked async def move_channel_y(self, channel: int, y: float): - """Move a channel in the y direction.""" + """Move a channel safely in the y direction.""" + + # Anti-channel-crash feature + if channel > 0: + max_y_pos = await self.request_y_pos_channel_n(channel - 1) + if y > max_y_pos: + raise ValueError( + f"channel {channel} y-target must be <= {max_y_pos} mm " + f"(channel {channel - 1} y-position is {round(y, 2)} mm)" + ) + else: + # STAR machines appear to lose connection to a channel if y > 635 mm + max_y_pos = 635 + if y > max_y_pos: + raise ValueError(f"channel {channel} y-target must be <= {max_y_pos} mm (machine limit)") + + if channel < (self.num_channels - 1): + min_y_pos = await self.request_y_pos_channel_n(channel + 1) + if y < min_y_pos: + raise ValueError( + f"channel {channel} y-target must be >= {min_y_pos} mm " + f"(channel {channel + 1} y-position is {round(y, 2)} mm)" + ) + else: + # STAR machines appear to lose connection to a channel if y < 6 mm + min_y_pos = 6 + if y < min_y_pos: + raise ValueError(f"channel {channel} y-target must be >= {min_y_pos} mm (machine limit)") + await self.position_single_pipetting_channel_in_y_direction( pipetting_channel_index=channel + 1, y_position=round(y * 10) ) @@ -2856,6 +3178,17 @@ async def core_check_resource_exists_at_location_center( audio.play_got_item() return True + def _position_96_head_in_resource(self, resource: Resource) -> Coordinate: + """The firmware command expects location of tip A1 of the head. We center the head in the given + resource.""" + head_size_x = 9 * 11 # 12 channels, 9mm spacing in between + head_size_y = 9 * 7 # 8 channels, 9mm spacing in between + channel_size = 9 + loc = resource.get_absolute_location() + loc.x += (resource.get_size_x() - head_size_x) / 2 + channel_size / 2 + loc.y += (resource.get_size_y() - head_size_y) / 2 + channel_size / 2 + return loc + # ============== Firmware Commands ============== # -------------- 3.2 System general commands -------------- @@ -2887,8 +3220,6 @@ async def define_tip_needle( power OFF or RESET. After power ON the default values apply. (see Table 3) """ - # pylint: disable=redefined-builtin - assert 0 <= tip_type_table_index <= 99, "tip_type_table_index must be between 0 and 99" assert 0 <= tip_type_table_index <= 99, "tip_type_table_index must be between 0 and 99" assert 1 <= tip_length <= 1999, "tip_length must be between 1 and 1999" @@ -2951,8 +3282,6 @@ async def request_electronic_board_type(self): The board type. """ - # pylint: disable=undefined-variable - resp = await self.send_command(module="C0", command="QB") try: return STAR.BoardType(resp["qb"]) @@ -3076,7 +3405,9 @@ async def set_not_stop(self, non_stop): # -------------- 3.3.2 Non volatile settings (stored in EEPROM) -------------- async def store_installation_data( - self, date: datetime.datetime = datetime.datetime.now(), serial_number: str = "0000" + self, + date: datetime.datetime = datetime.datetime.now(), + serial_number: str = "0000", ): """Store installation data @@ -3723,7 +4054,7 @@ async def pick_up_tip( module="C0", command="TP", tip_pattern=tip_pattern, - read_timeout=60, + read_timeout=max(120, self.read_timeout), xp=[f"{x:05}" for x in x_positions], yp=[f"{y:04}" for y in y_positions], tm=tip_pattern, @@ -3788,6 +4119,7 @@ async def discard_tip( module="C0", command="TR", tip_pattern=tip_pattern, + read_timeout=max(120, self.read_timeout), fmt="kz### (n)vz### (n)", xp=[f"{x:05}" for x in x_positions], yp=[f"{y:04}" for y in y_positions], @@ -4043,7 +4375,7 @@ async def aspirate_pip( module="C0", command="AS", tip_pattern=tip_pattern, - read_timeout=max(60, self.read_timeout), + read_timeout=max(120, self.read_timeout), at=[f"{at:01}" for at in aspiration_type], tm=tip_pattern, xp=[f"{xp:05}" for xp in x_positions], @@ -4277,7 +4609,7 @@ async def dispense_pip( module="C0", command="DS", tip_pattern=tip_pattern, - read_timeout=max(60, self.read_timeout), + read_timeout=max(120, self.read_timeout), dm=[f"{dm:01}" for dm in dispensing_mode], tm=[f"{tm:01}" for tm in tip_pattern], xp=[f"{xp:05}" for xp in x_positions], @@ -4354,7 +4686,7 @@ async def get_core(self, p1: int, p2: int): pb=f"{p2:02}", tp=f"{2350 + self.core_adjustment.z:04}", tz=f"{2250 + self.core_adjustment.z:04}", - th=round(self._traversal_height * 10), + th=round(self._iswap_traversal_height * 10), tt="14", ) self._core_parked = False @@ -4380,8 +4712,8 @@ async def put_core(self): yb=f"{1065 + self.core_adjustment.y:04}", tp=f"{2150 + self.core_adjustment.z:04}", tz=f"{2050 + self.core_adjustment.z:04}", - th=round(self._traversal_height * 10), - te=round(self._traversal_height * 10), + th=round(self._iswap_traversal_height * 10), + te=round(self._iswap_traversal_height * 10), ) self._core_parked = True return command_output @@ -4521,10 +4853,6 @@ async def core_move_plate_to_position( # -------------- 3.5.6 Adjustment & movement commands -------------- - # TODO:(command:JY) Position all pipetting channels in Y-direction - - # TODO:(command:JZ) Position all pipetting channels in Z-direction - async def position_single_pipetting_channel_in_y_direction( self, pipetting_channel_index: int, y_position: int ): @@ -4600,6 +4928,7 @@ async def spread_pip_channels(self): return await self.send_command(module="C0", command="JE") + @need_iswap_parked async def move_all_pipetting_channels_to_defined_position( self, tip_pattern: bool = True, @@ -4640,16 +4969,19 @@ async def move_all_pipetting_channels_to_defined_position( # TODO:(command:JR): teach rack using pipetting channel n - async def position_max_free_y_for_n(self, pipetting_channel_index: int = 1): + @need_iswap_parked + async def position_max_free_y_for_n(self, pipetting_channel_index: int): """Position all pipetting channels so that there is maximum free Y range for channel n Args: - pipetting_channel_index: Index of pipetting channel. Must be between 1 and 16. Default 1. + pipetting_channel_index: Index of pipetting channel. Must be between 0 and self.num_channels. """ assert ( - 1 <= pipetting_channel_index <= self.num_channels + 0 <= pipetting_channel_index < self.num_channels ), "pipetting_channel_index must be between 1 and self.num_channels" + # convert Python's 0-based indexing to Hamilton firmware's 1-based indexing + pipetting_channel_index = pipetting_channel_index + 1 return await self.send_command( module="C0", @@ -4666,42 +4998,54 @@ async def move_all_channels_in_z_safety(self): # TODO:(command:RY): Request Y-Positions of all pipetting channels - async def request_y_pos_channel_n(self, pipetting_channel_index: int = 1): + async def request_y_pos_channel_n(self, pipetting_channel_index: int) -> float: """Request Y-Position of Pipetting channel n Args: - pipetting_channel_index: Index of pipetting channel. Must be between 1 and 16. Default 1. + pipetting_channel_index: Index of pipetting channel. Must be between 0 and 15. + 0 is the backmost channel. """ - assert 1 <= pipetting_channel_index <= 16, "pipetting_channel_index must be between 1 and 16" + assert ( + 0 <= pipetting_channel_index < self.num_channels + ), "pipetting_channel_index must be between 0 and self.num_channels" + # convert Python's 0-based indexing to Hamilton firmware's 1-based indexing + pipetting_channel_index = pipetting_channel_index + 1 - return await self.send_command( + y_pos_query = await self.send_command( module="C0", command="RB", fmt="rb####", pn=f"{pipetting_channel_index:02}", ) + # Extract y-coordinate and convert to mm + return float(y_pos_query["rb"] / 10) # TODO:(command:RZ): Request Z-Positions of all pipetting channels - async def request_z_pos_channel_n(self, pipetting_channel_index: int = 1): + async def request_z_pos_channel_n(self, pipetting_channel_index: int) -> float: """Request Z-Position of Pipetting channel n Args: - pipetting_channel_index: Index of pipetting channel. Must be between 1 and 16. Default 1. + pipetting_channel_index: Index of pipetting channel. Must be between 0 and 15. + 0 is the backmost channel. Returns: Z-Position of channel n [0.1mm]. Taking into account tip presence and length. """ - assert 1 <= pipetting_channel_index <= 16, "pipetting_channel_index must be between 1 and 16" + assert 0 <= pipetting_channel_index <= 15, "pipetting_channel_index must be between 0 and 15" + # convert Python's 0-based indexing to Hamilton firmware's 1-based indexing + pipetting_channel_index = pipetting_channel_index + 1 - return await self.send_command( + z_pos_query = await self.send_command( module="C0", command="RD", fmt="rd####", pn=f"{pipetting_channel_index:02}", ) + # Extract z-coordinate and convert to mm + return float(z_pos_query["rd"] / 10) async def request_tip_presence(self) -> List[int]: """Request query tip presence on each channel @@ -4862,45 +5206,28 @@ async def request_tadm_status(self): # -------------- 3.10.1 Initialization -------------- async def initialize_core_96_head( - self, - x_position: int = 2321, - x_direction: int = 1, - y_position: int = 1103, - z_deposit_position: int = 1890, - z_position_at_the_command_end: int = 2450, + self, trash96: Trash, z_position_at_the_command_end: float = 245.0 ): """Initialize CoRe 96 Head - Initialize CoRe 96 Head. Dependent to configuration initialization change. - Args: - x_position: X-Position [0.1mm] (discard position of tip A1). Must be between 0 and 30000. - Default 0. - x_direction: X-direction. 0 = positive 1 = negative. Must be between 0 and 1. Default 0. - y_position: Y-Position [0.1mm] (discard position of tip A1 ). Must be between 1054 and 5743. - Default 5743. - z_deposit_position_[0.1mm]: Z- deposit position [0.1mm] (collar bearing position). Must be - between 0 and 3425. Default 3425. - z_position_at_the_command_end: Z-Position at the command end [0.1mm]. Must be between 0 and - 3425. Default 3425. + trash96: Trash object where tips should be disposed. The 96 head will be positioned in the + center of the trash. + z_position_at_the_command_end: Z position at the end of the command [mm]. """ - assert 0 <= x_position <= 30000, "x_position must be between 0 and 30000" - assert 0 <= x_direction <= 1, "x_direction must be between 0 and 1" - assert 1054 <= y_position <= 5743, "y_position must be between 1054 and 5743" - assert 0 <= z_deposit_position <= 3425, "z_deposit_position must be between 0 and 3425" - assert ( - 0 <= z_position_at_the_command_end <= 3425 - ), "z_position_at_the_command_end must be between 0 and 3425" + # The firmware command expects location of tip A1 of the head. + loc = self._position_96_head_in_resource(trash96) return await self.send_command( module="C0", command="EI", - xs=f"{x_position:05}", - xd=x_direction, - yh=f"{y_position}", - za=f"{z_deposit_position}", - ze=f"{z_position_at_the_command_end}", + read_timeout=60, + xs=f"{abs(round(loc.x * 10)):05}", + xd=0 if loc.x >= 0 else 1, + yh=f"{abs(round(loc.y * 10)):04}", + za=f"{round(loc.z * 10):04}", + ze=f"{round(z_position_at_the_command_end*10):04}", ) async def move_core_96_to_safe_position(self): @@ -5048,7 +5375,7 @@ async def aspirate_core_96( mix_cycles: int = 0, mix_position_from_liquid_surface: int = 250, surface_following_distance_during_mix: int = 0, - mix_speed: int = 1000, + speed_of_mix: int = 1000, channel_pattern: List[bool] = [True] * 96, limit_curve_index: int = 0, tadm_algorithm: bool = False, @@ -5102,7 +5429,7 @@ async def aspirate_core_96( liquid surface (LLD or absolute terms) [0.1mm]. Must be between 0 and 990. Default 250. surface_following_distance_during_mix: surface following distance during mix [0.1mm]. Must be between 0 and 990. Default 0. - mix_speed: Speed of mix [0.1ul/s]. Must be between 3 and 5000. + speed_of_mix: Speed of mix [0.1ul/s]. Must be between 3 and 5000. Default 1000. todo: TODO: 24 hex chars. Must be between 4 and 5000. limit_curve_index: limit curve index. Must be between 0 and 999. Default 0. @@ -5157,7 +5484,7 @@ async def aspirate_core_96( assert ( 0 <= surface_following_distance_during_mix <= 990 ), "surface_following_distance_during_mix must be between 0 and 990" - assert 3 <= mix_speed <= 5000, "mix_speed must be between 3 and 5000" + assert 3 <= speed_of_mix <= 5000, "speed_of_mix must be between 3 and 5000" assert 0 <= limit_curve_index <= 999, "limit_curve_index must be between 0 and 999" assert 0 <= recording_mode <= 2, "recording_mode must be between 0 and 2" @@ -5198,7 +5525,7 @@ async def aspirate_core_96( hc=f"{mix_cycles:02}", hp=f"{mix_position_from_liquid_surface:03}", mj=f"{surface_following_distance_during_mix:03}", - hs=f"{mix_speed:04}", + hs=f"{speed_of_mix:04}", cw=channel_pattern_hex, cr=f"{limit_curve_index:03}", cj=tadm_algorithm, @@ -5238,7 +5565,7 @@ async def dispense_core_96( mixing_cycles: int = 0, mixing_position_from_liquid_surface: int = 250, surface_following_distance_during_mixing: int = 0, - mix_speed: int = 1000, + speed_of_mixing: int = 1000, channel_pattern: List[bool] = [True] * 12 * 8, limit_curve_index: int = 0, tadm_algorithm: bool = False, @@ -5295,7 +5622,7 @@ async def dispense_core_96( surface (LLD or absolute terms) [0.1mm]. Must be between 0 and 990. Default 250. surface_following_distance_during_mixing: surface following distance during mixing [0.1mm]. Must be between 0 and 990. Default 0. - mix_speed: Speed of mixing [0.1ul/s]. Must be between 3 and 5000. Default 1000. + speed_of_mixing: Speed of mixing [0.1ul/s]. Must be between 3 and 5000. Default 1000. channel_pattern: list of 96 boolean values limit_curve_index: limit curve index. Must be between 0 and 999. Default 0. tadm_algorithm: TADM algorithm. Default False. @@ -5351,7 +5678,7 @@ async def dispense_core_96( assert ( 0 <= surface_following_distance_during_mixing <= 990 ), "surface_following_distance_during_mixing must be between 0 and 990" - assert 3 <= mix_speed <= 5000, "mix_speed must be between 3 and 5000" + assert 3 <= speed_of_mixing <= 5000, "speed_of_mixing must be between 3 and 5000" assert 0 <= limit_curve_index <= 999, "limit_curve_index must be between 0 and 999" assert 0 <= recording_mode <= 2, "recording_mode must be between 0 and 2" @@ -5393,7 +5720,7 @@ async def dispense_core_96( hc=f"{mixing_cycles:02}", hp=f"{mixing_position_from_liquid_surface:03}", mj=f"{surface_following_distance_during_mixing:03}", - hs=f"{mix_speed:04}", + hs=f"{speed_of_mixing:04}", cw=channel_pattern_hex, cr=f"{limit_curve_index:03}", cj=tadm_algorithm, @@ -5654,7 +5981,10 @@ async def load_carrier( park_autoload_after: Whether to park autoload after loading. Default True. """ - barcode_reading_direction_dict = {"vertical": "0", "horizontal": "1"} + barcode_reading_direction_dict = { + "vertical": "0", + "horizontal": "1", + } barcode_symbology_dict = { "ISBT Standard": "70", "Code 128 (Subset B and C)": "71", @@ -5689,7 +6019,9 @@ async def load_carrier( if barcode_reading: # Choose barcode symbology await self.send_command( - module="C0", command="CB", bt=barcode_symbology_dict[barcode_symbology] + module="C0", + command="CB", + bt=barcode_symbology_dict[barcode_symbology], ) # Load and read out barcodes resp = await self.send_command( @@ -5730,7 +6062,10 @@ def pattern2hex(pattern: List[bool]) -> str: blink_pattern_hex = pattern2hex(blink_pattern) return await self.send_command( - module="C0", command="CP", cl=bit_pattern_hex, cb=blink_pattern_hex + module="C0", + command="CP", + cl=bit_pattern_hex, + cb=blink_pattern_hex, ) # TODO:(command:CS) Check for presence of carriers on loading tray @@ -5757,11 +6092,18 @@ async def set_barcode_type( EAN8: EAN8. Default True. """ - # pylint: disable=invalid-name - # Encode values into bit pattern. Last bit is always one. bt = "" - for t in [ISBT_Standard, code128, code39, codebar, code2_5, UPC_AE, EAN8, True]: + for t in [ + ISBT_Standard, + code128, + code39, + codebar, + code2_5, + UPC_AE, + EAN8, + True, + ]: bt += "1" if t else "0" # Convert bit pattern to hex. @@ -5942,55 +6284,96 @@ async def position_components_for_free_iswap_y_range(self): return await self.send_command(module="C0", command="FY") - async def move_iswap_x_direction(self, step_size: int = 0, direction: int = 0): - """Move iSWAP in X-direction - + async def move_iswap_x_relative(self, step_size: float, allow_splitting: bool = False): + """ Args: - step_size: X Step size [0.1mm] Between 0 and 999. Default 0. - direction: X direction. 0 = positive 1 = negative + step_size: X Step size [1mm] Between -99.9 and 99.9 if allow_splitting is False. + allow_splitting: Allow splitting of the movement into multiple steps. Default False. """ - return await self.send_command(module="C0", command="GX", gx=step_size, xd=direction) + direction = 0 if step_size >= 0 else 1 + max_step_size = 99.9 + if abs(step_size) > max_step_size: + if not allow_splitting: + raise ValueError("step_size must be less than 99.9") + await self.move_iswap_x_relative( + step_size=max_step_size if step_size > 0 else -max_step_size, allow_splitting=True + ) + remaining_steps = step_size - max_step_size if step_size > 0 else step_size + max_step_size + return await self.move_iswap_x_relative(remaining_steps, allow_splitting) - async def move_iswap_y_direction(self, step_size: int = 0, direction: int = 0): - """Move iSWAP in Y-direction + return await self.send_command( + module="C0", command="GX", gx=str(round(abs(step_size) * 10)).zfill(3), xd=direction + ) + async def move_iswap_y_relative(self, step_size: float, allow_splitting: bool = False): + """ Args: - step_size: Y Step size [0.1mm] Between 0 and 999. Default 0. - direction: Y direction. 0 = positive 1 = negative + step_size: Y Step size [1mm] Between -99.9 and 99.9 if allow_splitting is False. + allow_splitting: Allow splitting of the movement into multiple steps. Default False. """ - return await self.send_command(module="C0", command="GY", gx=step_size, xd=direction) + direction = 0 if step_size >= 0 else 1 + max_step_size = 99.9 + if abs(step_size) > max_step_size: + if not allow_splitting: + raise ValueError("step_size must be less than 99.9") + await self.move_iswap_y_relative( + step_size=max_step_size if step_size > 0 else -max_step_size, allow_splitting=True + ) + remaining_steps = step_size - max_step_size if step_size > 0 else step_size + max_step_size + return await self.move_iswap_y_relative(remaining_steps, allow_splitting) - async def move_iswap_z_direction(self, step_size: int = 0, direction: int = 0): - """Move iSWAP in Z-direction + return await self.send_command( + module="C0", command="GY", gy=str(round(abs(step_size) * 10)).zfill(3), yd=direction + ) + async def move_iswap_z_relative(self, step_size: float, allow_splitting: bool = False): + """ Args: - step_size: Z Step size [0.1mm] Between 0 and 999. Default 0. - direction: Z direction. 0 = positive 1 = negative + step_size: Z Step size [1mm] Between -99.9 and 99.9 if allow_splitting is False. + allow_splitting: Allow splitting of the movement into multiple steps. Default False. """ - return await self.send_command(module="C0", command="GZ", gx=step_size, xd=direction) + direction = 0 if step_size >= 0 else 1 + max_step_size = 99.9 + if abs(step_size) > max_step_size: + if not allow_splitting: + raise ValueError("step_size must be less than 99.9") + await self.move_iswap_z_relative( + step_size=max_step_size if step_size > 0 else -max_step_size, allow_splitting=True + ) + remaining_steps = step_size - max_step_size if step_size > 0 else step_size + max_step_size + return await self.move_iswap_z_relative(remaining_steps, allow_splitting) - async def open_not_initialized_gripper(self): - """Open not initialized gripper""" + return await self.send_command( + module="C0", command="GZ", gz=str(round(abs(step_size) * 10)).zfill(3), zd=direction + ) + async def open_not_initialized_gripper(self): return await self.send_command(module="C0", command="GI") - async def iswap_open_gripper(self, open_position: int = 1320): + async def iswap_open_gripper(self, open_position: Optional[int] = None): """Open gripper Args: open_position: Open position [0.1mm] (0.1 mm = 16 increments) The gripper moves to pos + 20. - Must be between 0 and 9999. Default 860. + Must be between 0 and 9999. Default 1320 for iSWAP 4.0 (landscape). Default to + 910 for iSWAP 3 (portrait). """ + if open_position is None: + open_position = 910 if (await self.get_iswap_version()).startswith("3") else 1320 + assert 0 <= open_position <= 9999, "open_position must be between 0 and 9999" return await self.send_command(module="C0", command="GF", go=f"{open_position:04}") async def iswap_close_gripper( - self, grip_strength: int = 5, plate_width: int = 0, plate_width_tolerance: int = 0 + self, + grip_strength: int = 5, + plate_width: int = 0, + plate_width_tolerance: int = 0, ): """Close gripper @@ -6004,12 +6387,19 @@ async def iswap_close_gripper( """ return await self.send_command( - module="C0", command="GC", gw=grip_strength, gb=plate_width, gt=plate_width_tolerance + module="C0", + command="GC", + gw=grip_strength, + gb=plate_width, + gt=plate_width_tolerance, ) # -------------- 3.17.2 Stack handling commands CP -------------- - async def park_iswap(self, minimum_traverse_height_at_beginning_of_a_command: int = 2840): + async def park_iswap( + self, + minimum_traverse_height_at_beginning_of_a_command: int = 2840, + ): """Close gripper The gripper should be at the position gb+gt+20 before sending this command. @@ -6024,7 +6414,9 @@ async def park_iswap(self, minimum_traverse_height_at_beginning_of_a_command: in ), "minimum_traverse_height_at_beginning_of_a_command must be between 0 and 3600" command_output = await self.send_command( - module="C0", command="PG", th=minimum_traverse_height_at_beginning_of_a_command + module="C0", + command="PG", + th=minimum_traverse_height_at_beginning_of_a_command, ) # Once the command has completed successfully, set _iswap_parked to True @@ -6504,15 +6896,19 @@ async def request_iswap_position(self): """Request iSWAP position ( grip center ) Returns: - xs: Hotel center in X direction [0.1mm] + xs: Hotel center in X direction [1mm] xd: X direction 0 = positive 1 = negative - yj: Gripper center in Y direction [0.1mm] + yj: Gripper center in Y direction [1mm] yd: Y direction 0 = positive 1 = negative - zj: Gripper Z height (gripping height) [0.1mm] + zj: Gripper Z height (gripping height) [1mm] zd: Z direction 0 = positive 1 = negative """ - return await self.send_command(module="C0", command="QG", fmt="xs#####xd#yj####yd#zj####zd#") + resp = await self.send_command(module="C0", command="QG", fmt="xs#####xd#yj####yd#zj####zd#") + resp["xs"] = resp["xs"] / 10 + resp["yj"] = resp["yj"] / 10 + resp["zj"] = resp["zj"] / 10 + return resp async def request_iswap_initialization_status(self) -> bool: """Request iSWAP initialization status @@ -6524,6 +6920,10 @@ async def request_iswap_initialization_status(self) -> bool: resp = await self.send_command(module="R0", command="QW", fmt="qw#") return cast(int, resp["qw"]) == 1 + async def request_iswap_version(self) -> str: + """Firmware command for getting iswap version""" + return cast(str, (await self.send_command("R0", "RF", fmt="rf" + "&" * 15))["rf"]) + # -------------- 3.18 Cover and port control -------------- async def lock_cover(self): @@ -6658,7 +7058,11 @@ async def close_plate_lock(self, device_number: int): # -------------- 4.1.2 HHS Shaking -------------- async def start_shaking_at_hhs( - self, device_number: int, rpm: int, rotation: int = 0, plate_locked_during_shaking: bool = True + self, + device_number: int, + rpm: int, + rotation: int = 0, + plate_locked_during_shaking: bool = True, ): """Start shaking of specified HHS @@ -6726,7 +7130,10 @@ async def get_temperature_at_hhs(self, device_number: int) -> dict: request_temperature = await self.send_command(module=f"T{device_number}", command="RT") processed_t_info = [int(x) / 10 for x in request_temperature.split("+")[-2:]] - return {"middle_T": processed_t_info[0], "edge_T": processed_t_info[-1]} + return { + "middle_T": processed_t_info[0], + "edge_T": processed_t_info[-1], + } async def stop_temperature_control_at_hhs(self, device_number: int): """Stop temperature regulation of specified HHS""" @@ -6817,7 +7224,10 @@ async def get_temperature_at_hhc(self, device_number: int) -> dict: request_temperature = await self.send_command(module=f"T{device_number}", command="RT") processed_t_info = [int(x) / 10 for x in request_temperature.split("+")[-2:]] - return {"middle_T": processed_t_info[0], "edge_T": processed_t_info[-1]} + return { + "middle_T": processed_t_info[0], + "edge_T": processed_t_info[-1], + } async def query_whether_temperature_reached_at_hhc(self, device_number: int): """Stop temperature regulation of specified HHC""" @@ -6838,92 +7248,645 @@ async def stop_temperature_control_at_hhc(self, device_number: int): # -------------- Extra - Probing labware with STAR - making STAR into a CMM -------------- - async def probe_z_height_using_channel( + y_drive_mm_per_increment = 0.046302082 + z_drive_mm_per_increment = 0.01072765 + + @staticmethod + def mm_to_y_drive_increment(value_mm: float) -> int: + return round(value_mm / STAR.y_drive_mm_per_increment) + + @staticmethod + def y_drive_increment_to_mm(value_mm: int) -> float: + return round(value_mm * STAR.y_drive_mm_per_increment, 2) + + @staticmethod + def mm_to_z_drive_increment(value_mm: float) -> int: + return round(value_mm / STAR.z_drive_mm_per_increment) + + @staticmethod + def z_drive_increment_to_mm(value_increments: int) -> float: + return round(value_increments * STAR.z_drive_mm_per_increment, 2) + + async def clld_probe_z_height_using_channel( self, - channel_idx: int, - lowest_immers_pos: int = 10000, - start_pos_lld_search: int = 31200, - channel_speed: int = 1000, - channel_acceleration: int = 75, + channel_idx: int, # 0-based indexing of channels! + lowest_immers_pos: float = 99.98, # mm + start_pos_search: float = 330.0, # mm + channel_speed: float = 10.0, # mm + channel_acceleration: float = 800.0, # mm/sec**2 detection_edge: int = 10, detection_drop: int = 2, post_detection_trajectory: Literal[0, 1] = 1, - post_detection_dist: int = 100, + post_detection_dist: float = 2.0, # mm move_channels_to_save_pos_after: bool = False, ) -> float: - """Probes the Z-height using a specified channel on a liquid handling device. - Commands the liquid handler to perform a Liquid Level Detection (LLD) operation using the - specified channel (this means only conductive materials can be probed!). + """Probes the Z-height below the specified channel on a Hamilton STAR liquid handling machine + using the channels 'capacitive Liquid Level Detection' (cLLD) capabilities. + N.B.: this means only conductive materials can be probed! Args: - self: The liquid handler. - channel_idx: The index of the channel to use for probing. - lowest_immers_pos: The lowest immersion position in increments. - start_pos_lld_search: The start position for LLD search in increments. - channel_speed: The speed of channel movement. - channel_acceleration: The acceleration of the channel. + channel_idx: The index of the channel to use for probing. Backmost channel = 0. + lowest_immers_pos: The lowest immersion position in mm. + start_pos_lld_search: The start position for z-touch search in mm. + channel_speed: The speed of channel movement in mm/sec. + channel_acceleration: The acceleration of the channel in mm/sec**2. detection_edge: The edge steepness at capacitive LLD detection. detection_drop: The offset after capacitive LLD edge detection. - post_detection_trajectory: Movement of the channel up (1) or down (0) after contacting the - surface. - post_detection_dist (int): Distance to move up after detection to avoid pressure build-up. - move_channels_to_save_pos_after (bool): Flag to move channels to a safe position after + post_detection_trajectory (0, 1): Movement of the channel up (1) or down (0) after + contacting the surface. + post_detection_dist: Distance to move into the trajectory after detection in mm. + move_channels_to_save_pos_after: Flag to move channels to a safe position after operation. Returns: - float: The detected Z-height in mm. + The detected Z-height in mm. """ + lowest_immers_pos_increments = STAR.mm_to_z_drive_increment(lowest_immers_pos) + start_pos_search_increments = STAR.mm_to_z_drive_increment(start_pos_search) + channel_speed_increments = STAR.mm_to_z_drive_increment(channel_speed) + channel_acceleration_thousand_increments = STAR.mm_to_z_drive_increment( + channel_acceleration / 1000 + ) + post_detection_dist_increments = STAR.mm_to_z_drive_increment(post_detection_dist) + + assert 9_320 <= lowest_immers_pos_increments <= 31_200, ( + f"Lowest immersion position must be between \n{STAR.z_drive_increment_to_mm(9_320)}" + + f" and {STAR.z_drive_increment_to_mm(31_200)} mm, is {lowest_immers_pos} mm" + ) + assert 9_320 <= start_pos_search_increments <= 31_200, ( + f"Start position of LLD search must be between \n{STAR.z_drive_increment_to_mm(9_320)}" + + f" and {STAR.z_drive_increment_to_mm(31_200)} mm, is {start_pos_search} mm" + ) + assert 20 <= channel_speed_increments <= 15_000, ( + f"LLD search speed must be between \n{STAR.z_drive_increment_to_mm(20)}" + + f"and {STAR.z_drive_increment_to_mm(15_000)} mm/sec, is {channel_speed} mm/sec" + ) + assert 5 <= channel_acceleration_thousand_increments <= 150, ( + f"Channel acceleration must be between \n{STAR.z_drive_increment_to_mm(5*1_000)} " + + f" and {STAR.z_drive_increment_to_mm(150*1_000)} mm/sec**2, is {channel_acceleration} mm/sec**2" + ) assert ( - 9320 <= lowest_immers_pos <= 31200 - ), "Lowest immersion position [increment] must be between 9320 and 31200" - assert ( - 9320 <= start_pos_lld_search <= 31200 - ), "Start position of LLD search [increment] must be between 9320 and 31200" - assert ( - 20 <= channel_speed <= 15000 - ), "LLD search speed [increment/second] must be between 20 and 15000" - assert ( - 5 <= channel_acceleration <= 150 - ), "Channel acceleration [increment] must be between 5 and 150" - assert ( - 0 <= detection_edge <= 1023 + 0 <= detection_edge <= 1_023 ), "Edge steepness at capacitive LLD detection must be between 0 and 1023" assert ( - 0 <= detection_drop <= 1023 + 0 <= detection_drop <= 1_023 ), "Offset after capacitive LLD edge detection must be between 0 and 1023" - assert ( - 0 <= post_detection_dist <= 9999 - ), "Immersion depth after Liquid Level Detection [increment] must be between 0 and 9999" + assert 0 <= post_detection_dist_increments <= 9_999, ( + "Post cLLD-detection movement distance must be between \n0" + + f" and {STAR.z_drive_increment_to_mm(9_999)} mm, is {post_detection_dist} mm" + ) - lowest_immers_pos_str = f"{lowest_immers_pos:05}" - start_pos_lld_search_str = f"{start_pos_lld_search:05}" - channel_speed_str = f"{channel_speed:05}" - channel_acc_str = f"{channel_acceleration:03}" + lowest_immers_pos_str = f"{lowest_immers_pos_increments:05}" + start_pos_search_str = f"{start_pos_search_increments:05}" + channel_speed_str = f"{channel_speed_increments:05}" + channel_acc_str = f"{channel_acceleration_thousand_increments:03}" detection_edge_str = f"{detection_edge:04}" detection_drop_str = f"{detection_drop:04}" - post_detection_dist_str = f"{post_detection_dist:04}" + post_detection_dist_str = f"{post_detection_dist_increments:04}" await self.send_command( - module=f"P{channel_idx}", + module=STAR.channel_id(channel_idx), command="ZL", zh=lowest_immers_pos_str, # Lowest immersion position [increment] - zc=start_pos_lld_search_str, # Start position of LLD search [increment] + zc=start_pos_search_str, # Start position of LLD search [increment] zl=channel_speed_str, # Speed of channel movement zr=channel_acc_str, # Acceleration [1000 increment/second^2] gt=detection_edge_str, # Edge steepness at capacitive LLD detection gl=detection_drop_str, # Offset after capacitive LLD edge detection zj=post_detection_trajectory, # Movement of the channel after contacting surface - zi=post_detection_dist_str, # Distance to move up after detection + zi=post_detection_dist_str, # Distance to move up after detection [increment] ) if move_channels_to_save_pos_after: await self.move_all_channels_in_z_safety() get_llds = await self.request_pip_height_last_lld() - result_in_mm = float(get_llds["lh"][channel_idx - 1] / 10) + result_in_mm = float(get_llds["lh"][channel_idx] / 10) return result_in_mm + async def request_tip_len_on_channel( + self, + channel_idx: int, # 0-based indexing of channels! + ) -> float: + """ + Measures the length of the tip attached to the specified pipetting channel. + Checks if a tip is present on the given channel. If present, moves all channels + to THE safe Z position, 334.3 mm, measures the tip bottom Z-coordinate, and calculates + the total tip length. Supports tips of lengths 50.4 mm, 59.9 mm, and 95.1 mm. + Raises an error if the tip length is unsupported or if no tip is present. + Parameters: + channel_idx: Index of the pipetting channel (0-based). + Returns: + The measured tip length in millimeters. + Raises: + ValueError: If no tip is present on the channel or if the tip length is unsupported. + """ + + # Check there is a tip on the channel + all_channel_occupancy = await self.request_tip_presence() + if not all_channel_occupancy[channel_idx]: + raise ValueError(f"No tip present on channel {channel_idx}") + + # Level all channels + await self.move_all_channels_in_z_safety() + known_top_position_channel_head = 334.3 # mm + fitting_depth_of_all_standard_channel_tips = 8 # mm + unknown_offset_for_all_tips = 0.4 # mm + + # Request z-coordinate of channel+tip bottom + tip_bottom_z_coordinate = await self.request_z_pos_channel_n( + pipetting_channel_index=channel_idx + ) + + total_tip_len = round( + known_top_position_channel_head + - ( + tip_bottom_z_coordinate + - fitting_depth_of_all_standard_channel_tips + - unknown_offset_for_all_tips + ), + 1, + ) + + if total_tip_len in [50.4, 59.9, 95.1]: # 50ul, 300ul, 1000ul + return total_tip_len + raise ValueError(f"Tip of length {total_tip_len} not yet supported") + + async def ztouch_probe_z_height_using_channel( + self, + channel_idx: int, # 0-based indexing of channels! + tip_len: Optional[float] = None, # mm + lowest_immers_pos: float = 99.98, # mm + start_pos_search: Optional[float] = None, # mm + channel_speed: float = 10.0, # mm/sec + channel_acceleration: float = 800.0, # mm/sec**2 + channel_speed_upwards: float = 125.0, # mm + detection_limiter_in_PWM: int = 1, + push_down_force_in_PWM: int = 0, + post_detection_dist: float = 2.0, # mm + move_channels_to_save_pos_after: bool = False, + ) -> float: + """Probes the Z-height below the specified channel on a Hamilton STAR liquid handling machine + using the channels 'z-touchoff' capabilities, i.e. a controlled triggering of the z-drive, + aka a controlled 'crash'. + + Args: + channel_idx: The index of the channel to use for probing. Backmost channel = 0. + tip_len: override the tip length (of tip on channel `channel_idx`). Default is the tip length + of the tip that was picked up. + lowest_immers_pos: The lowest immersion position in mm. + start_pos_lld_search: The start position for z-touch search in mm. + channel_speed: The speed of channel movement in mm/sec. + channel_acceleration: The acceleration of the channel in mm/sec**2. + detection_limiter_in_PWM: Offset PWM limiter value for searching + push_down_force_in_PWM: Offset PWM value for push down force. + cf000 = No push down force, drive is switched off. + post_detection_dist: Distance to move into the trajectory after detection in mm. + move_channels_to_save_pos_after: Flag to move channels to a safe position after + operation. + + Returns: + The detected Z-height in mm. + """ + + version = await self.request_pip_channel_version(channel_idx) + year_matches = re.search(r"\b\d{4}\b", version) + if year_matches is not None: + year = int(year_matches.group()) + if year < 2022: + raise ValueError( + "Z-touch probing is not supported for PIP versions predating 2022, " + f"found version '{version}'" + ) + + if tip_len is None: + # currently a bug, will be fixed in the future + # reverted to previous implementation + # tip_len = self.head[channel_idx].get_tip().total_tip_length + tip_len = await self.request_tip_len_on_channel(channel_idx) + + # fitting_depth = 8 mm for 10, 50, 300, 1000 ul Hamilton tips + # fitting_depth = self.head[channel_idx].get_tip().fitting_depth + fitting_depth = 8 # mm, for 10, 50, 300, 1000 ul Hamilton tips + + if start_pos_search is None: + start_pos_search = 334.7 - tip_len + fitting_depth + + tip_len_used_in_increments = (tip_len - fitting_depth) / STAR.z_drive_mm_per_increment + channel_head_start_pos = ( + start_pos_search + tip_len - fitting_depth + ) # start_pos of the head itself! + safe_head_bottom_z_pos = ( + 99.98 + tip_len - fitting_depth + ) # 99.98 == STAR.z_drive_increment_to_mm(9_320) + safe_head_top_z_pos = 334.7 # 334.7 == STAR.z_drive_increment_to_mm(31_200) + + lowest_immers_pos_increments = STAR.mm_to_z_drive_increment(lowest_immers_pos) + start_pos_search_increments = STAR.mm_to_z_drive_increment(channel_head_start_pos) + channel_speed_increments = STAR.mm_to_z_drive_increment(channel_speed) + channel_acceleration_thousand_increments = STAR.mm_to_z_drive_increment( + channel_acceleration / 1000 + ) + channel_speed_upwards_increments = STAR.mm_to_z_drive_increment(channel_speed_upwards) + + assert 0 <= channel_idx <= 15, f"channel_idx must be between 0 and 15, is {channel_idx}" + assert 20 <= tip_len <= 120, "Total tip length must be between 20 and 120" + + assert 9320 <= lowest_immers_pos_increments <= 31_200, ( + "Lowest immersion position must be between \n99.98" + + f" and 334.7 mm, is {lowest_immers_pos} mm" + ) + assert safe_head_bottom_z_pos <= channel_head_start_pos <= safe_head_top_z_pos, ( + f"Start position of LLD search must be between \n{safe_head_bottom_z_pos}" + + f" and {safe_head_top_z_pos} mm, is {channel_head_start_pos} mm" + ) + assert 20 <= channel_speed_increments <= 15_000, ( + f"Z-touch search speed must be between \n{STAR.z_drive_increment_to_mm(20)}" + + f" and {STAR.z_drive_increment_to_mm(15_000)} mm/sec, is {channel_speed} mm/sec" + ) + assert 5 <= channel_acceleration_thousand_increments <= 150, ( + f"Channel acceleration must be between \n{STAR.z_drive_increment_to_mm(5*1_000)}" + + f" and {STAR.z_drive_increment_to_mm(150*1_000)} mm/sec**2, is {channel_speed} mm/sec**2" + ) + assert 20 <= channel_speed_upwards_increments <= 15_000, ( + f"Channel retraction speed must be between \n{STAR.z_drive_increment_to_mm(20)}" + + f" and {STAR.z_drive_increment_to_mm(15_000)} mm/sec, is {channel_speed_upwards} mm/sec" + ) + assert ( + 0 <= detection_limiter_in_PWM <= 125 + ), "Detection limiter value must be between 0 and 125 PWM." + assert 0 <= push_down_force_in_PWM <= 125, "Push down force between 0 and 125 PWM values" + assert ( + 0 <= post_detection_dist <= 245 + ), f"Post detection distance must be between 0 and 245 mm, is {post_detection_dist}" + + lowest_immers_pos_str = f"{lowest_immers_pos_increments:05}" + start_pos_search_str = f"{start_pos_search_increments:05}" + channel_speed_str = f"{channel_speed_increments:05}" + channel_acc_str = f"{channel_acceleration_thousand_increments:03}" + channel_speed_up_str = f"{channel_speed_upwards_increments:05}" + detection_limiter_in_PWM_str = f"{detection_limiter_in_PWM:03}" + push_down_force_in_PWM_str = f"{push_down_force_in_PWM:03}" + + ztouch_probed_z_height = await self.send_command( + module=STAR.channel_id(channel_idx), + command="ZH", + zb=start_pos_search_str, # begin of searching range [increment] + za=lowest_immers_pos_str, # end of searching range [increment] + zv=channel_speed_up_str, # speed z-drive upper section [increment/second] + zr=channel_acc_str, # acceleration z-drive [1000 increment/second] + zu=channel_speed_str, # speed z-drive lower section [increment/second] + cg=detection_limiter_in_PWM_str, # offset PWM limiter value for searching + cf=push_down_force_in_PWM_str, # offset PWM value for push down force + fmt="rz#####", + ) + # Subtract tip_length from measurement in increment, and convert to mm + result_in_mm = STAR.z_drive_increment_to_mm( + ztouch_probed_z_height["rz"] - tip_len_used_in_increments + ) + if post_detection_dist != 0: # Safety first + await self.move_channel_z(z=result_in_mm + post_detection_dist, channel=channel_idx) + if move_channels_to_save_pos_after: + await self.move_all_channels_in_z_safety() + + return float(result_in_mm) + + class RotationDriveOrientation(enum.Enum): + LEFT = 1 + FRONT = 2 + RIGHT = 3 + + async def rotate_iswap_rotation_drive(self, orientation: RotationDriveOrientation): + return await self.send_command( + module="R0", + command="WP", + auto_id=False, + wp=orientation.value, + ) + + class WristOrientation(enum.Enum): + RIGHT = 1 + STRAIGHT = 2 + LEFT = 3 + REVERSE = 4 + + async def rotate_iswap_wrist(self, orientation: WristOrientation): + return await self.send_command( + module="R0", + command="TP", + auto_id=False, + tp=orientation.value, + ) + + @staticmethod + def channel_id(channel_idx: int) -> str: + """channel_idx: plr style, 0-indexed from the back""" + channel_ids = "123456789ABCDEFG" + return "P" + channel_ids[channel_idx] + + async def get_channels_y_positions(self) -> Dict[int, float]: + """Get the Y position of all channels in mm""" + resp = await self.send_command( + module="C0", + command="RY", + fmt="ry#### (n)", + ) + y_positions = [round(y / 10, 2) for y in resp["ry"]] + + # sometimes there is (likely) a floating point error and channels are reported to be + # less than 9mm apart. (When you set channels using position_channels_in_y_direction, + # it will raise an error.) The minimum y is 6mm, so we fix that first (in case that + # values is misreported). Then, we traverse the list in reverse and set the min_diff. + if y_positions[-1] < 5.8: + raise RuntimeError( + "Channels are reported to be too close to the front of the machine. " + "The known minimum is 6, which will be fixed automatically for 5.8=9mm. We start with the channel closest to `back_channel`, and make sure the + # channel behind it is at least 9mm, updating if needed. Iterating from the front (closest + # to `back_channel`) to the back (channel 0), all channels are put at the correct location. + # This order matters because the channel in front of any channel may have been moved in the + # previous iteration. + # Note that if a channel is already spaced at >=9mm, it is not moved. + use_channels = list(ys.keys()) + back_channel = min(use_channels) + for channel_idx in range(back_channel, 0, -1): + if (channel_locations[channel_idx - 1] - channel_locations[channel_idx]) < 9: + channel_locations[channel_idx - 1] = channel_locations[channel_idx] + 9 + + # Similarly for the channels to the front of `front_channel`, make sure they are all + # spaced >=9mm apart. This time, we iterate from back (closest to `front_channel`) + # to the front (lh.backend.num_channels - 1), and put each channel >=9mm before the + # one behind it. + front_channel = max(use_channels) + for channel_idx in range(front_channel, self.num_channels - 1): + if (channel_locations[channel_idx] - channel_locations[channel_idx + 1]) < 9: + channel_locations[channel_idx + 1] = channel_locations[channel_idx] - 9 + + # Quick checks before movement. + if channel_locations[0] > 650: + raise ValueError("Channel 0 would hit the back of the robot") + + if channel_locations[self.num_channels - 1] < 6: + raise ValueError("Channel N would hit the front of the robot") + + if not all( + int((channel_locations[i] - channel_locations[i + 1]) * 1000) >= 8_999 # float fixing + for i in range(len(channel_locations) - 1) + ): + raise ValueError("Channels must be at least 9mm apart and in descending order") + + yp = " ".join([f"{round(y*10):04}" for y in channel_locations.values()]) + return await self.send_command( + module="C0", + command="JY", + yp=yp, + ) + + async def get_channels_z_positions(self) -> Dict[int, float]: + """Get the Y position of all channels in mm""" + resp = await self.send_command( + module="C0", + command="RZ", + fmt="rz#### (n)", + ) + return {channel_idx: round(y / 10, 2) for channel_idx, y in enumerate(resp["rz"])} + + async def position_channels_in_z_direction(self, zs: Dict[int, float]): + channel_locations = await self.get_channels_z_positions() + + for channel_idx, z in zs.items(): + channel_locations[channel_idx] = z + + return await self.send_command( + module="C0", command="JZ", zp=[f"{round(z*10):04}" for z in channel_locations.values()] + ) + + async def pierce_foil( + self, + wells: Union[Well, List[Well]], + piercing_channels: List[int], + hold_down_channels: List[int], + move_inwards: float, + spread: Literal["wide", "tight"] = "wide", + one_by_one: bool = False, + distance_from_bottom: float = 20.0, + ): + """Pierce the foil of the media source plate at the specified column. Throw away the tips + after piercing because there will be a bit of foil stuck to the tips. Use this method + before aspirating from a foil-sealed plate to make sure the tips are clean and the + aspirations are accurate. + + Args: + wells: Well or wells in the plate to pierce the foil. If multiple wells, they must be on one + column. + piercing_channels: The channels to use for piercing the foil. + hold_down_channels: The channels to use for holding down the plate when moving up the + piercing channels. + spread: The spread of the piercing channels in the well. + one_by_one: If True, the channels will pierce the foil one by one. If False, all channels + will pierce the foil simultaneously. + """ + + x: float + ys: List[float] + z: float + + # if only one well is give, but in a list, convert to Well so we fall into single-well logic. + if isinstance(wells, list) and len(wells) == 1: + wells = wells[0] + + if isinstance(wells, Well): + well = wells + x, y, z = well.get_absolute_location("c", "c", "cavity_bottom") + + if spread == "wide": + offsets = get_wide_single_resource_liquid_op_offsets( + well, num_channels=len(piercing_channels) + ) + else: + offsets = get_tight_single_resource_liquid_op_offsets( + well, num_channels=len(piercing_channels) + ) + ys = [y + offset.y for offset in offsets] + else: + assert ( + len(set(w.get_absolute_location().x for w in wells)) == 1 + ), "Wells must be on the same column" + absolute_center = wells[0].get_absolute_location("c", "c", "cavity_bottom") + x = absolute_center.x + ys = [well.get_absolute_location(x="c", y="c").y for well in wells] + z = absolute_center.z + + await self.move_channel_x(0, x=x) + + await self.position_channels_in_y_direction( + {channel: y for channel, y in zip(piercing_channels, ys)} + ) + + zs = [z + distance_from_bottom for _ in range(len(piercing_channels))] + if one_by_one: + for channel in piercing_channels: + await self.move_channel_z(channel, z) + else: + await self.position_channels_in_z_direction( + {channel: z for channel, z in zip(piercing_channels, zs)} + ) + + await self.step_off_foil( + [wells] if isinstance(wells, Well) else wells, + back_channel=hold_down_channels[0], + front_channel=hold_down_channels[1], + move_inwards=move_inwards, + ) + + async def step_off_foil( + self, + wells: Union[Well, List[Well]], + front_channel: int, + back_channel: int, + move_inwards: float = 2, + move_height: float = 15, + ): + """ + Hold down a plate by placing two channels on the edges of a plate that is sealed with foil + while moving up the channels that are still within the foil. This is useful when, for + example, aspirating from a plate that is sealed: without holding it down, the tips might get + stuck in the plate and move it up when retracting. Putting plates on the edge prevents this. + + When aspirating or dispensing in the foil, be sure to set the `min_z_endpos` parameter in + `lh.aspirate` or `lh.dispense` to a value in the foil. You might want to use something like + + .. code-block:: python + + well = plate.get_well("A3") + await wc.lh.aspirate( + [well]*4, vols=[100]*4, use_channels=[7,8,9,10], + min_z_endpos=well.get_absolute_location(z="cavity_bottom").z, + surface_following_distance=0, + pull_out_distance_transport_air=[0] * 4) + await step_off_foil(lh.backend, [well], front_channel=11, back_channel=6, move_inwards=3) + + Args: + wells: Wells in the plate to hold down. (x-coordinate of channels will be at center of wells). + Must be sorted from back to front. + front_channel: The channel to place on the front of the plate. + back_channel: The channel to place on the back of the plate. + move_inwards: mm to move inwards (backward on the front channel; frontward on the back). + move_height: mm to move upwards after piercing the foil. front_channel and back_channel will hold the plate down. + """ + + if front_channel <= back_channel: + raise ValueError( + "front_channel should be in front of back_channel. " "Channels are 0-indexed from the back." + ) + + if isinstance(wells, Well): + wells = [wells] + + plates = set(well.parent for well in wells) + assert len(plates) == 1, "All wells must be in the same plate" + plate = plates.pop() + assert plate is not None + + z_location = plate.get_absolute_location(z="top").z + + if plate.get_absolute_rotation().z % 360 == 0: + back_location = plate.get_absolute_location(y="b") + front_location = plate.get_absolute_location(y="f") + elif plate.get_absolute_rotation().z % 360 == 90: + back_location = plate.get_absolute_location(x="r") + front_location = plate.get_absolute_location(x="l") + elif plate.get_absolute_rotation().z % 360 == 180: + back_location = plate.get_absolute_location(y="f") + front_location = plate.get_absolute_location(y="b") + elif plate.get_absolute_rotation().z % 360 == 270: + back_location = plate.get_absolute_location(x="l") + front_location = plate.get_absolute_location(x="r") + else: + raise ValueError("Plate rotation must be a multiple of 90 degrees") + + try: + # Then move all channels in the y-space simultaneously. + await self.position_channels_in_y_direction( + { + front_channel: front_location.y + move_inwards, + back_channel: back_location.y - move_inwards, + } + ) + + await self.move_channel_z(front_channel, z_location) + await self.move_channel_z(back_channel, z_location) + finally: + # Move channels that are lower than the `front_channel` and `back_channel` to + # the just above the foil, in case the foil pops up. + zs = await self.get_channels_z_positions() + indices = [channel_idx for channel_idx, z in zs.items() if z < z_location] + idx = { + idx: z_location + move_height for idx in indices if idx not in (front_channel, back_channel) + } + await self.position_channels_in_z_direction(idx) + + # After that, all channels are clear to move up. + await self.move_all_channels_in_z_safety() + + async def request_volume_in_tip(self, channel: int) -> float: + resp = await self.send_command(STAR.channel_id(channel), "QC", fmt="qc##### (n)") + _, current_volume = resp["qc"] # first is max volume + return float(current_volume) / 10 + + @asynccontextmanager + async def slow_iswap(self, wrist_velocity: int = 20_000, gripper_velocity: int = 20_000): + """A context manager that sets the iSWAP to slow speed during the context""" + assert 20 <= gripper_velocity <= 75_000 + assert 20 <= wrist_velocity <= 65_000 + + original_wv = (await self.send_command("R0", "RA", ra="wv", fmt="wv#####"))["wv"] + original_tv = (await self.send_command("R0", "RA", ra="tv", fmt="tv#####"))["tv"] + + await self.send_command("R0", "AA", wv=gripper_velocity) # wrist velocity + await self.send_command("R0", "AA", tv=wrist_velocity) # gripper velocity + try: + yield + finally: + await self.send_command("R0", "AA", wv=original_wv) + await self.send_command("R0", "AA", tv=original_tv) + class UnSafe: """ @@ -6939,7 +7902,6 @@ async def put_in_hotel( hotel_center_x_coord: int = 0, hotel_center_y_coord: int = 0, hotel_center_z_coord: int = 0, - # for direction, 0 is positive, 1 is negative hotel_center_x_direction: Literal[0, 1] = 0, hotel_center_y_direction: Literal[0, 1] = 0, hotel_center_z_direction: Literal[0, 1] = 0, @@ -7079,3 +8041,16 @@ async def get_from_hotel( xe=f"{high_acceleration_index} {low_acceleration_index}", gc=int(fold_up_at_end), ) + + async def violently_shoot_down_tip(self, channel_idx: int): + """Shoot down the tip on the specified channel by releasing the drive that holds the spring. The + tips will shoot down in place at an acceleration bigger than g. This is done by initializing + the squeezer drive wihile a tip is mounted. + + Safe to do when above a tip rack, for example directly after a tip pickup. + + .. warning:: + + Consider this method an easter egg. Not for serious use. + """ + await self.star.send_command(module=STAR.channel_id(channel_idx), command="SI") diff --git a/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py b/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py index a7303adba9..b103940f42 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py +++ b/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py @@ -1,33 +1,31 @@ +# mypy: disable-error-code="attr-defined,method-assign" + import unittest import unittest.mock from typing import cast from pylabrobot.liquid_handling import LiquidHandler -from pylabrobot.liquid_handling.liquid_classes.hamilton.star import ( - HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty, - StandardVolumeFilter_Water_DispenseJet_Empty, - StandardVolumeFilter_Water_DispenseSurface, -) from pylabrobot.liquid_handling.standard import GripDirection, Pickup from pylabrobot.plate_reading import PlateReader -from pylabrobot.plate_reading.plate_reader_tests import MockPlateReaderBackend +from pylabrobot.plate_reading.chatterbox import PlateReaderChatterboxBackend from pylabrobot.resources import ( - HT_P, - HTF_L, + HT, + HTF, PLT_CAR_L5AC_A00, + PLT_CAR_L5MD_A00, + PLT_CAR_P3AC_A01, TIP_CAR_288_C00, TIP_CAR_480_A00, + AGenBio_1_troughplate_190000uL_Fl, + CellTreat_96_wellplate_350ul_Ub, Container, Coordinate, Cor_96_wellplate_360ul_Fb, Lid, - Plate, ResourceStack, no_volume_tracking, ) -from pylabrobot.resources.hamilton import STARLetDeck -from pylabrobot.resources.ml_star import STF_L -from tests.usb import MockDev, MockEndpoint +from pylabrobot.resources.hamilton import STF, STARLetDeck from .STAR import ( STAR, @@ -39,26 +37,6 @@ parse_star_fw_string, ) -PICKUP_TIP_FORMAT = "xp##### (n)yp#### (n)tm# (n)tt##tp####tz####th####td#" -DROP_TIP_FORMAT = "xp##### (n)yp#### (n)tm# (n)tp####tz####th####ti#" -ASPIRATION_COMMAND_FORMAT = ( - "at# (n)tm# (n)xp##### (n)yp#### (n)th####te####lp#### (n)ch### (n)zl#### (n)zx#### (n)" - "ip#### (n)it# (n)fp#### (n)av#### (n)as#### (n)ta### (n)ba#### (n)oa### (n)lm# (n)ll# (n)" - "lv# (n)ld## (n)de#### (n)wt## (n)mv##### (n)mc## (n)mp### (n)ms#### (n)gi### (n)gj#gk#" - "zu#### (n)zr#### (n)mh#### (n)zo### (n)po#### (n)lk# (n)ik#### (n)sd#### (n)se#### (n)" - "sz#### (n)io#### (n)il##### (n)in#### (n)" -) -DISPENSE_RESPONSE_FORMAT = ( - "dm# (n)tm# (n)xp##### (n)yp#### (n)zx#### (n)lp#### (n)zl#### (n)ip#### (n)it# (n)fp#### (n)" - "th####te####dv##### (n)ds#### (n)ss#### (n)rv### (n)ta### (n)ba#### (n)lm# (n)zo### (n)" - "ll# (n)lv# (n)de#### (n)mv##### (n)mc## (n)mp### (n)ms#### (n)wt## (n)gi### (n)gj#gk#" - "zu#### (n)zr##### (n)mh#### (n)po#### (n)" -) - -GET_PLATE_FMT = "xs#####xd#yj####yd#zj####zd#gr#th####te####gw#go####gb####gt##ga#gc#" -PUT_PLATE_FMT = "xs#####xd#yj####yd#zj####zd#th####te####gr#go####ga#" -INTERMEDIATE_FMT = "xs#####xd#yj####yd#zj####zd#gr#th####ga#xe# #" - class TestSTARResponseParsing(unittest.TestCase): """Test parsing of response from Hamilton.""" @@ -89,10 +67,10 @@ def test_parse_response_params(self): self.assertEqual(parsed, "") with self.assertRaises(ValueError): - parse_star_fw_string("C0QM", "id####") # pylint: disable=expression-not-assigned + parse_star_fw_string("C0QM", "id####") with self.assertRaises(ValueError): - parse_star_fw_string("C0RV", "") # pylint: disable=expression-not-assigned + parse_star_fw_string("C0RV", "") def test_parse_response_no_errors(self): parsed = parse_star_fw_string("C0QMid1111", "") @@ -130,8 +108,14 @@ def test_parse_response_slave_errors(self): self.assertIsInstance(e.errors["Pipetting channel 16"], HamiltonNoTipError) self.assertEqual(e.errors["Pipetting channel 2"].message, "No error") - self.assertEqual(e.errors["Pipetting channel 4"].message, "Unknown trace information code 98") - self.assertEqual(e.errors["Pipetting channel 16"].message, "Tip already picked up") + self.assertEqual( + e.errors["Pipetting channel 4"].message, + "Unknown trace information code 98", + ) + self.assertEqual( + e.errors["Pipetting channel 16"].message, + "Tip already picked up", + ) def test_parse_slave_response_errors(self): with self.assertRaises(STARFirmwareError) as ctx: @@ -145,35 +129,39 @@ def test_parse_slave_response_errors(self): self.assertEqual(e.errors["Pipetting channel 1"].message, "Unknown command") -class STARUSBCommsMocker(STAR): - """Mocks PyUSB""" - - async def setup(self, send_response: str): # type: ignore - self.dev = MockDev(send_response) - self.read_endpoint = MockEndpoint() - self.write_endpoint = MockEndpoint() +def _any_write_and_read_command_call(cmd): + return unittest.mock.call( + id_=unittest.mock.ANY, + cmd=cmd, + write_timeout=unittest.mock.ANY, + read_timeout=unittest.mock.ANY, + wait=unittest.mock.ANY, + ) class TestSTARUSBComms(unittest.IsolatedAsyncioTestCase): """Test that USB data is parsed correctly.""" + async def asyncSetUp(self): + self.star = STAR(read_timeout=2, packet_read_timeout=1) + self.star.set_deck(STARLetDeck()) + self.star.io = unittest.mock.MagicMock() + await super().asyncSetUp() + async def test_send_command_correct_response(self): - star = STARUSBCommsMocker() - await star.setup(send_response="C0QMid0001") # correct response - resp = await star.send_command("C0", command="QM", fmt="id####") + self.star.io.read.side_effect = [b"C0QMid0001"] + resp = await self.star.send_command("C0", command="QM", fmt="id####") self.assertEqual(resp, {"id": 1}) async def test_send_command_wrong_id(self): - star = STARUSBCommsMocker(read_timeout=2, packet_read_timeout=1) - await star.setup(send_response="C0QMid0000") # wrong response + self.star.io.read.side_effect = lambda: b"C0QMid0002" with self.assertRaises(TimeoutError): - await star.send_command("C0", command="QM") + await self.star.send_command("C0", command="QM", fmt="id####") async def test_send_command_plaintext_response(self): - star = STARUSBCommsMocker(read_timeout=2, packet_read_timeout=1) - await star.setup(send_response="this is plain text") # wrong response + self.star.io.read.side_effect = lambda: b"this is plaintext" with self.assertRaises(TimeoutError): - await star.send_command("C0", command="QM") + await self.star.send_command("C0", command="QM", fmt="id####") class STARCommandCatcher(STAR): @@ -184,23 +172,26 @@ def __init__(self): super().__init__() self.commands = [] - async def setup(self) -> None: + async def setup(self) -> None: # type: ignore self._num_channels = 8 self.iswap_installed = True self.core96_head_installed = True self._core_parked = True - async def send_command( + async def send_command( # type: ignore self, module, command, + auto_id=True, tip_pattern=None, - fmt="", # type: ignore + fmt="", read_timeout=0, write_timeout=0, **kwargs, ): - cmd, _ = self._assemble_command(module, command, tip_pattern, **kwargs) + cmd, _ = self._assemble_command( + module=module, command=command, auto_id=auto_id, tip_pattern=tip_pattern, **kwargs + ) self.commands.append(cmd) async def stop(self): @@ -211,14 +202,19 @@ class TestSTARLiquidHandlerCommands(unittest.IsolatedAsyncioTestCase): """Test STAR backend for liquid handling.""" async def asyncSetUp(self): - # pylint: disable=invalid-name - self.mockSTAR = STARCommandCatcher() + self.STAR = STAR(read_timeout=1) + self.STAR._write_and_read_command = unittest.mock.AsyncMock() + self.STAR.io = unittest.mock.MagicMock() + self.STAR.io.setup = unittest.mock.AsyncMock() + self.STAR.io.write = unittest.mock.MagicMock() + self.STAR.io.read = unittest.mock.MagicMock() + self.deck = STARLetDeck() - self.lh = LiquidHandler(self.mockSTAR, deck=self.deck) + self.lh = LiquidHandler(self.STAR, deck=self.deck) self.tip_car = TIP_CAR_480_A00(name="tip carrier") - self.tip_car[1] = self.tip_rack = STF_L(name="tip_rack_01") - self.tip_car[2] = self.tip_rack2 = HTF_L(name="tip_rack_02") + self.tip_car[1] = self.tip_rack = STF(name="tip_rack_01") + self.tip_car[2] = self.tip_rack2 = HTF(name="tip_rack_02") self.deck.assign_child_resource(self.tip_car, rails=1) self.plt_car = PLT_CAR_L5AC_A00(name="plate carrier") @@ -260,74 +256,29 @@ def __init__(self, name: str): self.maxDiff = None + self.STAR._num_channels = 8 + self.STAR.core96_head_installed = True + self.STAR.iswap_installed = True + self.STAR.setup = unittest.mock.AsyncMock() + self.STAR._core_parked = True + self.STAR._iswap_parked = True await self.lh.setup() - self.hlc = StandardVolumeFilter_Water_DispenseSurface.copy() - self.hlc.aspiration_air_transport_volume = 0 - self.hlc.dispense_air_transport_volume = 0 - async def asyncTearDown(self): await self.lh.stop() - def _assert_command_in_command_buffer(self, cmd: str, should_be: bool, fmt: str): - """Assert that the given command was sent to the backend. The ordering of the parameters is not - taken into account, but the values and formatting should match. The id parameter of the command - is ignored. - - If a command is found, it is removed from the command buffer. - - Args: - cmd: the command to look for - should_be: whether the command should be found or not - fmt: the format of the command - """ - - found = False - # Command that fits the format, but is not the same as the command we are looking for. - similar = None - - parsed_cmd = parse_star_fw_string(cmd, fmt) - parsed_cmd.pop("id") - - for sent_cmd in self.mockSTAR.commands: - # When the module and command do not match, there is no point in comparing the parameters. - if sent_cmd[0:4] != cmd[0:4]: - continue - - try: - parsed_sent_cmd = parse_star_fw_string(sent_cmd, fmt) - parsed_sent_cmd.pop("id") - - if parsed_cmd == parsed_sent_cmd: - self.mockSTAR.commands.remove(sent_cmd) - found = True - break - else: - similar = parsed_sent_cmd - except ValueError as e: - # The command could not be parsed. - print(e) - continue - - if should_be and not found: - if similar is not None: - # These will not be equal, but this method does give a better error message than `fail`. - self.assertEqual(similar, parsed_cmd) - else: - self.fail(f"Command {cmd} not found in sent commands: {self.mockSTAR.commands}") - elif not should_be and found: - self.fail(f"Command {cmd} was found in sent commands: {self.mockSTAR.commands}") - async def test_indictor_light(self): - """Test the indicator light.""" - await self.mockSTAR.set_loading_indicators(bit_pattern=[True] * 54, blink_pattern=[False] * 54) - self._assert_command_sent_once( - "C0CPid0000cl3FFFFFFFFFFFFFcb00000000000000", "cl**************cb**************" + await self.STAR.set_loading_indicators(bit_pattern=[True] * 54, blink_pattern=[False] * 54) + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0CPid0001cl3FFFFFFFFFFFFFcb00000000000000", + ) + ] ) def test_ops_to_fw_positions(self): """Convert channel positions to firmware positions.""" - # pylint: disable=protected-access tip_a1 = self.tip_rack.get_item("A1") tip_f1 = self.tip_rack.get_item("F1") tip = self.tip_rack.get_tip("A1") @@ -335,25 +286,29 @@ def test_ops_to_fw_positions(self): op1 = Pickup(resource=tip_a1, tip=tip, offset=Coordinate.zero()) op2 = Pickup(resource=tip_f1, tip=tip, offset=Coordinate.zero()) self.assertEqual( - self.mockSTAR._ops_to_fw_positions((op1,), use_channels=[0]), + self.STAR._ops_to_fw_positions((op1,), use_channels=[0]), ([1179, 0], [2418, 0], [True, False]), ) self.assertEqual( - self.mockSTAR._ops_to_fw_positions((op1, op2), use_channels=[0, 1]), + self.STAR._ops_to_fw_positions((op1, op2), use_channels=[0, 1]), ([1179, 1179, 0], [2418, 1968, 0], [True, True, False]), ) self.assertEqual( - self.mockSTAR._ops_to_fw_positions((op1, op2), use_channels=[1, 2]), - ([0, 1179, 1179, 0], [0, 2418, 1968, 0], [False, True, True, False]), + self.STAR._ops_to_fw_positions((op1, op2), use_channels=[1, 2]), + ( + [0, 1179, 1179, 0], + [0, 2418, 1968, 0], + [False, True, True, False], + ), ) # check two operations on the same row, different column. tip_a2 = self.tip_rack.get_item("A2") op3 = Pickup(resource=tip_a2, tip=tip, offset=Coordinate.zero()) self.assertEqual( - self.mockSTAR._ops_to_fw_positions((op1, op3), use_channels=[0, 1]), + self.STAR._ops_to_fw_positions((op1, op3), use_channels=[0, 1]), ([1179, 1269, 0], [2418, 2418, 0], [True, True, False]), ) @@ -363,52 +318,61 @@ def test_ops_to_fw_positions(self): tip_b2 = self.tip_rack.get_item("B2") op5 = Pickup(resource=tip_b2, tip=tip, offset=Coordinate.zero()) self.assertEqual( - self.mockSTAR._ops_to_fw_positions((op1, op4, op3, op5), use_channels=[0, 1, 2, 3]), - ([1179, 1179, 1269, 1269, 0], [2418, 2328, 2418, 2328, 0], [True, True, True, True, False]), + self.STAR._ops_to_fw_positions((op1, op4, op3, op5), use_channels=[0, 1, 2, 3]), + ( + [1179, 1179, 1269, 1269, 0], + [2418, 2328, 2418, 2328, 0], + [True, True, True, True, False], + ), ) # make sure two operations on the same spot are not allowed with self.assertRaises(ValueError): - self.mockSTAR._ops_to_fw_positions((op1, op1), use_channels=[0, 1]) - - def _assert_command_sent_once(self, cmd: str, fmt: str): - """Assert that the given command was sent to the backend exactly once.""" - self._assert_command_in_command_buffer(cmd, True, fmt) - self._assert_command_in_command_buffer(cmd, False, fmt) + self.STAR._ops_to_fw_positions((op1, op1), use_channels=[0, 1]) def test_tip_definition(self): pass async def test_tip_pickup_01(self): await self.lh.pick_up_tips(self.tip_rack["A1", "B1"]) - self._assert_command_sent_once( - "C0TPid0000xp01179 01179 00000&yp2418 2328 0000tm1 1 0&tt01tp2244tz2164th2450td0", - PICKUP_TIP_FORMAT, + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0TTid0001tt01tf1tl0519tv03600tg2tu0", + ), + _any_write_and_read_command_call( + "C0TPid0002xp01179 01179 00000&yp2418 2328 0000&tm1 1 0&tt01tp2244tz2164th2450td0", + ), + ] ) async def test_tip_pickup_56(self): await self.lh.pick_up_tips(self.tip_rack["E1", "F1"], use_channels=[4, 5]) - self._assert_command_sent_once( - "C0TPid0000xp00000 00000 00000 00000 01179 01179 00000&yp0000 0000 0000 0000 2058 1968 " - "0000&tm0 0 0 0 1 1 0 &tt01tp2244tz2164th2450td0", - PICKUP_TIP_FORMAT, - ) - - async def test_tip_pickup_15(self): - await self.lh.pick_up_tips(self.tip_rack["A1", "F1"], use_channels=[0, 4]) - self._assert_command_sent_once( - "C0TPid0000xp01179 00000 00000 00000 01179 00000&yp2418 0000 0000 0000 1968 0000 " - "&tm1 0 0 0 1 0&tt01tp2244tz2164th2450td0", - PICKUP_TIP_FORMAT, - ) + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0TTid0001tt01tf1tl0519tv03600tg2tu0", + ), + _any_write_and_read_command_call( + "C0TPid0002xp00000 00000 00000 00000 01179 01179 00000&yp0000 0000 0000 0000 2058 1968 0000&tm0 0 0 0 1 1 0&tt01tp2244tz2164th2450td0", + ), + ] + ) + self.STAR.io.write.reset_mock() async def test_tip_drop_56(self): await self.test_tip_pickup_56() # pick up tips first + self.STAR._write_and_read_command.side_effect = [ + "C0TRid0003kz000 000 000 000 000 000 000 000vz000 000 000 000 000 000 000 000" + ] await self.lh.drop_tips(self.tip_rack["E1", "F1"], use_channels=[4, 5]) - self._assert_command_sent_once( - "C0TRid0000xp00000 00000 00000 00000 01179 01179 00000&yp0000 0000 0000 0000 2058 1968 " - "0000&tm0 0 0 0 1 1 0&tp2244tz2164th2450ti1", - DROP_TIP_FORMAT, + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0TRid0003xp00000 00000 00000 00000 01179 01179 00000&yp0000 0000 0000 0000 2058 1968 " + "0000&tm0 0 0 0 1 1 0&tp2244tz2164th2450te2450ti1", + ) + ] ) async def test_aspirate56(self): @@ -418,31 +382,29 @@ async def test_aspirate56(self): self.plate.lid.unassign() for well in self.plate.get_items(["A1", "B1"]): well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction - corrected_vol = self.hlc.compute_corrected_volume(100) - await self.lh.aspirate( - self.plate["A1", "B1"], - vols=[corrected_vol, corrected_vol], - use_channels=[4, 5], - **self.hlc.make_asp_kwargs(2), - ) - self._assert_command_sent_once( - "C0ASid0004at0 0 0 0 0 0 0&tm0 0 0 0 1 1 0&xp00000 00000 00000 " - "00000 02983 02983 00000&yp0000 0000 0000 0000 1457 1367 0000&th2450te2450lp2000 2000 2000 " - "2000 2000 2000 2000&ch000 000 000 000 000 000 000&zl1866 1866 1866 1866 1866 1866 1866&" - "po0100 0100 0100 0100 0100 0100 0100&zu0032 0032 0032 0032 0032 0032 0032&zr06180 06180 " - "06180 06180 06180 06180 06180&zx1866 1866 1866 1866 1866 1866 1866&ip0000 0000 0000 0000 " - "0000 0000 0000&it0 0 0 0 0 0 0&fp0000 0000 0000 0000 0000 0000 0000&av01072 01072 01072 " - "01072 01072 01072 01072&as1000 1000 1000 1000 1000 1000 1000&ta000 000 000 000 000 000 000&" - "ba0000 0000 0000 0000 0000 0000 0000&oa000 000 000 000 000 000 000&lm0 0 0 0 0 0 0&ll1 1 1 " - "1 1 1 1&lv1 1 1 1 1 1 1&zo000 000 000 000 000 000 000&ld00 00 00 00 00 00 00&de0020 0020 " - "0020 0020 0020 0020 0020&wt10 10 10 10 10 10 10&mv00000 00000 00000 00000 00000 00000 00000&" - "mc00 00 00 00 00 00 00&mp000 000 000 000 000 000 000&ms1000 1000 1000 1000 1000 1000 1000&" - "mh0000 0000 0000 0000 0000 0000 0000&gi000 000 000 000 000 000 000&gj0gk0lk0 0 0 0 0 0 0&" - "ik0000 0000 0000 0000 0000 0000 0000&sd0500 0500 0500 0500 0500 0500 0500&se0500 0500 0500 " - "0500 0500 0500 0500&sz0300 0300 0300 0300 0300 0300 0300&io0000 0000 0000 0000 0000 0000 0" - "000&il00000 00000 00000 00000 00000 00000 00000&in0000 0000 0000 0000 0000 0000 0000&", - ASPIRATION_COMMAND_FORMAT, + await self.lh.aspirate(self.plate["A1", "B1"], vols=[100, 100], use_channels=[4, 5]) + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0ASid0003at0 0 0 0 0 0 0&tm0 0 0 0 1 1 0&xp00000 00000 00000 " + "00000 02983 02983 00000&yp0000 0000 0000 0000 1457 1367 0000&th2450te2450lp2000 2000 2000 " + "2000 2000 2000 2000&ch000 000 000 000 000 000 000&zl1866 1866 1866 1866 1866 1866 1866&" + "po0100 0100 0100 0100 0100 0100 0100&zu0032 0032 0032 0032 0032 0032 0032&zr06180 06180 " + "06180 06180 06180 06180 06180&zx1866 1866 1866 1866 1866 1866 1866&ip0000 0000 0000 0000 " + "0000 0000 0000&it0 0 0 0 0 0 0&fp0000 0000 0000 0000 0000 0000 0000&av01072 01072 01072 " + "01072 01072 01072 01072&as1000 1000 1000 1000 1000 1000 1000&ta000 000 000 000 000 000 000&" + "ba0000 0000 0000 0000 0000 0000 0000&oa000 000 000 000 000 000 000&lm0 0 0 0 0 0 0&ll1 1 1 " + "1 1 1 1&lv1 1 1 1 1 1 1&zo000 000 000 000 000 000 000&ld00 00 00 00 00 00 00&de0020 0020 " + "0020 0020 0020 0020 0020&wt10 10 10 10 10 10 10&mv00000 00000 00000 00000 00000 00000 00000&" + "mc00 00 00 00 00 00 00&mp000 000 000 000 000 000 000&ms1000 1000 1000 1000 1000 1000 1000&" + "mh0000 0000 0000 0000 0000 0000 0000&gi000 000 000 000 000 000 000&gj0gk0lk0 0 0 0 0 0 0&" + "ik0000 0000 0000 0000 0000 0000 0000&sd0500 0500 0500 0500 0500 0500 0500&se0500 0500 0500 " + "0500 0500 0500 0500&sz0300 0300 0300 0300 0300 0300 0300&io0000 0000 0000 0000 0000 0000 0" + "000&il00000 00000 00000 00000 00000 00000 00000&in0000 0000 0000 0000 0000 0000 0000&", + ) + ] ) + self.STAR.io.write.reset_mock() async def test_single_channel_aspiration(self): self.lh.update_head_state({0: self.tip_rack.get_tip("A1")}) @@ -450,19 +412,18 @@ async def test_single_channel_aspiration(self): self.plate.lid.unassign() well = self.plate.get_item("A1") well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction - await self.lh.aspirate( - [well], vols=[self.hlc.compute_corrected_volume(100)], **self.hlc.make_asp_kwargs(1) - ) - - # This passes the test, but is not the real command. - self._assert_command_sent_once( - "C0ASid0002at0 0&tm1 0&xp02983 00000&yp1457 0000&th2450te2450lp2000 2000&ch000 000&zl1866 " - "1866&po0100 0100&zu0032 0032&zr06180 06180&zx1866 1866&ip0000 0000&it0 0&fp0000 0000&" - "av01072 01072&as1000 1000&ta000 000&ba0000 0000&oa000 000&lm0 0&ll1 1&lv1 1&zo000 000&" - "ld00 00&de0020 0020&wt10 10&mv00000 00000&mc00 00&mp000 000&ms1000 1000&mh0000 0000&" - "gi000 000&gj0gk0lk0 0&ik0000 0000&sd0500 0500&se0500 0500&sz0300 0300&io0000 0000&" - "il00000 00000&in0000 0000&", - fmt=ASPIRATION_COMMAND_FORMAT, + await self.lh.aspirate([well], vols=[100]) + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0ASid0001at0 0&tm1 0&xp02983 00000&yp1457 0000&th2450te2450lp2000 2000&ch000 000&zl1866 " + "1866&po0100 0100&zu0032 0032&zr06180 06180&zx1866 1866&ip0000 0000&it0 0&fp0000 0000&" + "av01072 01072&as1000 1000&ta000 000&ba0000 0000&oa000 000&lm0 0&ll1 1&lv1 1&zo000 000&" + "ld00 00&de0020 0020&wt10 10&mv00000 00000&mc00 00&mp000 000&ms1000 1000&mh0000 0000&" + "gi000 000&gj0gk0lk0 0&ik0000 0000&sd0500 0500&se0500 0500&sz0300 0300&io0000 0000&" + "il00000 00000&in0000 0000&", + ) + ] ) async def test_single_channel_aspiration_liquid_height(self): @@ -472,22 +433,20 @@ async def test_single_channel_aspiration_liquid_height(self): self.plate.lid.unassign() well = self.plate.get_item("A1") well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction - await self.lh.aspirate( - [well], - vols=[self.hlc.compute_corrected_volume(100)], - liquid_height=[10], - **self.hlc.make_asp_kwargs(1), - ) + await self.lh.aspirate([well], vols=[100], liquid_height=[10]) # This passes the test, but is not the real command. - self._assert_command_sent_once( - "C0ASid0002at0 0&tm1 0&xp02983 00000&yp1457 0000&th2450te2450lp2000 2000&ch000 000&zl1966 " - "1966&po0100 0100&zu0032 0032&zr06180 06180&zx1866 1866&ip0000 0000&it0 0&fp0000 0000&" - "av01072 01072&as1000 1000&ta000 000&ba0000 0000&oa000 000&lm0 0&ll1 1&lv1 1&zo000 000&" - "ld00 00&de0020 0020&wt10 10&mv00000 00000&mc00 00&mp000 000&ms1000 1000&mh0000 0000&" - "gi000 000&gj0gk0lk0 0&ik0000 0000&sd0500 0500&se0500 0500&sz0300 0300&io0000 0000&" - "il00000 00000&in0000 0000&", - fmt=ASPIRATION_COMMAND_FORMAT, + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0ASid0001at0 0&tm1 0&xp02983 00000&yp1457 0000&th2450te2450lp2000 2000&ch000 000&zl1966 " + "1966&po0100 0100&zu0032 0032&zr06180 06180&zx1866 1866&ip0000 0000&it0 0&fp0000 0000&" + "av01072 01072&as1000 1000&ta000 000&ba0000 0000&oa000 000&lm0 0&ll1 1&lv1 1&zo000 000&" + "ld00 00&de0020 0020&wt10 10&mv00000 00000&mc00 00&mp000 000&ms1000 1000&mh0000 0000&" + "gi000 000&gj0gk0lk0 0&ik0000 0000&sd0500 0500&se0500 0500&sz0300 0300&io0000 0000&" + "il00000 00000&in0000 0000&", + ) + ] ) async def test_multi_channel_aspiration(self): @@ -498,100 +457,93 @@ async def test_multi_channel_aspiration(self): wells = self.plate.get_items("A1:B1") for well in wells: well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction - corrected_vol = self.hlc.compute_corrected_volume(100) - await self.lh.aspirate( - self.plate["A1:B1"], vols=[corrected_vol] * 2, **self.hlc.make_asp_kwargs(2) - ) + await self.lh.aspirate(self.plate["A1:B1"], vols=[100] * 2) # This passes the test, but is not the real command. - self._assert_command_sent_once( - "C0ASid0002at0 0 0&tm1 1 0&xp02983 02983 00000&yp1457 1367 0000&th2450te2450lp2000 2000 2000&" - "ch000 000 000&zl1866 1866 1866&po0100 0100 0100&zu0032 0032 0032&zr06180 06180 06180&" - "zx1866 1866 1866&ip0000 0000 0000&it0 0 0&fp0000 0000 0000&av01072 01072 01072&as1000 1000 " - "1000&ta000 000 000&ba0000 0000 0000&oa000 000 000&lm0 0 0&ll1 1 1&lv1 1 1&zo000 000 000&" - "ld00 00 00&de0020 0020 0020&wt10 10 10&mv00000 00000 00000&mc00 00 00&mp000 000 000&" - "ms1000 1000 1000&mh0000 0000 0000&gi000 000 000&gj0gk0lk0 0 0&ik0000 0000 0000&sd0500 0500 " - "0500&se0500 0500 0500&sz0300 0300 0300&io0000 0000 0000&il00000 00000 00000&in0000 0000 " - "0000&", - fmt=ASPIRATION_COMMAND_FORMAT, + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0ASid0001at0 0 0&tm1 1 0&xp02983 02983 00000&yp1457 1367 0000&th2450te2450lp2000 2000 2000&" + "ch000 000 000&zl1866 1866 1866&po0100 0100 0100&zu0032 0032 0032&zr06180 06180 06180&" + "zx1866 1866 1866&ip0000 0000 0000&it0 0 0&fp0000 0000 0000&av01072 01072 01072&as1000 1000 " + "1000&ta000 000 000&ba0000 0000 0000&oa000 000 000&lm0 0 0&ll1 1 1&lv1 1 1&zo000 000 000&" + "ld00 00 00&de0020 0020 0020&wt10 10 10&mv00000 00000 00000&mc00 00 00&mp000 000 000&" + "ms1000 1000 1000&mh0000 0000 0000&gi000 000 000&gj0gk0lk0 0 0&ik0000 0000 0000&sd0500 0500 " + "0500&se0500 0500 0500&sz0300 0300 0300&io0000 0000 0000&il00000 00000 00000&in0000 0000 " + "0000&", + ) + ] ) async def test_aspirate_single_resource(self): self.lh.update_head_state({i: self.tip_rack.get_tip(i) for i in range(5)}) - corrected_vol = self.hlc.compute_corrected_volume(10) with no_volume_tracking(): await self.lh.aspirate( [self.bb] * 5, - vols=[corrected_vol] * 5, + vols=[10] * 5, use_channels=[0, 1, 2, 3, 4], liquid_height=[1] * 5, - **self.hlc.make_asp_kwargs(5), ) - self._assert_command_sent_once( - "C0ASid0002at0 0 0 0 0 0&tm1 1 1 1 1 0&xp04865 04865 04865 04865 04865 00000&yp2098 1962 " - "1825 1688 1552 0000&th2450te2450lp2000 2000 2000 2000 2000 2000&ch000 000 000 000 000 000&" - "zl1210 1210 1210 1210 1210 1210&po0100 0100 0100 0100 0100 0100&zu0032 0032 0032 0032 0032 " - "0032&zr06180 06180 06180 06180 06180 06180&zx1200 1200 1200 1200 1200 1200&ip0000 0000 0000 " - "0000 0000 0000&it0 0 0 0 0 0&fp0000 0000 0000 0000 0000 0000&av00119 00119 00119 00119 " - "00119 00119&as1000 1000 1000 1000 1000 1000&ta000 000 000 000 000 000&ba0000 0000 0000 0000 " - "0000 0000&oa000 000 000 000 000 000&lm0 0 0 0 0 0&ll1 1 1 1 1 1&lv1 1 1 1 1 1&zo000 000 000 " - "000 000 000&ld00 00 00 00 00 00&de0020 0020 0020 0020 0020 0020&wt10 10 10 10 10 10&mv00000 " - "00000 00000 00000 00000 00000&mc00 00 00 00 00 00&mp000 000 000 000 000 000&ms1000 1000 " - "1000 1000 1000 1000&mh0000 0000 0000 0000 0000 0000&gi000 000 000 000 000 000&gj0gk0lk0 0 0 " - "0 0 0&ik0000 0000 0000 0000 0000 0000&sd0500 0500 0500 0500 0500 0500&se0500 0500 0500 0500 " - "0500 0500&sz0300 0300 0300 0300 0300 0300&io0000 0000 0000 0000 0000 0000&il00000 00000 " - "00000 00000 00000 00000&in0000 0000 0000 0000 0000 0000&", - fmt=ASPIRATION_COMMAND_FORMAT, + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0ASid0001at0 0 0 0 0 0&tm1 1 1 1 1 0&xp04865 04865 04865 04865 04865 00000&yp2098 1962 " + "1825 1688 1552 0000&th2450te2450lp2000 2000 2000 2000 2000 2000&ch000 000 000 000 000 000&" + "zl1210 1210 1210 1210 1210 1210&po0100 0100 0100 0100 0100 0100&zu0032 0032 0032 0032 0032 " + "0032&zr06180 06180 06180 06180 06180 06180&zx1200 1200 1200 1200 1200 1200&ip0000 0000 0000 " + "0000 0000 0000&it0 0 0 0 0 0&fp0000 0000 0000 0000 0000 0000&av00119 00119 00119 00119 " + "00119 00119&as1000 1000 1000 1000 1000 1000&ta000 000 000 000 000 000&ba0000 0000 0000 0000 " + "0000 0000&oa000 000 000 000 000 000&lm0 0 0 0 0 0&ll1 1 1 1 1 1&lv1 1 1 1 1 1&zo000 000 000 " + "000 000 000&ld00 00 00 00 00 00&de0020 0020 0020 0020 0020 0020&wt10 10 10 10 10 10&mv00000 " + "00000 00000 00000 00000 00000&mc00 00 00 00 00 00&mp000 000 000 000 000 000&ms1000 1000 " + "1000 1000 1000 1000&mh0000 0000 0000 0000 0000 0000&gi000 000 000 000 000 000&gj0gk0lk0 0 0 " + "0 0 0&ik0000 0000 0000 0000 0000 0000&sd0500 0500 0500 0500 0500 0500&se0500 0500 0500 0500 " + "0500 0500&sz0300 0300 0300 0300 0300 0300&io0000 0000 0000 0000 0000 0000&il00000 00000 " + "00000 00000 00000 00000&in0000 0000 0000 0000 0000 0000&", + ) + ] ) async def test_dispense_single_resource(self): self.lh.update_head_state({i: self.tip_rack.get_tip(i) for i in range(5)}) - hlc = StandardVolumeFilter_Water_DispenseJet_Empty - corrected_vol = hlc.compute_corrected_volume(10) with no_volume_tracking(): await self.lh.dispense( [self.bb] * 5, - vols=[corrected_vol] * 5, + vols=[10] * 5, + use_channels=[0, 1, 2, 3, 4], liquid_height=[1] * 5, - jet=[True] * 5, blow_out=[True] * 5, - **hlc.make_disp_kwargs(5), + jet=[True] * 5, ) - self._assert_command_sent_once( - "C0DSid0002dm1 1 1 1 1 1&tm1 1 1 1 1 0&xp04865 04865 04865 04865 04865 00000&yp2098 1962 " - "1825 1688 1552 0000&zx1200 1200 1200 1200 1200 1200&lp2000 2000 2000 2000 2000 2000&zl1210 " - "1210 1210 1210 1210 1210&po0100 0100 0100 0100 0100 0100&ip0000 0000 0000 0000 0000 0000&" - "it0 0 0 0 0 0&fp0000 0000 0000 0000 0000 0000&zu0032 0032 0032 0032 0032 0032&zr06180 06180 " - "06180 06180 06180 06180&th2450te2450dv00116 00116 00116 00116 00116 00116&ds1800 1800 1800 " - "1800 1800 1800&ss0050 0050 0050 0050 0050 0050&rv000 000 000 000 000 000&ta050 050 050 050 " - "050 050&ba0300 0300 0300 0300 0300 0300&lm0 0 0 0 0 0&dj00zo000 000 000 000 000 000&ll1 1 1 " - "1 1 1&lv1 1 1 1 1 1&de0010 0010 0010 0010 0010 0010&wt00 00 00 00 00 00&mv00000 00000 00000 " - "00000 00000 00000&mc00 00 00 00 00 00&mp000 000 000 000 000 000&ms0010 0010 0010 0010 0010 " - "0010&mh0000 0000 0000 0000 0000 0000&gi000 000 000 000 000 000&gj0gk0", - fmt=DISPENSE_RESPONSE_FORMAT, + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0DSid0001dm1 1 1 1 1 1&tm1 1 1 1 1 0&xp04865 04865 04865 04865 04865 00000&yp2098 1962 " + "1825 1688 1552 0000&zx1200 1200 1200 1200 1200 1200&lp2000 2000 2000 2000 2000 2000&zl1210 " + "1210 1210 1210 1210 1210&po0100 0100 0100 0100 0100 0100&ip0000 0000 0000 0000 0000 0000&" + "it0 0 0 0 0 0&fp0000 0000 0000 0000 0000 0000&zu0032 0032 0032 0032 0032 0032&zr06180 06180 " + "06180 06180 06180 06180&th2450te2450dv00116 00116 00116 00116 00116 00116&ds1800 1800 1800 " + "1800 1800 1800&ss0050 0050 0050 0050 0050 0050&rv000 000 000 000 000 000&ta050 050 050 050 " + "050 050&ba0300 0300 0300 0300 0300 0300&lm0 0 0 0 0 0&dj00zo000 000 000 000 000 000&ll1 1 1 " + "1 1 1&lv1 1 1 1 1 1&de0010 0010 0010 0010 0010 0010&wt00 00 00 00 00 00&mv00000 00000 00000 " + "00000 00000 00000&mc00 00 00 00 00 00&mp000 000 000 000 000 000&ms0010 0010 0010 0010 0010 " + "0010&mh0000 0000 0000 0000 0000 0000&gi000 000 000 000 000 000&gj0gk0", + ) + ] ) async def test_single_channel_dispense(self): self.lh.update_head_state({0: self.tip_rack.get_tip("A1")}) assert self.plate.lid is not None self.plate.lid.unassign() - hlc = StandardVolumeFilter_Water_DispenseJet_Empty - corrected_vol = hlc.compute_corrected_volume(100) with no_volume_tracking(): - await self.lh.dispense( - self.plate["A1"], - vols=[corrected_vol], - jet=[True], - blow_out=[True], - **hlc.make_disp_kwargs(1), - ) - self._assert_command_sent_once( - "C0DSid0002dm1 1&tm1 0&xp02983 00000&yp1457 0000&zx1866 1866&lp2000 2000&zl1866 1866&" - "po0100 0100&ip0000 0000&it0 0&fp0000 0000&zu0032 0032&zr06180 06180&th2450te2450" - "dv01072 01072&ds1800 1800&ss0050 0050&rv000 000&ta050 050&ba0300 03000&lm0 0&" - "dj00zo000 000&ll1 1&lv1 1&de0010 0010&wt00 00&mv00000 00000&mc00 00&mp000 000&" - "ms0010 0010&mh0000 0000&gi000 000&gj0gk0", - fmt=DISPENSE_RESPONSE_FORMAT, + await self.lh.dispense(self.plate["A1"], vols=[100], jet=[True], blow_out=[True]) + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0DSid0001dm1 1&tm1 0&xp02983 00000&yp1457 0000&zx1866 1866&lp2000 2000&zl1866 1866&po0100 0100&ip0000 0000&it0 0&fp0000 0000&zu0032 0032&zr06180 06180&th2450te2450dv01072 01072&ds1800 1800&ss0050 0050&rv000 000&ta050 050&ba0300 0300&lm0 0&dj00zo000 000&ll1 1&lv1 1&de0010 0010&wt00 00&mv00000 00000&mc00 00&mp000 000&ms0010 0010&mh0000 0000&gi000 000&gj0gk0", + ) + ] ) async def test_multi_channel_dispense(self): @@ -599,99 +551,91 @@ async def test_multi_channel_dispense(self): # TODO: Hamilton liquid classes assert self.plate.lid is not None self.plate.lid.unassign() - hlc = StandardVolumeFilter_Water_DispenseJet_Empty - corrected_vol = hlc.compute_corrected_volume(100) with no_volume_tracking(): await self.lh.dispense( self.plate["A1:B1"], - vols=[corrected_vol] * 2, + vols=[100] * 2, jet=[True] * 2, blow_out=[True] * 2, - **hlc.make_disp_kwargs(2), ) - self._assert_command_sent_once( - "C0DSid0002dm1 1 1&tm1 1 0&xp02983 02983 00000&yp1457 1367 0000&zx1866 1866 1866&lp2000 2000 " - "2000&zl1866 1866 1866&po0100 0100 0100&ip0000 0000 0000&it0 0 0&fp0000 0000 0000&zu0032 " - "0032 0032&zr06180 06180 06180&th2450te2450dv01072 01072 01072&ds1800 1800 1800&" - "ss0050 0050 0050&rv000 000 000&ta050 050 050&ba0300 0300 0300&lm0 0 0&dj00zo000 000 000&" - "ll1 1 1&lv1 1 1&de0010 0010 0010&wt00 00 00&mv00000 00000 00000&mc00 00 00&mp000 000 000&" - "ms0010 0010 0010&mh0000 0000 0000&gi000 000 000&gj0gk0", - fmt=DISPENSE_RESPONSE_FORMAT, + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0DSid0001dm1 1 1&tm1 1 0&xp02983 02983 00000&yp1457 1367 0000&zx1866 1866 1866&lp2000 2000 " + "2000&zl1866 1866 1866&po0100 0100 0100&ip0000 0000 0000&it0 0 0&fp0000 0000 0000&zu0032 " + "0032 0032&zr06180 06180 06180&th2450te2450dv01072 01072 01072&ds1800 1800 1800&" + "ss0050 0050 0050&rv000 000 000&ta050 050 050&ba0300 0300 0300&lm0 0 0&dj00zo000 000 000&" + "ll1 1 1&lv1 1 1&de0010 0010 0010&wt00 00 00&mv00000 00000 00000&mc00 00 00&mp000 000 000&" + "ms0010 0010 0010&mh0000 0000 0000&gi000 000 000&gj0gk0", + ) + ] ) - async def test_zero_volume_liquid_handling(self): - # just test that this does not throw an error - self.lh.update_head_state({0: self.tip_rack.get_tip("A1")}) - assert self.plate.lid is not None - self.plate.lid.unassign() - await self.lh.aspirate(self.plate["A1"], vols=[0]) - await self.lh.dispense(self.plate["A1"], vols=[0]) - async def test_core_96_tip_pickup(self): await self.lh.pick_up_tips96(self.tip_rack) - - self._assert_command_sent_once( - "C0EPid0208xs01179xd0yh2418tt01wu0za2164zh2450ze2450", - "xs#####xd#yh####tt##wu#za####zh####ze####", + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call("C0TTid0001tt01tf1tl0519tv03600tg2tu0"), + _any_write_and_read_command_call("C0EPid0002xs01179xd0yh2418tt01wu0za2164zh2450ze2450"), + ] ) async def test_core_96_tip_drop(self): await self.lh.pick_up_tips96(self.tip_rack) # pick up tips first + self.STAR._write_and_read_command.reset_mock() await self.lh.drop_tips96(self.tip_rack) - - self._assert_command_sent_once( - "C0ERid0213xs01179xd0yh2418za2164zh2450ze2450", "xs#####xd#yh####za####zh####ze####" + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call("C0ERid0003xs01179xd0yh2418za2164zh2450ze2450"), + ] ) async def test_core_96_tip_discard(self): await self.lh.pick_up_tips96(self.tip_rack) # pick up tips first + self.STAR._write_and_read_command.reset_mock() await self.lh.discard_tips96() - - self._assert_command_sent_once( - "C0ERid0213xs02321xd1yh1103za2164zh2450ze2450", "xs#####xd#yh####za####zh####ze####" + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call("C0ERid0003xs00420xd1yh1203za2164zh2450ze2450"), + ] ) async def test_core_96_aspirate(self): await self.lh.pick_up_tips96(self.tip_rack2) # pick up high volume tips + self.STAR._write_and_read_command.reset_mock() # TODO: Hamilton liquid classes assert self.plate.lid is not None self.plate.lid.unassign() - hlc = HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty - corrected_volume = hlc.compute_corrected_volume(100) - await self.lh.aspirate96(self.plate, volume=corrected_volume, **hlc.make_asp96_kwargs()) + await self.lh.aspirate96(self.plate, volume=100, blow_out=True) # volume used to be 01072, but that was generated using a non-core liquid class. - self._assert_command_sent_once( - "C0EAid0001aa0xs02983xd0yh1457zh2450ze2450lz1999zt1866zm1866iw000ix0fh000af01083ag2500vt050" - "bv00000wv00050cm0cs1bs0020wh10hv00000hc00hp000hs1200zv0032zq06180mj000cj0cx0cr000" - "cwFFFFFFFFFFFFFFFFFFFFFFFFpp0100", - "xs#####xd#yh####zh####ze####lz####zt####zm####iw###ix#fh###af#####ag####vt###" - "bv#####wv#####cm#cs#bs####wh##hv#####hc##hp###hs####zv####zq#####mj###cj#cx#cr###" - "cw************************pp####", + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0EAid0003aa0xs02983xd0yh1457zh2450ze2450lz1999zt1866pp0100zm1866zv0032zq06180iw000ix0fh000af01083ag2500vt050bv00000wv00050cm0cs1bs0020wh10hv00000hc00hp000mj000hs1200cwFFFFFFFFFFFFFFFFFFFFFFFFcr000cj0cx0" + ), + ] ) async def test_core_96_dispense(self): await self.lh.pick_up_tips96(self.tip_rack2) # pick up high volume tips if self.plate.lid is not None: self.plate.lid.unassign() - hlc = HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty - corrected_volume = hlc.compute_corrected_volume(100) - await self.lh.aspirate96(self.plate, corrected_volume, **hlc.make_asp96_kwargs()) + await self.lh.aspirate96(self.plate, 100, blow_out=True) # aspirate first + self.STAR._write_and_read_command.reset_mock() with no_volume_tracking(): - await self.lh.dispense96( - self.plate, corrected_volume, blow_out=True, **hlc.make_disp96_kwargs() - ) + await self.lh.dispense96(self.plate, 100, blow_out=True) - self._assert_command_sent_once( - "C0EDid0001da3xs02983xd0yh1457zh2450ze2450lz1999zt1866zm1866iw000ix0fh000df01083dg1200vt050" - "bv00000cm0cs1bs0020wh00hv00000hc00hp000hs1200es0050ev000zv0032ej00zq06180mj000cj0cx0cr000" - "cwFFFFFFFFFFFFFFFFFFFFFFFFpp0100", - "da#xs#####xd#yh##6#zh####ze####lz####zt####zm##6#iw###ix#fh###df#####dg####vt###" - "bv#####cm#cs#bs####wh##hv#####hc##hp###hs####es####ev###zv####ej##zq#6###mj###cj#cx#cr###" - "cw************************pp####", + # volume used to be 01072, but that was generated using a non-core liquid class. + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0EDid0004da3xs02983xd0yh1457zm1866zv0032zq06180lz1999zt1866pp0100iw000ix0fh000zh2450ze2450df01083dg1200es0050ev000vt050bv00000cm0cs1ej00bs0020wh00hv00000hc00hp000mj000hs1200cwFFFFFFFFFFFFFFFFFFFFFFFFcr000cj0cx0" + ), + ] ) async def test_zero_volume_liquid_handling96(self): @@ -703,21 +647,31 @@ async def test_zero_volume_liquid_handling96(self): await self.lh.dispense96(self.plate, 0) async def test_iswap(self): - await self.lh.move_plate(self.plate, self.plt_car[2], pickup_distance_from_top=13.2 - 3.33) - self._assert_command_sent_once( - "C0PPid0011xs03479xd0yj1142yd0zj1874zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", - "xs#####xd#yj####yd#zj####zd#gr#th####te####gw#go####gb####gt##ga#gc#", + await self.lh.move_plate( + self.plate, + self.plt_car[2], + pickup_distance_from_top=13.2 - 3.33, ) - self._assert_command_sent_once( - "C0PRid0012xs03479xd0yj3062yd0zj1874zd0th2450te2450gr1go1308ga0", - "xs#####xd#yj####yd#zj####zd#th####te####go####ga#", + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0PPid0001xs03479xd0yj1142yd0zj1874zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1", + ), + _any_write_and_read_command_call( + "C0PRid0002xs03479xd0yj3062yd0zj1874zd0th2840te2840gr1go1308ga0", + ), + ] ) async def test_iswap_plate_reader(self): plate_reader = PlateReader( - name="plate_reader", backend=MockPlateReaderBackend(), size_x=0, size_y=0, size_z=0 + name="plate_reader", + backend=PlateReaderChatterboxBackend(), + size_x=0, + size_y=0, + size_z=0, ) - self.lh.deck.assign_child_resource( + self.deck.assign_child_resource( plate_reader, location=Coordinate(1000, 264.7, 200 - 3.03) ) # 666: 00002 @@ -725,39 +679,20 @@ async def test_iswap_plate_reader(self): self.plate, plate_reader, pickup_distance_from_top=8.2 - 3.33, - get_direction=GripDirection.FRONT, - put_direction=GripDirection.LEFT, - ) - plate_origin_location = { - "xs": "03479", - "xd": "0", - "yj": "1142", - "yd": "0", - "zj": "1924", - "zd": "0", - } - plate_reader_location = { - "xs": "10427", - "xd": "0", - "yj": "3286", - "yd": "0", - "zj": "2063", - "zd": "0", - } - self._assert_command_sent_once( - f"C0PPid0003xs{plate_origin_location['xs']}xd{plate_origin_location['xd']}" - f"yj{plate_origin_location['yj']}yd{plate_origin_location['yd']}" - f"zj{plate_origin_location['zj']}zd{plate_origin_location['zd']}" - f"th2450te2450gw4gb1245go1308gt20gr1ga0gc1", - "xs#####xd#yj####yd#zj####zd#th####te####gw#gb####go####gt##gr#ga#gc#", - ) - self._assert_command_sent_once( - f"C0PRid0004xs{plate_reader_location['xs']}xd{plate_reader_location['xd']}" - f"yj{plate_reader_location['yj']}yd{plate_reader_location['yd']}" - f"zj{plate_reader_location['zj']}zd{plate_reader_location['zd']}" - f"th2450te2450go1308gr4ga0", - "xs#####xd#yj####yd#zj####zd#th####te####go####gr#ga#", + pickup_direction=GripDirection.FRONT, + drop_direction=GripDirection.LEFT, + ) + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0PPid0001xs03479xd0yj1142yd0zj1924zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1", + ), + _any_write_and_read_command_call( + "C0PRid0002xs10427xd0yj3286yd0zj2063zd0th2840te2840gr4go1308ga0", + ), + ] ) + self.STAR._write_and_read_command.reset_mock() assert self.plate.rotation.z == 270 self.assertAlmostEqual(self.plate.get_absolute_size_x(), 85.48, places=2) @@ -767,22 +702,18 @@ async def test_iswap_plate_reader(self): plate_reader.get_plate(), self.plt_car[0], pickup_distance_from_top=8.2 - 3.33, - get_direction=GripDirection.LEFT, - put_direction=GripDirection.FRONT, + pickup_direction=GripDirection.LEFT, + drop_direction=GripDirection.FRONT, ) - self._assert_command_sent_once( - f"C0PPid0005xs{plate_reader_location['xs']}xd{plate_reader_location['xd']}" - f"yj{plate_reader_location['yj']}yd{plate_reader_location['yd']}" - f"zj{plate_reader_location['zj']}zd{plate_reader_location['zd']}" - f"gr4th2450te2450gw4go1308gb1245gt20ga0gc1", - "xs#####xd#yj####yd#zj####zd#gr#th####te####gw#go####gb####gt##ga#gc#", - ) - self._assert_command_sent_once( - f"C0PRid0006xs{plate_origin_location['xs']}xd{plate_origin_location['xd']}" - f"yj{plate_origin_location['yj']}yd{plate_origin_location['yd']}" - f"zj{plate_origin_location['zj']}zd{plate_origin_location['zd']}" - f"th2450te2450gr1go1308ga0", - "xs#####xd#yj####yd#zj####zd#th####te####gr#go####ga#", + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0PPid0003xs10427xd0yj3286yd0zj2063zd0gr4th2840te2840gw4go1308gb1245gt20ga0gc1", + ), + _any_write_and_read_command_call( + "C0PRid0004xs03479xd0yj1142yd0zj1924zd0th2840te2840gr1go1308ga0", + ), + ] ) async def test_iswap_move_lid(self): @@ -790,91 +721,118 @@ async def test_iswap_move_lid(self): self.other_plate.lid.unassign() # remove lid from plate await self.lh.move_lid(self.plate.lid, self.other_plate) - self._assert_command_sent_once( - "C0PPid0002xs03479xd0yj1142yd0zj1950zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", - GET_PLATE_FMT, - ) - self._assert_command_sent_once( # zj sent = 1849 - "C0PRid0003xs03479xd0yj2102yd0zj1950zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0PPid0001xs03479xd0yj1142yd0zj1950zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1" + ), + _any_write_and_read_command_call( + "C0PRid0002xs03479xd0yj2102yd0zj1950zd0th2840te2840gr1go1308ga0" + ), + ] ) async def test_iswap_stacking_area(self): stacking_area = ResourceStack("stacking_area", direction="z") # for some reason it was like this at some point # self.lh.assign_resource(hotel, location=Coordinate(6, 414-63, 217.2 - 100)) - # self.lh.deck.assign_child_resource(hotel, location=Coordinate(6, 414-63, 231.7 - 100 +4.5)) - self.lh.deck.assign_child_resource(stacking_area, location=Coordinate(6, 414, 226.2 - 3.33)) + # f.lh.deck.assign_child_resource(hotel, location=Coordinate(6, 414-63, 231.7 - 100 +4.5)) + self.deck.assign_child_resource(stacking_area, location=Coordinate(6, 414, 226.2 - 3.33)) assert self.plate.lid is not None await self.lh.move_lid(self.plate.lid, stacking_area) - self._assert_command_sent_once( - "C0PPid0002xs03479xd0yj1142yd0zj1950zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", - GET_PLATE_FMT, - ) - self._assert_command_sent_once( - "C0PRid0003xs00699xd0yj4567yd0zj2305zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT - ) + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0PPid0001xs03479xd0yj1142yd0zj1950zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1" + ), + _any_write_and_read_command_call( + "C0PRid0002xs00699xd0yj4567yd0zj2305zd0th2840te2840gr1go1308ga0" + ), + ] + ) + self.STAR._write_and_read_command.reset_mock() # Move lids back (reverse order) await self.lh.move_lid(cast(Lid, stacking_area.get_top_item()), self.plate) - self._assert_command_sent_once( - "C0PPid0004xs00699xd0yj4567yd0zj2305zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", - GET_PLATE_FMT, - ) - self._assert_command_sent_once( - "C0PRid0005xs03479xd0yj1142yd0zj1950zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0PPid0003xs00699xd0yj4567yd0zj2305zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1" + ), + _any_write_and_read_command_call( + "C0PRid0004xs03479xd0yj1142yd0zj1950zd0th2840te2840gr1go1308ga0" + ), + ] ) async def test_iswap_stacking_area_2lids(self): # for some reason it was like this at some point # self.lh.assign_resource(hotel, location=Coordinate(6, 414-63, 217.2 - 100)) stacking_area = ResourceStack("stacking_area", direction="z") - self.lh.deck.assign_child_resource(stacking_area, location=Coordinate(6, 414, 226.2 - 3.33)) + self.deck.assign_child_resource(stacking_area, location=Coordinate(6, 414, 226.2 - 3.33)) assert self.plate.lid is not None and self.other_plate.lid is not None await self.lh.move_lid(self.plate.lid, stacking_area) - self._assert_command_sent_once( - "C0PPid0002xs03479xd0yj1142yd0zj1950zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", - GET_PLATE_FMT, - ) - self._assert_command_sent_once( - "C0PRid0003xs00699xd0yj4567yd0zj2305zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT - ) + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0PPid0001xs03479xd0yj1142yd0zj1950zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1" + ), + _any_write_and_read_command_call( + "C0PRid0002xs00699xd0yj4567yd0zj2305zd0th2840te2840gr1go1308ga0" + ), + ] + ) + self.STAR._write_and_read_command.reset_mock() await self.lh.move_lid(self.other_plate.lid, stacking_area) - self._assert_command_sent_once( - "C0PPid0004xs03479xd0yj2102yd0zj1950zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", - GET_PLATE_FMT, - ) - self._assert_command_sent_once( - "C0PRid0005xs00699xd0yj4567yd0zj2405zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT - ) + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0PPid0003xs03479xd0yj2102yd0zj1950zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1" + ), + _any_write_and_read_command_call( + "C0PRid0004xs00699xd0yj4567yd0zj2405zd0th2840te2840gr1go1308ga0" + ), + ] + ) + self.STAR._write_and_read_command.reset_mock() # Move lids back (reverse order) top_item = stacking_area.get_top_item() assert isinstance(top_item, Lid) await self.lh.move_lid(top_item, self.plate) - self._assert_command_sent_once( - "C0PPid0004xs00699xd0yj4567yd0zj2405zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", - GET_PLATE_FMT, - ) - self._assert_command_sent_once( - "C0PRid0005xs03479xd0yj1142yd0zj1950zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT - ) + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0PPid0005xs00699xd0yj4567yd0zj2405zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1" + ), + _any_write_and_read_command_call( + "C0PRid0006xs03479xd0yj1142yd0zj1950zd0th2840te2840gr1go1308ga0" + ), + ] + ) + self.STAR._write_and_read_command.reset_mock() top_item = stacking_area.get_top_item() assert isinstance(top_item, Lid) await self.lh.move_lid(top_item, self.other_plate) - self._assert_command_sent_once( - "C0PPid0004xs00699xd0yj4567yd0zj2305zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", - GET_PLATE_FMT, - ) - self._assert_command_sent_once( - "C0PRid0005xs03479xd0yj2102yd0zj1950zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT - ) + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0PPid0007xs00699xd0yj4567yd0zj2305zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1" + ), + _any_write_and_read_command_call( + "C0PRid0008xs03479xd0yj2102yd0zj1950zd0th2840te2840gr1go1308ga0" + ), + ] + ) + self.STAR._write_and_read_command.reset_mock() async def test_iswap_move_with_intermediate_locations(self): + self.plt_car[1].resource.unassign() await self.lh.move_plate( self.plate, self.plt_car[1], @@ -884,55 +842,60 @@ async def test_iswap_move_with_intermediate_locations(self): ], ) - self._assert_command_sent_once( - "C0PPid0023xs03479xd0yj1142yd0zj1874zd0gr1th2450te2450gw4go1308gb1245gt20ga0gc1", - GET_PLATE_FMT, - ) - self._assert_command_sent_once( - "C0PMid0024xs02979xd0yj4022yd0zj2432zd0gr1th2450ga1xe4 1", INTERMEDIATE_FMT - ) - self._assert_command_sent_once( - "C0PMid0025xs03979xd0yj3062yd0zj2432zd0gr1th2450ga1xe4 1", INTERMEDIATE_FMT - ) - self._assert_command_sent_once( - "C0PRid0026xs03479xd0yj2102yd0zj1874zd0th2450te2450gr1go1308ga0", PUT_PLATE_FMT + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0PPid0001xs03479xd0yj1142yd0zj1874zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1" + ), + _any_write_and_read_command_call("C0PMid0002xs03979xd0yj3062yd0zj2432zd0gr1th2840ga1xe4 1"), + _any_write_and_read_command_call("C0PMid0003xs02979xd0yj4022yd0zj2432zd0gr1th2840ga1xe4 1"), + _any_write_and_read_command_call( + "C0PRid0004xs03479xd0yj2102yd0zj1874zd0th2840te2840gr1go1308ga0" + ), + ] ) async def test_discard_tips(self): await self.lh.pick_up_tips(self.tip_rack["A1:H1"]) + # {"id": 2, "kz": [000, 000, 000, 000, 000, 000, 000, 000], "vz": [000, 000, 000, 000, 000, 000, 000, 000]} + self.STAR._write_and_read_command.side_effect = [ + "C0TRid0003kz000 000 000 000 000 000 000 000vz000 000 000 000 000 000 000 000" + ] + self.STAR._write_and_read_command.reset_mock() await self.lh.discard_tips() - self._assert_command_sent_once( - "C0TRid0206xp08000 08000 08000 08000 08000 08000 08000 08000yp4050 3782 3514 3246 2978 2710 " - "2442 2174tp1970tz1870th2450te2450tm1 1 1 1 1 1 1 1ti0", - DROP_TIP_FORMAT, + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0TRid0003xp08000 08000 08000 08000 08000 08000 08000 08000yp3427 3337 3247 3157 3067 2977 2887 2797tm1 1 1 1 1 1 1 1tp1970tz1870th2450te2450ti0", + ) + ] ) async def test_portrait_tip_rack_handling(self): - # Test with an alternative setup. - deck = STARLetDeck() - lh = LiquidHandler(self.mockSTAR, deck=deck) + lh = LiquidHandler(self.STAR, deck=deck) tip_car = TIP_CAR_288_C00(name="tip carrier") - tip_car[0] = tr = HT_P(name="tips_01") + tip_car[0] = tr = HT(name="tips_01").rotated(z=90) assert tr.rotation.z == 90 assert tr.location == Coordinate(82.6, 0, 0) deck.assign_child_resource(tip_car, rails=2) await lh.setup() await lh.pick_up_tips(tr["A4:A1"]) - - self._assert_command_sent_once( - "C0TPid0035xp01360 01360 01360 01360 00000&yp1380 1290 1200 1110 0000&tm1 1 1 1 0&tt01tp2263tz" - "2163th2450td0", - PICKUP_TIP_FORMAT, - ) - + self.STAR._write_and_read_command.side_effect = [ + "C0TRid0002kz000 000 000 000 000 000 000 000vz000 000 000 000 000 000 000 000" + ] await lh.drop_tips(tr["A4:A1"]) - self._assert_command_sent_once( - "C0TRid0036xp01360 01360 01360 01360 00000&yp1380 1290 1200 1110 0000&tm1 1 1 1 0&tp2263tz" - "2183th2450ti1", - DROP_TIP_FORMAT, + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0TPid0002xp01360 01360 01360 01360 00000&yp1380 1290 1200 1110 0000&tm1 1 1 1 0&tt01tp2263tz2163th2450td0" + ), + _any_write_and_read_command_call( + "C0TRid0003xp01360 01360 01360 01360 00000&yp1380 1290 1200 1110 0000&tm1 1 1 1 0&tp2263tz2183th2450te2450ti1" + ), + ] ) def test_serialize(self): @@ -942,64 +905,362 @@ def test_serialize(self): self.assertEqual(deserialized.backend.__class__.__name__, "STAR") async def test_move_core(self): + self.plt_car[1].resource.unassign() await self.lh.move_plate( - self.plate, self.plt_car[1], pickup_distance_from_top=13 - 3.33, use_arm="core" - ) - self._assert_command_sent_once( - "C0ZTid0020xs07975xd0ya1240yb1065pa07pb08tp2350tz2250th2450tt14", - "xs#####xd#ya####yb####pa##pb##tp####tz####th####tt##", - ) - self._assert_command_sent_once( - "C0ZPid0021xs03479xd0yj1142yv0050zj1876zy0500yo0885yg0825yw15" "th2450te2450", - "xs#####xd#yj####yv####zj####zy####yo####yg####yw##th####te####", - ) - self._assert_command_sent_once( - "C0ZRid0022xs03479xd0yj2102zj1876zi000zy0500yo0885th2450te2450", - "xs#####xd#yj####zj####zi###zy####yo####th####te####", - ) - self._assert_command_sent_once( - "C0ZSid0023xs07975xd0ya1240yb1065tp2150tz2050th2450te2450", - "xs#####xd#ya####yb####tp####tz####th####te####", - ) - - async def test_iswap_pick_up_resource_grip_direction_changes_plate_width(self): - size_x = 100 - size_y = 200 - plate = Plate("dummy", size_x=size_x, size_y=size_y, size_z=100, ordered_items={}) - plate.location = Coordinate.zero() - - with unittest.mock.patch.object(self.lh.backend, "iswap_get_plate") as mocked_iswap_get_plate: - await cast(STAR, self.lh.backend).iswap_pick_up_resource(plate, GripDirection.FRONT, 1) - assert mocked_iswap_get_plate.call_args.kwargs["plate_width"] == size_x * 10 - 33 - - with unittest.mock.patch.object(self.lh.backend, "iswap_get_plate") as mocked_iswap_get_plate: - await cast(STAR, self.lh.backend).iswap_pick_up_resource(plate, GripDirection.LEFT, 1) - assert mocked_iswap_get_plate.call_args.kwargs["plate_width"] == size_y * 10 - 33 - - async def test_iswap_release_picked_up_resource_grip_direction_changes_plate_width(self): - size_x = 100 - size_y = 200 - plate = Plate("dummy", size_x=size_x, size_y=size_y, size_z=100, ordered_items={}) - plate.location = Coordinate.zero() - - with unittest.mock.patch.object(self.lh.backend, "iswap_put_plate") as mocked_iswap_get_plate: - await cast(STAR, self.lh.backend).iswap_release_picked_up_resource( - location=Coordinate.zero(), - resource=plate, - rotation=0, - offset=Coordinate.zero(), - grip_direction=GripDirection.FRONT, - pickup_distance_from_top=1, - ) - assert mocked_iswap_get_plate.call_args.kwargs["open_gripper_position"] == size_x * 10 + 30 - - with unittest.mock.patch.object(self.lh.backend, "iswap_put_plate") as mocked_iswap_get_plate: - await cast(STAR, self.lh.backend).iswap_release_picked_up_resource( - location=Coordinate.zero(), - resource=plate, - rotation=0, - offset=Coordinate.zero(), - grip_direction=GripDirection.LEFT, - pickup_distance_from_top=1, - ) - assert mocked_iswap_get_plate.call_args.kwargs["open_gripper_position"] == size_y * 10 + 30 + self.plate, + self.plt_car[1], + pickup_distance_from_top=13 - 3.33, + use_arm="core", + # kwargs specific to pickup and drop + channel_1=7, + channel_2=8, + return_core_gripper=True, + ) + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0ZTid0001xs07975xd0ya1240yb1065pa07pb08tp2350tz2250th2840tt14" + ), + _any_write_and_read_command_call( + "C0ZPid0002xs03479xd0yj1142yv0050zj1876zy0500yo0885yg0825yw15" "th2840te2840" + ), + _any_write_and_read_command_call( + "C0ZRid0003xs03479xd0yj2102zj1876zi000zy0500yo0885th2840te2840" + ), + _any_write_and_read_command_call( + "C0ZSid0004xs07975xd0ya1240yb1065tp2150tz2050th2840te2840" + ), + ] + ) + + +class STARIswapMovementTests(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self): + self.STAR = STAR() + self.STAR._write_and_read_command = unittest.mock.AsyncMock() + self.deck = STARLetDeck() + self.lh = LiquidHandler(self.STAR, deck=self.deck) + + self.plt_car = PLT_CAR_L5MD_A00(name="plt_car") + self.plt_car[0] = self.plate = CellTreat_96_wellplate_350ul_Ub(name="plate", with_lid=True) + self.deck.assign_child_resource(self.plt_car, rails=15) + + self.plt_car2 = PLT_CAR_P3AC_A01(name="plt_car2") + self.deck.assign_child_resource(self.plt_car2, rails=3) + + self.STAR._num_channels = 8 + self.STAR.core96_head_installed = True + self.STAR.iswap_installed = True + self.STAR.setup = unittest.mock.AsyncMock() + self.STAR._core_parked = True + self.STAR._iswap_parked = True + await self.lh.setup() + + async def test_simple_movement(self): + await self.lh.move_plate(self.plate, self.plt_car[1]) + await self.lh.move_plate(self.plate, self.plt_car[0]) + + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0PPid0001xs04829xd0yj1141yd0zj2143zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1", + ), + _any_write_and_read_command_call( + "C0PRid0002xs04829xd0yj2101yd0zj2143zd0th2840te2840gr1go1308ga0", + ), + _any_write_and_read_command_call( + "C0PPid0003xs04829xd0yj2101yd0zj2143zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1", + ), + _any_write_and_read_command_call( + "C0PRid0004xs04829xd0yj1141yd0zj2143zd0th2840te2840gr1go1308ga0" + ), + ] + ) + + async def test_movement_to_portrait_site_left(self): + await self.lh.move_plate(self.plate, self.plt_car2[0], drop_direction=GripDirection.LEFT) + await self.lh.move_plate(self.plate, self.plt_car[0], drop_direction=GripDirection.LEFT) + + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0PPid0001xs04829xd0yj1141yd0zj2143zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1", + ), + _any_write_and_read_command_call( + "C0PRid0002xs02317xd0yj1644yd0zj1884zd0th2840te2840gr4go1308ga0", + ), + _any_write_and_read_command_call( + "C0PPid0003xs02317xd0yj1644yd0zj1884zd0gr1th2840te2840gw4go0881gb0818gt20ga0gc1", + ), + _any_write_and_read_command_call( + "C0PRid0004xs04829xd0yj1141yd0zj2143zd0th2840te2840gr4go0881ga0", + ), + ] + ) + + async def test_movement_to_portrait_site_right(self): + await self.lh.move_plate(self.plate, self.plt_car2[0], drop_direction=GripDirection.RIGHT) + await self.lh.move_plate(self.plate, self.plt_car[0], drop_direction=GripDirection.RIGHT) + + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0PPid0001xs04829xd0yj1141yd0zj2143zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1", + ), + _any_write_and_read_command_call( + "C0PRid0002xs02317xd0yj1644yd0zj1884zd0th2840te2840gr2go1308ga0", + ), + _any_write_and_read_command_call( + "C0PPid0003xs02317xd0yj1644yd0zj1884zd0gr1th2840te2840gw4go0881gb0818gt20ga0gc1", + ), + _any_write_and_read_command_call( + "C0PRid0004xs04829xd0yj1141yd0zj2143zd0th2840te2840gr2go0881ga0", + ), + ] + ) + + async def test_move_lid_across_rotated_resources(self): + self.plt_car2[0] = plate2 = CellTreat_96_wellplate_350ul_Ub( + name="plate2", with_lid=False + ).rotated(z=270) + self.plt_car2[1] = plate3 = CellTreat_96_wellplate_350ul_Ub( + name="plate3", with_lid=False + ).rotated(z=90) + + assert plate2.get_absolute_location() == Coordinate(x=189.1, y=228.26, z=183.98) + assert plate3.get_absolute_location() == Coordinate(x=274.21, y=246.5, z=183.98) + + assert self.plate.lid is not None + await self.lh.move_lid(self.plate.lid, plate2, drop_direction=GripDirection.LEFT) + assert plate2.lid is not None + await self.lh.move_lid(plate2.lid, plate3, drop_direction=GripDirection.BACK) + assert plate3.lid is not None + await self.lh.move_lid(plate3.lid, self.plate, drop_direction=GripDirection.LEFT) + + self.STAR._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call( + "C0PPid0001xs04829xd0yj1142yd0zj2242zd0gr1th2840te2840gw4go1308gb1245gt20ga0gc1", + ), + _any_write_and_read_command_call( + "C0PRid0002xs02318xd0yj1644yd0zj1983zd0th2840te2840gr4go1308ga0", + ), + _any_write_and_read_command_call( + "C0PPid0003xs02318xd0yj1644yd0zj1983zd0gr1th2840te2840gw4go0885gb0822gt20ga0gc1", + ), + _any_write_and_read_command_call( + "C0PRid0004xs02315xd0yj3104yd0zj1983zd0th2840te2840gr3go0885ga0", + ), + _any_write_and_read_command_call( + "C0PPid0005xs02315xd0yj3104yd0zj1983zd0gr1th2840te2840gw4go0885gb0822gt20ga0gc1", + ), + _any_write_and_read_command_call( + "C0PRid0006xs04829xd0yj1142yd0zj2242zd0th2840te2840gr4go0885ga0", + ), + ] + ) + + +class STARFoilTests(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self): + self.star = STAR() + self.star._write_and_read_command = unittest.mock.AsyncMock() + self.deck = STARLetDeck() + self.lh = LiquidHandler(backend=self.star, deck=self.deck) + + tip_carrier = TIP_CAR_480_A00(name="tip_carrier") + tip_carrier[1] = self.tip_rack = HT(name="tip_rack") + self.deck.assign_child_resource(tip_carrier, rails=1) + + plt_carrier = PLT_CAR_L5AC_A00(name="plt_carrier") + plt_carrier[0] = self.plate = AGenBio_1_troughplate_190000uL_Fl(name="plate") + self.well = self.plate.get_well("A1") + self.deck.assign_child_resource(plt_carrier, rails=10) + + self.star._num_channels = 8 + self.star.core96_head_installed = True + self.star.iswap_installed = True + self.star.setup = unittest.mock.AsyncMock() + self.star._core_parked = True + self.star._iswap_parked = True + await self.lh.setup() + + await self.lh.pick_up_tips(self.tip_rack["A1:H1"]) + + async def test_pierce_foil_wide(self): + aspiration_channels = [1, 2, 3, 4, 5, 6] + hold_down_channels = [0, 7] + self.star._write_and_read_command.side_effect = [ + "C0JXid0051er00/00", + "C0RYid0052er00/00ry+1530 +1399 +1297 +1196 +1095 +0994 +0892 +0755", + "C0JYid0053er00/00", + "C0RZid0054er00/00rz+2476 +2476 +2476 +2476 +2476 +2476 +2476 +2476", + "C0JZid0055er00/00", + "C0RYid0056er00/00ry+1530 +1399 +1297 +1196 +1095 +0994 +0892 +0755", + "C0JYid0057er00/00", + "C0KZid0058er00/00", + "C0KZid0059er00/00", + "C0RZid0060er00/00rz+2256 +2083 +2083 +2083 +2083 +2083 +2083 +2256", + "C0RZid0061er00/00rz+2256 +2083 +2083 +2083 +2083 +2083 +2083 +2256", + "C0JZid0062er00/00", + "C0ZAid0063er00/00", + ] + await self.star.pierce_foil( + wells=[self.well], + piercing_channels=aspiration_channels, + hold_down_channels=hold_down_channels, + move_inwards=4, + one_by_one=False, + spread="wide", + ) + self.star._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call("C0JXid0003xs03702"), + _any_write_and_read_command_call("C0RYid0004"), + _any_write_and_read_command_call("C0JYid0005yp1530 1399 1297 1196 1095 0994 0892 0755"), + _any_write_and_read_command_call("C0RZid0006"), + _any_write_and_read_command_call("C0JZid0007zp2476 2083 2083 2083 2083 2083 2083 2476"), + _any_write_and_read_command_call("C0RYid0008"), + _any_write_and_read_command_call("C0JYid0009yp1530 1399 1297 1196 1095 0994 0892 0755"), + _any_write_and_read_command_call("C0KZid0010pn08zj2256"), + _any_write_and_read_command_call("C0KZid0011pn01zj2256"), + _any_write_and_read_command_call("C0RZid0012"), + _any_write_and_read_command_call("C0RZid0013"), + _any_write_and_read_command_call("C0JZid0014zp2256 2406 2406 2406 2406 2406 2406 2256"), + _any_write_and_read_command_call("C0ZAid0015"), + ] + ) + + async def test_pierce_foil_tight(self): + aspiration_channels = [1, 2, 3, 4, 5, 6] + hold_down_channels = [0, 7] + self.star._write_and_read_command.side_effect = [ + "C0JXid0064er00/00", + "C0RYid0065er00/00ry+1530 +1399 +1297 +1196 +1095 +0994 +0892 +0755", + "C0JYid0066er00/00", + "C0RZid0067er00/00rz+2476 +2476 +2476 +2476 +2476 +2476 +2476 +2476", + "C0JZid0068er00/00", + "C0RYid0069er00/00ry+1530 +1370 +1280 +1190 +1100 +1010 +0920 +0755", + "C0JYid0070er00/00", + "C0KZid0071er00/00", + "C0KZid0072er00/00", + "C0RZid0073er00/00rz+2256 +2083 +2083 +2083 +2083 +2083 +2083 +2256", + "C0RZid0074er00/00rz+2256 +2083 +2083 +2083 +2083 +2083 +2083 +2256", + "C0JZid0075er00/00", + "C0ZAid0076er00/00", + ] + await self.star.pierce_foil( + wells=[self.well], + piercing_channels=aspiration_channels, + hold_down_channels=hold_down_channels, + move_inwards=4, + one_by_one=False, + spread="tight", + ) + self.star._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call("C0JXid0003xs03702"), + _any_write_and_read_command_call("C0RYid0004"), + _any_write_and_read_command_call("C0JYid0005yp1530 1370 1280 1190 1100 1010 0920 0755"), + _any_write_and_read_command_call("C0RZid0006"), + _any_write_and_read_command_call("C0JZid0007zp2476 2083 2083 2083 2083 2083 2083 2476"), + _any_write_and_read_command_call("C0RYid0008"), + _any_write_and_read_command_call("C0JYid0009yp1530 1370 1280 1190 1100 1010 0920 0755"), + _any_write_and_read_command_call("C0KZid0010pn08zj2256"), + _any_write_and_read_command_call("C0KZid0011pn01zj2256"), + _any_write_and_read_command_call("C0RZid0012"), + _any_write_and_read_command_call("C0RZid0013"), + _any_write_and_read_command_call("C0JZid0014zp2256 2406 2406 2406 2406 2406 2406 2256"), + _any_write_and_read_command_call("C0ZAid0015"), + ] + ) + + async def test_pierce_foil_portrait_wide(self): + self.plate.rotate(z=90) + aspiration_channels = [1, 2, 3, 4, 5, 6] + hold_down_channels = [0, 7] + self.star._write_and_read_command.side_effect = [ + "C0JXid0170er00/00", + "C0RYid0171er00/00ry+1530 +1399 +1297 +1196 +1095 +0994 +0892 +0755", + "C0JYid0172er00/00", + "C0RZid0173er00/00rz+2476 +2476 +2476 +2476 +2476 +2476 +2476 +2476", + "C0JZid0174er00/00", + "C0RYid0175er00/00ry+1825 +1735 +1582 +1429 +1275 +1122 +0969 +0755", + "C0JYid0176er00/00", + "C0KZid0177er00/00", + "C0KZid0178er00/00", + "C0RZid0179er00/00rz+2256 +2083 +2083 +2083 +2083 +2083 +2083 +2256", + "C0RZid0180er00/00rz+2256 +2083 +2083 +2083 +2083 +2083 +2083 +2256", + "C0JZid0181er00/00", + "C0ZAid0182er00/00", + ] + await self.star.pierce_foil( + wells=[self.well], + piercing_channels=aspiration_channels, + hold_down_channels=hold_down_channels, + move_inwards=4, + one_by_one=False, + spread="tight", + ) + self.star._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call("C0JXid0003xs02634"), + _any_write_and_read_command_call("C0RYid0004"), + _any_write_and_read_command_call("C0JYid0005yp1667 1577 1487 1397 1307 1217 1127 0755"), + _any_write_and_read_command_call("C0RZid0006"), + _any_write_and_read_command_call("C0JZid0007zp2476 2083 2083 2083 2083 2083 2083 2476"), + _any_write_and_read_command_call("C0RYid0008"), + _any_write_and_read_command_call("C0JYid0009yp1953 1735 1582 1429 1275 1122 0969 0755"), + _any_write_and_read_command_call("C0KZid0010pn08zj2256"), + _any_write_and_read_command_call("C0KZid0011pn01zj2256"), + _any_write_and_read_command_call("C0RZid0012"), + _any_write_and_read_command_call("C0RZid0013"), + _any_write_and_read_command_call("C0JZid0014zp2256 2406 2406 2406 2406 2406 2406 2256"), + _any_write_and_read_command_call("C0ZAid0015"), + ] + ) + + async def test_pierce_foil_portrait_tight(self): + self.plate.rotate(z=90) + aspiration_channels = [1, 2, 3, 4, 5, 6] + hold_down_channels = [0, 7] + self.star._write_and_read_command.side_effect = [ + "C0JXid0183er00/00", + "C0RYid0184er00/00ry+1953 +1735 +1582 +1429 +1275 +1122 +0969 +0755", + "C0JYid0185er00/00", + "C0RZid0186er00/00rz+2476 +2476 +2476 +2476 +2476 +2476 +2476 +2476", + "C0JZid0187er00/00", + "C0RYid0188er00/00ry+1953 +1577 +1487 +1397 +1307 +1217 +1127 +0755", + "C0JYid0189er00/00", + "C0KZid0190er00/00", + "C0KZid0191er00/00", + "C0RZid0192er00/00rz+2256 +2083 +2083 +2083 +2083 +2083 +2083 +2256", + "C0RZid0193er00/00rz+2256 +2083 +2083 +2083 +2083 +2083 +2083 +2256", + "C0JZid0194er00/00", + "C0ZAid0195er00/00", + ] + await self.star.pierce_foil( + wells=[self.well], + piercing_channels=aspiration_channels, + hold_down_channels=hold_down_channels, + move_inwards=4, + one_by_one=False, + spread="tight", + ) + self.star._write_and_read_command.assert_has_calls( + [ + _any_write_and_read_command_call("C0JXid0003xs02634"), + _any_write_and_read_command_call("C0RYid0004"), + _any_write_and_read_command_call("C0JYid0005yp1953 1577 1487 1397 1307 1217 1127 0755"), + _any_write_and_read_command_call("C0RZid0006"), + _any_write_and_read_command_call("C0JZid0007zp2476 2083 2083 2083 2083 2083 2083 2476"), + _any_write_and_read_command_call("C0RYid0008"), + _any_write_and_read_command_call("C0JYid0009yp1953 1577 1487 1397 1307 1217 1127 0755"), + _any_write_and_read_command_call("C0KZid0010pn08zj2256"), + _any_write_and_read_command_call("C0KZid0011pn01zj2256"), + _any_write_and_read_command_call("C0RZid0012"), + _any_write_and_read_command_call("C0RZid0013"), + _any_write_and_read_command_call("C0JZid0014zp2256 2406 2406 2406 2406 2406 2406 2256"), + _any_write_and_read_command_call("C0ZAid0015"), + ] + ) diff --git a/pylabrobot/liquid_handling/backends/hamilton/vantage.py b/pylabrobot/liquid_handling/backends/hamilton/vantage.py index 4b0cf7127a..901c3214f3 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/vantage.py +++ b/pylabrobot/liquid_handling/backends/hamilton/vantage.py @@ -1,28 +1,43 @@ -# pylint: disable=invalid-name - import asyncio import random import re import sys from typing import Dict, List, Optional, Sequence, Union, cast -from pylabrobot.liquid_handling.backends.hamilton.base import HamiltonLiquidHandler -from pylabrobot.liquid_handling.liquid_classes.hamilton import HamiltonLiquidClass +from pylabrobot.liquid_handling.backends.hamilton.base import ( + HamiltonLiquidHandler, +) +from pylabrobot.liquid_handling.liquid_classes.hamilton import ( + HamiltonLiquidClass, + get_vantage_liquid_class, +) from pylabrobot.liquid_handling.standard import ( - Aspiration, - AspirationContainer, - AspirationPlate, - Dispense, - DispenseContainer, - DispensePlate, Drop, DropTipRack, - Move, + MultiHeadAspirationContainer, + MultiHeadAspirationPlate, + MultiHeadDispenseContainer, + MultiHeadDispensePlate, Pickup, PickupTipRack, + ResourceDrop, + ResourceMove, + ResourcePickup, + SingleChannelAspiration, + SingleChannelDispense, +) +from pylabrobot.resources import ( + Coordinate, + Liquid, + Resource, + TipRack, + Well, +) +from pylabrobot.resources.hamilton import ( + HamiltonTip, + TipPickupMethod, + TipSize, ) -from pylabrobot.resources import Coordinate, Resource, TipRack, Well -from pylabrobot.resources.ml_star import HamiltonTip, TipPickupMethod, TipSize if sys.version_info >= (3, 8): from typing import Literal @@ -266,7 +281,9 @@ def __eq__(self, __value: object) -> bool: ) -def vantage_response_string_to_error(string: str) -> VantageFirmwareError: +def vantage_response_string_to_error( + string: str, +) -> VantageFirmwareError: """Convert a Vantage firmware response string to a VantageFirmwareError. Assumes that the response is an error response.""" @@ -372,7 +389,7 @@ def get_id_from_fw_response(self, resp: str) -> Optional[int]: def check_fw_string_error(self, resp: str): """Raise an error if the firmware response is an error response.""" - if "er" in resp and not "er0" in resp: + if "er" in resp and "er0" not in resp: error = vantage_response_string_to_error(resp) raise error @@ -380,11 +397,13 @@ def _parse_response(self, resp: str, fmt: Dict[str, str]) -> dict: """Parse a firmware response.""" return parse_vantage_fw_string(resp, fmt) - async def setup(self): - """setup - - Creates a USB connection and finds read/write interfaces. - """ + async def setup( + self, + skip_loading_cover: bool = False, + skip_core96: bool = False, + skip_ipg: bool = False, + ): + """Creates a USB connection and finds read/write interfaces.""" await super().setup() @@ -411,11 +430,11 @@ async def setup(self): ) loading_cover_initialized = await self.loading_cover_request_initialization_status() - if not loading_cover_initialized: + if not loading_cover_initialized and not skip_loading_cover: await self.loading_cover_initialize() core96_initialized = await self.core96_request_initialization_status() - if not core96_initialized: + if not core96_initialized and not skip_core96: await self.core96_initialize( x_position=7347, # TODO: get trash location from deck. y_position=2684, # TODO: get trash location from deck. @@ -424,11 +443,12 @@ async def setup(self): end_z_deposit_position=2420, ) - ipg_initialized = await self.ipg_request_initialization_status() - if not ipg_initialized: - await self.ipg_initialize() - if not await self.ipg_get_parking_status(): - await self.ipg_park() + if not skip_ipg: + ipg_initialized = await self.ipg_request_initialization_status() + if not ipg_initialized: + await self.ipg_initialize() + if not await self.ipg_get_parking_status(): + await self.ipg_park() @property def num_channels(self) -> int: @@ -545,8 +565,10 @@ def _assert_valid_resources(self, resources: Sequence[Resource]) -> None: async def aspirate( self, - ops: List[Aspiration], + ops: List[SingleChannelAspiration], use_channels: List[int], + jet: Optional[List[bool]] = None, + blow_out: Optional[List[bool]] = None, hlcs: Optional[List[Optional[HamiltonLiquidClass]]] = None, type_of_aspiration: Optional[List[int]] = None, minimal_traverse_height_at_begin_of_command: Optional[List[float]] = None, @@ -593,15 +615,44 @@ async def aspirate( blow_out: Whether to search for a "blow out" liquid class. This is only used on dispense. Note that in the VENUS liquid editor, the term "empty" is used for this, but in the firmware documentation, "empty" is used for a different mode (dm4). + hlcs: The Hamiltonian liquid classes to use. If `None`, the liquid classes will be + determined automatically based on the tip and liquid used. """ - if hlcs is not None: - raise NotImplementedError("hlcs is deprecated") - x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) + if jet is None: + jet = [False] * len(ops) + if blow_out is None: + blow_out = [False] * len(ops) + + if hlcs is None: + hlcs = [] + for j, bo, op in zip(jet, blow_out, ops): + liquid = Liquid.WATER # default to WATER + # [-1][0]: get last liquid in well, [0] is indexing into the tuple + if len(op.liquids) > 0 and op.liquids[-1][0] is not None: + liquid = op.liquids[-1][0] + hlcs.append( + get_vantage_liquid_class( + tip_volume=op.tip.maximal_volume, + is_core=False, + is_tip=True, + has_filter=op.tip.has_filter, + liquid=liquid, + jet=j, + blow_out=bo, + ) + ) + self._assert_valid_resources([op.resource for op in ops]) + # correct volumes using the liquid class + volumes = [ + hlc.compute_corrected_volume(op.volume) if hlc is not None else op.volume + for op, hlc in zip(ops, hlcs) + ] + well_bottoms = [ op.resource.get_absolute_location().z + op.offset.z + op.resource.material_z_thickness for op in ops @@ -617,10 +668,14 @@ async def aspirate( for wb, op in zip(well_bottoms, ops) ] - flow_rates = [op.flow_rate or 100 for op in ops] - blow_out_air_volumes = [op.blow_out_air_volume or 0 for op in ops] - - print(mix_speed) + flow_rates = [ + op.flow_rate or (hlc.aspiration_flow_rate if hlc is not None else 100) + for op, hlc in zip(ops, hlcs) + ] + blow_out_air_volumes = [ + (op.blow_out_air_volume or (hlc.dispense_blow_out_volume if hlc is not None else 0)) + for op, hlc in zip(ops, hlcs) + ] return await self.pip_aspirate( x_position=x_positions, @@ -655,9 +710,13 @@ async def aspirate( surface_following_distance=[ round(sfd * 10) for sfd in surface_following_distance or [0] * len(ops) ], - aspiration_volume=[round(op.volume * 100) for op in ops], + aspiration_volume=[round(vol * 100) for vol in volumes], aspiration_speed=[round(fr * 10) for fr in flow_rates], - transport_air_volume=[round(tav * 10) for tav in transport_air_volume or [0] * len(ops)], + transport_air_volume=[ + round(tav * 10) + for tav in transport_air_volume + or [hlc.aspiration_air_transport_volume if hlc is not None else 0 for hlc in hlcs] + ], blow_out_air_volume=[round(bav * 100) for bav in blow_out_air_volumes], pre_wetting_volume=[round(pwv * 100) for pwv in pre_wetting_volume or [0] * len(ops)], lld_mode=lld_mode or [0] * len(ops), @@ -687,7 +746,7 @@ async def aspirate( async def dispense( self, - ops: List[Dispense], + ops: List[SingleChannelDispense], use_channels: List[int], jet: Optional[List[bool]] = None, blow_out: Optional[List[bool]] = None, # "empty" in the VENUS liquid editor @@ -733,6 +792,8 @@ async def dispense( Args: ops: The aspiration operations. use_channels: The channels to use. + hlcs: The Hamiltonian liquid classes to use. If `None`, the liquid classes will be + determined automatically based on the tip and liquid used. jet: Whether to use jetting for each dispense. Defaults to `False` for all. Used for determining the dispense mode. True for dispense mode 0 or 1. @@ -744,9 +805,6 @@ async def dispense( documentation. Dispense mode 4. """ - if hlcs is not None: - raise NotImplementedError("hlcs is deprecated") - x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) if jet is None: @@ -756,8 +814,33 @@ async def dispense( if blow_out is None: blow_out = [False] * len(ops) + if hlcs is None: + hlcs = [] + for j, bo, op in zip(jet, blow_out, ops): + liquid = Liquid.WATER # default to WATER + # [-1][0]: get last liquid in tip, [0] is indexing into the tuple + if len(op.liquids) > 0 and op.liquids[-1][0] is not None: + liquid = op.liquids[-1][0] + hlcs.append( + get_vantage_liquid_class( + tip_volume=op.tip.maximal_volume, + is_core=False, + is_tip=True, + has_filter=op.tip.has_filter, + liquid=liquid, + jet=j, + blow_out=bo, + ) + ) + self._assert_valid_resources([op.resource for op in ops]) + # correct volumes using the liquid class + volumes = [ + hlc.compute_corrected_volume(op.volume) if hlc is not None else op.volume + for op, hlc in zip(ops, hlcs) + ] + well_bottoms = [ op.resource.get_absolute_location().z + op.offset.z + op.resource.material_z_thickness for op in ops @@ -771,9 +854,15 @@ async def dispense( for wb, op in zip(well_bottoms, ops) ] - flow_rates = [op.flow_rate or 100 for op in ops] + flow_rates = [ + op.flow_rate or (hlc.dispense_flow_rate if hlc is not None else 100) + for op, hlc in zip(ops, hlcs) + ] - blow_out_air_volumes = [op.blow_out_air_volume or 0 for op in ops] + blow_out_air_volumes = [ + (op.blow_out_air_volume or (hlc.dispense_blow_out_volume if hlc is not None else 0)) + for op, hlc in zip(ops, hlcs) + ] type_of_dispensing_mode = type_of_dispensing_mode or [ _get_dispense_mode(jet=jet[i], empty=empty[i], blow_out=blow_out[i]) for i in range(len(ops)) @@ -811,11 +900,15 @@ async def dispense( round(mh * 10) for mh in minimal_height_at_command_end or [self._traversal_height] * len(ops) ], - dispense_volume=[round(op.volume * 100) for op in ops], + dispense_volume=[round(vol * 100) for vol in volumes], dispense_speed=[round(fr * 10) for fr in flow_rates], cut_off_speed=[round(cs * 10) for cs in cut_off_speed or [250] * len(ops)], stop_back_volume=[round(sbv * 100) for sbv in stop_back_volume or [0] * len(ops)], - transport_air_volume=[round(tav * 10) for tav in transport_air_volume or [0] * len(ops)], + transport_air_volume=[ + round(tav * 10) + for tav in transport_air_volume + or [hlc.dispense_air_transport_volume if hlc is not None else 0 for hlc in hlcs] + ], blow_out_air_volume=[round(boav * 100) for boav in blow_out_air_volumes], lld_mode=lld_mode or [0] * len(ops), side_touch_off_distance=round(side_touch_off_distance * 10), @@ -884,7 +977,8 @@ async def drop_tips96( position = tip_spot_a1.get_absolute_location() + tip_spot_a1.center() + drop.offset else: raise NotImplementedError( - "Only TipRacks are supported for dropping tips on Vantage", f"got {drop.resource}" + "Only TipRacks are supported for dropping tips on Vantage", + f"got {drop.resource}", ) offset_z = drop.offset.z @@ -902,7 +996,9 @@ async def drop_tips96( async def aspirate96( self, - aspiration: Union[AspirationPlate, AspirationContainer], + aspiration: Union[MultiHeadAspirationPlate, MultiHeadAspirationContainer], + jet: bool = False, + blow_out: bool = False, hlc: Optional[HamiltonLiquidClass] = None, type_of_aspiration: int = 0, minimal_traverse_height_at_begin_of_command: Optional[float] = None, @@ -913,6 +1009,7 @@ async def aspirate96( immersion_depth: float = 0, surface_following_distance: float = 0, transport_air_volume: Optional[float] = None, + blow_out_air_volume: Optional[float] = None, pre_wetting_volume: float = 0, lld_mode: int = 0, lld_sensitivity: int = 4, @@ -928,12 +1025,19 @@ async def aspirate96( tadm_algorithm_on_off: int = 0, recording_mode: int = 0, ): - # assert self.core96_head_installed, "96 head must be installed" + """Aspirate from a plate. - if hlc is not None: - raise NotImplementedError("hlc is deprecated") + Args: + jet: Whether to find a liquid class with "jet" mode. Only used on dispense. + blow_out: Whether to find a liquid class with "blow out" mode. Only used on dispense. Note + that this is called "empty" in the VENUS liquid editor, but "blow out" in the firmware + documentation. + hlc: The Hamiltonian liquid classes to use. If `None`, the liquid classes will be + determined automatically based on the tip and liquid used in the first well. + """ + # assert self.core96_head_installed, "96 head must be installed" - if isinstance(aspiration, AspirationPlate): + if isinstance(aspiration, MultiHeadAspirationPlate): top_left_well = aspiration.wells[0] position = ( top_left_well.get_absolute_location() @@ -955,20 +1059,35 @@ async def aspirate96( liquid_height = position.z + (aspiration.liquid_height or 0) - if transport_air_volume is None: - transport_air_volume = 0 - if aspiration.blow_out_air_volume is None: - blow_out_air_volume = 0.0 - else: - blow_out_air_volume = aspiration.blow_out_air_volume - if aspiration.flow_rate is None: - flow_rate = 250.0 - else: - flow_rate = aspiration.flow_rate - if swap_speed is None: - swap_speed = 100 - if settling_time is None: - settling_time = 5 + tip = aspiration.tips[0] + liquid_to_be_aspirated = Liquid.WATER # default to water + if len(aspiration.liquids[0]) > 0 and aspiration.liquids[0][-1][0] is not None: + # first part of tuple in last liquid of first well + liquid_to_be_aspirated = aspiration.liquids[0][-1][0] + if hlc is None: + hlc = get_vantage_liquid_class( + tip_volume=tip.maximal_volume, + is_core=True, + is_tip=True, + has_filter=tip.has_filter, + liquid=liquid_to_be_aspirated, + jet=jet, + blow_out=blow_out, + ) + + volume = ( + hlc.compute_corrected_volume(aspiration.volume) if hlc is not None else aspiration.volume + ) + + transport_air_volume = transport_air_volume or ( + hlc.aspiration_air_transport_volume if hlc is not None else 0 + ) + blow_out_air_volume = blow_out_air_volume or ( + hlc.aspiration_blow_out_volume if hlc is not None else 0 + ) + flow_rate = aspiration.flow_rate or (hlc.aspiration_flow_rate if hlc is not None else 250) + swap_speed = swap_speed or (hlc.aspiration_swap_speed if hlc is not None else 100) + settling_time = settling_time or (hlc.aspiration_settling_time if hlc is not None else 5) return await self.core96_aspiration_of_liquid( x_position=round(position.x * 10), @@ -990,7 +1109,7 @@ async def aspirate96( tube_2nd_section_ratio=round(tube_2nd_section_ratio * 10), immersion_depth=round(immersion_depth * 10), surface_following_distance=round(surface_following_distance * 10), - aspiration_volume=round(aspiration.volume * 100), + aspiration_volume=round(volume * 100), aspiration_speed=round(flow_rate * 10), transport_air_volume=round(transport_air_volume * 10), blow_out_air_volume=round(blow_out_air_volume * 100), @@ -1016,7 +1135,7 @@ async def aspirate96( async def dispense96( self, - dispense: Union[DispensePlate, DispenseContainer], + dispense: Union[MultiHeadDispensePlate, MultiHeadDispenseContainer], jet: bool = False, blow_out: bool = False, # "empty" in the VENUS liquid editor empty: bool = False, # truly "empty", does not exist in liquid editor, dm4 @@ -1032,6 +1151,7 @@ async def dispense96( cut_off_speed: float = 250.0, stop_back_volume: float = 0, transport_air_volume: Optional[float] = None, + blow_out_air_volume: Optional[float] = None, lld_mode: int = 0, lld_sensitivity: int = 4, side_touch_off_distance: float = 0, @@ -1062,10 +1182,7 @@ async def dispense96( determined based on the jet, blow_out, and empty parameters. """ - if hlc is not None: - raise NotImplementedError("hlc is deprecated") - - if isinstance(dispense, DispensePlate): + if isinstance(dispense, MultiHeadDispensePlate): top_left_well = dispense.wells[0] position = ( top_left_well.get_absolute_location() @@ -1087,24 +1204,36 @@ async def dispense96( liquid_height = position.z + (dispense.liquid_height or 0) + 10 - if transport_air_volume is None: - transport_air_volume = 0 - if dispense.blow_out_air_volume is None: - blow_out_air_volume = 0.0 - else: - blow_out_air_volume = dispense.blow_out_air_volume - if dispense.flow_rate is None: - flow_rate = 250.0 - else: - flow_rate = dispense.flow_rate - if swap_speed is None: - swap_speed = 100 - if settling_time is None: - settling_time = 5 - if mix_speed is None: - mix_speed = 100 - if type_of_dispensing_mode is None: - type_of_dispensing_mode = _get_dispense_mode(jet=jet, empty=empty, blow_out=blow_out) + tip = dispense.tips[0] + liquid_to_be_dispensed = Liquid.WATER # default to WATER + if len(dispense.liquids[0]) > 0 and dispense.liquids[0][-1][0] is not None: + # first part of tuple in last liquid of first well + liquid_to_be_dispensed = dispense.liquids[0][-1][0] + if hlc is None: + hlc = get_vantage_liquid_class( + tip_volume=tip.maximal_volume, + is_core=True, + is_tip=True, + has_filter=tip.has_filter, + liquid=liquid_to_be_dispensed, + jet=jet, + blow_out=blow_out, # see method docstring + ) + volume = hlc.compute_corrected_volume(dispense.volume) if hlc is not None else dispense.volume + + transport_air_volume = transport_air_volume or ( + hlc.dispense_air_transport_volume if hlc is not None else 0 + ) + blow_out_air_volume = blow_out_air_volume or ( + hlc.dispense_blow_out_volume if hlc is not None else 0 + ) + flow_rate = dispense.flow_rate or (hlc.dispense_flow_rate if hlc is not None else 250) + swap_speed = swap_speed or (hlc.dispense_swap_speed if hlc is not None else 100) + settling_time = settling_time or (hlc.dispense_settling_time if hlc is not None else 5) + mix_speed = mix_speed or (hlc.dispense_mix_flow_rate if hlc is not None else 100) + type_of_dispensing_mode = type_of_dispensing_mode or _get_dispense_mode( + jet=jet, empty=empty, blow_out=blow_out + ) return await self.core96_dispensing_of_liquid( x_position=round(position.x * 10), @@ -1126,7 +1255,7 @@ async def dispense96( minimal_height_at_command_end=round( (minimal_height_at_command_end or self._traversal_height) * 10 ), - dispense_volume=round(dispense.volume * 100), + dispense_volume=round(volume * 100), dispense_speed=round(flow_rate * 10), cut_off_speed=round(cut_off_speed * 10), stop_back_volume=round(stop_back_volume * 100), @@ -1150,25 +1279,9 @@ async def dispense96( recording_mode=recording_mode, ) - async def move_resource(self, move: Move): - await self.pick_up_resource( - resource=move.resource, - offset=move.resource_offset, - pickup_distance_from_top=move.pickup_distance_from_top, - ) - - await self.release_picked_up_resource( - resource=move.resource, - destination=move.destination, - offset=move.destination_offset, - pickup_distance_from_top=move.pickup_distance_from_top, - ) - async def pick_up_resource( self, - resource: Resource, - offset: Coordinate, - pickup_distance_from_top: float, + pickup: ResourcePickup, grip_strength: int = 81, plate_width_tolerance: float = 2.0, acceleration_index: int = 4, @@ -1179,9 +1292,9 @@ async def pick_up_resource( """Pick up a resource with the IPG. You probably want to use :meth:`move_resource`, which allows you to pick up and move a resource with a single command.""" - center = resource.get_absolute_location() + resource.center() + offset - grip_height = center.z + resource.get_absolute_size_z() - pickup_distance_from_top - plate_width = resource.get_absolute_size_x() + center = pickup.resource.get_absolute_location(x="c", y="c", z="b") + pickup.offset + grip_height = center.z + pickup.resource.get_absolute_size_z() - pickup.pickup_distance_from_top + plate_width = pickup.resource.get_absolute_size_x() await self.ipg_grip_plate( x_position=round(center.x * 10), @@ -1199,7 +1312,7 @@ async def pick_up_resource( ), ) - async def move_picked_up_resource(self): + async def move_picked_up_resource(self, move: ResourceMove): """Move a resource picked up with the IPG. See :meth:`pick_up_resource`. You probably want to use :meth:`move_resource`, which allows you to pick up and move a resource @@ -1208,12 +1321,9 @@ async def move_picked_up_resource(self): raise NotImplementedError() - async def release_picked_up_resource( + async def drop_resource( self, - resource: Resource, - destination: Coordinate, - offset: Coordinate, - pickup_distance_from_top: float, + drop: ResourceDrop, z_clearance_height: float = 0, press_on_distance: int = 5, hotel_depth: float = 0, @@ -1225,9 +1335,9 @@ async def release_picked_up_resource( with a single command. """ - center = destination + resource.center() + offset - grip_height = center.z + resource.get_absolute_size_z() - pickup_distance_from_top - plate_width = resource.get_absolute_size_x() + center = drop.destination + drop.resource.center() + drop.offset + grip_height = center.z + drop.resource.get_absolute_size_z() - drop.pickup_distance_from_top + plate_width = drop.resource.get_absolute_size_x() await self.ipg_put_plate( x_position=round(center.x * 10), @@ -1247,7 +1357,7 @@ async def prepare_for_manual_channel_operation(self, channel: int): return await self.expose_channel_n(channel_index=channel + 1) # ? - async def move_channel_x(self, channel: int, x: float): # pylint: disable=unused-argument + async def move_channel_x(self, channel: int, x: float): """Move the specified channel to the specified x coordinate.""" return await self.x_arm_move_to_x_position(round(x * 10)) @@ -1334,7 +1444,9 @@ async def loading_cover_initialize(self): command="MI", ) - async def arm_request_instrument_initialization_status(self) -> bool: + async def arm_request_instrument_initialization_status( + self, + ) -> bool: """Request the instrument initialization status. This command was based on the STAR command (QW) and the VStarTranslator log. A1AM corresponds @@ -5091,7 +5203,11 @@ async def x_arm_request_x_drive_recorded_data( async def disco_mode(self): """Easter egg.""" for _ in range(69): - r, g, b = random.randint(30, 100), random.randint(30, 100), random.randint(30, 100) + r, g, b = ( + random.randint(30, 100), + random.randint(30, 100), + random.randint(30, 100), + ) await self.set_led_color("on", intensity=100, white=0, red=r, green=g, blue=b, uv=0) await asyncio.sleep(0.1) @@ -5106,11 +5222,27 @@ async def russian_roulette(self): return if random.randint(1, 6) == 6: - await self.set_led_color("on", intensity=100, white=100, red=100, green=0, blue=0, uv=100) + await self.set_led_color( + "on", + intensity=100, + white=100, + red=100, + green=0, + blue=0, + uv=100, + ) print("You lost.") else: await self.set_led_color("on", intensity=100, white=100, red=0, green=100, blue=0, uv=0) print("You won.") await asyncio.sleep(5) - await self.set_led_color("on", intensity=100, white=100, red=100, green=100, blue=100, uv=0) + await self.set_led_color( + "on", + intensity=100, + white=100, + red=100, + green=100, + blue=100, + uv=0, + ) diff --git a/pylabrobot/liquid_handling/backends/hamilton/vantage_tests.py b/pylabrobot/liquid_handling/backends/hamilton/vantage_tests.py index 53fa50e46f..47e4bb8bdd 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/vantage_tests.py +++ b/pylabrobot/liquid_handling/backends/hamilton/vantage_tests.py @@ -2,15 +2,10 @@ from typing import Any, List, Optional from pylabrobot.liquid_handling import LiquidHandler -from pylabrobot.liquid_handling.liquid_classes.hamilton.vantage import ( - HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty, - HighVolumeFilter_Water_DispenseSurface_Empty, - HighVolumeFilter_Water_DispenseSurface_Part, -) from pylabrobot.liquid_handling.standard import Pickup from pylabrobot.resources import ( - HT_L, - LT_L, + HT, + LT, PLT_CAR_L5AC_A00, TIP_CAR_480_A00, Coordinate, @@ -166,20 +161,25 @@ def test_parse_error_response(self): resp = 'I1AMRQid0000er4et"Slave not available"' error = vantage_response_string_to_error(resp) self.assertEqual( - error, VantageFirmwareError(errors={"Cover": "Slave not available"}, raw_response=resp) + error, + VantageFirmwareError(errors={"Cover": "Slave not available"}, raw_response=resp), ) resp = 'I1AMLPid215er57et"S-Drive: Drive not initialized"' error = vantage_response_string_to_error(resp) self.assertEqual( error, - VantageFirmwareError(errors={"Cover": "S-Drive: Drive not initialized"}, raw_response=resp), + VantageFirmwareError( + errors={"Cover": "S-Drive: Drive not initialized"}, + raw_response=resp, + ), ) resp = 'A1HMDAid239er99es"H070"' error = vantage_response_string_to_error(resp) self.assertEqual( - error, VantageFirmwareError(errors={"Core 96": "No liquid level found"}, raw_response=resp) + error, + VantageFirmwareError(errors={"Core 96": "No liquid level found"}, raw_response=resp), ) resp = 'A1PMDAid262er99es"P170 P270 P370 P470 P570 P670 P770 P870"' @@ -210,7 +210,7 @@ def __init__(self): super().__init__() self.commands = [] - async def setup(self) -> None: + async def setup(self) -> None: # type: ignore self.setup_finished = True self._num_channels = 8 self.iswap_installed = True @@ -220,6 +220,7 @@ async def send_command( self, module: str, command: str, + auto_id: bool = True, tip_pattern: Optional[List[bool]] = None, write_timeout: Optional[int] = None, read_timeout: Optional[int] = None, @@ -227,7 +228,9 @@ async def send_command( fmt: Optional[Any] = None, **kwargs, ): - cmd, _ = self._assemble_command(module, command, tip_pattern, **kwargs) + cmd, _ = self._assemble_command( + module=module, command=command, auto_id=auto_id, tip_pattern=tip_pattern, **kwargs + ) self.commands.append(cmd) async def stop(self): @@ -238,14 +241,13 @@ class TestVantageLiquidHandlerCommands(unittest.IsolatedAsyncioTestCase): """Test Vantage backend for liquid handling.""" async def asyncSetUp(self): - # pylint: disable=invalid-name self.mockVantage = VantageCommandCatcher() self.deck = VantageDeck(size=1.3) self.lh = LiquidHandler(self.mockVantage, deck=self.deck) self.tip_car = TIP_CAR_480_A00(name="tip carrier") - self.tip_car[0] = self.tip_rack = HT_L(name="tip_rack_01") - self.tip_car[1] = self.small_tip_rack = LT_L(name="tip_rack_02") + self.tip_car[0] = self.tip_rack = HT(name="tip_rack_01") + self.tip_car[1] = self.small_tip_rack = LT(name="tip_rack_02") self.deck.assign_child_resource(self.tip_car, rails=18) self.plt_car = PLT_CAR_L5AC_A00(name="plate carrier") @@ -311,7 +313,6 @@ def _assert_command_in_command_buffer(self, cmd: str, should_be: bool, fmt: dict def test_ops_to_fw_positions(self): """Convert channel positions to firmware positions.""" - # pylint: disable=protected-access tip_a1 = self.tip_rack.get_item("A1") tip_f1 = self.tip_rack.get_item("F1") tip = self.tip_rack.get_tip("A1") @@ -330,7 +331,11 @@ def test_ops_to_fw_positions(self): self.assertEqual( self.mockVantage._ops_to_fw_positions((op1, op2), use_channels=[1, 2]), - ([0, 4329, 4329, 0], [0, 1458, 1008, 0], [False, True, True, False]), + ( + [0, 4329, 4329, 0], + [0, 1458, 1008, 0], + [False, True, True, False], + ), ) def _assert_command_sent_once(self, cmd: str, fmt: dict): @@ -369,41 +374,37 @@ async def test_small_tip_drop(self): await self.test_small_tip_pickup() # pick up tips first await self.lh.drop_tips(self.small_tip_rack["A1"]) self._assert_command_sent_once( - "A1PMTRid0012xp4329 0&yp2418 0&tp2024&tz1924&th2450&te2450&tm1 0&ts0td0&", DROP_TIP_FORMAT + "A1PMTRid0012xp4329 0&yp2418 0&tp2024&tz1924&th2450&te2450&tm1 0&ts0td0&", + DROP_TIP_FORMAT, ) async def test_aspirate(self): await self.lh.pick_up_tips(self.tip_rack["A1"]) # pick up tips first - hlc = HighVolumeFilter_Water_DispenseSurface_Part - corrected_volume = hlc.compute_corrected_volume(100) - await self.lh.aspirate(self.plate["A1"], vols=[corrected_volume], **hlc.make_asp_kwargs(1)) + await self.lh.aspirate(self.plate["A1"], vols=[100]) self._assert_command_sent_once( "A1PMDAid0248at0&tm1 0&xp05683 0&yp1457 0 &th2450&te2450&lp1990&" "ch000&zl1866&zx1866&ip0000&fp0000&av010830&as2500&ta000&ba00000&oa000&lm0&ll4&lv4&de0020&" - "wt10&mv00000&mc00&mp000&ms1200&gi000&gj0gk0zu0000&zr00000&mh0000&zo005&po0109&dj0la0&lb0&" + "wt10&mv00000&mc00&mp000&ms2500&gi000&gj0gk0zu0000&zr00000&mh0000&zo005&po0109&dj0la0&lb0&" "lc0&", ASPIRATE_FORMAT, ) async def test_dispense(self): await self.lh.pick_up_tips(self.tip_rack["A1"]) # pick up tips first - hlc = HighVolumeFilter_Water_DispenseSurface_Empty - corrected_volume = hlc.compute_corrected_volume(100) - await self.lh.aspirate(self.plate["A1"], vols=[corrected_volume], **hlc.make_asp_kwargs(1)) + await self.lh.aspirate(self.plate["A1"], vols=[100]) await self.lh.dispense( self.plate["A2"], - vols=[corrected_volume], + vols=[100], liquid_height=[5], jet=[False], blow_out=[True], - **hlc.make_disp_kwargs(1), ) self._assert_command_sent_once( "A1PMDDid0253dm3&tm1 0&xp05773 0&yp1457 0&zx1866&lp1990&zl1916&" "ip0000&fp0021&th2450&te2450&dv010830&ds1200&ss2500&rv000&ta050&ba00000&lm0&zo005&ll1&lv1&" - "de0020&mv00000&mc00&mp000&ms1200&wt00&gi000&gj0gk0zu0000&dj00zr00000&mh0000&po0050&la0&", + "de0010&mv00000&mc00&mp000&ms0010&wt00&gi000&gj0gk0zu0000&dj00zr00000&mh0000&po0050&la0&", DISPENSE_FORMAT, ) @@ -417,7 +418,15 @@ async def test_tip_pickup96(self): await self.lh.pick_up_tips96(self.tip_rack) self._assert_command_sent_once( "A1HMTPid0237xp04329yp1458tt01td0tz2164th2450te2450", - {"xp": "int", "yp": "int", "tt": "int", "td": "int", "tz": "int", "th": "int", "te": "int"}, + { + "xp": "int", + "yp": "int", + "tt": "int", + "td": "int", + "tz": "int", + "th": "int", + "te": "int", + }, ) async def test_tip_drop96(self): @@ -425,17 +434,20 @@ async def test_tip_drop96(self): await self.lh.drop_tips96(self.tip_rack) self._assert_command_sent_once( "A1HMTRid0284xp04329yp1458tz2164th2450te2450", - {"xp": "int", "yp": "int", "tz": "int", "th": "int", "te": "int"}, + { + "xp": "int", + "yp": "int", + "tz": "int", + "th": "int", + "te": "int", + }, ) async def test_aspirate96(self): await self.lh.pick_up_tips96(self.tip_rack) - hlc = HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty - await self.lh.aspirate96( - self.plate, volume=hlc.compute_corrected_volume(100), **hlc.make_asp96_kwargs() - ) + await self.lh.aspirate96(self.plate, volume=100, jet=True, blow_out=True) self._assert_command_sent_once( - "A1HMDAid0236at0xp05683yp1457th2450te2450lp1990zl1866zx1866ip000fp000av010920as2500ta050" + "A1HMDAid0236at0xp05683yp1457th2450te2450lp1990zl1866zx1866ip000fp000av010720as2500ta050" "ba004000oa00000lm0ll4de0020wt10mv00000mc00mp000ms2500zu0000zr00000mh000gj0gk0gi000" "cwFFFFFFFFFFFFFFFFFFFFFFFFpo0050", { @@ -473,19 +485,10 @@ async def test_aspirate96(self): async def test_dispense96(self): await self.lh.pick_up_tips96(self.tip_rack) - hlc = HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty - await self.lh.aspirate96( - self.plate, volume=hlc.compute_corrected_volume(100), **hlc.make_asp96_kwargs() - ) - await self.lh.dispense96( - self.plate, - volume=hlc.compute_corrected_volume(100), - jet=True, - blow_out=True, - **hlc.make_disp96_kwargs(), - ) + await self.lh.aspirate96(self.plate, volume=100, jet=True, blow_out=True) + await self.lh.dispense96(self.plate, volume=100, jet=True, blow_out=True) self._assert_command_sent_once( - "A1HMDDid0238dm1xp05683yp1457th2450te2450lp1990zl1966zx1866ip000fp029dv10920ds4000ta050" + "A1HMDDid0238dm1xp05683yp1457th2450te2450lp1990zl1966zx1866ip000fp029dv010720ds4000ta050" "ba004000lm0ll4de0010wt00mv00000mc00mp000ms0010ss2500rv000zu0000dj00zr00000mh000gj0gk0gi000" "cwFFFFFFFFFFFFFFFFFFFFFFFFpo0050", { @@ -531,6 +534,7 @@ async def test_zero_volume_liquid_handling96(self): await self.lh.dispense96(self.plate, volume=0) async def test_move_plate(self): + self.plt_car[1].resource.unassign() await self.lh.move_plate(self.plate, self.plt_car[1], pickup_distance_from_top=5.2 - 3.33) # pickup @@ -553,5 +557,13 @@ async def test_move_plate(self): # release self._assert_command_sent_once( "A1RMDRid0242xp6179yp2102zp1954yo1310zc0hd0te2840", - {"xp": "int", "yp": "int", "zp": "int", "yo": "int", "zc": "int", "hd": "int", "te": "int"}, + { + "xp": "int", + "yp": "int", + "zp": "int", + "yo": "int", + "zc": "int", + "hd": "int", + "te": "int", + }, ) diff --git a/pylabrobot/liquid_handling/liquid_handler.py b/pylabrobot/liquid_handling/liquid_handler.py index 5f6cb61969..0afc7a4b32 100644 --- a/pylabrobot/liquid_handling/liquid_handler.py +++ b/pylabrobot/liquid_handling/liquid_handler.py @@ -1,4 +1,4 @@ -""" Defines LiquidHandler class, the coordinator for liquid handling operations. """ +"""Defines LiquidHandler class, the coordinator for liquid handling operations.""" from __future__ import annotations @@ -9,23 +9,42 @@ import logging import threading import warnings -from typing import Any, Callable, Dict, List, Optional, Protocol, Sequence, Set, Tuple, Union, cast +from typing import ( + Any, + Callable, + Dict, + List, + Literal, + Optional, + Protocol, + Sequence, + Set, + Tuple, + Union, + cast, +) from pylabrobot.liquid_handling.errors import ChannelizedError -from pylabrobot.liquid_handling.strictness import Strictness, get_strictness +from pylabrobot.liquid_handling.strictness import ( + Strictness, + get_strictness, +) +from pylabrobot.liquid_handling.utils import ( + get_tight_single_resource_liquid_op_offsets, + get_wide_single_resource_liquid_op_offsets, +) from pylabrobot.machines.machine import Machine, need_setup_finished from pylabrobot.plate_reading import PlateReader from pylabrobot.resources import ( - CarrierSite, Container, Coordinate, Deck, Lid, - MFXModule, Plate, PlateAdapter, - PlateCarrierSite, + PlateHolder, Resource, + ResourceHolder, ResourceStack, Tip, TipRack, @@ -40,22 +59,25 @@ ) from pylabrobot.resources.errors import CrossContaminationError, HasTipError from pylabrobot.resources.liquid import Liquid +from pylabrobot.resources.rotation import Rotation from pylabrobot.tilting.tilter import Tilter from .backends import LiquidHandlerBackend from .standard import ( - Aspiration, - AspirationContainer, - AspirationPlate, - Dispense, - DispenseContainer, - DispensePlate, Drop, DropTipRack, GripDirection, - Move, + MultiHeadAspirationContainer, + MultiHeadAspirationPlate, + MultiHeadDispenseContainer, + MultiHeadDispensePlate, Pickup, PickupTipRack, + ResourceDrop, + ResourceMove, + ResourcePickup, + SingleChannelAspiration, + SingleChannelDispense, ) logger = logging.getLogger("pylabrobot") @@ -77,10 +99,10 @@ def check_updatable(src_tracker: VolumeTracker, dest_tracker: VolumeTracker): class BlowOutVolumeError(Exception): - ... + pass -class LiquidHandler(Machine): +class LiquidHandler(Resource, Machine): """ Front end for liquid handlers. @@ -109,14 +131,15 @@ def __init__(self, backend: LiquidHandlerBackend, deck: Deck): deck: Deck to use. """ - super().__init__( + Resource.__init__( + self, name=f"lh_{deck.name}", size_x=deck._size_x, size_y=deck._size_y, size_z=deck._size_z, - backend=backend, category="liquid_handler", ) + Machine.__init__(self, backend=backend) self.backend: LiquidHandlerBackend = backend # fix type self._callbacks: Dict[str, OperationCallback] = {} @@ -136,6 +159,8 @@ def __init__(self, backend: LiquidHandlerBackend, deck: Deck): self.location = Coordinate.zero() super().assign_child_resource(deck, location=deck.location or Coordinate.zero()) + self._resource_pickup: Optional[ResourcePickup] = None + async def setup(self, **backend_kwargs): """Prepare the robot for use.""" @@ -143,6 +168,7 @@ async def setup(self, **backend_kwargs): raise RuntimeError("The setup has already finished. See `LiquidHandler.stop`.") self.backend.set_deck(self.deck) + self.backend.set_heads(head=self.head, head96=self.head96) await super().setup(**backend_kwargs) self.head = {c: TipTracker(thing=f"Channel {c}") for c in range(self.backend.num_channels)} @@ -152,6 +178,8 @@ async def setup(self, **backend_kwargs): for resource in self.deck.children: self._send_assigned_resource_to_backend(resource) + self._resource_pickup = None + def serialize_state(self) -> Dict[str, Any]: """Serialize the state of this liquid handler. Use :meth:`~Resource.serialize_all_states` to serialize the state of the liquid handler and all children (the deck).""" @@ -250,13 +278,21 @@ def _assert_resources_exist(self, resources: Sequence[Resource]): raise ValueError(f"Resource {resource} is not assigned to the deck.") def _check_args( - self, method: Callable, backend_kwargs: Dict[str, Any], default: Set[str] + self, + method: Callable, + backend_kwargs: Dict[str, Any], + default: Set[str], + strictness: Strictness, ) -> Set[str]: """Checks that the arguments to `method` are valid. Args: method: Method to check. backend_kwargs: Keyword arguments to `method`. + default: Default arguments to `method`. (Of the abstract backend) + strictness: Strictness level. If `Strictness.STRICT`, raises an error if there are extra + arguments. If `Strictness.WARN`, raises a warning. If `Strictness.IGNORE`, logs a debug + message. Raises: TypeError: If the arguments are invalid. @@ -277,12 +313,14 @@ def _check_args( args = { arg: param for arg, param in args.items() # keep only *args and **kwargs - if param.kind not in {inspect.Parameter.VAR_POSITIONAL, inspect.Parameter.VAR_KEYWORD} + if param.kind + not in { + inspect.Parameter.VAR_POSITIONAL, + inspect.Parameter.VAR_KEYWORD, + } } non_default = {arg for arg, param in args.items() if param.default == inspect.Parameter.empty} - strictness = get_strictness() - backend_kws = set(backend_kwargs.keys()) missing = non_default - backend_kws @@ -322,19 +360,19 @@ async def pick_up_tips( Examples: Pick up all tips in the first column. - >>> lh.pick_up_tips(tips_resource["A1":"H1"]) + >>> await lh.pick_up_tips(tips_resource["A1":"H1"]) Pick up tips on odd numbered rows, skipping the other channels. - >>> lh.pick_up_tips(tips_resource["A1", "C1", "E1", "G1"],use_channels=[0, 2, 4, 6]) + >>> await lh.pick_up_tips(tips_resource["A1", "C1", "E1", "G1"],use_channels=[0, 2, 4, 6]) Pick up tips from different tip resources: - >>> lh.pick_up_tips(tips_resource1["A1"] + tips_resource2["B2"] + tips_resource3["C3"]) + >>> await lh.pick_up_tips(tips_resource1["A1"] + tips_resource2["B2"] + tips_resource3["C3"]) Picking up tips with different offsets: - >>> lh.pick_up_tips( + >>> await lh.pick_up_tips( ... tip_spots=tips_resource["A1":"C1"], ... offsets=[ ... Coordinate(0, 0, 0), # A1 @@ -399,7 +437,10 @@ async def pick_up_tips( # fix the backend kwargs extras = self._check_args( - self.backend.pick_up_tips, backend_kwargs, default={"ops", "use_channels"} + self.backend.pick_up_tips, + backend_kwargs, + default={"ops", "use_channels"}, + strictness=get_strictness(), ) for extra in extras: del backend_kwargs[extra] @@ -408,7 +449,7 @@ async def pick_up_tips( error: Optional[Exception] = None try: await self.backend.pick_up_tips(ops=pickups, use_channels=use_channels, **backend_kwargs) - except Exception as e: # pylint: disable=broad-except + except Exception as e: error = e # determine which channels were successful @@ -435,7 +476,7 @@ async def pick_up_tips( @need_setup_finished async def drop_tips( self, - tip_spots: List[Union[TipSpot, Trash]], + tip_spots: Sequence[Union[TipSpot, Trash]], use_channels: Optional[List[int]] = None, offsets: Optional[List[Coordinate]] = None, allow_nonzero_volume: bool = False, @@ -446,11 +487,11 @@ async def drop_tips( Examples: Dropping tips to the first column. - >>> lh.pick_up_tips(tip_rack["A1:H1"]) + >>> await lh.pick_up_tips(tip_rack["A1:H1"]) Dropping tips with different offsets: - >>> lh.drop_tips( + >>> await lh.drop_tips( ... channels=tips_resource["A1":"C1"], ... offsets=[ ... Coordinate(0, 0, 0), # A1 @@ -528,7 +569,10 @@ async def drop_tips( # fix the backend kwargs extras = self._check_args( - self.backend.drop_tips, backend_kwargs, default={"ops", "use_channels"} + self.backend.drop_tips, + backend_kwargs, + default={"ops", "use_channels"}, + strictness=get_strictness(), ) for extra in extras: del backend_kwargs[extra] @@ -537,7 +581,7 @@ async def drop_tips( error: Optional[Exception] = None try: await self.backend.drop_tips(ops=drops, use_channels=use_channels, **backend_kwargs) - except Exception as e: # pylint: disable=broad-except + except Exception as e: error = e # determine which channels were successful @@ -565,16 +609,24 @@ async def drop_tips( **backend_kwargs, ) - async def return_tips(self, use_channels: Optional[list[int]] = None, **backend_kwargs): + async def return_tips( + self, + use_channels: Optional[list[int]] = None, + allow_nonzero_volume: bool = False, + **backend_kwargs, + ): """Return all tips that are currently picked up to their original place. Examples: Return the tips on the head to the tip rack where they were picked up: - >>> lh.pick_up_tips(tip_rack["A1"]) - >>> lh.return_tips() + >>> await lh.pick_up_tips(tip_rack["A1"]) + >>> await lh.return_tips() Args: + use_channels: List of channels to use. Index from front to back. If `None`, all that have + tips will be used. + allow_nonzero_volume: If `True`, tips will be returned even if their volumes are not zero. backend_kwargs: backend kwargs passed to `drop_tips`. Raises: @@ -597,12 +649,18 @@ async def return_tips(self, use_channels: Optional[list[int]] = None, **backend_ if len(tip_spots) == 0: raise RuntimeError("No tips have been picked up.") - return await self.drop_tips(tip_spots=tip_spots, use_channels=channels, **backend_kwargs) + return await self.drop_tips( + tip_spots=tip_spots, + use_channels=channels, + allow_nonzero_volume=allow_nonzero_volume, + **backend_kwargs, + ) async def discard_tips( self, use_channels: Optional[List[int]] = None, allow_nonzero_volume: bool = True, + offsets: Optional[List[Coordinate]] = None, **backend_kwargs, ): """Permanently discard tips in the trash. @@ -610,15 +668,16 @@ async def discard_tips( Examples: Discarding the tips on channels 1 and 2: - >>> lh.discard_tips(use_channels=[0, 1]) + >>> await lh.discard_tips(use_channels=[0, 1]) Discarding all tips currently picked up: - >>> lh.discard_tips() + >>> await lh.discard_tips() Args: use_channels: List of channels to use. Index from front to back. If `None`, all that have tips will be used. + allow_nonzero_volume: If `True`, tips will be returned even if their volumes are not zero. backend_kwargs: Additional keyword arguments for the backend, optional. """ @@ -632,7 +691,16 @@ async def discard_tips( raise RuntimeError("No tips have been picked up and no channels were specified.") trash = self.deck.get_trash_area() - offsets = [c - trash.center() for c in reversed(trash.centers(yn=n))] # offset is wrt center + trash_offsets = get_tight_single_resource_liquid_op_offsets( + trash, + num_channels=n, + ) + # add trash_offsets to offsets if defined, otherwise use trash_offsets + # too advanced for mypy + offsets = [ + o + to if o is not None else to + for o, to in zip(offsets or [None] * n, trash_offsets) # type: ignore + ] return await self.drop_tips( tip_spots=[trash] * n, @@ -658,6 +726,7 @@ async def aspirate( offsets: Optional[List[Coordinate]] = None, liquid_height: Optional[List[Optional[float]]] = None, blow_out_air_volume: Optional[List[Optional[float]]] = None, + spread: Literal["wide", "tight", "custom"] = "wide", **backend_kwargs, ): """Aspirate liquid from the specified wells. @@ -665,28 +734,28 @@ async def aspirate( Examples: Aspirate a constant amount of liquid from the first column: - >>> lh.aspirate(plate["A1:H1"], 50) + >>> await lh.aspirate(plate["A1:H1"], 50) Aspirate an linearly increasing amount of liquid from the first column: - >>> lh.aspirate(plate["A1:H1"], range(0, 500, 50)) + >>> await lh.aspirate(plate["A1:H1"], range(0, 500, 50)) Aspirate arbitrary amounts of liquid from the first column: - >>> lh.aspirate(plate["A1:H1"], [0, 40, 10, 50, 100, 200, 300, 400]) + >>> await lh.aspirate(plate["A1:H1"], [0, 40, 10, 50, 100, 200, 300, 400]) Aspirate liquid from wells in different plates: - >>> lh.aspirate(plate["A1"] + plate2["A1"] + plate3["A1"], 50) + >>> await lh.aspirate(plate["A1"] + plate2["A1"] + plate3["A1"], 50) Aspirating with a 10mm z-offset: - >>> lh.aspirate(plate["A1"], vols=50, offsets=[Coordinate(0, 0, 10)]) + >>> await lh.aspirate(plate["A1"], vols=50, offsets=[Coordinate(0, 0, 10)]) Aspirate from a blue bucket (big container), with the first 4 channels (which will be spaced equally apart): - >>> lh.aspirate(blue_bucket, vols=50, use_channels=[0, 1, 2, 3]) + >>> await lh.aspirate(blue_bucket, vols=50, use_channels=[0, 1, 2, 3]) Args: resources: A list of wells to aspirate liquid from. Can be a single resource, or a list of @@ -702,6 +771,10 @@ async def aspirate( liquid_height: The height of the liquid in the well wrt the bottom, in mm. blow_out_air_volume: The volume of air to aspirate after the liquid, in ul. If `None`, the backend default will be used. + spread: Used if aspirating from a single resource with multiple channels. If "tight", the + channels will be spaced as close as possible. If "wide", the channels will be spaced as far + apart as possible. If "custom", the user must specify the offsets wrt the center of the + resource. backend_kwargs: Additional keyword arguments for the backend, optional. Raises: @@ -742,11 +815,22 @@ async def aspirate( # center of the resource. if len(set(resources)) == 1: resource = resources[0] - n = len(use_channels) resources = [resource] * len(use_channels) - centers = list(reversed(resource.centers(yn=n, zn=0))) - centers = [c - resource.center() for c in centers] # offset is wrt center - offsets = [c + o for c, o in zip(centers, offsets)] # user-defined + if spread == "tight": + center_offsets = get_tight_single_resource_liquid_op_offsets( + resource=resource, num_channels=len(use_channels) + ) + elif spread == "wide": + center_offsets = get_wide_single_resource_liquid_op_offsets( + resource=resource, num_channels=len(use_channels) + ) + elif spread == "custom": + center_offsets = [Coordinate.zero()] * len(use_channels) + else: + raise ValueError("Invalid value for 'spread'. Must be 'tight', 'wide', or 'custom'.") + + # add user defined offsets to the computed centers + offsets = [c + o for c, o in zip(center_offsets, offsets)] # liquid(s) for each channel. If volume tracking is disabled, use None as the liquid. liquids: List[List[Tuple[Optional[Liquid], float]]] = [] @@ -758,7 +842,7 @@ async def aspirate( # create operations aspirations = [ - Aspiration( + SingleChannelAspiration( resource=r, volume=v, offset=o, @@ -769,7 +853,14 @@ async def aspirate( liquids=lvs, ) for r, v, o, fr, lh, t, bav, lvs in zip( - resources, vols, offsets, flow_rates, liquid_height, tips, blow_out_air_volume, liquids + resources, + vols, + offsets, + flow_rates, + liquid_height, + tips, + blow_out_air_volume, + liquids, ) ] @@ -781,7 +872,10 @@ async def aspirate( # Cross contamination check if does_cross_contamination_tracking(): - if check_contaminated(op.tip.tracker.liquid_history, op.resource.tracker.liquid_history): + if check_contaminated( + op.tip.tracker.liquid_history, + op.resource.tracker.liquid_history, + ): raise CrossContaminationError( f"Attempting to aspirate {next(reversed(op.liquids))[0]} with a tip contaminated " f"with {op.tip.tracker.liquid_history}." @@ -791,7 +885,10 @@ async def aspirate( op.tip.tracker.add_liquid(liquid=liquid, volume=volume) extras = self._check_args( - self.backend.aspirate, backend_kwargs, default={"ops", "use_channels"} + self.backend.aspirate, + backend_kwargs, + default={"ops", "use_channels"}, + strictness=get_strictness(), ) for extra in extras: del backend_kwargs[extra] @@ -800,7 +897,7 @@ async def aspirate( error: Optional[Exception] = None try: await self.backend.aspirate(ops=aspirations, use_channels=use_channels, **backend_kwargs) - except Exception as e: # pylint: disable=broad-exception-caught + except Exception as e: error = e # determine which channels were successful @@ -813,7 +910,8 @@ async def aspirate( if does_volume_tracking(): if not op.resource.tracker.is_disabled: (op.resource.tracker.commit if success else op.resource.tracker.rollback)() - (self.head[channel].get_tip().tracker.commit if success else self.head[channel].rollback)() + tip_volume_tracker = self.head[channel].get_tip().tracker + (tip_volume_tracker.commit if success else tip_volume_tracker.rollback)() # trigger callback self._trigger_callback( @@ -835,6 +933,7 @@ async def dispense( offsets: Optional[List[Coordinate]] = None, liquid_height: Optional[List[Optional[float]]] = None, blow_out_air_volume: Optional[List[Optional[float]]] = None, + spread: Literal["wide", "tight", "custom"] = "wide", **backend_kwargs, ): """Dispense liquid to the specified channels. @@ -842,28 +941,28 @@ async def dispense( Examples: Dispense a constant amount of liquid to the first column: - >>> lh.dispense(plate["A1:H1"], 50) + >>> await lh.dispense(plate["A1:H1"], 50) Dispense an linearly increasing amount of liquid to the first column: - >>> lh.dispense(plate["A1:H1"], range(0, 500, 50)) + >>> await lh.dispense(plate["A1:H1"], range(0, 500, 50)) Dispense arbitrary amounts of liquid to the first column: - >>> lh.dispense(plate["A1:H1"], [0, 40, 10, 50, 100, 200, 300, 400]) + >>> await lh.dispense(plate["A1:H1"], [0, 40, 10, 50, 100, 200, 300, 400]) Dispense liquid to wells in different plates: - >>> lh.dispense((plate["A1"], 50), (plate2["A1"], 50), (plate3["A1"], 50)) + >>> await lh.dispense((plate["A1"], 50), (plate2["A1"], 50), (plate3["A1"], 50)) Dispensing with a 10mm z-offset: - >>> lh.dispense(plate["A1"], vols=50, offsets=[Coordinate(0, 0, 10)]) + >>> await lh.dispense(plate["A1"], vols=50, offsets=[Coordinate(0, 0, 10)]) Dispense a blue bucket (big container), with the first 4 channels (which will be spaced equally apart): - >>> lh.dispense(blue_bucket, vols=50, use_channels=[0, 1, 2, 3]) + >>> await lh.dispense(blue_bucket, vols=50, use_channels=[0, 1, 2, 3]) Args: wells: A list of resources to dispense liquid to. Can be a list of resources, or a single @@ -914,11 +1013,22 @@ async def dispense( # center of the resource. if len(set(resources)) == 1: resource = resources[0] - n = len(use_channels) resources = [resource] * len(use_channels) - centers = list(reversed(resource.centers(yn=n, zn=0))) - centers = [c - resource.center() for c in centers] # offset is wrt center - offsets = [c + o for c, o in zip(centers, offsets)] # user-defined + if spread == "tight": + center_offsets = get_tight_single_resource_liquid_op_offsets( + resource=resource, num_channels=len(use_channels) + ) + elif spread == "wide": + center_offsets = get_wide_single_resource_liquid_op_offsets( + resource=resource, num_channels=len(use_channels) + ) + elif spread == "custom": + center_offsets = [Coordinate.zero()] * len(use_channels) + else: + raise ValueError("Invalid value for 'spread'. Must be 'tight', 'wide', or 'custom'.") + + # add user defined offsets to the computed centers + offsets = [c + o for c, o in zip(center_offsets, offsets)] tips = [self.head[channel].get_tip() for channel in use_channels] @@ -926,7 +1036,6 @@ async def dispense( if does_volume_tracking(): if any(bav is not None and bav != 0.0 for bav in blow_out_air_volume): if self._blow_out_air_volume is None: - print(blow_out_air_volume) raise BlowOutVolumeError("No blowout volume was aspirated.") for requested_bav, done_bav in zip(blow_out_air_volume, self._blow_out_air_volume): if requested_bav is not None and done_bav is not None and requested_bav > done_bav: @@ -940,15 +1049,14 @@ async def dispense( # liquid(s) for each channel. If volume tracking is disabled, use None as the liquid. if does_volume_tracking(): - liquids = [ - c.get_tip().tracker.get_liquids(top_volume=vol) for c, vol in zip(self.head.values(), vols) - ] + channels = [self.head[channel] for channel in use_channels] + liquids = [c.get_tip().tracker.get_liquids(top_volume=vol) for c, vol in zip(channels, vols)] else: liquids = [[(None, vol)] for vol in vols] # create operations dispenses = [ - Dispense( + SingleChannelDispense( resource=r, volume=v, offset=o, @@ -959,7 +1067,14 @@ async def dispense( blow_out_air_volume=bav, ) for r, v, o, fr, lh, t, bav, lvs in zip( - resources, vols, offsets, flow_rates, liquid_height, tips, blow_out_air_volume, liquids + resources, + vols, + offsets, + flow_rates, + liquid_height, + tips, + blow_out_air_volume, + liquids, ) ] @@ -977,7 +1092,10 @@ async def dispense( # fix the backend kwargs extras = self._check_args( - self.backend.dispense, backend_kwargs, default={"ops", "use_channels"} + self.backend.dispense, + backend_kwargs, + default={"ops", "use_channels"}, + strictness=get_strictness(), ) for extra in extras: del backend_kwargs[extra] @@ -986,7 +1104,7 @@ async def dispense( error: Optional[Exception] = None try: await self.backend.dispense(ops=dispenses, use_channels=use_channels, **backend_kwargs) - except Exception as e: # pylint: disable=broad-except + except Exception as e: error = e # determine which channels were successful @@ -999,7 +1117,8 @@ async def dispense( if does_volume_tracking(): if not op.resource.tracker.is_disabled: (op.resource.tracker.commit if success else op.resource.tracker.rollback)() - (self.head[channel].get_tip().tracker.commit if success else self.head[channel].rollback)() + tip_volume_tracker = self.head[channel].get_tip().tracker + (tip_volume_tracker.commit if success else tip_volume_tracker.rollback)() if any(bav is not None for bav in blow_out_air_volume): self._blow_out_air_volume = None @@ -1022,7 +1141,7 @@ async def transfer( ratios: Optional[List[float]] = None, target_vols: Optional[List[float]] = None, aspiration_flow_rate: Optional[float] = None, - dispense_flow_rates: Optional[Union[float, List[Optional[float]]]] = None, + dispense_flow_rates: Optional[List[Optional[float]]] = None, **backend_kwargs, ): """Transfer liquid from one well to another. @@ -1031,19 +1150,19 @@ async def transfer( Transfer 50 uL of liquid from the first well to the second well: - >>> lh.transfer(plate["A1"], plate["B1"], source_vol=50) + >>> await lh.transfer(plate["A1"], plate["B1"], source_vol=50) Transfer 80 uL of liquid from the first well equally to the first column: - >>> lh.transfer(plate["A1"], plate["A1:H1"], source_vol=80) + >>> await lh.transfer(plate["A1"], plate["A1:H1"], source_vol=80) Transfer 60 uL of liquid from the first well in a 1:2 ratio to 2 other wells: - >>> lh.transfer(plate["A1"], plate["B1:C1"], source_vol=60, ratios=[2, 1]) + >>> await lh.transfer(plate["A1"], plate["B1:C1"], source_vol=60, ratios=[2, 1]) Transfer arbitrary volumes to the first column: - >>> lh.transfer(plate["A1"], plate["A1:H1"], target_vols=[3, 1, 4, 1, 5, 9, 6, 2]) + >>> await lh.transfer(plate["A1"], plate["A1:H1"], target_vols=[3, 1, 4, 1, 5, 9, 6, 2]) Args: source: The source well. @@ -1078,13 +1197,17 @@ async def transfer( target_vols = [source_vol * r / sum(ratios) for r in ratios] await self.aspirate( - resources=[source], vols=[sum(target_vols)], flow_rates=aspiration_flow_rate, **backend_kwargs + resources=[source], + vols=[sum(target_vols)], + flow_rates=[aspiration_flow_rate], + **backend_kwargs, ) - for target, vol in zip(targets, target_vols): + dispense_flow_rates = dispense_flow_rates or [None] * len(targets) + for target, vol, dfr in zip(targets, target_vols, dispense_flow_rates): await self.dispense( resources=[target], vols=[vol], - flow_rates=dispense_flow_rates, + flow_rates=[dfr], use_channels=[0], **backend_kwargs, ) @@ -1097,15 +1220,15 @@ def use_channels(self, channels: List[int]): Use channel index 2 for all liquid handling operations inside the context: >>> with lh.use_channels([2]): - ... lh.pick_up_tips(tip_rack["A1"]) - ... lh.aspirate(plate["A1"], 50) - ... lh.dispense(plate["A1"], 50) + ... await lh.pick_up_tips(tip_rack["A1"]) + ... await lh.aspirate(plate["A1"], 50) + ... await lh.dispense(plate["A1"], 50) This is equivalent to: - >>> lh.pick_up_tips(tip_rack["A1"], use_channels=[2]) - >>> lh.aspirate(plate["A1"], 50, use_channels=[2]) - >>> lh.dispense(plate["A1"], 50, use_channels=[2]) + >>> await lh.pick_up_tips(tip_rack["A1"], use_channels=[2]) + >>> await lh.aspirate(plate["A1"], 50, use_channels=[2]) + >>> await lh.dispense(plate["A1"], 50, use_channels=[2]) Within the context manager, you can override the default channels by specifying the `use_channels` argument explicitly. @@ -1119,14 +1242,17 @@ def use_channels(self, channels: List[int]): self._default_use_channels = None async def pick_up_tips96( - self, tip_rack: TipRack, offset: Coordinate = Coordinate.zero(), **backend_kwargs + self, + tip_rack: TipRack, + offset: Coordinate = Coordinate.zero(), + **backend_kwargs, ): """Pick up tips using the 96 head. This will pick up 96 tips. Examples: Pick up tips from a 96-tip tiprack: - >>> lh.pick_up_tips96(my_tiprack) + >>> await lh.pick_up_tips96(my_tiprack) Args: tip_rack: The tip rack to pick up tips from. @@ -1139,7 +1265,9 @@ async def pick_up_tips96( if not tip_rack.num_items == 96: raise ValueError("Tip rack must have 96 tips") - extras = self._check_args(self.backend.pick_up_tips96, backend_kwargs, default={"pickup"}) + extras = self._check_args( + self.backend.pick_up_tips96, backend_kwargs, default={"pickup"}, strictness=get_strictness() + ) for extra in extras: del backend_kwargs[extra] @@ -1154,7 +1282,7 @@ async def pick_up_tips96( pickup_operation = PickupTipRack(resource=tip_rack, offset=offset) try: await self.backend.pick_up_tips96(pickup=pickup_operation, **backend_kwargs) - except Exception as error: # pylint: disable=broad-except + except Exception as error: for i, tip_spot in enumerate(tip_rack.get_all_items()): if does_tip_tracking() and not tip_spot.tracker.is_disabled: tip_spot.tracker.rollback() @@ -1191,11 +1319,11 @@ async def drop_tips96( Examples: Drop tips to a 96-tip tiprack: - >>> lh.drop_tips96(my_tiprack) + >>> await lh.drop_tips96(my_tiprack) Drop tips to the trash: - >>> lh.drop_tips96(lh.deck.get_trash_area96()) + >>> await lh.drop_tips96(lh.deck.get_trash_area96()) Args: resource: The tip rack to drop tips to. @@ -1211,7 +1339,9 @@ async def drop_tips96( if isinstance(resource, TipRack) and not resource.num_items == 96: raise ValueError("Tip rack must have 96 tips") - extras = self._check_args(self.backend.drop_tips96, backend_kwargs, default={"drop"}) + extras = self._check_args( + self.backend.drop_tips96, backend_kwargs, default={"drop"}, strictness=get_strictness() + ) for extra in extras: del backend_kwargs[extra] @@ -1230,7 +1360,7 @@ async def drop_tips96( drop_operation = DropTipRack(resource=resource, offset=offset) try: await self.backend.drop_tips96(drop=drop_operation, **backend_kwargs) - except Exception as e: # pylint: disable=broad-except + except Exception as e: for i in range(96): if isinstance(resource, TipRack): tip_spot = resource.get_item(i) @@ -1286,8 +1416,8 @@ async def return_tips96(self, allow_nonzero_volume: bool = False, **backend_kwar Examples: Return the tips on the 96 head to the tip rack where they were picked up: - >>> lh.pick_up_tips96(my_tiprack) - >>> lh.return_tips96() + >>> await lh.pick_up_tips96(my_tiprack) + >>> await lh.return_tips96() Raises: RuntimeError: If no tips have been picked up. @@ -1297,7 +1427,9 @@ async def return_tips96(self, allow_nonzero_volume: bool = False, **backend_kwar if tip_rack is None: raise RuntimeError("No tips have been picked up with the 96 head") return await self.drop_tips96( - tip_rack, allow_nonzero_volume=allow_nonzero_volume, **backend_kwargs + tip_rack, + allow_nonzero_volume=allow_nonzero_volume, + **backend_kwargs, ) async def discard_tips96(self, allow_nonzero_volume: bool = True, **backend_kwargs): @@ -1308,7 +1440,7 @@ async def discard_tips96(self, allow_nonzero_volume: bool = True, **backend_kwar Examples: Discard the tips on the 96 head: - >>> lh.discard_tips96() + >>> await lh.discard_tips96() Args: allow_nonzero_volume: If `True`, the tip will be dropped even if its volume is not zero (there @@ -1321,7 +1453,9 @@ async def discard_tips96(self, allow_nonzero_volume: bool = True, **backend_kwar """ return await self.drop_tips96( - self.deck.get_trash_area96(), allow_nonzero_volume=allow_nonzero_volume, **backend_kwargs + self.deck.get_trash_area96(), + allow_nonzero_volume=allow_nonzero_volume, + **backend_kwargs, ) async def aspirate96( @@ -1338,8 +1472,8 @@ async def aspirate96( Examples: Aspirate an entire 96 well plate or a container of sufficient size: - >>> lh.aspirate96(plate, volume=50) - >>> lh.aspirate96(container, volume=50) + >>> await lh.aspirate96(plate, volume=50) + >>> await lh.aspirate96(container, volume=50) Args: resource (Union[Plate, Container, List[Well]]): Resource object or list of wells. @@ -1359,19 +1493,22 @@ async def aspirate96( ): raise TypeError(f"Resource must be a Plate, Container, or list of Wells, got {resource}") - extras = self._check_args(self.backend.aspirate96, backend_kwargs, default={"aspiration"}) + extras = self._check_args( + self.backend.aspirate96, backend_kwargs, default={"aspiration"}, strictness=get_strictness() + ) for extra in extras: del backend_kwargs[extra] tips = [channel.get_tip() for channel in self.head96.values()] all_liquids: List[List[Tuple[Optional[Liquid], float]]] = [] - aspiration: Union[AspirationPlate, AspirationContainer] + aspiration: Union[MultiHeadAspirationPlate, MultiHeadAspirationContainer] # Convert everything to floats to handle exotic number types volume = float(volume) flow_rate = float(flow_rate) if flow_rate is not None else None blow_out_air_volume = float(blow_out_air_volume) if blow_out_air_volume is not None else None + containers: Sequence[Container] if isinstance(resource, Container): if ( resource.get_absolute_size_x() < 108.0 or resource.get_absolute_size_y() < 70.0 @@ -1392,7 +1529,7 @@ async def aspirate96( for liquid, vol in reversed(liquids): channel.get_tip().tracker.add_liquid(liquid=liquid, volume=vol) - aspiration = AspirationContainer( + aspiration = MultiHeadAspirationContainer( container=resource, volume=volume, offset=offset, @@ -1402,24 +1539,26 @@ async def aspirate96( blow_out_air_volume=blow_out_air_volume, liquids=cast(List[List[Tuple[Optional[Liquid], float]]], all_liquids), # stupid ) + + containers = [resource] else: if isinstance(resource, Plate): if resource.has_lid(): raise ValueError("Aspirating from plate with lid") - wells = resource.get_all_items() + containers = resource.get_all_items() else: - wells = resource + containers = resource # ensure that wells are all in the same plate - plate = wells[0].parent - for well in wells: + plate = containers[0].parent + for well in containers: if well.parent != plate: raise ValueError("All wells must be in the same plate") - if not len(wells) == 96: - raise ValueError(f"aspirate96 expects 96 wells, got {len(wells)}") + if not len(containers) == 96: + raise ValueError(f"aspirate96 expects 96 wells, got {len(containers)}") - for well, channel in zip(wells, self.head96.values()): + for well, channel in zip(containers, self.head96.values()): # superfluous to have append in two places but the type checker is very angry and does not # understand that Optional[Liquid] (remove_liquid) is the same as None from the first case if well.tracker.is_disabled or not does_volume_tracking(): @@ -1432,8 +1571,8 @@ async def aspirate96( for liquid, vol in reversed(liquids): channel.get_tip().tracker.add_liquid(liquid=liquid, volume=vol) - aspiration = AspirationPlate( - wells=wells, + aspiration = MultiHeadAspirationPlate( + wells=cast(List[Well], containers), volume=volume, offset=offset, flow_rate=flow_rate, @@ -1445,10 +1584,10 @@ async def aspirate96( try: await self.backend.aspirate96(aspiration=aspiration, **backend_kwargs) - except Exception as error: # pylint: disable=broad-except - for channel, well in zip(self.head96.values(), wells): - if does_volume_tracking() and not well.tracker.is_disabled: - well.tracker.rollback() + except Exception as error: + for channel, container in zip(self.head96.values(), containers): + if does_volume_tracking() and not container.tracker.is_disabled: + container.tracker.rollback() channel.get_tip().tracker.rollback() self._trigger_callback( "aspirate96", @@ -1458,10 +1597,11 @@ async def aspirate96( **backend_kwargs, ) else: - for channel, well in zip(self.head96.values(), wells): - if does_volume_tracking() and not well.tracker.is_disabled: - well.tracker.commit() - channel.get_tip().tracker.commit() + for channel, container in zip(self.head96.values(), containers): + if does_volume_tracking() and not container.tracker.is_disabled: + container.tracker.commit() + channel.get_tip().tracker.commit() + self._trigger_callback( "aspirate96", liquid_handler=self, @@ -1484,7 +1624,7 @@ async def dispense96( Examples: Dispense an entire 96 well plate: - >>> lh.dispense96(plate, volume=50) + >>> await lh.dispense96(plate, volume=50) Args: resource (Union[Plate, Container, List[Well]]): Resource object or list of wells. @@ -1504,19 +1644,22 @@ async def dispense96( ): raise TypeError(f"Resource must be a Plate, Container, or list of Wells, got {resource}") - extras = self._check_args(self.backend.dispense96, backend_kwargs, default={"dispense"}) + extras = self._check_args( + self.backend.dispense96, backend_kwargs, default={"dispense"}, strictness=get_strictness() + ) for extra in extras: del backend_kwargs[extra] tips = [channel.get_tip() for channel in self.head96.values()] all_liquids: List[List[Tuple[Optional[Liquid], float]]] = [] - dispense: Union[DispensePlate, DispenseContainer] + dispense: Union[MultiHeadDispensePlate, MultiHeadDispenseContainer] # Convert everything to floats to handle exotic number types volume = float(volume) flow_rate = float(flow_rate) if flow_rate is not None else None blow_out_air_volume = float(blow_out_air_volume) if blow_out_air_volume is not None else None + containers: Sequence[Container] if isinstance(resource, Container): if ( resource.get_absolute_size_x() < 108.0 or resource.get_absolute_size_y() < 70.0 @@ -1526,18 +1669,18 @@ async def dispense96( for channel in self.head96.values(): # superfluous to have append in two places but the type checker is very angry and does not # understand that Optional[Liquid] (remove_liquid) is the same as None from the first case - liquids: List[Tuple[Optional[Liquid], float]] + reversed_liquids: List[Tuple[Optional[Liquid], float]] if resource.tracker.is_disabled or not does_volume_tracking(): - liquids = [(None, volume)] - all_liquids.append(liquids) + reversed_liquids = [(None, volume)] + all_liquids.append(reversed_liquids) else: - liquids = resource.tracker.remove_liquid(volume=volume) # type: ignore - all_liquids.append(liquids) + reversed_liquids = resource.tracker.remove_liquid(volume=volume) # type: ignore + all_liquids.append(reversed_liquids) - for liquid, vol in reversed(liquids): + for liquid, vol in reversed(reversed_liquids): channel.get_tip().tracker.add_liquid(liquid=liquid, volume=vol) - dispense = DispenseContainer( + dispense = MultiHeadDispenseContainer( container=resource, volume=volume, offset=offset, @@ -1547,35 +1690,37 @@ async def dispense96( blow_out_air_volume=blow_out_air_volume, liquids=cast(List[List[Tuple[Optional[Liquid], float]]], all_liquids), # stupid ) + + containers = [resource] else: if isinstance(resource, Plate): if resource.has_lid(): raise ValueError("Aspirating from plate with lid") - wells = resource.get_all_items() - else: - wells = resource + containers = resource.get_all_items() + else: # List[Well] + containers = resource # ensure that wells are all in the same plate - plate = wells[0].parent - for well in wells: + plate = containers[0].parent + for well in containers: if well.parent != plate: raise ValueError("All wells must be in the same plate") - if not len(wells) == 96: - raise ValueError(f"dispense96 expects 96 wells, got {len(wells)}") + if not len(containers) == 96: + raise ValueError(f"dispense96 expects 96 wells, got {len(containers)}") - for channel, well in zip(self.head96.values(), wells): + for channel, well in zip(self.head96.values(), containers): # even if the volume tracker is disabled, a liquid (None, volume) is added to the list # during the aspiration command - l = channel.get_tip().tracker.remove_liquid(volume=volume) - liquids = list(reversed(l)) - all_liquids.append(liquids) + liquids = channel.get_tip().tracker.remove_liquid(volume=volume) + reversed_liquids = list(reversed(liquids)) + all_liquids.append(reversed_liquids) - for liquid, vol in liquids: + for liquid, vol in reversed_liquids: well.tracker.add_liquid(liquid=liquid, volume=vol) - dispense = DispensePlate( - wells=wells, + dispense = MultiHeadDispensePlate( + wells=cast(List[Well], containers), volume=volume, offset=offset, flow_rate=flow_rate, @@ -1587,10 +1732,10 @@ async def dispense96( try: await self.backend.dispense96(dispense=dispense, **backend_kwargs) - except Exception as error: # pylint: disable=broad-except - for channel, well in zip(self.head96.values(), wells): + except Exception as error: + for channel, container in zip(self.head96.values(), containers): if does_volume_tracking() and not well.tracker.is_disabled: - well.tracker.rollback() + container.tracker.rollback() channel.get_tip().tracker.rollback() self._trigger_callback( @@ -1601,9 +1746,9 @@ async def dispense96( **backend_kwargs, ) else: - for channel, well in zip(self.head96.values(), wells): + for channel, container in zip(self.head96.values(), containers): if does_volume_tracking() and not well.tracker.is_disabled: - well.tracker.commit() + container.tracker.commit() channel.get_tip().tracker.commit() self._trigger_callback( @@ -1642,16 +1787,207 @@ async def stamp( await self.aspirate96(resource=source, volume=volume, flow_rate=aspiration_flow_rate) await self.dispense96(resource=source, volume=volume, flow_rate=dispense_flow_rate) - async def move_resource( + async def pick_up_resource( self, resource: Resource, + offset: Coordinate = Coordinate.zero(), + pickup_distance_from_top: float = 0, + direction: GripDirection = GripDirection.FRONT, + **backend_kwargs, + ): + if self._resource_pickup is not None: + raise RuntimeError(f"Resource {self._resource_pickup.resource.name} already picked up") + + self._resource_pickup = ResourcePickup( + resource=resource, + offset=offset, + pickup_distance_from_top=pickup_distance_from_top, + direction=direction, + ) + + extras = self._check_args( + self.backend.pick_up_resource, backend_kwargs, default={"pickup"}, strictness=get_strictness() + ) + for extra in extras: + del backend_kwargs[extra] + + try: + await self.backend.pick_up_resource( + pickup=self._resource_pickup, + **backend_kwargs, + ) + except Exception as e: + self._resource_pickup = None + raise e + + async def move_picked_up_resource( + self, to: Coordinate, + ): + if self._resource_pickup is None: + raise RuntimeError("No resource picked up") + await self.backend.move_picked_up_resource( + ResourceMove( + location=to, + resource=self._resource_pickup.resource, + gripped_direction=self._resource_pickup.direction, + ) + ) + + async def drop_resource( + self, + destination: Union[ResourceStack, ResourceHolder, Resource, Coordinate], + offset: Coordinate = Coordinate.zero(), + direction: GripDirection = GripDirection.FRONT, + **backend_kwargs, + ): + if self._resource_pickup is None: + raise RuntimeError("No resource picked up") + resource = self._resource_pickup.resource + + # compute rotation based on the pickup_direction and drop_direction + if self._resource_pickup.direction == direction: + rotation_applied_by_move = 0 + if (self._resource_pickup.direction, direction) in ( + (GripDirection.FRONT, GripDirection.RIGHT), + (GripDirection.RIGHT, GripDirection.BACK), + (GripDirection.BACK, GripDirection.LEFT), + (GripDirection.LEFT, GripDirection.FRONT), + ): + rotation_applied_by_move = 90 + if (self._resource_pickup.direction, direction) in ( + (GripDirection.FRONT, GripDirection.BACK), + (GripDirection.BACK, GripDirection.FRONT), + (GripDirection.LEFT, GripDirection.RIGHT), + (GripDirection.RIGHT, GripDirection.LEFT), + ): + rotation_applied_by_move = 180 + if (self._resource_pickup.direction, direction) in ( + (GripDirection.RIGHT, GripDirection.FRONT), + (GripDirection.BACK, GripDirection.RIGHT), + (GripDirection.LEFT, GripDirection.BACK), + (GripDirection.FRONT, GripDirection.LEFT), + ): + rotation_applied_by_move = 270 + + # the resource's absolute rotation should be the resource's previous rotation plus the + # rotation the move applied. The resource's absolute rotation is the rotation of the + # new parent plus the resource's rotation relative to the parent. So to find the new + # rotation of the resource wrt its new parent, we compute what the new absolute rotation + # should be and subtract the rotation of the new parent. + + # moving from a resource from a rotated parent to a non-rotated parent means child inherits/'houses' the rotation after move + resource_absolute_rotation_after_move = ( + resource.get_absolute_rotation().z + rotation_applied_by_move + ) + destination_rotation = ( + destination.get_absolute_rotation().z if not isinstance(destination, Coordinate) else 0 + ) + resource_rotation_wrt_destination = resource_absolute_rotation_after_move - destination_rotation + + # `get_default_child_location`, which is used to compute the translation of the child wrt the parent, + # only considers the child's local rotation. In order to set this new child rotation locally for the + # translation computation, we have to subtract the current rotation of the resource, so we can use + # resource.rotated(z=resource_rotation_wrt_destination_wrt_local) to 'set' the new local rotation. + # Remember, rotated() applies the rotation on top of the current rotation. <- TODO: stupid + resource_rotation_wrt_destination_wrt_local = ( + resource_rotation_wrt_destination - resource.rotation.z + ) + + # get the location of the destination + if isinstance(destination, ResourceStack): + assert ( + destination.direction == "z" + ), "Only ResourceStacks with direction 'z' are currently supported" + to_location = destination.get_absolute_location(z="top") + elif isinstance(destination, Coordinate): + to_location = destination + elif isinstance(destination, ResourceHolder): + if destination.resource is not None and destination.resource is not resource: + raise RuntimeError("Destination already has a plate") + child_wrt_parent = destination.get_default_child_location( + resource.rotated(z=resource_rotation_wrt_destination_wrt_local) + ).rotated(destination.get_absolute_rotation()) + to_location = (destination.get_absolute_location()) + child_wrt_parent + elif isinstance(destination, PlateAdapter): + if not isinstance(resource, Plate): + raise ValueError("Only plates can be moved to a PlateAdapter") + # Calculate location adjustment of Plate based on PlateAdapter geometry + adjusted_plate_anchor = destination.compute_plate_location( + resource.rotated(z=resource_rotation_wrt_destination_wrt_local) + ).rotated(destination.get_absolute_rotation()) + to_location = destination.get_absolute_location() + adjusted_plate_anchor + elif isinstance(destination, Plate) and isinstance(resource, Lid): + lid = resource + plate_location = destination.get_absolute_location() + child_wrt_parent = destination.get_lid_location( + lid.rotated(z=resource_rotation_wrt_destination_wrt_local) + ).rotated(destination.get_absolute_rotation()) + to_location = plate_location + child_wrt_parent + else: + to_location = destination.get_absolute_location() + + drop = ResourceDrop( + resource=self._resource_pickup.resource, + destination=to_location, + destination_absolute_rotation=destination.get_absolute_rotation() + if isinstance(destination, Resource) + else Rotation(0, 0, 0), + offset=offset, + pickup_distance_from_top=self._resource_pickup.pickup_distance_from_top, + pickup_direction=self._resource_pickup.direction, + drop_direction=direction, + rotation=rotation_applied_by_move, + ) + result = await self.backend.drop_resource(drop=drop, **backend_kwargs) + + # we rotate the resource on top of its original rotation. So in order to set the new rotation, + # we have to subtract its current rotation. + resource.rotate(z=resource_rotation_wrt_destination - resource.rotation.z) + + # assign to destination + resource.unassign() + if isinstance(destination, Coordinate): + to_location -= self.deck.location # passed as an absolute location, but stored as relative + self.deck.assign_child_resource(resource, location=to_location) + elif isinstance(destination, PlateHolder): # .zero() resources + destination.assign_child_resource(resource) + elif isinstance(destination, ResourceHolder): # .zero() resources + destination.assign_child_resource(resource) + elif isinstance(destination, (ResourceStack, PlateReader)): # manage its own resources + if isinstance(destination, ResourceStack) and destination.direction != "z": + raise ValueError("Only ResourceStacks with direction 'z' are currently supported") + destination.assign_child_resource(resource) + elif isinstance(destination, Tilter): + destination.assign_child_resource(resource, location=destination.child_location) + elif isinstance(destination, PlateAdapter): + if not isinstance(resource, Plate): + raise ValueError("Only plates can be moved to a PlateAdapter") + destination.assign_child_resource( + resource, location=destination.compute_plate_location(resource) + ) + elif isinstance(destination, Plate) and isinstance(resource, Lid): + destination.assign_child_resource(resource) + else: + destination.assign_child_resource(resource, location=to_location) + + self._resource_pickup = None + + return result + + async def move_resource( + self, + resource: Resource, + to: Union[ResourceStack, ResourceHolder, Resource, Coordinate], intermediate_locations: Optional[List[Coordinate]] = None, - resource_offset: Coordinate = Coordinate.zero(), + resource_offset: Optional[Coordinate] = None, + pickup_offset: Coordinate = Coordinate.zero(), destination_offset: Coordinate = Coordinate.zero(), pickup_distance_from_top: float = 0, - get_direction: GripDirection = GripDirection.FRONT, - put_direction: GripDirection = GripDirection.FRONT, + pickup_direction: GripDirection = GripDirection.FRONT, + drop_direction: GripDirection = GripDirection.FRONT, + get_direction: Optional[GripDirection] = None, + put_direction: Optional[GripDirection] = None, **backend_kwargs, ): """Move a resource to a new location. @@ -1661,63 +1997,76 @@ async def move_resource( Examples: Move a plate to a new location: - >>> lh.move_resource(plate, to=Coordinate(100, 100, 100)) + >>> await lh.move_resource(plate, to=Coordinate(100, 100, 100)) Args: resource: The Resource object. to: The absolute coordinate (meaning relative to deck) to move the resource to. intermediate_locations: A list of intermediate locations to move the resource through. - resource_offset: The offset from the resource's origin, optional (rarely necessary). + pickup_offset: The offset from the resource's origin, optional (rarely necessary). destination_offset: The offset from the location's origin, optional (rarely necessary). pickup_distance_from_top: The distance from the top of the resource to pick up from. - get_direction: The direction from which to pick up the resource. - put_direction: The direction from which to put down the resource. + pickup_direction: The direction from which to pick up the resource. + drop_direction: The direction from which to put down the resource. """ # TODO: move conditional statements from move_plate into move_resource to enable # movement to other types besides Coordinate - extras = self._check_args(self.backend.move_resource, backend_kwargs, default={"move"}) - for extra in extras: - del backend_kwargs[extra] + # https://github.com/PyLabRobot/pylabrobot/issues/329 + if resource_offset is not None: + raise NotImplementedError("resource_offset is deprecated, use pickup_offset instead") + if get_direction is not None: + raise NotImplementedError("get_direction is deprecated, use pickup_direction instead") + if put_direction is not None: + raise NotImplementedError("put_direction is deprecated, use drop_direction instead") + + extra = self._check_args( + self.backend.pick_up_resource, + backend_kwargs, + default={"pickup"}, + strictness=Strictness.IGNORE, + ) + pickup_kwargs = {k: v for k, v in backend_kwargs.items() if k not in extra} - move_operation = Move( + await self.pick_up_resource( resource=resource, - destination=to, - intermediate_locations=intermediate_locations or [], - resource_offset=resource_offset, - destination_offset=destination_offset, + offset=pickup_offset, pickup_distance_from_top=pickup_distance_from_top, - get_direction=get_direction, - put_direction=put_direction, + direction=pickup_direction, + **pickup_kwargs, ) - result = await self.backend.move_resource(move=move_operation, **backend_kwargs) + for intermediate_location in intermediate_locations or []: + await self.move_picked_up_resource(to=intermediate_location) - # rotate the resource if the move operation has a rotation. - # this code should be expanded to also update the resource's location - if move_operation.rotation != 0: - move_operation.resource.rotate(z=move_operation.rotation) - - self._trigger_callback( - "move_resource", - liquid_handler=self, - move=move_operation, - error=None, - **backend_kwargs, + extra = self._check_args( + self.backend.drop_resource, + backend_kwargs, + default={"drop"}, + strictness=Strictness.IGNORE, ) + drop_kwargs = {k: v for k, v in backend_kwargs.items() if k not in extra} - return result + await self.drop_resource( + destination=to, + offset=destination_offset, + direction=drop_direction, + **drop_kwargs, + ) async def move_lid( self, lid: Lid, to: Union[Plate, ResourceStack, Coordinate], intermediate_locations: Optional[List[Coordinate]] = None, - resource_offset: Coordinate = Coordinate.zero(), + resource_offset: Optional[Coordinate] = None, + pickup_offset: Coordinate = Coordinate.zero(), destination_offset: Coordinate = Coordinate.zero(), - get_direction: GripDirection = GripDirection.FRONT, - put_direction: GripDirection = GripDirection.FRONT, + pickup_direction: GripDirection = GripDirection.FRONT, + drop_direction: GripDirection = GripDirection.FRONT, + get_direction: Optional[GripDirection] = None, + put_direction: Optional[GripDirection] = None, pickup_distance_from_top: float = 5.7 - 3.33, **backend_kwargs, ): @@ -1728,69 +2077,55 @@ async def move_lid( Examples: Move a lid to the :class:`~resources.ResourceStack`: - >>> lh.move_lid(plate.lid, stacking_area) + >>> await lh.move_lid(plate.lid, stacking_area) Move a lid to the stacking area and back, grabbing it from the left side: - >>> lh.move_lid(plate.lid, stacking_area, get_direction=GripDirection.LEFT) - >>> lh.move_lid(stacking_area.get_top_item(), plate, put_direction=GripDirection.LEFT) + >>> await lh.move_lid(plate.lid, stacking_area, pickup_direction=GripDirection.LEFT) + >>> await lh.move_lid(stacking_area.get_top_item(), plate, drop_direction=GripDirection.LEFT) Args: lid: The lid to move. Can be either a Plate object or a Lid object. to: The location to move the lid to, either a plate, ResourceStack or a Coordinate. - resource_offset: The offset from the resource's origin, optional (rarely necessary). + pickup_offset: The offset from the resource's origin, optional (rarely necessary). destination_offset: The offset from the location's origin, optional (rarely necessary). Raises: ValueError: If the lid is not assigned to a resource. """ - if isinstance(to, Plate): - to_location = to.get_absolute_location() - to_location = Coordinate( - x=to_location.x, - y=to_location.y, - z=to_location.z + to.get_absolute_size_z() - lid.nesting_z_height, - ) - elif isinstance(to, ResourceStack): - assert to.direction == "z", "Only ResourceStacks with direction 'z' are currently supported" - to_location = to.get_absolute_location(z="top") - elif isinstance(to, Coordinate): - to_location = to - else: - raise ValueError(f"Cannot move lid to {to}") + # https://github.com/PyLabRobot/pylabrobot/issues/329 + if resource_offset is not None: + raise NotImplementedError("resource_offset is deprecated, use pickup_offset instead") + if get_direction is not None: + raise NotImplementedError("get_direction is deprecated, use pickup_direction instead") + if put_direction is not None: + raise NotImplementedError("put_direction is deprecated, use drop_direction instead") await self.move_resource( lid, - to=to_location, + to=to, intermediate_locations=intermediate_locations, pickup_distance_from_top=pickup_distance_from_top, - resource_offset=resource_offset, + pickup_offset=pickup_offset, destination_offset=destination_offset, - get_direction=get_direction, - put_direction=put_direction, + pickup_direction=pickup_direction, + drop_direction=drop_direction, **backend_kwargs, ) - lid.unassign() - if isinstance(to, Coordinate): - self.deck.assign_child_resource(lid, location=to_location) - elif isinstance(to, ResourceStack): # manage its own resources - to.assign_child_resource(lid) - elif isinstance(to, Plate): - to.assign_child_resource(resource=lid) - else: - raise ValueError("'to' must be either a Coordinate, ResourceStack or Plate") - async def move_plate( self, plate: Plate, - to: Union[ResourceStack, CarrierSite, Resource, Coordinate], + to: Union[ResourceStack, ResourceHolder, Resource, Coordinate], intermediate_locations: Optional[List[Coordinate]] = None, - resource_offset: Coordinate = Coordinate.zero(), + resource_offset: Optional[Coordinate] = None, + pickup_offset: Coordinate = Coordinate.zero(), destination_offset: Coordinate = Coordinate.zero(), - put_direction: GripDirection = GripDirection.FRONT, - get_direction: GripDirection = GripDirection.FRONT, + drop_direction: GripDirection = GripDirection.FRONT, + pickup_direction: GripDirection = GripDirection.FRONT, + get_direction: Optional[GripDirection] = None, + put_direction: Optional[GripDirection] = None, pickup_distance_from_top: float = 13.2 - 3.33, **backend_kwargs, ): @@ -1801,96 +2136,51 @@ async def move_plate( Examples: Move a plate to into a carrier spot: - >>> lh.move_plate(plate, plt_car[1]) + >>> await lh.move_plate(plate, plt_car[1]) Move a plate to an absolute location: - >>> lh.move_plate(plate_01, Coordinate(100, 100, 100)) + >>> await lh.move_plate(plate_01, Coordinate(100, 100, 100)) Move a lid to another carrier spot, grabbing it from the left side: - >>> lh.move_plate(plate, plt_car[1], get_direction=GripDirection.LEFT) - >>> lh.move_plate(plate, plt_car[0], put_direction=GripDirection.LEFT) + >>> await lh.move_plate(plate, plt_car[1], pickup_direction=GripDirection.LEFT) + >>> await lh.move_plate(plate, plt_car[0], drop_direction=GripDirection.LEFT) Move a resource while visiting a few intermediate locations along the way: - >>> lh.move_plate(plate, plt_car[1], intermediate_locations=[ + >>> await lh.move_plate(plate, plt_car[1], intermediate_locations=[ ... Coordinate(100, 100, 100), ... Coordinate(200, 200, 200), ... ]) Args: - plate: The plate to move. Can be either a Plate object or a CarrierSite object. - to: The location to move the plate to, either a plate, CarrierSite or a Coordinate. - resource_offset: The offset from the resource's origin, optional (rarely necessary). + plate: The plate to move. Can be either a Plate object or a ResourceHolder object. + to: The location to move the plate to, either a plate, ResourceHolder or a Coordinate. + pickup_offset: The offset from the resource's origin, optional (rarely necessary). destination_offset: The offset from the location's origin, optional (rarely necessary). """ - if isinstance(to, ResourceStack): - assert to.direction == "z", "Only ResourceStacks with direction 'z' are currently supported" - to_location = to.get_absolute_location(z="top") - elif isinstance(to, Coordinate): - to_location = to - elif isinstance(to, (MFXModule, Tilter)): - to_location = to.get_absolute_location() + to.child_resource_location - elif isinstance(to, PlateCarrierSite): - to_location = to.get_absolute_location() - # Sanity check for equal well clearances / dz - well_dz_set = { - round(well.location.z, 2) - for well in plate.get_all_children() - if well.category == "well" and well.location is not None - } - assert len(well_dz_set) == 1, "All wells must have the same dz" - well_dz = well_dz_set.pop() - # Plate "sinking" logic based on well dz to pedestal relationship - # 1. no pedestal - # 2. pedestal taller than plate.well.dz - # 3. pedestal shorter than plate.well.dz - pedestal_size_z = abs(to.pedestal_size_z) - z_sinking_depth = min(pedestal_size_z, well_dz) - correction_anchor = Coordinate(0, 0, -z_sinking_depth) - to_location += correction_anchor - elif isinstance(to, PlateAdapter): - # Calculate location adjustment of Plate based on PlateAdapter geometry - adjusted_plate_anchor = to.compute_plate_location(plate) - to_location = to.get_absolute_location() + adjusted_plate_anchor - else: - to_location = to.get_absolute_location() + # https://github.com/PyLabRobot/pylabrobot/issues/329 + if resource_offset is not None: + raise NotImplementedError("resource_offset is deprecated, use pickup_offset instead") + if get_direction is not None: + raise NotImplementedError("get_direction is deprecated, use pickup_direction instead") + if put_direction is not None: + raise NotImplementedError("put_direction is deprecated, use drop_direction instead") await self.move_resource( plate, - to=to_location, + to=to, intermediate_locations=intermediate_locations, pickup_distance_from_top=pickup_distance_from_top, - resource_offset=resource_offset, + pickup_offset=pickup_offset, destination_offset=destination_offset, - get_direction=get_direction, - put_direction=put_direction, + pickup_direction=pickup_direction, + drop_direction=drop_direction, **backend_kwargs, ) - # Some of the code below should probably be moved to `move_resource` so that is can be shared - # with the `move_lid` convenience method. - plate.unassign() - if isinstance(to, Coordinate): - to_location -= self.deck.location # passed as an absolute location, but stored as relative - self.deck.assign_child_resource(plate, location=to_location) - elif isinstance(to, PlateCarrierSite): # .zero() resources - to.assign_child_resource(plate) - elif isinstance(to, CarrierSite): # .zero() resources - to.assign_child_resource(plate) - elif isinstance(to, (ResourceStack, PlateReader)): # manage its own resources - if isinstance(to, ResourceStack) and to.direction != "z": - raise ValueError("Only ResourceStacks with direction 'z' are currently supported") - to.assign_child_resource(plate) - elif isinstance(to, (MFXModule, Tilter)): - to.assign_child_resource(plate, location=to.child_resource_location) - elif isinstance(to, PlateAdapter): - to.assign_child_resource(plate, location=to.compute_plate_location(plate)) - else: - to.assign_child_resource(plate, location=to_location) - def register_callback(self, method_name: str, callback: OperationCallback): """Registers a callback for a specific method.""" if method_name in self._callbacks: @@ -1901,7 +2191,13 @@ def register_callback(self, method_name: str, callback: OperationCallback): raise RuntimeError(error_message) self._callbacks[method_name] = callback - def _trigger_callback(self, method_name: str, *args, error: Optional[Exception] = None, **kwargs): + def _trigger_callback( + self, + method_name: str, + *args, + error: Optional[Exception] = None, + **kwargs, + ): """Triggers the callback associated with a method, if any. NB: If an error exists it will be passed to the callback instead of being raised. @@ -1915,6 +2211,9 @@ def _trigger_callback(self, method_name: str, *args, error: Optional[Exception] def callbacks(self): return self._callbacks + def serialize(self): + return {**Resource.serialize(self), **Machine.serialize(self)} + @classmethod def deserialize(cls, data: dict, allow_marshal: bool = False) -> LiquidHandler: """Deserialize a liquid handler from a dictionary. @@ -1939,12 +2238,31 @@ def load(cls, path: str) -> LiquidHandler: with open(path, "r", encoding="utf-8") as f: return cls.deserialize(json.load(f)) + async def prepare_for_manual_channel_operation(self, channel: int): + assert 0 <= channel < self.backend.num_channels, f"Invalid channel: {channel}" + await self.backend.prepare_for_manual_channel_operation(channel=channel) + + async def move_channel_x(self, channel: int, x: float): + """Move channel to absolute x position""" + assert 0 <= channel < self.backend.num_channels, f"Invalid channel: {channel}" + await self.backend.move_channel_x(channel=channel, x=x) + + async def move_channel_y(self, channel: int, y: float): + """Move channel to absolute y position""" + assert 0 <= channel < self.backend.num_channels, f"Invalid channel: {channel}" + await self.backend.move_channel_y(channel=channel, y=y) + + async def move_channel_z(self, channel: int, z: float): + """Move channel to absolute z position""" + assert 0 <= channel < self.backend.num_channels, f"Invalid channel: {channel}" + await self.backend.move_channel_z(channel=channel, z=z) + # -- Resource methods -- def assign_child_resource( self, resource: Resource, - location: Coordinate, + location: Optional[Coordinate], reassign: bool = True, ): """Not implement on LiquidHandler, since the deck is managed by the :attr:`deck` attribute.""" From bc1ee194a616079c76868cdd0f112396ba696a92 Mon Sep 17 00:00:00 2001 From: Rick Wierenga Date: Tue, 25 Mar 2025 14:13:42 -0700 Subject: [PATCH 18/18] the actual changes? --- .../liquid_handling/backends/hamilton/STAR.py | 323 ++++-------------- .../backends/hamilton/STAR_tests.py | 76 ++++- .../backends/hamilton/vantage.py | 222 +++--------- .../backends/hamilton/vantage_tests.py | 101 +++--- 4 files changed, 236 insertions(+), 486 deletions(-) diff --git a/pylabrobot/liquid_handling/backends/hamilton/STAR.py b/pylabrobot/liquid_handling/backends/hamilton/STAR.py index 0c8e403a5e..7070626aa3 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/STAR.py +++ b/pylabrobot/liquid_handling/backends/hamilton/STAR.py @@ -23,10 +23,7 @@ HamiltonLiquidHandler, ) from pylabrobot.liquid_handling.errors import ChannelizedError -from pylabrobot.liquid_handling.liquid_classes.hamilton import ( - HamiltonLiquidClass, - get_star_liquid_class, -) +from pylabrobot.liquid_handling.liquid_classes.hamilton import HamiltonLiquidClass from pylabrobot.liquid_handling.standard import ( Drop, DropTipRack, @@ -71,7 +68,6 @@ STAR_SIZE_X, STARLET_SIZE_X, ) -from pylabrobot.resources.liquid import Liquid from pylabrobot.resources.rotation import Rotation from pylabrobot.resources.trash import Trash @@ -1597,8 +1593,6 @@ async def aspirate( self, ops: List[SingleChannelAspiration], use_channels: List[int], - jet: Optional[List[bool]] = None, - blow_out: Optional[List[bool]] = None, lld_search_height: Optional[List[float]] = None, clot_detection_height: Optional[List[float]] = None, pull_out_distance_transport_air: Optional[List[float]] = None, @@ -1645,9 +1639,6 @@ async def aspirate( Args: ops: The aspiration operations to perform. use_channels: The channels to use for the operations. - jet: whether to search for a jet liquid class. Only used on dispense. Default is False. - blow_out: whether to blow out air. Only used on dispense. Note that in the VENUS Liquid - Editor, this is called "empty". Default is False. lld_search_height: The height to start searching for the liquid level when using LLD. clot_detection_height: Unknown, but probably the height to search for clots when doing LLD. @@ -1696,49 +1687,19 @@ async def aspirate( starting an aspiration. min_z_endpos: The minimum height to move to, this is the end of aspiration. - hamilton_liquid_classes: Override the default liquid classes. See - pylabrobot/liquid_handling/liquid_classes/hamilton/star.py liquid_surface_no_lld: Liquid surface at function without LLD [mm]. Must be between 0 and 360. Defaults to well bottom + liquid height. Should use absolute z. """ + if hamilton_liquid_classes is not None: + raise NotImplementedError("Hamilton liquid classes are deprecated.") + x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) n = len(ops) - if jet is None: - jet = [False] * n - if blow_out is None: - blow_out = [False] * n - - if hamilton_liquid_classes is None: - hamilton_liquid_classes = [] - for i, op in enumerate(ops): - liquid = Liquid.WATER # default to WATER - # [-1][0]: get last liquid in well, [0] is indexing into the tuple - if len(op.liquids) > 0 and op.liquids[-1][0] is not None: - liquid = op.liquids[-1][0] - - hamilton_liquid_classes.append( - get_star_liquid_class( - tip_volume=op.tip.maximal_volume, - is_core=False, - is_tip=True, - has_filter=op.tip.has_filter, - liquid=liquid, - jet=jet[i], - blow_out=blow_out[i], - ) - ) - self._assert_valid_resources([op.resource for op in ops]) - # correct volumes using the liquid class - volumes = [ - hlc.compute_corrected_volume(op.volume) if hlc is not None else op.volume - for op, hlc in zip(ops, hamilton_liquid_classes) - ] - well_bottoms = [ op.resource.get_absolute_location().z + op.offset.z + op.resource.material_z_thickness for op in ops @@ -1755,13 +1716,7 @@ async def aspirate( ] else: lld_search_height = [(wb + sh) for wb, sh in zip(well_bottoms, lld_search_height)] - clot_detection_height = _fill_in_defaults( - clot_detection_height, - default=[ - hlc.aspiration_clot_retract_height if hlc is not None else 0 - for hlc in hamilton_liquid_classes - ], - ) + clot_detection_height = _fill_in_defaults(clot_detection_height, default=[0] * n) pull_out_distance_transport_air = _fill_in_defaults(pull_out_distance_transport_air, [10] * n) second_section_height = _fill_in_defaults(second_section_height, [3.2] * n) second_section_ratio = _fill_in_defaults(second_section_ratio, [618.0] * n) @@ -1770,21 +1725,9 @@ async def aspirate( immersion_depth = _fill_in_defaults(immersion_depth, [0] * n) immersion_depth_direction = _fill_in_defaults(immersion_depth_direction, [0] * n) surface_following_distance = _fill_in_defaults(surface_following_distance, [0] * n) - flow_rates = [ - op.flow_rate or (hlc.aspiration_flow_rate if hlc is not None else 100) - for op, hlc in zip(ops, hamilton_liquid_classes) - ] - transport_air_volume = _fill_in_defaults( - transport_air_volume, - default=[ - hlc.aspiration_air_transport_volume if hlc is not None else 0 - for hlc in hamilton_liquid_classes - ], - ) - blow_out_air_volumes = [ - (op.blow_out_air_volume or (hlc.aspiration_blow_out_volume if hlc is not None else 0)) - for op, hlc in zip(ops, hamilton_liquid_classes) - ] + flow_rates = [op.flow_rate or 100 for op in ops] + transport_air_volume = _fill_in_defaults(transport_air_volume, default=[0] * n) + blow_out_air_volumes = [op.blow_out_air_volume or 0 for op in ops] pre_wetting_volume = _fill_in_defaults(pre_wetting_volume, [0] * n) lld_mode = _fill_in_defaults(lld_mode, [self.__class__.LLDMode.OFF] * n) gamma_lld_sensitivity = _fill_in_defaults(gamma_lld_sensitivity, [1] * n) @@ -1795,27 +1738,12 @@ async def aspirate( detection_height_difference_for_dual_lld = _fill_in_defaults( detection_height_difference_for_dual_lld, [0] * n ) - swap_speed = _fill_in_defaults( - swap_speed, - default=[ - hlc.aspiration_swap_speed if hlc is not None else 100 for hlc in hamilton_liquid_classes - ], - ) - settling_time = _fill_in_defaults( - settling_time, - default=[ - hlc.aspiration_settling_time if hlc is not None else 0 for hlc in hamilton_liquid_classes - ], - ) + swap_speed = _fill_in_defaults(swap_speed, default=[100] * n) + settling_time = _fill_in_defaults(settling_time, default=[0] * n) mix_volume = _fill_in_defaults(mix_volume, [0] * n) mix_cycles = _fill_in_defaults(mix_cycles, [0] * n) mix_position_from_liquid_surface = _fill_in_defaults(mix_position_from_liquid_surface, [0] * n) - mix_speed = _fill_in_defaults( - mix_speed, - default=[ - hlc.aspiration_mix_flow_rate if hlc is not None else 50.0 for hlc in hamilton_liquid_classes - ], - ) + mix_speed = _fill_in_defaults(mix_speed, [50] * n) mix_surface_following_distance = _fill_in_defaults(mix_surface_following_distance, [0] * n) limit_curve_index = _fill_in_defaults(limit_curve_index, [0] * n) @@ -1842,7 +1770,7 @@ async def aspirate( tip_pattern=channels_involved, x_positions=x_positions, y_positions=y_positions, - aspiration_volumes=[round(vol * 10) for vol in volumes], + aspiration_volumes=[round(op.volume * 10) for op in ops], lld_search_height=[round(lsh * 10) for lsh in lld_search_height], clot_detection_height=[round(cd * 10) for cd in clot_detection_height], liquid_surface_no_lld=[round(ls * 10) for ls in liquid_surfaces_no_lld], @@ -1995,6 +1923,9 @@ async def dispense( documentation. Dispense mode 4. """ + if hamilton_liquid_classes is not None: + raise NotImplementedError("Hamilton liquid classes are deprecated.") + x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) n = len(ops) @@ -2006,32 +1937,6 @@ async def dispense( if blow_out is None: blow_out = [False] * n - if hamilton_liquid_classes is None: - hamilton_liquid_classes = [] - for i, op in enumerate(ops): - liquid = Liquid.WATER # default to WATER - # [-1][0]: get last liquid in tip, [0] is indexing into the tuple - if len(op.liquids) > 0 and op.liquids[-1][0] is not None: - liquid = op.liquids[-1][0] - - hamilton_liquid_classes.append( - get_star_liquid_class( - tip_volume=op.tip.maximal_volume, - is_core=False, - is_tip=True, - has_filter=op.tip.has_filter, - liquid=liquid, - jet=jet[i], - blow_out=blow_out[i], - ) - ) - - # correct volumes using the liquid class - volumes = [ - hlc.compute_corrected_volume(op.volume) if hlc is not None else op.volume - for op, hlc in zip(ops, hamilton_liquid_classes) - ] - well_bottoms = [ op.resource.get_absolute_location().z + op.offset.z + op.resource.material_z_thickness for op in ops @@ -2061,55 +1966,23 @@ async def dispense( immersion_depth = _fill_in_defaults(immersion_depth, [0] * n) immersion_depth_direction = _fill_in_defaults(immersion_depth_direction, [0] * n) surface_following_distance = _fill_in_defaults(surface_following_distance, [0] * n) - flow_rates = [ - op.flow_rate or (hlc.dispense_flow_rate if hlc is not None else 120) - for op, hlc in zip(ops, hamilton_liquid_classes) - ] + flow_rates = [op.flow_rate or 120 for op in ops] cut_off_speed = _fill_in_defaults(cut_off_speed, [5.0] * n) - stop_back_volume = _fill_in_defaults( - stop_back_volume, - default=[ - hlc.dispense_stop_back_volume if hlc is not None else 0 for hlc in hamilton_liquid_classes - ], - ) - transport_air_volume = _fill_in_defaults( - transport_air_volume, - default=[ - hlc.dispense_air_transport_volume if hlc is not None else 0 - for hlc in hamilton_liquid_classes - ], - ) - blow_out_air_volumes = [ - (op.blow_out_air_volume or (hlc.dispense_blow_out_volume if hlc is not None else 0)) - for op, hlc in zip(ops, hamilton_liquid_classes) - ] + stop_back_volume = _fill_in_defaults(stop_back_volume, default=[0] * n) + transport_air_volume = _fill_in_defaults(transport_air_volume, [0] * n) + blow_out_air_volumes = [op.blow_out_air_volume or 0 for op in ops] lld_mode = _fill_in_defaults(lld_mode, [self.__class__.LLDMode.OFF] * n) dispense_position_above_z_touch_off = _fill_in_defaults( dispense_position_above_z_touch_off, default=[0] * n ) gamma_lld_sensitivity = _fill_in_defaults(gamma_lld_sensitivity, [1] * n) dp_lld_sensitivity = _fill_in_defaults(dp_lld_sensitivity, [1] * n) - swap_speed = _fill_in_defaults( - swap_speed, - default=[ - hlc.dispense_swap_speed if hlc is not None else 10.0 for hlc in hamilton_liquid_classes - ], - ) - settling_time = _fill_in_defaults( - settling_time, - default=[ - hlc.dispense_settling_time if hlc is not None else 0 for hlc in hamilton_liquid_classes - ], - ) + swap_speed = _fill_in_defaults(swap_speed, [10.0] * n) + settling_time = _fill_in_defaults(settling_time, [0] * n) mix_volume = _fill_in_defaults(mix_volume, [0] * n) mix_cycles = _fill_in_defaults(mix_cycles, [0] * n) mix_position_from_liquid_surface = _fill_in_defaults(mix_position_from_liquid_surface, [0] * n) - mix_speed = _fill_in_defaults( - mix_speed, - default=[ - hlc.dispense_mix_flow_rate if hlc is not None else 50.0 for hlc in hamilton_liquid_classes - ], - ) + mix_speed = _fill_in_defaults(mix_speed, [50.0] * n) mix_surface_following_distance = _fill_in_defaults(mix_surface_following_distance, [0] * n) limit_curve_index = _fill_in_defaults(limit_curve_index, [0] * n) @@ -2119,7 +1992,7 @@ async def dispense( x_positions=x_positions, y_positions=y_positions, dispensing_mode=dispensing_modes, - dispense_volumes=[round(vol * 10) for vol in volumes], + dispense_volumes=[round(op.volume * 10) for op in ops], lld_search_height=[round(lsh * 10) for lsh in lld_search_height], liquid_surface_no_lld=[round(ls * 10) for ls in liquid_surfaces_no_lld], pull_out_distance_transport_air=[round(po * 10) for po in pull_out_distance_transport_air], @@ -2255,7 +2128,7 @@ async def aspirate96( mix_cycles: int = 0, mix_position_from_liquid_surface: float = 0, surface_following_distance_during_mix: float = 0, - speed_of_mix: float = 120.0, + mix_speed: float = 120.0, limit_curve_index: int = 0, ): """Aspirate using the Core96 head. @@ -2263,13 +2136,6 @@ async def aspirate96( Args: aspiration: The aspiration to perform. - jet: Whether to search for a jet liquid class. Only used on dispense. - blow_out: Whether to use "blow out" dispense mode. Only used on dispense. Note that this is - labelled as "empty" in the VENUS liquid editor, but "blow out" in the firmware - documentation. - hlc: The Hamiltonian liquid class to use. If `None`, the liquid class will be determined - automatically. - use_lld: If True, use gamma liquid level detection. If False, use liquid height. liquid_height: The height of the liquid above the bottom of the well, in millimeters. air_transport_retract_dist: The distance to retract after aspirating, in millimeters. @@ -2298,10 +2164,13 @@ async def aspirate96( liquid surface. surface_following_distance_during_mix: The distance to follow the liquid surface during mix. - speed_of_mix: The speed of mix. + mix_speed: The speed of mix. limit_curve_index: The index of the limit curve to use. """ + if hlc is not None: + raise NotImplementedError("Hamilton liquid classes are deprecated.") + assert self.core96_head_installed, "96 head must be installed" # get the first well and tip as representatives @@ -2316,57 +2185,27 @@ async def aspirate96( else: position = aspiration.container.get_absolute_location(y="b") + aspiration.offset - tip = aspiration.tips[0] - liquid_height = position.z + liquid_height - liquid_to_be_aspirated = Liquid.WATER - if len(aspiration.liquids[0]) > 0 and aspiration.liquids[0][0][0] is not None: - # [channel][liquid][PyLabRobot.resources.liquid.Liquid] - liquid_to_be_aspirated = aspiration.liquids[0][0][0] - hlc = hlc or get_star_liquid_class( - tip_volume=tip.maximal_volume, - is_core=True, - is_tip=True, - has_filter=tip.has_filter, - # get last liquid in pipette, first to be dispensed - liquid=liquid_to_be_aspirated, - jet=jet, - blow_out=blow_out, # see comment in method docstring - ) - - if hlc is not None: - volume = hlc.compute_corrected_volume(aspiration.volume) + if transport_air_volume is None: + transport_air_volume = 0 + if aspiration.blow_out_air_volume is None: + blow_out_air_volume = 0.0 else: - volume = aspiration.volume - - # Get better default values from the HLC if available - transport_air_volume = transport_air_volume or ( - hlc.aspiration_air_transport_volume if hlc is not None else 0 - ) - blow_out_air_volume = aspiration.blow_out_air_volume or ( - hlc.aspiration_blow_out_volume if hlc is not None else 0 - ) - flow_rate = aspiration.flow_rate or (hlc.aspiration_flow_rate if hlc is not None else 250) - swap_speed = swap_speed or (hlc.aspiration_swap_speed if hlc is not None else 100) - settling_time = settling_time or (hlc.aspiration_settling_time if hlc is not None else 0.5) - speed_of_mix = speed_of_mix or (hlc.aspiration_mix_flow_rate if hlc is not None else 10.0) + blow_out_air_volume = aspiration.blow_out_air_volume + if aspiration.flow_rate is None: + flow_rate = 250.0 + else: + flow_rate = aspiration.flow_rate + if swap_speed is None: + swap_speed = 100 + if settling_time is None: + settling_time = 0.5 + if mix_speed is None: + mix_speed = 10.0 channel_pattern = [True] * 12 * 8 - # Was this ever true? Just copied it over from pyhamilton. Could have something to do with - # the liquid classes and whether blow_out mode is enabled. - # # Unfortunately, `blow_out_air_volume` does not work correctly, so instead we aspirate air - # # manually. - # if blow_out_air_volume is not None and blow_out_air_volume > 0: - # await self.aspirate_core_96( - # x_position=int(position.x * 10), - # y_positions=int(position.y * 10), - # lld_mode=0, - # liquid_surface_at_function_without_lld=int((liquid_height + 30) * 10), - # aspiration_volumes=int(blow_out_air_volume * 10) - # ) - return await self.aspirate_core_96( x_position=round(position.x * 10), x_direction=0, @@ -2389,7 +2228,7 @@ async def aspirate96( liquid_surface_sink_distance_at_the_end_of_aspiration=round( liquid_surface_sink_distance_at_the_end_of_aspiration * 10 ), - aspiration_volumes=round(volume * 10), + aspiration_volumes=round(aspiration.volume * 10), aspiration_speed=round(flow_rate * 10), transport_air_volume=round(transport_air_volume * 10), blow_out_air_volume=round(blow_out_air_volume * 10), @@ -2402,7 +2241,7 @@ async def aspirate96( mix_cycles=mix_cycles, mix_position_from_liquid_surface=round(mix_position_from_liquid_surface * 10), surface_following_distance_during_mix=round(surface_following_distance_during_mix * 10), - speed_of_mix=round(speed_of_mix * 10), + mix_speed=round(mix_speed * 10), channel_pattern=channel_pattern, limit_curve_index=limit_curve_index, tadm_algorithm=False, @@ -2437,7 +2276,7 @@ async def dispense96( mixing_cycles: int = 0, mixing_position_from_liquid_surface: float = 0, surface_following_distance_during_mixing: float = 0, - speed_of_mixing: float = 120.0, + mix_speed: float = 120.0, limit_curve_index: int = 0, cut_off_speed: float = 5.0, stop_back_volume: float = 0, @@ -2473,12 +2312,15 @@ async def dispense96( mixing_cycles: Mixing cycles. mixing_position_from_liquid_surface: Mixing position from liquid surface, in mm. surface_following_distance_during_mixing: Surface following distance during mixing, in mm. - speed_of_mixing: Speed of mixing, in ul/s. + mix_speed: Speed of mixing, in ul/s. limit_curve_index: Limit curve index. cut_off_speed: Unknown. stop_back_volume: Unknown. """ + if hlc is not None: + raise NotImplementedError("Hamilton liquid classes are deprecated.") + assert self.core96_head_installed, "96 head must be installed" # get the first well and tip as representatives @@ -2492,42 +2334,27 @@ async def dispense96( ) else: position = dispense.container.get_absolute_location(y="b") + dispense.offset - tip = dispense.tips[0] liquid_height = position.z + liquid_height dispense_mode = _dispensing_mode_for_op(empty=empty, jet=jet, blow_out=blow_out) - liquid_to_be_dispensed = Liquid.WATER # default to water. - if len(dispense.liquids[0]) > 0 and dispense.liquids[0][-1][0] is not None: - # [channel][liquid][PyLabRobot.resources.liquid.Liquid] - liquid_to_be_dispensed = dispense.liquids[0][-1][0] - hlc = hlc or get_star_liquid_class( - tip_volume=tip.maximal_volume, - is_core=True, - is_tip=True, - has_filter=tip.has_filter, - # get last liquid in pipette, first to be dispensed - liquid=liquid_to_be_dispensed, - jet=jet, - blow_out=blow_out, # see comment in method docstring - ) - - if hlc is not None: - volume = hlc.compute_corrected_volume(dispense.volume) + if transport_air_volume is None: + transport_air_volume = 0 + if dispense.blow_out_air_volume is None: + blow_out_air_volume = 0.0 else: - volume = dispense.volume - - transport_air_volume = transport_air_volume or ( - hlc.dispense_air_transport_volume if hlc is not None else 0 - ) - blow_out_air_volume = dispense.blow_out_air_volume or ( - hlc.dispense_blow_out_volume if hlc is not None else 0 - ) - flow_rate = dispense.flow_rate or (hlc.dispense_flow_rate if hlc is not None else 120) - swap_speed = swap_speed or (hlc.dispense_swap_speed if hlc is not None else 100) - settling_time = settling_time or (hlc.dispense_settling_time if hlc is not None else 5) - speed_of_mixing = speed_of_mixing or (hlc.dispense_mix_flow_rate if hlc is not None else 100) + blow_out_air_volume = dispense.blow_out_air_volume + if dispense.flow_rate is None: + flow_rate = 120.0 + else: + flow_rate = dispense.flow_rate + if swap_speed is None: + swap_speed = 100 + if settling_time is None: + settling_time = 5 + if mix_speed is None: + mix_speed = 100 channel_pattern = [True] * 12 * 8 @@ -2553,7 +2380,7 @@ async def dispense96( liquid_surface_sink_distance_at_the_end_of_dispense=round( liquid_surface_sink_distance_at_the_end_of_dispense * 10 ), - dispense_volume=round(volume * 10), + dispense_volume=round(dispense.volume * 10), dispense_speed=round(flow_rate * 10), transport_air_volume=round(transport_air_volume * 10), blow_out_air_volume=round(blow_out_air_volume * 10), @@ -2565,7 +2392,7 @@ async def dispense96( mixing_cycles=mixing_cycles, mixing_position_from_liquid_surface=round(mixing_position_from_liquid_surface * 10), surface_following_distance_during_mixing=round(surface_following_distance_during_mixing * 10), - speed_of_mixing=round(speed_of_mixing * 10), + mix_speed=round(mix_speed * 10), channel_pattern=channel_pattern, limit_curve_index=limit_curve_index, tadm_algorithm=False, @@ -5375,7 +5202,7 @@ async def aspirate_core_96( mix_cycles: int = 0, mix_position_from_liquid_surface: int = 250, surface_following_distance_during_mix: int = 0, - speed_of_mix: int = 1000, + mix_speed: int = 1000, channel_pattern: List[bool] = [True] * 96, limit_curve_index: int = 0, tadm_algorithm: bool = False, @@ -5429,7 +5256,7 @@ async def aspirate_core_96( liquid surface (LLD or absolute terms) [0.1mm]. Must be between 0 and 990. Default 250. surface_following_distance_during_mix: surface following distance during mix [0.1mm]. Must be between 0 and 990. Default 0. - speed_of_mix: Speed of mix [0.1ul/s]. Must be between 3 and 5000. + mix_speed: Speed of mix [0.1ul/s]. Must be between 3 and 5000. Default 1000. todo: TODO: 24 hex chars. Must be between 4 and 5000. limit_curve_index: limit curve index. Must be between 0 and 999. Default 0. @@ -5484,7 +5311,7 @@ async def aspirate_core_96( assert ( 0 <= surface_following_distance_during_mix <= 990 ), "surface_following_distance_during_mix must be between 0 and 990" - assert 3 <= speed_of_mix <= 5000, "speed_of_mix must be between 3 and 5000" + assert 3 <= mix_speed <= 5000, "mix_speed must be between 3 and 5000" assert 0 <= limit_curve_index <= 999, "limit_curve_index must be between 0 and 999" assert 0 <= recording_mode <= 2, "recording_mode must be between 0 and 2" @@ -5525,7 +5352,7 @@ async def aspirate_core_96( hc=f"{mix_cycles:02}", hp=f"{mix_position_from_liquid_surface:03}", mj=f"{surface_following_distance_during_mix:03}", - hs=f"{speed_of_mix:04}", + hs=f"{mix_speed:04}", cw=channel_pattern_hex, cr=f"{limit_curve_index:03}", cj=tadm_algorithm, @@ -5565,7 +5392,7 @@ async def dispense_core_96( mixing_cycles: int = 0, mixing_position_from_liquid_surface: int = 250, surface_following_distance_during_mixing: int = 0, - speed_of_mixing: int = 1000, + mix_speed: int = 1000, channel_pattern: List[bool] = [True] * 12 * 8, limit_curve_index: int = 0, tadm_algorithm: bool = False, @@ -5622,7 +5449,7 @@ async def dispense_core_96( surface (LLD or absolute terms) [0.1mm]. Must be between 0 and 990. Default 250. surface_following_distance_during_mixing: surface following distance during mixing [0.1mm]. Must be between 0 and 990. Default 0. - speed_of_mixing: Speed of mixing [0.1ul/s]. Must be between 3 and 5000. Default 1000. + mix_speed: Speed of mixing [0.1ul/s]. Must be between 3 and 5000. Default 1000. channel_pattern: list of 96 boolean values limit_curve_index: limit curve index. Must be between 0 and 999. Default 0. tadm_algorithm: TADM algorithm. Default False. @@ -5678,7 +5505,7 @@ async def dispense_core_96( assert ( 0 <= surface_following_distance_during_mixing <= 990 ), "surface_following_distance_during_mixing must be between 0 and 990" - assert 3 <= speed_of_mixing <= 5000, "speed_of_mixing must be between 3 and 5000" + assert 3 <= mix_speed <= 5000, "mix_speed must be between 3 and 5000" assert 0 <= limit_curve_index <= 999, "limit_curve_index must be between 0 and 999" assert 0 <= recording_mode <= 2, "recording_mode must be between 0 and 2" @@ -5720,7 +5547,7 @@ async def dispense_core_96( hc=f"{mixing_cycles:02}", hp=f"{mixing_position_from_liquid_surface:03}", mj=f"{surface_following_distance_during_mixing:03}", - hs=f"{speed_of_mixing:04}", + hs=f"{mix_speed:04}", cw=channel_pattern_hex, cr=f"{limit_curve_index:03}", cj=tadm_algorithm, diff --git a/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py b/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py index b103940f42..fe56f607fe 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py +++ b/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py @@ -5,6 +5,11 @@ from typing import cast from pylabrobot.liquid_handling import LiquidHandler +from pylabrobot.liquid_handling.liquid_classes.hamilton.star import ( + HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty, + StandardVolumeFilter_Water_DispenseJet_Empty, + StandardVolumeFilter_Water_DispenseSurface, +) from pylabrobot.liquid_handling.standard import GripDirection, Pickup from pylabrobot.plate_reading import PlateReader from pylabrobot.plate_reading.chatterbox import PlateReaderChatterboxBackend @@ -264,6 +269,10 @@ def __init__(self, name: str): self.STAR._iswap_parked = True await self.lh.setup() + self.hlc = StandardVolumeFilter_Water_DispenseSurface.copy() + self.hlc.aspiration_air_transport_volume = 0 + self.hlc.dispense_air_transport_volume = 0 + async def asyncTearDown(self): await self.lh.stop() @@ -380,9 +389,15 @@ async def test_aspirate56(self): await self.test_tip_pickup_56() # pick up tips first assert self.plate.lid is not None self.plate.lid.unassign() + corrected_vol = self.hlc.compute_corrected_volume(100) for well in self.plate.get_items(["A1", "B1"]): - well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction - await self.lh.aspirate(self.plate["A1", "B1"], vols=[100, 100], use_channels=[4, 5]) + well.tracker.set_liquids([(None, corrected_vol)]) + await self.lh.aspirate( + self.plate["A1", "B1"], + vols=[corrected_vol] * 2, + use_channels=[4, 5], + **self.hlc.make_asp_kwargs(2), + ) self.STAR._write_and_read_command.assert_has_calls( [ _any_write_and_read_command_call( @@ -411,8 +426,9 @@ async def test_single_channel_aspiration(self): assert self.plate.lid is not None self.plate.lid.unassign() well = self.plate.get_item("A1") - well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction - await self.lh.aspirate([well], vols=[100]) + corrected_volume = self.hlc.compute_corrected_volume(100) + well.tracker.set_liquids([(None, corrected_volume)]) # liquid class correction + await self.lh.aspirate([well], vols=[corrected_volume], **self.hlc.make_asp_kwargs(1)) self.STAR._write_and_read_command.assert_has_calls( [ _any_write_and_read_command_call( @@ -432,8 +448,11 @@ async def test_single_channel_aspiration_liquid_height(self): assert self.plate.lid is not None self.plate.lid.unassign() well = self.plate.get_item("A1") - well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction - await self.lh.aspirate([well], vols=[100], liquid_height=[10]) + corrected_volume = self.hlc.compute_corrected_volume(100) + well.tracker.set_liquids([(None, corrected_volume)]) # liquid class correction + await self.lh.aspirate( + [well], vols=[corrected_volume], liquid_height=[10], **self.hlc.make_asp_kwargs(1) + ) # This passes the test, but is not the real command. self.STAR._write_and_read_command.assert_has_calls( @@ -455,9 +474,12 @@ async def test_multi_channel_aspiration(self): assert self.plate.lid is not None self.plate.lid.unassign() wells = self.plate.get_items("A1:B1") + corrected_volume = self.hlc.compute_corrected_volume(100) for well in wells: - well.tracker.set_liquids([(None, 100 * 1.072)]) # liquid class correction - await self.lh.aspirate(self.plate["A1:B1"], vols=[100] * 2) + well.tracker.set_liquids([(None, corrected_volume)]) # liquid class correction + await self.lh.aspirate( + self.plate["A1:B1"], vols=[corrected_volume] * 2, **self.hlc.make_asp_kwargs(2) + ) # This passes the test, but is not the real command. self.STAR._write_and_read_command.assert_has_calls( @@ -477,12 +499,14 @@ async def test_multi_channel_aspiration(self): async def test_aspirate_single_resource(self): self.lh.update_head_state({i: self.tip_rack.get_tip(i) for i in range(5)}) + corrected_volume = self.hlc.compute_corrected_volume(10) with no_volume_tracking(): await self.lh.aspirate( [self.bb] * 5, - vols=[10] * 5, + vols=[corrected_volume] * 5, use_channels=[0, 1, 2, 3, 4], liquid_height=[1] * 5, + **self.hlc.make_asp_kwargs(5), ) self.STAR._write_and_read_command.assert_has_calls( [ @@ -506,14 +530,17 @@ async def test_aspirate_single_resource(self): async def test_dispense_single_resource(self): self.lh.update_head_state({i: self.tip_rack.get_tip(i) for i in range(5)}) + hlc = StandardVolumeFilter_Water_DispenseJet_Empty + corrected_volume = hlc.compute_corrected_volume(10) with no_volume_tracking(): await self.lh.dispense( [self.bb] * 5, - vols=[10] * 5, + vols=[corrected_volume] * 5, use_channels=[0, 1, 2, 3, 4], liquid_height=[1] * 5, blow_out=[True] * 5, jet=[True] * 5, + **hlc.make_disp_kwargs(5), ) self.STAR._write_and_read_command.assert_has_calls( [ @@ -536,8 +563,16 @@ async def test_single_channel_dispense(self): self.lh.update_head_state({0: self.tip_rack.get_tip("A1")}) assert self.plate.lid is not None self.plate.lid.unassign() + hlc = StandardVolumeFilter_Water_DispenseJet_Empty + corrected_vol = hlc.compute_corrected_volume(100) with no_volume_tracking(): - await self.lh.dispense(self.plate["A1"], vols=[100], jet=[True], blow_out=[True]) + await self.lh.dispense( + self.plate["A1"], + vols=[corrected_vol], + jet=[True], + blow_out=[True], + **hlc.make_disp_kwargs(1), + ) self.STAR._write_and_read_command.assert_has_calls( [ _any_write_and_read_command_call( @@ -548,15 +583,17 @@ async def test_single_channel_dispense(self): async def test_multi_channel_dispense(self): self.lh.update_head_state({0: self.tip_rack.get_tip("A1"), 1: self.tip_rack.get_tip("B1")}) - # TODO: Hamilton liquid classes assert self.plate.lid is not None self.plate.lid.unassign() + hlc = StandardVolumeFilter_Water_DispenseJet_Empty + corrected_vol = hlc.compute_corrected_volume(100) with no_volume_tracking(): await self.lh.dispense( self.plate["A1:B1"], - vols=[100] * 2, + vols=[corrected_vol] * 2, jet=[True] * 2, blow_out=[True] * 2, + **hlc.make_disp_kwargs(2), ) self.STAR._write_and_read_command.assert_has_calls( @@ -605,10 +642,11 @@ async def test_core_96_aspirate(self): await self.lh.pick_up_tips96(self.tip_rack2) # pick up high volume tips self.STAR._write_and_read_command.reset_mock() - # TODO: Hamilton liquid classes assert self.plate.lid is not None self.plate.lid.unassign() - await self.lh.aspirate96(self.plate, volume=100, blow_out=True) + hlc = HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty + corrected_volume = hlc.compute_corrected_volume(100) + await self.lh.aspirate96(self.plate, volume=corrected_volume, **hlc.make_asp96_kwargs()) # volume used to be 01072, but that was generated using a non-core liquid class. self.STAR._write_and_read_command.assert_has_calls( @@ -623,11 +661,15 @@ async def test_core_96_dispense(self): await self.lh.pick_up_tips96(self.tip_rack2) # pick up high volume tips if self.plate.lid is not None: self.plate.lid.unassign() - await self.lh.aspirate96(self.plate, 100, blow_out=True) # aspirate first + hlc = HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty + corrected_volume = hlc.compute_corrected_volume(100) + await self.lh.aspirate96(self.plate, corrected_volume, **hlc.make_asp96_kwargs()) self.STAR._write_and_read_command.reset_mock() with no_volume_tracking(): - await self.lh.dispense96(self.plate, 100, blow_out=True) + await self.lh.dispense96( + self.plate, corrected_volume, blow_out=True, **hlc.make_disp96_kwargs() + ) # volume used to be 01072, but that was generated using a non-core liquid class. self.STAR._write_and_read_command.assert_has_calls( diff --git a/pylabrobot/liquid_handling/backends/hamilton/vantage.py b/pylabrobot/liquid_handling/backends/hamilton/vantage.py index 901c3214f3..1d08c916a4 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/vantage.py +++ b/pylabrobot/liquid_handling/backends/hamilton/vantage.py @@ -7,10 +7,7 @@ from pylabrobot.liquid_handling.backends.hamilton.base import ( HamiltonLiquidHandler, ) -from pylabrobot.liquid_handling.liquid_classes.hamilton import ( - HamiltonLiquidClass, - get_vantage_liquid_class, -) +from pylabrobot.liquid_handling.liquid_classes.hamilton import HamiltonLiquidClass from pylabrobot.liquid_handling.standard import ( Drop, DropTipRack, @@ -28,7 +25,6 @@ ) from pylabrobot.resources import ( Coordinate, - Liquid, Resource, TipRack, Well, @@ -567,8 +563,6 @@ async def aspirate( self, ops: List[SingleChannelAspiration], use_channels: List[int], - jet: Optional[List[bool]] = None, - blow_out: Optional[List[bool]] = None, hlcs: Optional[List[Optional[HamiltonLiquidClass]]] = None, type_of_aspiration: Optional[List[int]] = None, minimal_traverse_height_at_begin_of_command: Optional[List[float]] = None, @@ -615,44 +609,15 @@ async def aspirate( blow_out: Whether to search for a "blow out" liquid class. This is only used on dispense. Note that in the VENUS liquid editor, the term "empty" is used for this, but in the firmware documentation, "empty" is used for a different mode (dm4). - hlcs: The Hamiltonian liquid classes to use. If `None`, the liquid classes will be - determined automatically based on the tip and liquid used. """ - x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) + if hlcs is not None: + raise NotImplementedError("hlcs is deprecated") - if jet is None: - jet = [False] * len(ops) - if blow_out is None: - blow_out = [False] * len(ops) - - if hlcs is None: - hlcs = [] - for j, bo, op in zip(jet, blow_out, ops): - liquid = Liquid.WATER # default to WATER - # [-1][0]: get last liquid in well, [0] is indexing into the tuple - if len(op.liquids) > 0 and op.liquids[-1][0] is not None: - liquid = op.liquids[-1][0] - hlcs.append( - get_vantage_liquid_class( - tip_volume=op.tip.maximal_volume, - is_core=False, - is_tip=True, - has_filter=op.tip.has_filter, - liquid=liquid, - jet=j, - blow_out=bo, - ) - ) + x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) self._assert_valid_resources([op.resource for op in ops]) - # correct volumes using the liquid class - volumes = [ - hlc.compute_corrected_volume(op.volume) if hlc is not None else op.volume - for op, hlc in zip(ops, hlcs) - ] - well_bottoms = [ op.resource.get_absolute_location().z + op.offset.z + op.resource.material_z_thickness for op in ops @@ -668,14 +633,8 @@ async def aspirate( for wb, op in zip(well_bottoms, ops) ] - flow_rates = [ - op.flow_rate or (hlc.aspiration_flow_rate if hlc is not None else 100) - for op, hlc in zip(ops, hlcs) - ] - blow_out_air_volumes = [ - (op.blow_out_air_volume or (hlc.dispense_blow_out_volume if hlc is not None else 0)) - for op, hlc in zip(ops, hlcs) - ] + flow_rates = [op.flow_rate or 100 for op in ops] + blow_out_air_volumes = [op.blow_out_air_volume or 0 for op in ops] return await self.pip_aspirate( x_position=x_positions, @@ -710,13 +669,9 @@ async def aspirate( surface_following_distance=[ round(sfd * 10) for sfd in surface_following_distance or [0] * len(ops) ], - aspiration_volume=[round(vol * 100) for vol in volumes], + aspiration_volume=[round(op.volume * 100) for op in ops], aspiration_speed=[round(fr * 10) for fr in flow_rates], - transport_air_volume=[ - round(tav * 10) - for tav in transport_air_volume - or [hlc.aspiration_air_transport_volume if hlc is not None else 0 for hlc in hlcs] - ], + transport_air_volume=[round(tav * 10) for tav in transport_air_volume or [0] * len(ops)], blow_out_air_volume=[round(bav * 100) for bav in blow_out_air_volumes], pre_wetting_volume=[round(pwv * 100) for pwv in pre_wetting_volume or [0] * len(ops)], lld_mode=lld_mode or [0] * len(ops), @@ -792,8 +747,6 @@ async def dispense( Args: ops: The aspiration operations. use_channels: The channels to use. - hlcs: The Hamiltonian liquid classes to use. If `None`, the liquid classes will be - determined automatically based on the tip and liquid used. jet: Whether to use jetting for each dispense. Defaults to `False` for all. Used for determining the dispense mode. True for dispense mode 0 or 1. @@ -805,6 +758,9 @@ async def dispense( documentation. Dispense mode 4. """ + if hlcs is not None: + raise NotImplementedError("hlcs is deprecated") + x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels) if jet is None: @@ -814,33 +770,8 @@ async def dispense( if blow_out is None: blow_out = [False] * len(ops) - if hlcs is None: - hlcs = [] - for j, bo, op in zip(jet, blow_out, ops): - liquid = Liquid.WATER # default to WATER - # [-1][0]: get last liquid in tip, [0] is indexing into the tuple - if len(op.liquids) > 0 and op.liquids[-1][0] is not None: - liquid = op.liquids[-1][0] - hlcs.append( - get_vantage_liquid_class( - tip_volume=op.tip.maximal_volume, - is_core=False, - is_tip=True, - has_filter=op.tip.has_filter, - liquid=liquid, - jet=j, - blow_out=bo, - ) - ) - self._assert_valid_resources([op.resource for op in ops]) - # correct volumes using the liquid class - volumes = [ - hlc.compute_corrected_volume(op.volume) if hlc is not None else op.volume - for op, hlc in zip(ops, hlcs) - ] - well_bottoms = [ op.resource.get_absolute_location().z + op.offset.z + op.resource.material_z_thickness for op in ops @@ -854,15 +785,9 @@ async def dispense( for wb, op in zip(well_bottoms, ops) ] - flow_rates = [ - op.flow_rate or (hlc.dispense_flow_rate if hlc is not None else 100) - for op, hlc in zip(ops, hlcs) - ] + flow_rates = [op.flow_rate or 100 for op in ops] - blow_out_air_volumes = [ - (op.blow_out_air_volume or (hlc.dispense_blow_out_volume if hlc is not None else 0)) - for op, hlc in zip(ops, hlcs) - ] + blow_out_air_volumes = [op.blow_out_air_volume or 0 for op in ops] type_of_dispensing_mode = type_of_dispensing_mode or [ _get_dispense_mode(jet=jet[i], empty=empty[i], blow_out=blow_out[i]) for i in range(len(ops)) @@ -900,15 +825,11 @@ async def dispense( round(mh * 10) for mh in minimal_height_at_command_end or [self._traversal_height] * len(ops) ], - dispense_volume=[round(vol * 100) for vol in volumes], + dispense_volume=[round(op.volume * 100) for op in ops], dispense_speed=[round(fr * 10) for fr in flow_rates], cut_off_speed=[round(cs * 10) for cs in cut_off_speed or [250] * len(ops)], stop_back_volume=[round(sbv * 100) for sbv in stop_back_volume or [0] * len(ops)], - transport_air_volume=[ - round(tav * 10) - for tav in transport_air_volume - or [hlc.dispense_air_transport_volume if hlc is not None else 0 for hlc in hlcs] - ], + transport_air_volume=[round(tav * 10) for tav in transport_air_volume or [0] * len(ops)], blow_out_air_volume=[round(boav * 100) for boav in blow_out_air_volumes], lld_mode=lld_mode or [0] * len(ops), side_touch_off_distance=round(side_touch_off_distance * 10), @@ -997,8 +918,6 @@ async def drop_tips96( async def aspirate96( self, aspiration: Union[MultiHeadAspirationPlate, MultiHeadAspirationContainer], - jet: bool = False, - blow_out: bool = False, hlc: Optional[HamiltonLiquidClass] = None, type_of_aspiration: int = 0, minimal_traverse_height_at_begin_of_command: Optional[float] = None, @@ -1025,18 +944,11 @@ async def aspirate96( tadm_algorithm_on_off: int = 0, recording_mode: int = 0, ): - """Aspirate from a plate. - - Args: - jet: Whether to find a liquid class with "jet" mode. Only used on dispense. - blow_out: Whether to find a liquid class with "blow out" mode. Only used on dispense. Note - that this is called "empty" in the VENUS liquid editor, but "blow out" in the firmware - documentation. - hlc: The Hamiltonian liquid classes to use. If `None`, the liquid classes will be - determined automatically based on the tip and liquid used in the first well. - """ # assert self.core96_head_installed, "96 head must be installed" + if hlc is not None: + raise NotImplementedError("hlc is deprecated") + if isinstance(aspiration, MultiHeadAspirationPlate): top_left_well = aspiration.wells[0] position = ( @@ -1059,35 +971,20 @@ async def aspirate96( liquid_height = position.z + (aspiration.liquid_height or 0) - tip = aspiration.tips[0] - liquid_to_be_aspirated = Liquid.WATER # default to water - if len(aspiration.liquids[0]) > 0 and aspiration.liquids[0][-1][0] is not None: - # first part of tuple in last liquid of first well - liquid_to_be_aspirated = aspiration.liquids[0][-1][0] - if hlc is None: - hlc = get_vantage_liquid_class( - tip_volume=tip.maximal_volume, - is_core=True, - is_tip=True, - has_filter=tip.has_filter, - liquid=liquid_to_be_aspirated, - jet=jet, - blow_out=blow_out, - ) - - volume = ( - hlc.compute_corrected_volume(aspiration.volume) if hlc is not None else aspiration.volume - ) - - transport_air_volume = transport_air_volume or ( - hlc.aspiration_air_transport_volume if hlc is not None else 0 - ) - blow_out_air_volume = blow_out_air_volume or ( - hlc.aspiration_blow_out_volume if hlc is not None else 0 - ) - flow_rate = aspiration.flow_rate or (hlc.aspiration_flow_rate if hlc is not None else 250) - swap_speed = swap_speed or (hlc.aspiration_swap_speed if hlc is not None else 100) - settling_time = settling_time or (hlc.aspiration_settling_time if hlc is not None else 5) + if transport_air_volume is None: + transport_air_volume = 0 + if aspiration.blow_out_air_volume is None: + blow_out_air_volume = 0.0 + else: + blow_out_air_volume = aspiration.blow_out_air_volume + if aspiration.flow_rate is None: + flow_rate = 250.0 + else: + flow_rate = aspiration.flow_rate + if swap_speed is None: + swap_speed = 100 + if settling_time is None: + settling_time = 5 return await self.core96_aspiration_of_liquid( x_position=round(position.x * 10), @@ -1109,7 +1006,7 @@ async def aspirate96( tube_2nd_section_ratio=round(tube_2nd_section_ratio * 10), immersion_depth=round(immersion_depth * 10), surface_following_distance=round(surface_following_distance * 10), - aspiration_volume=round(volume * 100), + aspiration_volume=round(aspiration.volume * 100), aspiration_speed=round(flow_rate * 10), transport_air_volume=round(transport_air_volume * 10), blow_out_air_volume=round(blow_out_air_volume * 100), @@ -1182,6 +1079,9 @@ async def dispense96( determined based on the jet, blow_out, and empty parameters. """ + if hlc is not None: + raise NotImplementedError("hlc is deprecated") + if isinstance(dispense, MultiHeadDispensePlate): top_left_well = dispense.wells[0] position = ( @@ -1204,36 +1104,24 @@ async def dispense96( liquid_height = position.z + (dispense.liquid_height or 0) + 10 - tip = dispense.tips[0] - liquid_to_be_dispensed = Liquid.WATER # default to WATER - if len(dispense.liquids[0]) > 0 and dispense.liquids[0][-1][0] is not None: - # first part of tuple in last liquid of first well - liquid_to_be_dispensed = dispense.liquids[0][-1][0] - if hlc is None: - hlc = get_vantage_liquid_class( - tip_volume=tip.maximal_volume, - is_core=True, - is_tip=True, - has_filter=tip.has_filter, - liquid=liquid_to_be_dispensed, - jet=jet, - blow_out=blow_out, # see method docstring - ) - volume = hlc.compute_corrected_volume(dispense.volume) if hlc is not None else dispense.volume - - transport_air_volume = transport_air_volume or ( - hlc.dispense_air_transport_volume if hlc is not None else 0 - ) - blow_out_air_volume = blow_out_air_volume or ( - hlc.dispense_blow_out_volume if hlc is not None else 0 - ) - flow_rate = dispense.flow_rate or (hlc.dispense_flow_rate if hlc is not None else 250) - swap_speed = swap_speed or (hlc.dispense_swap_speed if hlc is not None else 100) - settling_time = settling_time or (hlc.dispense_settling_time if hlc is not None else 5) - mix_speed = mix_speed or (hlc.dispense_mix_flow_rate if hlc is not None else 100) - type_of_dispensing_mode = type_of_dispensing_mode or _get_dispense_mode( - jet=jet, empty=empty, blow_out=blow_out - ) + if transport_air_volume is None: + transport_air_volume = 0 + if dispense.blow_out_air_volume is None: + blow_out_air_volume = 0.0 + else: + blow_out_air_volume = dispense.blow_out_air_volume + if dispense.flow_rate is None: + flow_rate = 250.0 + else: + flow_rate = dispense.flow_rate + if swap_speed is None: + swap_speed = 100 + if settling_time is None: + settling_time = 5 + if mix_speed is None: + mix_speed = 100 + if type_of_dispensing_mode is None: + type_of_dispensing_mode = _get_dispense_mode(jet=jet, empty=empty, blow_out=blow_out) return await self.core96_dispensing_of_liquid( x_position=round(position.x * 10), @@ -1255,7 +1143,7 @@ async def dispense96( minimal_height_at_command_end=round( (minimal_height_at_command_end or self._traversal_height) * 10 ), - dispense_volume=round(volume * 100), + dispense_volume=round(dispense.volume * 100), dispense_speed=round(flow_rate * 10), cut_off_speed=round(cut_off_speed * 10), stop_back_volume=round(stop_back_volume * 100), diff --git a/pylabrobot/liquid_handling/backends/hamilton/vantage_tests.py b/pylabrobot/liquid_handling/backends/hamilton/vantage_tests.py index 47e4bb8bdd..219d437907 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/vantage_tests.py +++ b/pylabrobot/liquid_handling/backends/hamilton/vantage_tests.py @@ -2,6 +2,11 @@ from typing import Any, List, Optional from pylabrobot.liquid_handling import LiquidHandler +from pylabrobot.liquid_handling.liquid_classes.hamilton.vantage import ( + HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty, + HighVolumeFilter_Water_DispenseSurface_Empty, + HighVolumeFilter_Water_DispenseSurface_Part, +) from pylabrobot.liquid_handling.standard import Pickup from pylabrobot.resources import ( HT, @@ -161,25 +166,20 @@ def test_parse_error_response(self): resp = 'I1AMRQid0000er4et"Slave not available"' error = vantage_response_string_to_error(resp) self.assertEqual( - error, - VantageFirmwareError(errors={"Cover": "Slave not available"}, raw_response=resp), + error, VantageFirmwareError(errors={"Cover": "Slave not available"}, raw_response=resp) ) resp = 'I1AMLPid215er57et"S-Drive: Drive not initialized"' error = vantage_response_string_to_error(resp) self.assertEqual( error, - VantageFirmwareError( - errors={"Cover": "S-Drive: Drive not initialized"}, - raw_response=resp, - ), + VantageFirmwareError(errors={"Cover": "S-Drive: Drive not initialized"}, raw_response=resp), ) resp = 'A1HMDAid239er99es"H070"' error = vantage_response_string_to_error(resp) self.assertEqual( - error, - VantageFirmwareError(errors={"Core 96": "No liquid level found"}, raw_response=resp), + error, VantageFirmwareError(errors={"Core 96": "No liquid level found"}, raw_response=resp) ) resp = 'A1PMDAid262er99es"P170 P270 P370 P470 P570 P670 P770 P870"' @@ -210,7 +210,7 @@ def __init__(self): super().__init__() self.commands = [] - async def setup(self) -> None: # type: ignore + async def setup(self) -> None: self.setup_finished = True self._num_channels = 8 self.iswap_installed = True @@ -220,7 +220,7 @@ async def send_command( self, module: str, command: str, - auto_id: bool = True, + auto_id=True, tip_pattern: Optional[List[bool]] = None, write_timeout: Optional[int] = None, read_timeout: Optional[int] = None, @@ -241,6 +241,7 @@ class TestVantageLiquidHandlerCommands(unittest.IsolatedAsyncioTestCase): """Test Vantage backend for liquid handling.""" async def asyncSetUp(self): + # pylint: disable=invalid-name self.mockVantage = VantageCommandCatcher() self.deck = VantageDeck(size=1.3) self.lh = LiquidHandler(self.mockVantage, deck=self.deck) @@ -313,6 +314,7 @@ def _assert_command_in_command_buffer(self, cmd: str, should_be: bool, fmt: dict def test_ops_to_fw_positions(self): """Convert channel positions to firmware positions.""" + # pylint: disable=protected-access tip_a1 = self.tip_rack.get_item("A1") tip_f1 = self.tip_rack.get_item("F1") tip = self.tip_rack.get_tip("A1") @@ -331,11 +333,7 @@ def test_ops_to_fw_positions(self): self.assertEqual( self.mockVantage._ops_to_fw_positions((op1, op2), use_channels=[1, 2]), - ( - [0, 4329, 4329, 0], - [0, 1458, 1008, 0], - [False, True, True, False], - ), + ([0, 4329, 4329, 0], [0, 1458, 1008, 0], [False, True, True, False]), ) def _assert_command_sent_once(self, cmd: str, fmt: dict): @@ -374,41 +372,45 @@ async def test_small_tip_drop(self): await self.test_small_tip_pickup() # pick up tips first await self.lh.drop_tips(self.small_tip_rack["A1"]) self._assert_command_sent_once( - "A1PMTRid0012xp4329 0&yp2418 0&tp2024&tz1924&th2450&te2450&tm1 0&ts0td0&", - DROP_TIP_FORMAT, + "A1PMTRid0012xp4329 0&yp2418 0&tp2024&tz1924&th2450&te2450&tm1 0&ts0td0&", DROP_TIP_FORMAT ) async def test_aspirate(self): await self.lh.pick_up_tips(self.tip_rack["A1"]) # pick up tips first - await self.lh.aspirate(self.plate["A1"], vols=[100]) + hlc = HighVolumeFilter_Water_DispenseSurface_Part + corrected_volume = hlc.compute_corrected_volume(100) + await self.lh.aspirate(self.plate["A1"], vols=[corrected_volume], **hlc.make_asp_kwargs(1)) self._assert_command_sent_once( "A1PMDAid0248at0&tm1 0&xp05683 0&yp1457 0 &th2450&te2450&lp1990&" "ch000&zl1866&zx1866&ip0000&fp0000&av010830&as2500&ta000&ba00000&oa000&lm0&ll4&lv4&de0020&" - "wt10&mv00000&mc00&mp000&ms2500&gi000&gj0gk0zu0000&zr00000&mh0000&zo005&po0109&dj0la0&lb0&" + "wt10&mv00000&mc00&mp000&ms1200&gi000&gj0gk0zu0000&zr00000&mh0000&zo005&po0109&dj0la0&lb0&" "lc0&", ASPIRATE_FORMAT, ) async def test_dispense(self): await self.lh.pick_up_tips(self.tip_rack["A1"]) # pick up tips first - await self.lh.aspirate(self.plate["A1"], vols=[100]) + hlc = HighVolumeFilter_Water_DispenseSurface_Empty + corrected_volume = hlc.compute_corrected_volume(100) + await self.lh.aspirate(self.plate["A1"], vols=[corrected_volume], **hlc.make_asp_kwargs(1)) await self.lh.dispense( self.plate["A2"], - vols=[100], + vols=[corrected_volume], liquid_height=[5], jet=[False], blow_out=[True], + **hlc.make_disp_kwargs(1), ) self._assert_command_sent_once( "A1PMDDid0253dm3&tm1 0&xp05773 0&yp1457 0&zx1866&lp1990&zl1916&" "ip0000&fp0021&th2450&te2450&dv010830&ds1200&ss2500&rv000&ta050&ba00000&lm0&zo005&ll1&lv1&" - "de0010&mv00000&mc00&mp000&ms0010&wt00&gi000&gj0gk0zu0000&dj00zr00000&mh0000&po0050&la0&", + "de0020&mv00000&mc00&mp000&ms1200&wt00&gi000&gj0gk0zu0000&dj00zr00000&mh0000&po0050&la0&", DISPENSE_FORMAT, ) - async def test_zero_volume_liquid_handling(self): + async def test_zero_volumeiquid_handling(self): # just test that this does not throw an error await self.lh.pick_up_tips(self.tip_rack["A1"]) # pick up tips first await self.lh.aspirate(self.plate["A1"], vols=[0]) @@ -418,15 +420,7 @@ async def test_tip_pickup96(self): await self.lh.pick_up_tips96(self.tip_rack) self._assert_command_sent_once( "A1HMTPid0237xp04329yp1458tt01td0tz2164th2450te2450", - { - "xp": "int", - "yp": "int", - "tt": "int", - "td": "int", - "tz": "int", - "th": "int", - "te": "int", - }, + {"xp": "int", "yp": "int", "tt": "int", "td": "int", "tz": "int", "th": "int", "te": "int"}, ) async def test_tip_drop96(self): @@ -434,20 +428,17 @@ async def test_tip_drop96(self): await self.lh.drop_tips96(self.tip_rack) self._assert_command_sent_once( "A1HMTRid0284xp04329yp1458tz2164th2450te2450", - { - "xp": "int", - "yp": "int", - "tz": "int", - "th": "int", - "te": "int", - }, + {"xp": "int", "yp": "int", "tz": "int", "th": "int", "te": "int"}, ) async def test_aspirate96(self): await self.lh.pick_up_tips96(self.tip_rack) - await self.lh.aspirate96(self.plate, volume=100, jet=True, blow_out=True) + hlc = HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty + await self.lh.aspirate96( + self.plate, volume=hlc.compute_corrected_volume(100), **hlc.make_asp96_kwargs() + ) self._assert_command_sent_once( - "A1HMDAid0236at0xp05683yp1457th2450te2450lp1990zl1866zx1866ip000fp000av010720as2500ta050" + "A1HMDAid0236at0xp05683yp1457th2450te2450lp1990zl1866zx1866ip000fp000av010920as2500ta050" "ba004000oa00000lm0ll4de0020wt10mv00000mc00mp000ms2500zu0000zr00000mh000gj0gk0gi000" "cwFFFFFFFFFFFFFFFFFFFFFFFFpo0050", { @@ -485,10 +476,19 @@ async def test_aspirate96(self): async def test_dispense96(self): await self.lh.pick_up_tips96(self.tip_rack) - await self.lh.aspirate96(self.plate, volume=100, jet=True, blow_out=True) - await self.lh.dispense96(self.plate, volume=100, jet=True, blow_out=True) + hlc = HighVolumeFilter_96COREHead1000ul_Water_DispenseJet_Empty + await self.lh.aspirate96( + self.plate, volume=hlc.compute_corrected_volume(100), **hlc.make_asp96_kwargs() + ) + await self.lh.dispense96( + self.plate, + volume=hlc.compute_corrected_volume(100), + jet=True, + blow_out=True, + **hlc.make_disp96_kwargs(), + ) self._assert_command_sent_once( - "A1HMDDid0238dm1xp05683yp1457th2450te2450lp1990zl1966zx1866ip000fp029dv010720ds4000ta050" + "A1HMDDid0238dm1xp05683yp1457th2450te2450lp1990zl1966zx1866ip000fp029dv10920ds4000ta050" "ba004000lm0ll4de0010wt00mv00000mc00mp000ms0010ss2500rv000zu0000dj00zr00000mh000gj0gk0gi000" "cwFFFFFFFFFFFFFFFFFFFFFFFFpo0050", { @@ -527,13 +527,14 @@ async def test_dispense96(self): }, ) - async def test_zero_volume_liquid_handling96(self): + async def test_zero_volumeiquid_handling96(self): # just test that this does not throw an error await self.lh.pick_up_tips96(self.tip_rack) await self.lh.aspirate96(self.plate, volume=0) await self.lh.dispense96(self.plate, volume=0) async def test_move_plate(self): + assert self.plt_car[1].resource is not None self.plt_car[1].resource.unassign() await self.lh.move_plate(self.plate, self.plt_car[1], pickup_distance_from_top=5.2 - 3.33) @@ -557,13 +558,5 @@ async def test_move_plate(self): # release self._assert_command_sent_once( "A1RMDRid0242xp6179yp2102zp1954yo1310zc0hd0te2840", - { - "xp": "int", - "yp": "int", - "zp": "int", - "yo": "int", - "zc": "int", - "hd": "int", - "te": "int", - }, + {"xp": "int", "yp": "int", "zp": "int", "yo": "int", "zc": "int", "hd": "int", "te": "int"}, )