Pipette

class acq4.devices.Pipette.Pipette(deviceManager, config, name)[source]

Bases: Device, OptomechDevice

Represents a pipette or electrode attached to a motorized manipulator.

This device provides a camera module interface for driving a motorized electrode holder:

  • Visually direct pipette tip via camera module

  • Automatically align pipette tip for diagonal approach to cells

  • Automatically calibrate pipette tip position (via Tracker)

This device must be configured with a Stage as its parent.

The local coordinate system of the device is configured such that the X axis points in the direction of the pipette tip, the Z axis points upward (same as global +Z), and the Y axis is the vector perpendicular to both X and Z.

Configuration options:

  • pitch (float or ‘auto’, required): The angle of the pipette (in degrees) relative to the horizontal plane. Positive values point downward. This option must be specified in the configuration. If the value ‘auto’ is given, then the pitch is derived from the parent manipulator’s X axis (or other specified by parentAutoAxis) pitch.

  • yaw (float or ‘auto’, required): The angle of the pipette (in degrees) relative to the global +X axis (points to the operator’s right when facing the microscope). Positive values are clockwise from global +X. This option must be specified in the configuration. If the value ‘auto’ is given, then the yaw is derived from the parent manipulator’s X axis (or other specified by parentAutoAxis) yaw.

  • parentAutoAxis (str, optional): One of ‘+x’ (default), ‘-x’, ‘+y’, ‘-y’, ‘+z’, or ‘-z’ indicating the axis and direction in the parent manipulator’s coordinate system that points along the pipette and toward the tip. This axis is used by the pitch and yaw options when they are set to ‘auto’. If the pipette is not parallel to one of these axes, then a numerical value must be provided for the pitch and/or yaw.

  • searchHeight (float, optional): The distance to focus above the sample surface when searching for pipette tips. This should be about 1-2mm, enough to avoid collisions between the pipette tip and the sample during search. Default is 2 * mm.

  • searchTipHeight (float, optional): The distance above the sample surface to bring the (putative) pipette tip position when searching for new pipette tips. For low working-distance objectives, this should be about 0.5 mm less than searchHeight to avoid collisions between the tip and the objective during search. Default is 1.5 * mm.

  • approachHeight (float, optional): The distance to bring the pipette tip above the sample surface when beginning a diagonal approach. Default is 100 * um.

  • idleHeight (float, optional): The distance to bring the pipette tip above the sample surface when in idle position. Default is 1 * mm.

  • idleDistance (float, optional): The x/y distance from the global origin from which the pipette top should be placed in idle mode. Default is 7 * mm.

  • recordingChambers (list, optional): List of names of RecordingChamber devices that this Pipette is meant to work with.

  • cleaningWell (str, optional): Name of the well (RecordingChamber) device associated with

    this pipette for cleaning.

  • reasonableTipOffsetDistance (float, optional): When updating the tip offset, this is the maximum distance (in meters)

    from the original tip offset that is considered reasonable. If the tip offset is outside this distance, the user will be prompted to confirm the new offset. Default is 30 * um.

Standard OptomechDevice configuration options (see OptomechDevice base class):

  • parentDevice (str, required): Name of parent Stage device (manipulator)

  • transform (dict, optional): Spatial transform relative to parent device

Example configuration:

PatchPipette1:
    driver: 'Pipette'
    parentDevice: 'Manipulator1'
    pitch: 15.0
    yaw: 45.0
    searchHeight: 2 * mm
    approachHeight: 100 * um
    idleHeight: 1 * mm
    recordingChambers: ['Chamber1']
    cleaningWell: 'CleaningWell1'
advance(depth, speed, name=None)[source]

Move the electrode along its axis until it reaches the specified (global) depth.

approachDepth()[source]

Return the global depth where the electrode should move to when starting approach mode.

This is defined as the sample surface + 100um.

averageHistoricOffset()[source]
cameraModuleInterface(mod)[source]
checkRangeOfMotion(pos, name, tolerance=0.0005)[source]

