Skip to content

fluid_control

Aspirator

Bases: AspirateMixin, PressureOverLiquidControl

Aspirator class for modular aspirating applications.

Driver for a Festo aspirator, e.g. VTOI, VTOE, VTOF. Currently, there are hard-coded dependencies on the festo-pgva and festo-vaem drivers for their respective hardware modules.

The aspirate operation is provided by AspirateMixin.

Construction is handled entirely by PressureOverLiquidControl; component_id defaults to "aspirator_1" (derived from component_type).

Examples:

Aspirate 40 uL of water on channel 1:

1
2
3
4
5
6
>>> import json
>>> from fluid_control import Aspirator
>>> with open("aspirator-config.json") as fh:
...     config = json.load(fh)
>>> aspirator = Aspirator(config=config, component_id="aspirator")
>>> aspirator.aspirate({1: {"volume": 40.0, "liquid_class": "water"}})
Source code in src/fluid_control/aspirator.py
class Aspirator(AspirateMixin, PressureOverLiquidControl):
    """
    Aspirator class for modular aspirating applications.

    Driver for a Festo aspirator, e.g. VTOI, VTOE, VTOF.
    Currently, there are hard-coded dependencies on the festo-pgva and festo-vaem drivers
    for their respective hardware modules.

    The ``aspirate`` operation is provided by [`AspirateMixin`][fluid_control.capabilities.AspirateMixin].

    Construction is handled entirely by
    [`PressureOverLiquidControl`][fluid_control.fluid_control.PressureOverLiquidControl]; ``component_id``
    defaults to ``"aspirator_1"`` (derived from ``component_type``).

    Examples:
        Aspirate 40 uL of water on channel 1:

        >>> import json
        >>> from fluid_control import Aspirator
        >>> with open("aspirator-config.json") as fh:
        ...     config = json.load(fh)
        >>> aspirator = Aspirator(config=config, component_id="aspirator")
        >>> aspirator.aspirate({1: {"volume": 40.0, "liquid_class": "water"}})

    """

    component_type: str = "aspirator"

Dispenser

Bases: DispenseMixin, PressureOverLiquidControl

Dispenser class for modular dispensing applications.

Driver for a Festo dispenser, e.g. VTOI, VTOE, VTOF. Currently, there are hard-coded dependencies on the festo-pgva and festo-vaem drivers for their respective hardware modules.

The dispense operation is provided by DispenseMixin.

Construction is handled entirely by PressureOverLiquidControl; component_id defaults to "dispenser_1" (derived from component_type).

Examples:

Load an instrument configuration and dispense 25 uL of water on channel 1:

1
2
3
4
5
6
>>> import json
>>> from fluid_control import Dispenser
>>> with open("micro-dispenser-config.json") as fh:
...     config = json.load(fh)
>>> dispenser = Dispenser(config=config, component_id="micro-dispenser")
>>> dispenser.dispense({1: {"volume": 25.0, "liquid_class": "water"}})

Use as a context manager to guarantee the instrument is returned to a safe state on exit, even if an exception is raised:

>>> with Dispenser(config=config, component_id="micro-dispenser") as dispenser:
...     dispenser.dispense({1: {"volume": 30.0, "liquid_class": "water"}})
Source code in src/fluid_control/dispenser.py
class Dispenser(DispenseMixin, PressureOverLiquidControl):
    """
    Dispenser class for modular dispensing applications.

    Driver for a Festo dispenser, e.g. VTOI, VTOE, VTOF.
    Currently, there are hard-coded dependencies on the festo-pgva and festo-vaem drivers
    for their respective hardware modules.

    The ``dispense`` operation is provided by [`DispenseMixin`][fluid_control.capabilities.DispenseMixin].

    Construction is handled entirely by
    [`PressureOverLiquidControl`][fluid_control.fluid_control.PressureOverLiquidControl]; ``component_id``
    defaults to ``"dispenser_1"`` (derived from ``component_type``).

    Examples:
        Load an instrument configuration and dispense 25 uL of water on channel 1:

        >>> import json
        >>> from fluid_control import Dispenser
        >>> with open("micro-dispenser-config.json") as fh:
        ...     config = json.load(fh)
        >>> dispenser = Dispenser(config=config, component_id="micro-dispenser")
        >>> dispenser.dispense({1: {"volume": 25.0, "liquid_class": "water"}})

        Use as a context manager to guarantee the instrument is returned to a
        safe state on exit, even if an exception is raised:

        >>> with Dispenser(config=config, component_id="micro-dispenser") as dispenser:
        ...     dispenser.dispense({1: {"volume": 30.0, "liquid_class": "water"}})

    """

    component_type: str = "dispenser"

Pipettor

Bases: AspirateMixin, DispenseMixin, MixMixin, TipHandlingMixin, PressureOverLiquidControl

Festo multi-channel pressure-over-liquid pipettor.

Composes the full set of fluid-handling capabilities onto the PressureOverLiquidControl engine:

Construction is handled entirely by PressureOverLiquidControl; component_id defaults to "pipettor_1" (derived from component_type).

Examples:

Aspirate, mix, then dispense on a mounted pipettor:

