calibrate_force

lumicks.pylake.calibrate_force

calibrate_force(force_voltage_data, bead_diameter, temperature, *, sample_rate, viscosity=None, active_calibration=False, driving_data=None, driving_frequency_guess=None, axial=False, hydrodynamically_correct=False, rho_sample=None, rho_bead=1060.0, distance_to_surface=None, fast_sensor=False, num_points_per_block=2000, fit_range=(100.0, 23000.0), excluded_ranges=None, fixed_diode=None, fixed_alpha=None, drag=None, driving_sample_rate=None, corner_frequency_factor=None) CalibrationResults

Determine force calibration factors.

This function can be used to perform both active and passive calibration.

  • For experiments performed near the surface, it is recommended to provide a distance_to_surface.

  • For lateral calibration with beads larger than 1 micron, it is recommended to use the hydrodynamically correct theory (hydrodynamically_correct=True), unless so close to the surface (0.75 x diameter) that this model becomes invalid.

  • For axial calibration the flag axial=True should be set.

  • In the case of a pre-characterized diode, the values for its parameters can be passed to fixed_alpha and fixed_diode.

  • In the case of active calibration, it is mandatory to provide a nanostage signal, as well as a guess of the driving frequency.

The power spectrum calibration algorithm implemented here is based on [1] [2] [3] [4] [5] [6]. Please refer to the theory section and tutorial on force calibration for more information on the calibration methods implemented.

Parameters:
  • force_voltage_data (numpy.ndarray) – Uncalibrated force data in volts.

  • bead_diameter (float) – Bead diameter [um].

  • temperature (float) – Liquid temperature [Celsius].

  • sample_rate (float) – Sample rate at which the signals were acquired.

  • viscosity (float, optional) – Liquid viscosity [Pa*s]. When omitted, the temperature will be used to look up the viscosity of water at that particular temperature.

  • active_calibration (bool, optional) – Active calibration, when set to True, driving_data must also be provided.

  • driving_data (numpy.ndarray, optional) – Array of driving data.

  • driving_frequency_guess (float, optional) – Guess of the driving frequency. Required for active calibration.

  • axial (bool, optional) – Is this an axial calibration? Only valid for a passive calibration.

  • hydrodynamically_correct (bool, optional) – Enable hydrodynamically correct model.

  • rho_sample (float, optional) – Density of the sample [kg/m**3]. Only used when using hydrodynamically correct model.

  • rho_bead (float, optional) – Density of the bead [kg/m**3]. Only used when using hydrodynamically correct model.

  • distance_to_surface (float, optional) – Distance from bead center to the surface [um] When specifying None, the model will use an approximation which is only suitable for measurements performed deep in bulk.

  • fast_sensor (bool, optional) – Fast sensor? Fast sensors do not have the diode effect included in the model.

  • fit_range (tuple of float, optional) – Tuple of two floats (f_min, f_max), indicating the frequency range to use for the full model fit. [Hz]

  • num_points_per_block (int, optional) – The spectrum is first block averaged by this number of points per block. Default: 2000.

  • excluded_ranges (list of tuple of float, optional) – List of ranges to exclude specified as a list of (frequency_min, frequency_max).

  • drag (float, optional) – Overrides the drag coefficient to this particular value. Note that you want to use the bulk drag coefficient for this (obtained from the field gamma_ex). This can be used to carry over an estimate of the drag coefficient obtained using an active calibration procedure.

  • fixed_diode (float, optional) – Fix diode frequency to a particular frequency.

  • fixed_alpha (float, optional) – Fix diode relaxation factor to particular value.

  • driving_sample_rate (float, optional) – Sample rate at which the driving frequency is sampled. This is only used for active calibration and when omitted the sample rate of the force data will be used (default: None).

  • corner_frequency_factor (float | None, optional) – Use adaptive fitting ranges. This is a factor that is multiplied with the corner frequency to determine the upper bound for the fitting range.

Raises:
  • ValueError – If physical parameters are provided that are outside their sensible range.

  • ValueError – If the distance from the bead center to the surface is set smaller than the bead radius.

  • ValueError – If the hydrodynamically correct model is enabled, but the distance to the surface is specified below 0.75 times the bead diameter (this model is not valid so close to the surface).

  • NotImplementedError – If the hydrodynamically correct model is selected in conjunction with axial force calibration.

  • RuntimeError – If active calibration is selected, but the driving peak can’t be found near the guess of its frequency.

References

Examples

import lumicks.pylake as lk
f = lk.File("calibration_file.h5")
force_slice = f.force1x

# Decalibrate existing data
calibration_item = force_slice.calibration[0]
volts = force_slice / calibration_item["Response (pN/V)"]

# Determine calibration factors using the viscosity of water at T=25 C.
new_calibration = lk.calibrate_force(
    volts.data, bead_diameter=0.58, temperature=25, sample_rate=volts.sample_rate
)

# Determine calibration factors using the hydrodynamically correct model
new_calibration = lk.calibrate_force(
    volts.data,
    bead_diameter=4.89,
    temperature=25,
    sample_rate=volts.sample_rate,
    hydrodynamically_correct=True
)

# Determine calibration factors using the hydrodynamically correct model with active
# calibration at a distance of 7 micron from the surface
driving_data = f["Nanostage position"]["X"]
new_calibration = lk.calibrate_force(
    volts.data,
    bead_diameter=4.89,
    temperature=25,
    sample_rate=volts.sample_rate,
    hydrodynamically_correct=True,
    distance_to_surface=7,
    driving_data=driving_data.data,
    driving_frequency_guess=37,
    active_calibration=True,
    driving_sample_rate=driving_data.sample_rate,
)

# Determine calibration factors using a calibrated diode and automatic fitting ranges

# Grab the diode calibration model for this trap
diode_calibration_model = calibration_item.diode_calibration

# Look up the diode parameters at a particular power
diode_params = diode_calibration_model(f["Diagnostics"]["Trap power 1"])

new_calibration = lk.calibrate_force(
    volts.data,
    bead_diameter=4.89,
    temperature=25,
    sample_rate=volts.sample_rate,
    hydrodynamically_correct=True,
    num_points_per_block=200,  # Lower than default blocking for lower powers
    corner_frequency_factor=4,  # Automatic fitting ranges
    **diode_params,  # Unpack fixed (pre-characterized) diode parameters
)

# Inspect the fit
new_calibration.plot()

# Recalibrate force channel with this calibration
f.force1x.recalibrate_force(new_calibration)