Warn user if the position (in global coordinates) is within 500µm of the manipulator’s range of motion.

property cleanApproachHeight
clearSavedOffsets(parent)[source]

Clear the saved offsets if the parent manipulator’s axes are re-calibrated.

defaultMotionPlanners = {'aboveTarget': <class 'acq4.devices.Pipette.planners.AboveTargetMotionPlanner'>, 'approach': <class 'acq4.devices.Pipette.planners.ApproachMotionPlanner'>, 'clean': <class 'acq4.devices.Pipette.planners.CleanMotionPlanner'>, 'home': <class 'acq4.devices.Pipette.planners.HomeMotionPlanner'>, 'idle': <class 'acq4.devices.Pipette.planners.IdleMotionPlanner'>, 'rinse': <class 'acq4.devices.Pipette.planners.CleanMotionPlanner'>, 'saved': <class 'acq4.devices.Pipette.planners.SavedPositionMotionPlanner'>, 'search': <class 'acq4.devices.Pipette.planners.SearchMotionPlanner'>, 'target': <class 'acq4.devices.Pipette.planners.TargetMotionPlanner'>}
depthBelowSurface()[source]

Return the current depth of the pipette tip below the sample surface (positive values are below the surface).

deviceInterface(win)[source]

Return a widget with a UI to put in the device rack

findNewPipette()[source]
focusTarget(speed='fast', raiseErrors=False)[source]
focusTip(speed='fast', raiseErrors=False)[source]
getBoundaries() List[Plane][source]
getCleaningWell() RecordingChamber | None[source]

Return the RecordingChamber instance that is associated with this Pipette for cleaning (see ‘cleaningWell’ config option).

getGeometry(name=None)[source]
getRecordingChambers() List[RecordingChamber][source]

Return a list of RecordingChamber instances that are associated with this Pipette (see ‘recordingChambers’ config option).

globalDirection()[source]

Return a global unit vector pointing in the direction of the pipette axis.

globalPosition()[source]

Return the position of the electrode tip in global coordinates.

Note: the position in local coordinates is always [0, 0, 0].

goAboveTarget(speed, **kwds)[source]
goApproach(speed, **kwds)[source]

Move the electrode tip such that it is 100um above the sample surface with its axis aligned to the target.

goHome(speed='fast', **kwds)[source]

Extract pipette tip diagonally, then move to home position.

goIdle(speed='fast', **kwds)[source]
goSearch(speed='fast', distance=0, **kwds)[source]
goTarget(speed, **kwds)[source]
hideMarkers(hide)[source]
imagingDevice() Camera[source]
iterativelyFindTip(max_reps=10, found_threshold=3e-06, delay_after_move=0.2, max_allowed_offset=None, delay_after_update=0, reserve_devices=True, go_to_tip_first=False, _future=None)[source]

Iteratively refine the tip position by finding the tip in frame and focusing, until convergence.

Returns if convergence is reached (tip position changes less than found_threshold between iterations) or after max_reps iterations. Otherwise, raises an exception.

Parameters

max_repsint

Maximum number of iterations to perform. If exceeded before convergence, TimeoutError is raised.

found_thresholdfloat

Distance threshold (meters) for convergence.

delay_after_movefloat

Time to wait (seconds) after each move before finding the tip again.

max_allowed_offsetfloat

Maximum allowed tip offset distance (meters). If exceeded, ValueError is raised.

delay_after_updatefloat

Time to wait (seconds) after updating the tip position before the next iteration. Default is 0; this is used to allow visual confirmation of the update before moving on.

reserve_devicesbool

If True, then devices will be reserved for the duration of this method.

go_to_tip_firstbool

If True, then the pipette will first move to the current tip position before starting the iterative process.

loadPosition(name, default=None)[source]

Return a previously saved position.

localDirection()[source]

Return a local unit vector pointing in the direction of the pipette axis.

moveTo(position: str, speed, raiseErrors=False, **kwds)[source]

