Flesh out calibcant discussion.
authorW. Trevor King <wking@drexel.edu>
Fri, 22 Apr 2011 02:01:13 +0000 (22:01 -0400)
committerW. Trevor King <wking@drexel.edu>
Fri, 22 Apr 2011 02:01:13 +0000 (22:01 -0400)
posts/calibcant.mdwn [deleted file]
posts/calibcant.mdwn_itex [new file with mode: 0644]
posts/calibcant/bump.png [new file with mode: 0644]
posts/calibcant/statistics.png [new file with mode: 0644]
posts/calibcant/vibration.png [new file with mode: 0644]

diff --git a/posts/calibcant.mdwn b/posts/calibcant.mdwn
deleted file mode 100644 (file)
index 0281bd0..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-[[!meta  title="calibcant"]]
-[[!template id=gitrepo repo=calibcant]]
-
-Here is my Python module for AFM cantilever calibration via the
-thermal tune method.
-
-The `README` is posted on the [PyPI page][pypi], and you might also be
-interested in the [[package dependency graph|calibcant.svg]] generated
-with Yu-Jie Lin's [PDepGraph.py][]:
-
-    $ IGNORED=matplotlib,scipy,numpy,pyyaml,h5py,python,eselect-python
-    $ python PDepGraph.py -o calibcant.dot -D "$IGNORED" calibcant
-    $ dot -T svg -o calibcant.svg calibcant.dot
-
-[pypi]: http://pypi.python.org/pypi/calibcant/
-[PDepgraph.py]:
-  http://code.google.com/p/yjl/source/browse/Miscellaneous/PDepGraph.py
-
-[[!tag tags/code]]
-[[!tag tags/linux]]
-[[!tag tags/programming]]
-[[!tag tags/pypi]]
-[[!tag tags/python]]
diff --git a/posts/calibcant.mdwn_itex b/posts/calibcant.mdwn_itex
new file mode 100644 (file)
index 0000000..a08b02e
--- /dev/null
@@ -0,0 +1,104 @@
+[[!meta  title="calibcant"]]
+[[!template id=gitrepo repo=calibcant]]
+
+Here is my Python module for AFM cantilever calibration via the
+thermal tune method.
+
+The `README` is posted on the [PyPI page][pypi], and you might also be
+interested in the [[package dependency graph|calibcant.svg]] generated
+with Yu-Jie Lin's [PDepGraph.py][]:
+
+    $ IGNORED=matplotlib,scipy,numpy,pyyaml,h5py,python,eselect-python
+    $ python PDepGraph.py -o calibcant.dot -D "$IGNORED" calibcant
+    $ dot -T svg -o calibcant.svg calibcant.dot
+
+Thermal calibration requires three separate measurements: photodiode
+sensitivity (via surface bumps), fluid temperature (estimated, or via
+thermocouple), and thermal vibration (watching the cantilever vibrate
+in far from the surface).  The calibcant package takes [[repeated
+measurements|statistics.png]] of each of these parameters to allow
+estimation of statistical uncertainty:
+
+    $ calibcant-analyze.py calibcant/examples/calibration.h5
+    ...
+    ... variable (units)         : mean +/- std. dev. (relative error)
+    ... cantilever k (N/m)       : 0.0629167 +/- 0.00439057 (0.0697838)
+    ... photo sensitivity (V/m)  : 2.4535e+07 +/- 616119 (0.0251118)
+    ... T (K)                    : 295.15 +/- 0 (0)
+    ... vibration variance (V^2) : 3.89882e-05 +/- 1.88897e-06 (0.0484497)
+               ...
+
+While this cannot account for systematic errors, calibration numbers
+are fairly meaninless without at least statistical error estimates.
+
+Extracting the photodiode sensitivity and thermal deflection variance
+from the raw data can vary a suprising amount depending on your
+cantilever/photodiode linearity and drift and signal/noise ratio in
+the vibration data.  To help deal with this, calibcant provides a
+choice of models for fitting each measurement type.
+
+The contact region of surface bumps can be fit with either linear or
+quadratic models.  Here is an example of a single surface bump fit
+with a quadratic model.  The green line is the initial guess (before
+fitting), the red line is the final model (after fitting), and the
+blue dots are measured data points.
+
+[[!img bump.png alt="Surface bump for photodiode sensitivity"
+  title="Surface bump for photodiode sensitivity" ]]
+
+Extracting the thermal vibration variance is also trickier than it
+might seem.  Fitting the data in frequency-space to a Lorentzian
+([Breit-Wigner][]?)  model helps filter out low frequency drift, as
+well as white noise from the measurement equipment.
+
+\[
+  \text{PSD}(x, \omega) =
+    \frac{2 k_BT \beta}
+         { \pi m \left[{(\omega_0^2-\omega^2)^2 + \beta^2\omega^2}\right] }
+    + N \;.
+\]
+
+where $\beta$ and $\omega_0$ come from the damped-forced harmonic
+oscillator equation of motion
+
+\[
+  \ddot{x} + \beta \dot{x} + \omega_0^2 x = \frac{F(t)}{m} \;,
+\]
+
+$m$ is the cantilever's effective mass, and $N$ is an optional
+white-noise offset.
+
+Here is an example of a one-second thermal vibration fit with the
+offset Breit-Wigner model.  The top panel is the time-series
+deflection voltage (bits vs sample index).  The center pannel is a
+histogram of the deflection voltage, showing an approximately Gaussian
+distribution.  The bottom panel shows the power spectral density fit
+(red dots) fit with an offset Breit-Wigner model (blue curve).  The
+horizontal blue line marks the white-noise offset, and the vertical
+blue line marks the resonant frequency.  Points outside the light blue
+region were not considered during the fitting.  This allows us to
+isolate the cantilever's thermal vibration from other noise sources,
+which leads to more accurate and reproducible spring constant
+estimates.
+
+[[!img bump.png alt="Surface bump for photodiode sensitivity"
+  title="Surface bump for photodiode sensitivity" ]]
+
+
+Finally, all data and analysis results are stored in the standard,
+portable [[HDF5]] file format, so it's easy to reanalyze earlier
+calibration data with different models if you decide to do so at a
+later date, or just look back and see exactly what calculations went
+into your spring constant calibration in the first place.
+
+[pypi]: http://pypi.python.org/pypi/calibcant/
+[PDepgraph.py]:
+  http://code.google.com/p/yjl/source/browse/Miscellaneous/PDepGraph.py
+[Breit-Wigner]:
+  http://en.wikipedia.org/wiki/Relativistic_Breit%E2%80%93Wigner_distribution
+
+[[!tag tags/code]]
+[[!tag tags/linux]]
+[[!tag tags/programming]]
+[[!tag tags/pypi]]
+[[!tag tags/python]]
diff --git a/posts/calibcant/bump.png b/posts/calibcant/bump.png
new file mode 100644 (file)
index 0000000..980a700
Binary files /dev/null and b/posts/calibcant/bump.png differ
diff --git a/posts/calibcant/statistics.png b/posts/calibcant/statistics.png
new file mode 100644 (file)
index 0000000..710c279
Binary files /dev/null and b/posts/calibcant/statistics.png differ
diff --git a/posts/calibcant/vibration.png b/posts/calibcant/vibration.png
new file mode 100644 (file)
index 0000000..0e0ef49
Binary files /dev/null and b/posts/calibcant/vibration.png differ