Holypipette¶
Contents¶
User manual¶
Manipulator selection¶
Select the current manipulator with numbers (1, 2).
Ranges of axes¶
To measure the range (minimum and maximum) of the axes of the unit and microscope, type M, then move the unit axes and microscope Z to all limit positions (min and max for all axes). This can be done for example by moving to two opposite corners. The same must be done for all units and for the XY stage. For the XY stage, note that the calibration process uses the camera and therefore it must be checked that not only the positions are reachable, but that the image is also acceptable (in particular, there must be light). Type M again to end the measurement process.
Calibration¶
The coordinate systems of the XY stage and manipulators must be matched to the coordinate system of the camera and microscope. This operation is called calibration. The way it works is by matching photos of the pipette tip. Thus, it is very important that the image is clean and sharp at all positions reached by the calibration procedure.
Mount a pipette on the manipulator. In principle, any object could be used, the main requirement being that it should be sharp and with a good contrast when seen under the microscope.
Put water on the coverslip, as much as possible.
Move the microscope as high as possible. If it is an immersion objective, move it up as much as possible while remaining immersed. If it is not an immersion objective, focus on the top of the water drop.
Move the pipette manually with the tip in focus, in the center of field.
Run the calibration (key: C). The program will first move the XY stage, then move each axis of the unit. If the unit is mounted on the stage, it will also make compensatory movements with the stage when the unit is moved beyond the field of view.
The calibration runs a maximum number of calibration_moves
exponential moves,
which consist in a sequence of movements of the axis, each movement being twice
larger than the previous one, with a minimum distance equal to half
stack_depth
.
The program also stops if the next movement would not be reachable by the axes,
or if it would go beyond the minimum vertical position (Z).
The minimum vertical position for the microscope or floor can be set with
key F. It has not been set, then the program chooses 300 um below the current position.
Initially, minimum and maximum ranges of axes are not set, which means that all
positions are considered reachable.
Save the calibration with Ctrl+S.
Secondary calibration¶
When the pipette is changed, or if the pipette appears to be miscalibrated, for example after a large movement, then the pipette should be recalibrated. The idea is that the axis angles should be stable but there can be a shift (translation) in the coordinate systems. To recalibrate, move the pipette in focus and right click on the tip.
Manipulators¶
Hardware control¶
Manipulators are groups of motorized axes, typically an XY stage or an XYZ unit.
The basic class is a ManipulatorUnit
, which depends on a controller. The controller is
a set of axes that can be moved independently (for example the Luigs and Neumann controller, which
controls up to 9 axes).
Example:
controller = LuigsNeumann_SM10()
stage = ManipulatorUnit(controller, [7, 8])
A ManipulatorUnit
can be moved with relative or absolute displacements expressed in µm.
Calibrated units¶
Calibrated units are manipulator units that can be moved in the coordinate system of the camera, called
the reference system.
A CalibratedUnit
must be associated to a camera, a microscope Z axis, and can be attached to an XY stage.
A CalibratedStage
is a special kind that a horizontal XY stage (i.e., to be parallel to the focal plane of the
microscope).
Examples:
calibrated_stage = CalibratedStage(stage, microscope=microscope, camera=camera)
XYZ = CalibratedUnit(unit, calibrated_stage, microscope, camera=camera)
The position in the camera system is given by \({\bf M}\cdot{\bf u} + {\bf r}_0 + {\bf r}_S\), where \({\bf u}\) is the position of the manipulator axes, \({\bf r}_S\) is the position of the stage in the reference system to which the manipulator is attached, \({\bf M}\) is coordinate change matrix and \({\bf r}_0\) is an offset.
Movement algorithms¶
Reference move¶
The basic move is a reference_move
. It simply inverts the matrix relation to find the
target position in the coordinate system of the manipulator coordinates.
However, this is not as simple as it sounds. For some manipulators (including Luigs and Neumann),
the resulting displacement is not necessarily a straight line because each axis has a fixed speed independent
of the movement. This can result in a broken trajectory; first a diagonal move then a move in the remaining
directions. As a result, the pipette could collide with the coverslip or other problems.
To avoid this problem, the method has a safe
option. If True, the method first determines whether the
the third axis, which is assumed to be Z, will be moved up or down (see calibration algorithms).
If it is going up, then this axis is moved first; otherwise it is moved last. This simple algorithm
maximizes the minimum altitude of the trajectory, so as to avoid colliding with the coverslip.
This is only done with absolute moves and not relative moves.
Withdraw¶
The withdraw
method moves the first axis to its upper endpoint. This presupposes that the two endpoints
have been previously identified.
Focus¶
The focus
method moves the microscope Z axis so that the tip is in focus. This does not use an autofocus
but rather the calibration system (so the manipulator must be correctly calibrated for this to work).
Safe move¶
The safe_move
method moves the manipulator to a target point, with a trajectory that aims at minimizing
mechanical interaction with the tissue. It also essentially removes the pipette from the field of view during the
approach, which could be helpful if tracking the cell.
If the movement is up, a normal movement is done (with the safe
option). If it is down, then the trajectory
is more complex. First, the manipulator is moved horizontally, then along the first axis of the manipulator.
Note that by horizontally, it is meant that the start and end positions are on the same horizontal plane, but
the trajectory does not necessarily remain in that plane for reasons explained above; thus the
safe
option is also used.
If the recalibrate
option is True
and the movement is at least 500 µm, then the program tries to fix
errors in calibration before the target. To this end, the manipulator stops 50 µm before the target,
then focus on the tip, automatically recalibrate (see below), then move the focus back, and finish the movement.
Moving a new pipette in the field¶
This is not fully tested code. The move_new_pipette_back
method moves a new pipette into the field.
This assumes that the calibration is right, except for an offset (due e.g. to the length and slightly different
geometry of the pipette). The algorithm is as follows:
Move the pipette 2 mm before target position (in the direction of the first axis), which is the center of the microscope view.
Take 10 photos at 10 Hz.
Calculate the mean standard deviation of the images (more or less the contrast).
Move the pipette down by 100 µm along the axis.
If the standard deviation of the image differs by at least 20% from the mean calculated previously, stop.
Otherwise, go to 4; stop at 5 mm.
In practice, if the pipette is cleaned, this method might not be that useful.
Move and track¶
The move_and_track
is used by calibration algorithms. It moves the pipette along one axis,
then focus the microscope on the tip using calculation and then template matching. Optionally,
it also moves the stage to center the tip. The final image is focused on the tip, but the tip
is not necessarily in the center (depending on the precision of calibration).
Finally, it returns the position of the tip on screen and focal plane.
Move back¶
The move_back
method is used by calibration algorithms.
It moves the microscope, manipulator and stage to a given position (previously stored), in
a certain order that is intended to avoid collisions.
First, the microscope is moved (normally, up), then the manipulator, then the stage.
The pipette is then back at the initial position, which is supposed to be in focus in the center
of view. Then the pipette is located and refocused, and the pipette position and focal plane are
returned.
Calibration algorithms¶
Calibration consists in determining the matrix \({\bf M}\) and the offset \({\bf r}_0\), as well as whether the axes go up or down (in Z) in the positive direction.
Recalibration¶
This assumes that the manipulator is correctly calibrated, except for an offset.
The method recalibrate
updates \({\bf r}_0\) assuming that the tip is in the center of view
(red cross), or at the given (x,y) position on screen if provided (right-click on the standard
interface).
Stage calibration¶
The stage is assumed to be horizontal, and thus the Z axis of the microscope is not moved. It is assumed that there is an object in focus in the field of view, attached to the stage (pipette, or coverslip). Algorithm:
Take a photo of the center of the field: this is the template.
Move the first axis by 40 µm, and locate the template in the image: deduce the first column of \({\bf M}\).
Repeat for the second axis.
Using the first estimate of \({\bf M}\), move to each of three corners of the image (top left, top right, bottom left), with a safety margin, and locate the template.
Calculate \({\bf M}\) again based on these three points.
Manipulator calibration¶
This is the calibrate
method, plus a number of methods that it calls.
The tip must be in focus at the center of view.
Initial steps
Calibrate the stage to which it is attached.
Take photos of the pipette along the Z axis of the microscope, every 1 µm over distance
stack_depth
(positive and negative).
First estimate
Move and track the first axis by a distance equal to half the
stack_depth
. As initially the matrix is zero, there is no predictive move of the focus.Repeat for each axis.
Calculate the matrix.
Go back to the initial position.
This first very crude estimate is used to calculate the vertical direction of the axes.
Up directions
This is done in method calculate_up_directions
. It takes the matrix and estimates
for each axis whether a positive movement makes the pipette go up or down.
Then the minimum reachable Z (coverslip) is determined as 300 µm below the current position,
unless it has been specified explicitly (floor position).
Calibration
Each axis is calibrated in turn. For each axis:
Double the movement amplitude.
Check whether the movement is reachable (which presupposes that ranges have been set).
Estimate whether the movement will make the pipette move out from the field of view.
Move the pipette and track, and move the stage to compensate if the pipette is out of field.
Calculate the relevant column of \({\bf M}\), based on camera positions before and after the movement.
Repeat
calibration_moves
times.Move back to the initial position.
Calculate the relevant column of \({\bf M}\), based on camera positions before and after the movement.
Thus, only the last movement (which is the largest one) is actually used to calculate the matrix.
Manual calibration¶
The manual_calibration
method takes 4 points chosen by the user, and deduce the matrix
from them.
Automatic recalibration¶
Locate the pipette over a depth of +-25 µm, using templates and movements of microscope Z.
Update the offset \({\bf r_0}\) (recalibration).
With option
center
, move the stage and focus so that the pipette tip is centered.
Pressure control¶
Holy Pipette can control a pressure controller.
Classes inherit the PressureController
class, which implements
three methods. Currently only Elveflow’s OB1
controller is implemented.
Example:
controller = OB1()
controller.set_pressure(25, port = 0)
pressure = controller.measure(port = 0)
controller.ramp(amplitude = -100., duration = 1., port = 0)
Pressure is mBar.
Fake pressure controller¶
For development purposes, a FakePressureController
is implemented.
It behaves as a pressure controller, except it is not connected to an actual device.
Amplifiers¶
We currently only deal with the Multiclamp 700B.
Automatic patch clamp¶
These are automatic patch clamp algorithms adapted from the literature.
Main patch clamp algorithm¶
Amplifier start-up (on Multiclamp 700B):
Voltage-clamp.
Disable resistance metering and pulses.
Compensate pipette (slow and fast).
Set pulse amplitude and frequency (default 1e-2 and 1e-2, units unclear).
Set zap duration at 1 ms.
Do pipette offset (V=0).
Set holding potential V = 0.
Enable resistance metering (triggers voltage pulses).
Resistance check:
1. Set pressure at pressure_near
(>0).
2. Do pipette offset (V=0) and wait for 4 s.
3. Check that the resistance is within specified bounds.
Approach:
Move the manipulator with a safe move to a distance
cell_distance
above the target position, if specified.Do pipette offset and wait for 2 s.
Check that resistance has not increased by
1+cell_R_increase
.Move down by 1 µm and wait for 1 s (maximum total movement
max_distance
).Measure R. Unless R has increased by
1+cell_R_increase
, repeat (7).
Sealing:
Release the pressure and wait for 10 s.
If R is smaller than
1+cell_R_increase
timesR
: go back to approach (7). Note that pressure is now released.Set pressure at
pressure_sealing
(<0).If
R>gigaseal_R
: success (next stage).Ramp V down to
Vramp_amplitude
(default -70 mV) over durationVramp_duration
.Wait for at least
seal_min_time
, and untilR>gigaseal_R
(success) or time is out (seal_deadline
) (failure).Success or failure: release pressure.
Break-in:
If
R<gigaseal_R
: failure (seal lost).Increase max pressure by
pressure_ramp_increment
; fail if greater thanpressure_ramp_max
.If
zap
is True, do an electric zap.Do a pressure ramp up to max pressure, of duration
pressure_ramp_duration
; wait for 1.3 s.If
R<max_cell_R
: success.
Ending (also if stopped in the middle):
Stop the amplifier: disable resistance metering and pulses; current-clamp.
Set the pressure at
pressure_near
(>0).
Developer guide¶
Code structure¶
The code has been separated into a “backend” part and a “frontend” part.
The backend part controls the hardware and implements the algorithms, e.g. what to
do to perform a patch clamp on a cell. This code has been written without using
any reference to Qt
and can therefore be reused in simple scripts or in
interactive use for testing. However, the use of certain provided functions
makes it possible to tightly integrate the code with the GUI, most importantly
by making long-running tasks interruptable. For more information, see
Adding new low-level functionality below.
The frontend is written based on the Qt
libraries which not only provides the
graphical user interface (GUI) but also tools to run things in separate threads
and communicate via signals.
This basic structure is summarized in the figure below, showing the names of a few of the most important classes:
GUI classes (first column)¶
These classes provide the main window the user interacts with. It also defines
how the available commands defined in the interfaces (see below) are exposed,
e.g. via a Key press or a mouse click. See Exposing existing functionality in the GUI below for
more details. GUIs that show the camera image should inherit from
CameraGui
which not only provides the GUI for the basic camera image but also
an automatic help window, based on the configured mouse/key-bindings, and a
viewer for the log file. GUIs that want to expose control of the
micromanipulators should inherit from ManipulatorGui
(which itself inherits
from CameraGui
). Finally, the PatchGui
supports semi-automatic patch-clamp
recordings and itself inherits from ManipulatorGui
.
Interface classes (second column)¶
The interface classes provide the link between the GUI and the actual operations
defined in the controllers (see below). They all inherit from the
TaskInterface
class and declare and launch commands. Each command has to be
implemented in a method and annotated with either the @command
or
the @blocking_command
decorator. Non-blocking commands
(@command
) are straightforward, short commands that have a direct
effect and should be executed from within the main thread. A typical example
would be a change in the exposure time of the camera, or storing the current
position of the microscope or the manipulators. Blocking commands
(@blocking_command
) are commands that potentially take a
long time, such as moving the manipulators to a certain position, and should
not be interfered with. For example, during the movement of the manipulator all
other commands to move the manipulator should be ignored. To handle starting and
ending (potentially by a user abort) of such tasks correctly, the actual task
has to be implemented in one or several methods of a TaskController
(see
below). This method should not be called directly, but instead be called via
TaskInterface.execute
which will take care of handling errors and signalling
the completion of the task. For more details on this, see
Adding new low-level functionality below.
Controller classes (third column)¶
These classes implement the actual tasks by calling the device classes (see
below), e.g. by stating that to patch, the cell has to move down until the
resistance changes, then set a negative pressure, etc. These classes should be
independent from the GUI (e.g. not rely on any Qt
classes) so that they can
be used without it. However, they should inherit from the TaskController
class and make use of its logging methods (debug
,
info
, etc.). By using these methods, messages will not only
use the general logging system, but also automatically check back whether the
user requested the task to be aborted and handle this situation. For more
details, see Adding new low-level functionality below.
Device classes (fourth column)¶
These classes expose the hardware functionality in a generic interface, so that
hardware can be exchanged without having to change code in the controller
classes (see above). By being built on generic classes, actual hardware can also
replaced by “fake” devices useful for development. For example, the generic
Camera
class states that all cameras have a Camera.snap
function that
returns the latest camera image. The FakeCamera
inherits from this class and
provides an implementation that returns an artificially generated camera image,
while the uManagerCamera
provides an implementation that returns an actual
microscope image via the MicroManager software.
Adding functionality¶
In the following, we describe how to add various kinds of functionality to existing or newly written classes.
Post-processing the camera image¶
In GUIs inherting from CameraGui
(which uses the LiveFeedQt
widget to
display the camera image), “image edit functions” can be used to post-process
the camera image. To add such a function, either call CameraGui
’s
__init__
function with your post-processing function (or a list of
such functions) as an argument to its image_edit
argument, or append to the
list stored in image_edit_funcs
afterwards. The post-processing
function or method should take a single argument, the image as a numpy array,
and return the post-processed image. Such post-processing functions should only
be used to change the image in a way that needs the actual image information;
image-independent information that should simply be displayed on top should use
the mechanism described in Displaying information overlaid on the camera image below.
As an example, consider the following autoscale method that scales the
contrast of the image to span the full range. It can be implemented in a class
inheriting from CameraGui
as follows:
def autoscale(self, image):
# This assumes a 2D array, i.e. no colors
if np.issubdtype(image.dtype, np.integer):
info = np.iinfo(image.dtype)
total_min, total_max = info.min, info.max
else:
total_min, total_max = 0.0, 1.0
min_val, max_val = image.min(), image.max()
range = (max_val - min_val)
# Avoid overflow issues with integer types
float_image = np.array(image, dtype=np.float64)
new_image = (total_max - total_min)*(float_image - min_val)/range + total_min
return np.array(new_image, dtype=image.dtype)
def __init__(self, camera, ...):
super(..., self).__init__(camera, image_edit=self.autoscale)
Warning
Post-processing functions should not change the size and dtype of the image array, other code might directly asks the camera for the size of the video image and then e.g. scale overlays accordingly.
Displaying information overlaid on the camera image¶
Similar to the image post-processing functions described above, classes
inheriting from CameraGui
can define “display edit functions” which can
directly draw on top of the camera image. In the same way as for the image
post-processing functions, such functions can be added by either providing them
as a display_edit
argument to CameraGui.__init__
or by appending to its
display_edit_funcs
attribute. Note that the former will overwrite
CameraGui
’s default overlay, i.e. the cross at the middle of the screen. The
overlay function receives a QPixmap
object and can paint on it using a
QPainter
. It should probably use some transparency to not cover the camera
image completely. As an example, the following, admittedly not very useful, code
will add a semi-transparent vertical blue line and write “left” and “right” in
its two halves:
def show_halves(self, pixmap):
painter = QtGui.QPainter(pixmap)
pen = QtGui.QPen(QtGui.QColor(0, 0, 200, 125)) #blue, semi-transparent
pen.setWidth(4)
painter.setPen(pen)
c_x, c_y = pixmap.width() / 2, pixmap.height() / 2
painter.drawLine(c_x, 0, c_x, pixmap.height())
painter.drawText(c_x / 2, c_y, 'left')
painter.drawText(c_x + c_x / 2, c_y, 'right')
painter.end()
def __init__(self, camera, ...):
super(..., self).__init__(camera)
self.display_edit_funcs.append(self.show_halves)
Adding information to the status bar¶
The status bar in all GUIs inheriting from CameraGui
automatically shows
long-running tasks or success/failure messages on its left. In principle, GUI
code (i.e. code running in the main thread) could show other temporary messages
there by calling the showMessage
function of CameraGui
’s
status_bar
attribute. The status bar also shows permanent messages
on the bottom right, e.g. which micromanipulator is currently in use. A class
can add additional information there by calling CameraGui.set_status_message
which takes a category and a message as its argument. If this function is called
again with a new message for the same category, the previous message will be
overwritten. Such an update can be triggered regularly by using a
QTimer()
. For example, the following code will update the currently
use zoom factor every second by comparing the size of the displayed image
(in pixels) with the size of the camera image (a better solution for this use
case would be to have this update triggered by a size change instead of with a
regular timer).
def __init__(self, camera, ...):
super(..., self).__init__(camera)
...
self.zoom_timer = QtCore.QTimer()
self.zoom_timer.timeout.connect(self.set_zoom_status)
self.zoom_timer.start(1000)
def set_zoom_status(self):
display_size = self.video.pixmap().width()
image_size = self.camera.width
zoom = 1.0*display_size/image_size
self.set_status_message('Zoom', 'Zoom: {:3.0f}%'.format(zoom*100))
Exposing existing functionality in the GUI¶
If a functionality has been defined in the interface class (see
Interface classes (second column) above, and Adding new low-level functionality below), it
can be exposed in the GUI. There are two standard methods which also take care
of integrating the function with the automatic help window:
register_key_action
and register_mouse_action
. By
convention, these functions should be called in an overwritten version of
CameraGui.register_commands
(which should normally call the parent
implementation). The first two arguments of these are the key (as a Qt
constant, e.g. Qt.Key_X
), respectively the mouse button (e.g.
Qt.RightButton
) and the modifier. The modifier can either be a
Qt
constant such as Qt.ShiftModifier
to only trigger the action if the
modifier is pressed, or None
if the action should be triggered independent
of the modifier. The modifier Qt.NoModifier
should be used if the action
should only by triggered if the key or mouse button is pressed without any
modifier.
Warning
Do not use Qt.KeypadModifier
, it will be automatically removed from the
key event, in particular to avoid problems on OS X where all number key
presses carry this modifier.
The third argument is the action to trigger, this should be a method of a
TaskInterface
annotated with @command
or
@blocking_command
(see Interface classes (second column)). Key
actions can take an additional argument
, this can be used to perform a
parametrized action, e.g. a move of a given size. Functions that are triggered
by mouse clicks automatically receive the mouse position in the camera image
(i.e. rescaled and independent of the window size on screen) as an argument.
Finally, the optional default_doc
argument can be set to False
to not
automatically document the action in the Help window. This can be useful when
registering many similar commands (e.g. moves of different directions/sizes);
they can be summarized with fewer custom help entries by calling
KeyboardHelpWindow.register_custom_action
.
Adding new low-level functionality¶
Low-level functionality should be added in a TaskController
class. Such
classes should not use any Qt
-specific code, i.e. should stay independent
of the GUI. However, they should make use of the logging functions such as
debug
and info
, which will automatically
check for user-requested cancellations of a running task. Similarly, a task that
needs to wait (e.g. for a manipulator that is still moving), should use the
TaskController.sleep
method instead of Python’s standard sleep
.
After adding such functionality, it should be exposed in the TaskInterface
by
adding a method annotated with @command
or
@blocking_command
(see Interface classes (second column)). Finally,
this method can then be linked to a keypress or a mouse click in the GUI (see
Exposing existing functionality in the GUI).
API reference¶
holypipette package¶
Subpackages¶
holypipette.controller package¶
Package defining TaskController
classes. Objects of these classes are
responsible for the high-level logic of controlling the hardware, e.g. dealing
with the calibration of a manipulator, or defining the procedure for an
automatic patch clamp experiment.
Submodules¶
holypipette.controller.base module¶
Module defining the TaskController
class.
- exception holypipette.controller.base.RequestedAbortException[source]¶
Bases:
Exception
Exception that should be raised when a function aborts its execution due to
abort_requested
.
- class holypipette.controller.base.TaskController[source]¶
Bases:
LoggingObject
Base class for objects that control the high-level logic to control the hardware, e.g. the calibration of a manipulator or the steps to follow for a patch clamp experiment. Objects will usually be instantiated from more specific subclasses.
The class provides several convenient ways to interact with an asynchronously requested abort of the current task. A long-running task can check explicitly whether an abort has been requested with
abort_if_requested
which will raise aRequestedAbortException
if theabort_requested
attribute has been set. This check will also be performed automatically ifdebug
,info
, orwarn
is called (which otherwise simply forward their message to the logging system). Finally, tasks should callsleep
(instead oftime.sleep
) which will periodically check for an abort request during the sleep time.- abort_if_requested()[source]¶
Checks for an abort request and interrupts the current task if necessary. Can be explicitly called during long-running tasks, but will also be called automatically by the logging functions
debug
,info
,warn
, or the wait functionsleep
. :raises RequestedAbortException: If theabort_requested
attribute is set
- delete_state()[source]¶
Delete any previously saved state. By default, overwrites the
saved_state
attribute withNone
.
- has_saved_state()[source]¶
Whether this object has a saved state that can be recovered with
recover_state
.- Returns:
has_state – Whether this object has a saved state. By default, checks whether the
saved_state
attribute is notNone
.- Return type:
- recover_state()[source]¶
Recover the state (e.g. the position of the manipulators) after a failure or abort. Has to be overwritten in subclasses.
- save_state()[source]¶
Save the current state (e.g. the position of the manipulators) for later recovery in the case of a failure or abort. Has to be overwritten in subclasses. Should save the state to the
saved_state
variable or overwritehas_saved_state
as well.
- sleep(seconds)[source]¶
Convenience function that sleeps (as
time.sleep
) but remains sensitive to abort requests
- holypipette.controller.base.check_for_abort(obj, func)[source]¶
Decorator to make a function raise a
RequestedAbortException
ifabort_requested
attribute is set.
holypipette.controller.paramecium_device module¶
- class holypipette.controller.paramecium_device.ParameciumDeviceController(calibrated_unit, microscope, calibrated_stage, camera, config)[source]¶
Bases:
TaskController
holypipette.controller.paramecium_droplet module¶
- class holypipette.controller.paramecium_droplet.ParameciumDropletController(calibrated_unit, microscope, calibrated_stage, camera, config)[source]¶
Bases:
TaskController
holypipette.controller.patch module¶
- class holypipette.controller.patch.AutoPatcher(amplifier, pressure, calibrated_unit, microscope, calibrated_stage, config)[source]¶
Bases:
TaskController
holypipette.devices package¶
Subpackages¶
holypipette.devices.amplifier package¶
Submodules¶
holypipette.devices.amplifier.amplifier module¶
- class holypipette.devices.amplifier.amplifier.Amplifier[source]¶
Bases:
TaskController
Base class for amplifiers.
- set_zap_duration(duration)[source]¶
Set the duration for the
zap
. :Parameters: duration (float) – Duration of the zap in seconds.
- class holypipette.devices.amplifier.amplifier.FakeAmplifier[source]¶
Bases:
Amplifier
“Fake” amplifier that only notes down changes/commands
- set_holding(value)[source]¶
Set holding voltage or current
- Parameters:
value (float) – Holding voltage or current
- set_zap_duration(duration)[source]¶
Set the duration for the
zap
. :Parameters: duration (float) – Duration of the zap in seconds.
holypipette.devices.amplifier.axoclamp900A_gui module¶
holypipette.devices.amplifier.multiclamp module¶
### Ported from Clamper ## configure_board and acquire() are unused here
Basic Interface to the MultiClamp 700A and 700B amplifiers.
Note that the MultiClamp Commander has to be running in order to use the device.
For each of the two channels, we have: * command (I or V) * primary * secondary * scope There is also a scope trigger (in the rear)
Gains: actually these are additional gains
- class holypipette.devices.amplifier.multiclamp.MultiClamp(*channels)[source]¶
Bases:
object
Device representing a MultiClamp amplifier with two channels or more.
- Parameters:
channels – List of MultiClamp channels. If none, a single 2-channel Multiclamp is assumed.
- acquire(*inputs, **outputs)[source]¶
Send commands and acquire signals.
- Parameters:
inputs – A list of input variables to acquire. From: V1, I1, Ve1, V2, I2, etc (electrode potential)
outputs – A dictionary of commands. From: V1, I1, V2, I2…
- configure_board(theboard, primary=None, secondary=None, command=None)[source]¶
Configure an acquisition board.
- Parameters:
primary – A list of names of connections on the board for the primary signal, for each channel.
secondary – A list of names of connections on the board for the secondary signal, for each channel.
command – A list of names of connections on the board for the command signal, for each channel.
- class holypipette.devices.amplifier.multiclamp.MultiClampChannel(**kwds)[source]¶
Bases:
Amplifier
Device representing a MultiClamp amplifier channel (i.e., one amplifier with two channels is represented by two devices).
- Parameters:
kwds – Enough information to uniquely identify the device. If there is a single device, no information is needed. If there is a single amplifier with two channels, only the channel number (e.g.
channel=1
) is needed. If there are multiple amplifiers, they can be identified via their port/ device number (700A) or using their serial number (700B).
- acquire(*inputs, **outputs)[source]¶
Send commands and acquire signals.
- Parameters:
inputs – A list of input variables to acquire. From: V, I, Ve (electrode potential) A maximum of two inputs.
outputs – A dictionary of commands. From: V, I. Only one command!
- all_devices = None¶
- check_error(fail=False)[source]¶
Check the error code of the last command.
- Parameters:
fail (bool) – If
False
(the default), any error will give rise to a warning; ifTrue
, any error will give rise to anIOError
.
- configure_board(theboard, primary=None, secondary=None, command=None)[source]¶
Configure an acquisition board.
- Parameters:
primary – A connection name on the board for the primary signal.
secondary – A connection name on the board for the secondary signal.
command – A connection name on the board for the command signal.
- dll_path = 'C:\\Program Files\\Molecular Devices\\MultiClamp 700B Commander\\3rd Party Support\\AxMultiClampMsg'¶
- find_amplifiers()[source]¶
Return a list of all amplifier devices (each described by a dictionary, see
_identifiy_amplifier
).- Returns:
amplifiers – A list of all detected amplifier devices.
- Return type:
list of dict
- select_amplifier()[source]¶
Select the current amplifier (will be called automatically when executing command such as
MultiClamp.voltage_clamp
.
- selected_device = None¶
- set_zap_duration(duration)[source]¶
Set the duration for the
zap
. :Parameters: duration (float) – Duration of the zap in seconds.
holypipette.devices.camera package¶
Submodules¶
holypipette.devices.gamepad package¶
Submodules¶
holypipette.devices.gamepad.gamepad module¶
holypipette.devices.manipulator package¶
Submodules¶
holypipette.devices.manipulator.calibratedunit module¶
A class to handle a manipulator unit with coordinates calibrated to the reference system of a camera. It contains methods to calibrate the unit.
Should messages be issued? Also ranges should be taken into account
Should this be in devices/ ? Maybe in a separate calibration folder
- class holypipette.devices.manipulator.calibratedunit.CalibratedStage(unit, stage=None, microscope=None, camera=None, config=None)[source]¶
Bases:
CalibratedUnit
A horizontal stage calibrated to a fixed reference coordinate system. The optional stage refers to a platform on which the unit is mounted, which can be None. The stage is assumed to be parallel to the focal plane (no autofocus needed)
- Parameters:
unit (ManipulatorUnit for this stage)
stage (CalibratedUnit for a stage on which this stage might be mounted)
microscope (ManipulatorUnit for the microscope (single axis))
camera (a camera, ie, object with a
snap()
method (optional, for visual calibration))
- equalize_matrix(M=None)[source]¶
Equalizes the length of columns in a matrix, by default the current transformation matrix
- mosaic(width=None, height=None)[source]¶
Takes a photo mosaic. Current position corresponds to the top left corner of the collated image. Stops when the unit’s position is out of range, unless width and height are specified.
- Parameters:
width (total width in pixel (optional))
height (total height in pixel (optional))
- Return type:
A large image of the mosaic.
- class holypipette.devices.manipulator.calibratedunit.CalibratedUnit(unit, stage=None, microscope=None, camera=None, config=None)[source]¶
Bases:
ManipulatorUnit
- auto_recalibrate(center=True)[source]¶
Recalibrates the unit by shifting the reference frame (r0). The pipette is visually identified using a stack of photos.
- Parameters:
center (if True, move stage and focus to center the pipette)
- calculate_up_directions(M)[source]¶
Calculates up directions for all axes and microscope from the matrix.
- calibrate(rig=1)[source]¶
Automatic calibration. Starts without moving the stage, then moves the stage (unless it is fixed).
- calibrate2()[source]¶
Automatic calibration. Second algorithm: moves along axes of the reference system.
- delete_state()[source]¶
Delete any previously saved state. By default, overwrites the
saved_state
attribute withNone
.
- equalize_matrix(M=None)[source]¶
Normalizes the transformation matrix so that each column corresponds to a 1 um move. By default the current transformation matrix is used. This requires a calibrated stage.
- load_configuration(config)[source]¶
Loads configuration from dictionary config. Variables not present in the dictionary are untouched.
- locate_pipette(threshold=None, depth=None, return_correlation=False)[source]¶
Locates the pipette on screen, using photos previously taken.
- Parameters:
threshold (correlation threshold)
depth (maximum distance in z to search; if None, only uses the depth of the photo stack)
return_correlation (if True, returns the best correlation in the template matching)
- Returns:
x,y,z
- Return type:
position on screen relative to center
- manual_calibration(landmarks)[source]¶
Calibrates the unit based on 4 landmarks. The stage must be properly calibrated.
- move_and_track(distance, axis, M, move_stage=False)[source]¶
Moves along one axis and track the pipette with microscope and optionally the stage.
- Parameters:
distance (distance to move)
axis (axis number)
- Returns:
x,y,z
- Return type:
pipette position on screen and focal plane
- move_back(z0, u0, us0=None)[source]¶
Moves back up to original position, refocus and locate pipette
- Parameters:
z0 (microscope position)
u0 (unit position)
us0 (stage position)
- Returns:
x,y,z
- Return type:
pipette position on screen and focal plane
- normalize_axis(column)[source]¶
Normalizes a column so that it corresponds to a 1 um move. This requires a calibrated stage.
- pixel_per_um(M=None)[source]¶
Returns the objective magnification in pixel per um, calculated for each manipulator axis.
- recalibrate(xy=(0, 0))[source]¶
Recalibrates the unit by shifting the reference frame (r0). It assumes that the pipette is centered on screen.
- recover_state()[source]¶
Recover the state (e.g. the position of the manipulators) after a failure or abort. Has to be overwritten in subclasses.
- reference_move(r, safe=False)[source]¶
Moves the unit to position r in reference camera system, without moving the stage.
- Parameters:
r (XYZ position vector in um)
safe (if True, moves the Z axis first or last, so as to avoid touching the coverslip)
- reference_move_not_X(r, safe=False)[source]¶
Moves the unit to position r in reference camera system, without moving the stage, but without moving the X axis (so this can be done last).
- Parameters:
r (XYZ position vector in um)
safe (if True, moves the Z axis first or last, so as to avoid touching the coverslip)
- reference_move_not_Z(r, safe=False)[source]¶
Moves the unit to position r in reference camera system, without moving the stage, but without moving the Z axis (so this can be done last).
- Parameters:
r (XYZ position vector in um)
safe (if True, moves the Z axis first or last, so as to avoid touching the coverslip)
- reference_position()[source]¶
Position in the reference camera system.
- Return type:
The current position in um as an XYZ vector.
- reference_relative_move(r)[source]¶
Moves the unit by vector r in reference camera system, without moving the stage.
- Parameters:
r (XYZ position vector in um)
- safe_move(r, withdraw=0.0, recalibrate=False)[source]¶
Moves the device to position x (an XYZ vector) in a way that minimizes interaction with tissue.
If the movement is down, the manipulator is first moved horizontally, then along the pipette axis. If the movement is up, a direct move is done.
- Parameters:
r (target position in um, an (X,Y,Z) vector)
withdraw (in um; if not 0, the pipette is withdrawn by this value from the target position x)
recalibrate (if True, pipette is recalibrated 1 mm before its target)
- save_state()[source]¶
Save the current state (e.g. the position of the manipulators) for later recovery in the case of a failure or abort. Has to be overwritten in subclasses. Should save the state to the
saved_state
variable or overwritehas_saved_state
as well.
holypipette.devices.manipulator.fakemanipulator module¶
A fake device useful for development. It has 9 axes, numbered 1 to 9.
- class holypipette.devices.manipulator.fakemanipulator.FakeManipulator(min=None, max=None, angle=25.0)[source]¶
Bases:
Manipulator
holypipette.devices.manipulator.leica module¶
A Z Unit for a Leica microscope, using MicroManager. Communication through serial COM port.
- class holypipette.devices.manipulator.leica.Leica(name='COM1')[source]¶
Bases:
Microscope
- absolute_move(x)[source]¶
Moves the device axis to position x in um.
- Parameters:
axis (this is ignored)
x (target position in um.)
- position()[source]¶
Current position along an axis.
- Parameters:
axis (this is ignored)
- Return type:
The current position of the device axis in um.
holypipette.devices.manipulator.luigsneumann_SM10 module¶
Manipulator class for the Luigs and Neumann SM-10 manipulator controller.
Adapted from Michael Graupner’s LandNSM5 class.
Not all commands are implemented.
- class holypipette.devices.manipulator.luigsneumann_SM10.LuigsNeumann_SM10(name=None, stepmoves=True)[source]¶
Bases:
SerialDevice
,Manipulator
- absolute_move(x, axis, fast=None)[source]¶
Moves the device axis to position x.
- Parameters:
axis (axis number (starting at 1))
x (target position in um.)
speed (optional speed in um/s.)
fast (True if fast move, False if slow move.)
- absolute_move_group(x, axes, fast=None)[source]¶
Moves the device group of axes to position x.
- Parameters:
axes (list of axis numbers)
x (target position in um (vector or list))
fast (True if fast move, False if slow move.)
- position(axis)[source]¶
Current position along an axis.
- Parameters:
axis (axis number (starting at 1))
- Return type:
The current position of the device axis in um.
- position2(axis)[source]¶
Current position along an axis, using the second counter.
- Parameters:
axis (axis number (starting at 1))
- Return type:
The current position of the device axis in um.
- position_group(axes)[source]¶
Current position along a group of axes.
- Parameters:
axes (list of axis numbers)
- Return type:
The current position of the device axis in um (vector).
- relative_move(x, axis, fast=None)[source]¶
Moves the device axis by relative amount x in um.
- Parameters:
axis (axis number)
x (position shift in um.)
fast (True if fast move, False if slow move. None: decide based on distance.)
- relative_move_group(x, axes, fast=None)[source]¶
Moves the device group of axes by relative amount x in um.
- Parameters:
axes (list of axis numbers)
x (position shift in um (vector or list).)
fast (True if fast move, False if slow move. None: decide based on distance.)
- set_ramp_length(axis, length)[source]¶
Sets the ramp length for the chosen axis
- Parameters:
axis (axis number)
length (length between 0 and 16)
- set_single_step_distance(axis, distance)[source]¶
Distance (in um) for
single_step
.
- set_single_step_factor_trackball(axis, factor)[source]¶
Sets the single step factor with the trackball command
- Parameters:
axis (axis number)
factor (single step factor (what is it ??))
- set_single_step_velocity(axis, velocity)[source]¶
Velocity for
single_step
. See table rps_slow.
- single_step(axis, steps)[source]¶
Moves the given axis by a signed number of steps using the StepIncrement or StepDecrement command. Using a steps argument different from 1 (or -1) simply sends multiple StepIncrement/StepDecrement commands. Uses distance and velocity set by
set_single_step_distance
resp.set_single_step_velocity
.
- single_step_trackball(axis, steps)[source]¶
Makes a number of single steps with the trackball command
- Parameters:
axis (axis number)
steps (number of steps)
- step_move(distance, axis=None, maxstep=255)[source]¶
Relative move using steps of up to 255 um. This fixes a bug on L&N controller.
holypipette.devices.manipulator.luigsneumann_SM5 module¶
Manipulator class for the Luigs and Neumann SM-5 manipulator controller.
Adapted from Michael Graupner’s LandNSM5 class.
Not all commands are implemented.
- class holypipette.devices.manipulator.luigsneumann_SM5.LuigsNeumann_SM5(name=None, stepmoves=True)[source]¶
Bases:
SerialDevice
,Manipulator
- absolute_move(x, axis)[source]¶
Moves the device axis to position x. It uses the fast movement command.
- Parameters:
axis (axis number (starting at 1))
x (target position in um.)
speed (optional speed in um/s.)
- absolute_move_group(x, axes)[source]¶
Moves the device group of axes to position x.
- Parameters:
axes (list of axis numbers)
x (target position in um (vector or list).)
- position(axis)[source]¶
Current position along an axis.
- Parameters:
axis (axis number (starting at 1))
- Return type:
The current position of the device axis in um.
- position2(axis)[source]¶
Current position along an axis on the second counter.
- Parameters:
axis (axis number (starting at 1))
- Return type:
The current position of the device axis in um.
- relative_move(x, axis)[source]¶
Moves the device axis by relative amount x in um. It uses the fast command.
- Parameters:
axis (axis number)
x (position shift in um.)
- send_command(ID, data, nbytes_answer, ack_ID='', resends=0)[source]¶
Send a command to the controller
- set_ramp_length(axis, length)[source]¶
Set the ramp length for the chosen axis :param axis: axis which ramp shall be changed :param length: 0<length<=16 :return:
- set_single_step_distance(axis, distance)[source]¶
Distance (in um) for
single_step
.
- set_to_zero_second_counter(axes)[source]¶
Sets the current position of the axes as the zero position on the second counter.
- single_step(axis, steps)[source]¶
Moves the given axis by a signed number of steps using the StepIncrement or StepDecrement command. Using a steps argument different from 1 (or -1) simply sends multiple StepIncrement/StepDecrement commands. Uses distance and velocity set by
set_single_step_distance
resp.set_single_step_velocity
.
holypipette.devices.manipulator.manipulator module¶
Generic Manipulator class for manipulators.
To make a new device, one must implement at least: * position * absolute_move
TODO: * Add minimum and maximum for each axis
- class holypipette.devices.manipulator.manipulator.Manipulator[source]¶
Bases:
TaskController
- absolute_move(x, axis=None)[source]¶
Moves the device axis to position x.
- Parameters:
axis (axis number)
x (target position in um.)
- absolute_move_group(x, axes)[source]¶
Moves the device group of axes to position x.
- Parameters:
axes (list of axis numbers)
x (target position in um (vector or list).)
- delete_state()[source]¶
Delete any previously saved state. By default, overwrites the
saved_state
attribute withNone
.
- position(axis=None)[source]¶
Current position along an axis.
- Parameters:
axis (axis number)
- Return type:
The current position of the device axis in um.
- position_group(axes)[source]¶
Current position along a group of axes.
- Parameters:
axes (list of axis numbers)
- Return type:
The current position of the device axis in um (vector).
- recover_state()[source]¶
Recover the state (e.g. the position of the manipulators) after a failure or abort. Has to be overwritten in subclasses.
- relative_move(x, axis)[source]¶
Moves the device axis by relative amount x in um.
- Parameters:
axis (axis number)
x (position shift in um.)
- relative_move_group(x, axes)[source]¶
Moves the device group of axes by relative amount x in um.
- Parameters:
axes (list of axis numbers)
x (position shift in um (vector or list).)
- save_state()[source]¶
Save the current state (e.g. the position of the manipulators) for later recovery in the case of a failure or abort. Has to be overwritten in subclasses. Should save the state to the
saved_state
variable or overwritehas_saved_state
as well.
- wait_until_reached(position, axes=None, precision=0.5, timeout=10)[source]¶
Waits until position is reached within precision, and raises an error if the target is not reached after the time out, unless the manipulator is still moving.
- Parameters:
position (target position in micrometer)
axes (axis number of list of axis numbers)
precision (precision in micrometer)
timeout (time out in second)
holypipette.devices.manipulator.manipulatorunit module¶
A class for access to a particular unit managed by a device. It is essentially a subset of a Manipulator
- class holypipette.devices.manipulator.manipulatorunit.ManipulatorUnit(dev, axes)[source]¶
Bases:
Manipulator
- absolute_move(x, axis=None)[source]¶
Moves the device axis to position x in um.
- Parameters:
axis (axis number starting at 0; if None, all XYZ axes)
x (target position in um.)
- absolute_move_group(x, axes)[source]¶
Moves the device group of axes to position x.
- Parameters:
axes (list of axis numbers)
x (target position in um (vector or list).)
- is_accessible(x, axis=None)[source]¶
Checks whether position x is accessible.
THIS METHOD IS INCORRECT.
- motor_ranges()[source]¶
Runs the motors to calculate ranges of the motors.
DOESN’T WORK! DO NOT USE!
- position(axis=None)[source]¶
Current position along an axis.
- Parameters:
axis (axis number starting at 0; if None, all XYZ axes)
- Return type:
The current position of the device axis in um.
- relative_move(x, axis=None)[source]¶
Moves the device axis by relative amount x in um.
- Parameters:
axis (axis number starting at 0; if None, all XYZ axes)
x (position shift in um.)
- wait_until_reached(position, axes=None, precision=0.5, timeout=10)[source]¶
Waits until position is reached within precision, and raises an error if the target is not reached after the time out, unless the manipulator is still moving.
- Parameters:
position (target position in micrometer)
axes (axis number of list of axis numbers)
precision (precision in micrometer)
timeout (time out in second)
holypipette.devices.manipulator.microscope module¶
A microscope is a manipulator with a single axis. With methods to take a stack of images, autofocus, etc.
TODO: * a umanager class that autoconfigures with umanager config file * steps for stack acquisition?
- class holypipette.devices.manipulator.microscope.Microscope(dev, axis)[source]¶
Bases:
Manipulator
A microscope Z axis, obtained here from an axis of a Manipulator.
- absolute_move(x)[source]¶
Moves the device axis to position x in um.
- Parameters:
x (target position in um.)
- load_configuration(config)[source]¶
Loads configuration from dictionary config. Variables not present in the dictionary are untouched.
- relative_move(x)[source]¶
Moves the device axis by relative amount x in um.
- Parameters:
x (position shift in um.)
- stack(camera, z, preprocessing=<function Microscope.<lambda>>, save=None, pause=0.3)[source]¶
Take a stack of images at the positions given in the z list
- Parameters:
camera (a camera, eg with a snap() method)
z (A list of z positions)
preprocessing (a function that processes the images (optional))
save (saves images to disk if True)
pause (pause in second after each movement)
holypipette.devices.manipulator.proscan module¶
Prior Proscan III Stage control.
- class holypipette.devices.manipulator.proscan.Prior[source]¶
Bases:
Manipulator
- absolute_move(x, axis)[source]¶
Moves the device axis to position x.
- Parameters:
axis (axis number)
x (target position in um.)
- absolute_move_group(x, axes)[source]¶
Moves the device group of axes to position x.
- Parameters:
axes (list of axis numbers)
x (target position in um (vector or list).)
- position(axis)[source]¶
Current position along an axis.
- Parameters:
axis (axis number)
- Return type:
The current position of the device axis in um.
- position_group(axes)[source]¶
Current position along a group of axes.
- Parameters:
axes (list of axis numbers)
- Return type:
The current position of the device axis in um (vector).
holypipette.devices.manipulator.sensapex module¶
holypipette.devices.pressurecontroller package¶
Submodules¶
holypipette.devices.pressurecontroller.ob1 module¶
Elveflow OB1 microfluidic flow control system
Running this program calibrates the pressure controller.
holypipette.devices.pressurecontroller.pressurecontroller module¶
A general pressure controller class
- class holypipette.devices.pressurecontroller.pressurecontroller.FakePressureController[source]¶
Bases:
PressureController
- get_pressure(port=0)[source]¶
Gets the pressure on the designated port. Note that this does not refer to any measurement, but simply to the pressure as set via
set_pressure
.
- class holypipette.devices.pressurecontroller.pressurecontroller.PressureController[source]¶
Bases:
TaskController
- get_pressure(port=0)[source]¶
Gets the pressure on the designated port. Note that this does not refer to any measurement, but simply to the pressure as set via
set_pressure
.
Submodules¶
holypipette.geometry package¶
Submodules¶
holypipette.geometry.planes module¶
Calculation related to planes (intersections, etc)
- class holypipette.geometry.planes.Plane(vector, offset)[source]¶
Bases:
object
A plane is defined by its normal vector n and an offset a, according to: n.x + a = 0
holypipette.gui package¶
Submodules¶
holypipette.gui.camera module¶
- class holypipette.gui.camera.CameraGui(camera, image_edit=None, display_edit=None, with_tracking=False, base_directory='.')[source]¶
Bases:
QMainWindow
The basic GUI for showing a camera image.
- Parameters:
camera (
Camera
) – TheCamera
object that will be used for displaying an image viaLiveFeedQt
.image_edit (function or list of functions, optional) – A function that will be called with the numpy array returned by the camera. Can be used to post-process the image, e.g. to change its brightness.
display_edit (function or list of functions, optional) – A function that will be called with the
QPixmap
that is based on the camera image. Can be used to display additional information on top of this image, e.g. a scale bar or text.with_tracking (bool, optional) – Whether to activate the object tracking interface. Defaults to
False
.
- camera_reset_signal¶
- camera_signal¶
- display_edit(pixmap)[source]¶
Applies the functions stored in
display_edit_funcs
to the video image pixmap.- Parameters:
pixmap (
QPixmap
) – The pixmap to draw on.
- draw_cross(pixmap)[source]¶
Draws a cross at the center. Meant to be used as a
display_edit
function.- Parameters:
pixmap (
QPixmap
) – The pixmap to draw on.
- image_edit(image)[source]¶
Applies the functions stored in
image_edit_funcs
to the video image. Each function works on the result of the previous function- Parameters:
image (
ndarray
) – The original video image or the image returned by a previously called function.- Returns:
new_image – The post-processed image. Should be of the same size and data type as the original image.
- Return type:
ndarray
- log_signal¶
- register_commands()[source]¶
Tie keypresses and mouse clicks to commands. Should call
register_key_action
andregister_mouse_action
. Overriding methods in subclass should call the superclass if they want to keep the commands registered by the superclass(es).
- register_key_action(key, modifier, command, argument=None, default_doc=True)[source]¶
Link a keypress to an action.
- Parameters:
key (
Qt.Key
) – The key that should be handled, specified as aQt
constant, e.g.Qt.Key_X
orQt.Key_5
.modifier (
Qt.Modifer
orNone
) – The modifier that needs to be pressed at the same time to trigger the action. The modifier needs to be given as aQt
constant, e.g.Qt.ShiftModifier
orQt.ControlModifier
. Alternatively,None
can be used to specify that the keypress should lead to the action independent of the modifier.command (method) – A method implementing the action that has been annotated with the
@command
or@blocking_command
decorator.argument (object, optional) – An additional argument that should be handled to the method defined as
command
. Can be used to re-use the same action in a parametrized way (e.g. steps of different size).default_doc (bool, optional) – Whether to include the action in the automatically generated help. Defaults to
True
.
- register_mouse_action(click_type, modifier, command, default_doc=True)[source]¶
Link a mouse click on the camera image to an action.
- Parameters:
click_type (
Qt.MouseButton
) – The type of click that should be handled as aQt
constant, e.g.Qt.LeftButton
orQt.RightButton
.modifier (
Qt.Modifer
orNone
) – The modifier that needs to be pressed at the same time to trigger the action. The modifier needs to be given as aQt
constant, e.g.Qt.ShiftModifier
orQt.ControlModifier
. Alternatively,None
can be used to specify that the mouse click should lead to the action independent of the modifier.command (method) – A method implementing the action that has been annotated with the
@command
or@blocking_command
decorator.default_doc (bool, optional) – Whether to include the action in the automatically generated help. Defaults to
True
.
- class holypipette.gui.camera.ConfigGui(config, show_name=False)[source]¶
Bases:
QWidget
- value_changed_signal¶
- class holypipette.gui.camera.ElidedLabel(text, minimum_width=200, *args, **kwds)[source]¶
Bases:
QLabel
- class holypipette.gui.camera.LogViewerWindow(parent)[source]¶
Bases:
QMainWindow
- close_signal¶
- levels = {'DEBUG': 10, 'ERROR': 40, 'INFO': 20, 'WARN': 30}¶
holypipette.gui.livefeed module¶
holypipette.gui.manipulator module¶
- class holypipette.gui.manipulator.ManipulatorGui(camera, pipette_interface, with_tracking=False)[source]¶
Bases:
CameraGui
- pipette_command_signal¶
- pipette_reset_signal¶
- register_commands(manipulator_keys=True)[source]¶
Tie keypresses and mouse clicks to commands. Should call
register_key_action
andregister_mouse_action
. Overriding methods in subclass should call the superclass if they want to keep the commands registered by the superclass(es).
holypipette.gui.movingList module¶
holypipette.gui.paramecium_device module¶
GUI for Paramecium electrophysiology
- class holypipette.gui.paramecium_device.ParameciumDeviceGui(camera, pipette_interface)[source]¶
Bases:
ManipulatorGui
- paramecium_command_signal¶
- paramecium_reset_signal¶
- register_commands()[source]¶
Tie keypresses and mouse clicks to commands. Should call
register_key_action
andregister_mouse_action
. Overriding methods in subclass should call the superclass if they want to keep the commands registered by the superclass(es).
holypipette.gui.paramecium_device2 module¶
Simplified Paramecium device GUI
GUI for Paramecium electrophysiology, with the immobilization device
- class holypipette.gui.paramecium_device2.ParameciumDeviceGui(stage, microscope, camera, units, config_filename='paramecium_device.cfg')[source]¶
Bases:
ManipulatorGui
- register_commands()[source]¶
Tie keypresses and mouse clicks to commands. Should call
register_key_action
andregister_mouse_action
. Overriding methods in subclass should call the superclass if they want to keep the commands registered by the superclass(es).
holypipette.gui.paramecium_droplet module¶
GUI for Paramecium electrophysiology
- class holypipette.gui.paramecium_droplet.ParameciumDropletGui(camera, pipette_interface)[source]¶
Bases:
ManipulatorGui
- paramecium_command_signal¶
- paramecium_reset_signal¶
- register_commands()[source]¶
Tie keypresses and mouse clicks to commands. Should call
register_key_action
andregister_mouse_action
. Overriding methods in subclass should call the superclass if they want to keep the commands registered by the superclass(es).
- holypipette.gui.paramecium_droplet.create_painter(pixmap, color, width=1)[source]¶
Setup a
QPainter
with aQPen
of a given color and width.- Parameters:
pixmap (
QPixMap
) – The pixmap on which to draw.color (tuple) – The 4-element tuple defining the color (R, G, B, alpha).
width (int) – The width in pixels.
- Returns:
painter – The painter that can be used for drawing on the pixmap.
- Return type:
QPainter
holypipette.gui.patch module¶
- class holypipette.gui.patch.PatchGui(camera, pipette_interface, patch_interface, with_tracking=False)[source]¶
Bases:
ManipulatorGui
- patch_command_signal¶
- patch_reset_signal¶
- register_commands()[source]¶
Tie keypresses and mouse clicks to commands. Should call
register_key_action
andregister_mouse_action
. Overriding methods in subclass should call the superclass if they want to keep the commands registered by the superclass(es).
- class holypipette.gui.patch.TrackingPatchGui(camera, pipette_interface, patch_interface, with_tracking=False)[source]¶
Bases:
PatchGui
- register_commands()[source]¶
Tie keypresses and mouse clicks to commands. Should call
register_key_action
andregister_mouse_action
. Overriding methods in subclass should call the superclass if they want to keep the commands registered by the superclass(es).
holypipette.interface package¶
Package defining TaskInterface
classes. These classes are the interfaces
between the GUI and the classes that perform the actual tasks such as patching,
controlling the camera, etc. The key role of the TaskInterface
classes is
to define the commands that it supports (e.g. patching, moving the manipulators,
etc.) and what should be done if such command is received.
Submodules¶
holypipette.interface.base module¶
Package defining the TaskInterface
class, central to the interface between
GUI and TaskController
objects.
- class holypipette.interface.base.TaskInterface[source]¶
Bases:
QObject
,LoggingObject
Class defining the basic interface between the GUI and the objects controlling the hardware. Classes inheriting from this class should:
Call this class’s
__init__
function in its__init__
Annotate all functions providing commands with the
@command
or@blocking_command
decorator.To correctly interact with the GUI for blocking commands (show that task is running, show error message if task fails, etc.), the method needs to call the
execute
function to execute the command.
- abort_task()[source]¶
The user asked for an abort of the currently running (blocking) command. We transmit this information to all executing objects (for simplicity, only one should be running) by setting the
TaskController.abort_requested
attribute. The object runs in a separate thread, but will finish its operation as soon as it checks for this attribute (either by explicitly checking withTaskController.abort_if_requested
, or by usingTaskController.sleep
or one of the logging methods).
- command_received(command, argument)[source]¶
Slot that is triggered when the GUI triggers a command handled by this
TaskInterface
. If an error occurs in the handling of the command (e.g., the command does not exist or received the wrong number of arguments), an error is logged and thetask_finished
signal is emitted. Note that the handling of errors within the command, as well as the handling of abort requests is performed in theexecute
method.- Parameters:
command (method) – A reference to the requested command.
argument (object) – The argument of the requested command (possibly
None
).
- connect(main_gui)[source]¶
Connect signals to slots in the main GUI. Will be called automatically during initialization of the GUI.
- Parameters:
main_gui (
CameraGui
) – The main GUI in control.
- execute(task, argument=None)[source]¶
Execute a function in a
TaskController
and signal the (successful or unsuccessful) completion via thetask_finished
signal.Can either execute a single task or a chain of tasks where each task is only executed when the previous was successful.
- Parameters:
task (method or list of methods) – A method of a
TaskController
object that should be executed, or a list of such methods.argument (object or list of object, optional) – An argument that will be provided to
task
orNone
(the default). For a chain of function calls, provide a list of arguments.
- Returns:
success – Whether the execution was completed successfully. This can be used to manually enchain multiple tasks to avoid calling subsequent tasks after a failed/aborted task. Note that it can be easier to pass a list of functions instead.
- Return type:
- reset_requested(controller)[source]¶
Slot that will be triggered when the user asks for resetting the state after an aborted or failed command.
- Parameters:
controller (
TaskController
) – The object that was executing the task that failed or was aborted. This object is requested to reset its state.
- task_finished¶
Signals the end of a task with an “error code”: 0: successful execution; 1: error during execution; 2: aborted
- holypipette.interface.base.blocking_command(category, description, task_description, default_arg=None)[source]¶
Decorator that annotates a function with information about the implemented (blocking) command.
- Parameters:
category (str) – The command category (used for structuring the help window).
description (str) – A descriptive text for the command (used in the help window).
task_description (str) – Text that will be displayed to the user while the task is running
default_arg (object, optional) – A default argument provided to the method or
None
(the default).
- holypipette.interface.base.command(category, description, default_arg=None, success_message=None)[source]¶
Decorator that annotates a function with information about the implemented command.
- Parameters:
category (str) – The command category (used for structuring the help window).
description (str) – A descriptive text for the command (used in the help window).
default_arg (object, optional) – A default argument provided to the method or
None
(the default).success_message (str, optional) – A message that will be displayed in the status bar of the GUI window after the execution of the command. For simple commands that have visual feedback, e.g. moving the manipulator or changing the exposure time, this should not be set to avoid unnecessary messages. For actions that have no visual feedback, e.g. storing a position, this should be set to give the user an indication that something happened.
holypipette.interface.camera module¶
- class holypipette.interface.camera.CameraInterface(camera, with_tracking=False)[source]¶
Bases:
TaskInterface
- connect(main_gui)[source]¶
Connect signals to slots in the main GUI. Will be called automatically during initialization of the GUI.
- Parameters:
main_gui (
CameraGui
) – The main GUI in control.
- decrease_exposure(decrease)[source]¶
Decrease exposure time by 2.5ms
- Parameters:
decrease (object, optional) – If no argument is given, 2.5 will be used as a default argument
- increase_exposure(increase)[source]¶
Increase exposure time by 2.5ms
- Parameters:
increase (object, optional) – If no argument is given, 2.5 will be used as a default argument
- track_object(position=None)[source]¶
Select an object for automatic tracking
- Parameters:
position (object, optional)
- updated_exposure¶
holypipette.interface.paramecium_device module¶
- class holypipette.interface.paramecium_device.CalibratedUnitProxy(pipette_interface)[source]¶
Bases:
object
Small helper object that forwards all requests to the currently selected manipulator.
- class holypipette.interface.paramecium_device.ParameciumDeviceConfig(value_changed=None, *args, **kwds)[source]¶
Bases:
Config
params(calibration_level=NumberWithUnit, impalement_level=NumberWithUnit, impalement_step=NumberWithUnit, pause_between_steps=NumberWithUnit, pipette_distance=NumberWithUnit, short_withdraw_distance=NumberWithUnit, withdraw_distance=NumberWithUnit, working_level=NumberWithUnit, name=String) [1;32mParameters of ‘ParameciumDeviceConfig’ ====================================== [0m [1;31mParameters changed from their default values are marked in red.[0m [1;36mSoft bound values are marked in cyan.[0m C/V= Constant/Variable, RO/RW = ReadOnly/ReadWrite, AN=Allow None
[1;34mName Value Type Bounds Mode [0m
working_level 50 NumberWithUnit (0, 500) V RW calibration_level 200 NumberWithUnit (0, 1000) V RW impalement_level 10 NumberWithUnit (0, 100) V RW withdraw_distance 1000 NumberWithUnit (0, 3000) V RW pipette_distance 250 NumberWithUnit (0, 2000) V RW short_withdraw_distance 20 NumberWithUnit (0, 100) V RW impalement_step 5 NumberWithUnit (1, 10) V RW pause_between_steps 0.5 NumberWithUnit (0, 2) V RW
[1;32mParameter docstrings: =====================[0m
[1;34mworking_level: Working level[0m [1;31mcalibration_level: Calibration level[0m [1;34mimpalement_level: Impalement level[0m [1;31mwithdraw_distance: Withdraw distance[0m [1;34mpipette_distance: Pipette distance from center[0m [1;31mshort_withdraw_distance: Withdraw before impalement[0m [1;34mimpalement_step: Step size for impalement[0m [1;31mpause_between_steps: Pause between impalement steps[0m
- calibration_level = 200¶
- categories = [('Manipulation', ['working_level', 'calibration_level', 'impalement_level', 'withdraw_distance', 'pipette_distance', 'short_withdraw_distance']), ('Automation', ['impalement_step', 'pause_between_steps'])]¶
- impalement_level = 10¶
- impalement_step = 5¶
- name = 'ParameciumDeviceConfig'¶
- oscilloscope_filename = '/home/docs/holypipette/oscilloscope.txt'¶
- pause_between_steps = 0.5¶
- pipette_distance = 250¶
- short_withdraw_distance = 20¶
- withdraw_distance = 1000¶
- working_level = 50¶
- class holypipette.interface.paramecium_device.ParameciumDeviceInterface(pipette_interface, camera)[source]¶
Bases:
TaskInterface
- class holypipette.interface.paramecium_device.ParameciumDeviceSimplifiedInterface(stage, microscope, camera, units, config_filename=None)[source]¶
Bases:
PipetteInterface
holypipette.interface.paramecium_droplet module¶
- class holypipette.interface.paramecium_droplet.CalibratedUnitProxy(pipette_interface)[source]¶
Bases:
object
Small helper object that forwards all requests to the currently selected manipulator.
- class holypipette.interface.paramecium_droplet.ParameciumDropletConfig(value_changed=None, *args, **kwds)[source]¶
Bases:
Config
params(autofocus_size=NumberWithUnit, autofocus_sleep=NumberWithUnit, blur_size=NumberWithUnit, draw_contours=Boolean, draw_fitted_ellipses=Boolean, max_displacement=NumberWithUnit, max_gradient=NumberWithUnit, max_length=NumberWithUnit, max_width=NumberWithUnit, min_gradient=NumberWithUnit, min_length=NumberWithUnit, min_width=NumberWithUnit, minimum_contour=NumberWithUnit, minimum_stop_time=NumberWithUnit, stop_amplitude=NumberWithUnit, stop_duration=NumberWithUnit, target_pixelperum=Number, working_distance=NumberWithUnit, name=String) [1;32mParameters of ‘ParameciumDropletConfig’ ======================================= [0m [1;31mParameters changed from their default values are marked in red.[0m [1;36mSoft bound values are marked in cyan.[0m C/V= Constant/Variable, RO/RW = ReadOnly/ReadWrite, AN=Allow None
[1;34mName Value Type Bounds Mode [0m
target_pixelperum 1 Number (0, 4) V RW min_gradient 75 NumberWithUnit (0, 100) V RW max_gradient 98 NumberWithUnit (0, 100) V RW blur_size 10 NumberWithUnit (0, 100) V RW minimum_contour 100 NumberWithUnit (0, 1000) V RW min_length 65 NumberWithUnit (0, 1000) V RW max_length 170 NumberWithUnit (0, 1000) V RW min_width 30 NumberWithUnit (0, 1000) V RW max_width 60 NumberWithUnit (0, 1000) V RW max_displacement 50 NumberWithUnit (0, 1000) V RW autofocus_size 150 NumberWithUnit (0, 1000) V RW autofocus_sleep 0.5 NumberWithUnit (0, 1) V RW minimum_stop_time 0 NumberWithUnit (0, 5000) V RW stop_duration 50 NumberWithUnit (0, 1000) V RW stop_amplitude 5 NumberWithUnit (0, 1000) V RW working_distance 200 NumberWithUnit (0, 1000) V RW draw_contours False Boolean (0, 1) V RW draw_fitted_ellipses False Boolean (0, 1) V RW
[1;32mParameter docstrings: =====================[0m
[1;34mtarget_pixelperum: Target number of pixel per um[0m [1;31mmin_gradient: Minimum gradient quantile for edge detection[0m [1;34mmax_gradient: Maximum gradient quantile for edge detection[0m [1;31mblur_size: Gaussian blurring size[0m [1;34mminimum_contour: Minimum contour length[0m [1;31mmin_length: Minimum length ellipsis[0m [1;34mmax_length: Maximum length for ellipsis[0m [1;31mmin_width: Minimum width for ellipsis[0m [1;34mmax_width: Maximum width for ellipsis[0m [1;31mmax_displacement: Maximum displacement over one frame[0m [1;34mautofocus_size: Size of bounding box for autofocus[0m [1;31mautofocus_sleep: Sleep time autofocus[0m [1;34mminimum_stop_time: Time before starting automation[0m [1;31mstop_duration: Stopping duration before detection[0m [1;34mstop_amplitude: Movement threshold for detecting stop[0m [1;31mworking_distance: Working distance for pipettes[0m [1;34mdraw_contours: Draw contours?[0m [1;31mdraw_fitted_ellipses: Draw fitted ellipses?[0m
- autofocus_size = 150¶
- autofocus_sleep = 0.5¶
- blur_size = 10¶
- categories = [('Tracking', ['target_pixelperum', 'min_gradient', 'max_gradient', 'blur_size', 'minimum_contour', 'min_length', 'max_length', 'min_width', 'max_width', 'max_displacement']), ('Manipulation', ['working_distance', 'autofocus_size', 'autofocus_sleep']), ('Automation', ['stop_duration', 'stop_amplitude', 'minimum_stop_time']), ('Debugging', ['draw_contours', 'draw_fitted_ellipses'])]¶
- draw_contours = False¶
- draw_fitted_ellipses = False¶
- max_displacement = 50¶
- max_gradient = 98¶
- max_length = 170¶
- max_width = 60¶
- min_gradient = 75¶
- min_length = 65¶
- min_width = 30¶
- minimum_contour = 100¶
- minimum_stop_time = 0¶
- name = 'ParameciumDropletConfig'¶
- stop_amplitude = 5¶
- stop_duration = 50¶
- target_pixelperum = 1¶
- working_distance = 200¶
- class holypipette.interface.paramecium_droplet.ParameciumDropletInterface(pipette_interface, camera)[source]¶
Bases:
TaskInterface
- move_pipette_floor(xy_position)[source]¶
Move pipettes to position at floor level
- Parameters:
xy_position (object, optional)
- move_pipette_working_level(xy_position)[source]¶
Move pipette down to position at working distance level
- Parameters:
xy_position (object, optional)
holypipette.interface.patch module¶
Control of automatic patch clamp algorithm
- class holypipette.interface.patch.AutoPatchInterface(amplifier, pressure, pipette_interface)[source]¶
Bases:
TaskInterface
A class to run automatic patch-clamp
- contact_detection()[source]¶
Moving down the calibrated manipulator to detect the contact point with the coverslip
- property current_autopatcher¶
- patch_with_move(position)[source]¶
Move to cell and patch it
- Parameters:
position (object, optional)
- class holypipette.interface.patch.PatchConfig(value_changed=None, *args, **kwds)[source]¶
Bases:
Config
params(Vramp_amplitude=NumberWithUnit, Vramp_duration=NumberWithUnit, cell_R_increase=Number, cell_distance=NumberWithUnit, gigaseal_R=NumberWithUnit, max_R=NumberWithUnit, max_R_increase=NumberWithUnit, max_cell_R=NumberWithUnit, max_distance=NumberWithUnit, min_R=NumberWithUnit, pressure_near=NumberWithUnit, pressure_ramp_duration=NumberWithUnit, pressure_ramp_increment=NumberWithUnit, pressure_ramp_max=NumberWithUnit, pressure_sealing=NumberWithUnit, seal_deadline=NumberWithUnit, seal_min_time=NumberWithUnit, zap=Boolean, name=String) [1;32mParameters of ‘PatchConfig’ =========================== [0m [1;31mParameters changed from their default values are marked in red.[0m [1;36mSoft bound values are marked in cyan.[0m C/V= Constant/Variable, RO/RW = ReadOnly/ReadWrite, AN=Allow None
[1;34mName Value Type Bounds Mode [0m
pressure_near 20 NumberWithUnit (0, 100) V RW pressure_sealing -20 NumberWithUnit (-100, 0) V RW pressure_ramp_increment -25 NumberWithUnit (-100, 0) V RW pressure_ramp_max -300.0 NumberWithUnit (-1000, 0) V RW pressure_ramp_duration 1.15 NumberWithUnit (0, 10) V RW min_R 2000000.0 NumberWithUnit (0, 1000000000.0) V RW max_R 25000000.0 NumberWithUnit (0, 1000000000.0) V RW max_cell_R 300000000.0 NumberWithUnit (0, 1000000000.0) V RW cell_distance 10 NumberWithUnit (0, 100) V RW max_distance 20 NumberWithUnit (0, 100) V RW max_R_increase 1000000.0 NumberWithUnit (0, 100000000.0) V RW cell_R_increase 0.15 Number (0, 1) V RW gigaseal_R 1000000000.0 NumberWithUnit (100000000.0, 10000000000.0) V RW seal_min_time 15 NumberWithUnit (0, 60) V RW seal_deadline 90.0 NumberWithUnit (0, 300) V RW Vramp_duration 10.0 NumberWithUnit (0, 60) V RW Vramp_amplitude -0.07 NumberWithUnit (-0.2, 0) V RW zap False Boolean (0, 1) V RW
[1;32mParameter docstrings: =====================[0m
[1;34mpressure_near: Pressure during approach[0m [1;31mpressure_sealing: Pressure for sealing[0m [1;34mpressure_ramp_increment: Pressure ramp increment[0m [1;31mpressure_ramp_max: Pressure ramp maximum[0m [1;34mpressure_ramp_duration: Pressure ramp duration[0m [1;31mmin_R: Minimum normal resistance[0m [1;34mmax_R: Maximum normal resistance[0m [1;31mmax_cell_R: Maximum cell resistance[0m [1;34mcell_distance: Initial distance above target cell[0m [1;31mmax_distance: Maximum movement during approach[0m [1;34mmax_R_increase: Increase in resistance indicating obstruction[0m [1;31mcell_R_increase: Proportional increase in resistance indicating cell presence[0m [1;34mgigaseal_R: Gigaseal resistance[0m [1;31mseal_min_time: Minimum time for seal[0m [1;34mseal_deadline: Maximum time for seal formation[0m [1;31mVramp_duration: Voltage ramp duration[0m [1;34mVramp_amplitude: Voltage ramp amplitude[0m [1;31mzap: Zap the cell to break the seal[0m
- Vramp_amplitude = -0.07¶
- Vramp_duration = 10.0¶
- categories = [('Approach', ['min_R', 'max_R', 'pressure_near', 'cell_distance', 'max_distance', 'cell_R_increase']), ('Sealing', ['pressure_sealing', 'gigaseal_R', 'Vramp_duration', 'Vramp_amplitude', 'seal_min_time', 'seal_deadline']), ('Break-in', ['zap', 'pressure_ramp_increment', 'pressure_ramp_max', 'pressure_ramp_duration', 'max_cell_R'])]¶
- cell_R_increase = 0.15¶
- cell_distance = 10¶
- gigaseal_R = 1000000000.0¶
- max_R = 25000000.0¶
- max_R_increase = 1000000.0¶
- max_cell_R = 300000000.0¶
- max_distance = 20¶
- min_R = 2000000.0¶
- name = 'PatchConfig'¶
- pressure_near = 20¶
- pressure_ramp_duration = 1.15¶
- pressure_ramp_increment = -25¶
- pressure_ramp_max = -300.0¶
- pressure_sealing = -20¶
- seal_deadline = 90.0¶
- seal_min_time = 15¶
- zap = False¶
holypipette.interface.pipettes module¶
- class holypipette.interface.pipettes.PipetteInterface(stage, microscope, camera, units, config_filename=None)[source]¶
Bases:
TaskInterface
Controller for the stage, the microscope, and several pipettes.
- connect(main_gui)[source]¶
Connect signals to slots in the main GUI. Will be called automatically during initialization of the GUI.
- Parameters:
main_gui (
CameraGui
) – The main GUI in control.
- manipulator_switched¶
- measure_ranges()[source]¶
This is called every 500 ms when measuring ranges. It updates the min and max on each axis.
- move_microscope(distance)[source]¶
Move microscope by 10μm
- Parameters:
distance (object, optional) – If no argument is given, 10 will be used as a default argument
- move_pipette(xy_position)[source]¶
Move pipette to position
- Parameters:
xy_position (object, optional)
- move_pipette_x(distance)[source]¶
Move pipette in x direction by 10μm
- Parameters:
distance (object, optional) – If no argument is given, 10 will be used as a default argument
- move_pipette_y(distance)[source]¶
Move pipette in y direction by 10μm
- Parameters:
distance (object, optional) – If no argument is given, 10 will be used as a default argument
- move_pipette_z(distance)[source]¶
Move pipette in z direction by 10μm
- Parameters:
distance (object, optional) – If no argument is given, 10 will be used as a default argument
- move_stage_horizontal(distance)[source]¶
Move stage horizontally by 10μm
- Parameters:
distance (object, optional) – If no argument is given, 10 will be used as a default argument
- move_stage_vertical(distance)[source]¶
Move stage vertically by 10μm
- Parameters:
distance (object, optional) – If no argument is given, 10 will be used as a default argument
holypipette.utils package¶
Submodules¶
holypipette.utils.filelock module¶
A platform independent file lock that supports the with-statement.
- class holypipette.utils.filelock.BaseFileLock(lock_file, timeout=- 1)[source]¶
Bases:
object
Implements the base class of a file lock.
- acquire(timeout=None, poll_intervall=0.05)[source]¶
Acquires the file lock or fails with a
Timeout
error.# You can use this method in the context manager (recommended) with lock.acquire(): pass # Or use an equivalent try-finally construct: lock.acquire() try: pass finally: lock.release()
- Parameters:
timeout (float) – The maximum time waited for the file lock. If
timeout < 0
, there is no timeout and this method will block until the lock could be acquired. Iftimeout
is None, the defaulttimeout
is used.poll_intervall (float) – We check once in poll_intervall seconds if we can acquire the file lock.
- Raises:
Timeout – if the lock could not be acquired in timeout seconds.
Changed in version 2.0.0: This method returns now a proxy object instead of self, so that it can be used in a with statement without side effects.
- property is_locked¶
True, if the object holds the file lock.
Changed in version 2.0.0: This was previously a method and is now a property.
- property lock_file¶
The path to the lock file.
- release(force=False)[source]¶
Releases the file lock.
Please note, that the lock is only completly released, if the lock counter is 0.
Also note, that the lock file itself is not automatically deleted.
- Parameters:
force (bool) – If true, the lock counter is ignored and the lock is released in every case.
- property timeout¶
You can set a default timeout for the filelock. It will be used as fallback value in the acquire method, if no timeout value (None) is given.
If you want to disable the timeout, set it to a negative value.
A timeout of 0 means, that there is exactly one attempt to acquire the file lock.
New in version 2.0.0.
- holypipette.utils.filelock.FileLock¶
Alias for the lock, which should be used for the current platform. On Windows, this is an alias for
WindowsFileLock
, on Unix forUnixFileLock
and otherwise forSoftFileLock
.
- class holypipette.utils.filelock.SoftFileLock(lock_file, timeout=- 1)[source]¶
Bases:
BaseFileLock
Simply watches the existence of the lock file.
- exception holypipette.utils.filelock.Timeout(lock_file)[source]¶
Bases:
TimeoutError
Raised when the lock could not be acquired in timeout seconds.
- lock_file¶
The path of the file lock.
- class holypipette.utils.filelock.UnixFileLock(lock_file, timeout=- 1)[source]¶
Bases:
BaseFileLock
Uses the
fcntl.flock()
to hard lock the lock file on unix systems.
- class holypipette.utils.filelock.WindowsFileLock(lock_file, timeout=- 1)[source]¶
Bases:
BaseFileLock
Uses the
msvcrt.locking()
function to hard lock the lock file on windows systems.
holypipette.vision package¶
Image processing algorithms
Submodules¶
holypipette.vision.crop module¶
Methods to crop images
holypipette.vision.findpipette module¶
Methods to find the pipette in an image
holypipette.vision.paramecium_tracking module¶
These are functions to locate paramecium in an image
- class holypipette.vision.paramecium_tracking.ParameciumTracker(config=None, history_size=100)[source]¶
Bases:
object
- holypipette.vision.paramecium_tracking.where_is_droplet(frame, pixel_per_um=5.0, ratio=None, xc=None, yc=None)[source]¶
Locate a droplet in an image.
- Parameters:
frame (the image)
pixel_per_um (number of pixels per um)
ratio (decimating ratio (to make the image smaller))
xc, yc (coordinate of a point inside the droplet)
- Returns:
x, y, r
- Return type:
position and radius on screen
holypipette.vision.phase_cross_correlation module¶
Copied from scikit-image.registration 0.18.0. Masking removed.
- holypipette.vision.phase_cross_correlation.phase_cross_correlation(reference_image, moving_image, upsample_factor=1, space='real', return_error=True, overlap_ratio=0.3)[source]¶
Efficient subpixel image translation registration by cross-correlation. This code gives the same precision as the FFT upsampled cross-correlation in a fraction of the computation time and with reduced memory requirements. It obtains an initial estimate of the cross-correlation peak by an FFT and then refines the shift estimation by upsampling the DFT only in a small neighborhood of that estimate by means of a matrix-multiply DFT. :Parameters: * reference_image (array) – Reference image.
moving_image (array) – Image to register. Must be same dimensionality as
reference_image
.upsample_factor (int, optional) – Upsampling factor. Images will be registered to within
1 / upsample_factor
of a pixel. For exampleupsample_factor == 20
means the images will be registered within 1/20th of a pixel. Default is 1 (no upsampling). Not used if any ofreference_mask
ormoving_mask
is not None.space (string, one of “real” or “fourier”, optional) – Defines how the algorithm interprets input data. “real” means data will be FFT’d to compute the correlation, while “fourier” data will bypass FFT of input data. Case insensitive. Not used if any of
reference_mask
ormoving_mask
is not None.return_error (bool, optional) – Returns error and phase difference if on, otherwise only shifts are returned. Has noeffect if any of
reference_mask
ormoving_mask
is not None. In this case only shifts is returned.overlap_ratio (float, optional) – Minimum allowed overlap ratio between images. The correlation for translations corresponding with an overlap ratio lower than this threshold will be ignored. A lower
overlap_ratio
leads to smaller maximum translation, while a higheroverlap_ratio
leads to greater robustness against spurious matches due to small overlap between masked images. Used only if one ofreference_mask
ormoving_mask
is None.
- Returns:
shifts (ndarray) – Shift vector (in pixels) required to register
moving_image
withreference_image
. Axis ordering is consistent with numpy (e.g. Z, Y, X)error (float) – Translation invariant normalized RMS error between
reference_image
andmoving_image
.phasediff (float) – Global phase difference between the two images (should be zero if images are non-negative).
References
holypipette.vision.templatematching module¶
Search a template image in an other image Not scale nor rotation invariant
Uses OpenCV. Alternatively, one might use skimage.feature.match_template
- holypipette.vision.templatematching.templatematching(img, template, threshold=0)[source]¶
Search a template image in an other image Not scale nor rotation invariant.
- Parameters:
img (image to look in)
template (image to look for)
threshold (throw an error if match value is below threshold)
- Returns:
x (x coordinate of the template in the image)
y (y coordinate)
maxval (maximum value corresponding to the best matching ratio)
Submodules¶
holypipette.config module¶
Support for configuration objects (based on the param package)
- class holypipette.config.Config(value_changed=None, *args, **kwds)[source]¶
Bases:
Parameterized
params(name=String) [1;32mParameters of ‘Config’ ====================== [0m Object has no parameters.
- name = 'Config'¶
- class holypipette.config.NumberWithUnit(default, unit, magnitude=1.0, *args, **kwds)[source]¶
Bases:
Number
A numeric Dynamic Parameter, with a default value and optional bounds.
There are two types of bounds:
bounds
andsoftbounds
.bounds
are hard bounds: the parameter must have a value within the specified range. The default bounds are (None,None), meaning there are actually no hard bounds. One or both bounds can be set by specifying a value (e.g. bounds=(None,10) means there is no lower bound, and an upper bound of 10). Bounds are inclusive by default, but exclusivity can be specified for each bound by setting inclusive_bounds (e.g. inclusive_bounds=(True,False) specifies an exclusive upper bound).Number is also a type of Dynamic parameter, so its value can be set to a callable to get a dynamically generated number (see Dynamic).
When not being dynamically generated, bounds are checked when a Number is created or set. Using a default value outside the hard bounds, or one that is not numeric, results in an exception. When being dynamically generated, bounds are checked when the value of a Number is requested. A generated value that is not numeric, or is outside the hard bounds, results in an exception.
As a special case, if allow_None=True (which is true by default if the parameter has a default of None when declared) then a value of None is also allowed.
A separate function set_in_bounds() is provided that will silently crop the given value into the legal range, for use in, for instance, a GUI.
softbounds
are present to indicate the typical range of the parameter, but are not enforced. Setting the soft bounds allows, for instance, a GUI to know what values to display on sliders for the Number.Example of creating a Number:
AB = Number(default=0.5, bounds=(None,10), softbounds=(0,1), doc='Distance from A to B.')
- magnitude¶
- unit¶