diff --git a/.vscode/settings.json b/.vscode/settings.json index c8e6972ee9..9c46ac217a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -14,6 +14,7 @@ "pytest", "subclassing", "subresource", + "tadm", "tiprack", "usascientific", "websockets" diff --git a/docs/pylabrobot.liquid_handling.backends.rst b/docs/pylabrobot.liquid_handling.backends.rst index 97051f97ca..2e51a49b7c 100644 --- a/docs/pylabrobot.liquid_handling.backends.rst +++ b/docs/pylabrobot.liquid_handling.backends.rst @@ -25,8 +25,9 @@ Hardware :nosignatures: :recursive: - pylabrobot.liquid_handling.backends.hamilton.STAR.HamiltonLiquidHandler + pylabrobot.liquid_handling.backends.hamilton.base.HamiltonLiquidHandler pylabrobot.liquid_handling.backends.hamilton.STAR.STAR + pylabrobot.liquid_handling.backends.hamilton.vantage.Vantage pylabrobot.liquid_handling.backends.opentrons_backend.OpentronsBackend pylabrobot.liquid_handling.backends.tecan.EVO.EVO diff --git a/pylabrobot/liquid_handling/backends/__init__.py b/pylabrobot/liquid_handling/backends/__init__.py index b271458a32..70d5c1b735 100644 --- a/pylabrobot/liquid_handling/backends/__init__.py +++ b/pylabrobot/liquid_handling/backends/__init__.py @@ -5,8 +5,8 @@ from .websocket import WebSocketBackend # simulation relies on websocket backend from .USBBackend import USBBackend -from .hamilton.errors import HamiltonError from .hamilton.STAR import STAR +from .hamilton.vantage import Vantage from .http import HTTPBackend from .opentrons_backend import OpentronsBackend from .saver_backend import SaverBackend diff --git a/pylabrobot/liquid_handling/backends/hamilton/STAR.py b/pylabrobot/liquid_handling/backends/hamilton/STAR.py index cb88e255a8..72f362320e 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/STAR.py +++ b/pylabrobot/liquid_handling/backends/hamilton/STAR.py @@ -3,23 +3,20 @@ """ # pylint: disable=invalid-sequence-index, dangerous-default-value -from abc import ABCMeta, abstractmethod -import asyncio +from abc import ABC import datetime import enum import functools import logging import re -import threading -import time -from typing import Callable, Dict, List, Optional, Tuple, Sequence, TypeVar, Union, cast - -import pylabrobot.liquid_handling.backends.hamilton.errors as herrors -from pylabrobot.liquid_handling.backends.hamilton.errors import HamiltonFirmwareError -from pylabrobot.liquid_handling.liquid_classes.hamilton import get_liquid_class -from pylabrobot.liquid_handling.backends.USBBackend import USBBackend +from typing import Callable, Dict, ItemsView, List, Optional, Sequence, Type, TypeVar, cast + +from pylabrobot.liquid_handling.backends.hamilton.base import ( + HamiltonLiquidHandler, + HamiltonFirmwareError +) +from pylabrobot.liquid_handling.liquid_classes.hamilton import get_star_liquid_class from pylabrobot.liquid_handling.standard import ( - PipettingOp, Pickup, PickupTipRack, Drop, @@ -31,7 +28,7 @@ GripDirection, Move ) -from pylabrobot.resources import Coordinate, Plate, Resource, TipSpot, Well +from pylabrobot.resources import Coordinate, Plate, Resource, TipSpot from pylabrobot.resources.errors import ( TooLittleVolumeError, TooLittleLiquidError, @@ -77,448 +74,957 @@ def _fill_in_defaults(val: Optional[List[T]], default: List[T]) -> List[T]: return default -class HamiltonLiquidHandler(USBBackend, metaclass=ABCMeta): - """ - Abstract base class for Hamilton liquid handling robot backends. +def parse_star_fw_string(resp: str, fmt: str = "") -> dict: + """ 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 + the same: + - '&': char + - '#': decimal + - '*': hex + + The order of parameters in the format and response string do not + have to (and often do not) match. + + The identifier parameter (id####) is added automatically. + + TODO: string parsing + The firmware docs mention strings in the following format: '...' + However, the length of these is always known (except when reading + barcodes), so it is easier to convert strings to the right number + of '&'. With barcode reading the length of the barcode is included + with the response string. We'll probably do a custom implementation + for that. + + TODO: spaces + We should also parse responses where integers are separated by spaces, + like this: `ua#### #### ###### ###### ###### ######` + + Args: + resp: The response string to parse. + fmt: The format string. + + Raises: + ValueError: if the format string is incompatible with the response. + + Returns: + A dictionary containing the parsed values. + + Examples: + Parsing a string containing decimals (`1111`), hex (`0xB0B`) and chars (`'rw'`): + + ``` + >>> parse_fw_string("aa1111bbrwccB0B", "aa####bb&&cc***") + {'aa': 1111, 'bb': 'rw', 'cc': 2827} + ``` """ - @abstractmethod + # Remove device and cmd identifier from response. + resp = resp[4:] + + # Parse the parameters in the fmt string. + info = {} + + def find_param(param): + name, data = param[0:2], param[2:] + type_ = { + "#": "int", + "*": "hex", + "&": "str" + }[data[0]] + + # Build a regex to match this parameter. + exp = { + "int": r"[-+]?[\d ]", + "hex": r"[\da-fA-F ]", + "str": ".", + }[type_] + len_ = len(data.split(" ")[0]) # Get length of first block. + regex = f"{name}((?:{exp}{ {len_} }" + + if param.endswith(" (n)"): + regex += " ?)+)" + is_list = True + else: + regex += "))" + is_list = False + + # Match response against regex, save results in right datatype. + r = re.search(regex, resp) + if r is None: + raise ValueError(f"could not find matches for parameter {name}") + + g = r.groups() + if len(g) == 0: + raise ValueError(f"could not find value for parameter {name}") + m = g[0] + + if is_list: + m = m.split(" ") + + if type_ == "str": + info[name] = m + elif type_ == "int": + info[name] = [int(m_) for m_ in m if m_ != ""] + elif type_ == "hex": + info[name] = [int(m_, base=16) for m_ in m if m_ != ""] + else: + if type_ == "str": + info[name] = m + elif type_ == "int": + info[name] = int(m) + elif type_ == "hex": + info[name] = int(m, base=16) + + # Find params in string. All params are identified by 2 lowercase chars. + param = "" + prevchar = None + for char in fmt: + if char.islower() and prevchar != "(": + if len(param) > 2: + find_param(param) + param = "" + param += char + prevchar = char + if param != "": + find_param(param) # last parameter is not closed by loop. + + # If id not in fmt, add it. + if "id" not in info: + find_param("id####") + + return info + + +class STARModuleError(ABC): + """ Base class for all Hamilton backend errors, raised by a single module. """ + def __init__( self, - device_address: Optional[int] = None, - packet_read_timeout: int = 3, - read_timeout: int = 30, - write_timeout: int = 30, + message: str, + trace_information: int, + raw_response: str, + raw_module: str, ): - """ + self.message = message + self.trace_information = trace_information + self.raw_response = raw_response + self.raw_module = raw_module - Args: - device_address: The USB address of the Hamilton device. Only useful if using more than one - Hamilton device. - packet_read_timeout: The timeout for reading packets from the Hamilton machine in seconds. - read_timeout: The timeout for from the Hamilton machine in seconds. - num_channels: the number of pipette channels present on the robot. - """ + def __repr__(self) -> str: + return f"{self.__class__.__name__}('{self.message}')" - super().__init__( - address=device_address, - packet_read_timeout=packet_read_timeout, - read_timeout=read_timeout, - write_timeout=write_timeout, - id_vendor=0x08af, - id_product=0x8000) - self.id_ = 0 +class CommandSyntaxError(STARModuleError): + """ Command syntax error - self._reading_thread: Optional[threading.Thread] = None - self._waiting_tasks: Dict[str, - Tuple[asyncio.AbstractEventLoop, asyncio.Future, str, str, float]] = {} + Code: 01 + """ - def _generate_id(self) -> str: - """ continuously generate unique ids 0 <= x < 10000. """ - self.id_ += 1 - return f"{self.id_ % 10000:04}" - def _to_list(self, val: List[T], tip_pattern: List[bool]) -> List[T]: - """ Convert a list of values to a list of values with the correct length. +class HardwareError(STARModuleError): + """ Hardware error - This is roughly one-hot encoding. STAR expects a value for a list parameter at the position - for the corresponding channel. If `tip_pattern` is False, there, the value itself is ignored, - but it must be present. + Possible cause(s): + drive blocked, low power etc. - Args: - val: A list of values, exactly one for each channel that is involved in the operation. - tip_pattern: A list of booleans indicating whether a channel is involved in the operation. + Code: 02 + """ - Returns: - A list of values with the correct length. Each value that is not involved in the operation - is set to the first value in `val`, which is ignored by STAR. - """ - # use the default value if a channel is not involved, otherwise use the value in val - assert len(val) > 0 - assert len(val) <= len(tip_pattern) - - result: List[T] = [] - arg_index = 0 - for channel_involved in tip_pattern: - if channel_involved: - if arg_index >= len(val): - raise ValueError(f"Too few values for tip pattern {tip_pattern}: {val}") - result.append(val[arg_index]) - arg_index += 1 - else: - # this value will be ignored, and using the first value silences mypy - result.append(val[0]) - if arg_index < len(val): - raise ValueError(f"Too many values for tip pattern {tip_pattern}: {val}") - return result +class CommandNotCompletedError(STARModuleError): + """ Command not completed - def _assemble_command( - self, - module: str, - command: str, - tip_pattern: Optional[List[bool]], - **kwargs) -> Tuple[str, str]: - """ Assemble a firmware command to the Hamilton machine. + Possible cause(s): + error in previous sequence (not executed) - Args: - module: 2 character module identifier (C0 for master, ...) - command: 2 character command identifier (QM for request status, ...) - tip_pattern: A list of booleans indicating whether a channel is involved in the operation. - This value will be used to convert the list values in kwargs to the correct length. - kwargs: any named parameters. the parameter name should also be 2 characters long. The value - can be any size. + Code: 03 + """ - Returns: - A string containing the assembled command. - """ - cmd = module + command - id_ = self._generate_id() - cmd += f"id{id_}" # has to be first param - - for k, v in kwargs.items(): - if type(v) is datetime.datetime: - v = v.strftime("%Y-%m-%d %h:%M") - elif type(v) is bool: - v = 1 if v else 0 - elif type(v) is list: - # If this command is 'one-hot' encoded, for the channels, then the list should be the - # same length as the 'one-hot' encoding key (tip_pattern.) If the list is shorter than - # that, it will be 'one-hot encoded automatically. Note that this may raise an error if - # the number of values provided is not the same as the number of channels used. - if tip_pattern is not None: - if len(v) != len(tip_pattern): - # convert one-hot encoded list to int list - v = self._to_list(v, tip_pattern) - # list is now of length len(tip_pattern) - if type(v[0]) is bool: # convert bool list to int list - v = [int(x) for x in v] - v = " ".join([str(e) for e in v]) + ("&" if len(v) < self.num_channels else "") - if k.endswith("_"): # workaround for kwargs named in, as, ... - k = k[:-1] - assert len(k) == 2, "Keyword arguments should be 2 characters long, but got: " + k - cmd += f"{k}{v}" - - return cmd, id_ - - def parse_fw_string(self, resp: str, fmt: str = "") -> dict: - """ 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 - the same: - - '&': char - - '#': decimal - - '*': hex - - The order of parameters in the format and response string do not - have to (and often do not) match. - - The identifier parameter (id####) is added automatically. - - TODO: string parsing - The firmware docs mention strings in the following format: '...' - However, the length of these is always known (except when reading - barcodes), so it is easier to convert strings to the right number - of '&'. With barcode reading the length of the barcode is included - with the response string. We'll probably do a custom implementation - for that. - - TODO: spaces - We should also parse responses where integers are separated by spaces, - like this: `ua#### #### ###### ###### ###### ######` +class ClotDetectedError(STARModuleError): + """ Clot detected - Args: - resp: The response string to parse. - fmt: The format string. + Possible cause(s): + LLD not interrupted - Raises: - ValueError: if the format string is incompatible with the response. + Code: 04 + """ - Returns: - A dictionary containing the parsed values. - Examples: - Parsing a string containing decimals (`1111`), hex (`0xB0B`) and chars (`'rw'`): +class BarcodeUnreadableError(STARModuleError): + """ Barcode unreadable - ``` - >>> parse_fw_string("aa1111bbrwccB0B", "aa####bb&&cc***") - {'aa': 1111, 'bb': 'rw', 'cc': 2827} - ``` - """ + Possible cause(s): + bad or missing barcode - # Remove device and cmd identifier from response. - resp = resp[4:] - - # Parse the parameters in the fmt string. - info = {} - - def find_param(param): - name, data = param[0:2], param[2:] - type_ = { - "#": "int", - "*": "hex", - "&": "str" - }[data[0]] - - # Build a regex to match this parameter. - exp = { - "int": r"[-+]?[\d ]", - "hex": r"[\da-fA-F ]", - "str": ".", - }[type_] - len_ = len(data.split(" ")[0]) # Get length of first block. - regex = f"{name}((?:{exp}{ {len_} }" - - if param.endswith(" (n)"): - regex += " ?)+)" - is_list = True - else: - regex += "))" - is_list = False - - # Match response against regex, save results in right datatype. - r = re.search(regex, resp) - if r is None: - raise ValueError(f"could not find matches for parameter {name}") - - g = r.groups() - if len(g) == 0: - raise ValueError(f"could not find value for parameter {name}") - m = g[0] - - if is_list: - m = m.split(" ") - - if type_ == "str": - info[name] = m - elif type_ == "int": - info[name] = [int(m_) for m_ in m if m_ != ""] - elif type_ == "hex": - info[name] = [int(m_, base=16) for m_ in m if m_ != ""] - else: - if type_ == "str": - info[name] = m - elif type_ == "int": - info[name] = int(m) - elif type_ == "hex": - info[name] = int(m, base=16) - - # Find params in string. All params are identified by 2 lowercase chars. - param = "" - prevchar = None - for char in fmt: - if char.islower() and prevchar != "(": - if len(param) > 2: - find_param(param) - param = "" - param += char - prevchar = char - if param != "": - find_param(param) # last parameter is not closed by loop. - if "id" not in info: # auto add id if we don't have it yet. - find_param("id####") - - return info - - def parse_response(self, resp: str, fmt: str) -> dict: - """ Parse a response from the Hamilton machine. - - This method uses the `parse_fw_string` method to get the info from the response string. - Additionally, it finds any errors in the response. + Code: 05 + """ - Args: - response: A string containing the response from the Hamilton machine. - fmt: A string containing the format of the response. - Raises: - ValueError: if the format string is incompatible with the response. - HamiltonException: if the response contains an error. +class TipTooLittleVolumeError(STARModuleError): + """ Too little liquid - Returns: - A dictionary containing the parsed response. - """ + Possible cause(s): + 1. liquid surface is not detected, + 2. Aspirate / Dispense conditions could not be fulfilled. - # Parse errors. - module = resp[:2] - if module == "C0": - # C0 sends errors as er##/##. P1 raises errors as er## where the first group is the error - # code, and the second group is the trace information. - # Beyond that, specific errors may be added for individual channels and modules. These - # are formatted as P1##/## H0##/##, etc. These items are added programmatically as - # named capturing groups to the regex. + Code: 06 + """ - 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"]: - exp += f" ?(?:{module}(?P<{module}>[0-9]{{2}}/[0-9]{{2}}))?" - errors = re.search(exp, resp) - else: - # Other modules send errors as er##, and do not contain slave errors. - exp = f"er(?P<{module}>[0-9]{{2}})" - errors = re.search(exp, resp) - if errors is not None: - # filter None elements - 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"]} +class TipAlreadyFittedError(STARModuleError): + """ Tip already fitted - has_error = not (errors is None or len(errors_dict) == 0) - if has_error: - he = HamiltonFirmwareError(errors_dict, raw_response=resp) + Possible cause(s): + Repeated attempts to fit a tip or iSwap movement with tips - # If there is a faulty parameter error, request which parameter that is. - for module_name, error in he.items(): - if error.message == "Unknown parameter": - # 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 + Code: 07 + """ - # pylint: disable=unnecessary-dict-index-lookup - he[module_name].message += " (call lh.backend.request_name_of_last_faulty_parameter)" - raise he +class HamiltonNoTipError(STARModuleError): + """ No tips - info = self.parse_fw_string(resp, fmt) - return info + Possible cause(s): + command was started without fitting tip (tip was not fitted or fell off again) - async def send_command( - self, - module: str, - command: str, - tip_pattern: Optional[List[bool]] = None, - write_timeout: Optional[int] = None, - read_timeout: Optional[int] = None, - fmt: str = "", - wait = True, - **kwargs - ): - """ Send a firmware command to the Hamilton machine. + Code: 08 + """ - Args: - module: 2 character module identifier (C0 for master, ...) - command: 2 character command identifier (QM for request status) - write_timeout: write timeout in seconds. If None, `self.write_timeout` is used. - read_timeout: read timeout in seconds. If None, `self.read_timeout` is used. - fmt: A string containing the format of the response. If None, just the id parameter is read. - wait: If True, wait for a response. If False, return `None` immediately after sending the - command. - kwargs: any named parameters. The parameter name should also be 2 characters long. The value - can be of any size. - Raises: - HamiltonFirmwareError: if an error response is received. +class NoCarrierError(STARModuleError): + """ No carrier - Returns: - A dictionary containing the parsed response, or None if no response was read within `timeout`. - """ + Possible cause(s): + load command without carrier - cmd, id_ = self._assemble_command(module=module, command=command, tip_pattern=tip_pattern, - **kwargs) - return await self._write_and_read_command(id_=id_, cmd=cmd, fmt=fmt, - write_timeout=write_timeout, read_timeout=read_timeout, wait=wait) + Code: 09 + """ - async def _write_and_read_command( - self, - id_: str, - cmd: str, - fmt: str = "", - write_timeout: Optional[int] = None, - read_timeout: Optional[int] = None, - wait: bool = True - ) -> Optional[dict]: - """ Write a command to the Hamilton machine and read the response. """ - self.write(cmd, timeout=write_timeout) - if not wait: - return None +class NotCompletedError(STARModuleError): + """ Not completed - # Attempt to read packets until timeout, or when we identify the right id. - if read_timeout is None: - read_timeout = self.read_timeout + Possible cause(s): + Command in command buffer was aborted due to an error in a previous command, or command stack + was deleted. - loop = asyncio.get_event_loop() - fut = loop.create_future() - self._start_reading(id_, loop, fut, cmd, fmt, read_timeout) - result = await fut - return cast(dict, result) # Futures are generic in Python 3.9, but not in 3.8, so we need cast. + Code: 10 + """ - def _start_reading( - self, - id_: str, - loop: asyncio.AbstractEventLoop, - fut: asyncio.Future, - cmd: str, - fmt: str, - timeout: int) -> None: - """ Submit a task to the reading thread. Starts reading thread if it is not already running. """ - - timeout_time = time.time() + timeout - self._waiting_tasks[id_] = (loop, fut, cmd, fmt, timeout_time) - - # Start reading thread if it is not already running. - if len(self._waiting_tasks) == 1: - self._reading_thread = threading.Thread(target=self._continuously_read) - self._reading_thread.start() - - def _continuously_read(self) -> None: - """ Continuously read from the USB port until all tasks are completed. - - Tasks are stored in the `self._waiting_tasks` dictionary, and contain a future that will be - completed when the task is finished. Tasks are submitted to the dictionary using the - `self._start_reading` method. - - On each iteration, read the USB port. If a response is received, parse it and check if it is - relevant to any of the tasks. If so, complete the future and remove the task from the - dictionary. If a task has timed out, complete the future with a `TimeoutError`. + +class DispenseWithPressureLLDError(STARModuleError): + """ Dispense with pressure LLD + + Possible cause(s): + dispense with pressure LLD is not permitted + + Code: 11 + """ + + +class NoTeachInSignalError(STARModuleError): + """ No Teach In Signal + + Possible cause(s): + X-Movement to LLD reached maximum allowable position with- out detecting Teach in signal + + Code: 12 + """ + + +class LoadingTrayError(STARModuleError): + """ Loading Tray error + + Possible cause(s): + position already occupied + + Code: 13 + """ + + +class SequencedAspirationWithPressureLLDError(STARModuleError): + """ Sequenced aspiration with pressure LLD + + Possible cause(s): + sequenced aspiration with pressure LLD is not permitted + + Code: 14 + """ + + +class NotAllowedParameterCombinationError(STARModuleError): + """ Not allowed parameter combination + + Possible cause(s): + i.e. PLLD and dispense or wrong X-drive assignment + + Code: 15 + """ + + +class CoverCloseError(STARModuleError): + """Cover close error + + Possible cause(s): + cover is not closed and couldn't be locked + + Code: 16 + """ + + +class AspirationError(STARModuleError): + """ Aspiration error + + Possible cause(s): + aspiration liquid stream error detected + + Code: 17 + """ + + +class WashFluidOrWasteError(STARModuleError): + """Wash fluid or trash error + + Possible cause(s): + 1. missing wash fluid + 2. trash of particular washer is full + + Code: 18 + """ + + +class IncubationError(STARModuleError): + """ Incubation error + + Possible cause(s): + incubator temperature out of limit + + Code: 19 + """ + + +class TADMMeasurementError(STARModuleError): + """TADM measurement error + + Possible cause(s): + overshoot of limits during aspiration or dispensation + + Code: 20, 26 + """ + + +class NoElementError(STARModuleError): + """ No element + + Possible cause(s): + expected element not detected + + Code: 21 + """ + + +class ElementStillHoldingError(STARModuleError): + """Element still holding + + Possible cause(s): + "Get command" is sent twice or element is not droped expected element is missing (lost) + + Code: 22 + """ + + +class ElementLostError(STARModuleError): + """ Element lost + + Possible cause(s): + expected element is missing (lost) + + Code: 23 + """ + + +class IllegalTargetPlatePositionError(STARModuleError): + """Illegal target plate position + + Possible cause(s): + 1. over or underflow of iSWAP positions + 2. iSWAP is not in park position during pipetting activities + + Code: 24 + """ + + +class IllegalUserAccessError(STARModuleError): + """Illegal user access + + Possible cause(s): + carrier was manually removed or cover is open (immediate stop is executed) + + Code: 25 + """ + + +class PositionNotReachableError(STARModuleError): + """Position not reachable + + Possible cause(s): + position out of mechanical limits using iSWAP, CoRe gripper or PIP-channels + + Code: 27 + """ + + +class UnexpectedLLDError(STARModuleError): + """ unexpected LLD + + Possible cause(s): + liquid level is reached before LLD scanning is started (using PIP or XL channels) + + Code: 28 + """ + + +class AreaAlreadyOccupiedError(STARModuleError): + """ area already occupied + + Possible cause(s): + Its impossible to occupy area because this area is already in use + + Code: 29 + """ + + +class ImpossibleToOccupyAreaError(STARModuleError): + """ impossible to occupy area + + Possible cause(s): + Area cant be occupied because is no solution for arm prepositioning + + Code: 30 + """ + + +class AntiDropControlError(STARModuleError): + """ + Anti drop controlling out of tolerance. (VENUS only) + + Code: 31 + """ + + +class DecapperError(STARModuleError): + """ + Decapper lock error while screw / unscrew a cap by twister channels. (VENUS only) + + Code: 32 + """ + + +class DecapperHandlingError(STARModuleError): + """ + Decapper station error while lock / unlock a cap. (VENUS only) + + Code: 33 + """ + + +class SlaveError(STARModuleError): + """ Slave error + + Possible cause(s): + This error code indicates an error in one of slaves. (for error handling purpose using service + software macro code) + + Code: 99 + """ + + +class WrongCarrierError(STARModuleError): + """ + Wrong carrier barcode detected. (VENUS only) + + Code: 100 + """ + + +class NoCarrierBarcodeError(STARModuleError): + """ + Carrier barcode could not be read or is missing. (VENUS only) + + Code: 101 + """ + + +class LiquidLevelError(STARModuleError): + """ + Liquid surface not detected. (VENUS only) + + This error is created from main / slave error 06/70, 06/73 and 06/87. + + Code: 102 + """ + + +class NotDetectedError(STARModuleError): + """ + Carrier not detected at deck end position. (VENUS only) + + Code: 103 + """ + + +class NotAspiratedError(STARModuleError): + """ + Dispense volume exceeds the aspirated volume. (VENUS only) + + This error is created from main / slave error 02/54. + + Code: 104 + """ + + +class ImproperDispensationError(STARModuleError): + """ + The dispensed volume is out of tolerance (may only occur for Nano Pipettor Dispense steps). + (VENUS only) + + This error is created from main / slave error 02/52 and 02/54. + + Code: 105 + """ + + +class NoLabwareError(STARModuleError): + """ + The labware to be loaded was not detected by autoload module. (VENUS only) + + Note: + + May only occur on a Reload Carrier step if the labware property 'MlStarCarPosAreRecognizable' is + set to 1. + + Code: 106 + """ + + +class UnexpectedLabwareError(STARModuleError): + """ + The labware contains unexpected barcode ( may only occur on a Reload Carrier step ). (VENUS only) + + Code: 107 + """ + + +class WrongLabwareError(STARModuleError): + """ + The labware to be reloaded contains wrong barcode ( may only occur on a Reload Carrier step ). + (VENUS only) + + Code: 108 + """ + + +class BarcodeMaskError(STARModuleError): + """ + The barcode read doesn't match the barcode mask defined. (VENUS only) + + Code: 109 + """ + + +class BarcodeNotUniqueError(STARModuleError): + """ + The barcode read is not unique. Previously loaded labware with same barcode was loaded without + unique barcode check. (VENUS only) + + Code: 110 + """ + + +class BarcodeAlreadyUsedError(STARModuleError): + """ + The barcode read is already loaded as unique barcode ( it's not possible to load the same barcode + twice ). (VENUS only) + + Code: 111 + """ + + +class KitLotExpiredError(STARModuleError): + """ + Kit Lot expired. (VENUS only) + + Code: 112 + """ + + +class DelimiterError(STARModuleError): + """ + Barcode contains character which is used as delimiter in result string. (VENUS only) + + Code: 113 + """ + + +class UnknownHamiltonError(STARModuleError): + """ Unknown error """ + + +def _module_id_to_module_name(id_): + """ Convert a module ID to a module name. """ + return { + "C0": "Master", + "X0": "X-drives", + "I0": "Auto Load", + "W1": "Wash station 1-3", + "W2": "Wash station 4-6", + "T1": "Temperature carrier 1", + "T2": "Temperature carrier 2", + "R0": "ISWAP", + "P1": "Pipetting channel 1", + "P2": "Pipetting channel 2", + "P3": "Pipetting channel 3", + "P4": "Pipetting channel 4", + "P5": "Pipetting channel 5", + "P6": "Pipetting channel 6", + "P7": "Pipetting channel 7", + "P8": "Pipetting channel 8", + "P9": "Pipetting channel 9", + "PA": "Pipetting channel 10", + "PB": "Pipetting channel 11", + "PC": "Pipetting channel 12", + "PD": "Pipetting channel 13", + "PE": "Pipetting channel 14", + "PF": "Pipetting channel 15", + "PG": "Pipetting channel 16", + "H0": "CoRe 96 Head", + "HW": "Pump station 1 station", + "HU": "Pump station 2 station", + "HV": "Pump station 3 station", + "N0": "Nano dispenser", + "D0": "384 dispensing head", + "NP": "Nano disp. pressure controller", + "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. """ + codes = { + 1: CommandSyntaxError, + 2: HardwareError, + 3: CommandNotCompletedError, + 4: ClotDetectedError, + 5: BarcodeUnreadableError, + 6: TipTooLittleVolumeError, + 7: TipAlreadyFittedError, + 8: HamiltonNoTipError, + 9: NoCarrierError, + 10: NotCompletedError, + 11: DispenseWithPressureLLDError, + 12: NoTeachInSignalError, + 13: LoadingTrayError, + 14: SequencedAspirationWithPressureLLDError, + 15: NotAllowedParameterCombinationError, + 16: CoverCloseError, + 17: AspirationError, + 18: WashFluidOrWasteError, + 19: IncubationError, + 20: TADMMeasurementError, + 21: NoElementError, + 22: ElementStillHoldingError, + 23: ElementLostError, + 24: IllegalTargetPlatePositionError, + 25: IllegalUserAccessError, + 26: TADMMeasurementError, + 27: PositionNotReachableError, + 28: UnexpectedLLDError, + 29: AreaAlreadyOccupiedError, + 30: ImpossibleToOccupyAreaError, + 31: AntiDropControlError, + 32: DecapperError, + 33: DecapperHandlingError, + 99: SlaveError, + 100: WrongCarrierError, + 101: NoCarrierBarcodeError, + 102: LiquidLevelError, + 103: NotDetectedError, + 104: NotAspiratedError, + 105: ImproperDispensationError, + 106: NoLabwareError, + 107: UnexpectedLabwareError, + 108: WrongLabwareError, + 109: BarcodeMaskError, + 110: BarcodeNotUniqueError, + 111: BarcodeAlreadyUsedError, + 112: KitLotExpiredError, + 113: DelimiterError + } + if code in codes: + return codes[code] + return UnknownHamiltonError + + +def trace_information_to_string(module_identifier: str, trace_information: int) -> str: + """ Convert a trace identifier to an error message. """ + table = None + + if module_identifier == "C0": + table = { + 10: "CAN error", + 11: "Slave command time out", + 20: "E2PROM error", + 30: "Unknown command", + 31: "Unknown parameter", + 32: "Parameter out of range", + 33: "Parameter does not belong to command, or not all parameters were sent", + 34: "Node name unknown", + 35: "id parameter error", + 37: "node name defined twice", + 38: "faulty XL channel settings", + 39: "faulty robotic channel settings", + 40: "PIP task busy", + 41: "Auto load task busy", + 42: "Miscellaneous task busy", + 43: "Incubator task busy", + 44: "Washer task busy", + 45: "iSWAP task busy", + 46: "CoRe 96 head task busy", + 47: "Carrier sensor doesn't work properly", + 48: "CoRe 384 head task busy", + 49: "Nano pipettor task busy", + 50: "XL channel task busy", + 51: "Tube gripper task busy", + 52: "Imaging channel task busy", + 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"]: + table = { + 0: "No error", + 20: "No communication to EEPROM", + 30: "Unknown command", + 31: "Unknown parameter", + 32: "Parameter out of range", + 35: "Voltages outside permitted range", + 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)", + 50: "Dispensing drive init. position not found", + 51: "Dispensing drive not initialized", + 52: "Dispensing drive movement error", + 53: "Maximum volume in tip reached", + 54: "Position outside of permitted area", + 55: "Y-drive blocked", + 56: "Y-drive not initialized", + 57: "Y-drive movement error", + 60: "X-drive blocked", + 61: "X-drive not initialized", + 62: "X-drive movement error", + 63: "X-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)", + 72: "Auto calibration at pressure (Sensor not possible)", + 73: "No liquid level found with dual LLD", + 74: "Liquid at a not allowed position detected", + 75: "No tip picked up, possibly because no was present at specified position", + 76: "Tip already picked up", + 77: "Tip not droped", + 78: "Wrong tip picked up", + 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: "No communication to digital potentiometer", + 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)", + 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" + } + elif module_identifier == "H0": # Core 96 head + table = { + 20: "No communication to EEPROM", + 30: "Unknown command", + 31: "Unknown parameter", + 32: "Parameter out of range", + 35: "Voltage outside permitted range", + 36: "Stop during execution of command", + 37: "The adjustment sensor did not switch", + 40: "No parallel processes permitted", + 50: "Dispensing drive initialization failed", + 51: "Dispensing drive not initialized", + 52: "Dispensing drive movement error", + 53: "Maximum volume in tip reached", + 54: "Position out of permitted area", + 55: "Y drive initialization failed", + 56: "Y drive not initialized", + 57: "Y drive movement error", + 58: "Y drive position outside of permitted area", + 60: "Z drive initialization failed", + 61: "Z drive not initialized", + 62: "Z drive movement error", + 63: "Z drive position outside of permitted area", + 65: "Squeezer drive initialization failed", + 66: "Squeezer drive not initialized", + 67: "Squeezer drive movement error: drive blocked or incremental sensor fault", + 68: "Squeezer drive position outside of permitted area", + 70: "No liquid level found", + 71: "Not enough liquid present", + 75: "No tip picked up", + 76: "Tip already picked up", + 81: "Clot detected", + } + elif module_identifier == "R0": # iswap + table = { + 20: "No communication to EEPROM", + 30: "Unknown command", + 31: "Unknown parameter", + 32: "Parameter out of range", + 33: "FW doesn't match to HW", + 36: "Stop during execution of command", + 37: "The adjustment sensor did not switch", + 38: "The adjustment sensor cannot be searched", + 40: "No parallel processes permitted", + 41: "No parallel processes permitted", + 42: "No parallel processes permitted", + 50: "Y-drive Initialization failed", + 51: "Y-drive not initialized", + 52: "Y-drive movement error: drive locked or incremental sensor fault", + 53: "Y-drive movement error: position counter over/underflow", + 60: "Z-drive initialization failed", + 61: "Z-drive not initialized", + 62: "Z-drive movement error: drive locked or incremental sensor fault", + 63: "Z-drive movement error: position counter over/underflow", + 70: "Rotation-drive initialization failed", + 71: "Rotation-drive not initialized", + 72: "Rotation-drive movement error: drive locked or incremental sensor fault", + 73: "Rotation-drive movement error: position counter over/underflow", + 80: "Wrist twist drive initialization failed", + 81: "Wrist twist drive not initialized", + 82: "Wrist twist drive movement error: drive locked or incremental sensor fault", + 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", + 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" + } + + if table is not None and trace_information in table: + return table[trace_information] + + return f"Unknown trace information code {trace_information:02}" + + +class STARFirmwareError(HamiltonFirmwareError): + """ + All Hamilton machine errors. + + Example: + >>> try: + ... lh.pick_up_tips([True, True, True]) + ... except STARFirmwareError as e: + ... print(e) + STARFirmwareError({ + 'Pipetting channel 1': NoTipError('Tip already picked up'), + 'Pipetting channel 3': NoTipError('Tip already picked up'), + }) + + >>> try: + ... lh.pick_up_tips([True, False, True]) + ... except STARFirmwareError as e: + ... if 'Pipetting channel 1' in e: + ... print('Pipetting channel 1 error: ', e['Pipetting channel 1'], e.error_code) + Pipetting channel 1 error: NoTipError('Tip already picked up'), '08/76' + """ + + def __init__(self, errors: Dict[str, STARModuleError], raw_response: Optional[str] = None): + self.raw_response = raw_response + self.errors = errors + + def __str__(self) -> str: + return f"STARFirmwareError(errors={self.errors}, raw_response={self.raw_response})" + + def __repr__(self) -> str: + return str(self) + + def __len__(self) -> int: + return len(self.errors) + + def __getitem__(self, key: str): + return self.errors[key] + + def __setitem__(self, key: str, value: STARModuleError): + self.errors[key] = value + + def __contains__(self, key: str) -> bool: + return key in self.errors + + def items(self) -> ItemsView[str, STARModuleError]: + return self.errors.items() + + def error_for_channel(self, channel: int) -> Optional[STARModuleError]: + """ Return the error for a given channel. + + .. warning:: + Channel here is 1-indexed, like the firmware API, but STAR uses 0-indexed channels. """ - logger.debug("Starting reading thread...") + return self.errors.get(f"Pipetting channel {channel}") - while len(self._waiting_tasks) > 0: - for id_, (loop, fut, cmd, fmt, timeout_time) in self._waiting_tasks.items(): - if time.time() > timeout_time: - logger.warning("Timeout while waiting for response to command %s.", cmd) - loop.call_soon_threadsafe(fut.set_exception, - TimeoutError(f"Timeout while waiting for response to command {cmd}.")) - del self._waiting_tasks[id_] - break - try: - resp = self.read().decode("utf-8") - except TimeoutError: - continue +def star_firmware_string_to_error( + error_code_dict: Dict[str, str], + raw_response: Optional[str] = None, +) -> STARFirmwareError: + """ Convert a firmware string to a STARFirmwareError. """ + + errors = {} - # Parse response. - try: - parsed_response = self.parse_fw_string(resp) - logger.info("Received response: %s", resp) - except ValueError: - if resp != "": - logger.warning("Could not parse response: %s", resp) + for module_id, error in error_code_dict.items(): + module_name = _module_id_to_module_name(module_id) + 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 continue + error_class = error_code_to_exception(error_code) + else: + # Slave modules: er## (just trace information) + 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) - for id_, (loop, fut, cmd, fmt, timeout_time) in self._waiting_tasks.items(): - if "id" in parsed_response and f"{parsed_response['id']:04}" == id_: - try: - parsed = self.parse_response(resp, fmt) - except HamiltonFirmwareError as e: - loop.call_soon_threadsafe(fut.set_exception, e) - else: - if fmt is not None and fmt != "": - loop.call_soon_threadsafe(fut.set_result, parsed) - else: - loop.call_soon_threadsafe(fut.set_result, resp) - del self._waiting_tasks[id_] - break + # If the master error is a SlaveError, remove it from the errors dict. + if isinstance(errors.get("Master"), SlaveError): + errors.pop("Master") - self._reading_thread = None - logger.debug("Reading thread stopped.") + return STARFirmwareError(errors=errors, raw_response=raw_response) class STAR(HamiltonLiquidHandler): @@ -548,11 +1054,10 @@ def __init__( device_address=device_address, packet_read_timeout=packet_read_timeout, read_timeout=read_timeout, - write_timeout=write_timeout) + write_timeout=write_timeout, + id_product=0x8000) - self._tth2tti: dict[int, int] = {} # hash to tip type index self._iswap_parked: Optional[bool] = None - self._num_channels: Optional[int] = None @property @@ -562,6 +1067,10 @@ def num_channels(self) -> int: raise RuntimeError("has not loaded num_channels, forgot to call `setup`?") return self._num_channels + @property + def module_id_length(self): + return 2 + def serialize(self) -> dict: return { **super().serialize(), @@ -574,6 +1083,92 @@ def serialize(self) -> dict: def iswap_parked(self) -> bool: return self._iswap_parked is True + 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####") + 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. + + Raises: + ValueError: if the format string is incompatible with the response. + HamiltonException: if the response contains an error. + """ + + # Parse errors. + module = resp[:2] + if module == "C0": + # C0 sends errors as er##/##. P1 raises errors as er## where the first group is the error + # code, and the second group is the trace information. + # Beyond that, specific errors may be added for individual channels and modules. These + # are formatted as P1##/## H0##/##, etc. These items are added programmatically as + # 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"]: + exp += f" ?(?:{module}(?P<{module}>[0-9]{{2}}/[0-9]{{2}}))?" + errors = re.search(exp, resp) + else: + # Other modules send errors as er##, and do not contain slave errors. + exp = f"er(?P<{module}>[0-9]{{2}})" + errors = re.search(exp, resp) + + if errors is not None: + # filter None elements + 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"]} + + has_error = not (errors is None or len(errors_dict) == 0) + if has_error: + he = star_firmware_string_to_error(error_code_dict=errors_dict, raw_response=resp) + + # If there is a faulty parameter error, request which parameter that is. + for module_name, error in he.items(): + if error.message == "Unknown parameter": + # 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 + + # pylint: disable=unnecessary-dict-index-lookup + he[module_name].message += " (call lh.backend.request_name_of_last_faulty_parameter)" + + raise he + + async def send_command( + self, + module: str, + command: str, + tip_pattern: Optional[List[bool]] = None, + write_timeout: Optional[int] = None, + read_timeout: Optional[int] = None, + wait = True, + fmt: str = "", + **kwargs + ): + """ Send a command to the machine. Parse the response if `fmt != ""`, else return the raw + response. """ + + resp = await super().send_command( + module=module, + command=command, + tip_pattern=tip_pattern, + write_timeout=write_timeout, + read_timeout=read_timeout, + wait=wait, + **kwargs + ) + if fmt != "": + parsed = parse_star_fw_string(resp, fmt) + return parsed + return resp + async def setup(self): """ setup @@ -625,105 +1220,6 @@ async def setup(self): await self.park_iswap() self._iswap_parked = True - async def stop(self): - self._waiting_tasks.clear() - - # ============== Tip Types ============== - - async def get_or_assign_tip_type_index(self, tip: HamiltonTip) -> int: - """ Get a tip type table index for the tip. - - If the tip has previously been defined, used that index. Otherwise, define a new tip type. - """ - - tip_type_hash = hash(tip) - - if tip_type_hash not in self._tth2tti: - ttti = len(self._tth2tti) + 1 - if ttti > 99: - raise ValueError("Too many tip types defined.") - - await self.define_tip_needle( - tip_type_table_index=ttti, - filter=tip.has_filter, - tip_length=int((tip.total_tip_length - tip.fitting_depth) * 10), # in 0.1mm - maximum_tip_volume=int(tip.maximal_volume * 10), # in 0.1ul - tip_size=tip.tip_size, - pickup_method=tip.pickup_method - ) - self._tth2tti[tip_type_hash] = ttti - - return self._tth2tti[tip_type_hash] - - def _get_hamilton_tip(self, tip_spots: List[TipSpot]) -> HamiltonTip: - """ Get the single tip type for all tip spots. If it does not exist or is not a HamiltonTip, - raise an error. """ - tips = set(tip_spot.get_tip() for tip_spot in tip_spots) - if len(tips) > 1: - raise ValueError("Cannot mix tips with different tip types.") - if len(tips) == 0: - raise ValueError("No tips specified.") - tip = tips.pop() - if not isinstance(tip, HamiltonTip): - raise ValueError(f"Tip {tip} is not a HamiltonTip.") - return tip - - async def get_ttti(self, tip_spots: List[TipSpot]) -> int: - """ Get tip type table index for a list of tips. - - Ensure that for all non-None tips, they have the same tip type, and return the tip type table - index for that tip type. - """ - - tip = self._get_hamilton_tip(tip_spots) - return await self.get_or_assign_tip_type_index(tip) - - def _ops_to_fw_positions( - self, - ops: Sequence[PipettingOp], - use_channels: List[int] - ) -> Tuple[List[int], List[int], List[bool]]: - """ use_channels is a list of channels to use. STAR expects this in one-hot encoding. This is - method converts that, and creates a matching list of x and y positions. """ - assert use_channels == sorted(use_channels), "Channels must be sorted." - - x_positions: List[int] = [] - y_positions: List[int] = [] - channels_involved: List[bool] = [] - for i, channel in enumerate(use_channels): - while channel > len(channels_involved): - channels_involved.append(False) - x_positions.append(0) - y_positions.append(0) - channels_involved.append(True) - offset = ops[i].offset - - x_pos = ops[i].resource.get_absolute_location().x - if offset is None or isinstance(ops[i].resource, (TipSpot, Well)): - x_pos += ops[i].resource.center().x - if offset is not None: - x_pos += offset.x - x_positions.append(int(x_pos*10)) - - y_pos = ops[i].resource.get_absolute_location().y - if offset is None or isinstance(ops[i].resource, (TipSpot, Well)): - y_pos += ops[i].resource.center().y - if offset is not None: - y_pos += offset.y - y_positions.append(int(y_pos*10)) - - if len(ops) > self.num_channels: - raise ValueError(f"Too many channels specified: {len(ops)} > {self.num_channels}") - - if len(x_positions) < self.num_channels: - # We do want to have a trailing zero on x_positions, y_positions, and channels_involved, for - # some reason, if the length < 8. - x_positions = x_positions + [0] - y_positions = y_positions + [0] - channels_involved = channels_involved + [False] - - return x_positions, y_positions, channels_involved - # ============== LiquidHandlerBackend methods ============== @need_iswap_parked @@ -737,7 +1233,11 @@ async def pick_up_tips( x_positions, y_positions, channels_involved = \ self._ops_to_fw_positions(ops, use_channels) - ttti = await self.get_ttti([op.resource for op in ops]) + tip_spots = [op.resource for op in ops] + tips = set(cast(HamiltonTip, tip_spot.get_tip()) for tip_spot in tip_spots) + if len(tips) > 1: + raise ValueError("Cannot mix tips with different tip types.") + ttti = (await self.get_ttti(list(tips)))[0] max_z = max(op.resource.get_absolute_location().z + \ (op.offset.z if op.offset is not None else 0) for op in ops) @@ -761,14 +1261,14 @@ async def pick_up_tips( minimum_traverse_height_at_beginning_of_a_command=2450, pickup_method=tip.pickup_method, ) - except HamiltonFirmwareError as e: + except STARFirmwareError as e: tip_already_fitted_errors: List[int] = [] no_tip_present_errors: List[int] = [] for i in range(1, self.num_channels+1): channel_error = e.error_for_channel(i) if channel_error is None: continue - if isinstance(channel_error, herrors.TipAlreadyFittedError): + if isinstance(channel_error, TipAlreadyFittedError): tip_already_fitted_errors.append(i-1) elif channel_error.trace_information in [75]: no_tip_present_errors.append(i-1) @@ -822,11 +1322,11 @@ async def drop_tips( z_position_at_end_of_a_command=2450, discarding_method=drop_method ) - except HamiltonFirmwareError as e: + except STARFirmwareError as e: tip_errors: List[int] = [] for i in range(1, self.num_channels+1): channel_error = e.error_for_channel(i) - if isinstance(channel_error, herrors.NoTipError): + if isinstance(channel_error, HamiltonNoTipError): tip_errors.append(i-1) if len(tip_errors) > 0: @@ -834,19 +1334,6 @@ async def drop_tips( raise e - def _get_tip_max_volumes(self, ops: Sequence[Union[Aspiration, Dispense]]) -> List[float]: - """ These tip volumes (mostly with 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. """ - - return [ - { 360.0: 300.0, - 1065.0: 1000.0, - 1250.0: 1000.0, - 4367.0: 4000.0, - 5420.0: 5000.0, - }.get(op.tip.maximal_volume, op.tip.maximal_volume) for op in ops] - def _assert_valid_resources(self, resources: Sequence[Resource]) -> None: """ Assert that resources are in a valid location for pipetting. """ for resource in resources: @@ -973,19 +1460,16 @@ async def aspirate( n = len(ops) - # convert max volumes - tip_max_volumes = self._get_tip_max_volumes(ops) - hamilton_liquid_classes = [ - get_liquid_class( - tip_volume=int(tmv), + get_star_liquid_class( + tip_volume=op.tip.maximal_volume, is_core=False, is_tip=True, has_filter=op.tip.has_filter, liquid=op.liquid or Liquid.WATER, jet=False, # for aspiration empty=False # for aspiration - ) for tmv, op in zip(tip_max_volumes, ops)] + ) for op in ops] self._assert_valid_resources([op.resource for op in ops]) @@ -1107,7 +1591,7 @@ async def aspirate( minimum_traverse_height_at_beginning_of_a_command, min_z_endpos=min_z_endpos, ) - except HamiltonFirmwareError as e: + except STARFirmwareError as e: tll: List[int] = [] tlv: List[int] = [] for i in range(1, self.num_channels+1): @@ -1218,9 +1702,6 @@ async def dispense( n = len(ops) - # convert max volumes - tip_max_volumes = self._get_tip_max_volumes(ops) - def should_jet(op): if op.liquid_height is None: return True @@ -1231,8 +1712,8 @@ def should_jet(op): return False hamilton_liquid_classes = [ - get_liquid_class( - tip_volume=int(tmv), + get_star_liquid_class( + tip_volume=op.tip.maximal_volume, is_core=False, is_tip=True, has_filter=op.tip.has_filter, @@ -1240,7 +1721,7 @@ def should_jet(op): jet=should_jet(op), # dispensing all, get_used_volume includes pending empty=op.tip.tracker.get_used_volume() == 0 - ) for tmv, op in zip(tip_max_volumes, ops)] + ) for op in ops] # correct volumes using the liquid class for op, hlc in zip(ops, hamilton_liquid_classes): @@ -1343,7 +1824,7 @@ def dispensing_mode_for_op(op: Dispense) -> int: min_z_endpos=min_z_endpos, side_touch_off_distance=side_touch_off_distance, ) - except HamiltonFirmwareError as e: + except STARFirmwareError as e: tll: List[int] = [] for i in range(1, self.num_channels+1): channel_error = e.error_for_channel(i) @@ -1878,9 +2359,9 @@ async def move_resource(self, move: Move): previous_location = location await self.release_picked_up_resource( - location=move.to, + location=move.destination, resource=move.resource, - offset=move.to_offset, + 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= @@ -1917,7 +2398,7 @@ async def pre_initialize_instrument(self): async def define_tip_needle( self, tip_type_table_index: int, - filter: bool, + has_filter: bool, tip_length: int, maximum_tip_volume: int, tip_size: TipSize, @@ -1927,7 +2408,7 @@ async def define_tip_needle( Args: tip_type_table_index: tip_table_index - filter: with(out) filter + has_filter: with(out) filter tip_length: Tip length [0.1mm] maximum_tip_volume: Maximum volume of tip [0.1ul] Note! it's automatically limited to max. channel capacity @@ -1948,7 +2429,7 @@ async def define_tip_needle( module="C0", command="TT", tt=f"{tip_type_table_index:02}", - tf=filter, + tf=has_filter, tl=f"{tip_length:04}", tv=f"{maximum_tip_volume:05}", tg=tip_size.value, diff --git a/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py b/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py index 12b940bdb0..e432ecdc4f 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py +++ b/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py @@ -1,4 +1,4 @@ -""" Tests for Hamilton backend. """ +""" Tests for the Hamilton STAR backend. """ from typing import cast import unittest @@ -25,11 +25,12 @@ from tests.usb import MockDev, MockEndpoint -from .STAR import STAR -from .errors import ( +from .STAR import ( + STAR, + parse_star_fw_string, + STARFirmwareError, CommandSyntaxError, - HamiltonFirmwareError, - NoTipError, + HamiltonNoTipError, HardwareError, UnknownHamiltonError ) @@ -64,45 +65,45 @@ def setUp(self): self.star = STAR() def test_parse_response_params(self): - parsed = self.star.parse_response("C0QMid1111", "") + parsed = parse_star_fw_string("C0QMid1111", "") self.assertEqual(parsed, {"id": 1111}) - parsed = self.star.parse_response("C0QMid1111", "id####") + parsed = parse_star_fw_string("C0QMid1111", "id####") self.assertEqual(parsed, {"id": 1111}) - parsed = self.star.parse_response("C0QMid1112aaabc", "aa&&&") + parsed = parse_star_fw_string("C0QMid1112aaabc", "aa&&&") self.assertEqual(parsed, {"id": 1112, "aa": "abc"}) - parsed = self.star.parse_response("C0QMid1112aa-21", "aa##") + parsed = parse_star_fw_string("C0QMid1112aa-21", "aa##") self.assertEqual(parsed, {"id": 1112, "aa": -21}) - parsed = self.star.parse_response("C0QMid1113pqABC", "pq***") + parsed = parse_star_fw_string("C0QMid1113pqABC", "pq***") self.assertEqual(parsed, {"id": 1113, "pq": int("ABC", base=16)}) with self.assertRaises(ValueError): # should fail with auto-added id. - parsed = self.star.parse_response("C0QMaaabc", "") + parsed = parse_star_fw_string("C0QMaaabc", "") self.assertEqual(parsed, "") with self.assertRaises(ValueError): - self.star.parse_response("C0QM", "id####") # pylint: disable=expression-not-assigned + parse_star_fw_string("C0QM", "id####") # pylint: disable=expression-not-assigned with self.assertRaises(ValueError): - self.star.parse_response("C0RV", "") # pylint: disable=expression-not-assigned + parse_star_fw_string("C0RV", "") # pylint: disable=expression-not-assigned def test_parse_response_no_errors(self): - parsed = self.star.parse_response("C0QMid1111", "") + parsed = parse_star_fw_string("C0QMid1111", "") self.assertEqual(parsed, {"id": 1111}) - parsed = self.star.parse_response("C0QMid1111 er00/00", "") + parsed = parse_star_fw_string("C0QMid1111 er00/00", "") self.assertEqual(parsed, {"id": 1111}) - parsed = self.star.parse_response("C0QMid1111 er00/00 P100/00", "") + parsed = parse_star_fw_string("C0QMid1111 er00/00 P100/00", "") self.assertEqual(parsed, {"id": 1111}) def test_parse_response_master_error(self): - with self.assertRaises(HamiltonFirmwareError) as ctx: - self.star.parse_response("C0QMid1111 er01/30", "") + with self.assertRaises(STARFirmwareError) as ctx: + self.star.check_fw_string_error("C0QMid1111 er01/30") e = ctx.exception self.assertEqual(len(e), 1) assert "Master" in e @@ -110,8 +111,8 @@ def test_parse_response_master_error(self): self.assertEqual(e["Master"].message, "Unknown command") def test_parse_response_slave_errors(self): - with self.assertRaises(HamiltonFirmwareError) as ctx: - self.star.parse_response("C0QMid1111 er99/00 P100/00 P235/00 P402/98 PG08/76", "") + with self.assertRaises(STARFirmwareError) as ctx: + self.star.check_fw_string_error("C0QMid1111 er99/00 P100/00 P235/00 P402/98 PG08/76") e = ctx.exception self.assertEqual(len(e), 3) assert "Master" not in e @@ -122,15 +123,15 @@ def test_parse_response_slave_errors(self): self.assertIsInstance(e["Pipetting channel 2"], UnknownHamiltonError) self.assertIsInstance(e["Pipetting channel 4"], HardwareError) - self.assertIsInstance(e["Pipetting channel 16"], NoTipError) + self.assertIsInstance(e["Pipetting channel 16"], HamiltonNoTipError) self.assertEqual(e["Pipetting channel 2"].message, "No error") self.assertEqual(e["Pipetting channel 4"].message, "Unknown trace information code 98") self.assertEqual(e["Pipetting channel 16"].message, "Tip already picked up") def test_parse_slave_response_errors(self): - with self.assertRaises(HamiltonFirmwareError) as ctx: - self.star.parse_response("P1OQid1111er30", "") + with self.assertRaises(STARFirmwareError) as ctx: + self.star.check_fw_string_error("P1OQid1111er30") e = ctx.exception self.assertEqual(len(e), 1) @@ -172,7 +173,7 @@ async def test_send_command_plaintext_response(self): class STARCommandCatcher(STAR): - """ Mock backend for star that catches commands and saves them instad of sending them to the + """ Mock backend for star that catches commands and saves them instead of sending them to the machine. """ def __init__(self): @@ -242,7 +243,7 @@ def _assert_command_in_command_buffer(self, cmd: str, should_be: bool, fmt: str) # Command that fits the format, but is not the same as the command we are looking for. similar = None - parsed_cmd = self.mockSTAR.parse_fw_string(cmd, fmt) + parsed_cmd = parse_star_fw_string(cmd, fmt) parsed_cmd.pop("id") for sent_cmd in self.mockSTAR.commands: @@ -251,7 +252,7 @@ def _assert_command_in_command_buffer(self, cmd: str, should_be: bool, fmt: str) continue try: - parsed_sent_cmd = self.mockSTAR.parse_fw_string(sent_cmd, fmt) + parsed_sent_cmd = parse_star_fw_string(sent_cmd, fmt) parsed_sent_cmd.pop("id") if parsed_cmd == parsed_sent_cmd: diff --git a/pylabrobot/liquid_handling/backends/hamilton/__init__.py b/pylabrobot/liquid_handling/backends/hamilton/__init__.py index 0dce853c81..6cd7e3d24a 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/__init__.py +++ b/pylabrobot/liquid_handling/backends/hamilton/__init__.py @@ -1,5 +1,7 @@ """ Hamilton backends for liquid handling. """ +from .base import HamiltonLiquidHandler from .STAR import STAR +from .vantage import Vantage from .pump import Pump # TODO: move elsewhere. diff --git a/pylabrobot/liquid_handling/backends/hamilton/base.py b/pylabrobot/liquid_handling/backends/hamilton/base.py new file mode 100644 index 0000000000..3a6067a2df --- /dev/null +++ b/pylabrobot/liquid_handling/backends/hamilton/base.py @@ -0,0 +1,398 @@ +from abc import ABCMeta, abstractmethod +import asyncio +import datetime +import logging +import threading +import time +from typing import Dict, List, Optional, Sequence, Tuple, TypeVar, cast + +from pylabrobot.liquid_handling.backends.USBBackend import USBBackend +from pylabrobot.liquid_handling.standard import PipettingOp +from pylabrobot.resources import TipSpot, Well +from pylabrobot.resources.ml_star import HamiltonTip, TipPickupMethod, TipSize + +T = TypeVar("T") + +logger = logging.getLogger(__name__) + + +class HamiltonFirmwareError(Exception, metaclass=ABCMeta): + """ Base class for all Hamilton backend errors, raised by firmware. """ + + +class HamiltonLiquidHandler(USBBackend, metaclass=ABCMeta): + """ + Abstract base class for Hamilton liquid handling robot backends. + """ + + @abstractmethod + def __init__( + self, + id_product: int, + device_address: Optional[int] = None, + packet_read_timeout: int = 3, + read_timeout: int = 30, + write_timeout: int = 30, + ): + """ + + Args: + device_address: The USB address of the Hamilton device. Only useful if using more than one + Hamilton device. + packet_read_timeout: The timeout for reading packets from the Hamilton machine in seconds. + read_timeout: The timeout for from the Hamilton machine in seconds. + num_channels: the number of pipette channels present on the robot. + """ + + super().__init__( + address=device_address, + packet_read_timeout=packet_read_timeout, + read_timeout=read_timeout, + write_timeout=write_timeout, + id_vendor=0x08af, + id_product=id_product) + + self.id_ = 0 + + self._reading_thread: Optional[threading.Thread] = None + self._waiting_tasks: Dict[int, + Tuple[asyncio.AbstractEventLoop, asyncio.Future, str, float]] = {} + self._tth2tti: dict[int, int] = {} # hash to tip type index + + async def stop(self): + self._waiting_tasks.clear() + await super().stop() + + @property + @abstractmethod + def module_id_length(self) -> int: + """ The length of the module identifier in firmware commands. """ + + def _generate_id(self) -> int: + """ continuously generate unique ids 0 <= x < 10000. """ + self.id_ += 1 + return self.id_ % 10000 + + def _to_list(self, val: List[T], tip_pattern: List[bool]) -> List[T]: + """ Convert a list of values to a list of values with the correct length. + + This is roughly one-hot encoding. STAR expects a value for a list parameter at the position + for the corresponding channel. If `tip_pattern` is False, there, the value itself is ignored, + but it must be present. + + Args: + val: A list of values, exactly one for each channel that is involved in the operation. + tip_pattern: A list of booleans indicating whether a channel is involved in the operation. + + Returns: + A list of values with the correct length. Each value that is not involved in the operation + is set to the first value in `val`, which is ignored by STAR. + """ + + # use the default value if a channel is not involved, otherwise use the value in val + assert len(val) > 0 + assert len(val) <= len(tip_pattern) + + result: List[T] = [] + arg_index = 0 + for channel_involved in tip_pattern: + if channel_involved: + if arg_index >= len(val): + raise ValueError(f"Too few values for tip pattern {tip_pattern}: {val}") + result.append(val[arg_index]) + arg_index += 1 + else: + # this value will be ignored, so just use a value we know is valid + result.append(val[0]) + if arg_index < len(val): + raise ValueError(f"Too many values for tip pattern {tip_pattern}: {val}") + return result + + def _assemble_command( + self, + module: str, + command: str, + tip_pattern: Optional[List[bool]], + **kwargs) -> Tuple[str, int]: + """ Assemble a firmware command to the Hamilton machine. + + Args: + module: 2 character module identifier (C0 for master, ...) + command: 2 character command identifier (QM for request status, ...) + tip_pattern: A list of booleans indicating whether a channel is involved in the operation. + This value will be used to convert the list values in kwargs to the correct length. + kwargs: any named parameters. the parameter name should also be 2 characters long. The value + can be any size. + + Returns: + A string containing the assembled command. + """ + + cmd = module + command + cmd_id = self._generate_id() + cmd += f"id{cmd_id:04}" # id has to be the first param + + for k, v in kwargs.items(): + if type(v) is datetime.datetime: + v = v.strftime("%Y-%m-%d %h:%M") + elif type(v) is bool: + v = 1 if v else 0 + elif type(v) is list: + # If this command is 'one-hot' encoded, for the channels, then the list should be the + # same length as the 'one-hot' encoding key (tip_pattern.) If the list is shorter than + # that, it will be 'one-hot encoded automatically. Note that this may raise an error if + # the number of values provided is not the same as the number of channels used. + if tip_pattern is not None: + if len(v) != len(tip_pattern): + # convert one-hot encoded list to int list + v = self._to_list(v, tip_pattern) + # list is now of length len(tip_pattern) + if type(v[0]) is bool: # convert bool list to int list + v = [int(x) for x in v] + v = " ".join([str(e) for e in v]) + ("&" if len(v) < self.num_channels else "") + if k.endswith("_"): # workaround for kwargs named in, as, ... + k = k[:-1] + assert len(k) == 2, "Keyword arguments should be 2 characters long, but got: " + k + cmd += f"{k}{v}" + + return cmd, cmd_id + + async def send_command( + self, + module: str, + command: str, + tip_pattern: Optional[List[bool]] = None, + write_timeout: Optional[int] = None, + read_timeout: Optional[int] = None, + wait = True, + **kwargs + ): + """ Send a firmware command to the Hamilton machine. + + Args: + module: 2 character module identifier (C0 for master, ...) + command: 2 character command identifier (QM for request status) + write_timeout: write timeout in seconds. If None, `self.write_timeout` is used. + read_timeout: read timeout in seconds. If None, `self.read_timeout` is used. + wait: If True, wait for a response. If False, return `None` immediately after sending the + command. + kwargs: any named parameters. The parameter name should also be 2 characters long. The value + can be of any size. + + Raises: + HamiltonFirmwareError: if an error response is received. + + Returns: + A dictionary containing the parsed response, or None if no response was read within `timeout`. + """ + + cmd, id_ = self._assemble_command(module=module, command=command, tip_pattern=tip_pattern, + **kwargs) + return await self._write_and_read_command(id_=id_, cmd=cmd, write_timeout=write_timeout, + read_timeout=read_timeout, wait=wait) + + async def _write_and_read_command( + self, + id_: int, + cmd: str, + write_timeout: Optional[int] = None, + read_timeout: Optional[int] = None, + wait: bool = True + ) -> Optional[dict]: + """ Write a command to the Hamilton machine and read the response. """ + self.write(cmd, timeout=write_timeout) + + if not wait: + return None + + # Attempt to read packets until timeout, or when we identify the right id. + if read_timeout is None: + read_timeout = self.read_timeout + + loop = asyncio.get_event_loop() + fut = loop.create_future() + self._start_reading(id_, loop, fut, cmd, read_timeout) + result = await fut + return cast(dict, result) # Futures are generic in Python 3.9, but not in 3.8, so we need cast. + + def _start_reading( + self, + id_: int, + loop: asyncio.AbstractEventLoop, + fut: asyncio.Future, + cmd: str, + timeout: int) -> None: + """ Submit a task to the reading thread. Starts reading thread if it is not already running. """ + + timeout_time = time.time() + timeout + self._waiting_tasks[id_] = (loop, fut, cmd, timeout_time) + + # Start reading thread if it is not already running. + if len(self._waiting_tasks) == 1: + self._reading_thread = threading.Thread(target=self._continuously_read) + self._reading_thread.start() + + @abstractmethod + def get_id_from_fw_response(self, resp: str) -> Optional[int]: + """ Get the id from a firmware response. """ + + @abstractmethod + def check_fw_string_error(self, resp: str): + """ Raise an error if the firmware response is an error response. """ + + def _continuously_read(self) -> None: + """ Continuously read from the USB port until all tasks are completed. + + Tasks are stored in the `self._waiting_tasks` dictionary, and contain a future that will be + completed when the task is finished. Tasks are submitted to the dictionary using the + `self._start_reading` method. + + On each iteration, read the USB port. If a response is received, parse it and check if it is + relevant to any of the tasks. If so, complete the future and remove the task from the + dictionary. If a task has timed out, complete the future with a `TimeoutError`. + """ + + logger.debug("Starting reading thread...") + + while len(self._waiting_tasks) > 0: + for id_, (loop, fut, cmd, timeout_time) in self._waiting_tasks.items(): + if time.time() > timeout_time: + logger.warning("Timeout while waiting for response to command %s.", cmd) + loop.call_soon_threadsafe(fut.set_exception, + TimeoutError(f"Timeout while waiting for response to command {cmd}.")) + del self._waiting_tasks[id_] + break + + try: + resp = self.read().decode("utf-8") + except TimeoutError: + continue + + logger.info("Received response: %s", resp) + + # Parse response. + try: + response_id = self.get_id_from_fw_response(resp) + except ValueError as e: + if resp != "": + logger.warning("Could not parse response: %s (%s)", resp, e) + continue + + for id_, (loop, fut, cmd, timeout_time) in self._waiting_tasks.items(): + if response_id == id_: + try: + self.check_fw_string_error(resp) + except Exception as e: # pylint: disable=broad-exception-caught + loop.call_soon_threadsafe(fut.set_exception, e) + else: + loop.call_soon_threadsafe(fut.set_result, resp) + del self._waiting_tasks[id_] + break + + self._reading_thread = None + logger.debug("Reading thread stopped.") + + def _ops_to_fw_positions( + self, + ops: Sequence[PipettingOp], + use_channels: List[int] + ) -> Tuple[List[int], List[int], List[bool]]: + """ use_channels is a list of channels to use. STAR expects this in one-hot encoding. This is + method converts that, and creates a matching list of x and y positions. """ + assert use_channels == sorted(use_channels), "Channels must be sorted." + + x_positions: List[int] = [] + y_positions: List[int] = [] + channels_involved: List[bool] = [] + for i, channel in enumerate(use_channels): + while channel > len(channels_involved): + channels_involved.append(False) + x_positions.append(0) + y_positions.append(0) + channels_involved.append(True) + offset = ops[i].offset + + x_pos = ops[i].resource.get_absolute_location().x + if offset is None or isinstance(ops[i].resource, (TipSpot, Well)): + x_pos += ops[i].resource.center().x + if offset is not None: + x_pos += offset.x + x_positions.append(int(x_pos*10)) + + y_pos = ops[i].resource.get_absolute_location().y + if offset is None or isinstance(ops[i].resource, (TipSpot, Well)): + y_pos += ops[i].resource.center().y + if offset is not None: + y_pos += offset.y + y_positions.append(int(y_pos*10)) + + if len(ops) > self.num_channels: + raise ValueError(f"Too many channels specified: {len(ops)} > {self.num_channels}") + + if len(x_positions) < self.num_channels: + # We do want to have a trailing zero on x_positions, y_positions, and channels_involved, for + # some reason, if the length < 8. + x_positions = x_positions + [0] + y_positions = y_positions + [0] + channels_involved = channels_involved + [False] + + return x_positions, y_positions, channels_involved + + @abstractmethod + async def define_tip_needle( + self, + tip_type_table_index: int, + has_filter: bool, + tip_length: int, + maximum_tip_volume: int, + tip_size: TipSize, + pickup_method: TipPickupMethod + ): + """ Tip/needle definition in firmware. """ + + async def get_or_assign_tip_type_index(self, tip: HamiltonTip) -> int: + """ Get a tip type table index for the tip. + + If the tip has previously been defined, used that index. Otherwise, define a new tip type. + """ + + tip_type_hash = hash(tip) + + if tip_type_hash not in self._tth2tti: + ttti = len(self._tth2tti) + 1 + if ttti > 99: + raise ValueError("Too many tip types defined.") + + await self.define_tip_needle( + tip_type_table_index=ttti, + has_filter=tip.has_filter, + tip_length=int((tip.total_tip_length - tip.fitting_depth) * 10), # in 0.1mm + maximum_tip_volume=int(tip.maximal_volume * 10), # in 0.1ul + tip_size=tip.tip_size, + pickup_method=tip.pickup_method + ) + self._tth2tti[tip_type_hash] = ttti + + return self._tth2tti[tip_type_hash] + + def _get_hamilton_tip(self, tip_spots: List[TipSpot]) -> HamiltonTip: + """ Get the single tip type for all tip spots. If it does not exist or is not a HamiltonTip, + raise an error. """ + tips = set(tip_spot.get_tip() for tip_spot in tip_spots) + if len(tips) > 1: + raise ValueError("Cannot mix tips with different tip types.") + if len(tips) == 0: + raise ValueError("No tips specified.") + tip = tips.pop() + if not isinstance(tip, HamiltonTip): + raise ValueError(f"Tip {tip} is not a HamiltonTip.") + return tip + + async def get_ttti(self, tips: List[HamiltonTip]) -> List[int]: + """ Get tip type table index for a list of tips. + + Ensure that for all non-None tips, they have the same tip type, and return the tip type table + index for that tip type. + """ + + return [await self.get_or_assign_tip_type_index(tip) for tip in tips] diff --git a/pylabrobot/liquid_handling/backends/hamilton/errors.py b/pylabrobot/liquid_handling/backends/hamilton/errors.py deleted file mode 100644 index 3ea5a48afd..0000000000 --- a/pylabrobot/liquid_handling/backends/hamilton/errors.py +++ /dev/null @@ -1,929 +0,0 @@ -""" Hamilton backend errors """ - -from abc import ABCMeta -from typing import Optional, Type, Dict, ItemsView - - -class HamiltonModuleError(Exception, metaclass=ABCMeta): - """ Base class for all Hamilton backend errors, raised by a single module. """ - - def __init__( - self, - message: str, - trace_information: int, - raw_response: str, - raw_module: str, - ): - self.message = message - self.trace_information = trace_information - self.raw_response = raw_response - self.raw_module = raw_module - - def __repr__(self) -> str: - return f"{self.__class__.__name__}('{self.message}')" - -class CommandSyntaxError(HamiltonModuleError): - """ Command syntax error - - Code: 01 - """ - - pass - - -class HardwareError(HamiltonModuleError): - """ Hardware error - - Possible cause(s): - drive blocked, low power etc. - - Code: 02 - """ - - pass - - -class CommandNotCompletedError(HamiltonModuleError): - """ Command not completed - - Possible cause(s): - error in previous sequence (not executed) - - Code: 03 - """ - - pass - - -class ClotDetectedError(HamiltonModuleError): - """ Clot detected - - Possible cause(s): - LLD not interrupted - - Code: 04 - """ - - pass - - -class BarcodeUnreadableError(HamiltonModuleError): - """ Barcode unreadable - - Possible cause(s): - bad or missing barcode - - Code: 05 - """ - - pass - - -class TipTooLittleVolumeError(HamiltonModuleError): - """ Too little liquid - - Possible cause(s): - 1. liquid surface is not detected, - 2. Aspirate / Dispense conditions could not be fulfilled. - - Code: 06 - """ - - pass - - -class TipAlreadyFittedError(HamiltonModuleError): - """ Tip already fitted - - Possible cause(s): - Repeated attempts to fit a tip or iSwap movement with tips - - Code: 07 - """ - - pass - - -class NoTipError(HamiltonModuleError): - """ No tips - - Possible cause(s): - command was started without fitting tip (tip was not fitted or fell off again) - - Code: 08 - """ - - pass - - -class NoCarrierError(HamiltonModuleError): - """ No carrier - - Possible cause(s): - load command without carrier - - Code: 09 - """ - - pass - - -class NotCompletedError(HamiltonModuleError): - """ Not completed - - Possible cause(s): - Command in command buffer was aborted due to an error in a previous command, or command stack - was deleted. - - Code: 10 - """ - - pass - - -class DispenseWithPressureLLDError(HamiltonModuleError): - """ Dispense with pressure LLD - - Possible cause(s): - dispense with pressure LLD is not permitted - - Code: 11 - """ - - pass - - -class NoTeachInSignalError(HamiltonModuleError): - """ No Teach In Signal - - Possible cause(s): - X-Movement to LLD reached maximum allowable position with- out detecting Teach in signal - - Code: 12 - """ - - pass - - -class LoadingTrayError(HamiltonModuleError): - """ Loading Tray error - - Possible cause(s): - position already occupied - - Code: 13 - """ - - pass - - -class SequencedAspirationWithPressureLLDError(HamiltonModuleError): - """ Sequenced aspiration with pressure LLD - - Possible cause(s): - sequenced aspiration with pressure LLD is not permitted - - Code: 14 - """ - - pass - - -class NotAllowedParameterCombinationError(HamiltonModuleError): - """ Not allowed parameter combination - - Possible cause(s): - i.e. PLLD and dispense or wrong X-drive assignment - - Code: 15 - """ - - pass - - -class CoverCloseError(HamiltonModuleError): - """Cover close error - - Possible cause(s): - cover is not closed and couldn't be locked - - Code: 16 - """ - - pass - - -class AspirationError(HamiltonModuleError): - """ Aspiration error - - Possible cause(s): - aspiration liquid stream error detected - - - Code: 17 - """ - - pass - - -class WashFluidOrWasteError(HamiltonModuleError): - """Wash fluid or trash error - - Possible cause(s): - 1. missing wash fluid - 2. trash of particular washer is full - - Code: 18 - """ - - pass - - -class IncubationError(HamiltonModuleError): - """ Incubation error - - Possible cause(s): - incubator temperature out of limit - - Code: 19 - """ - - pass - - -class TADMMeasurementError(HamiltonModuleError): - """TADM measurement error - - Possible cause(s): - overshoot of limits during aspiration or dispensation - - Code: 20, 26 - """ - - pass - - -class NoElementError(HamiltonModuleError): - """ No element - - Possible cause(s): - expected element not detected - - Code: 21 - """ - - pass - - -class ElementStillHoldingError(HamiltonModuleError): - """Element still holding - - Possible cause(s): - "Get command" is sent twice or element is not droped expected element is missing (lost) - - Code: 22 - """ - - pass - - -class ElementLostError(HamiltonModuleError): - """ Element lost - - Possible cause(s): - expected element is missing (lost) - - Code: 23 - """ - - pass - - -class IllegalTargetPlatePositionError(HamiltonModuleError): - """Illegal target plate position - - Possible cause(s): - 1. over or underflow of iSWAP positions - 2. iSWAP is not in park position during pipetting activities - - Code: 24 - """ - - pass - - -class IllegalUserAccessError(HamiltonModuleError): - """Illegal user access - - Possible cause(s): - carrier was manually removed or cover is open (immediate stop is executed) - - Code: 25 - """ - - pass - - -class PositionNotReachableError(HamiltonModuleError): - """Position not reachable - - Possible cause(s): - position out of mechanical limits using iSWAP, CoRe gripper or PIP-channels - - Code: 27 - """ - - pass - - -class UnexpectedLLDError(HamiltonModuleError): - """ unexpected LLD - - Possible cause(s): - liquid level is reached before LLD scanning is started (using PIP or XL channels) - - Code: 28 - """ - - pass - - -class AreaAlreadyOccupiedError(HamiltonModuleError): - """ area already occupied - - Possible cause(s): - Its impossible to occupy area because this area is already in use - - Code: 29 - """ - - pass - - -class ImpossibleToOccupyAreaError(HamiltonModuleError): - """ impossible to occupy area - - Possible cause(s): - Area cant be occupied because is no solution for arm prepositioning - - Code: 30 - """ - - pass - - -class AntiDropControlError(HamiltonModuleError): - """ - Anti drop controlling out of tolerance. (VENUS only) - - Code: 31 - """ - - pass - - -class DecapperError(HamiltonModuleError): - """ - Decapper lock error while screw / unscrew a cap by twister channels. (VENUS only) - - Code: 32 - """ - - pass - - -class DecapperHandlingError(HamiltonModuleError): - """ - Decapper station error while lock / unlock a cap. (VENUS only) - - Code: 33 - """ - - pass - - -class SlaveError(HamiltonModuleError): - """ Slave error - - Possible cause(s): - This error code indicates an error in one of slaves. (for error handling purpose using service - software macro code) - - Code: 99 - """ - - pass - - -class WrongCarrierError(HamiltonModuleError): - """ - Wrong carrier barcode detected. (VENUS only) - - Code: 100 - """ - - pass - - -class NoCarrierBarcodeError(HamiltonModuleError): - """ - Carrier barcode could not be read or is missing. (VENUS only) - - Code: 101 - """ - - pass - - -class LiquidLevelError(HamiltonModuleError): - """ - Liquid surface not detected. (VENUS only) - - This error is created from main / slave error 06/70, 06/73 and 06/87. - - Code: 102 - """ - - pass - - -class NotDetectedError(HamiltonModuleError): - """ - Carrier not detected at deck end position. (VENUS only) - - Code: 103 - """ - - pass - - -class NotAspiratedError(HamiltonModuleError): - """ - Dispense volume exceeds the aspirated volume. (VENUS only) - - This error is created from main / slave error 02/54. - - Code: 104 - """ - - pass - - -class ImproperDispensationError(HamiltonModuleError): - """ - The dispensed volume is out of tolerance (may only occur for Nano Pipettor Dispense steps). - (VENUS only) - - This error is created from main / slave error 02/52 and 02/54. - - Code: 105 - """ - - pass - - -class NoLabwareError(HamiltonModuleError): - """ - The labware to be loaded was not detected by autoload module. (VENUS only) - - Note: - - May only occur on a Reload Carrier step if the labware property 'MlStarCarPosAreRecognizable' is - set to 1. - - Code: 106 - """ - - pass - - -class UnexpectedLabwareError(HamiltonModuleError): - """ - The labware contains unexpected barcode ( may only occur on a Reload Carrier step ). (VENUS only) - - Code: 107 - """ - - pass - - -class WrongLabwareError(HamiltonModuleError): - """ - The labware to be reloaded contains wrong barcode ( may only occur on a Reload Carrier step ). - (VENUS only) - - Code: 108 - """ - - pass - - -class BarcodeMaskError(HamiltonModuleError): - """ - The barcode read doesn't match the barcode mask defined. (VENUS only) - - Code: 109 - """ - - pass - - -class BarcodeNotUniqueError(HamiltonModuleError): - """ - The barcode read is not unique. Previously loaded labware with same barcode was loaded without - unique barcode check. (VENUS only) - - Code: 110 - """ - - pass - - -class BarcodeAlreadyUsedError(HamiltonModuleError): - """ - The barcode read is already loaded as unique barcode ( it's not possible to load the same barcode - twice ). (VENUS only) - - Code: 111 - """ - - pass - - -class KitLotExpiredError(HamiltonModuleError): - """ - Kit Lot expired. (VENUS only) - - Code: 112 - """ - - pass - - -class DelimiterError(HamiltonModuleError): - """ - Barcode contains character which is used as delimiter in result string. (VENUS only) - - Code: 113 - """ - - pass - - -class UnknownHamiltonError(HamiltonModuleError): - """ Unknown error """ - - pass - - -def _module_id_to_module_name(id_): - """ Convert a module ID to a module name. """ - return { - "C0": "Master", - "X0": "X-drives", - "I0": "Auto Load", - "W1": "Wash station 1-3", - "W2": "Wash station 4-6", - "T1": "Temperature carrier 1", - "T2": "Temperature carrier 2", - "R0": "ISWAP", - "P1": "Pipetting channel 1", - "P2": "Pipetting channel 2", - "P3": "Pipetting channel 3", - "P4": "Pipetting channel 4", - "P5": "Pipetting channel 5", - "P6": "Pipetting channel 6", - "P7": "Pipetting channel 7", - "P8": "Pipetting channel 8", - "P9": "Pipetting channel 9", - "PA": "Pipetting channel 10", - "PB": "Pipetting channel 11", - "PC": "Pipetting channel 12", - "PD": "Pipetting channel 13", - "PE": "Pipetting channel 14", - "PF": "Pipetting channel 15", - "PG": "Pipetting channel 16", - "H0": "CoRe 96 Head", - "HW": "Pump station 1 station", - "HU": "Pump station 2 station", - "HV": "Pump station 3 station", - "N0": "Nano dispenser", - "D0": "384 dispensing head", - "NP": "Nano disp. pressure controller", - "M1": "Reserved for module 1" - }[id_] - - -def error_code_to_exception(code: int) -> Type[HamiltonModuleError]: - """ Convert an error code to an exception. """ - codes = { - 1: CommandSyntaxError, - 2: HardwareError, - 3: CommandNotCompletedError, - 4: ClotDetectedError, - 5: BarcodeUnreadableError, - 6: TipTooLittleVolumeError, - 7: TipAlreadyFittedError, - 8: NoTipError, - 9: NoCarrierError, - 10: NotCompletedError, - 11: DispenseWithPressureLLDError, - 12: NoTeachInSignalError, - 13: LoadingTrayError, - 14: SequencedAspirationWithPressureLLDError, - 15: NotAllowedParameterCombinationError, - 16: CoverCloseError, - 17: AspirationError, - 18: WashFluidOrWasteError, - 19: IncubationError, - 20: TADMMeasurementError, - 21: NoElementError, - 22: ElementStillHoldingError, - 23: ElementLostError, - 24: IllegalTargetPlatePositionError, - 25: IllegalUserAccessError, - 26: TADMMeasurementError, - 27: PositionNotReachableError, - 28: UnexpectedLLDError, - 29: AreaAlreadyOccupiedError, - 30: ImpossibleToOccupyAreaError, - 31: AntiDropControlError, - 32: DecapperError, - 33: DecapperHandlingError, - 99: SlaveError, - 100: WrongCarrierError, - 101: NoCarrierBarcodeError, - 102: LiquidLevelError, - 103: NotDetectedError, - 104: NotAspiratedError, - 105: ImproperDispensationError, - 106: NoLabwareError, - 107: UnexpectedLabwareError, - 108: WrongLabwareError, - 109: BarcodeMaskError, - 110: BarcodeNotUniqueError, - 111: BarcodeAlreadyUsedError, - 112: KitLotExpiredError, - 113: DelimiterError - } - if code in codes: - return codes[code] - return UnknownHamiltonError - - -class HamiltonError(Exception): - """ Base class for all Hamilton errors. """ - - pass - - -class HamiltonFirmwareError(HamiltonError): - """ - All Hamilton machine errors. - - Example: - >>> try: - ... lh.pick_up_tips([True, True, True]) - ... except HamiltonError as e: - ... print(e) - HamiltonFirmwareError({ - 'Pipetting channel 1': NoTipError('Tip already picked up'), - 'Pipetting channel 3': NoTipError('Tip already picked up'), - }) - - >>> try: - ... lh.pick_up_tips([True, False, True]) - ... except HamiltonError as e: - ... if 'Pipetting channel 1' in e: - ... print('Pipetting channel 1 error: ', e['Pipetting channel 1'], e.error_code) - Pipetting channel 1 error: NoTipError('Tip already picked up'), '08/76' - """ - - def __init__(self, errors, raw_response=None): - self.raw_response = raw_response - - # Convert error codes to error objects - self.errors: Dict[str, HamiltonModuleError] = {} - for module_id, error in errors.items(): - module_name = _module_id_to_module_name(module_id) - if "/" in error: - # C0 module: error code / trace information - error_code, trace_information = error.split("/") - error_code, trace_information = int(error_code), int(trace_information) - if error_code == 0: # No error - continue - error_class = error_code_to_exception(error_code) - else: - # Slave modules: er## (just trace information) - error_class = UnknownHamiltonError - trace_information = int(error) - error_description = HamiltonFirmwareError.trace_information_to_string( - module_identifier=module_id, trace_information=trace_information) - self.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(self.errors.get("Master"), SlaveError): - self.errors.pop("Master") - - def __str__(self) -> str: - return f"HamiltonFirmwareError({self.errors})" - - def __len__(self) -> int: - return len(self.errors) - - def __getitem__(self, key: str): - return self.errors[key] - - def __setitem__(self, key: str, value: HamiltonModuleError): - self.errors[key] = value - - def __contains__(self, key: str) -> bool: - return key in self.errors - - def items(self) -> ItemsView[str, HamiltonModuleError]: - return self.errors.items() - - def error_for_channel(self, channel: int) -> Optional[HamiltonModuleError]: - """ Return the error for a given channel. - - .. warning:: - Channel here is 1-indexed, like the firmware API, but STAR uses 0-indexed channels. - """ - - return self.errors.get(f"Pipetting channel {channel}") - - @staticmethod - def trace_information_to_string(module_identifier: str, trace_information: int) -> str: - """ Convert a trace identifier to an error message. """ - table = None - - if module_identifier == "C0": - table = { - 10: "CAN error", - 11: "Slave command time out", - 20: "E2PROM error", - 30: "Unknown command", - 31: "Unknown parameter", - 32: "Parameter out of range", - 33: "Parameter does not belong to command, or not all parameters were sent", - 34: "Node name unknown", - 35: "id parameter error", - 37: "node name defined twice", - 38: "faulty XL channel settings", - 39: "faulty robotic channel settings", - 40: "PIP task busy", - 41: "Auto load task busy", - 42: "Miscellaneous task busy", - 43: "Incubator task busy", - 44: "Washer task busy", - 45: "iSWAP task busy", - 46: "CoRe 96 head task busy", - 47: "Carrier sensor doesn't work properly", - 48: "CoRe 384 head task busy", - 49: "Nano pipettor task busy", - 50: "XL channel task busy", - 51: "Tube gripper task busy", - 52: "Imaging channel task busy", - 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"]: - table = { - 0: "No error", - 20: "No communication to EEPROM", - 30: "Unknown command", - 31: "Unknown parameter", - 32: "Parameter out of range", - 35: "Voltages outside permitted range", - 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)", - 50: "Dispensing drive init. position not found", - 51: "Dispensing drive not initialized", - 52: "Dispensing drive movement error", - 53: "Maximum volume in tip reached", - 54: "Position outside of permitted area", - 55: "Y-drive blocked", - 56: "Y-drive not initialized", - 57: "Y-drive movement error", - 60: "X-drive blocked", - 61: "X-drive not initialized", - 62: "X-drive movement error", - 63: "X-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)", - 72: "Auto calibration at pressure (Sensor not possible)", - 73: "No liquid level found with dual LLD", - 74: "Liquid at a not allowed position detected", - 75: "No tip picked up, possibly because no was present at specified position", - 76: "Tip already picked up", - 77: "Tip not droped", - 78: "Wrong tip picked up", - 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: "No communication to digital potentiometer", - 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)", - 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" - } - elif module_identifier == "H0": # Core 96 head - table = { - 20: "No communication to EEPROM", - 30: "Unknown command", - 31: "Unknown parameter", - 32: "Parameter out of range", - 35: "Voltage outside permitted range", - 36: "Stop during execution of command", - 37: "The adjustment sensor did not switch", - 40: "No parallel processes permitted", - 50: "Dispensing drive initialization failed", - 51: "Dispensing drive not initialized", - 52: "Dispensing drive movement error", - 53: "Maximum volume in tip reached", - 54: "Position out of permitted area", - 55: "Y drive initialization failed", - 56: "Y drive not initialized", - 57: "Y drive movement error", - 58: "Y drive position outside of permitted area", - 60: "Z drive initialization failed", - 61: "Z drive not initialized", - 62: "Z drive movement error", - 63: "Z drive position outside of permitted area", - 65: "Squeezer drive initialization failed", - 66: "Squeezer drive not initialized", - 67: "Squeezer drive movement error: drive blocked or incremental sensor fault", - 68: "Squeezer drive position outside of permitted area", - 70: "No liquid level found", - 71: "Not enough liquid present", - 75: "No tip picked up", - 76: "Tip already picked up", - 81: "Clot detected", - } - elif module_identifier == "R0": # iswap - table = { - 20: "No communication to EEPROM", - 30: "Unknown command", - 31: "Unknown parameter", - 32: "Parameter out of range", - 33: "FW doesn't match to HW", - 36: "Stop during execution of command", - 37: "The adjustment sensor did not switch", - 38: "The adjustment sensor cannot be searched", - 40: "No parallel processes permitted", - 41: "No parallel processes permitted", - 42: "No parallel processes permitted", - 50: "Y-drive Initialization failed", - 51: "Y-drive not initialized", - 52: "Y-drive movement error: drive locked or incremental sensor fault", - 53: "Y-drive movement error: position counter over/underflow", - 60: "Z-drive initialization failed", - 61: "Z-drive not initialized", - 62: "Z-drive movement error: drive locked or incremental sensor fault", - 63: "Z-drive movement error: position counter over/underflow", - 70: "Rotation-drive initialization failed", - 71: "Rotation-drive not initialized", - 72: "Rotation-drive movement error: drive locked or incremental sensor fault", - 73: "Rotation-drive movement error: position counter over/underflow", - 80: "Wrist twist drive initialization failed", - 81: "Wrist twist drive not initialized", - 82: "Wrist twist drive movement error: drive locked or incremental sensor fault", - 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", - 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" - } - - if table is not None and trace_information in table: - return table[trace_information] - - return f"Unknown trace information code {trace_information:02}" - - -class VENUSError(HamiltonError): - """ VENUS error """ - - pass diff --git a/pylabrobot/liquid_handling/backends/hamilton/vantage.py b/pylabrobot/liquid_handling/backends/hamilton/vantage.py new file mode 100644 index 0000000000..e3cc6edf7c --- /dev/null +++ b/pylabrobot/liquid_handling/backends/hamilton/vantage.py @@ -0,0 +1,4617 @@ +# pylint: disable=invalid-name + +import re +import sys +from typing import Dict, List, Optional, Sequence, Union, cast + +from pylabrobot.liquid_handling.backends.hamilton.base import ( + HamiltonLiquidHandler, + HamiltonFirmwareError +) +from pylabrobot.liquid_handling.liquid_classes.hamilton import get_vantage_liquid_class +from pylabrobot.liquid_handling.standard import ( + Pickup, + PickupTipRack, + Drop, + DropTipRack, + Aspiration, + AspirationPlate, + Dispense, + DispensePlate, + Move +) +from pylabrobot.resources import Coordinate, Liquid, Resource, Plate +from pylabrobot.resources.ml_star import HamiltonTip, TipPickupMethod, TipSize + + +if sys.version_info >= (3, 8): + from typing import Literal +else: + from typing_extensions import Literal + + +def parse_vantage_fw_string(s: str, fmt: Optional[Dict[str, str]] = None) -> dict: + """ Parse a Vantage firmware string into a dict. + + The identifier parameter (id) is added automatically. + + `fmt` is a dict that specifies the format of the string. The keys are the parameter names and the + values are the types. The following types are supported: + + - `"int"`: a single integer + - `"str"`: a string + - `"[int]"`: a list of integers + - `"hex"`: a hexadecimal number + + Example: + >>> parse_fw_string("id0xs30 -100 +1 1000", {"id": "int", "x": "[int]"}) + {"id": 0, "x": [30, -100, 1, 1000]} + + >>> parse_fw_string("es\"error string\"", {"es": "str"}) + {"es": "error string"} + """ + + parsed: dict = {} + + if fmt is None: + fmt = {} + + if not isinstance(fmt, dict): + raise TypeError(f"invalid fmt for fmt: expected dict, got {type(fmt)}") + + if "id" not in fmt: + fmt["id"] = "int" + + for key, data_type in fmt.items(): + if data_type == "int": + 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(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(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(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) + else: + raise ValueError(f"Unknown data type {data_type}") + + return parsed + +core96_errors = { + 0: "No error", + 21: "No communication to digital potentiometer", + 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)", + 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: "Dispensing drive initialization failed", + 51: "Dispensing drive not initialized", + 52: "Dispensing drive movement error", + 53: "Maximum volume in tip reached", + 54: "Dispensing 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", + 60: "Z drive initialization failed", + 61: "Z drive not initialized", + 62: "Z drive movement error", + 63: "Z drive position out of permitted area", + 65: "Squeezer drive initialization failed", + 66: "Squeezer drive not initialized", + 67: "Squeezer drive movement error", + 68: "Squeezer drive position out of permitted area", + 70: "No liquid level found", + 71: "Not enough liquid present", + 75: "No tip picked up", + 76: "Tip already picked up", + 81: "Clot detected with LLD sensor", + 82: "TADM measurement out of lower limit curve", + 83: "TADM measurement out of upper limit curve", + 84: "Not enough memory for TADM measurement", + 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", +} + +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", +} + +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", +} + + +class VantageFirmwareError(HamiltonFirmwareError): + def __init__(self, errors, raw_response): + self.errors = errors + self.raw_response = raw_response + + 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 + + +def vantage_response_string_to_error(string: str) -> HamiltonFirmwareError: + """ Convert a Vantage firmware response string to a HamiltonFirmwareError. Assumes that the + response is an error response. """ + + try: + error_format = r"[A-Z0-9]{2}[0-9]{2}" + error_string = parse_vantage_fw_string(string, {"es": "str"})["es"] + error_codes = re.findall(error_format, error_string) + errors = {} + num_channels = 16 + for error in error_codes: + module, error_code = error[:2], error[2:] + error_code = int(error_code) + for channel in range(1, num_channels + 1): + if module == f"P{channel}": + errors[f"Pipetting channel {channel}"] = pip_errors.get(error_code, "Unknown error") + elif module in ("H0", "HM"): + errors["Core 96"] = core96_errors.get(error_code, "Unknown error") + elif module == "RM": + errors["IPG"] = ipg_errors.get(error_code, "Unknown error") + elif module == "AM": + errors["Cover"] = "Unknown error" + except ValueError: + module_id = string[:4] + module = modules = { + "I1AM": "Cover", + "C0AM": "Master", + "A1PM": "Pip", + "A1HM": "Core 96", + "A1RM": "IPG", + }.get(module_id, "Unknown module") + error_string = parse_vantage_fw_string(string, {"et": "str"})["et"] + errors = {modules: error_string} + + return VantageFirmwareError(errors, string) + + +class Vantage(HamiltonLiquidHandler): + """ A Hamilton Vantage liquid handler. """ + + def __init__( + self, + device_address: Optional[int] = None, + packet_read_timeout: int = 3, + read_timeout: int = 30, + write_timeout: int = 30, + ): + """ Create a new STAR interface. + + Args: + device_address: the USB device address of the Hamilton STAR. Only useful if using more than + one Hamilton machine over USB. + packet_read_timeout: timeout in seconds for reading a single packet. + read_timeout: timeout in seconds for reading a full response. + write_timeout: timeout in seconds for writing a command. + num_channels: the number of pipette channels present on the robot. + """ + + super().__init__( + device_address=device_address, + packet_read_timeout=packet_read_timeout, + read_timeout=read_timeout, + write_timeout=write_timeout, + id_product=0x8003) + + self._iswap_parked: Optional[bool] = None + self._num_channels: Optional[int] = None + + @property + def module_id_length(self) -> int: + return 4 + + def get_id_from_fw_response(self, resp: str) -> Optional[int]: + """ 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. """ + + if "er" in resp and not "er0" in resp: + error = vantage_response_string_to_error(resp) + raise error + + async def setup(self): + """ setup + + Creates a USB connection and finds read/write interfaces. + """ + + await super().setup() + + self._num_channels = 8 # TODO: query + + await self.pre_initialize_instrument() + + # TODO: check if already initialized + await self.pip_initialize( + x_position=[7095]*self.num_channels, + y_position=[3891, 3623, 3355, 3087, 2819, 2551, 2283, 2016], + begin_z_deposit_position=[2450] * self.num_channels, + end_z_deposit_position=[1235] * self.num_channels, + minimal_height_at_command_end=[2450] * self.num_channels, + tip_pattern=[True]*self.num_channels, + tip_type=[1]*self.num_channels, + TODO_DI_2=70 + ) + + await self.loading_cover_initialize() + + await self.core96_initialize( + 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=2450, + minimal_height_at_command_end=2450, + end_z_deposit_position=2020, + ) + + @property + def num_channels(self) -> int: + """ The number of channels on the robot. """ + if self._num_channels is None: + raise RuntimeError("num_channels is not set.") + return self._num_channels + + # ============== LiquidHandlerBackend methods ============== + + async def pick_up_tips(self, ops: List[Pickup], use_channels: List[int]): + 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 if op.offset is not None else 0) 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) + + # 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: + max_tip_length += 2 + elif self._get_hamilton_tip([op.resource for op in ops]).tip_size != TipSize.STANDARD_VOLUME: + max_tip_length -= 2 + + try: + return await self.pip_tip_pick_up( + x_position=x_positions, + y_position=y_positions, + tip_pattern=tip_pattern, + tip_type=ttti, + begin_z_deposit_position=[int((max_z + max_total_tip_length)*10)]*len(ops), + end_z_deposit_position=[int((max_z + max_tip_length)*10)]*len(ops), + minimal_traverse_height_at_begin_of_command=[2450]*len(ops), + minimal_height_at_command_end=[2450]*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 + + # @need_iswap_parked + async def drop_tips( + self, + ops: List[Drop], + use_channels: List[int], + ): + """ Drop tips to a resource. """ + + 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 if op.offset is not None else 0) for op in ops) + + try: + return await self.pip_tip_discard( + x_position=x_positions, + y_position=y_positions, + tip_pattern=channels_involved, + begin_z_deposit_position=[int((max_z+10)*10)]*len(ops), # +10 + end_z_deposit_position=[int(max_z*10)]*len(ops), + minimal_traverse_height_at_begin_of_command=[2450]*len(ops), + minimal_height_at_command_end=[2450]*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, + ) + except Exception as e: + raise e + + def _assert_valid_resources(self, resources: Sequence[Resource]) -> None: + """ 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") + + async def aspirate( + self, + ops: List[Aspiration], + use_channels: List[int], + type_of_aspiration: Optional[List[int]] = None, + minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, + minimal_height_at_command_end: Optional[List[int]] = None, + lld_search_height: Optional[List[int]] = None, + clot_detection_height: Optional[List[int]] = None, + liquid_surface_at_function_without_lld: Optional[List[int]] = None, + pull_out_distance_to_take_transport_air_in_function_without_lld: Optional[List[int]] = None, + tube_2nd_section_height_measured_from_zm: Optional[List[int]] = None, + tube_2nd_section_ratio: Optional[List[int]] = None, + minimum_height: Optional[List[int]] = None, + immersion_depth: Optional[List[int]] = None, + surface_following_distance: Optional[List[int]] = None, + transport_air_volume: Optional[List[int]] = None, + pre_wetting_volume: Optional[List[int]] = None, + lld_mode: Optional[List[int]] = None, + lld_sensitivity: Optional[List[int]] = None, + pressure_lld_sensitivity: Optional[List[int]] = None, + aspirate_position_above_z_touch_off: Optional[List[int]] = None, + swap_speed: Optional[List[int]] = None, + settling_time: Optional[List[int]] = None, + mix_volume: Optional[List[int]] = None, + mix_cycles: Optional[List[int]] = None, + mix_position_in_z_direction_from_liquid_surface: Optional[List[int]] = None, + mix_speed: Optional[List[int]] = None, + surface_following_distance_during_mixing: Optional[List[int]] = None, + TODO_DA_5: Optional[List[int]] = None, + capacitive_mad_supervision_on_off: Optional[List[int]] = None, + pressure_mad_supervision_on_off: Optional[List[int]] = None, + tadm_algorithm_on_off: int = 0, + limit_curve_index: Optional[List[int]] = None, + recording_mode: int = 0, + ): + """ 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 + method additionally provides default values based on firmware instructions sent by Venus on + Vantage, rather than machine default values (which are often not what you want). + + Args: + ops: The aspiration operations. + use_channels: The channels to use. + """ + + x_positions, y_positions, channels_involved = \ + self._ops_to_fw_positions(ops, use_channels) + + hamilton_liquid_classes = [ + get_vantage_liquid_class( + tip_volume=op.tip.maximal_volume, + is_core=False, + is_tip=True, + has_filter=op.tip.has_filter, + liquid=op.liquid or Liquid.WATER, + jet=False, # for aspiration + empty=False # for aspiration + ) for op in ops] + + self._assert_valid_resources([op.resource for op in ops]) + + # correct volumes using the liquid class + for op, hlc in zip(ops, hamilton_liquid_classes): + op.volume = hlc.compute_corrected_volume(op.volume) if hlc is not None else op.volume + + well_bottoms = [op.resource.get_absolute_location().z + \ + (op.offset.z if op.offset is not None else 0) 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 = [wb + op.resource.get_size_z()+5-1 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, hamilton_liquid_classes)] + + return await self.pip_aspirate( + x_position=x_positions, + y_position=y_positions, + type_of_aspiration=type_of_aspiration or [0]*len(ops), + tip_pattern=channels_involved, + minimal_traverse_height_at_begin_of_command=minimal_traverse_height_at_begin_of_command or + [2450]*len(ops), + minimal_height_at_command_end=minimal_height_at_command_end or [2450]*len(ops), + lld_search_height=lld_search_height or [int(ls*10) for ls in lld_search_heights], + clot_detection_height=clot_detection_height or [0]*len(ops), + liquid_surface_at_function_without_lld=liquid_surface_at_function_without_lld or + [int(lsn * 10) for lsn in liquid_surfaces_no_lld], + pull_out_distance_to_take_transport_air_in_function_without_lld=\ + pull_out_distance_to_take_transport_air_in_function_without_lld or [109]*len(ops), + tube_2nd_section_height_measured_from_zm=tube_2nd_section_height_measured_from_zm or + [0]*len(ops), + tube_2nd_section_ratio=tube_2nd_section_ratio or [0]*len(ops), + minimum_height=minimum_height or [1871]*len(ops), + immersion_depth=immersion_depth or [0]*len(ops), + surface_following_distance=surface_following_distance or [0]*len(ops), + aspiration_volume=[int(op.volume*100) for op in ops], + aspiration_speed=[int(fr * 10) for fr in flow_rates], + transport_air_volume=transport_air_volume or + [int(hlc.aspiration_air_transport_volume*10) if hlc is not None else 0 + for hlc in hamilton_liquid_classes], + blow_out_air_volume=[int(op.blow_out_air_volume*100) for op in ops], + pre_wetting_volume=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=aspirate_position_above_z_touch_off or [5]*len(ops), + swap_speed=swap_speed or [20]*len(ops), + settling_time=settling_time or [10]*len(ops), + mix_volume=mix_volume or [0]*len(ops), + mix_cycles=mix_cycles or [0]*len(ops), + mix_position_in_z_direction_from_liquid_surface= + mix_position_in_z_direction_from_liquid_surface or [0]*len(ops), + mix_speed=mix_speed or [2500]*len(ops), + surface_following_distance_during_mixing=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), + recording_mode=recording_mode or 0, + ) + + async def dispense( + self, + ops: List[Dispense], + use_channels: List[int], + jet: Optional[List[bool]] = None, + empty: Optional[List[bool]] = None, + type_of_dispensing_mode: Optional[List[int]] = None, + minimum_height: Optional[List[int]] = None, + pull_out_distance_to_take_transport_air_in_function_without_lld: Optional[List[int]] = None, + immersion_depth: Optional[List[int]] = None, + surface_following_distance: Optional[List[int]] = None, + tube_2nd_section_height_measured_from_zm: Optional[List[int]] = None, + tube_2nd_section_ratio: Optional[List[int]] = None, + minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, + minimal_height_at_command_end: Optional[List[int]] = None, + cut_off_speed: Optional[List[int]] = None, + stop_back_volume: Optional[List[int]] = None, + transport_air_volume: Optional[List[int]] = None, + lld_mode: Optional[List[int]] = None, + side_touch_off_distance: int = 0, + dispense_position_above_z_touch_off: Optional[List[int]] = None, + lld_sensitivity: Optional[List[int]] = None, + pressure_lld_sensitivity: Optional[List[int]] = None, + swap_speed: Optional[List[int]] = None, + settling_time: Optional[List[int]] = None, + mix_volume: Optional[List[int]] = None, + mix_cycles: Optional[List[int]] = None, + mix_position_in_z_direction_from_liquid_surface: Optional[List[int]] = None, + mix_speed: Optional[List[int]] = None, + surface_following_distance_during_mixing: Optional[List[int]] = None, + TODO_DD_2: Optional[List[int]] = None, + tadm_algorithm_on_off: int = 0, + limit_curve_index: Optional[List[int]] = None, + recording_mode: int = 0, + ): + """ 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 + method additionally provides default values based on firmware instructions sent by Venus on + Vantage, rather than machine default values (which are often not what you want). + + Args: + ops: The aspiration operations. + use_channels: The channels to use. + jet: Whether to jet. If `True`, jet dispense will be used. If `False`, surface dispense will + be used. If `None`, dispense will be jet if the liquid_height for an operation is greater + than 0, or if the tip is empty. Otherwise, surface dispense will be used. + """ + + x_positions, y_positions, channels_involved = \ + self._ops_to_fw_positions(ops, use_channels) + + def should_jet(op): + if op.liquid_height is not None and op.liquid_height > 0: + return True + if hasattr(op.resource, "tracker") and op.resource.tracker.get_used_volume() == 0: + return True + return False + + def should_empty(op): + return op.tip.tracker.get_used_volume() == 0 + + if jet is None: + jet = [should_jet(op) for op in ops] + if empty is None: + empty = [should_empty(op) for op in ops] + + hamilton_liquid_classes = [ + get_vantage_liquid_class( + tip_volume=op.tip.maximal_volume, + is_core=False, + is_tip=True, + has_filter=op.tip.has_filter, + liquid=op.liquid or Liquid.WATER, + jet=jet, + empty=empty + ) for jet, empty, op in zip(jet, empty, ops)] + self._assert_valid_resources([op.resource for op in ops]) + + # correct volumes using the liquid class + for op, hlc in zip(ops, hamilton_liquid_classes): + op.volume = hlc.compute_corrected_volume(op.volume) if hlc is not None else op.volume + + well_bottoms = [op.resource.get_absolute_location().z + \ + (op.offset.z if op.offset is not None else 0) 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 = [wb + op.resource.get_size_z()+5-1 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, hamilton_liquid_classes)] + + 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 or [1]*len(ops), + minimum_height=minimum_height or [int(wb*10) for wb in well_bottoms], + lld_search_height=[int(sh*10) for sh in lld_search_heights], + liquid_surface_at_function_without_lld=[int(ls*10) for ls in liquid_surfaces_no_lld], + pull_out_distance_to_take_transport_air_in_function_without_lld= + pull_out_distance_to_take_transport_air_in_function_without_lld or [50]*len(ops), + immersion_depth=immersion_depth or [0]*len(ops), + surface_following_distance=surface_following_distance or [21]*len(ops), + tube_2nd_section_height_measured_from_zm=tube_2nd_section_height_measured_from_zm or + [0]*len(ops), + tube_2nd_section_ratio=tube_2nd_section_ratio or [0]*len(ops), + minimal_traverse_height_at_begin_of_command=minimal_traverse_height_at_begin_of_command or + [2450]*len(ops), + minimal_height_at_command_end=minimal_height_at_command_end or [2450]*len(ops), + dispense_volume=[int(op.volume * 100) for op in ops], + dispense_speed=[int(fr*10) for fr in flow_rates], + cut_off_speed=cut_off_speed or [2500]*len(ops), + stop_back_volume=stop_back_volume or [0]*len(ops), + transport_air_volume=transport_air_volume or + [int(hlc.dispense_air_transport_volume*10) if hlc is not None else 0 + for hlc in hamilton_liquid_classes], + blow_out_air_volume=[int(op.blow_out_air_volume*100) for op in ops], + lld_mode=lld_mode or [0]*len(ops), + side_touch_off_distance=side_touch_off_distance or 0, + dispense_position_above_z_touch_off=dispense_position_above_z_touch_off or [5]*len(ops), + lld_sensitivity=lld_sensitivity or [1]*len(ops), + pressure_lld_sensitivity=pressure_lld_sensitivity or [1]*len(ops), + swap_speed=swap_speed or [10]*len(ops), + settling_time=settling_time or [0]*len(ops), + mix_volume=mix_volume or [0]*len(ops), + mix_cycles=mix_cycles or [0]*len(ops), + mix_position_in_z_direction_from_liquid_surface= + mix_position_in_z_direction_from_liquid_surface or [0]*len(ops), + mix_speed=mix_speed or [10]*len(ops), + surface_following_distance_during_mixing=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), + recording_mode=recording_mode or 0, + ) + + async def pick_up_tips96( + self, + pickup: PickupTipRack, + tip_handling_method: int = 0, + z_deposit_position: int = 2164, + minimal_traverse_height_at_begin_of_command: int = 2450, + minimal_height_at_command_end: int = 2450, + ): + # 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 + + return await self.core96_tip_pick_up( + x_position=int(position.x * 10), + y_position=int(position.y * 10), + tip_type=ttti, + tip_handling_method=tip_handling_method, + z_deposit_position=z_deposit_position, + minimal_traverse_height_at_begin_of_command=minimal_traverse_height_at_begin_of_command, + minimal_height_at_command_end=minimal_height_at_command_end, + ) + + async def drop_tips96( + self, + drop: DropTipRack, + z_deposit_position: int = 2164, + minimal_traverse_height_at_begin_of_command: int = 2450, + minimal_height_at_command_end: int = 2450 + ): + # assert self.core96_head_installed, "96 head must be installed" + tip_spot_a1 = drop.resource.get_item("A1") + position = tip_spot_a1.get_absolute_location() + tip_spot_a1.center() + drop.offset + + return await self.core96_tip_discard( + x_position=int(position.x * 10), + y_position=int(position.y * 10), + z_deposit_position=z_deposit_position, + minimal_traverse_height_at_begin_of_command=minimal_traverse_height_at_begin_of_command, + minimal_height_at_command_end=minimal_height_at_command_end, + ) + + async def aspirate96( + self, + aspiration: AspirationPlate, + jet: bool = True, + empty: bool = True, + type_of_aspiration: int = 0, + minimal_traverse_height_at_begin_of_command: int = 2450, + minimal_height_at_command_end: int = 2450, + pull_out_distance_to_take_transport_air_in_function_without_lld: int = 50, + tube_2nd_section_height_measured_from_zm: int = 0, + tube_2nd_section_ratio: int = 0, + immersion_depth: int = 0, + surface_following_distance: int = 0, + transport_air_volume: Optional[int] = None, + blow_out_air_volume: Optional[int] = None, + pre_wetting_volume: int = 0, + lld_mode: int = 0, + lld_sensitivity: int = 4, + swap_speed: Optional[int] = None, + settling_time: Optional[int] = None, + mix_volume: int = 0, + mix_cycles: int = 0, + mix_position_in_z_direction_from_liquid_surface: int = 0, + surface_following_distance_during_mixing: int = 0, + mix_speed: int = 2000, + limit_curve_index: int = 0, + tadm_channel_pattern: Optional[List[bool]] = None, + tadm_algorithm_on_off: int = 0, + recording_mode: int = 0, + ): + # assert self.core96_head_installed, "96 head must be installed" + + assert isinstance(aspiration.resource, Plate), "Only Plate is supported." + well_a1 = aspiration.resource.get_item("A1") + position = well_a1.get_absolute_location() + well_a1.center() + + liquid_height = well_a1.get_absolute_location().z + (aspiration.liquid_height or 0) + + well_bottoms = well_a1.get_absolute_location().z + \ + (aspiration.offset.z if aspiration.offset is not None else 0) + + tip = aspiration.tips[0] + hlc = get_vantage_liquid_class( + tip_volume=tip.maximal_volume, + is_core=True, + is_tip=True, + has_filter=tip.has_filter, + liquid=aspiration.liquid or Liquid.WATER, + jet=jet, + empty=empty + ) + volume = hlc.compute_corrected_volume(aspiration.volume) if hlc is not None \ + else aspiration.volume + + lld_search_height = well_bottoms + well_a1.get_size_z() + 4 + + transport_air_volume = transport_air_volume or \ + (int(hlc.aspiration_air_transport_volume*10) if hlc is not None else 0) + blow_out_air_volume = blow_out_air_volume or \ + (int(hlc.aspiration_blow_out_volume * 100) 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 (int(hlc.aspiration_swap_speed*10) if hlc is not None else 100) + settling_time = settling_time or \ + (int(hlc.aspiration_settling_time*10) if hlc is not None else 5) + + return await self.core96_aspiration_of_liquid( + x_position=int(position.x * 10), + y_position=int(position.y * 10), + type_of_aspiration=type_of_aspiration, + minimal_traverse_height_at_begin_of_command=minimal_traverse_height_at_begin_of_command, + minimal_height_at_command_end=minimal_height_at_command_end, + lld_search_height=int(lld_search_height * 10), + liquid_surface_at_function_without_lld=int(liquid_height * 10), + pull_out_distance_to_take_transport_air_in_function_without_lld=\ + pull_out_distance_to_take_transport_air_in_function_without_lld, + minimum_height=int(well_bottoms * 10), + tube_2nd_section_height_measured_from_zm=tube_2nd_section_height_measured_from_zm, + tube_2nd_section_ratio=tube_2nd_section_ratio, + immersion_depth=immersion_depth, + surface_following_distance=surface_following_distance, + aspiration_volume=int(volume * 100), + aspiration_speed=int(flow_rate * 10), + transport_air_volume=transport_air_volume, + blow_out_air_volume=blow_out_air_volume, + pre_wetting_volume=pre_wetting_volume, + lld_mode=lld_mode, + lld_sensitivity=lld_sensitivity, + swap_speed=swap_speed, + settling_time=settling_time, + mix_volume=mix_volume, + mix_cycles=mix_cycles, + mix_position_in_z_direction_from_liquid_surface=\ + mix_position_in_z_direction_from_liquid_surface, + surface_following_distance_during_mixing=surface_following_distance_during_mixing, + mix_speed=mix_speed, + 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 dispense96( + self, + dispense: DispensePlate, + jet: Optional[bool] = None, + empty: Optional[bool] = None, + type_of_dispensing_mode: int = 0, + tube_2nd_section_height_measured_from_zm: int = 0, + tube_2nd_section_ratio: int = 0, + pull_out_distance_to_take_transport_air_in_function_without_lld: int = 50, + immersion_depth: int = 0, + surface_following_distance: int = 29, + minimal_traverse_height_at_begin_of_command: int = 2450, + minimal_height_at_command_end: int = 2450, + cut_off_speed: int = 2500, + stop_back_volume: int = 0, + transport_air_volume: Optional[int] = None, + blow_out_air_volume: Optional[int] = None, + lld_mode: int = 0, + lld_sensitivity: int = 4, + side_touch_off_distance: int = 0, + swap_speed: Optional[int] = None, + settling_time: Optional[int] = None, + mix_volume: int = 0, + mix_cycles: int = 0, + mix_position_in_z_direction_from_liquid_surface: int = 0, + surface_following_distance_during_mixing: int = 0, + mix_speed: Optional[int] = None, + limit_curve_index: int = 0, + tadm_channel_pattern: Optional[List[bool]] = None, + tadm_algorithm_on_off: int = 0, + recording_mode: int = 0, + ): + assert isinstance(dispense.resource, Plate), "Only Plate is supported." + well_a1 = dispense.resource.get_item("A1") + position = well_a1.get_absolute_location() + well_a1.center() + + liquid_height = well_a1.get_absolute_location().z + (dispense.liquid_height or 0) + \ + (dispense.offset.z if dispense.offset is not None else 0) + well_a1.get_size_z() + 1 # +1? + + well_bottoms = well_a1.get_absolute_location().z + \ + (dispense.offset.z if dispense.offset is not None else 0) + + if jet is None: + jet = dispense.liquid_height is None or dispense.liquid_height > 0 + if empty is None: + empty = all(tip.tracker.get_used_volume() == 0 for tip in dispense.tips) + + tip = dispense.tips[0] + hlc = get_vantage_liquid_class( + tip_volume=tip.maximal_volume, + is_core=True, + is_tip=True, + has_filter=tip.has_filter, + liquid=dispense.liquid or Liquid.WATER, + jet=jet, + empty=empty + ) + volume = hlc.compute_corrected_volume(dispense.volume) if hlc is not None \ + else dispense.volume + + lld_search_height = well_bottoms + well_a1.get_size_z() + 4 + + transport_air_volume = transport_air_volume or \ + (int(hlc.dispense_air_transport_volume*10) if hlc is not None else 0) + blow_out_air_volume = blow_out_air_volume or \ + (int(hlc.dispense_blow_out_volume * 100) 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 (int(hlc.dispense_swap_speed*10) if hlc is not None else 100) + settling_time = settling_time or \ + (int(hlc.dispense_settling_time*10) if hlc is not None else 5) + mix_speed = mix_speed or (int(hlc.dispense_mix_flow_rate*10) if hlc is not None else 100) + + return await self.core96_dispensing_of_liquid( + x_position=int(position.x * 10), + y_position=int(position.y * 10), + type_of_dispensing_mode=type_of_dispensing_mode, + minimum_height=int(well_bottoms * 10), + tube_2nd_section_height_measured_from_zm=tube_2nd_section_height_measured_from_zm, + tube_2nd_section_ratio=tube_2nd_section_ratio, + lld_search_height=int(lld_search_height * 10), + liquid_surface_at_function_without_lld=int(liquid_height * 10), + pull_out_distance_to_take_transport_air_in_function_without_lld=\ + pull_out_distance_to_take_transport_air_in_function_without_lld, + immersion_depth=immersion_depth, + surface_following_distance=surface_following_distance, + minimal_traverse_height_at_begin_of_command=minimal_traverse_height_at_begin_of_command, + minimal_height_at_command_end=minimal_height_at_command_end, + dispense_volume=int(volume * 100), + dispense_speed=int(flow_rate * 10), + cut_off_speed=cut_off_speed, + stop_back_volume=stop_back_volume, + transport_air_volume=transport_air_volume, + blow_out_air_volume=blow_out_air_volume, + lld_mode=lld_mode, + lld_sensitivity=lld_sensitivity, + side_touch_off_distance=side_touch_off_distance, + swap_speed=swap_speed, + settling_time=settling_time, + mix_volume=mix_volume, + mix_cycles=mix_cycles, + mix_position_in_z_direction_from_liquid_surface=\ + mix_position_in_z_direction_from_liquid_surface, + surface_following_distance_during_mixing=surface_following_distance_during_mixing, + mix_speed=mix_speed, + 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, + resource: Resource, + offset: Coordinate, + pickup_distance_from_top: float, + grip_strength: int = 81, + plate_width_tolerance: int = 20, + acceleration_index: int = 4, + z_clearance_height: int = 0, + hotel_depth: int = 0, + minimal_height_at_command_end: int = 2840, + ): + """ 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_size_z() - pickup_distance_from_top + plate_width = resource.get_size_x() + + await self.ipg_grip_plate( + x_position=int(center.x * 10), + y_position=int(center.y * 10), + z_position=int(grip_height * 10), + grip_strength=grip_strength, + open_gripper_position=int(plate_width*10) + 32, + plate_width=int(plate_width * 10) - 33, + plate_width_tolerance=plate_width_tolerance, + acceleration_index=acceleration_index, + z_clearance_height=z_clearance_height, + hotel_depth=hotel_depth, + minimal_height_at_command_end=minimal_height_at_command_end, + ) + + 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. + """ + + raise NotImplementedError() + + async def release_picked_up_resource( + self, + resource: Resource, + destination: Coordinate, + offset: Coordinate, + pickup_distance_from_top: float, + z_clearance_height: int = 0, + press_on_distance: int = 5, + hotel_depth: int = 0, + minimal_height_at_command_end: int = 2840 + ): + """ 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 = destination + resource.center() + offset + grip_height = center.z + resource.get_size_z() - pickup_distance_from_top + plate_width = resource.get_size_x() + + await self.ipg_put_plate( + x_position=int(center.x * 10), + y_position=int(center.y * 10), + z_position=int(grip_height * 10), + z_clearance_height=z_clearance_height, + open_gripper_position=int(plate_width*10) + 32, + press_on_distance=press_on_distance, + hotel_depth=hotel_depth, + minimal_height_at_command_end=minimal_height_at_command_end + ) + + # ============== Firmware Commands ============== + + async def set_led_color( + self, + mode: Union[Literal["on"], Literal["off"], Literal["blink"]], + intensity: int, + white: int, + red: int, + green: int, + blue: int, + uv: int, + blink_interval: Optional[int] = None, + ): + """ Set the LED color. + + Args: + mode: The mode of the LED. One of "on", "off", or "blink". + intensity: The intensity of the LED. 0-100. + white: The white color of the LED. 0-100. + red: The red color of the LED. 0-100. + green: The green color of the LED. 0-100. + blue: The blue color of the LED. 0-100. + uv: The UV color of the LED. 0-100. + blink_interval: The blink interval in ms. Only used if mode is "blink". + """ + + if blink_interval is not None: + if mode != "blink": + raise ValueError("blink_interval is only used when mode is 'blink'.") + + return await self.send_command( + module="C0AM", + command="LI", + li={ + "on": 1, + "off": 0, + "blink": 2, + }[mode], + os=intensity, + 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. + + Args: + cover_open: Whether the cover should be open or closed. + """ + + return await self.send_command( + module="I1AM", + command="LP", + lc=not cover_open + ) + + def loading_cover_initialize(self): + """ Initialize the loading cover. """ + + return self.send_command( + module="I1AM", + command="MI", + ) + + async def pre_initialize_instrument(self): + """ Initialize the main instrument. """ + + return await self.send_command(module="A1AM", command="MI") + + async def pip_initialize( + self, + x_position: List[int], + y_position: List[int], + begin_z_deposit_position: Optional[List[int]] = None, + end_z_deposit_position: Optional[List[int]] = None, + minimal_height_at_command_end: Optional[List[int]] = None, + tip_pattern: Optional[List[bool]] = None, + tip_type: Optional[List[int]] = None, + TODO_DI_2: int = 0, + ): + """ Initialize + + Args: + x_position: X Position [0.1mm]. + y_position: Y Position [0.1mm]. + begin_z_deposit_position: Begin of tip deposit process (Z- discard range) [0.1mm] ?? + end_z_deposit_position: Z deposit position [0.1mm] (collar bearing position). + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + tip_pattern: Tip pattern (channels involved). [0 = not involved, 1 = involved]. + tip_type: Tip type (see command TT). + TODO_DI_2: Unknown. + """ + + if not all(0 <= x <= 50000 for x in x_position): + raise ValueError("x_position must be in range 0 to 50000") + + if y_position is None: + y_position = [3000] * self.num_channels + elif not all(0 <= x <= 6500 for x in y_position): + raise ValueError("y_position must be in range 0 to 6500") + + if begin_z_deposit_position is None: + begin_z_deposit_position = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in begin_z_deposit_position): + raise ValueError("begin_z_deposit_position must be in range 0 to 3600") + + if end_z_deposit_position is None: + end_z_deposit_position = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in end_z_deposit_position): + raise ValueError("end_z_deposit_position must be in range 0 to 3600") + + if minimal_height_at_command_end is None: + minimal_height_at_command_end = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_height_at_command_end): + raise ValueError("minimal_height_at_command_end must be in range 0 to 3600") + + if tip_pattern is None: + tip_pattern = [False] * self.num_channels + elif not all(0 <= x <= 1 for x in tip_pattern): + raise ValueError("tip_pattern must be in range 0 to 1") + + if tip_type is None: + tip_type = [4] * self.num_channels + elif not all(0 <= x <= 199 for x in tip_type): + raise ValueError("tip_type must be in range 0 to 199") + + if not -1000 <= TODO_DI_2 <= 1000: + raise ValueError("TODO_DI_2 must be in range -1000 to 1000") + + return await self.send_command( + module="A1PM", + command="DI", + xp=x_position, + yp=y_position, + tp=begin_z_deposit_position, + tz=end_z_deposit_position, + te=minimal_height_at_command_end, + tm=tip_pattern, + tt=tip_type, + ts=TODO_DI_2, + ) + + async def define_tip_needle( + self, + tip_type_table_index: int, + has_filter: bool, + tip_length: int, + maximum_tip_volume: int, + tip_size: TipSize, + pickup_method: TipPickupMethod + ): + """ Tip/needle definition. + + Args: + tip_type_table_index: tip_table_index + filter: with(out) filter + tip_length: Tip length [0.1mm] + maximum_tip_volume: Maximum volume of tip [0.1ul] Note! it's automatically limited to max. + channel capacity + tip_type: Type of tip collar (Tip type identification) + pickup_method: pick up method. Attention! The values set here are temporary and apply only + until power OFF or RESET. After power ON the default values apply. (see Table 3) + """ + + 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}") + 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}") + if not 1 <= tip_length <= 1999: + 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}") + + return await self.send_command( + module="A1AM", + command="TT", + ti=f"{tip_type_table_index:02}", + tf=has_filter, + tl=f"{tip_length:04}", + tv=f"{maximum_tip_volume:05}", + tg=tip_size.value, + tu=pickup_method.value + ) + + async def pip_aspirate( + self, + x_position: List[int], + y_position: List[int], + type_of_aspiration: Optional[List[int]] = None, + tip_pattern: Optional[List[bool]] = None, + minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, + minimal_height_at_command_end: Optional[List[int]] = None, + lld_search_height: Optional[List[int]] = None, + clot_detection_height: Optional[List[int]] = None, + liquid_surface_at_function_without_lld: Optional[List[int]] = None, + pull_out_distance_to_take_transport_air_in_function_without_lld: Optional[List[int]] = None, + tube_2nd_section_height_measured_from_zm: Optional[List[int]] = None, + tube_2nd_section_ratio: Optional[List[int]] = None, + minimum_height: Optional[List[int]] = None, + immersion_depth: Optional[List[int]] = None, + surface_following_distance: Optional[List[int]] = None, + aspiration_volume: Optional[List[int]] = None, + TODO_DA_2: Optional[List[int]] = None, + aspiration_speed: Optional[List[int]] = None, + transport_air_volume: Optional[List[int]] = None, + blow_out_air_volume: Optional[List[int]] = None, + pre_wetting_volume: Optional[List[int]] = None, + lld_mode: Optional[List[int]] = None, + lld_sensitivity: Optional[List[int]] = None, + pressure_lld_sensitivity: Optional[List[int]] = None, + aspirate_position_above_z_touch_off: Optional[List[int]] = None, + TODO_DA_4: Optional[List[int]] = None, + swap_speed: Optional[List[int]] = None, + settling_time: Optional[List[int]] = None, + mix_volume: Optional[List[int]] = None, + mix_cycles: Optional[List[int]] = None, + mix_position_in_z_direction_from_liquid_surface: Optional[List[int]] = None, + mix_speed: Optional[List[int]] = None, + surface_following_distance_during_mixing: Optional[List[int]] = None, + TODO_DA_5: Optional[List[int]] = None, + capacitive_mad_supervision_on_off: Optional[List[int]] = None, + pressure_mad_supervision_on_off: Optional[List[int]] = None, + tadm_algorithm_on_off: int = 0, + limit_curve_index: Optional[List[int]] = None, + recording_mode: int = 0, + ): + """ Aspiration of liquid + + Args: + type_of_aspiration: Type of aspiration (0 = simple 1 = sequence 2 = cup emptied). + tip_pattern: Tip pattern (channels involved). [0 = not involved, 1 = involved]. + x_position: X Position [0.1mm]. + y_position: Y Position [0.1mm]. + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of command + [0.1mm]. + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + lld_search_height: LLD search height [0.1mm]. + clot_detection_height: (0). + liquid_surface_at_function_without_lld: Liquid surface at function without LLD [0.1mm]. + pull_out_distance_to_take_transport_air_in_function_without_lld: + Pull out distance to take transp. air in function without LLD [0.1mm]. + tube_2nd_section_height_measured_from_zm: Tube 2nd section height measured from zm [0.1mm]. + tube_2nd_section_ratio: Tube 2nd section ratio. + minimum_height: Minimum height (maximum immersion depth) [0.1mm]. + immersion_depth: Immersion depth [0.1mm]. + surface_following_distance: Surface following distance [0.1mm]. + aspiration_volume: Aspiration volume [0.01ul]. + TODO_DA_2: (0). + aspiration_speed: Aspiration speed [0.1ul]/s. + transport_air_volume: Transport air volume [0.1ul]. + blow_out_air_volume: Blow out air volume [0.01ul]. + pre_wetting_volume: Pre wetting volume [0.1ul]. + lld_mode: LLD Mode (0 = off). + lld_sensitivity: LLD sensitivity (1 = high, 4 = low). + pressure_lld_sensitivity: Pressure LLD sensitivity (1= high, 4=low). + aspirate_position_above_z_touch_off: (0). + TODO_DA_4: (0). + swap_speed: Swap speed (on leaving liquid) [0.1mm/s]. + settling_time: Settling time [0.1s]. + mix_volume: Mix volume [0.1ul]. + mix_cycles: Mix cycles. + mix_position_in_z_direction_from_liquid_surface: Mix position in Z direction from liquid + surface[0.1mm]. + mix_speed: Mix speed [0.1ul/s]. + surface_following_distance_during_mixing: Surface following distance during mixing [0.1mm]. + TODO_DA_5: (0). + capacitive_mad_supervision_on_off: Capacitive MAD supervision on/off (0 = OFF). + pressure_mad_supervision_on_off: Pressure MAD supervision on/off (0 = OFF). + tadm_algorithm_on_off: TADM algorithm on/off (0 = off). + limit_curve_index: Limit curve index. + recording_mode: Recording mode (0 = no 1 = TADM errors only 2 = all TADM measurements). + """ + + if type_of_aspiration is None: + type_of_aspiration = [0] * self.num_channels + elif not all(0 <= x <= 2 for x in type_of_aspiration): + raise ValueError("type_of_aspiration must be in range 0 to 2") + + if tip_pattern is None: + tip_pattern = [False] * self.num_channels + elif not all(0 <= x <= 1 for x in tip_pattern): + raise ValueError("tip_pattern must be in range 0 to 1") + + if not all(0 <= x <= 50000 for x in x_position): + raise ValueError("x_position must be in range 0 to 50000") + + if y_position is None: + y_position = [3000] * self.num_channels + elif not all(0 <= x <= 6500 for x in y_position): + raise ValueError("y_position must be in range 0 to 6500") + + if minimal_traverse_height_at_begin_of_command is None: + minimal_traverse_height_at_begin_of_command = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_traverse_height_at_begin_of_command): + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3600") + + if minimal_height_at_command_end is None: + minimal_height_at_command_end = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_height_at_command_end): + raise ValueError("minimal_height_at_command_end must be in range 0 to 3600") + + if lld_search_height is None: + lld_search_height = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in lld_search_height): + raise ValueError("lld_search_height must be in range 0 to 3600") + + if clot_detection_height is None: + clot_detection_height = [60] * self.num_channels + elif not all(0 <= x <= 500 for x in clot_detection_height): + raise ValueError("clot_detection_height must be in range 0 to 500") + + if liquid_surface_at_function_without_lld is None: + liquid_surface_at_function_without_lld = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in liquid_surface_at_function_without_lld): + raise ValueError("liquid_surface_at_function_without_lld must be in range 0 to 3600") + + 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") + + if tube_2nd_section_height_measured_from_zm is None: + tube_2nd_section_height_measured_from_zm = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in tube_2nd_section_height_measured_from_zm): + raise ValueError("tube_2nd_section_height_measured_from_zm must be in range 0 to 3600") + + if tube_2nd_section_ratio is None: + tube_2nd_section_ratio = [0] * self.num_channels + elif not all(0 <= x <= 10000 for x in tube_2nd_section_ratio): + raise ValueError("tube_2nd_section_ratio must be in range 0 to 10000") + + if minimum_height is None: + minimum_height = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimum_height): + raise ValueError("minimum_height must be in range 0 to 3600") + + if immersion_depth is None: + immersion_depth = [0] * self.num_channels + elif not all(-3600 <= x <= 3600 for x in immersion_depth): + raise ValueError("immersion_depth must be in range -3600 to 3600") + + if surface_following_distance is None: + surface_following_distance = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in surface_following_distance): + raise ValueError("surface_following_distance must be in range 0 to 3600") + + if aspiration_volume is None: + aspiration_volume = [0] * self.num_channels + elif not all(0 <= x <= 125000 for x in aspiration_volume): + raise ValueError("aspiration_volume must be in range 0 to 125000") + + if TODO_DA_2 is None: + TODO_DA_2 = [0] * self.num_channels + elif not all(0 <= x <= 125000 for x in TODO_DA_2): + raise ValueError("TODO_DA_2 must be in range 0 to 125000") + + if aspiration_speed is None: + aspiration_speed = [500] * self.num_channels + elif not all(10 <= x <= 10000 for x in aspiration_speed): + raise ValueError("aspiration_speed must be in range 10 to 10000") + + if transport_air_volume is None: + transport_air_volume = [0] * self.num_channels + elif not all(0 <= x <= 500 for x in transport_air_volume): + raise ValueError("transport_air_volume must be in range 0 to 500") + + if blow_out_air_volume is None: + blow_out_air_volume = [0] * self.num_channels + elif not all(0 <= x <= 125000 for x in blow_out_air_volume): + raise ValueError("blow_out_air_volume must be in range 0 to 125000") + + if pre_wetting_volume is None: + pre_wetting_volume = [0] * self.num_channels + elif not all(0 <= x <= 999 for x in pre_wetting_volume): + raise ValueError("pre_wetting_volume must be in range 0 to 999") + + if lld_mode is None: + lld_mode = [1] * self.num_channels + elif not all(0 <= x <= 4 for x in lld_mode): + raise ValueError("lld_mode must be in range 0 to 4") + + if lld_sensitivity is None: + lld_sensitivity = [1] * self.num_channels + elif not all(1 <= x <= 4 for x in lld_sensitivity): + raise ValueError("lld_sensitivity must be in range 1 to 4") + + if pressure_lld_sensitivity is None: + pressure_lld_sensitivity = [1] * self.num_channels + elif not all(1 <= x <= 4 for x in pressure_lld_sensitivity): + raise ValueError("pressure_lld_sensitivity must be in range 1 to 4") + + if aspirate_position_above_z_touch_off is None: + aspirate_position_above_z_touch_off = [5] * self.num_channels + elif not all(0 <= x <= 100 for x in aspirate_position_above_z_touch_off): + raise ValueError("aspirate_position_above_z_touch_off must be in range 0 to 100") + + if TODO_DA_4 is None: + TODO_DA_4 = [0] * self.num_channels + elif not all(0 <= x <= 1 for x in TODO_DA_4): + raise ValueError("TODO_DA_4 must be in range 0 to 1") + + if swap_speed is None: + swap_speed = [100] * self.num_channels + elif not all(3 <= x <= 1600 for x in swap_speed): + raise ValueError("swap_speed must be in range 3 to 1600") + + if settling_time is None: + settling_time = [5] * self.num_channels + elif not all(0 <= x <= 99 for x in settling_time): + raise ValueError("settling_time must be in range 0 to 99") + + if mix_volume is None: + mix_volume = [0] * self.num_channels + elif not all(0 <= x <= 12500 for x in mix_volume): + raise ValueError("mix_volume must be in range 0 to 12500") + + if mix_cycles is None: + mix_cycles = [0] * self.num_channels + elif not all(0 <= x <= 99 for x in mix_cycles): + raise ValueError("mix_cycles must be in range 0 to 99") + + if mix_position_in_z_direction_from_liquid_surface is None: + mix_position_in_z_direction_from_liquid_surface = [250] * self.num_channels + elif not all(0 <= x <= 900 for x in mix_position_in_z_direction_from_liquid_surface): + raise ValueError("mix_position_in_z_direction_from_liquid_surface must be in range 0 to 900") + + if mix_speed is None: + mix_speed = [500] * self.num_channels + elif not all(10 <= x <= 10000 for x in mix_speed): + raise ValueError("mix_speed must be in range 10 to 10000") + + if surface_following_distance_during_mixing is None: + surface_following_distance_during_mixing = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in surface_following_distance_during_mixing): + raise ValueError("surface_following_distance_during_mixing must be in range 0 to 3600") + + if TODO_DA_5 is None: + TODO_DA_5 = [0] * self.num_channels + elif not all(0 <= x <= 1 for x in TODO_DA_5): + raise ValueError("TODO_DA_5 must be in range 0 to 1") + + if capacitive_mad_supervision_on_off is None: + capacitive_mad_supervision_on_off = [0] * self.num_channels + elif not all(0 <= x <= 1 for x in capacitive_mad_supervision_on_off): + raise ValueError("capacitive_mad_supervision_on_off must be in range 0 to 1") + + if pressure_mad_supervision_on_off is None: + pressure_mad_supervision_on_off = [0] * self.num_channels + elif not all(0 <= x <= 1 for x in pressure_mad_supervision_on_off): + raise ValueError("pressure_mad_supervision_on_off must be in range 0 to 1") + + if not 0 <= tadm_algorithm_on_off <= 1: + raise ValueError("tadm_algorithm_on_off must be in range 0 to 1") + + if limit_curve_index is None: + limit_curve_index = [0] * self.num_channels + elif not all(0 <= x <= 999 for x in limit_curve_index): + raise ValueError("limit_curve_index must be in range 0 to 999") + + if not 0 <= recording_mode <= 2: + raise ValueError("recording_mode must be in range 0 to 2") + + return await self.send_command( + module="A1PM", + command="DA", + at=type_of_aspiration, + tm=tip_pattern, + xp=x_position, + yp=y_position, + th=minimal_traverse_height_at_begin_of_command, + te=minimal_height_at_command_end, + lp=lld_search_height, + ch=clot_detection_height, + zl=liquid_surface_at_function_without_lld, + po=pull_out_distance_to_take_transport_air_in_function_without_lld, + zu=tube_2nd_section_height_measured_from_zm, + zr=tube_2nd_section_ratio, + zx=minimum_height, + ip=immersion_depth, + fp=surface_following_distance, + av=aspiration_volume, + # ar=TODO_DA_2, # this parameters is not used by VoV + as_=aspiration_speed, + ta=transport_air_volume, + ba=blow_out_air_volume, + oa=pre_wetting_volume, + lm=lld_mode, + ll=lld_sensitivity, + lv=pressure_lld_sensitivity, + zo=aspirate_position_above_z_touch_off, + # lg=TODO_DA_4, + de=swap_speed, + wt=settling_time, + mv=mix_volume, + mc=mix_cycles, + mp=mix_position_in_z_direction_from_liquid_surface, + ms=mix_speed, + mh=surface_following_distance_during_mixing, + la=TODO_DA_5, + lb=capacitive_mad_supervision_on_off, + lc=pressure_mad_supervision_on_off, + gj=tadm_algorithm_on_off, + gi=limit_curve_index, + gk=recording_mode, + ) + + async def pip_dispense( + self, + x_position: List[int], + y_position: List[int], + type_of_dispensing_mode: Optional[List[int]] = None, + tip_pattern: Optional[List[bool]] = None, + minimum_height: Optional[List[int]] = None, + lld_search_height: Optional[List[int]] = None, + liquid_surface_at_function_without_lld: Optional[List[int]] = None, + pull_out_distance_to_take_transport_air_in_function_without_lld: Optional[List[int]] = None, + immersion_depth: Optional[List[int]] = None, + surface_following_distance: Optional[List[int]] = None, + tube_2nd_section_height_measured_from_zm: Optional[List[int]] = None, + tube_2nd_section_ratio: Optional[List[int]] = None, + minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, + minimal_height_at_command_end: Optional[List[int]] = None, + dispense_volume: Optional[List[int]] = None, + dispense_speed: Optional[List[int]] = None, + cut_off_speed: Optional[List[int]] = None, + stop_back_volume: Optional[List[int]] = None, + transport_air_volume: Optional[List[int]] = None, + blow_out_air_volume: Optional[List[int]] = None, + lld_mode: Optional[List[int]] = None, + side_touch_off_distance: int = 0, + dispense_position_above_z_touch_off: Optional[List[int]] = None, + lld_sensitivity: Optional[List[int]] = None, + pressure_lld_sensitivity: Optional[List[int]] = None, + swap_speed: Optional[List[int]] = None, + settling_time: Optional[List[int]] = None, + mix_volume: Optional[List[int]] = None, + mix_cycles: Optional[List[int]] = None, + mix_position_in_z_direction_from_liquid_surface: Optional[List[int]] = None, + mix_speed: Optional[List[int]] = None, + surface_following_distance_during_mixing: Optional[List[int]] = None, + TODO_DD_2: Optional[List[int]] = None, + tadm_algorithm_on_off: int = 0, + limit_curve_index: Optional[List[int]] = None, + recording_mode: int = 0, + ): + """ Dispensing of liquid + + Args: + type_of_dispensing_mode: Type of dispensing mode 0 = part in jet 1 = blow in jet 2 = Part at + surface 3 = Blow at surface 4 = Empty. + tip_pattern: Tip pattern (channels involved). [0 = not involved, 1 = involved]. + x_position: X Position [0.1mm]. + y_position: Y Position [0.1mm]. + minimum_height: Minimum height (maximum immersion depth) [0.1mm]. + lld_search_height: LLD search height [0.1mm]. + liquid_surface_at_function_without_lld: Liquid surface at function without LLD [0.1mm]. + pull_out_distance_to_take_transport_air_in_function_without_lld: + Pull out distance to take transp. air in function without LLD [0.1mm] + . + immersion_depth: Immersion depth [0.1mm]. + surface_following_distance: Surface following distance [0.1mm]. + tube_2nd_section_height_measured_from_zm: Tube 2nd section height measured from zm [0.1mm]. + tube_2nd_section_ratio: Tube 2nd section ratio. + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of command + [0.1mm]. + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + dispense_volume: Dispense volume [0.01ul]. + dispense_speed: Dispense speed [0.1ul/s]. + cut_off_speed: Cut off speed [0.1ul/s]. + stop_back_volume: Stop back volume [0.1ul]. + transport_air_volume: Transport air volume [0.1ul]. + blow_out_air_volume: Blow out air volume [0.01ul]. + lld_mode: LLD Mode (0 = off). + side_touch_off_distance: Side touch off distance [0.1mm]. + dispense_position_above_z_touch_off: (0). + lld_sensitivity: LLD sensitivity (1 = high, 4 = low). + pressure_lld_sensitivity: Pressure LLD sensitivity (1= high, 4=low). + swap_speed: Swap speed (on leaving liquid) [0.1mm/s]. + settling_time: Settling time [0.1s]. + mix_volume: Mix volume [0.1ul]. + mix_cycles: Mix cycles. + mix_position_in_z_direction_from_liquid_surface: Mix position in Z direction from liquid + surface[0.1mm]. + mix_speed: Mix speed [0.1ul/s]. + surface_following_distance_during_mixing: Surface following distance during mixing [0.1mm]. + TODO_DD_2: (0). + tadm_algorithm_on_off: TADM algorithm on/off (0 = off). + limit_curve_index: Limit curve index. + recording_mode: + Recording mode (0 = no 1 = TADM errors only 2 = all TADM measurements) + . + """ + + if type_of_dispensing_mode is None: + type_of_dispensing_mode = [0] * self.num_channels + elif not all(0 <= x <= 4 for x in type_of_dispensing_mode): + raise ValueError("type_of_dispensing_mode must be in range 0 to 4") + + if tip_pattern is None: + tip_pattern = [False] * self.num_channels + elif not all(0 <= x <= 1 for x in tip_pattern): + raise ValueError("tip_pattern must be in range 0 to 1") + + if not all(0 <= x <= 50000 for x in x_position): + raise ValueError("x_position must be in range 0 to 50000") + + if y_position is None: + y_position = [3000] * self.num_channels + elif not all(0 <= x <= 6500 for x in y_position): + raise ValueError("y_position must be in range 0 to 6500") + + if minimum_height is None: + minimum_height = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimum_height): + raise ValueError("minimum_height must be in range 0 to 3600") + + if lld_search_height is None: + lld_search_height = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in lld_search_height): + raise ValueError("lld_search_height must be in range 0 to 3600") + + if liquid_surface_at_function_without_lld is None: + liquid_surface_at_function_without_lld = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in liquid_surface_at_function_without_lld): + raise ValueError("liquid_surface_at_function_without_lld must be in range 0 to 3600") + + 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") + + if immersion_depth is None: + immersion_depth = [0] * self.num_channels + elif not all(-3600 <= x <= 3600 for x in immersion_depth): + raise ValueError("immersion_depth must be in range -3600 to 3600") + + if surface_following_distance is None: + surface_following_distance = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in surface_following_distance): + raise ValueError("surface_following_distance 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 + elif not all(0 <= x <= 3600 for x in tube_2nd_section_height_measured_from_zm): + raise ValueError("tube_2nd_section_height_measured_from_zm must be in range 0 to 3600") + + if tube_2nd_section_ratio is None: + tube_2nd_section_ratio = [0] * self.num_channels + elif not all(0 <= x <= 10000 for x in tube_2nd_section_ratio): + raise ValueError("tube_2nd_section_ratio must be in range 0 to 10000") + + if minimal_traverse_height_at_begin_of_command is None: + minimal_traverse_height_at_begin_of_command = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_traverse_height_at_begin_of_command): + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3600") + + if minimal_height_at_command_end is None: + minimal_height_at_command_end = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_height_at_command_end): + raise ValueError("minimal_height_at_command_end must be in range 0 to 3600") + + if dispense_volume is None: + dispense_volume = [0] * self.num_channels + elif not all(0 <= x <= 125000 for x in dispense_volume): + raise ValueError("dispense_volume must be in range 0 to 125000") + + if dispense_speed is None: + dispense_speed = [500] * self.num_channels + elif not all(10 <= x <= 10000 for x in dispense_speed): + raise ValueError("dispense_speed must be in range 10 to 10000") + + if cut_off_speed is None: + cut_off_speed = [250] * self.num_channels + elif not all(10 <= x <= 10000 for x in cut_off_speed): + raise ValueError("cut_off_speed must be in range 10 to 10000") + + if stop_back_volume is None: + stop_back_volume = [0] * self.num_channels + elif not all(0 <= x <= 180 for x in stop_back_volume): + raise ValueError("stop_back_volume must be in range 0 to 180") + + if transport_air_volume is None: + transport_air_volume = [0] * self.num_channels + elif not all(0 <= x <= 500 for x in transport_air_volume): + raise ValueError("transport_air_volume must be in range 0 to 500") + + if blow_out_air_volume is None: + blow_out_air_volume = [0] * self.num_channels + elif not all(0 <= x <= 125000 for x in blow_out_air_volume): + raise ValueError("blow_out_air_volume must be in range 0 to 125000") + + if lld_mode is None: + lld_mode = [1] * self.num_channels + elif not all(0 <= x <= 4 for x in lld_mode): + raise ValueError("lld_mode must be in range 0 to 4") + + if not 0 <= side_touch_off_distance <= 45: + raise ValueError("side_touch_off_distance must be in range 0 to 45") + + if dispense_position_above_z_touch_off is None: + dispense_position_above_z_touch_off = [5] * self.num_channels + elif not all(0 <= x <= 100 for x in dispense_position_above_z_touch_off): + raise ValueError("dispense_position_above_z_touch_off must be in range 0 to 100") + + if lld_sensitivity is None: + lld_sensitivity = [1] * self.num_channels + elif not all(1 <= x <= 4 for x in lld_sensitivity): + raise ValueError("lld_sensitivity must be in range 1 to 4") + + if pressure_lld_sensitivity is None: + pressure_lld_sensitivity = [1] * self.num_channels + elif not all(1 <= x <= 4 for x in pressure_lld_sensitivity): + raise ValueError("pressure_lld_sensitivity must be in range 1 to 4") + + if swap_speed is None: + swap_speed = [100] * self.num_channels + elif not all(3 <= x <= 1600 for x in swap_speed): + raise ValueError("swap_speed must be in range 3 to 1600") + + if settling_time is None: + settling_time = [5] * self.num_channels + elif not all(0 <= x <= 99 for x in settling_time): + raise ValueError("settling_time must be in range 0 to 99") + + if mix_volume is None: + mix_volume = [0] * self.num_channels + elif not all(0 <= x <= 12500 for x in mix_volume): + raise ValueError("mix_volume must be in range 0 to 12500") + + if mix_cycles is None: + mix_cycles = [0] * self.num_channels + elif not all(0 <= x <= 99 for x in mix_cycles): + raise ValueError("mix_cycles must be in range 0 to 99") + + if mix_position_in_z_direction_from_liquid_surface is None: + mix_position_in_z_direction_from_liquid_surface = [250] * self.num_channels + elif not all(0 <= x <= 900 for x in mix_position_in_z_direction_from_liquid_surface): + raise ValueError("mix_position_in_z_direction_from_liquid_surface must be in range 0 to 900") + + if mix_speed is None: + mix_speed = [500] * self.num_channels + elif not all(10 <= x <= 10000 for x in mix_speed): + raise ValueError("mix_speed must be in range 10 to 10000") + + if surface_following_distance_during_mixing is None: + surface_following_distance_during_mixing = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in surface_following_distance_during_mixing): + raise ValueError("surface_following_distance_during_mixing must be in range 0 to 3600") + + if TODO_DD_2 is None: + TODO_DD_2 = [0] * self.num_channels + elif not all(0 <= x <= 1 for x in TODO_DD_2): + raise ValueError("TODO_DD_2 must be in range 0 to 1") + + if not 0 <= tadm_algorithm_on_off <= 1: + raise ValueError("tadm_algorithm_on_off must be in range 0 to 1") + + if limit_curve_index is None: + limit_curve_index = [0] * self.num_channels + elif not all(0 <= x <= 999 for x in limit_curve_index): + raise ValueError("limit_curve_index must be in range 0 to 999") + + if not 0 <= recording_mode <= 2: + raise ValueError("recording_mode must be in range 0 to 2") + + return await self.send_command( + module="A1PM", + command="DD", + dm=type_of_dispensing_mode, + tm=tip_pattern, + xp=x_position, + yp=y_position, + zx=minimum_height, + lp=lld_search_height, + zl=liquid_surface_at_function_without_lld, + po=pull_out_distance_to_take_transport_air_in_function_without_lld, + ip=immersion_depth, + fp=surface_following_distance, + zu=tube_2nd_section_height_measured_from_zm, + zr=tube_2nd_section_ratio, + th=minimal_traverse_height_at_begin_of_command, + te=minimal_height_at_command_end, + dv=dispense_volume, + ds=dispense_speed, + ss=cut_off_speed, + rv=stop_back_volume, + ta=transport_air_volume, + ba=blow_out_air_volume, + lm=lld_mode, + dj=side_touch_off_distance, + zo=dispense_position_above_z_touch_off, + ll=lld_sensitivity, + lv=pressure_lld_sensitivity, + de=swap_speed, + wt=settling_time, + mv=mix_volume, + mc=mix_cycles, + mp=mix_position_in_z_direction_from_liquid_surface, + ms=mix_speed, + mh=surface_following_distance_during_mixing, + la=TODO_DD_2, + gj=tadm_algorithm_on_off, + gi=limit_curve_index, + gk=recording_mode, + ) + + async def simultaneous_aspiration_dispensation_of_liquid( + self, + x_position: List[int], + y_position: List[int], + type_of_aspiration: Optional[List[int]] = None, + type_of_dispensing_mode: Optional[List[int]] = None, + tip_pattern: Optional[List[bool]] = None, + TODO_DM_1: Optional[List[int]] = None, + minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, + minimal_height_at_command_end: Optional[List[int]] = None, + lld_search_height: Optional[List[int]] = None, + clot_detection_height: Optional[List[int]] = None, + liquid_surface_at_function_without_lld: Optional[List[int]] = None, + pull_out_distance_to_take_transport_air_in_function_without_lld: Optional[List[int]] = None, + minimum_height: Optional[List[int]] = None, + immersion_depth: Optional[List[int]] = None, + surface_following_distance: Optional[List[int]] = None, + tube_2nd_section_height_measured_from_zm: Optional[List[int]] = None, + tube_2nd_section_ratio: Optional[List[int]] = None, + aspiration_volume: Optional[List[int]] = None, + TODO_DM_3: Optional[List[int]] = None, + aspiration_speed: Optional[List[int]] = None, + dispense_volume: Optional[List[int]] = None, + dispense_speed: Optional[List[int]] = None, + cut_off_speed: Optional[List[int]] = None, + stop_back_volume: Optional[List[int]] = None, + transport_air_volume: Optional[List[int]] = None, + blow_out_air_volume: Optional[List[int]] = None, + pre_wetting_volume: Optional[List[int]] = None, + lld_mode: Optional[List[int]] = None, + aspirate_position_above_z_touch_off: Optional[List[int]] = None, + lld_sensitivity: Optional[List[int]] = None, + pressure_lld_sensitivity: Optional[List[int]] = None, + swap_speed: Optional[List[int]] = None, + settling_time: Optional[List[int]] = None, + mix_volume: Optional[List[int]] = None, + mix_cycles: Optional[List[int]] = None, + mix_position_in_z_direction_from_liquid_surface: Optional[List[int]] = None, + mix_speed: Optional[List[int]] = None, + surface_following_distance_during_mixing: Optional[List[int]] = None, + TODO_DM_5: Optional[List[int]] = None, + capacitive_mad_supervision_on_off: Optional[List[int]] = None, + pressure_mad_supervision_on_off: Optional[List[int]] = None, + tadm_algorithm_on_off: int = 0, + limit_curve_index: Optional[List[int]] = None, + recording_mode: int = 0, + ): + """ Simultaneous aspiration & dispensation of liquid + + Args: + type_of_aspiration: Type of aspiration (0 = simple 1 = sequence 2 = cup emptied). + type_of_dispensing_mode: Type of dispensing mode 0 = part in jet 1 = blow in jet 2 = Part at + surface 3 = Blow at surface 4 = Empty. + tip_pattern: Tip pattern (channels involved). [0 = not involved, 1 = involved]. + TODO_DM_1: (0). + x_position: X Position [0.1mm]. + y_position: Y Position [0.1mm]. + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of command + [0.1mm]. + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + lld_search_height: LLD search height [0.1mm]. + clot_detection_height: (0). + liquid_surface_at_function_without_lld: Liquid surface at function without LLD [0.1mm]. + pull_out_distance_to_take_transport_air_in_function_without_lld: + Pull out distance to take transp. air in function without LLD [0.1mm] + . + minimum_height: Minimum height (maximum immersion depth) [0.1mm]. + immersion_depth: Immersion depth [0.1mm]. + surface_following_distance: Surface following distance [0.1mm]. + tube_2nd_section_height_measured_from_zm: Tube 2nd section height measured from zm [0.1mm]. + tube_2nd_section_ratio: Tube 2nd section ratio. + aspiration_volume: Aspiration volume [0.01ul]. + TODO_DM_3: (0). + aspiration_speed: Aspiration speed [0.1ul]/s. + dispense_volume: Dispense volume [0.01ul]. + dispense_speed: Dispense speed [0.1ul/s]. + cut_off_speed: Cut off speed [0.1ul/s]. + stop_back_volume: Stop back volume [0.1ul]. + transport_air_volume: Transport air volume [0.1ul]. + blow_out_air_volume: Blow out air volume [0.01ul]. + pre_wetting_volume: Pre wetting volume [0.1ul]. + lld_mode: LLD Mode (0 = off). + aspirate_position_above_z_touch_off: (0). + lld_sensitivity: LLD sensitivity (1 = high, 4 = low). + pressure_lld_sensitivity: Pressure LLD sensitivity (1= high, 4=low). + swap_speed: Swap speed (on leaving liquid) [0.1mm/s]. + settling_time: Settling time [0.1s]. + mix_volume: Mix volume [0.1ul]. + mix_cycles: Mix cycles. + mix_position_in_z_direction_from_liquid_surface: Mix position in Z direction from liquid + surface[0.1mm]. + mix_speed: Mix speed [0.1ul/s]. + surface_following_distance_during_mixing: Surface following distance during mixing [0.1mm]. + TODO_DM_5: (0). + capacitive_mad_supervision_on_off: Capacitive MAD supervision on/off (0 = OFF). + pressure_mad_supervision_on_off: Pressure MAD supervision on/off (0 = OFF). + tadm_algorithm_on_off: TADM algorithm on/off (0 = off). + limit_curve_index: Limit curve index. + recording_mode: + Recording mode (0 = no 1 = TADM errors only 2 = all TADM measurements) + . + """ + + if type_of_aspiration is None: + type_of_aspiration = [0] * self.num_channels + elif not all(0 <= x <= 2 for x in type_of_aspiration): + raise ValueError("type_of_aspiration must be in range 0 to 2") + + if type_of_dispensing_mode is None: + type_of_dispensing_mode = [0] * self.num_channels + elif not all(0 <= x <= 4 for x in type_of_dispensing_mode): + raise ValueError("type_of_dispensing_mode must be in range 0 to 4") + + if tip_pattern is None: + tip_pattern = [False] * self.num_channels + elif not all(0 <= x <= 1 for x in tip_pattern): + raise ValueError("tip_pattern must be in range 0 to 1") + + if TODO_DM_1 is None: + TODO_DM_1 = [0] * self.num_channels + elif not all(0 <= x <= 1 for x in TODO_DM_1): + raise ValueError("TODO_DM_1 must be in range 0 to 1") + + if not all(0 <= x <= 50000 for x in x_position): + raise ValueError("x_position must be in range 0 to 50000") + + if y_position is None: + y_position = [3000] * self.num_channels + elif not all(0 <= x <= 6500 for x in y_position): + raise ValueError("y_position must be in range 0 to 6500") + + if minimal_traverse_height_at_begin_of_command is None: + minimal_traverse_height_at_begin_of_command = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_traverse_height_at_begin_of_command): + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3600") + + if minimal_height_at_command_end is None: + minimal_height_at_command_end = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_height_at_command_end): + raise ValueError("minimal_height_at_command_end must be in range 0 to 3600") + + if lld_search_height is None: + lld_search_height = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in lld_search_height): + raise ValueError("lld_search_height must be in range 0 to 3600") + + if clot_detection_height is None: + clot_detection_height = [60] * self.num_channels + elif not all(0 <= x <= 500 for x in clot_detection_height): + raise ValueError("clot_detection_height must be in range 0 to 500") + + if liquid_surface_at_function_without_lld is None: + liquid_surface_at_function_without_lld = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in liquid_surface_at_function_without_lld): + raise ValueError("liquid_surface_at_function_without_lld must be in range 0 to 3600") + + 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") + + if minimum_height is None: + minimum_height = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimum_height): + raise ValueError("minimum_height must be in range 0 to 3600") + + if immersion_depth is None: + immersion_depth = [0] * self.num_channels + elif not all(-3600 <= x <= 3600 for x in immersion_depth): + raise ValueError("immersion_depth must be in range -3600 to 3600") + + if surface_following_distance is None: + surface_following_distance = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in surface_following_distance): + raise ValueError("surface_following_distance 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 + elif not all(0 <= x <= 3600 for x in tube_2nd_section_height_measured_from_zm): + raise ValueError("tube_2nd_section_height_measured_from_zm must be in range 0 to 3600") + + if tube_2nd_section_ratio is None: + tube_2nd_section_ratio = [0] * self.num_channels + elif not all(0 <= x <= 10000 for x in tube_2nd_section_ratio): + raise ValueError("tube_2nd_section_ratio must be in range 0 to 10000") + + if aspiration_volume is None: + aspiration_volume = [0] * self.num_channels + elif not all(0 <= x <= 125000 for x in aspiration_volume): + raise ValueError("aspiration_volume must be in range 0 to 125000") + + if TODO_DM_3 is None: + TODO_DM_3 = [0] * self.num_channels + elif not all(0 <= x <= 125000 for x in TODO_DM_3): + raise ValueError("TODO_DM_3 must be in range 0 to 125000") + + if aspiration_speed is None: + aspiration_speed = [500] * self.num_channels + elif not all(10 <= x <= 10000 for x in aspiration_speed): + raise ValueError("aspiration_speed must be in range 10 to 10000") + + if dispense_volume is None: + dispense_volume = [0] * self.num_channels + elif not all(0 <= x <= 125000 for x in dispense_volume): + raise ValueError("dispense_volume must be in range 0 to 125000") + + if dispense_speed is None: + dispense_speed = [500] * self.num_channels + elif not all(10 <= x <= 10000 for x in dispense_speed): + raise ValueError("dispense_speed must be in range 10 to 10000") + + if cut_off_speed is None: + cut_off_speed = [250] * self.num_channels + elif not all(10 <= x <= 10000 for x in cut_off_speed): + raise ValueError("cut_off_speed must be in range 10 to 10000") + + if stop_back_volume is None: + stop_back_volume = [0] * self.num_channels + elif not all(0 <= x <= 180 for x in stop_back_volume): + raise ValueError("stop_back_volume must be in range 0 to 180") + + if transport_air_volume is None: + transport_air_volume = [0] * self.num_channels + elif not all(0 <= x <= 500 for x in transport_air_volume): + raise ValueError("transport_air_volume must be in range 0 to 500") + + if blow_out_air_volume is None: + blow_out_air_volume = [0] * self.num_channels + elif not all(0 <= x <= 125000 for x in blow_out_air_volume): + raise ValueError("blow_out_air_volume must be in range 0 to 125000") + + if pre_wetting_volume is None: + pre_wetting_volume = [0] * self.num_channels + elif not all(0 <= x <= 999 for x in pre_wetting_volume): + raise ValueError("pre_wetting_volume must be in range 0 to 999") + + if lld_mode is None: + lld_mode = [1] * self.num_channels + elif not all(0 <= x <= 4 for x in lld_mode): + raise ValueError("lld_mode must be in range 0 to 4") + + if aspirate_position_above_z_touch_off is None: + aspirate_position_above_z_touch_off = [5] * self.num_channels + elif not all(0 <= x <= 100 for x in aspirate_position_above_z_touch_off): + raise ValueError("aspirate_position_above_z_touch_off must be in range 0 to 100") + + if lld_sensitivity is None: + lld_sensitivity = [1] * self.num_channels + elif not all(1 <= x <= 4 for x in lld_sensitivity): + raise ValueError("lld_sensitivity must be in range 1 to 4") + + if pressure_lld_sensitivity is None: + pressure_lld_sensitivity = [1] * self.num_channels + elif not all(1 <= x <= 4 for x in pressure_lld_sensitivity): + raise ValueError("pressure_lld_sensitivity must be in range 1 to 4") + + if swap_speed is None: + swap_speed = [100] * self.num_channels + elif not all(3 <= x <= 1600 for x in swap_speed): + raise ValueError("swap_speed must be in range 3 to 1600") + + if settling_time is None: + settling_time = [5] * self.num_channels + elif not all(0 <= x <= 99 for x in settling_time): + raise ValueError("settling_time must be in range 0 to 99") + + if mix_volume is None: + mix_volume = [0] * self.num_channels + elif not all(0 <= x <= 12500 for x in mix_volume): + raise ValueError("mix_volume must be in range 0 to 12500") + + if mix_cycles is None: + mix_cycles = [0] * self.num_channels + elif not all(0 <= x <= 99 for x in mix_cycles): + raise ValueError("mix_cycles must be in range 0 to 99") + + if mix_position_in_z_direction_from_liquid_surface is None: + mix_position_in_z_direction_from_liquid_surface = [250] * self.num_channels + elif not all(0 <= x <= 900 for x in mix_position_in_z_direction_from_liquid_surface): + raise ValueError("mix_position_in_z_direction_from_liquid_surface must be in range 0 to 900") + + if mix_speed is None: + mix_speed = [500] * self.num_channels + elif not all(10 <= x <= 10000 for x in mix_speed): + raise ValueError("mix_speed must be in range 10 to 10000") + + if surface_following_distance_during_mixing is None: + surface_following_distance_during_mixing = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in surface_following_distance_during_mixing): + raise ValueError("surface_following_distance_during_mixing must be in range 0 to 3600") + + if TODO_DM_5 is None: + TODO_DM_5 = [0] * self.num_channels + elif not all(0 <= x <= 1 for x in TODO_DM_5): + raise ValueError("TODO_DM_5 must be in range 0 to 1") + + if capacitive_mad_supervision_on_off is None: + capacitive_mad_supervision_on_off = [0] * self.num_channels + elif not all(0 <= x <= 1 for x in capacitive_mad_supervision_on_off): + raise ValueError("capacitive_mad_supervision_on_off must be in range 0 to 1") + + if pressure_mad_supervision_on_off is None: + pressure_mad_supervision_on_off = [0] * self.num_channels + elif not all(0 <= x <= 1 for x in pressure_mad_supervision_on_off): + raise ValueError("pressure_mad_supervision_on_off must be in range 0 to 1") + + if not 0 <= tadm_algorithm_on_off <= 1: + raise ValueError("tadm_algorithm_on_off must be in range 0 to 1") + + if limit_curve_index is None: + limit_curve_index = [0] * self.num_channels + elif not all(0 <= x <= 999 for x in limit_curve_index): + raise ValueError("limit_curve_index must be in range 0 to 999") + + if not 0 <= recording_mode <= 2: + raise ValueError("recording_mode must be in range 0 to 2") + + return await self.send_command( + module="A1PM", + command="DM", + at=type_of_aspiration, + dm=type_of_dispensing_mode, + tm=tip_pattern, + dd=TODO_DM_1, + xp=x_position, + yp=y_position, + th=minimal_traverse_height_at_begin_of_command, + te=minimal_height_at_command_end, + lp=lld_search_height, + ch=clot_detection_height, + zl=liquid_surface_at_function_without_lld, + po=pull_out_distance_to_take_transport_air_in_function_without_lld, + zx=minimum_height, + ip=immersion_depth, + fp=surface_following_distance, + zu=tube_2nd_section_height_measured_from_zm, + zr=tube_2nd_section_ratio, + av=aspiration_volume, + ar=TODO_DM_3, + as_=aspiration_speed, + dv=dispense_volume, + ds=dispense_speed, + ss=cut_off_speed, + rv=stop_back_volume, + ta=transport_air_volume, + ba=blow_out_air_volume, + oa=pre_wetting_volume, + lm=lld_mode, + zo=aspirate_position_above_z_touch_off, + ll=lld_sensitivity, + lv=pressure_lld_sensitivity, + de=swap_speed, + wt=settling_time, + mv=mix_volume, + mc=mix_cycles, + mp=mix_position_in_z_direction_from_liquid_surface, + ms=mix_speed, + mh=surface_following_distance_during_mixing, + la=TODO_DM_5, + lb=capacitive_mad_supervision_on_off, + lc=pressure_mad_supervision_on_off, + gj=tadm_algorithm_on_off, + gi=limit_curve_index, + gk=recording_mode, + ) + + async def dispense_on_fly( + self, + y_position: List[int], + tip_pattern: Optional[List[bool]] = None, + TODO_DF_1: int = 0, + TODO_DF_2: int = 0, + TODO_DF_3: int = 100, + TODO_DF_4: int = 900, + x_speed: int = 270, + TODO_DF_5: int = 1, + 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, + dispense_volume: Optional[List[int]] = None, + dispense_speed: Optional[List[int]] = None, + cut_off_speed: Optional[List[int]] = None, + stop_back_volume: Optional[List[int]] = None, + transport_air_volume: Optional[List[int]] = None, + tadm_algorithm_on_off: int = 0, + limit_curve_index: Optional[List[int]] = None, + recording_mode: int = 0, + ): + """ Dispense on fly + + Args: + tip_pattern: Tip pattern (channels involved). [0 = not involved, 1 = involved]. + TODO_DF_1: (0). + TODO_DF_2: (0). + TODO_DF_3: (0). + TODO_DF_4: (0). + x_speed: X speed [0.1mm/s]. + TODO_DF_5: (0). + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of command + [0.1mm]. + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + y_position: Y Position [0.1mm]. + liquid_surface_at_function_without_lld: Liquid surface at function without LLD [0.1mm]. + dispense_volume: Dispense volume [0.01ul]. + dispense_speed: Dispense speed [0.1ul/s]. + cut_off_speed: Cut off speed [0.1ul/s]. + stop_back_volume: Stop back volume [0.1ul]. + transport_air_volume: Transport air volume [0.1ul]. + tadm_algorithm_on_off: TADM algorithm on/off (0 = off). + limit_curve_index: Limit curve index. + recording_mode: Recording mode (0 = no 1 = TADM errors only 2 = all TADM measurements). + """ + + if tip_pattern is None: + tip_pattern = [False] * self.num_channels + elif not all(0 <= x <= 1 for x in tip_pattern): + raise ValueError("tip_pattern must be in range 0 to 1") + + if not -50000 <= TODO_DF_1 <= 50000: + raise ValueError("TODO_DF_1 must be in range -50000 to 50000") + + if not -50000 <= TODO_DF_2 <= 50000: + raise ValueError("TODO_DF_2 must be in range -50000 to 50000") + + if not 0 <= TODO_DF_3 <= 900: + raise ValueError("TODO_DF_3 must be in range 0 to 900") + + if not 1 <= TODO_DF_4 <= 2500: + raise ValueError("TODO_DF_4 must be in range 1 to 2500") + + if not 20 <= x_speed <= 25000: + raise ValueError("x_speed must be in range 20 to 25000") + + if not 1 <= TODO_DF_5 <= 48: + raise ValueError("TODO_DF_5 must be in range 1 to 48") + + if minimal_traverse_height_at_begin_of_command is None: + minimal_traverse_height_at_begin_of_command = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_traverse_height_at_begin_of_command): + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3600") + + if minimal_height_at_command_end is None: + minimal_height_at_command_end = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_height_at_command_end): + raise ValueError("minimal_height_at_command_end must be in range 0 to 3600") + + if y_position is None: + y_position = [3000] * self.num_channels + elif not all(0 <= x <= 6500 for x in y_position): + raise ValueError("y_position must be in range 0 to 6500") + + if liquid_surface_at_function_without_lld is None: + liquid_surface_at_function_without_lld = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in liquid_surface_at_function_without_lld): + raise ValueError("liquid_surface_at_function_without_lld must be in range 0 to 3600") + + if dispense_volume is None: + dispense_volume = [0] * self.num_channels + elif not all(0 <= x <= 125000 for x in dispense_volume): + raise ValueError("dispense_volume must be in range 0 to 125000") + + if dispense_speed is None: + dispense_speed = [500] * self.num_channels + elif not all(10 <= x <= 10000 for x in dispense_speed): + raise ValueError("dispense_speed must be in range 10 to 10000") + + if cut_off_speed is None: + cut_off_speed = [250] * self.num_channels + elif not all(10 <= x <= 10000 for x in cut_off_speed): + raise ValueError("cut_off_speed must be in range 10 to 10000") + + if stop_back_volume is None: + stop_back_volume = [0] * self.num_channels + elif not all(0 <= x <= 180 for x in stop_back_volume): + raise ValueError("stop_back_volume must be in range 0 to 180") + + if transport_air_volume is None: + transport_air_volume = [0] * self.num_channels + elif not all(0 <= x <= 500 for x in transport_air_volume): + raise ValueError("transport_air_volume must be in range 0 to 500") + + if not 0 <= tadm_algorithm_on_off <= 1: + raise ValueError("tadm_algorithm_on_off must be in range 0 to 1") + + if limit_curve_index is None: + limit_curve_index = [0] * self.num_channels + elif not all(0 <= x <= 999 for x in limit_curve_index): + raise ValueError("limit_curve_index must be in range 0 to 999") + + if not 0 <= recording_mode <= 2: + raise ValueError("recording_mode must be in range 0 to 2") + + return await self.send_command( + module="A1PM", + command="DF", + tm=tip_pattern, + xa=TODO_DF_1, + xf=TODO_DF_2, + xh=TODO_DF_3, + xy=TODO_DF_4, + xv=x_speed, + xi=TODO_DF_5, + th=minimal_traverse_height_at_begin_of_command, + te=minimal_height_at_command_end, + yp=y_position, + zl=liquid_surface_at_function_without_lld, + dv=dispense_volume, + ds=dispense_speed, + ss=cut_off_speed, + rv=stop_back_volume, + ta=transport_air_volume, + gj=tadm_algorithm_on_off, + gi=limit_curve_index, + gk=recording_mode, + ) + + async def nano_pulse_dispense( + self, + x_position: List[int], + y_position: List[int], + TODO_DB_0: Optional[List[int]] = None, + liquid_surface_at_function_without_lld: Optional[List[int]] = None, + minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, + minimal_height_at_command_end: Optional[List[int]] = None, + TODO_DB_1: Optional[List[int]] = None, + TODO_DB_2: Optional[List[int]] = None, + TODO_DB_3: Optional[List[int]] = None, + TODO_DB_4: Optional[List[int]] = None, + TODO_DB_5: Optional[List[int]] = None, + TODO_DB_6: Optional[List[int]] = None, + TODO_DB_7: Optional[List[int]] = None, + TODO_DB_8: Optional[List[int]] = None, + TODO_DB_9: Optional[List[int]] = None, + TODO_DB_10: Optional[List[int]] = None, + TODO_DB_11: Optional[List[int]] = None, + TODO_DB_12: Optional[List[int]] = None, + ): + """ Nano pulse dispense + + Args: + TODO_DB_0: (0). + x_position: X Position [0.1mm]. + y_position: Y Position [0.1mm]. + liquid_surface_at_function_without_lld: Liquid surface at function without LLD [0.1mm]. + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of command + [0.1mm]. + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + TODO_DB_1: (0). + TODO_DB_2: (0). + TODO_DB_3: (0). + TODO_DB_4: (0). + TODO_DB_5: (0). + TODO_DB_6: (0). + TODO_DB_7: (0). + TODO_DB_8: (0). + TODO_DB_9: (0). + TODO_DB_10: (0). + TODO_DB_11: (0). + TODO_DB_12: (0). + """ + + if TODO_DB_0 is None: + TODO_DB_0 = [1] * self.num_channels + elif not all(0 <= x <= 1 for x in TODO_DB_0): + raise ValueError("TODO_DB_0 must be in range 0 to 1") + + if not all(0 <= x <= 50000 for x in x_position): + raise ValueError("x_position must be in range 0 to 50000") + + if y_position is None: + y_position = [3000] * self.num_channels + elif not all(0 <= x <= 6500 for x in y_position): + raise ValueError("y_position must be in range 0 to 6500") + + if liquid_surface_at_function_without_lld is None: + liquid_surface_at_function_without_lld = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in liquid_surface_at_function_without_lld): + raise ValueError("liquid_surface_at_function_without_lld must be in range 0 to 3600") + + if minimal_traverse_height_at_begin_of_command is None: + minimal_traverse_height_at_begin_of_command = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_traverse_height_at_begin_of_command): + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3600") + + if minimal_height_at_command_end is None: + minimal_height_at_command_end = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_height_at_command_end): + raise ValueError("minimal_height_at_command_end must be in range 0 to 3600") + + if TODO_DB_1 is None: + TODO_DB_1 = [0] * self.num_channels + elif not all(0 <= x <= 20000 for x in TODO_DB_1): + raise ValueError("TODO_DB_1 must be in range 0 to 20000") + + if TODO_DB_2 is None: + TODO_DB_2 = [0] * self.num_channels + elif not all(0 <= x <= 1 for x in TODO_DB_2): + raise ValueError("TODO_DB_2 must be in range 0 to 1") + + if TODO_DB_3 is None: + TODO_DB_3 = [0] * self.num_channels + elif not all(0 <= x <= 10000 for x in TODO_DB_3): + raise ValueError("TODO_DB_3 must be in range 0 to 10000") + + if TODO_DB_4 is None: + TODO_DB_4 = [0] * self.num_channels + elif not all(0 <= x <= 100 for x in TODO_DB_4): + raise ValueError("TODO_DB_4 must be in range 0 to 100") + + if TODO_DB_5 is None: + TODO_DB_5 = [0] * self.num_channels + elif not all(0 <= x <= 1 for x in TODO_DB_5): + raise ValueError("TODO_DB_5 must be in range 0 to 1") + + if TODO_DB_6 is None: + TODO_DB_6 = [0] * self.num_channels + elif not all(0 <= x <= 10000 for x in TODO_DB_6): + raise ValueError("TODO_DB_6 must be in range 0 to 10000") + + if TODO_DB_7 is None: + TODO_DB_7 = [0] * self.num_channels + elif not all(0 <= x <= 100 for x in TODO_DB_7): + raise ValueError("TODO_DB_7 must be in range 0 to 100") + + if TODO_DB_8 is None: + TODO_DB_8 = [0] * self.num_channels + elif not all(0 <= x <= 1 for x in TODO_DB_8): + raise ValueError("TODO_DB_8 must be in range 0 to 1") + + if TODO_DB_9 is None: + TODO_DB_9 = [0] * self.num_channels + elif not all(0 <= x <= 10000 for x in TODO_DB_9): + raise ValueError("TODO_DB_9 must be in range 0 to 10000") + + if TODO_DB_10 is None: + TODO_DB_10 = [0] * self.num_channels + elif not all(0 <= x <= 100 for x in TODO_DB_10): + raise ValueError("TODO_DB_10 must be in range 0 to 100") + + if TODO_DB_11 is None: + TODO_DB_11 = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in TODO_DB_11): + raise ValueError("TODO_DB_11 must be in range 0 to 3600") + + if TODO_DB_12 is None: + TODO_DB_12 = [1] * self.num_channels + elif not all(0 <= x <= 1 for x in TODO_DB_12): + raise ValueError("TODO_DB_12 must be in range 0 to 1") + + return await self.send_command( + module="A1PM", + command="DB", + tm=TODO_DB_0, + xp=x_position, + yp=y_position, + zl=liquid_surface_at_function_without_lld, + th=minimal_traverse_height_at_begin_of_command, + te=minimal_height_at_command_end, + pe=TODO_DB_1, + pd=TODO_DB_2, + pf=TODO_DB_3, + pg=TODO_DB_4, + ph=TODO_DB_5, + pj=TODO_DB_6, + pk=TODO_DB_7, + pl=TODO_DB_8, + pp=TODO_DB_9, + pq=TODO_DB_10, + pi=TODO_DB_11, + pm=TODO_DB_12, + ) + + async def wash_tips( + self, + x_position: List[int], + y_position: List[int], + tip_pattern: Optional[List[bool]] = None, + minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, + liquid_surface_at_function_without_lld: Optional[List[int]] = None, + aspiration_volume: Optional[List[int]] = None, + aspiration_speed: Optional[List[int]] = None, + dispense_speed: Optional[List[int]] = None, + swap_speed: Optional[List[int]] = None, + soak_time: int = 0, + wash_cycles: int = 0, + minimal_height_at_command_end: Optional[List[int]] = None, + ): + """ Wash tips + + Args: + tip_pattern: Tip pattern (channels involved). [0 = not involved, 1 = involved]. + x_position: X Position [0.1mm]. + y_position: Y Position [0.1mm]. + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of command + [0.1mm]. + liquid_surface_at_function_without_lld: Liquid surface at function without LLD [0.1mm]. + aspiration_volume: Aspiration volume [0.01ul]. + aspiration_speed: Aspiration speed [0.1ul]/s. + dispense_speed: Dispense speed [0.1ul/s]. + swap_speed: Swap speed (on leaving liquid) [0.1mm/s]. + soak_time: (0). + wash_cycles: (0). + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + """ + + if tip_pattern is None: + tip_pattern = [False] * self.num_channels + elif not all(0 <= x <= 1 for x in tip_pattern): + raise ValueError("tip_pattern must be in range 0 to 1") + + if not all(0 <= x <= 50000 for x in x_position): + raise ValueError("x_position must be in range 0 to 50000") + + if y_position is None: + y_position = [3000] * self.num_channels + elif not all(0 <= x <= 6500 for x in y_position): + raise ValueError("y_position must be in range 0 to 6500") + + if minimal_traverse_height_at_begin_of_command is None: + minimal_traverse_height_at_begin_of_command = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_traverse_height_at_begin_of_command): + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3600") + + if liquid_surface_at_function_without_lld is None: + liquid_surface_at_function_without_lld = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in liquid_surface_at_function_without_lld): + raise ValueError("liquid_surface_at_function_without_lld must be in range 0 to 3600") + + if aspiration_volume is None: + aspiration_volume = [0] * self.num_channels + elif not all(0 <= x <= 125000 for x in aspiration_volume): + raise ValueError("aspiration_volume must be in range 0 to 125000") + + if aspiration_speed is None: + aspiration_speed = [500] * self.num_channels + elif not all(10 <= x <= 10000 for x in aspiration_speed): + raise ValueError("aspiration_speed must be in range 10 to 10000") + + if dispense_speed is None: + dispense_speed = [500] * self.num_channels + elif not all(10 <= x <= 10000 for x in dispense_speed): + raise ValueError("dispense_speed must be in range 10 to 10000") + + if swap_speed is None: + swap_speed = [100] * self.num_channels + elif not all(3 <= x <= 1600 for x in swap_speed): + raise ValueError("swap_speed must be in range 3 to 1600") + + if not 0 <= soak_time <= 3600: + raise ValueError("soak_time must be in range 0 to 3600") + + if not 0 <= wash_cycles <= 99: + raise ValueError("wash_cycles must be in range 0 to 99") + + if minimal_height_at_command_end is None: + minimal_height_at_command_end = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_height_at_command_end): + raise ValueError("minimal_height_at_command_end must be in range 0 to 3600") + + return await self.send_command( + module="A1PM", + command="DW", + tm=tip_pattern, + xp=x_position, + yp=y_position, + th=minimal_traverse_height_at_begin_of_command, + zl=liquid_surface_at_function_without_lld, + av=aspiration_volume, + as_=aspiration_speed, + ds=dispense_speed, + de=swap_speed, + sa=soak_time, + dc=wash_cycles, + te=minimal_height_at_command_end, + ) + + async def pip_tip_pick_up( + self, + x_position: List[int], + y_position: List[int], + tip_pattern: Optional[List[bool]] = None, + tip_type: Optional[List[int]] = None, + begin_z_deposit_position: Optional[List[int]] = None, + end_z_deposit_position: Optional[List[int]] = None, + minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, + minimal_height_at_command_end: Optional[List[int]] = None, + blow_out_air_volume: Optional[List[int]] = None, + tip_handling_method: Optional[List[int]] = None, + ): + """ Tip Pick up + + Args: + x_position: X Position [0.1mm]. + y_position: Y Position [0.1mm]. + tip_pattern: Tip pattern (channels involved). [0 = not involved, 1 = involved]. + tip_type: Tip type (see command TT). + begin_z_deposit_position: (0). + end_z_deposit_position: Z deposit position [0.1mm] (collar bearing position). + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of command + [0.1mm]. + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + blow_out_air_volume: Blow out air volume [0.01ul]. + tip_handling_method: Tip handling method. (Unconfirmed, but likely: 0 = auto selection (see + command TT parameter tu), 1 = pick up out of rack, 2 = pick up out of wash liquid (slowly)) + """ + + if not all(0 <= x <= 50000 for x in x_position): + raise ValueError("x_position must be in range 0 to 50000") + + if y_position is None: + y_position = [3000] * self.num_channels + elif not all(0 <= x <= 6500 for x in y_position): + raise ValueError("y_position must be in range 0 to 6500") + + if tip_pattern is None: + tip_pattern = [False] * self.num_channels + elif not all(0 <= x <= 1 for x in tip_pattern): + raise ValueError("tip_pattern must be in range 0 to 1") + + if tip_type is None: + tip_type = [4] * self.num_channels + elif not all(0 <= x <= 199 for x in tip_type): + raise ValueError("tip_type must be in range 0 to 199") + + if begin_z_deposit_position is None: + begin_z_deposit_position = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in begin_z_deposit_position): + raise ValueError("begin_z_deposit_position must be in range 0 to 3600") + + if end_z_deposit_position is None: + end_z_deposit_position = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in end_z_deposit_position): + raise ValueError("end_z_deposit_position must be in range 0 to 3600") + + if minimal_traverse_height_at_begin_of_command is None: + minimal_traverse_height_at_begin_of_command = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_traverse_height_at_begin_of_command): + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3600") + + if minimal_height_at_command_end is None: + minimal_height_at_command_end = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_height_at_command_end): + raise ValueError("minimal_height_at_command_end must be in range 0 to 3600") + + if blow_out_air_volume is None: + blow_out_air_volume = [0] * self.num_channels + elif not all(0 <= x <= 125000 for x in blow_out_air_volume): + raise ValueError("blow_out_air_volume must be in range 0 to 125000") + + if tip_handling_method is None: + tip_handling_method = [0] * self.num_channels + elif not all(0 <= x <= 9 for x in tip_handling_method): + raise ValueError("tip_handling_method must be in range 0 to 9") + + return await self.send_command( + module="A1PM", + command="TP", + xp=x_position, + yp=y_position, + tm=tip_pattern, + tt=tip_type, + tp=begin_z_deposit_position, + tz=end_z_deposit_position, + th=minimal_traverse_height_at_begin_of_command, + te=minimal_height_at_command_end, + ba=blow_out_air_volume, + td=tip_handling_method, + ) + + async def pip_tip_discard( + self, + x_position: List[int], + y_position: List[int], + begin_z_deposit_position: Optional[List[int]] = None, + end_z_deposit_position: Optional[List[int]] = None, + minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, + minimal_height_at_command_end: Optional[List[int]] = None, + tip_pattern: Optional[List[bool]] = None, + TODO_TR_2: int = 0, + tip_handling_method: Optional[List[int]] = None, + ): + """ Tip Discard + + Args: + x_position: X Position [0.1mm]. + y_position: Y Position [0.1mm]. + begin_z_deposit_position: (0). + end_z_deposit_position: Z deposit position [0.1mm] (collar bearing position). + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of command + [0.1mm]. + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + tip_pattern: Tip pattern (channels involved). [0 = not involved, 1 = involved]. + TODO_TR_2: (0). + tip_handling_method: Tip handling method. + """ + + if not all(0 <= x <= 50000 for x in x_position): + raise ValueError("x_position must be in range 0 to 50000") + + if y_position is None: + y_position = [3000] * self.num_channels + elif not all(0 <= x <= 6500 for x in y_position): + raise ValueError("y_position must be in range 0 to 6500") + + if begin_z_deposit_position is None: + begin_z_deposit_position = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in begin_z_deposit_position): + raise ValueError("begin_z_deposit_position must be in range 0 to 3600") + + if end_z_deposit_position is None: + end_z_deposit_position = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in end_z_deposit_position): + raise ValueError("end_z_deposit_position must be in range 0 to 3600") + + if minimal_traverse_height_at_begin_of_command is None: + minimal_traverse_height_at_begin_of_command = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_traverse_height_at_begin_of_command): + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3600") + + if minimal_height_at_command_end is None: + minimal_height_at_command_end = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_height_at_command_end): + raise ValueError("minimal_height_at_command_end must be in range 0 to 3600") + + if tip_pattern is None: + tip_pattern = [False] * self.num_channels + elif not all(0 <= x <= 1 for x in tip_pattern): + raise ValueError("tip_pattern must be in range 0 to 1") + + if not -1000 <= TODO_TR_2 <= 1000: + raise ValueError("TODO_TR_2 must be in range -1000 to 1000") + + if tip_handling_method is None: + tip_handling_method = [0] * self.num_channels + elif not all(0 <= x <= 9 for x in tip_handling_method): + raise ValueError("tip_handling_method must be in range 0 to 9") + + return await self.send_command( + module="A1PM", + command="TR", + xp=x_position, + yp=y_position, + tp=begin_z_deposit_position, + tz=end_z_deposit_position, + th=minimal_traverse_height_at_begin_of_command, + te=minimal_height_at_command_end, + tm=tip_pattern, + ts=TODO_TR_2, + td=tip_handling_method, + ) + + async def search_for_teach_in_signal_in_x_direction( + self, + channel_index: int = 1, + x_search_distance: int = 0, + x_speed: int = 270, + ): + """ Search for Teach in signal in X direction + + Args: + channel_index: Channel index. + x_search_distance: X search distance [0.1mm]. + x_speed: X speed [0.1mm/s]. + """ + + if not 1 <= channel_index <= 16: + raise ValueError("channel_index must be in range 1 to 16") + + if not -50000 <= x_search_distance <= 50000: + raise ValueError("x_search_distance must be in range -50000 to 50000") + + if not 20 <= x_speed <= 25000: + raise ValueError("x_speed must be in range 20 to 25000") + + return await self.send_command( + module="A1PM", + command="DL", + pn=channel_index, + xs=x_search_distance, + xv=x_speed, + ) + + async def position_all_channels_in_y_direction( + self, + y_position: List[int], + ): + """ Position all channels in Y direction + + Args: + y_position: Y Position [0.1mm]. + """ + + if y_position is None: + y_position = [3000] * self.num_channels + elif not all(0 <= x <= 6500 for x in y_position): + raise ValueError("y_position must be in range 0 to 6500") + + return await self.send_command( + module="A1PM", + command="DY", + yp=y_position, + ) + + async def position_all_channels_in_z_direction( + self, + z_position: Optional[List[int]] = None, + ): + """ Position all channels in Z direction + + Args: + z_position: Z Position [0.1mm]. + """ + + if z_position is None: + z_position = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in z_position): + raise ValueError("z_position must be in range 0 to 3600") + + return await self.send_command( + module="A1PM", + command="DZ", + zp=z_position, + ) + + async def position_single_channel_in_y_direction( + self, + channel_index: int = 1, + y_position: int = 3000, + ): + """ Position single channel in Y direction + + Args: + channel_index: Channel index. + y_position: Y Position [0.1mm]. + """ + + if not 1 <= channel_index <= 16: + raise ValueError("channel_index must be in range 1 to 16") + + if not 0 <= y_position <= 6500: + raise ValueError("y_position must be in range 0 to 6500") + + return await self.send_command( + module="A1PM", + command="DV", + pn=channel_index, + yj=y_position, + ) + + async def position_single_channel_in_z_direction( + self, + channel_index: int = 1, + z_position: int = 0, + ): + """ Position single channel in Z direction + + Args: + channel_index: Channel index. + z_position: Z Position [0.1mm]. + """ + + if not 1 <= channel_index <= 16: + raise ValueError("channel_index must be in range 1 to 16") + + if not 0 <= z_position <= 3600: + raise ValueError("z_position must be in range 0 to 3600") + + return await self.send_command( + module="A1PM", + command="DU", + pn=channel_index, + zj=z_position, + ) + + async def move_to_defined_position( + self, + x_position: List[int], + y_position: List[int], + tip_pattern: Optional[List[bool]] = None, + minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, + z_position: Optional[List[int]] = None, + ): + """ Move to defined position + + Args: + tip_pattern: Tip pattern (channels involved). [0 = not involved, 1 = involved]. + x_position: X Position [0.1mm]. + y_position: Y Position [0.1mm]. + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of command + [0.1mm]. + z_position: Z Position [0.1mm]. + """ + + if tip_pattern is None: + tip_pattern = [False] * self.num_channels + elif not all(0 <= x <= 1 for x in tip_pattern): + raise ValueError("tip_pattern must be in range 0 to 1") + + if not all(0 <= x <= 50000 for x in x_position): + raise ValueError("x_position must be in range 0 to 50000") + + if y_position is None: + y_position = [3000] * self.num_channels + elif not all(0 <= x <= 6500 for x in y_position): + raise ValueError("y_position must be in range 0 to 6500") + + if minimal_traverse_height_at_begin_of_command is None: + minimal_traverse_height_at_begin_of_command = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_traverse_height_at_begin_of_command): + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3600") + + if z_position is None: + z_position = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in z_position): + raise ValueError("z_position must be in range 0 to 3600") + + return await self.send_command( + module="A1PM", + command="DN", + tm=tip_pattern, + xp=x_position, + yp=y_position, + th=minimal_traverse_height_at_begin_of_command, + zp=z_position, + ) + + async def teach_rack_using_channel_n( + self, + channel_index: int = 1, + gap_center_x_direction: int = 0, + gap_center_y_direction: int = 3000, + gap_center_z_direction: int = 0, + minimal_height_at_command_end: Optional[List[int]] = None, + ): + """ Teach rack using channel n + + Attention! Channels not involved must first be taken out of measurement range. + + Args: + channel_index: Channel index. + gap_center_x_direction: Gap center X direction [0.1mm]. + gap_center_y_direction: Gap center Y direction [0.1mm]. + gap_center_z_direction: Gap center Z direction [0.1mm]. + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + """ + + if not 1 <= channel_index <= 16: + raise ValueError("channel_index must be in range 1 to 16") + + if not -50000 <= gap_center_x_direction <= 50000: + raise ValueError("gap_center_x_direction must be in range -50000 to 50000") + + if not 0 <= gap_center_y_direction <= 6500: + raise ValueError("gap_center_y_direction must be in range 0 to 6500") + + if not 0 <= gap_center_z_direction <= 3600: + raise ValueError("gap_center_z_direction must be in range 0 to 3600") + + if minimal_height_at_command_end is None: + minimal_height_at_command_end = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_height_at_command_end): + raise ValueError("minimal_height_at_command_end must be in range 0 to 3600") + + return await self.send_command( + module="A1PM", + command="DT", + pn=channel_index, + xa=gap_center_x_direction, + yj=gap_center_y_direction, + zj=gap_center_z_direction, + te=minimal_height_at_command_end, + ) + + async def expose_channel_n( + self, + channel_index: int = 1, + ): + """ Expose channel n + + Args: + channel_index: Channel index. + """ + + if not 1 <= channel_index <= 16: + raise ValueError("channel_index must be in range 1 to 16") + + return await self.send_command( + module="A1PM", + command="DQ", + pn=channel_index, + ) + + async def calculates_check_sums_and_compares_them_with_the_value_saved_in_flash_eprom( + self, + TODO_DC_0: int = 0, + TODO_DC_1: int = 3000, + tip_type: Optional[List[int]] = None, + TODO_DC_2: Optional[List[int]] = None, + z_deposit_position: Optional[List[int]] = None, + 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 + + Args: + TODO_DC_0: (0). + TODO_DC_1: (0). + tip_type: Tip type (see command TT). + TODO_DC_2: (0). + z_deposit_position: Z deposit position [0.1mm] (collar bearing position). + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of command + [0.1mm]. + first_pip_channel_node_no: First (lower) pip. channel node no. (0 = disabled). + """ + + if not -50000 <= TODO_DC_0 <= 50000: + raise ValueError("TODO_DC_0 must be in range -50000 to 50000") + + if not 0 <= TODO_DC_1 <= 6500: + raise ValueError("TODO_DC_1 must be in range 0 to 6500") + + if tip_type is None: + tip_type = [4] * self.num_channels + elif not all(0 <= x <= 199 for x in tip_type): + raise ValueError("tip_type must be in range 0 to 199") + + if TODO_DC_2 is None: + TODO_DC_2 = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in TODO_DC_2): + raise ValueError("TODO_DC_2 must be in range 0 to 3600") + + if z_deposit_position is None: + z_deposit_position = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in z_deposit_position): + raise ValueError("z_deposit_position must be in range 0 to 3600") + + if minimal_traverse_height_at_begin_of_command is None: + minimal_traverse_height_at_begin_of_command = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_traverse_height_at_begin_of_command): + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3600") + + if not 1 <= first_pip_channel_node_no <= 16: + raise ValueError("first_pip_channel_node_no must be in range 1 to 16") + + return await self.send_command( + module="A1PM", + command="DC", + xa=TODO_DC_0, + yj=TODO_DC_1, + tt=tip_type, + tp=TODO_DC_2, + tz=z_deposit_position, + th=minimal_traverse_height_at_begin_of_command, + pa=first_pip_channel_node_no, + ) + + async def discard_core_gripper_tool( + self, + gripper_tool_x_position: int = 0, + first_gripper_tool_y_pos: int = 3000, + tip_type: Optional[List[int]] = None, + begin_z_deposit_position: Optional[List[int]] = None, + end_z_deposit_position: Optional[List[int]] = None, + minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, + first_pip_channel_node_no: int = 1, + minimal_height_at_command_end: Optional[List[int]] = None, + ): + """ Discard CoRe gripper tool + + Args: + gripper_tool_x_position: (0). + first_gripper_tool_y_pos: First (lower channel) CoRe gripper tool Y pos. [0.1mm] + tip_type: Tip type (see command TT). + begin_z_deposit_position: (0). + end_z_deposit_position: Z deposit position [0.1mm] (collar bearing position). + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of command + [0.1mm]. + first_pip_channel_node_no: First (lower) pip. channel node no. (0 = disabled). + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + """ + + if not -50000 <= gripper_tool_x_position <= 50000: + raise ValueError("gripper_tool_x_position must be in range -50000 to 50000") + + if not 0 <= first_gripper_tool_y_pos <= 6500: + raise ValueError("first_gripper_tool_y_pos must be in range 0 to 6500") + + if tip_type is None: + tip_type = [4] * self.num_channels + elif not all(0 <= x <= 199 for x in tip_type): + raise ValueError("tip_type must be in range 0 to 199") + + if begin_z_deposit_position is None: + begin_z_deposit_position = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in begin_z_deposit_position): + raise ValueError("begin_z_deposit_position must be in range 0 to 3600") + + if end_z_deposit_position is None: + end_z_deposit_position = [0] * self.num_channels + elif not all(0 <= x <= 3600 for x in end_z_deposit_position): + raise ValueError("end_z_deposit_position must be in range 0 to 3600") + + if minimal_traverse_height_at_begin_of_command is None: + minimal_traverse_height_at_begin_of_command = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_traverse_height_at_begin_of_command): + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3600") + + if not 1 <= first_pip_channel_node_no <= 16: + raise ValueError("first_pip_channel_node_no must be in range 1 to 16") + + if minimal_height_at_command_end is None: + minimal_height_at_command_end = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_height_at_command_end): + raise ValueError("minimal_height_at_command_end must be in range 0 to 3600") + + return await self.send_command( + module="A1PM", + command="DJ", + xa=gripper_tool_x_position, + yj=first_gripper_tool_y_pos, + tt=tip_type, + tp=begin_z_deposit_position, + tz=end_z_deposit_position, + th=minimal_traverse_height_at_begin_of_command, + pa=first_pip_channel_node_no, + te=minimal_height_at_command_end, + ) + + async def grip_plate( + self, + plate_center_x_direction: int = 0, + plate_center_y_direction: int = 3000, + plate_center_z_direction: int = 0, + z_speed: int = 1287, + open_gripper_position: int = 860, + plate_width: int = 800, + acceleration_index: int = 4, + grip_strength: int = 30, + minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, + minimal_height_at_command_end: Optional[List[int]] = None, + ): + """ Grip plate + + Args: + plate_center_x_direction: Plate center X direction [0.1mm]. + plate_center_y_direction: Plate center Y direction [0.1mm]. + plate_center_z_direction: Plate center Z direction [0.1mm]. + z_speed: Z speed [0.1mm/sec]. + open_gripper_position: Open gripper position [0.1mm]. + plate_width: Plate width [0.1mm]. + acceleration_index: Acceleration index. + grip_strength: Grip strength (0 = low 99 = high). + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of command + [0.1mm]. + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + """ + + if not -50000 <= plate_center_x_direction <= 50000: + raise ValueError("plate_center_x_direction must be in range -50000 to 50000") + + if not 0 <= plate_center_y_direction <= 6500: + raise ValueError("plate_center_y_direction must be in range 0 to 6500") + + if not 0 <= plate_center_z_direction <= 3600: + raise ValueError("plate_center_z_direction must be in range 0 to 3600") + + if not 3 <= z_speed <= 1600: + raise ValueError("z_speed must be in range 3 to 1600") + + if not 0 <= open_gripper_position <= 9999: + raise ValueError("open_gripper_position must be in range 0 to 9999") + + if not 0 <= plate_width <= 9999: + raise ValueError("plate_width must be in range 0 to 9999") + + if not 0 <= acceleration_index <= 4: + raise ValueError("acceleration_index must be in range 0 to 4") + + if not 0 <= grip_strength <= 99: + raise ValueError("grip_strength must be in range 0 to 99") + + if minimal_traverse_height_at_begin_of_command is None: + minimal_traverse_height_at_begin_of_command = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_traverse_height_at_begin_of_command): + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3600") + + if minimal_height_at_command_end is None: + minimal_height_at_command_end = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_height_at_command_end): + raise ValueError("minimal_height_at_command_end must be in range 0 to 3600") + + return await self.send_command( + module="A1PM", + command="DG", + xa=plate_center_x_direction, + yj=plate_center_y_direction, + zj=plate_center_z_direction, + zy=z_speed, + yo=open_gripper_position, + yg=plate_width, + ai=acceleration_index, + yw=grip_strength, + th=minimal_traverse_height_at_begin_of_command, + te=minimal_height_at_command_end, + ) + + async def put_plate( + self, + plate_center_x_direction: int = 0, + plate_center_y_direction: int = 3000, + plate_center_z_direction: int = 0, + press_on_distance: int = 5, + z_speed: int = 1287, + open_gripper_position: int = 860, + minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, + minimal_height_at_command_end: Optional[List[int]] = None, + ): + """ Put plate + + Args: + plate_center_x_direction: Plate center X direction [0.1mm]. + plate_center_y_direction: Plate center Y direction [0.1mm]. + plate_center_z_direction: Plate center Z direction [0.1mm]. + press_on_distance: Press on distance [0.1mm]. + z_speed: Z speed [0.1mm/sec]. + open_gripper_position: Open gripper position [0.1mm]. + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of command + [0.1mm]. + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + """ + + if not -50000 <= plate_center_x_direction <= 50000: + raise ValueError("plate_center_x_direction must be in range -50000 to 50000") + + if not 0 <= plate_center_y_direction <= 6500: + raise ValueError("plate_center_y_direction must be in range 0 to 6500") + + if not 0 <= plate_center_z_direction <= 3600: + raise ValueError("plate_center_z_direction must be in range 0 to 3600") + + if not 0 <= press_on_distance <= 999: + raise ValueError("press_on_distance must be in range 0 to 999") + + if not 3 <= z_speed <= 1600: + raise ValueError("z_speed must be in range 3 to 1600") + + if not 0 <= open_gripper_position <= 9999: + raise ValueError("open_gripper_position must be in range 0 to 9999") + + if minimal_traverse_height_at_begin_of_command is None: + minimal_traverse_height_at_begin_of_command = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_traverse_height_at_begin_of_command): + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3600") + + if minimal_height_at_command_end is None: + minimal_height_at_command_end = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_height_at_command_end): + raise ValueError("minimal_height_at_command_end must be in range 0 to 3600") + + return await self.send_command( + module="A1PM", + command="DR", + xa=plate_center_x_direction, + yj=plate_center_y_direction, + zj=plate_center_z_direction, + zi=press_on_distance, + zy=z_speed, + yo=open_gripper_position, + th=minimal_traverse_height_at_begin_of_command, + te=minimal_height_at_command_end, + ) + + async def move_to_position( + self, + plate_center_x_direction: int = 0, + plate_center_y_direction: int = 3000, + plate_center_z_direction: int = 0, + z_speed: int = 1287, + minimal_traverse_height_at_begin_of_command: Optional[List[int]] = None, + ): + """ Move to position + + Args: + plate_center_x_direction: Plate center X direction [0.1mm]. + plate_center_y_direction: Plate center Y direction [0.1mm]. + plate_center_z_direction: Plate center Z direction [0.1mm]. + z_speed: Z speed [0.1mm/sec]. + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of command + [0.1mm]. + """ + + if not -50000 <= plate_center_x_direction <= 50000: + raise ValueError("plate_center_x_direction must be in range -50000 to 50000") + + if not 0 <= plate_center_y_direction <= 6500: + raise ValueError("plate_center_y_direction must be in range 0 to 6500") + + if not 0 <= plate_center_z_direction <= 3600: + raise ValueError("plate_center_z_direction must be in range 0 to 3600") + + if not 3 <= z_speed <= 1600: + raise ValueError("z_speed must be in range 3 to 1600") + + if minimal_traverse_height_at_begin_of_command is None: + minimal_traverse_height_at_begin_of_command = [3600] * self.num_channels + elif not all(0 <= x <= 3600 for x in minimal_traverse_height_at_begin_of_command): + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3600") + + return await self.send_command( + module="A1PM", + command="DH", + xa=plate_center_x_direction, + yj=plate_center_y_direction, + zj=plate_center_z_direction, + zy=z_speed, + th=minimal_traverse_height_at_begin_of_command, + ) + + async def release_object( + self, + first_pip_channel_node_no: int = 1, + ): + """ Release object + + Args: + first_pip_channel_node_no: First (lower) pip. channel node no. (0 = disabled). + """ + + if not 1 <= first_pip_channel_node_no <= 16: + raise ValueError("first_pip_channel_node_no must be in range 1 to 16") + + return await self.send_command( + module="A1PM", + command="DO", + pa=first_pip_channel_node_no, + ) + + async def set_any_parameter_within_this_module(self): + """ Set any parameter within this module """ + + return await self.send_command( + module="A1PM", + command="AA", + ) + + async def request_y_positions_of_all_channels(self): + """ Request Y Positions of all channels """ + + return await self.send_command( + module="A1PM", + command="RY", + ) + + async def request_y_position_of_channel_n(self): + """ Request Y Position of channel n """ + + return await self.send_command( + module="A1PM", + command="RB", + ) + + async def request_z_positions_of_all_channels(self): + """ Request Z Positions of all channels """ + + return await self.send_command( + module="A1PM", + command="RZ", + ) + + async def request_z_position_of_channel_n(self): + """ Request Z Position of channel n """ + + return await self.send_command( + module="A1PM", + command="RD", + ) + + async def query_tip_presence(self): + """ Query Tip presence """ + + return await self.send_command( + module="A1PM", + command="QA", + ) + + async def request_height_of_last_lld(self): + """ Request height of last LLD """ + + return await self.send_command( + module="A1PM", + command="RL", + ) + + async def request_channel_dispense_on_fly_status(self): + """ Request channel dispense on fly status """ + + return await self.send_command( + module="A1PM", + command="QF", + ) + + async def core96_initialize( + self, + x_position: int = 5000, + y_position: int = 5000, + z_position: int = 0, + minimal_traverse_height_at_begin_of_command: int = 3900, + minimal_height_at_command_end: int = 3900, + end_z_deposit_position: int = 0, + tip_type: int = 4, + ): + """ Initialize 96 head. + + Args: + x_position: X Position [0.1mm]. + y_position: Y Position [0.1mm]. + z_position: Z Position [0.1mm]. + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of command + [0.1mm]. + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + end_z_deposit_position: Z deposit position [0.1mm] (collar bearing position). (not documented, + but present in the log files.) + tip_type: Tip type (see command TT). + """ + + if not -500000 <= x_position <= 50000: + raise ValueError("x_position must be in range -500000 to 50000") + + if not 422 <= y_position <= 5921: + raise ValueError("y_position must be in range 422 to 5921") + + if not 0 <= z_position <= 3900: + raise ValueError("z_position must be in range 0 to 3900") + + if not 0 <= minimal_traverse_height_at_begin_of_command <= 3900: + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3900") + + if not 0 <= minimal_height_at_command_end <= 3900: + raise ValueError("minimal_height_at_command_end must be in range 0 to 3900") + + if not 0 <= end_z_deposit_position <= 3600: + raise ValueError("end_z_deposit_position must be in range 0 to 3600") + + if not 0 <= tip_type <= 199: + raise ValueError("tip_type must be in range 0 to 199") + + return await self.send_command( + module="A1HM", + command="DI", + xp=x_position, + yp=y_position, + zp=z_position, + th=minimal_traverse_height_at_begin_of_command, + te=minimal_height_at_command_end, + tz=end_z_deposit_position, + tt=tip_type, + ) + + async def core96_aspiration_of_liquid( + self, + type_of_aspiration: int = 0, + x_position: int = 5000, + y_position: int = 5000, + minimal_traverse_height_at_begin_of_command: int = 3900, + minimal_height_at_command_end: int = 3900, + lld_search_height: int = 0, + liquid_surface_at_function_without_lld: int = 3900, + pull_out_distance_to_take_transport_air_in_function_without_lld: int = 50, + minimum_height: int = 3900, + tube_2nd_section_height_measured_from_zm: int = 0, + tube_2nd_section_ratio: int = 0, + immersion_depth: int = 0, + surface_following_distance: int = 0, + aspiration_volume: int = 0, + aspiration_speed: int = 2000, + transport_air_volume: int = 0, + blow_out_air_volume: int = 1000, + pre_wetting_volume: int = 0, + lld_mode: int = 1, + lld_sensitivity: int = 1, + swap_speed: int = 100, + settling_time: int = 5, + mix_volume: int = 0, + mix_cycles: int = 0, + mix_position_in_z_direction_from_liquid_surface: int = 0, + surface_following_distance_during_mixing: int = 0, + mix_speed: int = 2000, + limit_curve_index: int = 0, + tadm_channel_pattern: Optional[List[bool]] = None, + tadm_algorithm_on_off: int = 0, + recording_mode: int = 0, + ): + """ Aspiration of liquid using the 96 head. + + Args: + type_of_aspiration: Type of aspiration (0 = simple 1 = sequence 2 = cup emptied). + x_position: X Position [0.1mm]. + y_position: Y Position [0.1mm]. + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of + command [0.1mm]. + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + lld_search_height: LLD search height [0.1mm]. + liquid_surface_at_function_without_lld: Liquid surface at function without LLD [0.1mm]. + pull_out_distance_to_take_transport_air_in_function_without_lld: + Pull out distance to take transp. air in function without LLD [0.1mm] + . + minimum_height: Minimum height (maximum immersion depth) [0.1mm]. + tube_2nd_section_height_measured_from_zm: Tube 2nd section height measured from zm [0.1mm]. + tube_2nd_section_ratio: Tube 2nd section ratio. + immersion_depth: Immersion depth [0.1mm]. + surface_following_distance: Surface following distance [0.1mm]. + aspiration_volume: Aspiration volume [0.01ul]. + aspiration_speed: Aspiration speed [0.1ul]/s. + transport_air_volume: Transport air volume [0.1ul]. + blow_out_air_volume: Blow out air volume [0.01ul]. + pre_wetting_volume: Pre wetting volume [0.1ul]. + lld_mode: LLD Mode (0 = off). + lld_sensitivity: LLD sensitivity (1 = high, 4 = low). + swap_speed: Swap speed (on leaving liquid) [0.1mm/s]. + settling_time: Settling time [0.1s]. + mix_volume: Mix volume [0.1ul]. + mix_cycles: Mix cycles. + mix_position_in_z_direction_from_liquid_surface: Mix position in Z direction from liquid + surface[0.1mm]. + surface_following_distance_during_mixing: Surface following distance during mixing [0.1mm]. + mix_speed: Mix speed [0.1ul/s]. + limit_curve_index: Limit curve index. + tadm_channel_pattern: TADM Channel pattern. + tadm_algorithm_on_off: TADM algorithm on/off (0 = off). + recording_mode: + Recording mode (0 = no 1 = TADM errors only 2 = all TADM measurements) + . + """ + + if not 0 <= type_of_aspiration <= 2: + raise ValueError("type_of_aspiration must be in range 0 to 2") + + if not -500000 <= x_position <= 50000: + raise ValueError("x_position must be in range -500000 to 50000") + + if not 422 <= y_position <= 5921: + raise ValueError("y_position must be in range 422 to 5921") + + if not 0 <= minimal_traverse_height_at_begin_of_command <= 3900: + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3900") + + if not 0 <= minimal_height_at_command_end <= 3900: + raise ValueError("minimal_height_at_command_end must be in range 0 to 3900") + + if not 0 <= lld_search_height <= 3900: + raise ValueError("lld_search_height must be in range 0 to 3900") + + if not 0 <= liquid_surface_at_function_without_lld <= 3900: + 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") + + if not 0 <= minimum_height <= 3900: + raise ValueError("minimum_height must be in range 0 to 3900") + + if not 0 <= tube_2nd_section_height_measured_from_zm <= 3900: + raise ValueError("tube_2nd_section_height_measured_from_zm must be in range 0 to 3900") + + if not 0 <= tube_2nd_section_ratio <= 10000: + raise ValueError("tube_2nd_section_ratio must be in range 0 to 10000") + + if not -990 <= immersion_depth <= 990: + raise ValueError("immersion_depth must be in range -990 to 990") + + if not 0 <= surface_following_distance <= 990: + raise ValueError("surface_following_distance must be in range 0 to 990") + + if not 0 <= aspiration_volume <= 115000: + raise ValueError("aspiration_volume must be in range 0 to 115000") + + if not 3 <= aspiration_speed <= 5000: + raise ValueError("aspiration_speed must be in range 3 to 5000") + + if not 0 <= transport_air_volume <= 1000: + raise ValueError("transport_air_volume must be in range 0 to 1000") + + if not 0 <= blow_out_air_volume <= 115000: + raise ValueError("blow_out_air_volume must be in range 0 to 115000") + + if not 0 <= pre_wetting_volume <= 11500: + raise ValueError("pre_wetting_volume must be in range 0 to 11500") + + if not 0 <= lld_mode <= 1: + raise ValueError("lld_mode must be in range 0 to 1") + + if not 1 <= lld_sensitivity <= 4: + raise ValueError("lld_sensitivity must be in range 1 to 4") + + if not 3 <= swap_speed <= 1000: + raise ValueError("swap_speed must be in range 3 to 1000") + + if not 0 <= settling_time <= 99: + raise ValueError("settling_time must be in range 0 to 99") + + if not 0 <= mix_volume <= 11500: + raise ValueError("mix_volume must be in range 0 to 11500") + + if not 0 <= mix_cycles <= 99: + raise ValueError("mix_cycles must be in range 0 to 99") + + if not 0 <= mix_position_in_z_direction_from_liquid_surface <= 990: + raise ValueError("mix_position_in_z_direction_from_liquid_surface must be in range 0 to 990") + + if not 0 <= surface_following_distance_during_mixing <= 990: + raise ValueError("surface_following_distance_during_mixing must be in range 0 to 990") + + if not 3 <= mix_speed <= 5000: + raise ValueError("mix_speed must be in range 3 to 5000") + + if not 0 <= limit_curve_index <= 999: + raise ValueError("limit_curve_index must be in range 0 to 999") + + 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)}'") + 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: + raise ValueError("tadm_algorithm_on_off must be in range 0 to 1") + + if not 0 <= recording_mode <= 2: + raise ValueError("recording_mode must be in range 0 to 2") + + return await self.send_command( + module="A1HM", + command="DA", + at=type_of_aspiration, + xp=x_position, + yp=y_position, + th=minimal_traverse_height_at_begin_of_command, + te=minimal_height_at_command_end, + lp=lld_search_height, + zl=liquid_surface_at_function_without_lld, + po=pull_out_distance_to_take_transport_air_in_function_without_lld, + zx=minimum_height, + zu=tube_2nd_section_height_measured_from_zm, + zr=tube_2nd_section_ratio, + ip=immersion_depth, + fp=surface_following_distance, + av=aspiration_volume, + as_=aspiration_speed, + ta=transport_air_volume, + ba=blow_out_air_volume, + oa=pre_wetting_volume, + lm=lld_mode, + ll=lld_sensitivity, + de=swap_speed, + wt=settling_time, + mv=mix_volume, + mc=mix_cycles, + mp=mix_position_in_z_direction_from_liquid_surface, + mh=surface_following_distance_during_mixing, + ms=mix_speed, + gi=limit_curve_index, + cw=hex(tadm_channel_pattern_num)[2:].upper(), + gj=tadm_algorithm_on_off, + gk=recording_mode, + ) + + async def core96_dispensing_of_liquid( + self, + type_of_dispensing_mode: int = 0, + x_position: int = 5000, + y_position: int = 5000, + minimum_height: int = 3900, + tube_2nd_section_height_measured_from_zm: int = 0, + tube_2nd_section_ratio: int = 0, + lld_search_height: int = 0, + liquid_surface_at_function_without_lld: int = 3900, + pull_out_distance_to_take_transport_air_in_function_without_lld: int = 50, + immersion_depth: int = 0, + surface_following_distance: int = 0, + minimal_traverse_height_at_begin_of_command: int = 3900, + minimal_height_at_command_end: int = 3900, + dispense_volume: int = 0, + dispense_speed: int = 2000, + cut_off_speed: int = 1500, + stop_back_volume: int = 0, + transport_air_volume: int = 0, + blow_out_air_volume: int = 1000, + lld_mode: int = 1, + lld_sensitivity: int = 1, + side_touch_off_distance: int = 0, + swap_speed: int = 100, + settling_time: int = 5, + mix_volume: int = 0, + mix_cycles: int = 0, + mix_position_in_z_direction_from_liquid_surface: int = 0, + surface_following_distance_during_mixing: int = 0, + mix_speed: int = 2000, + limit_curve_index: int = 0, + tadm_channel_pattern: Optional[List[bool]] = None, + tadm_algorithm_on_off: int = 0, + recording_mode: int = 0, + ): + """ 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 + surface 3 = Blow at surface 4 = Empty. + x_position: X Position [0.1mm]. + y_position: Y Position [0.1mm]. + minimum_height: Minimum height (maximum immersion depth) [0.1mm]. + tube_2nd_section_height_measured_from_zm: Tube 2nd section height measured from zm [0.1mm]. + tube_2nd_section_ratio: Tube 2nd section ratio. + lld_search_height: LLD search height [0.1mm]. + liquid_surface_at_function_without_lld: Liquid surface at function without LLD [0.1mm]. + pull_out_distance_to_take_transport_air_in_function_without_lld: + Pull out distance to take transp. air in function without LLD [0.1mm] + . + immersion_depth: Immersion depth [0.1mm]. + surface_following_distance: Surface following distance [0.1mm]. + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of + command [0.1mm]. + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + dispense_volume: Dispense volume [0.01ul]. + dispense_speed: Dispense speed [0.1ul/s]. + cut_off_speed: Cut off speed [0.1ul/s]. + stop_back_volume: Stop back volume [0.1ul]. + transport_air_volume: Transport air volume [0.1ul]. + blow_out_air_volume: Blow out air volume [0.01ul]. + lld_mode: LLD Mode (0 = off). + lld_sensitivity: LLD sensitivity (1 = high, 4 = low). + side_touch_off_distance: Side touch off distance [0.1mm]. + swap_speed: Swap speed (on leaving liquid) [0.1mm/s]. + settling_time: Settling time [0.1s]. + mix_volume: Mix volume [0.1ul]. + mix_cycles: Mix cycles. + mix_position_in_z_direction_from_liquid_surface: Mix position in Z direction from liquid + surface[0.1mm]. + surface_following_distance_during_mixing: Surface following distance during mixing [0.1mm]. + mix_speed: Mix speed [0.1ul/s]. + limit_curve_index: Limit curve index. + tadm_channel_pattern: TADM Channel pattern. + tadm_algorithm_on_off: TADM algorithm on/off (0 = off). + recording_mode: + Recording mode (0 = no 1 = TADM errors only 2 = all TADM measurements) + . + """ + + if not 0 <= type_of_dispensing_mode <= 4: + raise ValueError("type_of_dispensing_mode must be in range 0 to 4") + + if not -500000 <= x_position <= 50000: + raise ValueError("x_position must be in range -500000 to 50000") + + if not 422 <= y_position <= 5921: + raise ValueError("y_position must be in range 422 to 5921") + + if not 0 <= minimum_height <= 3900: + raise ValueError("minimum_height must be in range 0 to 3900") + + if not 0 <= tube_2nd_section_height_measured_from_zm <= 3900: + raise ValueError("tube_2nd_section_height_measured_from_zm must be in range 0 to 3900") + + if not 0 <= tube_2nd_section_ratio <= 10000: + raise ValueError("tube_2nd_section_ratio must be in range 0 to 10000") + + if not 0 <= lld_search_height <= 3900: + raise ValueError("lld_search_height must be in range 0 to 3900") + + if not 0 <= liquid_surface_at_function_without_lld <= 3900: + 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") + + if not -990 <= immersion_depth <= 990: + raise ValueError("immersion_depth must be in range -990 to 990") + + if not 0 <= surface_following_distance <= 990: + raise ValueError("surface_following_distance must be in range 0 to 990") + + if not 0 <= minimal_traverse_height_at_begin_of_command <= 3900: + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3900") + + if not 0 <= minimal_height_at_command_end <= 3900: + raise ValueError("minimal_height_at_command_end must be in range 0 to 3900") + + if not 0 <= dispense_volume <= 115000: + raise ValueError("dispense_volume must be in range 0 to 115000") + + if not 3 <= dispense_speed <= 5000: + raise ValueError("dispense_speed must be in range 3 to 5000") + + if not 3 <= cut_off_speed <= 5000: + raise ValueError("cut_off_speed must be in range 3 to 5000") + + if not 0 <= stop_back_volume <= 2000: + raise ValueError("stop_back_volume must be in range 0 to 2000") + + if not 0 <= transport_air_volume <= 1000: + raise ValueError("transport_air_volume must be in range 0 to 1000") + + if not 0 <= blow_out_air_volume <= 115000: + raise ValueError("blow_out_air_volume must be in range 0 to 115000") + + if not 0 <= lld_mode <= 1: + raise ValueError("lld_mode must be in range 0 to 1") + + if not 1 <= lld_sensitivity <= 4: + raise ValueError("lld_sensitivity must be in range 1 to 4") + + if not 0 <= side_touch_off_distance <= 30: + raise ValueError("side_touch_off_distance must be in range 0 to 30") + + if not 3 <= swap_speed <= 1000: + raise ValueError("swap_speed must be in range 3 to 1000") + + if not 0 <= settling_time <= 99: + raise ValueError("settling_time must be in range 0 to 99") + + if not 0 <= mix_volume <= 11500: + raise ValueError("mix_volume must be in range 0 to 11500") + + if not 0 <= mix_cycles <= 99: + raise ValueError("mix_cycles must be in range 0 to 99") + + if not 0 <= mix_position_in_z_direction_from_liquid_surface <= 990: + raise ValueError("mix_position_in_z_direction_from_liquid_surface must be in range 0 to 990") + + if not 0 <= surface_following_distance_during_mixing <= 990: + raise ValueError("surface_following_distance_during_mixing must be in range 0 to 990") + + if not 3 <= mix_speed <= 5000: + raise ValueError("mix_speed must be in range 3 to 5000") + + if not 0 <= limit_curve_index <= 999: + raise ValueError("limit_curve_index must be in range 0 to 999") + + 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)}'") + 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: + raise ValueError("tadm_algorithm_on_off must be in range 0 to 1") + + if not 0 <= recording_mode <= 2: + raise ValueError("recording_mode must be in range 0 to 2") + + return await self.send_command( + module="A1HM", + command="DD", + dm=type_of_dispensing_mode, + xp=x_position, + yp=y_position, + zx=minimum_height, + zu=tube_2nd_section_height_measured_from_zm, + zr=tube_2nd_section_ratio, + lp=lld_search_height, + zl=liquid_surface_at_function_without_lld, + po=pull_out_distance_to_take_transport_air_in_function_without_lld, + ip=immersion_depth, + fp=surface_following_distance, + th=minimal_traverse_height_at_begin_of_command, + te=minimal_height_at_command_end, + dv=dispense_volume, + ds=dispense_speed, + ss=cut_off_speed, + rv=stop_back_volume, + ta=transport_air_volume, + ba=blow_out_air_volume, + lm=lld_mode, + ll=lld_sensitivity, + dj=side_touch_off_distance, + de=swap_speed, + wt=settling_time, + mv=mix_volume, + mc=mix_cycles, + mp=mix_position_in_z_direction_from_liquid_surface, + mh=surface_following_distance_during_mixing, + ms=mix_speed, + gi=limit_curve_index, + cw=hex(tadm_channel_pattern_num)[2:].upper(), + gj=tadm_algorithm_on_off, + gk=recording_mode, + ) + + async def core96_tip_pick_up( + self, + x_position: int = 5000, + y_position: int = 5000, + tip_type: int = 4, + tip_handling_method: int = 0, + z_deposit_position: int = 0, + minimal_traverse_height_at_begin_of_command: int = 3900, + minimal_height_at_command_end: int = 3900, + ): + """ Tip Pick up using the 96 head. + + Args: + x_position: X Position [0.1mm]. + y_position: Y Position [0.1mm]. + tip_type: Tip type (see command TT). + tip_handling_method: Tip handling method. + z_deposit_position: Z deposit position [0.1mm] (collar bearing position). + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of + command [0.1mm]. + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + """ + + if not -500000 <= x_position <= 50000: + raise ValueError("x_position must be in range -500000 to 50000") + + if not 422 <= y_position <= 5921: + raise ValueError("y_position must be in range 422 to 5921") + + if not 0 <= tip_type <= 199: + raise ValueError("tip_type must be in range 0 to 199") + + if not 0 <= tip_handling_method <= 2: + raise ValueError("tip_handling_method must be in range 0 to 2") + + if not 0 <= z_deposit_position <= 3900: + raise ValueError("z_deposit_position must be in range 0 to 3900") + + if not 0 <= minimal_traverse_height_at_begin_of_command <= 3900: + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3900") + + if not 0 <= minimal_height_at_command_end <= 3900: + raise ValueError("minimal_height_at_command_end must be in range 0 to 3900") + + return await self.send_command( + module="A1HM", + command="TP", + xp=x_position, + yp=y_position, + tt=tip_type, + td=tip_handling_method, + tz=z_deposit_position, + th=minimal_traverse_height_at_begin_of_command, + te=minimal_height_at_command_end, + ) + + async def core96_tip_discard( + self, + x_position: int = 5000, + y_position: int = 5000, + z_deposit_position: int = 0, + minimal_traverse_height_at_begin_of_command: int = 3900, + minimal_height_at_command_end: int = 3900, + ): + """ Tip Discard using the 96 head. + + Args: + x_position: X Position [0.1mm]. + y_position: Y Position [0.1mm]. + z_deposit_position: Z deposit position [0.1mm] (collar bearing position). + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of + command [0.1mm]. + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + """ + + if not -500000 <= x_position <= 50000: + raise ValueError("x_position must be in range -500000 to 50000") + + if not 422 <= y_position <= 5921: + raise ValueError("y_position must be in range 422 to 5921") + + if not 0 <= z_deposit_position <= 3900: + raise ValueError("z_deposit_position must be in range 0 to 3900") + + if not 0 <= minimal_traverse_height_at_begin_of_command <= 3900: + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3900") + + if not 0 <= minimal_height_at_command_end <= 3900: + raise ValueError("minimal_height_at_command_end must be in range 0 to 3900") + + return await self.send_command( + module="A1HM", + command="TR", + xp=x_position, + yp=y_position, + tz=z_deposit_position, + th=minimal_traverse_height_at_begin_of_command, + te=minimal_height_at_command_end, + ) + + async def core96_move_to_defined_position( + self, + x_position: int = 5000, + y_position: int = 5000, + z_position: int = 0, + minimal_traverse_height_at_begin_of_command: int = 3900, + ): + """ Move to defined position using the 96 head. + + Args: + x_position: X Position [0.1mm]. + y_position: Y Position [0.1mm]. + z_position: Z Position [0.1mm]. + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of + command [0.1mm]. + """ + + if not -500000 <= x_position <= 50000: + raise ValueError("x_position must be in range -500000 to 50000") + + if not 422 <= y_position <= 5921: + raise ValueError("y_position must be in range 422 to 5921") + + if not 0 <= z_position <= 3900: + raise ValueError("z_position must be in range 0 to 3900") + + if not 0 <= minimal_traverse_height_at_begin_of_command <= 3900: + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3900") + + return await self.send_command( + module="A1HM", + command="DN", + xp=x_position, + yp=y_position, + zp=z_position, + th=minimal_traverse_height_at_begin_of_command, + ) + + async def core96_wash_tips( + self, + x_position: int = 5000, + y_position: int = 5000, + liquid_surface_at_function_without_lld: int = 3900, + minimum_height: int = 3900, + surface_following_distance_during_mixing: int = 0, + minimal_traverse_height_at_begin_of_command: int = 3900, + mix_volume: int = 0, + mix_cycles: int = 0, + mix_speed: int = 2000, + ): + """ Wash tips on the 96 head. + + Args: + x_position: X Position [0.1mm]. + y_position: Y Position [0.1mm]. + liquid_surface_at_function_without_lld: Liquid surface at function without LLD [0.1mm]. + minimum_height: Minimum height (maximum immersion depth) [0.1mm]. + surface_following_distance_during_mixing: Surface following distance during mixing [0.1mm]. + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of command + [0.1mm]. + mix_volume: Mix volume [0.1ul]. + mix_cycles: Mix cycles. + mix_speed: Mix speed [0.1ul/s]. + """ + + if not -500000 <= x_position <= 50000: + raise ValueError("x_position must be in range -500000 to 50000") + + if not 422 <= y_position <= 5921: + raise ValueError("y_position must be in range 422 to 5921") + + if not 0 <= liquid_surface_at_function_without_lld <= 3900: + raise ValueError("liquid_surface_at_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") + + if not 0 <= surface_following_distance_during_mixing <= 990: + raise ValueError("surface_following_distance_during_mixing must be in range 0 to 990") + + if not 0 <= minimal_traverse_height_at_begin_of_command <= 3900: + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 3900") + + if not 0 <= mix_volume <= 11500: + raise ValueError("mix_volume must be in range 0 to 11500") + + if not 0 <= mix_cycles <= 99: + raise ValueError("mix_cycles must be in range 0 to 99") + + if not 3 <= mix_speed <= 5000: + raise ValueError("mix_speed must be in range 3 to 5000") + + return await self.send_command( + module="A1HM", + command="DW", + xp=x_position, + yp=y_position, + zl=liquid_surface_at_function_without_lld, + zx=minimum_height, + mh=surface_following_distance_during_mixing, + th=minimal_traverse_height_at_begin_of_command, + mv=mix_volume, + mc=mix_cycles, + ms=mix_speed, + ) + + async def core96_empty_washed_tips( + self, + 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. + + Args: + liquid_surface_at_function_without_lld: Liquid surface at function without LLD [0.1mm]. + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + """ + + if not 0 <= liquid_surface_at_function_without_lld <= 3900: + raise ValueError("liquid_surface_at_function_without_lld must be in range 0 to 3900") + + if not 0 <= minimal_height_at_command_end <= 3900: + raise ValueError("minimal_height_at_command_end must be in range 0 to 3900") + + return await self.send_command( + module="A1HM", + command="EE", + zl=liquid_surface_at_function_without_lld, + te=minimal_height_at_command_end, + ) + + async def core96_search_for_teach_in_signal_in_x_direction( + self, + x_search_distance: int = 0, + x_speed: int = 50, + ): + """ Search for Teach in signal in X direction on the 96 head. + + Args: + x_search_distance: X search distance [0.1mm]. + x_speed: X speed [0.1mm/s]. + """ + + if not -50000 <= x_search_distance <= 50000: + raise ValueError("x_search_distance must be in range -50000 to 50000") + + if not 20 <= x_speed <= 25000: + raise ValueError("x_speed must be in range 20 to 25000") + + return await self.send_command( + module="A1HM", + command="DL", + xs=x_search_distance, + xv=x_speed, + ) + + async def core96_set_any_parameter(self): + """ Set any parameter within the 96 head module. """ + + return await self.send_command( + module="A1HM", + command="AA", + ) + + async def core96_query_tip_presence(self): + """ Query Tip presence on the 96 head. """ + + return await self.send_command( + module="A1HM", + command="QA", + ) + + async def core96_request_position(self): + """ Request position of the 96 head. """ + + return await self.send_command( + module="A1HM", + command="QI", + ) + + async def core96_request_tadm_error_status( + self, + tadm_channel_pattern: Optional[List[bool]] = None, + ): + """ Request TADM error status on the 96 head. + + Args: + tadm_channel_pattern: TADM Channel pattern. + """ + + 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)}'") + tadm_channel_pattern_num = sum(2**i if tadm_channel_pattern[i] else 0 for i in range(96)) + + return await self.send_command( + module="A1HM", + command="VB", + cw=hex(tadm_channel_pattern_num)[2:].upper(), + ) + + async def ipg_initialize(self): + """ Initialize IPG """ + + return await self.send_command( + module="A1RM", + command="DI", + ) + + async def ipg_park(self): + """ Park IPG """ + + return await self.send_command( + module="A1RM", + command="GP", + ) + + async def ipg_expose_channel_n(self): + """ Expose channel n """ + + return await self.send_command( + module="A1RM", + command="DQ", + ) + + async def ipg_release_object(self): + """ Release object """ + + return await self.send_command( + module="A1RM", + command="DO", + ) + + async def ipg_search_for_teach_in_signal_in_x_direction( + self, + x_search_distance: int = 0, + x_speed: int = 50, + ): + """ Search for Teach in signal in X direction + + Args: + x_search_distance: X search distance [0.1mm]. + x_speed: X speed [0.1mm/s]. + """ + + if not -50000 <= x_search_distance <= 50000: + raise ValueError("x_search_distance must be in range -50000 to 50000") + + if not 20 <= x_speed <= 25000: + raise ValueError("x_speed must be in range 20 to 25000") + + return await self.send_command( + module="A1RM", + command="DL", + xs=x_search_distance, + xv=x_speed, + ) + + async def ipg_grip_plate( + self, + x_position: int = 5000, + y_position: int = 5600, + z_position: int = 3600, + grip_strength: int = 100, + open_gripper_position: int = 860, + plate_width: int = 800, + plate_width_tolerance: int = 20, + acceleration_index: int = 4, + z_clearance_height: int = 50, + hotel_depth: int = 0, + minimal_height_at_command_end: int = 3600, + ): + """ Grip plate + + Args: + x_position: X Position [0.1mm]. + y_position: Y Position [0.1mm]. + z_position: Z Position [0.1mm]. + grip_strength: Grip strength (0 = low 99 = high). + open_gripper_position: Open gripper position [0.1mm]. + plate_width: Plate width [0.1mm]. + plate_width_tolerance: Plate width tolerance [0.1mm]. + acceleration_index: Acceleration index. + z_clearance_height: Z clearance height [0.1mm]. + hotel_depth: Hotel depth [0.1mm] (0 = Stack). + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + """ + + if not -50000 <= x_position <= 50000: + raise ValueError("x_position must be in range -50000 to 50000") + + if not -10000 <= y_position <= 10000: + raise ValueError("y_position must be in range -10000 to 10000") + + if not 0 <= z_position <= 4000: + raise ValueError("z_position must be in range 0 to 4000") + + if not 0 <= grip_strength <= 160: + raise ValueError("grip_strength must be in range 0 to 160") + + if not 0 <= open_gripper_position <= 9999: + raise ValueError("open_gripper_position must be in range 0 to 9999") + + if not 0 <= plate_width <= 9999: + raise ValueError("plate_width must be in range 0 to 9999") + + if not 0 <= plate_width_tolerance <= 99: + raise ValueError("plate_width_tolerance must be in range 0 to 99") + + if not 0 <= acceleration_index <= 4: + raise ValueError("acceleration_index must be in range 0 to 4") + + if not 0 <= z_clearance_height <= 999: + raise ValueError("z_clearance_height must be in range 0 to 999") + + if not 0 <= hotel_depth <= 3000: + raise ValueError("hotel_depth must be in range 0 to 3000") + + if not 0 <= minimal_height_at_command_end <= 4000: + raise ValueError("minimal_height_at_command_end must be in range 0 to 4000") + + return await self.send_command( + module="A1RM", + command="DG", + xp=x_position, + yp=y_position, + zp=z_position, + yw=grip_strength, + yo=open_gripper_position, + yg=plate_width, + pt=plate_width_tolerance, + ai=acceleration_index, + zc=z_clearance_height, + hd=hotel_depth, + te=minimal_height_at_command_end, + ) + + async def ipg_put_plate( + self, + x_position: int = 5000, + y_position: int = 5600, + z_position: int = 3600, + open_gripper_position: int = 860, + z_clearance_height: int = 50, + press_on_distance: int = 5, + hotel_depth: int = 0, + minimal_height_at_command_end: int = 3600, + ): + """ Put plate + + Args: + x_position: X Position [0.1mm]. + y_position: Y Position [0.1mm]. + z_position: Z Position [0.1mm]. + open_gripper_position: Open gripper position [0.1mm]. + z_clearance_height: Z clearance height [0.1mm]. + press_on_distance: Press on distance [0.1mm]. + hotel_depth: Hotel depth [0.1mm] (0 = Stack). + minimal_height_at_command_end: Minimal height at command end [0.1mm]. + """ + + if not -50000 <= x_position <= 50000: + raise ValueError("x_position must be in range -50000 to 50000") + + if not -10000 <= y_position <= 10000: + raise ValueError("y_position must be in range -10000 to 10000") + + if not 0 <= z_position <= 4000: + raise ValueError("z_position must be in range 0 to 4000") + + if not 0 <= open_gripper_position <= 9999: + raise ValueError("open_gripper_position must be in range 0 to 9999") + + if not 0 <= z_clearance_height <= 999: + raise ValueError("z_clearance_height must be in range 0 to 999") + + if not 0 <= press_on_distance <= 999: + raise ValueError("press_on_distance must be in range 0 to 999") + + if not 0 <= hotel_depth <= 3000: + raise ValueError("hotel_depth must be in range 0 to 3000") + + if not 0 <= minimal_height_at_command_end <= 4000: + raise ValueError("minimal_height_at_command_end must be in range 0 to 4000") + + return await self.send_command( + module="A1RM", + command="DR", + xp=x_position, + yp=y_position, + zp=z_position, + yo=open_gripper_position, + zc=z_clearance_height, + # zi=press_on_distance, # not sent? + hd=hotel_depth, + te=minimal_height_at_command_end, + ) + + async def ipg_prepare_gripper_orientation( + self, + grip_orientation: int = 32, + minimal_traverse_height_at_begin_of_command: int = 3600, + ): + """ Prepare gripper orientation + + Args: + grip_orientation: Grip orientation. + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of + command [0.1mm]. + """ + + if not 1 <= grip_orientation <= 44: + raise ValueError("grip_orientation must be in range 1 to 44") + + if not 0 <= minimal_traverse_height_at_begin_of_command <= 4000: + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 4000") + + return await self.send_command( + module="A1RM", + command="GA", + gd=grip_orientation, + th=minimal_traverse_height_at_begin_of_command, + ) + + async def ipg_move_to_defined_position( + self, + x_position: int = 5000, + y_position: int = 5600, + z_position: int = 3600, + minimal_traverse_height_at_begin_of_command: int = 3600, + ): + """ Move to defined position + + Args: + x_position: X Position [0.1mm]. + y_position: Y Position [0.1mm]. + z_position: Z Position [0.1mm]. + minimal_traverse_height_at_begin_of_command: Minimal traverse height at begin of + command [0.1mm]. + """ + + if not -50000 <= x_position <= 50000: + raise ValueError("x_position must be in range -50000 to 50000") + + if not -10000 <= y_position <= 10000: + raise ValueError("y_position must be in range -10000 to 10000") + + if not 0 <= z_position <= 4000: + raise ValueError("z_position must be in range 0 to 4000") + + if not 0 <= minimal_traverse_height_at_begin_of_command <= 4000: + raise ValueError("minimal_traverse_height_at_begin_of_command must be in range 0 to 4000") + + return await self.send_command( + module="A1RM", + command="DN", + xp=x_position, + yp=y_position, + zp=z_position, + th=minimal_traverse_height_at_begin_of_command, + ) + + async def ipg_set_any_parameter_within_this_module(self): + """ Set any parameter within this module """ + + return await self.send_command( + module="A1RM", + command="AA", + ) + + async def ipg_get_parking_status(self): + """ Get parking status """ + + return await self.send_command( + module="A1RM", + command="RG", + ) + + async def ipg_query_tip_presence(self): + """ Query Tip presence """ + + return await self.send_command( + module="A1RM", + command="QA", + ) + + async def ipg_request_access_range(self, grip_orientation: int = 32): + """ Request access range + + Args: + grip_orientation: Grip orientation. + """ + + if not 1 <= grip_orientation <= 44: + raise ValueError("grip_orientation must be in range 1 to 44") + + return await self.send_command( + module="A1RM", + command="QR", + gd=grip_orientation, + ) + + async def ipg_request_position(self, grip_orientation: int = 32): + """ Request position + + Args: + grip_orientation: Grip orientation. + """ + + if not 1 <= grip_orientation <= 44: + raise ValueError("grip_orientation must be in range 1 to 44") + + return await self.send_command( + module="A1RM", + command="QI", + gd=grip_orientation, + ) + + async def ipg_request_actual_angular_dimensions(self): + """ Request actual angular dimensions """ + + return await self.send_command( + module="A1RM", + command="RR", + ) + + async def ipg_request_configuration(self): + """ Request configuration """ + + return await self.send_command( + module="A1RM", + command="RS", + ) diff --git a/pylabrobot/liquid_handling/backends/hamilton/vantage_tests.py b/pylabrobot/liquid_handling/backends/hamilton/vantage_tests.py new file mode 100644 index 0000000000..dff1a8f248 --- /dev/null +++ b/pylabrobot/liquid_handling/backends/hamilton/vantage_tests.py @@ -0,0 +1,346 @@ +import unittest + +from pylabrobot.liquid_handling import LiquidHandler +from pylabrobot.resources import ( + TIP_CAR_480_A00, + PLT_CAR_L5AC_A00, + Cos_96_EZWash, + HT_L, + LT_L, + Coordinate, +) +from pylabrobot.resources.hamilton import VantageDeck +from pylabrobot.liquid_handling.standard import Pickup + +from .vantage import ( + Vantage, + VantageFirmwareError, + parse_vantage_fw_string, + 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]"} + +# "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" } + +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]"} + + +class TestVantageResponseParsing(unittest.TestCase): + """ Test parsing of response from Hamilton. """ + + def test_parse_response_params(self): + parsed = parse_vantage_fw_string("A1PMDAid1111", None) + self.assertEqual(parsed, {"id": 1111}) + + parsed = parse_vantage_fw_string("A1PMDAid1111", {"id": "int"}) + self.assertEqual(parsed, {"id": 1111}) + + 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"}) + self.assertEqual(parsed, {"id": 1112, "rw": -21}) + + parsed = parse_vantage_fw_string("A1PMDAid1113rwABC", {"rw": "hex"}) + self.assertEqual(parsed, {"id": 1113, "rw": int("ABC", base=16)}) + + parsed = parse_vantage_fw_string("A1PMDAid1113rw1 -2 +3", {"rw": "[int]"}) + self.assertEqual(parsed, {"id": 1113, "rw": [1, -2, 3]}) + + with self.assertRaises(ValueError): + # should fail with auto-added id. + parsed = parse_vantage_fw_string("A1PMDrwbc", None) + self.assertEqual(parsed, "") + + with self.assertRaises(ValueError): + parse_vantage_fw_string("A1PMDA", {"id": "int"}) + + 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)) + + 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)) + + resp = "A1HMDAid239er99es\"H070\"" + error = vantage_response_string_to_error(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\"" + 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)) + + +class VantageCommandCatcher(Vantage): + """ 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: + self.setup_finished = True + self._num_channels = 8 + self.iswap_installed = True + self.core96_head_installed = True + + async def send_command(self, module, command, tip_pattern=None, read_timeout=0, + write_timeout=0, **kwargs): + cmd, _ = self._assemble_command(module, command, tip_pattern, **kwargs) + self.commands.append(cmd) + + async def stop(self): + self.stop_finished = True + + +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.deck.assign_child_resource(self.tip_car, rails=18) + + self.plt_car = PLT_CAR_L5AC_A00(name="plate carrier") + self.plt_car[0] = self.plate = Cos_96_EZWash(name="plate_01", with_lid=False) + self.plt_car[1] = self.other_plate = Cos_96_EZWash(name="plate_02", with_lid=False) + self.deck.assign_child_resource(self.plt_car, rails=24) + + self.maxDiff = None + + await self.lh.setup() + + 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 + 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_vantage_fw_string(cmd, fmt) + parsed_cmd.pop("id") + + for sent_cmd in self.mockVantage.commands: + # When the module and command do not match, there is no point in comparing the parameters. + if sent_cmd[0:6] != cmd[0:6]: + continue + + try: + parsed_sent_cmd = parse_vantage_fw_string(sent_cmd, fmt) + parsed_sent_cmd.pop("id") + + if parsed_cmd == parsed_sent_cmd: + self.mockVantage.commands.remove(sent_cmd) + found = True + break + else: + similar = parsed_sent_cmd + except ValueError as e: + # The command could not be parsed. + print("Could not parse command", e) + continue + + if should_be and not found: + if similar is not None: + # similar != parsed_cmd, but assertEqual gives a better error message than `fail`. + self.assertEqual(similar, parsed_cmd) + else: + self.fail(f"Command {cmd} not found in sent commands: {self.mockVantage.commands}") + elif not should_be and found: + 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. """ + # 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") + + op1 = Pickup(resource=tip_a1, tip=tip, offset=Coordinate.zero()) + 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]) + ) + + self.assertEqual( + self.mockVantage._ops_to_fw_positions((op1, op2), use_channels=[0, 1]), + ([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]) + ) + + def _assert_command_sent_once(self, cmd: str, fmt: dict): + """ 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._assert_command_sent_once( + "A1PMTPid0012xp4329 4329 0&yp1458 1368 0&tm1 1 0&tt1 1&tp2265 2265&tz2165 2165&th2450 2450&" + "te2450 2450&ba0 0&td1 1&", + PICKUP_TIP_FORMAT) + + async def test_tip_drop_01(self): + 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) + + 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&tp2223&tz2163&th2450&te2450&ba0&td1&", + PICKUP_TIP_FORMAT) + + 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) + + 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) + + self._assert_command_sent_once( + "A1PMDAid0248at0&tm1 0&xp05680 0&yp1460 0 &th2450&te2450&lp2001&" + "ch000&zl1871&zx1871&ip0000&fp0000&av010830&as2500&ta000&ba00000&oa000&lm0&ll4&lv4&de0020&" + "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 + await self.lh.aspirate(self.plate["A1"], vols=100) + await self.lh.dispense(self.plate["A2"], vols=100, liquid_height=[5], jet=[False]) + + self._assert_command_sent_once( + "A1PMDDid0253dm1&tm1 0&xp05770 0&yp1460 0&zx1871&lp2001&zl1921&" + "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) + + 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"}) + + 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"}) + + async def test_aspirate96(self): + await self.lh.pick_up_tips96(self.tip_rack) + await self.lh.aspirate_plate(self.plate, volume=100) + self._assert_command_sent_once( + "A1HMDAid0236at0xp05680yp1460th2450te2450lp2001zl1871zx1871ip000fp000av010720as2500ta050" + "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"}) + + async def test_dispense96(self): + await self.lh.pick_up_tips96(self.tip_rack) + await self.lh.aspirate_plate(self.plate, volume=100) + await self.lh.dispense_plate(self.plate, volume=100) + self._assert_command_sent_once( + "A1HMDDid0238dm1xp05680yp1460th2450te2450lp2001zl1971zx1871ip000fp029dv010720ds4000ta050" + "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"}) + + async def test_move_plate(self): + await self.lh.move_plate(self.plate, self.plt_car[1], pickup_distance_from_top=5.2) + + # pickup + self._assert_command_sent_once( + "A1RMDGid0240xp6175yp1145zp1954yw81yo1302yg1237pt20zc0hd0te2840", + {"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( + "A1RMDRid0242xp6175yp2105zp1954yo1302zc0hd0te2840", + {"xp": "int", "yp": "int", "zp": "int", "yo": "int", "zc": "int", "hd": "int", "te": "int"}) diff --git a/pylabrobot/liquid_handling/backends/serializing_backend.py b/pylabrobot/liquid_handling/backends/serializing_backend.py index 397435133f..108abd3b22 100644 --- a/pylabrobot/liquid_handling/backends/serializing_backend.py +++ b/pylabrobot/liquid_handling/backends/serializing_backend.py @@ -143,10 +143,10 @@ async def dispense96(self, dispense: DispensePlate): async def move_resource(self, move: Move, **backend_kwargs): await self.send_command(command="move", data={"move": { "resource_name": move.resource.name, - "to": serialize(move.to), + "to": serialize(move.destination), "intermediate_locations": [serialize(loc) for loc in move.intermediate_locations], "resource_offset": serialize(move.resource_offset), - "to_offset": serialize(move.to_offset), + "to_offset": serialize(move.destination_offset), "pickup_distance_from_top": move.pickup_distance_from_top, "get_direction": serialize(move.get_direction), "put_direction": serialize(move.put_direction), diff --git a/pylabrobot/liquid_handling/backends/simulation/simulator/lib.js b/pylabrobot/liquid_handling/backends/simulation/simulator/lib.js index e4510b3f0e..da1791d5ed 100644 --- a/pylabrobot/liquid_handling/backends/simulation/simulator/lib.js +++ b/pylabrobot/liquid_handling/backends/simulation/simulator/lib.js @@ -821,6 +821,11 @@ function classForResourceType(type) { return TipCarrier; case "Container": return Container; + case "VantageDeck": + alert( + "VantageDeck is not completely implemented yet: the trash and plate loader are not drawn" + ); + return HamiltonDeck; default: return Resource; } diff --git a/pylabrobot/liquid_handling/backends/tecan/EVO.py b/pylabrobot/liquid_handling/backends/tecan/EVO.py index 60ef99742b..cfa9bcbb43 100644 --- a/pylabrobot/liquid_handling/backends/tecan/EVO.py +++ b/pylabrobot/liquid_handling/backends/tecan/EVO.py @@ -506,7 +506,7 @@ async def move_resource(self, move: Move): z_range = await self.roma.report_z_param(5) x, y, z = self._roma_positions(move.resource, move.resource.get_absolute_location(), z_range) h = int(move.resource.get_size_y() * 10) - xt, yt, zt = self._roma_positions(move.resource, move.to, z_range) + xt, yt, zt = self._roma_positions(move.resource, move.destination, z_range) # move to resource await self.roma.set_smooth_move_x(1) diff --git a/pylabrobot/liquid_handling/liquid_classes/hamilton/__init__.py b/pylabrobot/liquid_handling/liquid_classes/hamilton/__init__.py new file mode 100644 index 0000000000..d5c69a497c --- /dev/null +++ b/pylabrobot/liquid_handling/liquid_classes/hamilton/__init__.py @@ -0,0 +1,3 @@ +from .base import HamiltonLiquidClass +from .vantage import get_vantage_liquid_class +from .star import get_star_liquid_class diff --git a/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py b/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py new file mode 100644 index 0000000000..2f411eedf2 --- /dev/null +++ b/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py @@ -0,0 +1,113 @@ +from typing import Any, Dict + + +class HamiltonLiquidClass: + """ A liquid class like used in VENUS / Venus on Vantage. """ + + def __init__( + self, + curve: Dict[float, float], + + aspiration_flow_rate: float, + aspiration_mix_flow_rate: float, + aspiration_air_transport_volume: float, + aspiration_blow_out_volume: float, + aspiration_swap_speed: float, + aspiration_settling_time: float, + aspiration_over_aspirate_volume: float, + aspiration_clot_retract_height: float, + + dispense_flow_rate: float, + dispense_mode: float, + dispense_mix_flow_rate: float, + dispense_air_transport_volume: float, + dispense_blow_out_volume: float, + dispense_swap_speed: float, + dispense_settling_time: float, + dispense_stop_flow_rate: float, + dispense_stop_back_volume: float, + ): + self.curve = curve + + self.aspiration_flow_rate = aspiration_flow_rate + self.aspiration_mix_flow_rate = aspiration_mix_flow_rate + self.aspiration_air_transport_volume = aspiration_air_transport_volume + self.aspiration_blow_out_volume = aspiration_blow_out_volume + self.aspiration_swap_speed = aspiration_swap_speed + self.aspiration_settling_time = aspiration_settling_time + self.aspiration_over_aspirate_volume = aspiration_over_aspirate_volume + self.aspiration_clot_retract_height = aspiration_clot_retract_height + + self.dispense_mode = dispense_mode + self.dispense_flow_rate = dispense_flow_rate + self.dispense_mix_flow_rate = dispense_mix_flow_rate + self.dispense_air_transport_volume = dispense_air_transport_volume + self.dispense_blow_out_volume = dispense_blow_out_volume + self.dispense_swap_speed = dispense_swap_speed + self.dispense_settling_time = dispense_settling_time + self.dispense_stop_flow_rate = dispense_stop_flow_rate + self.dispense_stop_back_volume = dispense_stop_back_volume + + def compute_corrected_volume(self, target_volume: float) -> float: + """ Compute corrected volume using the correction curve. + + Uses the correction curve data point if an exact match is + available. If the volume is bigger or smaller than the + min/max key, the min/max key will be used. Otherwise, linear + interpolation between the two nearest data points is used. If + no correction curve available, the initial volume will be returned. + + Args: + Target volume that needs to be pipetted. + + Returns: + Volume that should actually be pipetted to reach target volume. + """ + + targets = sorted(self.curve.keys()) + + if len(targets) == 0: + return target_volume + + if target_volume in self.curve: + return self.curve[target_volume] + + # use min non-zero value, so second index (if len(targets)>0, + # then 0 was automatically added at initialization). + if target_volume < targets[1]: # smaller than min + return self.curve[targets[1]]/targets[1] * target_volume + if target_volume > targets[-1]: # larger than max + return self.curve[targets[-1]]/targets[-1] * target_volume + + # interpolate between two nearest points. + for pt, t in zip(targets[:-1], targets[1:]): + if pt < target_volume < t: + return (self.curve[t]-self.curve[pt])/(t-pt) * \ + (target_volume - t) + self.curve[t] # (y = slope * (x-x1) + y1) + + assert False, "Should never reach this point. Please file an issue." + + def serialize(self) -> Dict[str, Any]: + """ Serialize the liquid class to a dictionary. """ + return { + "curve": self.curve, + + "aspiration_flow_rate": self.aspiration_flow_rate, + "aspiration_mix_flow_rate": self.aspiration_mix_flow_rate, + "aspiration_air_transport_volume": self.aspiration_air_transport_volume, + "aspiration_blow_out_volume": self.aspiration_blow_out_volume, + "aspiration_swap_speed": self.aspiration_swap_speed, + "aspiration_settling_time": self.aspiration_settling_time, + "aspiration_over_aspirate_volume": self.aspiration_over_aspirate_volume, + "aspiration_clot_retract_height": self.aspiration_clot_retract_height, + + "dispense_mode": self.dispense_mode, + "dispense_flow_rate": self.dispense_flow_rate, + "dispense_mix_flow_rate": self.dispense_mix_flow_rate, + "dispense_air_transport_volume": self.dispense_air_transport_volume, + "dispense_blow_out_volume": self.dispense_blow_out_volume, + "dispense_swap_speed": self.dispense_swap_speed, + "dispense_settling_time": self.dispense_settling_time, + "dispense_stop_flow_rate": self.dispense_stop_flow_rate, + "dispense_stop_back_volume": self.dispense_stop_back_volume, + } diff --git a/pylabrobot/liquid_handling/liquid_classes/hamilton.py b/pylabrobot/liquid_handling/liquid_classes/hamilton/star.py similarity index 91% rename from pylabrobot/liquid_handling/liquid_classes/hamilton.py rename to pylabrobot/liquid_handling/liquid_classes/hamilton/star.py index e35167d14d..4272c88ec2 100644 --- a/pylabrobot/liquid_handling/liquid_classes/hamilton.py +++ b/pylabrobot/liquid_handling/liquid_classes/hamilton/star.py @@ -1,126 +1,15 @@ # pylint: skip-file -from typing import Any, Dict, Tuple, Optional +from typing import Dict, Tuple, Optional from pylabrobot.resources.liquid import Liquid +from pylabrobot.liquid_handling.liquid_classes.hamilton.base import HamiltonLiquidClass -class HamiltonLiquidClass: - """ A liquid class like used in VENUS. """ - - def __init__( - self, - curve: Dict[float, float], - - aspiration_flow_rate: float, - aspiration_mix_flow_rate: float, - aspiration_air_transport_volume: float, - aspiration_blow_out_volume: float, - aspiration_swap_speed: float, - aspiration_settling_time: float, - aspiration_over_aspirate_volume: float, - aspiration_clot_retract_height: float, - - dispense_flow_rate: float, - dispense_mode: float, - dispense_mix_flow_rate: float, - dispense_air_transport_volume: float, - dispense_blow_out_volume: float, - dispense_swap_speed: float, - dispense_settling_time: float, - dispense_stop_flow_rate: float, - dispense_stop_back_volume: float, - ): - self.curve = curve - - self.aspiration_flow_rate = aspiration_flow_rate - self.aspiration_mix_flow_rate = aspiration_mix_flow_rate - self.aspiration_air_transport_volume = aspiration_air_transport_volume - self.aspiration_blow_out_volume = aspiration_blow_out_volume - self.aspiration_swap_speed = aspiration_swap_speed - self.aspiration_settling_time = aspiration_settling_time - self.aspiration_over_aspirate_volume = aspiration_over_aspirate_volume - self.aspiration_clot_retract_height = aspiration_clot_retract_height - - self.dispense_mode = dispense_mode - self.dispense_flow_rate = dispense_flow_rate - self.dispense_mix_flow_rate = dispense_mix_flow_rate - self.dispense_air_transport_volume = dispense_air_transport_volume - self.dispense_blow_out_volume = dispense_blow_out_volume - self.dispense_swap_speed = dispense_swap_speed - self.dispense_settling_time = dispense_settling_time - self.dispense_stop_flow_rate = dispense_stop_flow_rate - self.dispense_stop_back_volume = dispense_stop_back_volume - - def compute_corrected_volume(self, target_volume: float) -> float: - """ Compute corrected volume using the correction curve. - - Uses the correction curve data point if an exact match is - available. If the volume is bigger or smaller than the - min/max key, the min/max key will be used. Otherwise, linear - interpolation between the two nearest data points is used. If - no correction curve available, the initial volume will be returned. - - Args: - Target volume that needs to be pipetted. - - Returns: - Volume that should actually be pipetted to reach target volume. - """ - - targets = sorted(self.curve.keys()) - - if len(targets) == 0: - return target_volume - - if target_volume in self.curve: - return self.curve[target_volume] - - # use min non-zero value, so second index (if len(targets)>0, - # then 0 was automatically added at initialization). - if target_volume < targets[1]: # smaller than min - return self.curve[targets[1]]/targets[1] * target_volume - if target_volume > targets[-1]: # larger than max - return self.curve[targets[-1]]/targets[-1] * target_volume - - # interpolate between two nearest points. - for pt, t in zip(targets[:-1], targets[1:]): - if pt < target_volume < t: - return (self.curve[t]-self.curve[pt])/(t-pt) * \ - (target_volume - t) + self.curve[t] # (y = slope * (x-x1) + y1) - - assert False, "Should never reach this point. Please file an issue." - - def serialize(self) -> Dict[str, Any]: - """ Serialize the liquid class to a dictionary. """ - return { - "curve": self.curve, - - "aspiration_flow_rate": self.aspiration_flow_rate, - "aspiration_mix_flow_rate": self.aspiration_mix_flow_rate, - "aspiration_air_transport_volume": self.aspiration_air_transport_volume, - "aspiration_blow_out_volume": self.aspiration_blow_out_volume, - "aspiration_swap_speed": self.aspiration_swap_speed, - "aspiration_settling_time": self.aspiration_settling_time, - "aspiration_over_aspirate_volume": self.aspiration_over_aspirate_volume, - "aspiration_clot_retract_height": self.aspiration_clot_retract_height, - - "dispense_mode": self.dispense_mode, - "dispense_flow_rate": self.dispense_flow_rate, - "dispense_mix_flow_rate": self.dispense_mix_flow_rate, - "dispense_air_transport_volume": self.dispense_air_transport_volume, - "dispense_blow_out_volume": self.dispense_blow_out_volume, - "dispense_swap_speed": self.dispense_swap_speed, - "dispense_settling_time": self.dispense_settling_time, - "dispense_stop_flow_rate": self.dispense_stop_flow_rate, - "dispense_stop_back_volume": self.dispense_stop_back_volume, - } - - -mapping: Dict[Tuple[int, bool, bool, bool, Liquid, bool, bool], HamiltonLiquidClass] = {} - -def get_liquid_class( - tip_volume: int, +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, @@ -128,12 +17,23 @@ def get_liquid_class( jet: bool, empty: bool ) -> Optional[HamiltonLiquidClass]: - """ Get the liquid class for the given parameters. """ + """ Get the Hamilton STAR liquid class for the given parameters. """ + + # 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 mapping.get((tip_volume, is_core, is_tip, has_filter, liquid, jet, empty), None) + return star_mapping.get((tip_volume, is_core, is_tip, has_filter, liquid, jet, empty), None) -mapping[(1000, False, False, False, Liquid.WATER, True, True)] = \ +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, @@ -156,7 +56,7 @@ def get_liquid_class( ) -mapping[(1000, False, False, False, Liquid.WATER, True, False)] = \ +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, @@ -180,7 +80,7 @@ def get_liquid_class( # -mapping[(1000, False, False, False, Liquid.WATER, False, True)] = \ +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, @@ -204,7 +104,7 @@ def get_liquid_class( # -mapping[(1000, False, False, False, Liquid.WATER, False, False)] = \ +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, @@ -241,7 +141,7 @@ def get_liquid_class( # 200 1.25 - 0.51 # 500 0.91 0.02 # 1000 0.66 - 0.46 -mapping[(1000, False, False, False, Liquid.WATER, True, False)] = \ +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, @@ -279,7 +179,7 @@ def get_liquid_class( # 20 10.12 - 4.66 # 50 3.79 - 1.18 # -mapping[(1000, False, False, False, Liquid.WATER, False, False)] = \ +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, @@ -302,7 +202,7 @@ def get_liquid_class( ) -mapping[(10, False, False, False, Liquid.WATER, False, True)] = \ +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, @@ -325,7 +225,7 @@ def get_liquid_class( ) -mapping[(10, False, False, False, Liquid.WATER, False, False)] = \ +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, @@ -348,7 +248,7 @@ def get_liquid_class( ) -mapping[(50, False, True, True, Liquid.DMSO, True, False)] = \ +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, @@ -371,7 +271,7 @@ def get_liquid_class( ) -mapping[(50, False, True, True, Liquid.DMSO, True, True)] = \ +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, @@ -394,7 +294,7 @@ def get_liquid_class( ) -mapping[(50, False, True, True, Liquid.DMSO, False, True)] = \ +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, @@ -434,7 +334,7 @@ def get_liquid_class( # 100 1.67 -0.35 # 300 0.46 -0.61 # -mapping[(50, False, True, True, Liquid.ETHANOL, True, True)] = \ +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, @@ -475,7 +375,7 @@ def get_liquid_class( # 20 0.95 2.97 # 50 0.31 -0.10 # -mapping[(50, False, True, True, Liquid.ETHANOL, False, True)] = \ +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, @@ -517,7 +417,7 @@ def get_liquid_class( # 300 1.08 -0.87 # # -mapping[(50, False, True, True, Liquid.GLYCERIN80, False, True)] = \ +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, @@ -556,7 +456,7 @@ def get_liquid_class( # 100 0.81 0.99 # 300 1.00 0.65 # -mapping[(50, False, True, True, Liquid.SERUM, True, True)] = \ +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, @@ -598,7 +498,7 @@ def get_liquid_class( # 50 1.39 -0.12 # # -mapping[(50, False, True, True, Liquid.SERUM, False, True)] = \ +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, @@ -621,7 +521,7 @@ def get_liquid_class( ) -mapping[(50, False, True, True, Liquid.WATER, True, False)] = \ +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, @@ -644,7 +544,7 @@ def get_liquid_class( ) -mapping[(50, False, True, True, Liquid.WATER, True, True)] = \ +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, @@ -667,7 +567,7 @@ def get_liquid_class( ) -mapping[(50, False, True, True, Liquid.WATER, False, True)] = \ +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, @@ -690,7 +590,7 @@ def get_liquid_class( ) -mapping[(50, False, True, False, Liquid.DMSO, True, True)] = \ +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, @@ -713,7 +613,7 @@ def get_liquid_class( ) -mapping[(50, False, True, False, Liquid.DMSO, False, True)] = \ +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, @@ -753,7 +653,7 @@ def get_liquid_class( # 100 1.67 -0.35 # 300 0.46 -0.61 # -mapping[(50, False, True, False, Liquid.ETHANOL, True, True)] = \ +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, @@ -794,7 +694,7 @@ def get_liquid_class( # 20 0.95 2.97 # 50 0.31 -0.10 # -mapping[(50, False, True, False, Liquid.ETHANOL, False, True)] = \ +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, @@ -836,7 +736,7 @@ def get_liquid_class( # 300 1.08 -0.87 # # -mapping[(50, False, True, False, Liquid.GLYCERIN80, False, True)] = \ +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, @@ -875,7 +775,7 @@ def get_liquid_class( # 100 0.81 0.99 # 300 1.00 0.65 # -mapping[(50, False, True, False, Liquid.SERUM, True, True)] = \ +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, @@ -917,7 +817,7 @@ def get_liquid_class( # 50 1.39 -0.12 # # -mapping[(50, False, True, False, Liquid.SERUM, False, True)] = \ +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, @@ -940,7 +840,7 @@ def get_liquid_class( ) -mapping[(50, False, True, False, Liquid.WATER, True, True)] = \ +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, @@ -963,7 +863,7 @@ def get_liquid_class( ) -mapping[(50, False, True, False, Liquid.WATER, False, True)] = \ +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, @@ -1003,7 +903,7 @@ def get_liquid_class( # 100 1.04 0.05 # 300 0.63 -0.07 # -mapping[(300, False, False, False, Liquid.ACETONITRIL80WATER20, True, False)] = \ +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, @@ -1026,7 +926,7 @@ def get_liquid_class( ) -mapping[(300, False, False, False, Liquid.WATER, True, True)] = \ +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, @@ -1049,7 +949,7 @@ def get_liquid_class( ) -mapping[(300, False, False, False, Liquid.WATER, True, False)] = \ +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, @@ -1072,7 +972,7 @@ def get_liquid_class( ) -mapping[(300, False, False, False, Liquid.WATER, False, True)] = \ +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, @@ -1095,7 +995,7 @@ def get_liquid_class( ) -mapping[(300, False, False, False, Liquid.WATER, False, False)] = \ +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, @@ -1134,7 +1034,7 @@ def get_liquid_class( # 100 0.55 -0.01 # 300 0.71 0.39 # -mapping[(300, False, False, False, Liquid.DIMETHYLSULFOXID, True, False)] = \ +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, @@ -1174,7 +1074,7 @@ def get_liquid_class( # 50 1.32 -1.05 # # -mapping[(300, False, False, False, Liquid.DIMETHYLSULFOXID, False, False)] = \ +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, @@ -1214,7 +1114,7 @@ def get_liquid_class( # 100 1.67 -0.35 # 300 0.46 -0.61 # -mapping[(300, False, False, False, Liquid.ETHANOL, True, False)] = \ +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, @@ -1255,7 +1155,7 @@ def get_liquid_class( # 20 0.95 2.97 # 50 0.31 -0.10 # -mapping[(300, False, False, False, Liquid.ETHANOL, False, False)] = \ +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, @@ -1297,7 +1197,7 @@ def get_liquid_class( # 300 1.08 -0.87 # # -mapping[(300, False, False, False, Liquid.GLYCERIN80, False, False)] = \ +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, @@ -1336,7 +1236,7 @@ def get_liquid_class( # 100 0.81 0.99 # 300 1.00 0.65 # -mapping[(300, False, False, False, Liquid.SERUM, True, False)] = \ +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, @@ -1378,7 +1278,7 @@ def get_liquid_class( # 50 1.39 -0.12 # # -mapping[(300, False, False, False, Liquid.SERUM, False, False)] = \ +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, @@ -1417,7 +1317,7 @@ def get_liquid_class( # 100 0.81 0.99 # 300 1.00 0.65 # -mapping[(300, False, False, False, Liquid.SERUM, True, False)] = \ +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, @@ -1459,7 +1359,7 @@ def get_liquid_class( # 50 1.39 -0.12 # # -mapping[(300, False, False, False, Liquid.SERUM, False, False)] = \ +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, @@ -1499,7 +1399,7 @@ def get_liquid_class( # 200 0.16 0.55 # 300 0.17 0.35 # -mapping[(300, False, False, False, Liquid.WATER, True, False)] = \ +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, @@ -1540,7 +1440,7 @@ def get_liquid_class( # 20 0.63 0.73 # # -mapping[(300, False, False, False, Liquid.WATER, False, False)] = \ +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, @@ -1564,7 +1464,7 @@ def get_liquid_class( # Liquid class for washing rocket tips with CO-RE 384 head in 96 DC wash station. -mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ +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, @@ -1588,7 +1488,7 @@ def get_liquid_class( # Evaluation -mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ +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, @@ -1612,7 +1512,7 @@ def get_liquid_class( # Evaluation -mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ +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, @@ -1636,7 +1536,7 @@ def get_liquid_class( # Evaluation -mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ +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, @@ -1660,7 +1560,7 @@ def get_liquid_class( # Evaluation -mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ +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, @@ -1684,7 +1584,7 @@ def get_liquid_class( # Evaluation -mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ +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, @@ -1708,7 +1608,7 @@ def get_liquid_class( # Evaluation -mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ +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, @@ -1731,7 +1631,7 @@ def get_liquid_class( ) -mapping[(30, True, True, False, Liquid.DMSO, True, True)] = \ +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, @@ -1754,7 +1654,7 @@ def get_liquid_class( ) -mapping[(30, True, True, False, Liquid.DMSO, False, True)] = \ +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, @@ -1777,7 +1677,7 @@ def get_liquid_class( ) -mapping[(30, True, True, False, Liquid.ETHANOL, True, True)] = \ +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, @@ -1800,7 +1700,7 @@ def get_liquid_class( ) -mapping[(30, True, True, False, Liquid.ETHANOL, False, True)] = \ +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, @@ -1823,7 +1723,7 @@ def get_liquid_class( ) -mapping[(30, True, True, False, Liquid.GLYCERIN80, False, True)] = \ +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, @@ -1846,7 +1746,7 @@ def get_liquid_class( ) -mapping[(30, True, True, False, Liquid.WATER, True, True)] = \ +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, @@ -1869,7 +1769,7 @@ def get_liquid_class( ) -mapping[(30, True, True, False, Liquid.WATER, False, True)] = \ +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, @@ -1892,7 +1792,7 @@ def get_liquid_class( ) -mapping[(30, True, True, False, Liquid.WATER, False, False)] = \ +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, @@ -1915,7 +1815,7 @@ def get_liquid_class( ) -mapping[(4000, False, True, False, Liquid.DMSO, True, False)] = \ +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, @@ -1938,7 +1838,7 @@ def get_liquid_class( ) -mapping[(4000, False, True, False, Liquid.DMSO, True, True)] = \ +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, @@ -1961,7 +1861,7 @@ def get_liquid_class( ) -mapping[(4000, False, True, False, Liquid.DMSO, False, True)] = \ +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, @@ -1985,7 +1885,7 @@ def get_liquid_class( # First two times mixing with max volume. -mapping[(4000, False, True, False, Liquid.ETHANOL, True, False)] = \ +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, @@ -2008,7 +1908,7 @@ def get_liquid_class( ) -mapping[(4000, False, True, False, Liquid.ETHANOL, True, True)] = \ +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, @@ -2031,7 +1931,7 @@ def get_liquid_class( ) -mapping[(4000, False, True, False, Liquid.ETHANOL, False, True)] = \ +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, @@ -2054,7 +1954,7 @@ def get_liquid_class( ) -mapping[(4000, False, True, False, Liquid.GLYCERIN80, True, True)] = \ +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, @@ -2077,7 +1977,7 @@ def get_liquid_class( ) -mapping[(4000, False, True, False, Liquid.GLYCERIN80, False, True)] = \ +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, @@ -2100,7 +2000,7 @@ def get_liquid_class( ) -mapping[(4000, False, True, False, Liquid.WATER, True, False)] = \ +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, @@ -2123,7 +2023,7 @@ def get_liquid_class( ) -mapping[(4000, False, True, False, Liquid.WATER, True, True)] = \ +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, @@ -2146,7 +2046,7 @@ def get_liquid_class( ) -mapping[(4000, False, True, False, Liquid.WATER, False, True)] = \ +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, @@ -2169,7 +2069,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ +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, @@ -2192,7 +2092,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.DMSO, False, True)] = \ +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, @@ -2215,7 +2115,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = \ +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, @@ -2238,7 +2138,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.ETHANOL, False, True)] = \ +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, @@ -2261,7 +2161,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.GLYCERIN80, False, True)] = \ +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, @@ -2284,7 +2184,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ +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, @@ -2307,7 +2207,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.WATER, False, True)] = \ +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, @@ -2330,7 +2230,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.WATER, False, False)] = \ +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, @@ -2353,7 +2253,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ +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, @@ -2376,7 +2276,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ +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, @@ -2399,7 +2299,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.DMSO, True, False)] = \ +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, @@ -2422,7 +2322,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.DMSO, False, True)] = \ +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, @@ -2445,7 +2345,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = \ +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, @@ -2468,7 +2368,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.ETHANOL, True, True)] = \ +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, @@ -2491,7 +2391,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.ETHANOL, True, False)] = \ +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, @@ -2514,7 +2414,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.ETHANOL, False, True)] = \ +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, @@ -2537,7 +2437,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.GLYCERIN80, False, True)] = \ +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, @@ -2560,7 +2460,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ +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, @@ -2583,7 +2483,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ +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, @@ -2606,7 +2506,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.WATER, True, False)] = \ +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, @@ -2629,7 +2529,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.WATER, False, True)] = \ +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, @@ -2652,7 +2552,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.WATER, False, False)] = \ +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, @@ -2675,7 +2575,7 @@ def get_liquid_class( ) -mapping[(5000, False, True, False, Liquid.DMSO, True, False)] = \ +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, @@ -2698,7 +2598,7 @@ def get_liquid_class( ) -mapping[(5000, False, True, False, Liquid.DMSO, True, True)] = \ +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, @@ -2721,7 +2621,7 @@ def get_liquid_class( ) -mapping[(5000, False, True, False, Liquid.DMSO, False, True)] = \ +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, @@ -2745,7 +2645,7 @@ def get_liquid_class( # First two times mixing with max volume. -mapping[(5000, False, True, False, Liquid.ETHANOL, True, False)] = \ +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, @@ -2768,7 +2668,7 @@ def get_liquid_class( ) -mapping[(5000, False, True, False, Liquid.ETHANOL, True, True)] = \ +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, @@ -2791,7 +2691,7 @@ def get_liquid_class( ) -mapping[(5000, False, True, False, Liquid.ETHANOL, False, True)] = \ +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, @@ -2814,7 +2714,7 @@ def get_liquid_class( ) -mapping[(5000, False, True, False, Liquid.GLYCERIN80, True, True)] = \ +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, @@ -2837,7 +2737,7 @@ def get_liquid_class( ) -mapping[(5000, False, True, False, Liquid.GLYCERIN80, False, True)] = \ +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, @@ -2860,7 +2760,7 @@ def get_liquid_class( ) -mapping[(5000, False, True, False, Liquid.WATER, True, False)] = \ +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, @@ -2883,7 +2783,7 @@ def get_liquid_class( ) -mapping[(5000, False, True, False, Liquid.WATER, True, True)] = \ +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, @@ -2906,7 +2806,7 @@ def get_liquid_class( ) -mapping[(5000, False, True, False, Liquid.WATER, False, True)] = \ +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, @@ -2930,7 +2830,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 250 -mapping[(1000, False, False, False, Liquid.WATER, True, False)] = \ +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, @@ -2953,7 +2853,7 @@ def get_liquid_class( ) -mapping[(1000, False, False, False, Liquid.WATER, True, True)] = \ +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, @@ -2976,7 +2876,7 @@ def get_liquid_class( ) -mapping[(1000, False, False, False, Liquid.WATER, True, False)] = \ +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, @@ -3000,7 +2900,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 120 -mapping[(1000, False, False, False, Liquid.WATER, False, False)] = \ +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, @@ -3023,7 +2923,7 @@ def get_liquid_class( ) -mapping[(1000, False, False, False, Liquid.WATER, False, True)] = \ +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, @@ -3046,7 +2946,7 @@ def get_liquid_class( ) -mapping[(1000, False, False, False, Liquid.WATER, False, False)] = \ +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, @@ -3084,7 +2984,7 @@ def get_liquid_class( # 100 0.32 0.54 # 500 0.13 -0.06 # 1000 0.11 0.17 -mapping[(1000, False, True, False, Liquid.ACETONITRIL80WATER20, True, False)] = \ +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, @@ -3122,7 +3022,7 @@ def get_liquid_class( # 200 0.22 0.71 # 500 0.14 0.01 # 1000 0.17 0.02 -mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, False)] = \ +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, @@ -3145,7 +3045,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, True)] = \ +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, @@ -3168,7 +3068,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.ACETONITRILE, True, False)] = \ +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, @@ -3207,7 +3107,7 @@ def get_liquid_class( # 200 0.18 0.69 # 500 0.23 0.04 # 1000 0.22 0.05 -mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, False)] = \ +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, @@ -3230,7 +3130,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, True)] = \ +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, @@ -3253,7 +3153,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.ACETONITRILE, False, False)] = \ +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, @@ -3279,7 +3179,7 @@ def get_liquid_class( # - 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 -mapping[(1000, False, True, False, Liquid.BLOOD, True, False)] = \ +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, @@ -3319,7 +3219,7 @@ def get_liquid_class( # 100 0.23 0.93 # 200 0.15 0.41 # -mapping[(1000, False, True, False, Liquid.BRAINHOMOGENATE, True, False)] = \ +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, @@ -3358,7 +3258,7 @@ def get_liquid_class( # # # -mapping[(1000, False, True, False, Liquid.CHLOROFORM, True, False)] = \ +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, @@ -3398,7 +3298,7 @@ def get_liquid_class( # 100 ( 9 Aliquots) 0.25 -4.81 # # -mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = \ +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, @@ -3421,7 +3321,7 @@ def get_liquid_class( ) -mapping[(1000, True, True, True, Liquid.DMSO, True, True)] = \ +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, @@ -3444,7 +3344,7 @@ def get_liquid_class( ) -mapping[(1000, True, True, True, Liquid.DMSO, False, True)] = \ +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, @@ -3467,7 +3367,7 @@ def get_liquid_class( ) -mapping[(1000, True, True, True, Liquid.WATER, True, True)] = \ +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, @@ -3490,7 +3390,7 @@ def get_liquid_class( ) -mapping[(1000, True, True, True, Liquid.WATER, False, True)] = \ +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, @@ -3530,7 +3430,7 @@ def get_liquid_class( # 100 ( 9 Aliquots) 0.25 -4.81 # # -mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = \ +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, @@ -3554,7 +3454,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 250 -mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = \ +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, @@ -3577,7 +3477,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, True, Liquid.DMSO, True, True)] = \ +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, @@ -3600,7 +3500,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, True, Liquid.DMSO, True, False)] = \ +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, @@ -3624,7 +3524,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 120 -mapping[(1000, False, True, True, Liquid.DMSO, False, False)] = \ +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, @@ -3647,7 +3547,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, True, Liquid.DMSO, False, True)] = \ +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, @@ -3671,7 +3571,7 @@ def get_liquid_class( # -mapping[(1000, False, True, True, Liquid.DMSO, False, False)] = \ +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, @@ -3695,7 +3595,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 250, Stop back volume = 0 -mapping[(1000, False, True, True, Liquid.ETHANOL, True, False)] = \ +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, @@ -3718,7 +3618,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, True, Liquid.ETHANOL, True, True)] = \ +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, @@ -3741,7 +3641,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, True, Liquid.ETHANOL, True, False)] = \ +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, @@ -3765,7 +3665,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 120 -mapping[(1000, False, True, True, Liquid.ETHANOL, False, False)] = \ +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, @@ -3788,7 +3688,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, True, Liquid.ETHANOL, False, True)] = \ +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, @@ -3811,7 +3711,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, True, Liquid.ETHANOL, False, False)] = \ +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, @@ -3835,7 +3735,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 200 -mapping[(1000, False, True, True, Liquid.GLYCERIN80, True, False)] = \ +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, @@ -3859,7 +3759,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 200 -mapping[(1000, False, True, True, Liquid.GLYCERIN80, True, True)] = \ +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, @@ -3883,7 +3783,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 120 -mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, False)] = \ +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, @@ -3906,7 +3806,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, True)] = \ +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, @@ -3929,7 +3829,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, True, Liquid.GLYCERIN80, False, False)] = \ +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, @@ -3953,7 +3853,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 250 -mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = \ +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, @@ -3977,7 +3877,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 250 -mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = \ +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, @@ -4001,7 +3901,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 250, Settling time = 0 -mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = \ +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, @@ -4024,7 +3924,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, True, Liquid.SERUM, True, True)] = \ +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, @@ -4047,7 +3947,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, True, Liquid.SERUM, True, False)] = \ +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, @@ -4071,7 +3971,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 120 -mapping[(1000, False, True, True, Liquid.SERUM, False, False)] = \ +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, @@ -4094,7 +3994,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, True, Liquid.SERUM, False, True)] = \ +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, @@ -4117,7 +4017,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, True, Liquid.SERUM, False, False)] = \ +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, @@ -4141,7 +4041,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 250 -mapping[(1000, False, True, True, Liquid.WATER, True, False)] = \ +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, @@ -4165,7 +4065,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 250 -mapping[(1000, False, True, True, Liquid.WATER, True, False)] = \ +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, @@ -4189,7 +4089,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 250 -mapping[(1000, False, True, True, Liquid.WATER, True, False)] = \ +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, @@ -4212,7 +4112,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, True, Liquid.WATER, True, True)] = \ +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, @@ -4235,7 +4135,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, True, Liquid.WATER, True, False)] = \ +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, @@ -4259,7 +4159,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 120, Clot retract hight = 0 -mapping[(1000, False, True, True, Liquid.WATER, False, False)] = \ +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, @@ -4282,7 +4182,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, True, Liquid.WATER, False, True)] = \ +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, @@ -4305,7 +4205,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, True, Liquid.WATER, False, False)] = \ +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, @@ -4348,7 +4248,7 @@ def get_liquid_class( # 500 0.49 - 0.17 # 1000 0.55 0.712 # -mapping[(1000, False, True, False, Liquid.METHANOL, True, False)] = \ +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, @@ -4393,7 +4293,7 @@ def get_liquid_class( # 200 0.48 0.18 # 500 0.17 0.22 # 1000 0.75 0.29 -mapping[(1000, False, True, False, Liquid.METHANOL, False, False)] = \ +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, @@ -4434,7 +4334,7 @@ def get_liquid_class( # 200 0.14 0.06 # 500 0.12 - 0.07 # 1000 0.16 0.08 -mapping[(1000, False, True, False, Liquid.METHANOL70WATER030, True, False)] = \ +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, @@ -4473,7 +4373,7 @@ def get_liquid_class( # 20 2.85 2.92 # 200 0.14 0.59 # -mapping[(1000, False, True, False, Liquid.OCTANOL, True, False)] = \ +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, @@ -4513,7 +4413,7 @@ def get_liquid_class( # 200 0.30 1.30 # 500 0.31 0.01 # 1000 0.33 0.01 -mapping[(1000, False, True, False, Liquid.OCTANOL, False, False)] = \ +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, @@ -4536,7 +4436,7 @@ def get_liquid_class( ) -mapping[(1000, True, True, False, Liquid.DMSO, True, False)] = \ +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, @@ -4559,7 +4459,7 @@ def get_liquid_class( ) -mapping[(1000, True, True, False, Liquid.DMSO, True, True)] = \ +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, @@ -4582,7 +4482,7 @@ def get_liquid_class( ) -mapping[(1000, True, True, False, Liquid.DMSO, False, True)] = \ +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, @@ -4606,7 +4506,7 @@ def get_liquid_class( # to prevent drop's, mix 2x with e.g. 500ul -mapping[(1000, True, True, False, Liquid.ETHANOL, True, False)] = \ +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, @@ -4629,7 +4529,7 @@ def get_liquid_class( ) -mapping[(1000, True, True, False, Liquid.ETHANOL, True, True)] = \ +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, @@ -4653,7 +4553,7 @@ def get_liquid_class( # to prevent drop's, mix 2x with e.g. 500ul -mapping[(1000, True, True, False, Liquid.ETHANOL, False, True)] = \ +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, @@ -4676,7 +4576,7 @@ def get_liquid_class( ) -mapping[(1000, True, True, False, Liquid.GLYCERIN80, False, True)] = \ +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, @@ -4699,7 +4599,7 @@ def get_liquid_class( ) -mapping[(1000, True, True, False, Liquid.WATER, True, False)] = \ +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, @@ -4722,7 +4622,7 @@ def get_liquid_class( ) -mapping[(1000, True, True, False, Liquid.WATER, True, True)] = \ +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, @@ -4745,7 +4645,7 @@ def get_liquid_class( ) -mapping[(1000, True, True, False, Liquid.WATER, False, True)] = \ +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, @@ -4769,7 +4669,7 @@ def get_liquid_class( # Liquid class for wash high volume tips with CO-RE 96 Head in CO-RE 96 Head Washer. -mapping[(1000, True, True, False, Liquid.WATER, False, False)] = \ +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, @@ -4809,7 +4709,7 @@ def get_liquid_class( # 100 ( 9 Aliquots) 0.25 -4.81 # # -mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = \ +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, @@ -4833,7 +4733,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 250 -mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = \ +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, @@ -4856,7 +4756,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.DMSO, True, True)] = \ +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, @@ -4879,7 +4779,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.DMSO, True, False)] = \ +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, @@ -4903,7 +4803,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 120 -mapping[(1000, False, True, False, Liquid.DMSO, False, False)] = \ +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, @@ -4926,7 +4826,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.DMSO, False, True)] = \ +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, @@ -4949,7 +4849,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.DMSO, False, False)] = \ +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, @@ -4973,7 +4873,7 @@ def get_liquid_class( # V1.1: Set Stop back volume to 0 -mapping[(1000, False, True, False, Liquid.ETHANOL, True, False)] = \ +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, @@ -4996,7 +4896,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.ETHANOL, True, True)] = \ +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, @@ -5019,7 +4919,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.ETHANOL, True, False)] = \ +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, @@ -5042,7 +4942,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.ETHANOL, False, False)] = \ +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, @@ -5065,7 +4965,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.ETHANOL, False, True)] = \ +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, @@ -5088,7 +4988,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.ETHANOL, False, False)] = \ +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, @@ -5112,7 +5012,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 200 -mapping[(1000, False, True, False, Liquid.GLYCERIN80, True, False)] = \ +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, @@ -5135,7 +5035,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.GLYCERIN80, True, True)] = \ +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, @@ -5159,7 +5059,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 120 -mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, False)] = \ +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, @@ -5182,7 +5082,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, True)] = \ +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, @@ -5205,7 +5105,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.GLYCERIN80, False, False)] = \ +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, @@ -5229,7 +5129,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 250 -mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = \ +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, @@ -5253,7 +5153,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 250 -mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = \ +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, @@ -5277,7 +5177,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 250, settling time = 0 -mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = \ +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, @@ -5300,7 +5200,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.SERUM, True, True)] = \ +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, @@ -5323,7 +5223,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.SERUM, True, False)] = \ +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, @@ -5347,7 +5247,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 120 -mapping[(1000, False, True, False, Liquid.SERUM, False, False)] = \ +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, @@ -5370,7 +5270,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.SERUM, False, True)] = \ +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, @@ -5393,7 +5293,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.SERUM, False, False)] = \ +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, @@ -5417,7 +5317,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 250 -mapping[(1000, False, True, False, Liquid.WATER, True, False)] = \ +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, @@ -5441,7 +5341,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 250 -mapping[(1000, False, True, False, Liquid.WATER, True, False)] = \ +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, @@ -5465,7 +5365,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 250 -mapping[(1000, False, True, False, Liquid.WATER, True, False)] = \ +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, @@ -5488,7 +5388,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.WATER, True, True)] = \ +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, @@ -5511,7 +5411,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.WATER, True, False)] = \ +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, @@ -5535,7 +5435,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 120, clot retract height = 0 -mapping[(1000, False, True, False, Liquid.WATER, False, False)] = \ +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, @@ -5558,7 +5458,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.WATER, False, True)] = \ +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, @@ -5581,7 +5481,7 @@ def get_liquid_class( ) -mapping[(1000, False, True, False, Liquid.WATER, False, False)] = \ +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, @@ -5610,7 +5510,7 @@ def get_liquid_class( # - fix height from bottom between 0.5-0.7mm # - dispense mode jet empty tip # - also with higher DNA concentration -mapping[(10, False, False, False, Liquid.DNA_TRIS_EDTA, True, False)] = \ +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, @@ -5638,7 +5538,7 @@ def get_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 -mapping[(10, False, False, False, Liquid.DNA_TRIS_EDTA, False, False)] = \ +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, @@ -5662,7 +5562,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 60 -mapping[(10, False, False, False, Liquid.WATER, False, False)] = \ +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, @@ -5685,7 +5585,7 @@ def get_liquid_class( ) -mapping[(10, False, False, False, Liquid.WATER, True, False)] = \ +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, @@ -5708,7 +5608,7 @@ def get_liquid_class( ) -mapping[(10, False, False, False, Liquid.WATER, True, True)] = \ +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, @@ -5731,7 +5631,7 @@ def get_liquid_class( ) -mapping[(10, False, False, False, Liquid.WATER, True, False)] = \ +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, @@ -5755,7 +5655,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 60 -mapping[(10, False, False, False, Liquid.WATER, False, False)] = \ +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, @@ -5778,7 +5678,7 @@ def get_liquid_class( ) -mapping[(10, False, False, False, Liquid.WATER, False, True)] = \ +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, @@ -5801,7 +5701,7 @@ def get_liquid_class( ) -mapping[(10, False, False, False, Liquid.WATER, False, False)] = \ +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, @@ -5824,7 +5724,7 @@ def get_liquid_class( ) -mapping[(10, True, True, True, Liquid.DMSO, False, True)] = \ +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, @@ -5847,7 +5747,7 @@ def get_liquid_class( ) -mapping[(10, True, True, True, Liquid.WATER, False, True)] = \ +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, @@ -5870,7 +5770,7 @@ def get_liquid_class( ) -mapping[(10, True, True, True, Liquid.DMSO, False, True)] = \ +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, @@ -5893,7 +5793,7 @@ def get_liquid_class( ) -mapping[(10, True, True, True, Liquid.DMSO, False, False)] = \ +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, @@ -5916,7 +5816,7 @@ def get_liquid_class( ) -mapping[(10, True, True, True, Liquid.WATER, False, True)] = \ +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, @@ -5939,7 +5839,7 @@ def get_liquid_class( ) -mapping[(10, True, True, True, Liquid.WATER, False, False)] = \ +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, @@ -5963,7 +5863,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 75 -mapping[(10, False, True, True, Liquid.DMSO, False, False)] = \ +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, @@ -5986,7 +5886,7 @@ def get_liquid_class( ) -mapping[(10, False, True, True, Liquid.DMSO, False, True)] = \ +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, @@ -6009,7 +5909,7 @@ def get_liquid_class( ) -mapping[(10, False, True, True, Liquid.DMSO, False, False)] = \ +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, @@ -6033,7 +5933,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 75 -mapping[(10, False, True, True, Liquid.ETHANOL, False, False)] = \ +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, @@ -6056,7 +5956,7 @@ def get_liquid_class( ) -mapping[(10, False, True, True, Liquid.ETHANOL, False, True)] = \ +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, @@ -6079,7 +5979,7 @@ def get_liquid_class( ) -mapping[(10, False, True, True, Liquid.ETHANOL, False, False)] = \ +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, @@ -6103,7 +6003,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 10 -mapping[(10, False, True, True, Liquid.GLYCERIN, False, False)] = \ +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, @@ -6126,7 +6026,7 @@ def get_liquid_class( ) -mapping[(10, False, True, True, Liquid.GLYCERIN80, False, True)] = \ +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, @@ -6150,7 +6050,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 75 -mapping[(10, False, True, True, Liquid.WATER, False, False)] = \ +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, @@ -6173,7 +6073,7 @@ def get_liquid_class( ) -mapping[(10, False, True, True, Liquid.WATER, False, True)] = \ +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, @@ -6196,7 +6096,7 @@ def get_liquid_class( ) -mapping[(10, False, True, True, Liquid.WATER, False, False)] = \ +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, @@ -6236,7 +6136,7 @@ def get_liquid_class( # 5.0 1.08 -1.29 # 10.0 0.62 0.53 # -mapping[(10, False, True, False, Liquid.PLASMA, False, False)] = \ +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, @@ -6259,7 +6159,7 @@ def get_liquid_class( ) -mapping[(10, False, True, False, Liquid.PLASMA, False, True)] = \ +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, @@ -6282,7 +6182,7 @@ def get_liquid_class( ) -mapping[(10, False, True, False, Liquid.PLASMA, False, False)] = \ +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, @@ -6322,7 +6222,7 @@ def get_liquid_class( # 5.0 1.08 -1.29 # 10.0 0.62 0.53 # -mapping[(10, False, True, False, Liquid.SERUM, False, False)] = \ +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, @@ -6345,7 +6245,7 @@ def get_liquid_class( ) -mapping[(10, False, True, False, Liquid.SERUM, False, True)] = \ +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, @@ -6368,7 +6268,7 @@ def get_liquid_class( ) -mapping[(10, False, True, False, Liquid.SERUM, False, False)] = \ +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, @@ -6391,7 +6291,7 @@ def get_liquid_class( ) -mapping[(10, True, True, False, Liquid.DMSO, False, True)] = \ +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, @@ -6414,7 +6314,7 @@ def get_liquid_class( ) -mapping[(10, True, True, False, Liquid.WATER, False, True)] = \ +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, @@ -6437,7 +6337,7 @@ def get_liquid_class( ) -mapping[(10, True, True, False, Liquid.DMSO, False, True)] = \ +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, @@ -6460,7 +6360,7 @@ def get_liquid_class( ) -mapping[(10, True, True, False, Liquid.DMSO, False, False)] = \ +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, @@ -6483,7 +6383,7 @@ def get_liquid_class( ) -mapping[(10, True, True, False, Liquid.WATER, False, True)] = \ +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, @@ -6506,7 +6406,7 @@ def get_liquid_class( ) -mapping[(10, True, True, False, Liquid.WATER, False, False)] = \ +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, @@ -6530,7 +6430,7 @@ def get_liquid_class( # Liquid class for wash low volume tips with CO-RE 96 Head in CO-RE 96 Head Washer. -mapping[(10, True, True, False, Liquid.WATER, False, False)] = \ +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, @@ -6554,7 +6454,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 75 -mapping[(10, False, True, False, Liquid.DMSO, False, False)] = \ +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, @@ -6577,7 +6477,7 @@ def get_liquid_class( ) -mapping[(10, False, True, False, Liquid.DMSO, False, True)] = \ +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, @@ -6600,7 +6500,7 @@ def get_liquid_class( ) -mapping[(10, False, True, False, Liquid.DMSO, False, False)] = \ +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, @@ -6624,7 +6524,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 75 -mapping[(10, False, True, False, Liquid.ETHANOL, False, False)] = \ +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, @@ -6647,7 +6547,7 @@ def get_liquid_class( ) -mapping[(10, False, True, False, Liquid.ETHANOL, False, True)] = \ +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, @@ -6670,7 +6570,7 @@ def get_liquid_class( ) -mapping[(10, False, True, False, Liquid.ETHANOL, False, False)] = \ +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, @@ -6694,7 +6594,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 10 -mapping[(10, False, True, False, Liquid.GLYCERIN, False, False)] = \ +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, @@ -6718,7 +6618,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 75 -mapping[(10, False, True, False, Liquid.WATER, False, False)] = \ +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, @@ -6741,7 +6641,7 @@ def get_liquid_class( ) -mapping[(10, True, True, False, Liquid.WATER, False, False)] = \ +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, @@ -6764,7 +6664,7 @@ def get_liquid_class( ) -mapping[(10, True, True, False, Liquid.WATER, False, True)] = \ +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, @@ -6787,7 +6687,7 @@ def get_liquid_class( ) -mapping[(10, True, True, False, Liquid.WATER, False, False)] = \ +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, @@ -6810,7 +6710,7 @@ def get_liquid_class( ) -mapping[(10, False, True, False, Liquid.WATER, False, True)] = \ +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, @@ -6833,7 +6733,7 @@ def get_liquid_class( ) -mapping[(10, False, True, False, Liquid.WATER, False, False)] = \ +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, @@ -6868,7 +6768,7 @@ def get_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 -mapping[(300, True, True, True, Liquid.DMSO, True, False)] = \ +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, @@ -6891,7 +6791,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.DMSO, True, True)] = \ +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, @@ -6914,7 +6814,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.DMSO, False, True)] = \ +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, @@ -6950,7 +6850,7 @@ def get_liquid_class( # 4 x 50 ul = approximately 48.9 ul # 2 x 100 ul = approximately 97.2 ul # -mapping[(300, True, True, True, Liquid.WATER, True, False)] = \ +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, @@ -6973,7 +6873,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.WATER, True, True)] = \ +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, @@ -6996,7 +6896,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.WATER, False, True)] = \ +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, @@ -7032,7 +6932,7 @@ def get_liquid_class( # 4 x 50 ul = approximately 48.3 ul # 2 x 100 ul = approximately 95.7 ul # -mapping[(300, True, True, True, Liquid.DMSO, True, False)] = \ +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, @@ -7055,7 +6955,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.DMSO, True, True)] = \ +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, @@ -7078,7 +6978,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.DMSO, False, True)] = \ +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, @@ -7113,7 +7013,7 @@ def get_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 -mapping[(300, True, True, True, Liquid.ETHANOL, True, False)] = \ +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, @@ -7136,7 +7036,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.ETHANOL, True, True)] = \ +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, @@ -7159,7 +7059,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.ETHANOL, False, True)] = \ +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, @@ -7182,7 +7082,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.GLYCERIN80, False, True)] = \ +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, @@ -7217,7 +7117,7 @@ def get_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 -mapping[(300, True, True, True, Liquid.WATER, True, False)] = \ +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, @@ -7240,7 +7140,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.WATER, True, True)] = \ +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, @@ -7263,7 +7163,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.WATER, False, True)] = \ +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, @@ -7298,7 +7198,7 @@ def get_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 -mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ +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, @@ -7321,7 +7221,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ +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, @@ -7344,7 +7244,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ +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, @@ -7379,7 +7279,7 @@ def get_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 -mapping[(300, True, True, False, Liquid.ETHANOL, True, False)] = \ +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, @@ -7402,7 +7302,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.ETHANOL, True, True)] = \ +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, @@ -7425,7 +7325,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.ETHANOL, False, True)] = \ +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, @@ -7448,7 +7348,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.GLYCERIN80, False, True)] = \ +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, @@ -7484,7 +7384,7 @@ def get_liquid_class( # 4 x 50 ul = approximately 48.9 ul # 2 x 100 ul = approximately 97.2 ul # -mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ +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, @@ -7507,7 +7407,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ +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, @@ -7530,7 +7430,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ +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, @@ -7566,7 +7466,7 @@ def get_liquid_class( # 4 x 50 ul = approximately 48.3 ul # 2 x 100 ul = approximately 95.7 ul # -mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ +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, @@ -7589,7 +7489,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ +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, @@ -7612,7 +7512,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ +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, @@ -7647,7 +7547,7 @@ def get_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 -mapping[(300, True, True, False, Liquid.ETHANOL, True, False)] = \ +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, @@ -7670,7 +7570,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.ETHANOL, True, True)] = \ +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, @@ -7693,7 +7593,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.ETHANOL, False, True)] = \ +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, @@ -7716,7 +7616,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.GLYCERIN80, False, True)] = \ +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, @@ -7751,7 +7651,7 @@ def get_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 -mapping[(300, True, True, False, Liquid.SERUM, True, False)] = \ +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, @@ -7774,7 +7674,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.SERUM, True, True)] = \ +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, @@ -7797,7 +7697,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.SERUM, False, True)] = \ +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, @@ -7832,7 +7732,7 @@ def get_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 -mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ +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, @@ -7855,7 +7755,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ +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, @@ -7878,7 +7778,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ +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, @@ -7903,7 +7803,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 80 # V1.2: Stop back volume = 0 (previous value: 15) -mapping[(300, False, False, False, Liquid.WATER, True, False)] = \ +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, @@ -7926,7 +7826,7 @@ def get_liquid_class( ) -mapping[(300, False, False, False, Liquid.WATER, True, True)] = \ +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, @@ -7949,7 +7849,7 @@ def get_liquid_class( ) -mapping[(300, False, False, False, Liquid.WATER, True, False)] = \ +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, @@ -7972,7 +7872,7 @@ def get_liquid_class( ) -mapping[(300, False, False, False, Liquid.WATER, False, False)] = \ +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, @@ -7995,7 +7895,7 @@ def get_liquid_class( ) -mapping[(300, False, False, False, Liquid.WATER, False, True)] = \ +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, @@ -8018,7 +7918,7 @@ def get_liquid_class( ) -mapping[(300, False, False, False, Liquid.WATER, False, False)] = \ +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, @@ -8061,7 +7961,7 @@ def get_liquid_class( # 200 0.16 0.55 # 300 0.17 0.35 # -mapping[(300, False, True, False, Liquid.ACETONITRILE, True, False)] = \ +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, @@ -8084,7 +7984,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.ACETONITRILE, True, True)] = \ +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, @@ -8107,7 +8007,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.ACETONITRILE, True, False)] = \ +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, @@ -8150,7 +8050,7 @@ def get_liquid_class( # 200 0.65 0.65 # 300 0.21 0.88 # -mapping[(300, False, True, False, Liquid.ACETONITRILE, False, False)] = \ +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, @@ -8173,7 +8073,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.ACETONITRILE, False, True)] = \ +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, @@ -8196,7 +8096,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.ACETONITRILE, False, False)] = \ +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, @@ -8235,7 +8135,7 @@ def get_liquid_class( # 20 (12 Aliquots) 2.53 -2.97 # 50 ( 4 Aliquots) 0.84 -2.57 # -mapping[(300, False, True, False, Liquid.DMSO, True, False)] = \ +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, @@ -8275,7 +8175,7 @@ def get_liquid_class( # 200 0.53 0.08 # 300 0.54 0.22 # -mapping[(300, False, True, False, Liquid.ETHANOL, False, False)] = \ +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, @@ -8298,7 +8198,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.ETHANOL, False, True)] = \ +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, @@ -8321,7 +8221,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.ETHANOL, False, False)] = \ +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, @@ -8344,7 +8244,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.DMSO, True, True)] = \ +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, @@ -8367,7 +8267,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.DMSO, False, True)] = \ +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, @@ -8390,7 +8290,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.WATER, True, True)] = \ +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, @@ -8413,7 +8313,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.WATER, False, True)] = \ +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, @@ -8436,7 +8336,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.DMSO, True, True)] = \ +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, @@ -8459,7 +8359,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.DMSO, True, False)] = \ +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, @@ -8482,7 +8382,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.DMSO, False, True)] = \ +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, @@ -8505,7 +8405,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.DMSO, False, False)] = \ +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, @@ -8528,7 +8428,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.WATER, True, True)] = \ +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, @@ -8551,7 +8451,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.WATER, True, False)] = \ +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, @@ -8574,7 +8474,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.WATER, False, True)] = \ +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, @@ -8597,7 +8497,7 @@ def get_liquid_class( ) -mapping[(300, True, True, True, Liquid.WATER, False, False)] = \ +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, @@ -8636,7 +8536,7 @@ def get_liquid_class( # 20 (12 Aliquots) 2.53 -2.97 # 50 ( 4 Aliquots) 0.84 -2.57 # -mapping[(300, False, True, True, Liquid.DMSO, True, False)] = \ +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, @@ -8660,7 +8560,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 100 -mapping[(300, False, True, True, Liquid.DMSO, True, False)] = \ +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, @@ -8683,7 +8583,7 @@ def get_liquid_class( ) -mapping[(300, False, True, True, Liquid.DMSO, True, True)] = \ +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, @@ -8706,7 +8606,7 @@ def get_liquid_class( ) -mapping[(300, False, True, True, Liquid.DMSO, True, False)] = \ +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, @@ -8729,7 +8629,7 @@ def get_liquid_class( ) -mapping[(300, False, True, True, Liquid.DMSO, False, False)] = \ +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, @@ -8752,7 +8652,7 @@ def get_liquid_class( ) -mapping[(300, False, True, True, Liquid.DMSO, False, True)] = \ +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, @@ -8775,7 +8675,7 @@ def get_liquid_class( ) -mapping[(300, False, True, True, Liquid.DMSO, False, False)] = \ +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, @@ -8799,7 +8699,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 100, Stop back volume=0 -mapping[(300, False, True, True, Liquid.ETHANOL, True, False)] = \ +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, @@ -8822,7 +8722,7 @@ def get_liquid_class( ) -mapping[(300, False, True, True, Liquid.ETHANOL, True, True)] = \ +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, @@ -8845,7 +8745,7 @@ def get_liquid_class( ) -mapping[(300, False, True, True, Liquid.ETHANOL, True, False)] = \ +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, @@ -8869,7 +8769,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 20, dispense settling time=0, Stop back volume=0 -mapping[(300, False, True, True, Liquid.GLYCERIN, True, False)] = \ +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, @@ -8893,7 +8793,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 20, dispense settling time=0, Stop back volume=0 -mapping[(300, False, True, True, Liquid.GLYCERIN80, True, True)] = \ +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, @@ -8917,7 +8817,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 10 -mapping[(300, False, True, True, Liquid.GLYCERIN, False, False)] = \ +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, @@ -8940,7 +8840,7 @@ def get_liquid_class( ) -mapping[(300, False, True, True, Liquid.GLYCERIN80, False, True)] = \ +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, @@ -8963,7 +8863,7 @@ def get_liquid_class( ) -mapping[(300, False, True, True, Liquid.GLYCERIN80, False, False)] = \ +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, @@ -8987,7 +8887,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 100 -mapping[(300, False, True, True, Liquid.SERUM, True, False)] = \ +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, @@ -9011,7 +8911,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 100 -mapping[(300, False, True, True, Liquid.SERUM, True, False)] = \ +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, @@ -9035,7 +8935,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 100 -mapping[(300, False, True, True, Liquid.SERUM, True, False)] = \ +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, @@ -9058,7 +8958,7 @@ def get_liquid_class( ) -mapping[(300, False, True, True, Liquid.SERUM, True, True)] = \ +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, @@ -9081,7 +8981,7 @@ def get_liquid_class( ) -mapping[(300, False, True, True, Liquid.SERUM, True, False)] = \ +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, @@ -9104,7 +9004,7 @@ def get_liquid_class( ) -mapping[(300, False, True, True, Liquid.SERUM, False, False)] = \ +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, @@ -9127,7 +9027,7 @@ def get_liquid_class( ) -mapping[(300, False, True, True, Liquid.SERUM, False, False)] = \ +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, @@ -9151,7 +9051,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 100 -mapping[(300, False, True, True, Liquid.WATER, True, False)] = \ +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, @@ -9175,7 +9075,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 100 -mapping[(300, False, True, True, Liquid.WATER, True, False)] = \ +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, @@ -9199,7 +9099,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 100 -mapping[(300, False, True, True, Liquid.WATER, True, False)] = \ +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, @@ -9222,7 +9122,7 @@ def get_liquid_class( ) -mapping[(300, False, True, True, Liquid.WATER, True, True)] = \ +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, @@ -9245,7 +9145,7 @@ def get_liquid_class( ) -mapping[(300, False, True, True, Liquid.WATER, True, False)] = \ +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, @@ -9269,7 +9169,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 100 -mapping[(300, False, True, True, Liquid.WATER, False, False)] = \ +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, @@ -9292,7 +9192,7 @@ def get_liquid_class( ) -mapping[(300, False, True, True, Liquid.WATER, False, True)] = \ +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, @@ -9315,7 +9215,7 @@ def get_liquid_class( ) -mapping[(300, False, True, True, Liquid.WATER, False, False)] = \ +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, @@ -9359,7 +9259,7 @@ def get_liquid_class( # 200 0.56 0.07 # 300 0.54 1.12 # -mapping[(300, False, True, False, Liquid.METHANOL, True, False)] = \ +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, @@ -9405,7 +9305,7 @@ def get_liquid_class( # 200 0.51 0.59 # 300 0.81 0.22 # -mapping[(300, False, True, False, Liquid.METHANOL, False, False)] = \ +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, @@ -9445,7 +9345,7 @@ def get_liquid_class( # 200 0.29 0.17 # 300 0.16 0.80 # -mapping[(300, False, True, False, Liquid.OCTANOL, True, False)] = \ +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, @@ -9489,7 +9389,7 @@ def get_liquid_class( # 200 0.02 0.12 # 300 0.11 0.29 # -mapping[(300, False, True, False, Liquid.OCTANOL, False, False)] = \ +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, @@ -9527,7 +9427,7 @@ def get_liquid_class( # 10 1.99 4.39 # # -mapping[(300, False, True, False, Liquid.PBS_BUFFER, False, False)] = \ +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, @@ -9566,7 +9466,7 @@ def get_liquid_class( # 100 0.08 1.09 # 200 0.09 0.91 # -mapping[(300, False, True, False, Liquid.PLASMA, True, False)] = \ +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, @@ -9589,7 +9489,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.PLASMA, True, True)] = \ +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, @@ -9612,7 +9512,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.PLASMA, True, False)] = \ +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, @@ -9652,7 +9552,7 @@ def get_liquid_class( # 60 0.55 2.06 # # -mapping[(300, False, True, False, Liquid.PLASMA, False, False)] = \ +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, @@ -9675,7 +9575,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.PLASMA, False, True)] = \ +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, @@ -9698,7 +9598,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.PLASMA, False, False)] = \ +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, @@ -9721,7 +9621,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ +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, @@ -9744,7 +9644,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ +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, @@ -9767,7 +9667,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ +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, @@ -9790,7 +9690,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ +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, @@ -9813,7 +9713,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ +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, @@ -9836,7 +9736,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ +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, @@ -9859,7 +9759,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.DMSO, True, True)] = \ +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, @@ -9882,7 +9782,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.DMSO, True, False)] = \ +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, @@ -9905,7 +9805,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.DMSO, False, True)] = \ +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, @@ -9928,7 +9828,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.DMSO, False, False)] = \ +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, @@ -9951,7 +9851,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ +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, @@ -9974,7 +9874,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ +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, @@ -9997,7 +9897,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ +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, @@ -10020,7 +9920,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ +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, @@ -10044,7 +9944,7 @@ def get_liquid_class( # Liquid class for wash standard volume tips with CO-RE 96 Head in CO-RE 96 Head Washer. -mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ +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, @@ -10083,7 +9983,7 @@ def get_liquid_class( # 20 (12 Aliquots) 2.53 -2.97 # 50 ( 4 Aliquots) 0.84 -2.57 # -mapping[(300, False, True, False, Liquid.DMSO, True, False)] = \ +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, @@ -10107,7 +10007,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 100 -mapping[(300, False, True, False, Liquid.DMSO, True, False)] = \ +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, @@ -10130,7 +10030,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.DMSO, True, True)] = \ +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, @@ -10153,7 +10053,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.DMSO, True, False)] = \ +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, @@ -10176,7 +10076,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.DMSO, False, False)] = \ +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, @@ -10199,7 +10099,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.DMSO, False, True)] = \ +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, @@ -10222,7 +10122,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.DMSO, False, False)] = \ +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, @@ -10246,7 +10146,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 100, stop back volume = 0 -mapping[(300, False, True, False, Liquid.ETHANOL, True, False)] = \ +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, @@ -10269,7 +10169,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.ETHANOL, True, True)] = \ +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, @@ -10292,7 +10192,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.ETHANOL, True, False)] = \ +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, @@ -10316,7 +10216,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 20, dispense settling time=0, stop back volume = 0 -mapping[(300, False, True, False, Liquid.GLYCERIN, True, False)] = \ +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, @@ -10340,7 +10240,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 20, dispense settling time=0, stop back volume = 0 -mapping[(300, False, True, False, Liquid.GLYCERIN80, True, True)] = \ +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, @@ -10364,7 +10264,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 10 -mapping[(300, False, True, False, Liquid.GLYCERIN, False, False)] = \ +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, @@ -10387,7 +10287,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.GLYCERIN80, False, True)] = \ +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, @@ -10410,7 +10310,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.GLYCERIN80, False, False)] = \ +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, @@ -10434,7 +10334,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 100 -mapping[(300, False, True, False, Liquid.SERUM, True, False)] = \ +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, @@ -10458,7 +10358,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 100 -mapping[(300, False, True, False, Liquid.SERUM, True, False)] = \ +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, @@ -10482,7 +10382,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 100 -mapping[(300, False, True, False, Liquid.SERUM, True, False)] = \ +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, @@ -10505,7 +10405,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.SERUM, True, True)] = \ +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, @@ -10528,7 +10428,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.SERUM, True, False)] = \ +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, @@ -10551,7 +10451,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.SERUM, False, False)] = \ +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, @@ -10574,7 +10474,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.SERUM, False, True)] = \ +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, @@ -10597,7 +10497,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.SERUM, False, False)] = \ +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, @@ -10621,7 +10521,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 100 -mapping[(300, False, True, False, Liquid.WATER, True, False)] = \ +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, @@ -10645,7 +10545,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 100 -mapping[(300, False, True, False, Liquid.WATER, True, False)] = \ +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, @@ -10669,7 +10569,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 100 -mapping[(300, False, True, False, Liquid.WATER, True, False)] = \ +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, @@ -10692,7 +10592,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.WATER, True, True)] = \ +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, @@ -10715,7 +10615,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.WATER, True, False)] = \ +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, @@ -10738,7 +10638,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.WATER, True, True)] = \ +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, @@ -10761,7 +10661,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.WATER, True, False)] = \ +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, @@ -10785,7 +10685,7 @@ def get_liquid_class( # V1.1: Set mix flow rate to 100 -mapping[(300, False, True, False, Liquid.WATER, False, False)] = \ +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, @@ -10808,7 +10708,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ +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, @@ -10831,7 +10731,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.WATER, False, True)] = \ +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, @@ -10854,7 +10754,7 @@ def get_liquid_class( ) -mapping[(300, True, True, False, Liquid.WATER, False, False)] = \ +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, @@ -10877,7 +10777,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.WATER, False, True)] = \ +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, @@ -10900,7 +10800,7 @@ def get_liquid_class( ) -mapping[(300, False, True, False, Liquid.WATER, False, False)] = \ +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, @@ -10923,7 +10823,7 @@ def get_liquid_class( ) -mapping[(50, True, True, True, Liquid.DMSO, True, True)] = \ +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, @@ -10946,7 +10846,7 @@ def get_liquid_class( ) -mapping[(50, True, True, True, Liquid.DMSO, False, True)] = \ +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, @@ -10969,7 +10869,7 @@ def get_liquid_class( ) -mapping[(50, True, True, True, Liquid.WATER, True, True)] = \ +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, @@ -10992,7 +10892,7 @@ def get_liquid_class( ) -mapping[(50, True, True, True, Liquid.WATER, False, True)] = \ +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, @@ -11015,7 +10915,7 @@ def get_liquid_class( ) -mapping[(50, True, True, True, Liquid.DMSO, True, True)] = \ +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, @@ -11038,7 +10938,7 @@ def get_liquid_class( ) -mapping[(50, True, True, True, Liquid.DMSO, False, True)] = \ +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, @@ -11061,7 +10961,7 @@ def get_liquid_class( ) -mapping[(50, True, True, True, Liquid.WATER, True, True)] = \ +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, @@ -11084,7 +10984,7 @@ def get_liquid_class( ) -mapping[(50, True, True, True, Liquid.WATER, False, True)] = \ +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, @@ -11107,7 +11007,7 @@ def get_liquid_class( ) -mapping[(50, False, True, True, Liquid.DMSO, True, True)] = \ +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, @@ -11130,7 +11030,7 @@ def get_liquid_class( ) -mapping[(50, False, True, True, Liquid.DMSO, False, True)] = \ +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, @@ -11153,7 +11053,7 @@ def get_liquid_class( ) -mapping[(50, False, True, True, Liquid.ETHANOL, True, True)] = \ +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, @@ -11176,7 +11076,7 @@ def get_liquid_class( ) -mapping[(50, False, True, True, Liquid.ETHANOL, False, True)] = \ +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, @@ -11199,7 +11099,7 @@ def get_liquid_class( ) -mapping[(50, False, True, True, Liquid.GLYCERIN80, False, True)] = \ +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, @@ -11222,7 +11122,7 @@ def get_liquid_class( ) -mapping[(50, False, True, True, Liquid.SERUM, True, True)] = \ +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, @@ -11245,7 +11145,7 @@ def get_liquid_class( ) -mapping[(50, False, True, True, Liquid.SERUM, False, True)] = \ +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, @@ -11268,7 +11168,7 @@ def get_liquid_class( ) -mapping[(50, False, True, True, Liquid.WATER, True, True)] = \ +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, @@ -11291,7 +11191,7 @@ def get_liquid_class( ) -mapping[(50, False, True, True, Liquid.WATER, False, True)] = \ +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, @@ -11314,7 +11214,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ +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, @@ -11337,7 +11237,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.DMSO, False, True)] = \ +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, @@ -11360,7 +11260,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ +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, @@ -11383,7 +11283,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.WATER, False, True)] = \ +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, @@ -11406,7 +11306,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.DMSO, True, True)] = \ +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, @@ -11429,7 +11329,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.DMSO, False, True)] = \ +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, @@ -11452,7 +11352,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.WATER, True, True)] = \ +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, @@ -11475,7 +11375,7 @@ def get_liquid_class( ) -mapping[(50, True, True, False, Liquid.WATER, False, True)] = \ +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, @@ -11499,7 +11399,7 @@ def get_liquid_class( # Liquid class for wash 50ul tips with CO-RE 96 Head in CO-RE 96 Head Washer. -mapping[(50, True, True, False, Liquid.WATER, False, False)] = \ +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, @@ -11522,7 +11422,7 @@ def get_liquid_class( ) -mapping[(50, False, True, False, Liquid.DMSO, True, True)] = \ +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, @@ -11545,7 +11445,7 @@ def get_liquid_class( ) -mapping[(50, False, True, False, Liquid.DMSO, False, True)] = \ +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, @@ -11568,7 +11468,7 @@ def get_liquid_class( ) -mapping[(50, False, True, False, Liquid.ETHANOL, True, True)] = \ +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, @@ -11591,7 +11491,7 @@ def get_liquid_class( ) -mapping[(50, False, True, False, Liquid.ETHANOL, False, True)] = \ +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, @@ -11614,7 +11514,7 @@ def get_liquid_class( ) -mapping[(50, False, True, False, Liquid.GLYCERIN80, False, True)] = \ +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, @@ -11637,7 +11537,7 @@ def get_liquid_class( ) -mapping[(50, False, True, False, Liquid.SERUM, True, True)] = \ +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, @@ -11660,7 +11560,7 @@ def get_liquid_class( ) -mapping[(50, False, True, False, Liquid.SERUM, False, True)] = \ +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, @@ -11683,7 +11583,7 @@ def get_liquid_class( ) -mapping[(50, False, True, False, Liquid.WATER, True, True)] = \ +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, @@ -11706,7 +11606,7 @@ def get_liquid_class( ) -mapping[(50, False, True, False, Liquid.WATER, False, True)] = \ +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, diff --git a/pylabrobot/liquid_handling/liquid_classes/hamilton/vantage.py b/pylabrobot/liquid_handling/liquid_classes/hamilton/vantage.py new file mode 100644 index 0000000000..f790cbfdfc --- /dev/null +++ b/pylabrobot/liquid_handling/liquid_classes/hamilton/vantage.py @@ -0,0 +1,10830 @@ +# pylint: skip-file + +from typing import Dict, Tuple, Optional + +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( + tip_volume: float, + is_core: bool, + is_tip: bool, + has_filter: bool, + liquid: Liquid, + jet: bool, + empty: bool +) -> Optional[HamiltonLiquidClass]: + """ Get the Hamilton Vantage liquid class for the given parameters. """ + + # 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, empty), 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}, + aspiration_flow_rate=500.0, + aspiration_mix_flow_rate=500.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=500.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.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}, + aspiration_flow_rate=500.0, + aspiration_mix_flow_rate=500.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=500.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=50.0, + dispense_mode=5.0, + dispense_mix_flow_rate=50.0, + dispense_air_transport_volume=1.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=1.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=50.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=1.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth Asp. 0.5mm, without pre-rinsing +# - Disp.: jet mode empty tip +# - Pipetting-Volumes jet-dispense between 20 - 1000µl +# +# +# +# Typical performance data under laboratory conditions: +# Volume µl Precision % Trueness % +# 20 7.15 - 5.36 +# 50 2.81 - 1.49 +# 100 2.48 - 1.94 +# 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}, + aspiration_flow_rate=500.0, + aspiration_mix_flow_rate=500.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=10.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=500.0, + dispense_mode=0.0, + dispense_mix_flow_rate=500.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=0.4, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth: Asp. 0.5mm +# Disp. 0.5mm +# - without pre-rinsing +# - dispense mode: surface empty tip +# - Pipetting-Volumes surface-dispense between 20 - 50µl +# +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 20 10.12 - 4.66 +# 50 3.79 - 1.18 +# +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=10.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=500.0, + dispense_mode=1.0, + dispense_mix_flow_rate=500.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=2.0, + dispense_stop_flow_rate=0.4, + 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}, + aspiration_flow_rate=60.0, + aspiration_mix_flow_rate=60.0, + aspiration_air_transport_volume=1.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=60.0, + dispense_mode=5.0, + dispense_mix_flow_rate=60.0, + dispense_air_transport_volume=1.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.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}, + aspiration_flow_rate=60.0, + aspiration_mix_flow_rate=60.0, + aspiration_air_transport_volume=1.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=60.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=1.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=10.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( + 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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=1.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=2.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=250.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( + 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, + aspiration_air_transport_volume=2.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=1.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=3.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=2.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=1.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.0, + dispense_stop_back_volume=0.0 +) + + +# - Volume 20 - 300ul +# - submerge depth: Asp. 0.5mm +# Disp. 0.5mm +# - without pre-rinsing, in case of drops pre-rinsing 3x with Aspiratevolume, +# ( >100ul perhaps 2x or set mix speed to 100ul/s) +# - dispense mode jet empty tip +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 20 6.68 -2.95 +# 50 1.71 1.93 +# 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( + 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, + aspiration_air_transport_volume=7.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=7.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.0, + dispense_stop_back_volume=0.0 +) + + +# - Volume 5 - 50ul +# - submerge depth: Asp. 0.5mm +# Disp. 0.5mm +# - without pre-rinsing, in case of drops pre-rinsing 3x with Aspiratevolume, +# ( >100ul perhaps 2x or set mix speed to 100ul/s) +# - dispense mode surface empty tip +# +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 5 7.96 -0.03 +# 10 7.99 5.88 +# 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=7.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=5.0, + dispense_mix_flow_rate=150.0, + dispense_air_transport_volume=7.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=50.0, + dispense_settling_time=0.5, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth: Asp. 0.5mm +# Disp. 0.5mm +# - without pre-rinsing +# - dispense mode surface empty tip +# - Pipetting-Volumes jet-dispense between 5 - 300µl +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 5 3.28 0.86 +# 10 4.88 -0.29 +# 20 2.92 2.68 +# 50 2.44 1.18 +# 100 1.33 1.29 +# 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=5.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.5, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=10.0, + dispense_mode=5.0, + dispense_mix_flow_rate=50.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=5.0, + dispense_swap_speed=2.0, + dispense_settling_time=2.0, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth: Asp. 0.5mm +# - without pre-rinsing +# - dispense mode jet empty tip +# - Pipetting-Volumes jet-dispense between 20 - 300µl +# +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 20 2.78 -0.05 +# 50 0.89 1.06 +# 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( + 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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.0, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth: Asp. 0.5mm +# Disp. 0.5mm +# - without pre-rinsing +# - dispense mode surface empty tip +# - Pipetting-Volumes surface-dispense between 1 - 50µl +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 1 17.32 3.68 +# 2 16.68 0.24 +# 5 6.30 1.37 +# 10 2.03 5.71 +# 20 1.72 3.91 +# 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=5.0, + dispense_mix_flow_rate=150.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.5, + dispense_stop_flow_rate=10.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( + 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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=2.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=150.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=1.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=3.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=1.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_air_transport_volume=2.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=1.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=3.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=2.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=1.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.0, + dispense_stop_back_volume=0.0 +) + + +# - Volume 20 - 300ul +# - submerge depth: Asp. 0.5mm +# Disp. 0.5mm +# - without pre-rinsing, in case of drops pre-rinsing 3x with Aspiratevolume, +# ( >100ul perhaps 2x or set mix speed to 100ul/s) +# - dispense mode jet empty tip +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 20 6.68 -2.95 +# 50 1.71 1.93 +# 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( + 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, + aspiration_air_transport_volume=15.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.0, + dispense_stop_back_volume=0.0 +) + + +# - Volume 5 - 50ul +# - submerge depth: Asp. 0.5mm +# Disp. 0.5mm +# - without pre-rinsing, in case of drops pre-rinsing 3x with Aspiratevolume, +# ( >100ul perhaps 2x or set mix speed to 100ul/s) +# - dispense mode surface empty tip +# +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 5 7.96 -0.03 +# 10 7.99 5.88 +# 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=10.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=5.0, + dispense_mix_flow_rate=150.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=50.0, + dispense_settling_time=0.5, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth: Asp. 0.5mm +# Disp. 0.5mm +# - without pre-rinsing +# - dispense mode surface empty tip +# - Pipetting-Volumes jet-dispense between 5 - 300µl +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 5 3.28 0.86 +# 10 4.88 -0.29 +# 20 2.92 2.68 +# 50 2.44 1.18 +# 100 1.33 1.29 +# 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=5.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.5, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=10.0, + dispense_mode=5.0, + dispense_mix_flow_rate=50.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=5.0, + dispense_swap_speed=2.0, + dispense_settling_time=2.0, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth: Asp. 0.5mm +# - without pre-rinsing +# - dispense mode jet empty tip +# - Pipetting-Volumes jet-dispense between 20 - 300µl +# +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 20 2.78 -0.05 +# 50 0.89 1.06 +# 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( + 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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.0, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth: Asp. 0.5mm +# Disp. 0.5mm +# - without pre-rinsing +# - dispense mode surface empty tip +# - Pipetting-Volumes surface-dispense between 1 - 50µl +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 1 17.32 3.68 +# 2 16.68 0.24 +# 5 6.30 1.37 +# 10 2.03 5.71 +# 20 1.72 3.91 +# 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=5.0, + dispense_mix_flow_rate=150.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.5, + dispense_stop_flow_rate=10.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=1.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=3.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=1.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.0, + dispense_stop_back_volume=0.0 +) + + +# - Volume 10 - 300ul +# - submerge depth: Asp. 0.5mm +# - without pre-rinsing, in case of drops pre-rinsing 1-3x with Aspiratevolume, +# ( >100ul perhaps less than 2x or set mix speed to 100ul/s) +# - dispense mode jet empty tip +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 10 7.29 0.79 +# 20 5.85 -0.66 +# 50 2.57 0.82 +# 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=15.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=0.5, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=0.0, + dispense_mix_flow_rate=250.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=50.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=1.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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=1.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=50.0, + dispense_mode=5.0, + dispense_mix_flow_rate=50.0, + dispense_air_transport_volume=1.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=1.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=50.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=1.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth: Asp. 0.5mm +# - without pre-rinsing +# - dispense mode jet empty tip +# - Pipetting-Volumes jet-dispense between 20 - 300µl +# +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 20 2.21 0.57 +# 50 1.53 0.23 +# 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=0.0, + dispense_mix_flow_rate=250.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.0, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth: Asp. 0.5mm +# Disp. 0.5mm +# - without pre-rinsing +# - dispense mode surface empty tip +# - Pipetting-Volumes surface-dispense between 1 - 50µl +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 5 5.97 1.26 +# 10 2.53 1.22 +# 20 3.67 2.60 +# 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=1.0, + dispense_mix_flow_rate=150.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.5, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +# - Volume 20 - 300ul +# - submerge depth: Asp. 0.5mm +# Disp. 0.5mm +# - without pre-rinsing, in case of drops pre-rinsing 3x with Aspiratevolume, +# ( >100ul perhaps 2x or set mix speed to 100ul/s) +# - dispense mode jet empty tip +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 20 6.68 -2.95 +# 50 1.71 1.93 +# 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=15.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=0.0, + dispense_mix_flow_rate=250.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=50.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.0, + dispense_stop_back_volume=0.0 +) + + +# - Volume 5 - 50ul +# - submerge depth: Asp. 0.5mm +# Disp. 0.5mm +# - without pre-rinsing, in case of drops pre-rinsing 3x with Aspiratevolume, +# ( >100ul perhaps 2x or set mix speed to 100ul/s) +# - dispense mode surface empty tip +# +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 5 7.96 -0.03 +# 10 7.99 5.88 +# 20 0.95 2.97 +# 50 0.31 -0.10 +# +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, + aspiration_air_transport_volume=10.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=1.0, + dispense_mix_flow_rate=150.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=50.0, + dispense_settling_time=0.5, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth: Asp. 0.5mm +# Disp. 0.5mm +# - without pre-rinsing +# - dispense mode surface empty tip +# - Pipetting-Volumes jet-dispense between 5 - 300µl +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 5 3.28 0.86 +# 10 4.88 -0.29 +# 20 2.92 2.68 +# 50 2.44 1.18 +# 100 1.33 1.29 +# 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.5, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=50.0, + dispense_mode=1.0, + dispense_mix_flow_rate=50.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=2.0, + dispense_stop_flow_rate=50.0, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth: Asp. 0.5mm +# - without pre-rinsing +# - dispense mode jet empty tip +# - Pipetting-Volumes jet-dispense between 20 - 300µl +# +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 20 2.78 -0.05 +# 50 0.89 1.06 +# 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=0.0, + dispense_mix_flow_rate=250.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.0, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth: Asp. 0.5mm +# Disp. 0.5mm +# - without pre-rinsing +# - dispense mode surface empty tip +# - Pipetting-Volumes surface-dispense between 1 - 50µl +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 1 17.32 3.68 +# 2 16.68 0.24 +# 5 6.30 1.37 +# 10 2.03 5.71 +# 20 1.72 3.91 +# 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=1.0, + dispense_mix_flow_rate=150.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.5, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth: Asp. 0.5mm +# - without pre-rinsing +# - dispense mode jet empty tip +# - Pipetting-Volumes jet-dispense between 20 - 300µl +# +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 20 2.78 -0.05 +# 50 0.89 1.06 +# 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=0.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.0, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth: Asp. 0.5mm +# Disp. 0.5mm +# - without pre-rinsing +# - dispense mode surface empty tip +# - Pipetting-Volumes surface-dispense between 1 - 50µl +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 1 17.32 3.68 +# 2 16.68 0.24 +# 5 6.30 1.37 +# 10 2.03 5.71 +# 20 1.72 3.91 +# 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=1.0, + dispense_mix_flow_rate=150.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.5, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth: Asp. 0.5mm +# - without pre-rinsing +# - dispense mode jet empty tip +# - Pipetting-Volumes jet-dispense between 20 - 300µl +# +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 20 0.50 2.26 +# 50 0.30 0.65 +# 100 0.22 1.15 +# 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=0.0, + dispense_mix_flow_rate=200.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.0, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth: Asp. 0.5mm +# Disp. 0.5mm +# - without pre-rinsing +# - dispense mode surface empty tip +# - Pipetting-Volumes jet-dispense between 1 - 20µl +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 1 11.17 - 6.64 +# 2 4.50 1.95 +# 5 0.38 0.50 +# 10 0.94 0.73 +# 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=3.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=1.0, + dispense_mix_flow_rate=150.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=3.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.5, + dispense_stop_flow_rate=0.4, + 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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=7.5, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=120.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=80.0, + dispense_mode=5.0, + dispense_mix_flow_rate=80.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=10.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=7.5, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=160.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=3.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=2.0, + dispense_blow_out_volume=3.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=20.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=50.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=20.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=1.0, + aspiration_blow_out_volume=3.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=3.0, + dispense_blow_out_volume=3.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=20.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=1.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=50.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + 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}, + aspiration_flow_rate=150.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=2.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=100.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=2.0, + dispense_swap_speed=2.0, + dispense_settling_time=2.0, + dispense_stop_flow_rate=20.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=3.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=2.0, + dispense_blow_out_volume=3.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=20.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=50.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + 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}, + aspiration_flow_rate=10.0, + aspiration_mix_flow_rate=30.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=15.0, + aspiration_swap_speed=100.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=12.0, + dispense_mode=5.0, + dispense_mix_flow_rate=30.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=15.0, + 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}, + aspiration_flow_rate=2000.0, + aspiration_mix_flow_rate=500.0, + aspiration_air_transport_volume=20.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=1000.0, + dispense_mode=2.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=20.0, + dispense_blow_out_volume=50.0, + 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}, + aspiration_flow_rate=2000.0, + aspiration_mix_flow_rate=500.0, + aspiration_air_transport_volume=20.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=1000.0, + dispense_mode=3.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=20.0, + dispense_blow_out_volume=50.0, + 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}, + aspiration_flow_rate=2000.0, + aspiration_mix_flow_rate=500.0, + aspiration_air_transport_volume=20.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=500.0, + dispense_mode=5.0, + dispense_mix_flow_rate=500.0, + dispense_air_transport_volume=20.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=5.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=500.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}, + aspiration_flow_rate=2000.0, + aspiration_mix_flow_rate=2000.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=1000.0, + dispense_mode=2.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=50.0, + 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}, + aspiration_flow_rate=2000.0, + aspiration_mix_flow_rate=200.0, + aspiration_air_transport_volume=30.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=30.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=1000.0, + dispense_mode=3.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=30.0, + dispense_blow_out_volume=50.0, + 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}, + aspiration_flow_rate=2000.0, + aspiration_mix_flow_rate=200.0, + aspiration_air_transport_volume=30.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=30.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=1000.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=30.0, + dispense_blow_out_volume=50.0, + 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}, + aspiration_flow_rate=1200.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=30.0, + aspiration_blow_out_volume=100.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=500.0, + dispense_mode=3.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=50.0, + dispense_blow_out_volume=100.0, + 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}, + aspiration_flow_rate=1000.0, + aspiration_mix_flow_rate=200.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=70.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=5.0, + dispense_mix_flow_rate=200.0, + dispense_air_transport_volume=50.0, + dispense_blow_out_volume=70.0, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=10.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}, + aspiration_flow_rate=2000.0, + aspiration_mix_flow_rate=500.0, + aspiration_air_transport_volume=20.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=1000.0, + dispense_mode=2.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=20.0, + dispense_blow_out_volume=50.0, + 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}, + aspiration_flow_rate=2000.0, + aspiration_mix_flow_rate=500.0, + aspiration_air_transport_volume=20.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=1000.0, + dispense_mode=3.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=20.0, + dispense_blow_out_volume=50.0, + 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}, + aspiration_flow_rate=2000.0, + aspiration_mix_flow_rate=500.0, + aspiration_air_transport_volume=20.0, + aspiration_blow_out_volume=10.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=500.0, + dispense_mode=5.0, + dispense_mix_flow_rate=500.0, + dispense_air_transport_volume=20.0, + dispense_blow_out_volume=10.0, + dispense_swap_speed=5.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=500.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=3.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=2.0, + dispense_blow_out_volume=3.0, + 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, 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, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=50.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.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_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, + aspiration_blow_out_volume=3.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=3.0, + dispense_blow_out_volume=3.0, + 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=2.0, + aspiration_blow_out_volume=2.0, + aspiration_swap_speed=6.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=50.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=2.0, + 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}, + aspiration_flow_rate=30.0, + aspiration_mix_flow_rate=30.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=10.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=20.0, + dispense_mode=5.0, + dispense_mix_flow_rate=20.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=10.0, + 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_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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=2.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=20.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=2.0, + 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}, + aspiration_flow_rate=20.0, + aspiration_mix_flow_rate=30.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=15.0, + aspiration_swap_speed=100.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=25.0, + dispense_mode=5.0, + dispense_mix_flow_rate=30.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=15.0, + 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=3.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=2.0, + dispense_blow_out_volume=3.0, + 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=5.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=240.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=5.0, + 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, 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, + aspiration_air_transport_volume=2.0, + aspiration_blow_out_volume=3.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=2.0, + dispense_blow_out_volume=3.0, + 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=50.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=1.0, + aspiration_blow_out_volume=3.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=3.0, + dispense_blow_out_volume=3.0, + 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=1.0, + aspiration_blow_out_volume=5.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=240.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=3.0, + dispense_blow_out_volume=5.0, + 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, 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, + aspiration_air_transport_volume=3.0, + aspiration_blow_out_volume=3.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=3.0, + dispense_blow_out_volume=3.0, + 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=2.0, + aspiration_blow_out_volume=2.0, + aspiration_swap_speed=6.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=50.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=2.0, + 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}, + aspiration_flow_rate=30.0, + aspiration_mix_flow_rate=30.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=10.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=20.0, + dispense_mode=5.0, + dispense_mix_flow_rate=20.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=10.0, + 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=2.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=2.0, + 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=5.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=240.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=5.0, + 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, 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, + aspiration_air_transport_volume=2.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=2.0, + dispense_blow_out_volume=3.0, + 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=2.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=20.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=2.0, + 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}, + aspiration_flow_rate=20.0, + aspiration_mix_flow_rate=30.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=15.0, + aspiration_swap_speed=100.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=25.0, + dispense_mode=5.0, + dispense_mix_flow_rate=30.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=15.0, + 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}, + aspiration_flow_rate=2000.0, + aspiration_mix_flow_rate=200.0, + aspiration_air_transport_volume=20.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=1000.0, + dispense_mode=2.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=20.0, + dispense_blow_out_volume=50.0, + 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}, + aspiration_flow_rate=2000.0, + aspiration_mix_flow_rate=500.0, + aspiration_air_transport_volume=20.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=1000.0, + dispense_mode=3.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=20.0, + dispense_blow_out_volume=50.0, + 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}, + aspiration_flow_rate=2000.0, + aspiration_mix_flow_rate=500.0, + aspiration_air_transport_volume=20.0, + aspiration_blow_out_volume=20.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=500.0, + dispense_mode=5.0, + dispense_mix_flow_rate=500.0, + dispense_air_transport_volume=20.0, + dispense_blow_out_volume=20.0, + dispense_swap_speed=5.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=500.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}, + aspiration_flow_rate=2000.0, + aspiration_mix_flow_rate=2000.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=1000.0, + dispense_mode=2.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=50.0, + 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}, + aspiration_flow_rate=2000.0, + aspiration_mix_flow_rate=200.0, + aspiration_air_transport_volume=30.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=30.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=1000.0, + dispense_mode=3.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=30.0, + dispense_blow_out_volume=50.0, + 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}, + aspiration_flow_rate=2000.0, + aspiration_mix_flow_rate=200.0, + aspiration_air_transport_volume=30.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=30.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=1000.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=30.0, + dispense_blow_out_volume=50.0, + 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}, + aspiration_flow_rate=1200.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=30.0, + aspiration_blow_out_volume=100.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=500.0, + dispense_mode=3.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=50.0, + dispense_blow_out_volume=100.0, + 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}, + aspiration_flow_rate=1000.0, + aspiration_mix_flow_rate=200.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=70.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=5.0, + dispense_mix_flow_rate=200.0, + dispense_air_transport_volume=50.0, + dispense_blow_out_volume=70.0, + 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}, + aspiration_flow_rate=2000.0, + aspiration_mix_flow_rate=500.0, + aspiration_air_transport_volume=20.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=1000.0, + dispense_mode=2.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=20.0, + dispense_blow_out_volume=50.0, + 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}, + aspiration_flow_rate=2000.0, + aspiration_mix_flow_rate=500.0, + aspiration_air_transport_volume=20.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=1000.0, + dispense_mode=3.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=20.0, + dispense_blow_out_volume=50.0, + 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}, + aspiration_flow_rate=2000.0, + aspiration_mix_flow_rate=500.0, + aspiration_air_transport_volume=20.0, + aspiration_blow_out_volume=20.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=500.0, + dispense_mode=5.0, + dispense_mix_flow_rate=500.0, + dispense_air_transport_volume=20.0, + dispense_blow_out_volume=20.0, + dispense_swap_speed=5.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=500.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=500.0, + dispense_mode=0.0, + dispense_mix_flow_rate=250.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=50.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=500.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=50.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=500.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=350.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=20.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=1.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=20.0, + 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, 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, + aspiration_blow_out_volume=20.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=20.0, + 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, 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, + aspiration_blow_out_volume=20.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=10.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=100.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=30.0, + dispense_blow_out_volume=50.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=10.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=100.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=30.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=10.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=100.0, + aspiration_settling_time=0.5, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=10.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=100.0, + aspiration_settling_time=0.5, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=0.0, + dispense_mix_flow_rate=250.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=50.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=300.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=40.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=40.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=40.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=40.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.0, + dispense_stop_back_volume=0.0 +) + + +# - ohne vorbenetzen, gleicher Tip +# - Aspiration submerge depth 1.0mm +# - Prealiquot equal to Aliquotvolume, jet mode part volume +# - Aliquot, jet mode part volume +# - Postaliquot equal to Aliquotvolume, jet mode empty tip +# +# +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 50 (12 Aliquots) 0.22 -4.84 +# 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=300.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=40.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=0.0, + dispense_mix_flow_rate=250.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=40.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=40.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=40.0, + 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.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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=250.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=1.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=4.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=0.0, + dispense_mix_flow_rate=250.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=250.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=10.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.5, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=1.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=10.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=10.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.5, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=10.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=10.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.5, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=200.0, + aspiration_mix_flow_rate=200.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.5, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=300.0, + dispense_mode=0.0, + dispense_mix_flow_rate=200.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=50.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=250.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}, + aspiration_flow_rate=200.0, + aspiration_mix_flow_rate=200.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.5, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=300.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=50.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=250.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}, + aspiration_flow_rate=150.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.5, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=1.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=30.0, + 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}, + aspiration_flow_rate=150.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.5, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=30.0, + 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}, + aspiration_flow_rate=150.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.5, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=300.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=300.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=300.0, + dispense_mode=0.0, + dispense_mix_flow_rate=250.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=50.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=300.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=40.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=0.0, + dispense_mix_flow_rate=250.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=40.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=40.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=40.0, + 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.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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=250.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=1.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=300.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=300.0, + dispense_mode=0.0, + dispense_mix_flow_rate=250.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=50.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=40.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=0.0, + dispense_mix_flow_rate=250.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=40.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=40.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=40.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=300.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=20.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=1.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=30.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=40.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=250.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=40.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=40.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=10.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=4.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=300.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=10.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=400.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=10.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=10.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=250.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=150.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=5.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=5.0, + dispense_mix_flow_rate=150.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=5.0, + 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, 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, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.5, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=30.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=40.0, + 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, 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, + aspiration_blow_out_volume=40.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=40.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=220.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=100.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=220.0, + dispense_mode=5.0, + dispense_mix_flow_rate=220.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=5.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.0, + dispense_stop_back_volume=0.0 +) + + +# - ohne vorbenetzen, gleicher Tip +# - Aspiration submerge depth 1.0mm +# - Prealiquot equal to Aliquotvolume, jet mode part volume +# - Aliquot, jet mode part volume +# - Postaliquot equal to Aliquotvolume, jet mode empty tip +# +# +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 50 (12 Aliquots) 0.22 -4.84 +# 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=300.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=40.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=40.0, + 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.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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=0.0, + 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.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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=10.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.5, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=10.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.5, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=200.0, + aspiration_mix_flow_rate=200.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.5, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=300.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=50.0, + 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}, + aspiration_flow_rate=150.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.5, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=30.0, + 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}, + aspiration_flow_rate=150.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.5, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=300.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=40.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=40.0, + 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.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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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.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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=300.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=40.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=40.0, + 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.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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=300.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=120.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=120.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=50.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.0, + dispense_stop_back_volume=0.0 +) + + +# - without pre-rinsing +# - submerge depth Asp. 1mm +# - for Disp. in empty PCR-Plate from 1µl up +# - 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}, + aspiration_flow_rate=80.0, + aspiration_mix_flow_rate=80.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=0.0, + dispense_mix_flow_rate=80.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=2.0, + dispense_stop_flow_rate=100.0, + dispense_stop_back_volume=0.5 +) + + +# - without pre-rinsing +# - submerge depth Asp. 1mm +# - 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}, + aspiration_flow_rate=80.0, + aspiration_mix_flow_rate=80.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=1.0, + dispense_mix_flow_rate=80.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=2.0, + dispense_stop_flow_rate=10.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}, + aspiration_flow_rate=60.0, + aspiration_mix_flow_rate=60.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=100.0, + dispense_mode=1.0, + dispense_mix_flow_rate=60.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_air_transport_volume=15.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=0.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=150.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=15.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=150.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=15.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=150.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}, + aspiration_flow_rate=60.0, + aspiration_mix_flow_rate=60.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=100.0, + dispense_mode=1.0, + dispense_mix_flow_rate=60.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=60.0, + aspiration_mix_flow_rate=60.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=100.0, + dispense_mode=5.0, + dispense_mix_flow_rate=60.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=60.0, + aspiration_mix_flow_rate=60.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=100.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=35.0, + dispense_mode=5.0, + dispense_mix_flow_rate=35.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=25.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=35.0, + dispense_mode=4.0, + dispense_mix_flow_rate=35.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=25.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=35.0, + dispense_mode=5.0, + dispense_mix_flow_rate=35.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=25.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.5, + dispense_stop_flow_rate=50.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=1.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=56.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=50.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=50.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=2.0, + aspiration_blow_out_volume=3.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=1.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=2.0, + dispense_blow_out_volume=3.0, + dispense_swap_speed=50.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=2.0, + aspiration_blow_out_volume=3.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=2.0, + dispense_blow_out_volume=3.0, + dispense_swap_speed=50.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=50.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=2.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=2.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=50.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=50.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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=10.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=10.0, + dispense_mode=1.0, + dispense_mix_flow_rate=10.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=5.0, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=2.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=5.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=10.0, + dispense_mode=5.0, + dispense_mix_flow_rate=10.0, + dispense_air_transport_volume=1.0, + dispense_blow_out_volume=5.0, + dispense_swap_speed=2.0, + dispense_settling_time=2.0, + dispense_stop_flow_rate=2.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=1.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=56.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=50.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.5, + dispense_stop_flow_rate=50.0, + dispense_stop_back_volume=0.0 +) + + +# - Volume 0.5 - 10ul +# - submerge depth: Asp. 0.5mm +# Disp. 0.5mm +# - without pre-rinsing +# - dispense mode surface empty tip +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 0.5 5.77 12.44 +# 1.0 3.65 4.27 +# 2.0 2.18 2.27 +# 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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.5, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=1.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.5, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=10.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.5, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.5, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +# - Volume 0.5 - 10ul +# - submerge depth: Asp. 0.5mm +# Disp. 0.5mm +# - without pre-rinsing +# - dispense mode surface empty tip +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 0.5 5.77 12.44 +# 1.0 3.65 4.27 +# 2.0 2.18 2.27 +# 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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.5, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=1.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.5, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=10.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.5, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.5, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=35.0, + dispense_mode=5.0, + dispense_mix_flow_rate=35.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=25.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=35.0, + dispense_mode=5.0, + dispense_mix_flow_rate=35.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=25.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=35.0, + dispense_mode=5.0, + dispense_mix_flow_rate=35.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=25.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=35.0, + dispense_mode=4.0, + dispense_mix_flow_rate=35.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=25.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=35.0, + dispense_mode=5.0, + dispense_mix_flow_rate=35.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=25.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=35.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=25.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=150.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=100.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=1.0, + dispense_mix_flow_rate=150.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=5.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=56.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=1.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=56.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=50.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=50.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=2.0, + aspiration_blow_out_volume=3.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=1.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=2.0, + dispense_blow_out_volume=3.0, + dispense_swap_speed=50.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=2.0, + aspiration_blow_out_volume=3.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=2.0, + dispense_blow_out_volume=3.0, + dispense_swap_speed=50.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=50.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=2.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=2.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=50.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=50.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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=10.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=10.0, + dispense_mode=1.0, + dispense_mix_flow_rate=10.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=5.0, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=2.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=1.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=56.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=35.0, + dispense_mode=1.0, + dispense_mix_flow_rate=35.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=25.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=35.0, + dispense_mode=5.0, + dispense_mix_flow_rate=35.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=25.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=35.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=25.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=50.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.5, + dispense_stop_flow_rate=50.0, + dispense_stop_back_volume=0.0 +) + + +# Under laboratory conditions: +# +# Settings for aliquots: +# +# Prealiquot: Postaliquot: Aliquots: +# 20ul 20ul 13 x 20ul +# 50ul 50ul 4 x 50ul +# 50ul 50ul 2 x 100 ul +# +# 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( + 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=10.0, + aspiration_blow_out_volume=20.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=20.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=1.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=5.0, + dispense_mix_flow_rate=200.0, + dispense_air_transport_volume=1.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +# Under laboratory conditions: +# +# Settings for aliquots: +# +# Prealiquot: Postaliquot: Aliquots: +# 20ul 20ul 13 x 20ul +# 50ul 50ul 4 x 50ul +# 50ul 50ul 2 x 100 ul +# +# 12 x 20ul = approximately 19.6 ul +# 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}, + aspiration_flow_rate=200.0, + aspiration_mix_flow_rate=200.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=20.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=230.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=20.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=5.0, + dispense_mix_flow_rate=200.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.0, + dispense_stop_back_volume=0.0 +) + + +# Under laboratory conditions: +# +# Settings for aliquots: +# +# Prealiquot: Postaliquot: Aliquots: +# 20ul 20ul 13 x 20ul +# 50ul 50ul 4 x 50ul +# 50ul 50ul 2 x 100 ul +# +# 12 x 20ul = approximately 19.1 ul +# 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( + 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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=10.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=10.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=1.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=5.0, + dispense_mix_flow_rate=200.0, + dispense_air_transport_volume=1.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +# Under laboratory conditions: +# +# Settings for aliquots: +# +# Prealiquot: Postaliquot: Aliquots: +# 20ul 20ul 12 x 20ul +# 50ul 50ul 4 x 50ul +# 50ul 50ul 2 x 100 ul +# +# 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=2.0, + aspiration_blow_out_volume=2.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=5.0, + dispense_mix_flow_rate=200.0, + dispense_air_transport_volume=2.0, + dispense_blow_out_volume=2.0, + 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}, + aspiration_flow_rate=30.0, + aspiration_mix_flow_rate=30.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=30.0, + dispense_mode=5.0, + dispense_mix_flow_rate=30.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=2.0, + dispense_stop_flow_rate=2.0, + dispense_stop_back_volume=0.0 +) + + +# Under laboratory conditions: +# +# Settings for aliquots: +# +# Prealiquot: Postaliquot: Aliquots: +# 20ul 20ul 13 x 20ul +# 50ul 50ul 4 x 50ul +# 50ul 50ul 2 x 100 ul +# +# 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}, + aspiration_flow_rate=200.0, + aspiration_mix_flow_rate=200.0, + aspiration_air_transport_volume=3.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=3.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=30.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=5.0, + dispense_mix_flow_rate=200.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.0, + dispense_stop_back_volume=0.0 +) + + +# Under laboratory conditions: +# +# Settings for aliquots: +# +# Prealiquot: Postaliquot: Aliquots: +# 20ul 20ul 13 x 20ul +# 50ul 50ul 4 x 50ul +# 50ul 50ul 2 x 100 ul +# +# 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}, + aspiration_flow_rate=200.0, + aspiration_mix_flow_rate=200.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=10.0, + aspiration_blow_out_volume=10.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=10.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=1.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=5.0, + dispense_mix_flow_rate=200.0, + dispense_air_transport_volume=1.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +# Under laboratory conditions: +# +# Settings for aliquots: +# +# Prealiquot: Postaliquot: Aliquots: +# 20ul 20ul 10 x 20ul +# 50ul 50ul 4 x 50ul +# 50ul 50ul 2 x 100 ul +# +# 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=80.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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_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, + aspiration_blow_out_volume=2.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=5.0, + dispense_mix_flow_rate=150.0, + dispense_air_transport_volume=2.0, + dispense_blow_out_volume=2.0, + 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=50.0, + dispense_mode=5.0, + dispense_mix_flow_rate=50.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=2.0, + dispense_stop_flow_rate=2.0, + dispense_stop_back_volume=0.0 +) + + +# Under laboratory conditions: +# +# Settings for aliquots: +# +# Prealiquot: Postaliquot: Aliquots: +# 20ul 20ul 13 x 20ul +# 50ul 50ul 4 x 50ul +# 50ul 50ul 2 x 100 ul +# +# 12 x 20ul = approximately 19.6 ul +# 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}, + aspiration_flow_rate=200.0, + aspiration_mix_flow_rate=200.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=50.0, + 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_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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=5.0, + dispense_mix_flow_rate=200.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.0, + dispense_stop_back_volume=0.0 +) + + +# Under laboratory conditions: +# +# Settings for aliquots: +# +# Prealiquot: Postaliquot: Aliquots: +# 20ul 20ul 13 x 20ul +# 50ul 50ul 4 x 50ul +# 50ul 50ul 2 x 100 ul +# +# 12 x 20ul = approximately 19.1 ul +# 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( + 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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=10.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=10.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=1.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=5.0, + dispense_mix_flow_rate=200.0, + dispense_air_transport_volume=1.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +# Under laboratory conditions: +# +# Settings for aliquots: +# +# Prealiquot: Postaliquot: Aliquots: +# 20ul 20ul 12 x 20ul +# 50ul 50ul 4 x 50ul +# 50ul 50ul 2 x 100 ul +# +# 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=2.0, + aspiration_blow_out_volume=2.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=5.0, + dispense_mix_flow_rate=200.0, + dispense_air_transport_volume=2.0, + dispense_blow_out_volume=2.0, + 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}, + aspiration_flow_rate=30.0, + aspiration_mix_flow_rate=30.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=30.0, + dispense_mode=5.0, + dispense_mix_flow_rate=30.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=2.0, + dispense_stop_flow_rate=2.0, + dispense_stop_back_volume=0.0 +) + + +# Under laboratory conditions: +# +# Settings for aliquots: +# +# Prealiquot: Postaliquot: Aliquots: +# 20ul 20ul 13 x 20ul +# 50ul 50ul 4 x 50ul +# 50ul 50ul 2 x 100 ul +# +# 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( + 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, + aspiration_air_transport_volume=3.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=10.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=10.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=1.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=5.0, + dispense_mix_flow_rate=200.0, + dispense_air_transport_volume=1.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +# Under laboratory conditions: +# +# Settings for aliquots: +# +# Prealiquot: Postaliquot: Aliquots: +# 20ul 20ul 13 x 20ul +# 50ul 50ul 4 x 50ul +# 50ul 50ul 2 x 100 ul +# +# 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}, + aspiration_flow_rate=200.0, + aspiration_mix_flow_rate=200.0, + aspiration_air_transport_volume=3.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=3.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=50.0, + 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}, + aspiration_flow_rate=250.0, + aspiration_mix_flow_rate=250.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=5.0, + dispense_mix_flow_rate=200.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=80.0, + aspiration_mix_flow_rate=80.0, + aspiration_air_transport_volume=10.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=0.0, + dispense_mix_flow_rate=80.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=2.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, 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, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=30.0, + 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, 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, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=80.0, + aspiration_mix_flow_rate=80.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=1.0, + dispense_mix_flow_rate=80.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=80.0, + aspiration_mix_flow_rate=80.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=5.0, + dispense_mix_flow_rate=80.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=80.0, + aspiration_mix_flow_rate=80.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.5, + dispense_stop_flow_rate=5.0, + dispense_stop_back_volume=0.0 +) + + +# - set Air transport volume to 25ul +# - set Correction 200.0, from 220.0 back to 217.0 (V 1.0) +# +# - submerge depth: Asp. 1mm +# - without pre-rinsing +# - dispense mode jet empty tip +# +# +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 20 0.50 2.26 +# 50 0.30 0.65 +# 100 0.22 1.15 +# 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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=25.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=0.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=50.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=25.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_air_transport_volume=10.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.0, + dispense_stop_back_volume=10.0 +) + + +# - submerge depth: Asp. 2mm +# Disp. 2mm +# - without pre-rinsing +# - dispense mode surface empty tip +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 1 11.17 - 6.64 +# 2 4.50 1.95 +# 5 0.38 0.50 +# 10 0.94 0.73 +# 20 0.63 0.73 +# 50 0.39 1.28 +# 100 0.28 0.94 +# 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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=10.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=1.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=1.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=50.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=10.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=10.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=1.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=50.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=10.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=10.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=1.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=20.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=50.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +# - ohne vorbenetzen, gleicher Tip +# - Aspiration submerge depth 1.0mm +# - Prealiquot equal to Aliquotvolume, jet mode part volume +# - Aliquot, jet mode part volume +# - Postaliquot equal to Aliquotvolume, jet mode empty tip +# +# +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 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( + 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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=0.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=0.3, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.0, + dispense_stop_back_volume=10.0 +) + + +# - Volume 5 - 300ul +# - submerge depth: Asp. 0.5mm +# Disp. 0.5mm +# - pre-rinsing 3x with Aspiratevolume, ( >100ul perhaps 2x or set mix speed to 100ul/s) +# - dispense mode surface empty tip +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 20 3.51 3.16 +# 50 1.19 1.09 +# 100 0.76 0.42 +# 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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=3.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=100.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=1.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=0.4, + 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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=3.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=100.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=1.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=3.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=100.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=1.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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)] = \ +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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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.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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=4.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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.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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.0, + dispense_stop_back_volume=0.0 +) + + +# - ohne vorbenetzen, gleicher Tip +# - Aspiration submerge depth 1.0mm +# - Prealiquot equal to Aliquotvolume, jet mode part volume +# - Aliquot, jet mode part volume +# - Postaliquot equal to Aliquotvolume, jet mode empty tip +# +# +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=0.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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, 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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=1.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=10.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=0.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=50.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=20.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=20.0, + dispense_mode=0.0, + dispense_mix_flow_rate=20.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=20.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=20.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=20.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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=10.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=10.0, + dispense_mode=1.0, + dispense_mix_flow_rate=10.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=10.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=10.0, + dispense_mode=5.0, + dispense_mix_flow_rate=10.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=10.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=2.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.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( + 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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=0.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=50.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=250.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=0.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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, 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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=1.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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.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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=10.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=150.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( + 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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=0.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=0.3, + dispense_settling_time=0.0, + dispense_stop_flow_rate=150.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=0.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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, 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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=150.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=1.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.0, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth Asp. 1mm +# - 3x pre-rinsing with probevolume +# mix position 0mm (mix flow rate is intentional low) +# - Disp. mode jet empty tip +# - Pipettingvolume jet-dispense from 20µl - 300µl +# - To protect, the distance from Asp. to Disp. should be as short as possible( about 12slot), +# because MeOH could drop out in a long way! +# - some droplets on tip after dispense are also with more air transport volume not avoidable +# - sometimes it helpes using Filtertips +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 20 0.61 0.57 +# 50 1.21 0.87 +# 100 0.63 0.47 +# 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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=30.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=0.5, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=0.0, + dispense_mix_flow_rate=30.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=50.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.0, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth Asp. 2mm +# - 5x pre-rinsing with probevolume 5-50µl, 3x pre-rinsing with probevolume >100µl, +# mix position 1mm (mix flow rate is intentional low) +# - Disp. mode jet empty tip +# - Pipettingvolume surface-dispense from 5µl - 300µl +# - To protect, the distance from Asp. to Disp. should be as short as possible( about 12slot), +# because MeOH could drop out in a long way! +# - some droplets on tip after dispense are also with more air transport volume not avoidable +# - sometimes it helpes using Filtertips +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 5 13.22 5.95 +# 10 2.08 1.00 +# 20 1.52 0.58 +# 50 0.63 0.51 +# 100 0.66 0.26 +# 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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=30.0, + aspiration_air_transport_volume=10.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=0.1, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=1.0, + dispense_mix_flow_rate=30.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=50.0, + dispense_swap_speed=50.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=5.0, + dispense_stop_back_volume=0.0 +) + + +# - use pLLD +# - submerge depth>: Asp. 0.5 mm +# Disp. 1.0 mm (surface) +# - without pre-rinsing +# - dispense mode jet empty tip +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 20 0.94 0.94 +# 50 0.74 1.20 +# 100 1.39 1.37 +# 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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.5, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=0.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=50.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.0, + dispense_stop_back_volume=0.0 +) + + +# - use pLLD +# - submerge depth>: Asp. 0.5 mm +# Disp. 1.0 mm (surface) +# - without pre-rinsing +# - dispense mode surface empty tip +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 1 7.45 9.13 +# 2 3.99 1.51 +# 5 1.95 1.64 +# 10 0.51 3.81 +# 20 0.34 - 3.95 +# 50 2.74 1.38 +# 100 0.29 1.04 +# 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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.5, + aspiration_over_aspirate_volume=1.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=1.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=2.0, + dispense_stop_flow_rate=10.0, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth: Asp. 2mm +# Disp. 2mm +# - without pre-rinsing +# - dispense mode surface empty tip +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 1 4.67 0.55 +# 5 3.98 2.77 +# 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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=5.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=1.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=5.0, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=5.0, + dispense_stop_back_volume=0.0 +) + + +# - submerge depth: Asp. 0.5 mm +# - without pre-rinsing +# - dispense mode jet empty tip +# +# +# +# +# LC-Plasma is a copy from Serumclass, Plasma has the same Parameters and Correctioncurve! +# +# Typical performance data under laboratory conditions: +# (2 Volumes measured as control) +# +# Volume µl Precision % Trueness % +# 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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=0.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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, 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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.0, + dispense_stop_back_volume=5.0 +) + + +# - submerge depth: Asp. 0.5mm +# Disp. 0.5mm +# - without pre-rinsing +# - dispense mode surface empty tip +# +# +# LC-Plasma is a copy from Serumclass, Plasma has the same Parameters and Correctioncurve! +# +# Typical performance data under laboratory conditions: +# (3 Volumes measured as control) +# +# Volume µl Precision % Trueness % +# 10 2.09 4.37 +# 20 1.16 3.52 +# 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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=1.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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.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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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.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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=10.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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)] = \ +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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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.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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=4.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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.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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=150.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=100.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=1.0, + dispense_mix_flow_rate=150.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=5.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.0, + dispense_stop_back_volume=0.0 +) + + +# - ohne vorbenetzen, gleicher Tip +# - Aspiration submerge depth 1.0mm +# - Prealiquot equal to Aliquotvolume, jet mode part volume +# - Aliquot, jet mode part volume +# - Postaliquot equal to Aliquotvolume, jet mode empty tip +# +# +# +# +# +# Typical performance data under laboratory conditions: +# +# Volume µl Precision % Trueness % +# 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( + 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=250.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=0.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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, 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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=1.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=10.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=0.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=50.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=20.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=20.0, + dispense_mode=0.0, + dispense_mix_flow_rate=20.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=20.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=20.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=20.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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=10.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=10.0, + dispense_mode=1.0, + dispense_mix_flow_rate=10.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=10.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=10.0, + dispense_mode=5.0, + dispense_mix_flow_rate=10.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=10.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=2.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=10.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=2.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=250.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( + 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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=0.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=50.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=250.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=0.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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, 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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=10.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=1.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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.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, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + 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.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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=15.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=10.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=150.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( + 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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=200.0, + dispense_mode=0.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=0.3, + dispense_settling_time=0.0, + dispense_stop_flow_rate=150.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=0.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=2.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.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, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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.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, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + 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, 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, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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, 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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=2.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=1.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=150.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=1.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=1.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=100.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=5.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=100.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=5.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=4.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=1.0, + dispense_stop_flow_rate=5.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=10.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=3.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=1.0, + dispense_blow_out_volume=10.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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, 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, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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, 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, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.5, + dispense_stop_flow_rate=1.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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, 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, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=3.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=2.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=3.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=3.0, + dispense_blow_out_volume=50.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=2.0, + aspiration_blow_out_volume=2.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=2.0, + dispense_blow_out_volume=2.0, + dispense_swap_speed=50.0, + dispense_settling_time=0.5, + dispense_stop_flow_rate=50.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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=3.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=50.0, + dispense_mode=5.0, + dispense_mix_flow_rate=10.0, + dispense_air_transport_volume=2.0, + dispense_blow_out_volume=3.0, + dispense_swap_speed=2.0, + dispense_settling_time=2.0, + dispense_stop_flow_rate=1.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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, 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, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=100.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=3.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=100.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=10.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=3.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=1.0, + dispense_blow_out_volume=10.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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, 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, + aspiration_blow_out_volume=5.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=5.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=3.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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.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, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.5, + dispense_stop_flow_rate=1.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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, 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, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=0.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=0.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=10.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=3.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=1.0, + dispense_blow_out_volume=10.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=200.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=2.0, + aspiration_blow_out_volume=50.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=400.0, + dispense_mode=3.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=3.0, + dispense_blow_out_volume=50.0, + dispense_swap_speed=4.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.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}, + aspiration_flow_rate=100.0, + aspiration_mix_flow_rate=75.0, + aspiration_air_transport_volume=2.0, + aspiration_blow_out_volume=2.0, + aspiration_swap_speed=50.0, + aspiration_settling_time=0.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=75.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=2.0, + dispense_blow_out_volume=2.0, + dispense_swap_speed=50.0, + dispense_settling_time=0.5, + dispense_stop_flow_rate=50.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}, + aspiration_flow_rate=50.0, + aspiration_mix_flow_rate=50.0, + aspiration_air_transport_volume=0.0, + aspiration_blow_out_volume=2.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=50.0, + dispense_mode=5.0, + dispense_mix_flow_rate=10.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=2.0, + dispense_swap_speed=2.0, + dispense_settling_time=2.0, + dispense_stop_flow_rate=1.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=150.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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, 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, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=100.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.0, + dispense_stop_back_volume=0.0 +) + + +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, + aspiration_air_transport_volume=5.0, + aspiration_blow_out_volume=30.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=0.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=180.0, + dispense_mode=3.0, + dispense_mix_flow_rate=1.0, + dispense_air_transport_volume=5.0, + dispense_blow_out_volume=30.0, + 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, 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, + aspiration_blow_out_volume=1.0, + aspiration_swap_speed=2.0, + aspiration_settling_time=1.0, + aspiration_over_aspirate_volume=2.0, + aspiration_clot_retract_height=0.0, + dispense_flow_rate=120.0, + dispense_mode=5.0, + dispense_mix_flow_rate=75.0, + dispense_air_transport_volume=0.0, + dispense_blow_out_volume=1.0, + dispense_swap_speed=2.0, + dispense_settling_time=0.0, + dispense_stop_flow_rate=1.0, + dispense_stop_back_volume=0.0 +) diff --git a/pylabrobot/liquid_handling/liquid_handler.py b/pylabrobot/liquid_handling/liquid_handler.py index bfe50211ea..1ddb03bccd 100644 --- a/pylabrobot/liquid_handling/liquid_handler.py +++ b/pylabrobot/liquid_handling/liquid_handler.py @@ -89,7 +89,7 @@ async def setup(self): await self.backend.setup() - self.head = {c: TipTracker() for c in range(self.backend.num_channels)} + self.head = {c: TipTracker(thing=f"Channel {c}") for c in range(self.backend.num_channels)} self.resource_assigned_callback(self.deck) for resource in self.deck.children: @@ -226,7 +226,7 @@ def _check_args( 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() # filter *args and **kwargs + 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} @@ -238,7 +238,8 @@ def _check_args( if len(missing) > 0: raise TypeError(f"Missing arguments to backend.{method.__name__}: {missing}") - extra = backend_kws - non_default + extra = backend_kws - set(args.keys()) + if len(extra) > 0 and len(vars_keyword) == 0: if strictness == Strictness.STRICT: raise TypeError(f"Extra arguments to backend.{method.__name__}: {extra}") @@ -329,6 +330,8 @@ async def pick_up_tips( for channel, op in zip(use_channels, pickups): if does_tip_tracking() and not op.resource.tracker.is_disabled: op.resource.tracker.remove_tip() + if not does_tip_tracking() and self.head[channel].has_tip: + self.head[channel].remove_tip() # override the tip if a tip exists self.head[channel].add_tip(op.tip, origin=op.resource, commit=False) extras = self._check_args(self.backend.pick_up_tips, backend_kwargs, @@ -1113,7 +1116,7 @@ async def move_resource( to: Coordinate, intermediate_locations: Optional[List[Coordinate]] = None, resource_offset: Coordinate = Coordinate.zero(), - to_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, @@ -1131,7 +1134,7 @@ async def move_resource( 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). - to_offset: The offset from the location'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. @@ -1143,10 +1146,10 @@ async def move_resource( return await self.backend.move_resource(move=Move( resource=resource, - to=to, + destination=to, intermediate_locations=intermediate_locations or [], resource_offset=resource_offset, - to_offset=to_offset, + destination_offset=destination_offset, pickup_distance_from_top=pickup_distance_from_top, get_direction=get_direction, put_direction=put_direction), diff --git a/pylabrobot/liquid_handling/liquid_handler_tests.py b/pylabrobot/liquid_handling/liquid_handler_tests.py index ef799b09f7..8e20f628be 100644 --- a/pylabrobot/liquid_handling/liquid_handler_tests.py +++ b/pylabrobot/liquid_handling/liquid_handler_tests.py @@ -420,16 +420,23 @@ async def test_stamp(self): async def test_tip_tracking_double_pickup(self): await self.lh.pick_up_tips(self.tip_rack["A1"]) + set_tip_tracking(enabled=True) with self.assertRaises(HasTipError): await self.lh.pick_up_tips(self.tip_rack["A2"]) + set_tip_tracking(enabled=False) + + with no_tip_tracking(): + await self.lh.pick_up_tips(self.tip_rack["A2"]) async def test_tip_tracking_empty_drop(self): with self.assertRaises(NoTipError): await self.lh.drop_tips(self.tip_rack["A1"]) await self.lh.pick_up_tips(self.tip_rack["A2"]) + set_tip_tracking(enabled=True) with self.assertRaises(HasTipError): await self.lh.drop_tips(self.tip_rack["A3"]) + set_tip_tracking(enabled=False) async def test_tip_tracking_empty_pickup(self): self.tip_rack.get_item("A1").empty() @@ -447,30 +454,10 @@ async def test_tip_tracking_full_spot(self): set_tip_tracking(enabled=False) async def test_tip_tracking_double_pickup_single_command(self): + set_tip_tracking(enabled=True) with self.assertRaises(NoTipError): await self.lh.pick_up_tips(self.tip_rack["A1", "A1"]) - - async def test_disable_tip_tracking(self): - # Even with tip tracking disabled, we keep track of which tips are on the head. - - await self.lh.pick_up_tips(self.tip_rack["A1"]) - - # Disable tip tracking globally with context manager - with no_tip_tracking(): - with self.assertRaises(HasTipError): - await self.lh.pick_up_tips(self.tip_rack["A1"]) - - # Disable tip tracking globally and manually set_tip_tracking(enabled=False) - with self.assertRaises(HasTipError): - await self.lh.pick_up_tips(self.tip_rack["A1"]) - set_tip_tracking(enabled=True) - - # Disable tip tracking for a single tip rack - self.tip_rack.get_item("A1").tracker.disable() - with self.assertRaises(HasTipError): - await self.lh.pick_up_tips(self.tip_rack["A1"]) - self.tip_rack.get_item("A1").tracker.enable() async def test_discard_tips(self): tips = self.tip_rack.get_tips("A1:D1") @@ -512,7 +499,8 @@ async def test_strictness(self): class TestBackend(backends.SaverBackend): """ Override pick_up_tips for testing. """ async def pick_up_tips(self, ops, use_channels, non_default, default=True): - pass + # pylint: disable=unused-argument + assert non_default == default self.backend = TestBackend(num_channels=16) self.lh = LiquidHandler(self.backend, deck=self.deck) @@ -523,25 +511,32 @@ async def pick_up_tips(self, ops, use_channels, non_default, default=True): await self.lh.pick_up_tips(self.tip_rack["A1"], non_default=True) await self.lh.pick_up_tips(self.tip_rack["A1"], use_channels=[1], non_default=True, does_not_exist=True) - with self.assertRaises(TypeError): + with self.assertRaises(TypeError): # missing non_default await self.lh.pick_up_tips(self.tip_rack["A1"], use_channels=[2]) set_strictness(Strictness.WARN) await self.lh.pick_up_tips(self.tip_rack["A1"], non_default=True, use_channels=[3]) - with self.assertWarns(UserWarning): + with self.assertWarns(UserWarning): # extra kwargs should warn await self.lh.pick_up_tips(self.tip_rack["A1"], use_channels=[4], non_default=True, does_not_exist=True) - with self.assertRaises(TypeError): + # We override default to False, so this should raise an assertion error. To test whether + # overriding default to True works. + with self.assertRaises(AssertionError): + await self.lh.pick_up_tips(self.tip_rack["A1"], use_channels=[4], + non_default=True, does_not_exist=True, default=False) + with self.assertRaises(TypeError): # missing non_default await self.lh.pick_up_tips(self.tip_rack["A1"], use_channels=[5]) set_strictness(Strictness.STRICT) await self.lh.pick_up_tips(self.tip_rack["A1"], non_default=True, use_channels=[6]) - with self.assertRaises(TypeError): + with self.assertRaises(TypeError): # cannot have extra kwargs await self.lh.pick_up_tips(self.tip_rack["A1"], use_channels=[7], non_default=True, does_not_exist=True) - with self.assertRaises(TypeError): + with self.assertRaises(TypeError): # missing non_default await self.lh.pick_up_tips(self.tip_rack["A1"], use_channels=[8]) + set_strictness(Strictness.WARN) + async def test_save_state(self): set_volume_tracking(enabled=True) diff --git a/pylabrobot/liquid_handling/standard.py b/pylabrobot/liquid_handling/standard.py index e153d35d2a..e2ed1e70be 100644 --- a/pylabrobot/liquid_handling/standard.py +++ b/pylabrobot/liquid_handling/standard.py @@ -116,19 +116,19 @@ class Move: Attributes: resource: The resource to move. - to: The destination of the move. + destination: The destination of the move. resource_offset: The offset of the resource. - to_offset: The offset of the destination. + destination_offset: The offset of the destination. pickup_distance_from_top: The distance from the top of the resource to pick up from. get_direction: The direction from which to grab the resource. put_direction: The direction from which to put the resource. """ resource: Resource - to: Coordinate + destination: Coordinate intermediate_locations: List[Coordinate] = field(default_factory=list) resource_offset: Coordinate = field(default=Coordinate.zero()) - to_offset: Coordinate = field(default=Coordinate.zero()) + destination_offset: Coordinate = field(default=Coordinate.zero()) pickup_distance_from_top: float = 0 get_direction: GripDirection = GripDirection.FRONT put_direction: GripDirection = GripDirection.FRONT diff --git a/pylabrobot/resources/hamilton/__init__.py b/pylabrobot/resources/hamilton/__init__.py index 52d7c529c7..5e028c3eea 100644 --- a/pylabrobot/resources/hamilton/__init__.py +++ b/pylabrobot/resources/hamilton/__init__.py @@ -1 +1,2 @@ -from .hamilton_decks import HamiltonDeck, STARLetDeck, STARDeck +from .hamilton_decks import HamiltonDeck, HamiltonSTARDeck, STARLetDeck, STARDeck +from .vantage_decks import VantageDeck diff --git a/pylabrobot/resources/hamilton/hamilton_deck_tests.py b/pylabrobot/resources/hamilton/hamilton_deck_tests.py index 32723ba3cd..769ce462bb 100644 --- a/pylabrobot/resources/hamilton/hamilton_deck_tests.py +++ b/pylabrobot/resources/hamilton/hamilton_deck_tests.py @@ -15,7 +15,7 @@ Cos_96_DW_1mL, Cos_96_DW_500ul, ) -from pylabrobot.resources.hamilton import HamiltonDeck, STARLetDeck +from pylabrobot.resources.hamilton import HamiltonSTARDeck, STARLetDeck class HamiltonDeckTests(unittest.TestCase): @@ -23,7 +23,7 @@ class HamiltonDeckTests(unittest.TestCase): def test_parse_lay_file(self): fn = "./pylabrobot/testing/test_data/test_deck.lay" - deck = HamiltonDeck.load_from_lay_file(fn) + deck = HamiltonSTARDeck.load_from_lay_file(fn) tip_car = deck.get_resource("TIP_CAR_480_A00_0001") assert isinstance(tip_car, TipCarrier) diff --git a/pylabrobot/resources/hamilton/hamilton_decks.py b/pylabrobot/resources/hamilton/hamilton_decks.py index 68110c00b6..a042e1dbaf 100644 --- a/pylabrobot/resources/hamilton/hamilton_decks.py +++ b/pylabrobot/resources/hamilton/hamilton_decks.py @@ -1,5 +1,6 @@ from __future__ import annotations +from abc import ABCMeta, abstractmethod import inspect import logging from typing import Callable, Optional, cast @@ -37,7 +38,7 @@ def _rails_for_x_coordinate(x: int): return int((x - 100.0) / _RAILS_WIDTH) + 1 -class HamiltonDeck(Deck): +class HamiltonDeck(Deck, metaclass=ABCMeta): """ Hamilton decks. Currently only STARLet and STAR are supported. """ def __init__( @@ -66,6 +67,10 @@ def __init__( resource=Trash("trash", size_x=0, size_y=241.2, size_z=0), location=Coordinate(x=trash_x, y=190.6, z=137.1)) # z I am not sure about + @abstractmethod + def rails_to_location(self, rails: int) -> Coordinate: + """ Convert a rail identifier to an absolute (x, y, z) coordinate. """ + def serialize(self) -> dict: """ Serialize this deck. """ return { @@ -125,7 +130,7 @@ def assign_child_resource( raise ValueError(f"Resource with name '{resource.name}' already defined.") if rails is not None: - resource_location = Coordinate(x=self._x_coordinate_for_rails(rails), y=63, z=100) + resource_location = self.rails_to_location(rails) elif location is not None: resource_location = location else: @@ -133,7 +138,7 @@ def assign_child_resource( if resource_location is not None: # collision detection if resource_location.x + resource.get_size_x() > \ - self._x_coordinate_for_rails(self.num_rails) and \ + self.rails_to_location(self.num_rails).x and \ rails is not None: raise ValueError(f"Resource with width {resource.get_size_x()} does not " f"fit at rails {rails}.") @@ -156,10 +161,6 @@ def assign_child_resource( return super().assign_child_resource(resource, location=resource_location, reassign=reassign) - def _x_coordinate_for_rails(self, rails: int): - """ Convert a rail identifier to an x coordinate. """ - return 100.0 + (rails - 1) * _RAILS_WIDTH - @classmethod def load_from_lay_file(cls, fn: str) -> HamiltonDeck: """ Parse a .lay file (legacy layout definition) and build the layout on this deck. @@ -310,17 +311,25 @@ def parse_resource(resource): return summary_ +class HamiltonSTARDeck(HamiltonDeck): # pylint: disable=invalid-name + """ Base class for a Hamilton STAR(let) deck. """ + + def rails_to_location(self, rails: int) -> Coordinate: + x = 100.0 + (rails - 1) * _RAILS_WIDTH + return Coordinate(x=x, y=63, z=100) + + def STARLetDeck( # pylint: disable=invalid-name resource_assigned_callback: Optional[Callable] = None, resource_unassigned_callback: Optional[Callable] = None, origin: Coordinate = Coordinate.zero(), -) -> HamiltonDeck: - """ A STARLet deck. +) -> HamiltonSTARDeck: + """ Create a new STARLet deck. Sizes from `HAMILTON\\Config\\ML_Starlet.dck` """ - return HamiltonDeck( + return HamiltonSTARDeck( num_rails=STARLET_NUM_RAILS, size_x=STARLET_SIZE_X, size_y=STARLET_SIZE_Y, @@ -334,13 +343,13 @@ def STARDeck( # pylint: disable=invalid-name resource_assigned_callback: Optional[Callable] = None, resource_unassigned_callback: Optional[Callable] = None, origin: Coordinate = Coordinate.zero(), -) -> HamiltonDeck: - """ The Hamilton STAR deck. +) -> HamiltonSTARDeck: + """ Create a new STAR deck. Sizes from `HAMILTON\\Config\\ML_STAR2.dck` """ - return HamiltonDeck( + return HamiltonSTARDeck( num_rails=STAR_NUM_RAILS, size_x=STAR_SIZE_X, size_y=STAR_SIZE_Y, diff --git a/pylabrobot/resources/hamilton/vantage_decks.py b/pylabrobot/resources/hamilton/vantage_decks.py new file mode 100644 index 0000000000..169d8a7389 --- /dev/null +++ b/pylabrobot/resources/hamilton/vantage_decks.py @@ -0,0 +1,42 @@ +from pylabrobot.resources import Coordinate +from pylabrobot.resources.hamilton.hamilton_decks import HamiltonDeck, _RAILS_WIDTH + + + +class VantageDeck(HamiltonDeck): + """ A Hamilton Vantage deck. """ + + def __init__(self, size: float): + """ Create a new Vantage deck of the given size. + + TODO: parameters for setting up the Entry Exit module, waste, etc. + + Args: + size: The size of the deck to create. Must be 1.3 or 2.0 (meters). + """ + + # Unfortunately, float is not supported as a Literal type, so we have to use a runtime check. + if size == 1.3: + # Curiously stored in ML_STAR2.deck in HAMILTON\\Config after editing the deck to 1.3m using + # the HxConfigEditor. + super().__init__( + num_rails=54, + size_x=1237.5, + size_y=653.5, + size_z=900.0, + ) + self.size = 1.3 + elif size == 2.0: + raise NotImplementedError("2.0m Vantage decks are not yet supported.") + else: + raise ValueError(f"Invalid deck size: {size}") + + def rails_to_location(self, rails: int) -> Coordinate: + x = 32.5 + (rails - 1) * _RAILS_WIDTH + return Coordinate(x=x, y=63, z=100) + + def serialize(self) -> dict: + return { + **super().serialize(), + "size": self.size, + } diff --git a/pylabrobot/resources/liquid.py b/pylabrobot/resources/liquid.py index e1ba816fd8..763a943e71 100644 --- a/pylabrobot/resources/liquid.py +++ b/pylabrobot/resources/liquid.py @@ -2,7 +2,12 @@ class Liquid(enum.Enum): - """ A liquid class (eg water, ethanol, etc.). """ + """ A type of liquid (eg water, ethanol, etc.). + + Backends use this information to determine optimal parameters for aspirating and dispensing. In + software like VENUS and EvoWare, this information is part of "Liquid Classes". In PyLabRobot, + liquid classes are simply groups of parameters passed to lh. + """ ACETONITRIL80WATER20 = "Acetonitril/Water 80:20" # TODO: need a better way to represent this. WATER = "Water" diff --git a/pylabrobot/resources/tip_rack.py b/pylabrobot/resources/tip_rack.py index 41d86b8f48..05ef53dd46 100644 --- a/pylabrobot/resources/tip_rack.py +++ b/pylabrobot/resources/tip_rack.py @@ -32,7 +32,7 @@ def __init__(self, name: str, size_x: float, size_y: float, make_tip: TipCreator super().__init__(name, size_x=size_y, size_y=size_x, size_z=size_z, category=category) - self.tracker = TipTracker() + self.tracker = TipTracker(thing="Tip spot") self.parent: Optional["TipRack"] = None self.make_tip = make_tip diff --git a/pylabrobot/resources/tip_tracker.py b/pylabrobot/resources/tip_tracker.py index b3fb79d9ef..78e4b3e3ba 100644 --- a/pylabrobot/resources/tip_tracker.py +++ b/pylabrobot/resources/tip_tracker.py @@ -27,10 +27,11 @@ def no_tip_tracking(): this.tip_tracking_enabled = old_value # type: ignore -class TipTracker(): +class TipTracker: """ A tip tracker tracks tip operations and raises errors if the tip operations are invalid. """ - def __init__(self): + def __init__(self, thing: str): + self.thing = thing self._is_disabled = False self._tip: Optional["Tip"] = None self._pending_tip: Optional["Tip"] = None @@ -49,11 +50,11 @@ def get_tip(self) -> "Tip": """ Get the tip. Note that does includes pending operations. Raises: - NoTipError: If the tip spot has no tip. + NoTipError: If the tip spot does not have a tip. """ if self._tip is None: - raise NoTipError("Tip spot has no tip.") + raise NoTipError(f"{self.thing} does not have a tip.") return self._tip def disable(self) -> None: @@ -75,7 +76,7 @@ def add_tip(self, tip: Tip, origin: Optional["TipSpot"] = None, commit: bool = T if self.is_disabled: raise RuntimeError("Tip tracker is disabled. Call `enable()`.") if self._pending_tip is not None: - raise HasTipError("Tip spot already has a tip.") + raise HasTipError(f"{self.thing} already has a tip.") self._pending_tip = tip self._tip_origin = origin @@ -88,7 +89,7 @@ def remove_tip(self) -> None: if self.is_disabled: raise RuntimeError("Tip tracker is disabled. Call `enable()`.") if self._pending_tip is None: - raise NoTipError("Tip spot has no tip.") + raise NoTipError(f"{self.thing} does not have a tip.") self._pending_tip = None def commit(self) -> None: @@ -121,3 +122,7 @@ def load_state(self, state: dict) -> None: def get_tip_origin(self) -> Optional["TipSpot"]: """ Get the origin of the current tip, if known. """ return self._tip_origin + + def __repr__(self) -> str: + return f"TipTracker({self.thing}, is_disabled={self.is_disabled}, has_tip={self.has_tip}" + \ + f" tip={self._tip}, pending_tip={self._pending_tip})" diff --git a/pylabrobot/resources/tip_tracker_tests.py b/pylabrobot/resources/tip_tracker_tests.py index 901c9b482e..983b0800f1 100644 --- a/pylabrobot/resources/tip_tracker_tests.py +++ b/pylabrobot/resources/tip_tracker_tests.py @@ -12,11 +12,11 @@ def setUp(self) -> None: self.tip = Tip(has_filter=False, total_tip_length=10, maximal_volume=10, fitting_depth=10) def test_init(self): - tracker = TipTracker() + tracker = TipTracker(thing="tester") self.assertEqual(tracker.has_tip, False) def test_add_tip(self): - tracker = TipTracker() + tracker = TipTracker(thing="tester") tracker.add_tip(self.tip) self.assertEqual(tracker.has_tip, True) self.assertEqual(tracker.get_tip(), self.tip) @@ -25,7 +25,7 @@ def test_add_tip(self): tracker.add_tip(self.tip) def test_remove_tip(self): - tracker = TipTracker() + tracker = TipTracker(thing="tester") tracker.add_tip(self.tip) tracker.remove_tip() tracker.commit() diff --git a/tools/make_lc.py b/tools/make_lc.py index 07797ff485..165d6ea400 100644 --- a/tools/make_lc.py +++ b/tools/make_lc.py @@ -3,10 +3,11 @@ import binascii import csv import struct +import sys import textwrap from typing import Dict -from pylabrobot.liquid_handling.liquid_classes import Liquid +from pylabrobot.resources.liquid import Liquid def liquid_class_to_tip_volume(liquid_class: str) -> float: @@ -33,7 +34,7 @@ def ieee_754_to_float(dat: bytes) -> float: def main(): - with open("LiquidClass.csv", "r", encoding="utf-8") as f: + with open(sys.argv[1], "r", encoding="utf-8") as f: lines = f.readlines() lines = lines[1:] reader = csv.reader(lines)