Move the pipette tip to a named position, with safe motion planning.

If raiseErrors is True, then an exception will be raised in a background thread if the move fails.

newPipetteTipOffsetIsReasonable(pos) bool[source]
overrideTipOffsetHistory(pos)[source]
pathGeneratorClass

alias of PipettePathGenerator

pitchAngle()[source]

Return the pitch of the electrode in degrees (angle relative to horizontal plane).

For positive angles, the pipette tip points downward, toward -Z.

pitchRadians()[source]
positionAtDepth(depth, start=None)[source]

Return the global position at depth that lies along the axis of the pipette.

If start is given, then the pipette axis is assumed to go through this global position rather than its current position.

positionChangeFinished()[source]
positionChanged()[source]
quit()[source]
recordTipOffsetInHistory(pos)[source]
resetGlobalPosition(pos)[source]

Set the device transform such that the pipette tip is located at the global position pos.

This method is for recalibration; it does not physically move the device.

retractFromSurface(speed='slow') Future[source]

Retract the pipette along its axis until it is above the slice surface.

saveCalibration()[source]
saveManualTipPosition(stack=True, _future=None)[source]
savePosition(name, pos=None)[source]

Store a position in global coordinates for later use.

If no position is provided, then the current position of the pipette tip is used.

scopeDevice()[source]
setNewPipetteTipOffsetIfAcceptable(pos, _future=None)[source]

Returns whether the tip position was saved. Otherwise, the user requested a re-do.

setOffset(offset)[source]
setTarget(target)[source]
setTipOffset(pos)[source]

Given a global position, set the offset such that the pipette tip is located at that position.

setTipOffsetIfAcceptable(pos, _future=None)[source]
sigCalibrationChanged

pyqtSignal(*types, name: str = …, revision: int = …, arguments: Sequence = …) -> PYQT_SIGNAL

types is normally a sequence of individual types. Each type is either a type object or a string that is the name of a C++ type. Alternatively each type could itself be a sequence of types each describing a different overloaded signal. name is the optional C++ name of the signal. If it is not specified then the name of the class attribute that is bound to the signal is used. revision is the optional revision of the signal that is exported to QML. If it is not specified then 0 is used. arguments is the optional sequence of the names of the signal’s arguments.

sigMoveFinished

pyqtSignal(*types, name: str = …, revision: int = …, arguments: Sequence = …) -> PYQT_SIGNAL

types is normally a sequence of individual types. Each type is either a type object or a string that is the name of a C++ type. Alternatively each type could itself be a sequence of types each describing a different overloaded signal. name is the optional C++ name of the signal. If it is not specified then the name of the class attribute that is bound to the signal is used. revision is the optional revision of the signal that is exported to QML. If it is not specified then 0 is used. arguments is the optional sequence of the names of the signal’s arguments.

sigMoveRequested

pyqtSignal(*types, name: str = …, revision: int = …, arguments: Sequence = …) -> PYQT_SIGNAL

types is normally a sequence of individual types. Each type is either a type object or a string that is the name of a C++ type. Alternatively each type could itself be a sequence of types each describing a different overloaded signal. name is the optional C++ name of the signal. If it is not specified then the name of the class attribute that is bound to the signal is used. revision is the optional revision of the signal that is exported to QML. If it is not specified then 0 is used. arguments is the optional sequence of the names of the signal’s arguments.

sigMoveStarted

pyqtSignal(*types, name: str = …, revision: int = …, arguments: Sequence = …) -> PYQT_SIGNAL

types is normally a sequence of individual types. Each type is either a type object or a string that is the name of a C++ type. Alternatively each type could itself be a sequence of types each describing a different overloaded signal. name is the optional C++ name of the signal. If it is not specified then the name of the class attribute that is bound to the signal is used. revision is the optional revision of the signal that is exported to QML. If it is not specified then 0 is used. arguments is the optional sequence of the names of the signal’s arguments.

sigTargetChanged

