#
# calibcant - tools for thermally calibrating AFM cantilevers
#
-# Copyright (C) 2007,2008, William Trevor King
+# Copyright (C) 2007-2009 William Trevor King
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
"""
import os, time, numpy
-import GnuplotBiDir # used for fitting lorentzian
-import scipy.optimize # alternative for fitting lorentzian
-import common # common module for the calibcant package
-import config # config module for the calibcant package
+import GnuplotBiDir # can be used for fitting lorentzian
+import scipy.optimize # can be used for fitting lorentzian
+
import data_logger
import FFT_tools
from splittable_kwargs import splittableKwargsFunction, \
make_splittable_kwargs_function
+import .common
+import .config
+
+
PLOT_GUESSED_LORENTZIAN=False
@splittableKwargsFunction()
Vphoto_in2V is a function converting Vphoto values from bits to Volts.
This function is assumed linear, see bump_analyze().
"""
+ if config.TEXT_VERBOSE :
+ print "Calculating the naive (raw) variance"
Vphoto_std_bits = deflection_bits.std()
Vphoto_std = Vphoto_in2V(Vphoto_std_bits + zeroVphoto_bits)
+ if config.TEXT_VERBOSE :
+ print "Average deflection (Volts):", Vphoto_in2V(deflection_bits.mean())
return Vphoto_std**2
#@splittableKwargsFunction((fit_psd, 'freq_axis', 'psd_data'),
print "Converting %d bit values to voltages" % len(Vphoto_t)
for i in range(len(deflection_bits)) :
Vphoto_t[i] = Vphoto_in2V(deflection_bits[i])
-
+ if config.TEXT_VERBOSE :
+ print "Average deflection (Volts):", Vphoto_t.mean()
+
# Compute the average power spectral density per unit time (in uV**2/Hz)
- if config.TEXT_VERBOSE :
+ if config.TEXT_VERBOSE :
print "Compute the averaged power spectral density in uV**2/Hz"
(freq_axis, power) = \
FFT_tools.unitary_avg_power_spectrum((Vphoto_t - Vphoto_t.mean())*1e6,
A,B,C,D = fit_psd(freq_axis, power, **kwargs)
- if config.TEXT_VERBOSE :
+ if config.TEXT_VERBOSE :
print "Fitted f(x) = C / ((A**2-x**2)**2 + (x*B)**2) with"
print "A = %g, \t B = %g, \t C = %g, \t D = %g" % (A, B, C, D)
'minFreq', 'maxFreq'))
@splittableKwargsFunction((vib_analyze, 'deflection_bits', 'freq'))
-def vib_load_analyze_tweaked(tweak_file, **kwargs) :
+def vib_load_analyze_tweaked(tweak_file, analyze=vib_analyze, **kwargs) :
"""
Read the vib files listed in tweak_file.
Return an array of Vphoto variances (due to the cantilever) in Volts**2
"""
- vib_analyze_kwargs, = \
+ analyze_kwargs, = \
vib_load_analyze_tweaked._splitargs(vib_load_analyze_tweaked, kwargs)
dl = data_logger.data_load()
Vphoto_var = []
if config.TEXT_VERBOSE :
print "Analyzing '%s' at %g Hz" % (path, freq)
# analyze
- Vphoto_var.append(vib_analyze(deflection_bits, freq,
- **vib_analyze_kwargs))
+ if 'freq' in analyze._kwargs(analyze):
+ var = analyze(deflection_bits, freq, **analyze_kwargs)
+ else:
+ var = analyze(deflection_bits, **analyze_kwargs)
+ Vphoto_var.append(var)
return numpy.array(Vphoto_var, dtype=numpy.float)
# commandline interface functions
from optparse import OptionParser
usage_string = ('%prog <input-file>\n'
- '2008, W. Trevor King.\n'
+ '2007-2009 W. Trevor King.\n'
+ '\n'
+ 'There are several operation modes, each handling a different <input-file>\n'
+ 'type. In each case, the output is the fitted variance (in square Volts).\n'
'\n'
- 'Deflection power spectral density (PSD) data (X^2/Hz)\n'
- 'and returns the variance in X units (X^2)\n'
- '<input-file> should be 1 column ASCII without a header line.\n'
+ 'Single file mode without datalogger mode (the default) :\n'
+ '<input-file> should be a 1 column ASCII without a header line of cantilever\n'
+ 'deflection (in bits)\n'
'e.g: "<deflection bits>\\n..."\n'
- #TODO, better overview of input modes, e.g. a la T_analyze
+ '\n'
+ 'Single file mode with datalogger mode :\n'
+ 'Same as without datalogger mode, except the input should be a datalogger file\n'
+ 'with data stored in bits (e.g. as saved by the unfold module).\n'
+ '\n'
+ 'Tweak file mode:\n'
+ 'Runs the same analysis as in single file mode for each vib file in a tweak\n'
+ 'file. Each line in the tweak file specifies a single vib file. Blank lines\n'
+ 'and those beginning with a pound sign (#) are ignored. Vib files are valid\n'
+ 'datalogger files as per single-file-with-datalogger-mode.\n'
)
parser = OptionParser(usage=usage_string, version='%prog 0.1')
parser.add_option('-f', '--sample-freq', dest='freq', default=100e3,
parser.add_option('-d', '--datalogger-mode', dest='datalogger_mode', action='store_true',
help='Read input files with datalogger.read_dict_of_arrays(). This is useful, for example, to test a single line from a tweakfile.',
default=False)
+ parser.add_option('-s', '--disable-spectrum-fitting', dest='spectrum_fitting',
+ action='store_false',
+ help='Disable PSD fitting, just use the raw variance',
+ default=True)
parser.add_option('-v', '--verbose', dest='verbose', action='store_true',
help='Print lots of debugging information',
default=False)
config.PYLAB_VERBOSE = options.pylab
config.GNUPLOT_VERBOSE = options.gnuplot
PLOT_GUESSED_LORENTZIAN = options.plot_guess
+ if options.spectrum_fitting == True:
+ analyze = vib_analyze
+ analyze_args = {'freq':options.freq,
+ 'minFreq':options.min_freq,
+ 'maxFreq':options.max_freq}
+ else:
+ analyze = vib_analyze_naive
+ analyze_args = dict()
+ make_splittable_kwargs_function(vib_load_analyze_tweaked,
+ (vib_analyze, 'deflection_bits'))
- if options.tweakmode == False :
+ if options.tweakmode == False : # single file mode
if options.datalogger_mode:
data = vib_load(ifilename)
deflection_bits = data['Deflection input']
else:
deflection_bits = read_data(ifilename)
- Vphoto_var = vib_analyze(deflection_bits, freq=options.freq,
- minFreq=options.min_freq,
- maxFreq=options.max_freq)
+ Vphoto_var = analyze(deflection_bits, **analyze_args)
print >> ofile, Vphoto_var
else : # tweak mode
- Vphoto_vars = vib_load_analyze_tweaked(ifilename,
- minFreq=options.min_freq,
- maxFreq=options.max_freq)
+ if 'freq' in analyze_args:
+ analyze_args.pop('freq') # freq extracted from vib file names
+ Vphoto_vars = vib_load_analyze_tweaked(ifilename, analyze=analyze,
+ **analyze_args)
if options.comma_out :
sep = ','
else :
if options.ofilename != None :
ofile.close()
-
+
+# LocalWords: calibcant AFM