3 # calibcant - tools for thermally calibrating AFM cantilevers
5 # Copyright (C) 2007,2008, William Trevor King
7 # This program is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU General Public License as
9 # published by the Free Software Foundation; either version 3 of the
10 # License, or (at your option) any later version.
12 # This program is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 # See the GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22 # The author may be contacted at <wking@drexel.edu> on the Internet, or
23 # write to Trevor King, Drexel University, Physics Dept., 3141 Chestnut St.,
24 # Philadelphia PA 19104, USA.
27 Separate the more general T_analyze() from the other T_*()
28 functions in calibcant. Also provide a command line interface
29 for analyzing data acquired through other workflows.
31 The relevant physical quantities are :
32 T Temperature at which thermal vibration measurements were aquired
38 from splittable_kwargs import splittableKwargsFunction, \
39 make_splittable_kwargs_function
46 "Convert Celsius -> Kelvin."
47 return celsius + 273.15
50 "Convert Kelvin -> Kelvin."
53 @splittableKwargsFunction()
54 def T_analyze(T, convert_to_K=C_to_K) :
56 Not much to do here, just convert to Kelvin.
57 Uses C_to_K (defined above) by default.
59 try : # if T is an array, convert element by element
60 for i in range(len(T)) :
61 T[i] = convert_to_K(T[i])
62 except TypeError : # otherwise, make an array from a single T
66 @splittableKwargsFunction()
67 def T_save(T, log_dir=None) :
69 Save either a single T (if you are crazy :p),
70 or an array of them (more reasonable)
72 T = numpy.array(T, dtype=numpy.float)
74 log = data_logger.data_log(log_dir, noclobber_logsubdir=False,
76 log.write_binary(T.tostring())
77 if config.LOG_DATA != None :
78 log = data_logger.data_log(config.LOG_DIR, noclobber_logsubdir=False,
80 log.write_binary(T.tostring())
82 def T_load(datafile=None) :
84 Load the saved T array (possibly of length 1), and return it. If
85 datafile == None, return an array of one config.DEFAULT_TEMP
89 return numpy.array([config.DEFAULT_TEMP], dtype=numpy.float)
91 dl = data_logger.data_load()
92 return dl.read_binary(datafile)
94 @splittableKwargsFunction()
95 def T_plot(T, plotVerbose=False) :
97 Umm, just print the temperature?
99 if plotVerbose or config.PYLAB_VERBOSE or config.TEXT_VERBOSE :
100 print "Temperature ", T
102 @splittableKwargsFunction((T_analyze, 'T', 'convert_to_K'),
104 def T_load_analyze_tweaked(tweak_file, convert_to_K=C_to_K, textVerboseFile=None, **kwargs) :
105 "Load all the T array files from a tweak file and return a single array"
106 T_analyze_kwargs,T_plot_kwargs = \
107 T_load_analyze_tweaked._splitargs(T_load_analyze_tweaked, kwargs)
109 for line in file(tweak_file, 'r') :
110 parsed = line.split()
111 path = parsed[0].strip()
112 if path[0] == '#': # a comment
114 if textVerboseFile != None :
115 print >> textVerboseFile, "Reading data from %s" % (path)
119 T_analyze(Ts, convert_to_K=convert_to_K)
120 return numpy.array(Ts, dtype=numpy.float)
122 # commandline interface functions
125 def read_data(ifile):
126 "ifile can be a filename string or open (seekable) file object"
127 if ifile == None : ifile = sys.stdin
128 unlabeled_data=scipy.io.read_array(ifile)
129 return unlabeled_data
131 if __name__ == '__main__' :
132 # command line interface
133 from optparse import OptionParser
135 usage_string = ('%prog <input-file>\n'
136 '2008, W. Trevor King.\n'
138 'There are two operation modes, one to analyze a single T (temperature) file,\n'
139 'and one to analyze tweak files.\n'
141 'Single file mode (the default) :\n'
142 'Reads in single column ASCII file of temperatures and... prints them back out.\n'
143 'No need to do this, but the option is available for consistency with the other\n'
144 'calibcant modules.\n'
147 'Runs the same analysis as in single file mode for each T file in\n'
148 'a tweak file. Each line in the tweak file specifies a single T file.\n'
149 'Blank lines and those beginning with a pound sign (#) are ignored.\n'
150 'A T file contains a sequence of 32 bit floats representing temperature in K.\n'
152 parser = OptionParser(usage=usage_string, version='%prog 0.1')
153 parser.add_option('-C', '--celsius', dest='celsius',
154 help='Use Celsius input temperatures instead of Kelvin (default %default)\n',
155 action='store_true', default=False)
156 parser.add_option('-o', '--output-file', dest='ofilename',
157 help='write output to FILE (default stdout)',
158 type='string', metavar='FILE')
159 parser.add_option('-c', '--comma-out', dest='comma_out', action='store_true',
160 help='Output comma-seperated values (default %default)',
162 parser.add_option('-t', '--tweak-mode', dest='tweakmode', action='store_true',
163 help='Run in tweak-file mode',
165 parser.add_option('-v', '--verbose', dest='verbose', action='store_true',
166 help='Print lots of debugging information',
169 options,args = parser.parse_args()
171 assert len(args) >= 1, "Need an input file"
175 if options.ofilename != None :
176 ofile = file(options.ofilename, 'w')
179 if options.verbose == True :
183 config.TEXT_VERBOSE = options.verbose
184 config.PYLAB_VERBOSE = False
185 config.GNUPLOT_VERBOSE = False
187 convert_to_K = C_to_K
189 convert_to_K = K_to_K
191 if options.tweakmode == False :
192 data = read_data(ifilename)
193 Ts = T_analyze(data, convert_to_K)
194 else : # tweak file mode
195 Ts = T_load_analyze_tweaked(ifilename, convert_to_K, textVerboseFile=vfile)
197 if options.comma_out :
201 common.write_array(ofile, Ts, sep)
203 if options.ofilename != None :