pyqtSignal(*types, name: str = …, revision: int = …, arguments: Sequence = …) -> PYQT_SIGNAL

types is normally a sequence of individual types. Each type is either a type object or a string that is the name of a C++ type. Alternatively each type could itself be a sequence of types each describing a different overloaded signal. name is the optional C++ name of the signal. If it is not specified then the name of the class attribute that is bound to the signal is used. revision is the optional revision of the signal that is exported to QML. If it is not specified then 0 is used. arguments is the optional sequence of the names of the signal’s arguments.

startRecording()[source]

Return an object that records all motion updates from this pipette

stepwiseAdvance(depth: float | None = None, target: ndarray | None = None, speed: float = 1e-05, interval: float = 5, step: float = 1e-06, name: str | None = None, _future=None)[source]

Retract/advance in small steps, allowing for manual user movements.

Parameters

depthfloat | None

The target depth (in global coordinates) to advance to.

targetnp.ndarray | None

If specified, the pipette will advance toward this target position instead of the specified depth. The target should be in global coordinates.

speedfloat

The speed (in m/s) to use for the movement.

intervalfloat

The time (in seconds) to wait between steps.

stepfloat

The step size (in meters) to use for each advance.

stop()[source]
targetPosition()[source]
tipOffsetIsReasonable(pos) bool[source]
wiggle(speed, radius, repetitions, duration, pipette_direction=None, extra=None, _future=None)[source]
yawAngle()[source]

Return the yaw (azimuthal angle) of the electrode around the Z-axis in degrees.

Value is returned in degrees such that an angle of 0 indicate the tip points along the positive x axis, and 90 points along the positive y axis.

yawRadians()[source]

The Pipette device represents a pipette or electrode attached to a motorized manipulator, providing camera module interface capabilities for visual control and automated positioning.

Features

  • Visual Control: Camera module interface for visually directing pipette tip

  • Automatic Alignment: Align pipette tip for diagonal approach to cells

  • Tip Calibration: Automatic calibration of pipette tip position via tracking

  • Path Planning: Intelligent movement planning to avoid obstacles

  • Tip Detection: Computer vision-based pipette tip detection and tracking

Configuration

The Pipette device must be configured with a Stage as its parent device.

Required configuration options:

  • pitch (float or ‘auto’): The angle of the pipette in degrees relative to horizontal plane Positive values point downward

  • parentDevice (str): Name of the Stage device controlling the manipulator

Optional configuration:

  • searchHeight (float): Height above focal plane to search for pipette tip (default: 200e-6 m)

  • searchRegion (tuple): (width, height) of search region in meters (default: (500e-6, 500e-6))

  • approachAngle (float): Angle for diagonal approach in degrees (default: 45)

Example configuration:

Pipette1:
    driver: 'Pipette'
    parentDevice: 'Manipulator1'
    pitch: 15.0  # degrees downward from horizontal
    searchHeight: 200e-6
    searchRegion: [500e-6, 500e-6]
    approachAngle: 45.0

Coordinate System

The local coordinate system is configured such that:

  • X axis: Points in the direction of the pipette tip

  • Z axis: Points upward (same as global +Z)

  • Y axis: Perpendicular to both X and Z

Camera Module Integration

The Pipette device provides a camera module interface that allows:

  • Visual targeting of cells and structures

  • Real-time tip position feedback

  • Interactive movement control

  • Automated approach sequences

Path Planning

The device includes sophisticated path planning capabilities:

  • Obstacle avoidance during movements

  • Optimized trajectory calculation

  • Safe retraction paths

  • Collision detection with other devices

Tip Detection and Tracking

Uses computer vision algorithms to:

  • Automatically detect pipette tip location

  • Track tip position during movements

  • Calibrate tip position relative to manipulator coordinates

  • Provide visual feedback on tip status

Dependencies

  • Stage device (parent manipulator)

  • Camera device (for visual feedback)

  • Optional: Recording chamber for coordinate reference