Add --num-* arguments to calibcant-calibrate.py.
authorW. Trevor King <wking@tremily.us>
Fri, 17 Aug 2012 18:51:30 +0000 (14:51 -0400)
committerW. Trevor King <wking@tremily.us>
Fri, 17 Aug 2012 18:51:30 +0000 (14:51 -0400)
This allows you to adjust the number of surface bumps, temperature
measurements, and thermal vibration measurements from the command
line, which is much more convenient than editing the calibcant.config
file directly.

You can also skip a troublesome phase.  For example, if you want to
look at the vibration data without running surface bumps, you can try:

  $ calibcant-calibrate.py --num-bumps 0
  $ calibcant-plot.py *.h5

I adjusted analyze_all() so it can keep working even with one of the
num-* configs set to zero, although you won't be able to get a valid
calibration without at least one of each type of measurement.

bin/calibcant-calibrate.py
calibcant/analyze.py

index 3d20ab3dd0127ce1b145fcd227d137a3982927b9..5cf5a92f78570f7234e102866b9a64fd22a1c20d 100755 (executable)
@@ -7,7 +7,7 @@
 (``pyafm.storage.load_afm()``).
 """
 
-import os
+import argparse as _argparse
 import time as _time
 
 from calibcant.calibrate import Calibrator as _Calibrator
@@ -15,7 +15,22 @@ from pyafm.storage import load_afm as _load_afm
 import calibcant.config as _config
 
 
+_module_doc = __doc__
+
 def main(args):
+    parser = _argparse.ArgumentParser(description=_module_doc)
+    parser.add_argument(
+        '--num-bumps', type=int,
+        help='Number of surface bumps')
+    parser.add_argument(
+        '--num-temperatures', type=int,
+        help='Number of temperature measurements')
+    parser.add_argument(
+        '--num-vibrations', type=int,
+        help='Number of thermal vibration measurements')
+
+    args = parser.parse_args(args)
+
     timestamp = '{0}-{1:02d}-{2:02d}T{3:02d}-{4:02d}-{5:02d}'.format(
         *_time.localtime())
     filename = '{}-calibcant-data.h5'.format(timestamp)
@@ -25,6 +40,20 @@ def main(args):
         {'model':_config.Linear, 'initial-position':-150e-9})
     config['temperature'] = _config.TemperatureConfig()
     config['vibration'] = _config.VibrationConfig()
+    if args.num_bumps is None:
+        args.num_bumps = config['num-bumps']
+    else:
+        config['num-bumps'] = args.num_bumps
+    if args.num_temperatures is None:
+        args.num_temperatures = config['num-temperatures']
+    else:
+        config['num-temperatures'] = args.num_temperatures
+    if args.num_vibrations is None:
+        args.num_vibrations = config['num-vibrations']
+    else:
+        config['num-vibrations'] = args.num_vibrations
+    insufficient_calibration_data = 0 in [
+        args.num_bumps, args.num_temperatures, args.num_vibrations]
     devices = []
     try:
         afm = _load_afm()
@@ -34,7 +63,10 @@ def main(args):
         deflection = afm.piezo.read_deflection()
         try:
             afm.stepper_approach(target_deflection=deflection + 1e3)
-            k,k_s,data = calibrator.calibrate(filename=filename)
+            if insufficient_calibration_data:
+                data = calibrator.acquire(filename=filename)
+            else:
+                k,k_s,data = calibrator.calibrate(filename=filename)
         except:
             afm.move_away_from_surface()
             afm.piezo.zero()
@@ -42,7 +74,16 @@ def main(args):
     finally:
         for device in devices:
             device.close()
-    print 'k: {:g} +/- {:g}'.format(k, k_s)
+    if insufficient_calibration_data:
+        for count,field,label in [
+            (args.num_bumps, 'bump', 'photodiode sensitivity (V/m)'),
+            (args.num_temperatures, 'temperature', 'temperature (K)'),
+            (args.num_vibrations, 'vibration', 'variance (V**2)')]:
+            if count:
+                d = data[field]
+                print('{}: {:g} +/- {:g}'.format(label, d.mean(), d.std()))
+    else:
+        print('k: {:g} +/- {:g}'.format(k, k_s))
     return 0
 
 if __name__ == '__main__':
index f8d1bdd6b7620d657e2ecb0fab7e498997b79049..ec33d5687c8d5302303ed5a65b911f2cd0ef3d33 100644 (file)
@@ -224,13 +224,22 @@ def analyze_all(config, data, raw_data, maximum_relative_error=1e-5,
     if not data.get('vibrations', None):
         data['vibration'] = _numpy.zeros(
                 (config['num-vibrations'],), dtype=float)
+    if 'raw' not in data:
+        data['raw'] = {}
+    if 'bump' not in data['raw']:
+        data['raw']['bump'] = _numpy.zeros((config['num-bumps'],), dtype=float)
+    if 'temperature' not in data['raw']:
+        data['raw']['temperature'] = _numpy.zeros(
+        (config['num-temperatures'],), dtype=float)
+    if 'vibration' not in data['raw']:
+        data['raw']['vibration'] = _numpy.zeros(
+        (config['num-vibrations'],), dtype=float)
     axis_config = config['afm']['piezo'].select_config(
         setting_name='axes',
         attribute_value=config['afm']['main-axis'],
         get_attribute=_get_axis_name)
     input_config = config['afm']['piezo'].select_config(
         setting_name='inputs', attribute_value='deflection')
-    bumps_changed = temperatures_changed = vibrations_changed = False
     calibration_group = None
     if not isinstance(group, _h5py.Group) and not dry_run:
         f = _h5py.File(filename, mode='a')
@@ -238,9 +247,8 @@ def analyze_all(config, data, raw_data, maximum_relative_error=1e-5,
     else:
         f = None
     try:
-        if len(data.get('raw', {}).get('bump', [])) != len(data['bump']):
-            bumps_changed = True
-        for i,bump in enumerate(raw_data['bump']):
+        bumps_changed = len(data['raw']['bump']) != len(data['bump'])
+        for i,bump in enumerate(raw_data.get('bump', [])):  # compare values
             data['bump'][i],changed = check_bump(
                 index=i, bump=bump, config=config, z_axis_config=axis_config,
                 deflection_channel_config=input_config, plot=plot,
@@ -249,10 +257,9 @@ def analyze_all(config, data, raw_data, maximum_relative_error=1e-5,
                 bumps_changed = True
                 bump_group = _h5_create_group(group, 'bump/{}'.format(i))
                 _bump_save(group=bump_group, processed=data['bump'][i])
-        if len(data.get('raw', {}).get('temperature', [])
-               ) != len(data['temperature']):
-            temperatures_changed = True
-        for i,temperature in enumerate(raw_data['temperature']):
+        temperatures_changed = len(data['raw']['temperature']) != len(
+            data['temperature'])
+        for i,temperature in enumerate(raw_data.get('temperature', [])):
             data['temperature'][i],changed = check_temperature(
                 index=i, temperature=temperature, config=config,
                 maximum_relative_error=maximum_relative_error)
@@ -262,10 +269,9 @@ def analyze_all(config, data, raw_data, maximum_relative_error=1e-5,
                     group, 'temperature/{}'.format(i))
                 _temperature_save(
                     group=temperature_group, processed=data['temperature'][i])
-        if len(data.get('raw', {}).get('vibration', [])
-               ) != len(data['vibration']):
-            vibrations_changed = True
-        for i,vibration in enumerate(raw_data['vibration']):
+        vibrations_changed = len(data['raw']['vibration']) != len(
+            data['vibration'])
+        for i,vibration in enumerate(raw_data.get('vibration', [])):
             data['vibration'][i],changed = check_vibration(
                     index=i, vibration=vibration, config=config,
                     deflection_channel_config=input_config, plot=plot,
@@ -288,18 +294,20 @@ def analyze_all(config, data, raw_data, maximum_relative_error=1e-5,
             if vibrations_changed:
                 save_results(
                     group=calibration_group, vibration=data['vibration'])
-        if len(raw_data['bump']) != len(data['bump']):
+        if len(raw_data.get('bump', [])) != len(data['bump']):
             raise ValueError(
                 'not enough raw bump data: {} of {}'.format(
-                    len(raw_data['bump']), len(data['bump'])))
-        if len(raw_data['temperature']) != len(data['temperature']):
+                    len(raw_data.get('bump', [])), len(data['bump'])))
+        if len(raw_data.get('temperature', [])) != len(data['temperature']):
             raise ValueError(
                 'not enough raw temperature data: {} of {}'.format(
-                    len(raw_data['temperature']), len(data['temperature'])))
+                    len(raw_data.get('temperature', [])),
+                    len(data['temperature'])))
         if len(raw_data['vibration']) != len(data['vibration']):
             raise ValueError(
                 'not enough raw vibration data: {} of {}'.format(
-                    len(raw_data['vibration']), len(data['vibration'])))
+                    len(raw_data.get('vibration', [])),
+                    len(data['vibration'])))
         k,k_s,changed = check_calibration(
             k=data.get('processed', {}).get('spring_constant', None),
             k_s=data.get('processed', {}).get(
@@ -317,9 +325,9 @@ def analyze_all(config, data, raw_data, maximum_relative_error=1e-5,
         if f:
             f.close()
     if plot:
-        _plot(bumps=data['raw']['bump'],
-             temperatures=data['raw']['temperature'],
-             vibrations=data['raw']['vibration'])
+        _plot(bumps=data['bump'],
+              temperatures=data['temperature'],
+              vibrations=data['vibration'])
     return (k, k_s)
 
 def check_bump(index, bump, config=None, maximum_relative_error=0, **kwargs):