1
2
3
4
5
6
7
8
>>> import json
>>> from fluid_control import Pipettor
>>> with open("pipettor-config.json") as fh:
...     config = json.load(fh)
>>> pipettor = Pipettor(config=config, component_id="pipettor")
>>> pipettor.aspirate({1: {"volume": 50.0, "liquid_class": "water"}})
>>> pipettor.mix({1: {"volume": 20.0, "liquid_class": "water"}}, cycles=3)
>>> pipettor.dispense({1: {"volume": 50.0, "liquid_class": "water"}})
Source code in src/fluid_control/pipettor.py
class Pipettor(AspirateMixin, DispenseMixin, MixMixin, TipHandlingMixin, PressureOverLiquidControl):
    """
    Festo multi-channel pressure-over-liquid pipettor.

    Composes the full set of fluid-handling capabilities onto the
    [`PressureOverLiquidControl`][fluid_control.fluid_control.PressureOverLiquidControl] engine:

    - ``aspirate`` from [`AspirateMixin`][fluid_control.capabilities.AspirateMixin]
    - ``dispense`` from [`DispenseMixin`][fluid_control.capabilities.DispenseMixin]
    - ``mix`` from [`MixMixin`][fluid_control.capabilities.MixMixin]
    - ``pickup_tips`` / ``eject_tips`` from [`TipHandlingMixin`][fluid_control.capabilities.TipHandlingMixin]

    Construction is handled entirely by
    [`PressureOverLiquidControl`][fluid_control.fluid_control.PressureOverLiquidControl]; ``component_id``
    defaults to ``"pipettor_1"`` (derived from ``component_type``).

    Examples:
        Aspirate, mix, then dispense on a mounted pipettor:

        >>> import json
        >>> from fluid_control import Pipettor
        >>> with open("pipettor-config.json") as fh:
        ...     config = json.load(fh)
        >>> pipettor = Pipettor(config=config, component_id="pipettor")
        >>> pipettor.aspirate({1: {"volume": 50.0, "liquid_class": "water"}})
        >>> pipettor.mix({1: {"volume": 20.0, "liquid_class": "water"}}, cycles=3)
        >>> pipettor.dispense({1: {"volume": 50.0, "liquid_class": "water"}})

    """

    component_type: str = "pipettor"

PressureControl

Thin adapter exposing a uniform pressure-control interface over a backend controller.

Source code in src/fluid_control/pressure_control.py
class PressureControl:
    """Thin adapter exposing a uniform pressure-control interface over a backend controller."""

    def __init__(self, controller):
        """
        Store the backing controller.

        Args:
            controller: Backend pressure-control device exposing ``set_veab`` and ``get_veab``.

        """
        self.controller = controller

    def set_output_pressure(self, pressure: int):
        """
        Set the output pressure on the backing controller.

        Args:
            pressure (int): Target output pressure in mbar.

        """
        self.controller.set_veab(pressure)

    def get_output_pressure(self):
        """
        Return the current output pressure from the backing controller.

        Returns:
            The controller's current output pressure reading.

        """
        return self.controller.get_veab()

    def get_status(self):
        """
        Return the controller status.

        Raises:
            NotImplementedError: Status reporting is not yet implemented for this generic adapter.

        """
        raise NotImplementedError("PressureControl.get_status is not implemented for the generic adapter")

__init__(controller)

Store the backing controller.

Parameters:

Name Type Description Default
controller

Backend pressure-control device exposing set_veab and get_veab.

required
Source code in src/fluid_control/pressure_control.py
def __init__(self, controller):
    """
    Store the backing controller.

    Args:
        controller: Backend pressure-control device exposing ``set_veab`` and ``get_veab``.

    """
    self.controller = controller

get_output_pressure()

Return the current output pressure from the backing controller.

Returns:

Type Description

The controller's current output pressure reading.

Source code in src/fluid_control/pressure_control.py
def get_output_pressure(self):
    """
    Return the current output pressure from the backing controller.

    Returns:
        The controller's current output pressure reading.

    """
    return self.controller.get_veab()

get_status()

Return the controller status.

Raises:

Type Description
NotImplementedError

Status reporting is not yet implemented for this generic adapter.

Source code in src/fluid_control/pressure_control.py
def get_status(self):
    """
    Return the controller status.

    Raises:
        NotImplementedError: Status reporting is not yet implemented for this generic adapter.

    """
    raise NotImplementedError("PressureControl.get_status is not implemented for the generic adapter")

set_output_pressure(pressure)

Set the output pressure on the backing controller.

Parameters:

Name Type Description Default
pressure int

Target output pressure in mbar.

required
Source code in src/fluid_control/pressure_control.py
def set_output_pressure(self, pressure: int):
    """
    Set the output pressure on the backing controller.

    Args:
        pressure (int): Target output pressure in mbar.

    """
    self.controller.set_veab(pressure)

load_example_config()

1
2
3
4
5
Load and return the bundled example instrument configuration as a dict.

The returned mapping is the full instrument configuration and can be passed
directly to a device constructor. Select a component with ``component_id``
(``"micro-dispenser"`` or ``"pipettor"``).

Returns:

Name Type Description
dict dict[str, Any]

The parsed example instrument configuration.

Examples:

1
2
3
>>> from fluid_control import Dispenser, load_example_config
>>> config = load_example_config()
>>> dispenser = Dispenser(config=config, component_id="micro-dispenser")
Source code in src/fluid_control/reference_config.py
def load_example_config() -> dict[str, Any]:
    """
        Load and return the bundled example instrument configuration as a dict.

        The returned mapping is the full instrument configuration and can be passed
        directly to a device constructor. Select a component with ``component_id``
        (``"micro-dispenser"`` or ``"pipettor"``).

    Returns:
        dict: The parsed example instrument configuration.

    Examples:
        >>> from fluid_control import Dispenser, load_example_config
        >>> config = load_example_config()
        >>> dispenser = Dispenser(config=config, component_id="micro-dispenser")

    """
    with example_config_path().open("r", encoding="utf-8") as fh:
        return json.load(fh)