2 # calibcant - tools for thermally calibrating AFM cantilevers
6 """Run a cantilever calibration using the default AFM
7 (``pyafm.storage.load_afm()``).
10 import argparse as _argparse
14 from pyafm.storage import load_afm as _load_afm
16 from calibcant.calibrate import Calibrator as _Calibrator
17 import calibcant.config as _config
23 parser = _argparse.ArgumentParser(description=_module_doc)
25 '--num-bumps', type=int,
26 help='Number of surface bumps')
28 '--num-temperatures', type=int,
29 help='Number of temperature measurements')
31 '--num-vibrations', type=int,
32 help='Number of thermal vibration measurements')
34 args = parser.parse_args(args)
36 timestamp = '{0}-{1:02d}-{2:02d}T{3:02d}-{4:02d}-{5:02d}'.format(
38 filename = '{}-calibcant-data.h5'.format(timestamp)
39 config = _config.CalibrateConfig()
40 config['bump'] = _config.BumpConfig()
41 config['bump'].update(
42 {'model':_config.Linear, 'initial-position':-150e-9})
43 config['temperature'] = _config.TemperatureConfig()
44 config['vibration'] = _config.VibrationConfig()
45 if args.num_bumps is None:
46 args.num_bumps = config['num-bumps']
48 config['num-bumps'] = args.num_bumps
49 if args.num_temperatures is None:
50 args.num_temperatures = config['num-temperatures']
52 config['num-temperatures'] = args.num_temperatures
53 if args.num_vibrations is None:
54 args.num_vibrations = config['num-vibrations']
56 config['num-vibrations'] = args.num_vibrations
57 insufficient_calibration_data = 0 in [
58 args.num_bumps, args.num_temperatures, args.num_vibrations]
62 afm.load_from_config(devices=devices)
63 calibrator = _Calibrator(config=config, afm=afm)
64 calibrator.setup_config()
65 deflection = afm.piezo.read_deflection()
67 position,deflection = afm.stepper_approach(
68 target_deflection=deflection + 1e3, record_data=True)
69 with _h5py.File(filename) as f:
70 f['/approach/position'] = position
71 f['/approach/deflection'] = deflection
72 if insufficient_calibration_data:
73 data = calibrator.acquire(filename=filename)
75 k,k_s,data = calibrator.calibrate(filename=filename)
77 afm.move_away_from_surface()
81 for device in devices:
83 if insufficient_calibration_data:
84 for count,field,label in [
85 (args.num_bumps, 'bump', 'photodiode sensitivity (V/m)'),
86 (args.num_temperatures, 'temperature', 'temperature (K)'),
87 (args.num_vibrations, 'vibration', 'variance (V**2)')]:
90 print('{}: {:g} +/- {:g}'.format(label, d.mean(), d.std()))
92 print('k: {:g} +/- {:g}'.format(k, k_s))
95 if __name__ == '__main__':
98 sys.exit(main(sys.argv[1:]))