Thermal cantilever calibration has been common practice for many years
now\citep{hutter93,florin95}, starting with estimates of thermal
-noise\citep{martin87}. However, explicit derivations and discussion
-has been limited. While this is likely done because the underlying
+noise\citep{martin87}. However, discussion and explicit derivations
+have been limited. While this is likely done because the underlying
theory is ``obvious'', it makes it more likely that corner cases slip
by the notice of calibration experts\citep{hutter93-erratum} or
incorrect formul\ae\ are used during the fitting
large timescales as the microscope alignment drifts (e.g.~due to
thermal expansion as the room warms up). However TODO
-For example, on recent calibration run\footnote{2013-02-07T08-20-46} I
-measured $\sigma_p=35.68\pm0.87\U{V/$\mu$m}$,
+For example, on a recent calibration run\footnote{2013-02-07T08-20-46}
+I measured $\sigma_p=35.68\pm0.87\U{V/$\mu$m}$,
$T=298.151\pm0.033\U{K}$, and $\avg{V_p^2}=96.90\pm0.99\U{mV$^2$}$,
which gives $\kappa=54.1\pm2.7\U{mN/m}$. The uncertainty
contributions from each term are
parameters---$G_{1f}$, $f_0$, and $\beta_f$---come from fitting the
thermal vibration of the cantilever when it is far from the surface.
-\subsection{Related papers}
+\section{Related work}
\label{sec:calibcant:survey}
In reality, the cantilever motion is more complicated than a pure
underlies all frequency-space methods for improving the basic
$\kappa\avg{x^2} = k_BT$ method.
-Roters and Johannsmann describe a similar approach to deriving the
-power spectral density\citep{roters96}. %,
+\citet{roters96} describe a similar approach to deriving the
+power spectral density. TODO (extend)%,
%as do
% see Gittes 1998 for more thermal noise details
% see Berg-Sorensen05 for excellent overdamped treament.
\end{figure}
The retraction data is analyzed using a similar approach to \pypiezo's
-surface detaction algorithm to extract the slope of the contact
+surface detection algorithm to extract the slope of the contact
region. Where \pypiezo\ uses a bilinear model
(\cref{eq:bilinear-surface}), \calibcant\ uses a limited linear model.
\end{equation}
The fitted parameters are the surface contact point $(z_\text{kink},
-d_\text{kink})$ and the contact slope $\sigma_p$. The clipping
-deflection $d_\text{rail}$ is the deflection ADC's maximum measureable
-voltage ($2^{16}\U{bits}$ for our 16-bit ADCs).
+d_\text{kink})$ and the contact slope $\sigma_p$. ADCs can only
+digitize voltages between the rails of their power supply, and the
+clipping deflection $d_\text{rail}$ is the deflection ADC's maximum
+measureable voltage ($2^{16}\U{bits}$ for our 16-bit ADCs).
-By explicitly modeling the clipping voltage, we avoid the need for
+By explicitly modeling the clipping deflection, we avoid the need for
manual intervention when the configured approach distance is too large
for the cantilever geometry and a bump pushes too hard. With short
cantilevers, even small tip deflection distances can generate large
up as required so the number of samples will be an integer power
of two for efficient Fourier transformation. It defaults to
$1\U{s}$.
- \item[model] The vibration model. This between fitting methods for
- extracting the variance $\avg{V_p(t)^2}$. By default,
+ \item[model] The vibration model. This selects the fitting method
+ for extracting the variance $\avg{V_p(t)^2}$. By default,
\cref{eq:psd-Vp} is used, but you can add the constant offset
(discussed below) or use the na\"{\i}ve
$\avg{V_p(t)^2}=\sum(V_p^2)/N$.
\end{center}
\end{figure}
-\Cref{eq:psd-Vp} rolls off for large frequencies, but the measured
+\Cref{eq:psd-Vp} decreases for large frequencies, but the measured
\PSD\ levels out (\cref{fig:calibcant:vibration:no-offset}). I
attribute this to background white noise in the measurement circuit,
and not due to cantilever oscillation. To avoid artificially
As another alternative, you could fit in frequency
$f\equiv\omega/2\pi$ instead of angular frequency $\omega$. The
-analysis will be the same, but we must be careful with normalization.
-Comparing the angular frequency and normal frequency unitary Fourier
-transforms
+analysis will be the same, but we must be careful with normalization
+due to the different scales. Comparing the angular frequency and
+normal frequency unitary Fourier transforms
\begin{align}
\Four{x(t)}(\omega)
&\equiv \frac{1}{\sqrt{2\pi}} \iInfInf{t}{x(t) e^{-i \omega t}} \\
Basic configuration types include booleans, integers, floating point
numbers, enumerated choices, and freeform text. There is also support
-for lists of these basic types (e.g.~lists of integers). The killer
+for lists of these basic types (e.g.~lists of integers). The key
feature is nesting configuration classes. This means that your higher
level tools can have their own configuration settings and also include
the configuration settings for their lower level components. For
\item[logic] selects active high or active low operation.
\item[delay] sets the time delay between steps in seconds, in case
the motor response is slower than the digital output driver.
- \item[step size] approximates step size in meters.
+ \item[step size] approximates the step size in meters.
\item[backlash] estimates the drive chain backlash in half-steps.
\end{description}
The controller monitors the fluid cell temperature with a
thermocouple, and reading temperatures from the controller is fairly
straightforward (\cref{fig:unfold-protein:unfolder}). Temperature
-control is via a peltier mounted underneath the sample surface.
+control is via a peltier mounted underneath the sample surface
+(\cref{fig:peltier}).
+
+\begin{figure}
+ \begin{center}
+ % TODO: peltier image
+ \end{center}
+ \caption{TODO.\label{fig:peltier}}
+\end{figure}
The controller tries to keep the measured temperature at the setpoint
temperature via a modified proportional-integral-derivative (PID)
working with LabVIEW, but I had very little experience in other
languages and no formal training in project maintenance. I spent the
first two years of my research project floundering about until I
-aquired enough experience to start making progress on a sustainable
+acquired enough experience to start making progress on a sustainable
stack\footnote{%
Since last summer I've been helping the
\href{http://software-carpentry.org/}{Software Carpentry}
\protect\subref{fig:pyafm:labview-comparison:many}. The
LabVIEW/Windows stack takes $0.5\U{nm}$ piezo steps with ten
deflection reads at each step. The Comedi/Linux stack makes a
- single read per step, but can as many small steps as possible
- within DAQ card's memory buffer, frequency, and precision
- limitations. For $1\U{$\mu$m/s}$ pulls, a stepping/sampling
- frequency of $50\U{kHz}$ generated steps that were less than one
- DAC bit wide.}
+ single read per step, but can take as many small steps as
+ possible within DAQ card's memory buffer, frequency, and
+ precision limitations. For $1\U{$\mu$m/s}$ pulls, a
+ stepping/sampling frequency of $50\U{kHz}$ generated steps that
+ were less than one DAC bit wide.}
\end{center}
\end{figure}
Due to the table vibration, comparisons of non-contact noise between
the two stacks are less conclusive. However, rough comparisons of the
noise spectra show that noise in the Comedi/Linux data is generally a
-factor of two two three less than noise in the LabVIEW/Windows data
+factor of two to three less than noise in the LabVIEW/Windows data
across a range of frequencies
-(\cref{fig:pyafm:labview-comparison:non-contact-noise}). While
-the noise difference should be taken with a grain of salt, it does
-highlight the importance (and difficulty) of characterizing your
-apparatus and controlling software.
+(\cref{fig:pyafm:labview-comparison:non-contact-noise}). While the
+noise difference may be small, it does highlight the importance (and
+difficulty) of characterizing your apparatus and controlling software.
side, they produce a wide range of DAQ cards. On the software side,
they produce LabVIEW\citep{labview}, a graphical programming language
designed to make writing control and aquisition experiments
-straightforward. Both LabVIEW and NI-DAQ cards are ubiquitous in
+straightforward. Both LabVIEW and NI-DAQmx cards are ubiquitous in
scientific computing; in the four research labs I've worked in over my
career, every lab has used both. By the time I joined Prof.~Yang's
lab, I'd been using LabVIEW for years, and had become familiar with
its two major limitations: name based linking and a binary file
format.
-
+%
\nomenclature{DAQ}{Data acquisition. Although the term only refers to
input, it is sometimes implicitly extended to include signal output
as well (for controlling experiments as well as measuring results).}
The second obstacle to maintaining LabVIEW code is the binary file
format for VIs. The established method for recording software history
-is to use a version control system (VCS), which recording versions of
+is to use a version control system (VCS), which records versions of
the project in a repository. Each change to the project is committed
to the repository with some associated metadata (timestamp, committer
name, explanatory message, \ldots). Users can access this database to
The overhead of sending all the data through sockets to generic
hardware interface modules was larger than I had na\"{\i}vely
expected. I also had trouble with multithreaded socket code on
-Cygwin, and decided to scrap Microsoft Windows altogether in favor of
+Cygwin, and decided to drop Microsoft Windows altogether in favor of
a FLOSS operating system.
\begin{figure}
NI-DAQmx (which only supported Microsoft Windows). Luckily, the
\citetalias{comedi} project already provided FLOSS driver code for our
DAQ card (an NI-PCI-6052E). Comedi (from ``Control and Measurement
-Device Interface'') is general purpose library for interacting with
+Device Interface'') is a general purpose library for interacting with
DAQ devices, and supports a wide range of hardware. When I moved to
Comedi, it was a stand-alone kernel module, but since November 2008 it
has been included in the Linux source as a staging driver.
author = NI,
title = {{LabVIEW}},
url = {http://www.ni.com/labview/},
+ note = {A graphical programming language designed for developing
+ experiment control software.},
}
@misc{ national-instruments,
month = mar,
date = 14,
url = {http://www.ni.com/white-paper/2931/en},
+ note = {Control libraries for data aquisition. While these
+ libraries form the basis of \citetalias{labview}'s control stack,
+ you can also use them directly from other languages (like C).},
}
@misc{ cygwin,
title = {Cygwin},
url = {http://www.cygwin.com/},
+ note = {A POSIX emulation layer for Microsoft Windows. With Cygwin,
+ Windows seems more like UNIX or Linux.},
}
@misc{ epics,
paper_url = {http://dl.acm.org/citation.cfm?id=1267498.1267513},
publisher = USENIX,
address = {Berkeley, CA, USA},
+ note = {SWIG, the simplified wrapper and interface generator, makes
+ it easy to wrap C and C++ libraries for use from higher level
+ scripting languages like Python. Often, you don't need much more
+ than the library's header file to generate a full wrapper.
+ However, the generated wrappers are usually very thin, which can
+ make them awkward to use. If you want to write a thicker, more
+ idiomatic wrapper, it's probably easier to use a tool like
+ \citetalias{cython} instead of SWIG.},
}
@misc{ cython,
higher level language for the bulk of my experiments.
\citetalias{comedi} already had \citetalias{beazley96}-generated
Python bindings, so I set to work creating \pycomedi, an
-object-oriented interface around the SWIG bindings. The first
-generation \pycomedi\ interface was much easier to use than the raw
-SWIG bindings, especially for simultaneous analog input/output, which
-I needed to monitor cantilever deflection during piezo-sweeping
+object-oriented interface around the \citetalias{swig} bindings. The
+first generation \pycomedi\ interface was much easier to use than the
+raw SWIG bindings, especially for simultaneous analog input/output,
+which I needed to monitor cantilever deflection during piezo-sweeping
velocity-clamp pulls.
The SWIG-based interface to Comedi provided a solid base for my
experiment control stack, but as the stack matured, I started bumping
up against problems due to both my poor design
choices\footnote{\citet{brooks95} says ``plan to throw one away,''
- although I'm a more optimistic about the feasibility of long-term
+ although I'm more optimistic about the feasibility of long-term
maintenance than he is.} and general awkwardness with the thin SWIG
bindings. In 2011 I ripped out most of this layer and used
\citetalias{cython} to bind directly to Comedi's userspace library.
\ref{item:pypiezo-surface-ramp-approach}, which should clearly show
the contact kink, is fit to a bilinear model (a linear non-contact
region and a linear contact region, which meet at the the contact
-kink). The fitting is carried out my minimizing the residual
+kink). The fitting is carried out by minimizing the residual
difference between the approach data and bilinear model with SciPy's
\imint{python}|leastsq| optimizer, a wrapper around MINPACK's
\imint{fortran}|lmdif| and \imint{fortran}|lmder|