Convert calibcant to the new, nestable h5config.
authorW. Trevor King <wking@drexel.edu>
Thu, 15 Sep 2011 12:17:14 +0000 (08:17 -0400)
committerW. Trevor King <wking@drexel.edu>
Thu, 15 Sep 2011 12:17:14 +0000 (08:17 -0400)
calibcant/T.py
calibcant/T_analyze.py
calibcant/analyze.py
calibcant/bump.py
calibcant/bump_analyze.py
calibcant/calibrate.py
calibcant/config.py
calibcant/vib.py
calibcant/vib_analyze.py

index 5898a8c19daf44b069d20a3cd121761074770566..bf3c29dd5f799f1196f29e9b66aec19443770f53 100644 (file)
@@ -29,14 +29,14 @@ def T(get_T, temperature_config, filename, group='/'):
 
     >>> import os
     >>> import tempfile
-    >>> from h5config.hdf5 import pprint_HDF5
-    >>> from .config import HDF5_TemperatureConfig
+    >>> from h5config.storage.hdf5 import HDF5_Storage, pprint_HDF5
+    >>> from .config import TemperatureConfig
 
     >>> fd,filename = tempfile.mkstemp(suffix='.h5', prefix='calibcant-')
     >>> os.close(fd)
 
-    >>> temperature_config = HDF5_TemperatureConfig(
-    ...     filename=filename, group='/T/config/')
+    >>> temperature_config = TemperatureConfig(storage=HDF5_Storage(
+    ...         filename=filename, group='/T/config/'))
     >>> def get_T():
     ...     return 19.2
     >>> t = T(get_T=get_T, temperature_config=temperature_config,
@@ -45,8 +45,8 @@ def T(get_T, temperature_config, filename, group='/'):
     /
       /T
         /T/config
-          <HDF5 dataset "default": shape (), type "|S2">
-            no
+          <HDF5 dataset "default": shape (), type "|b1">
+            False
           <HDF5 dataset "units": shape (), type "|S7">
             Celsius
         <HDF5 dataset "processed": shape (), type "<f8">
@@ -59,8 +59,8 @@ def T(get_T, temperature_config, filename, group='/'):
     /
       /T
         /T/config
-          <HDF5 dataset "default": shape (), type "|S3">
-            yes
+          <HDF5 dataset "default": shape (), type "|b1">
+            True
           <HDF5 dataset "units": shape (), type "|S7">
             Celsius
         <HDF5 dataset "processed": shape (), type "<f8">
index 4831eacfde17e49393ee5adfccf9abcd7cf34a67..d03bf4d505ce7585b2049e883ececa0ab64a3edf 100644 (file)
@@ -30,14 +30,14 @@ The relevant physical quantities are:
 >>> import os
 >>> import tempfile
 >>> import numpy
->>> from .config import HDF5_TemperatureConfig
->>> from h5config.hdf5 import pprint_HDF5
+>>> from .config import TemperatureConfig
+>>> from h5config.storage.hdf5 import pprint_HDF5, HDF5_Storage
 
 >>> fd,filename = tempfile.mkstemp(suffix='.h5', prefix='calibcant-')
 >>> os.close(fd)
 
->>> temperature_config = HDF5_TemperatureConfig(
-...     filename=filename, group='/T/config/')
+>>> temperature_config = TemperatureConfig(storage=HDF5_Storage(
+...         filename=filename, group='/T/config/'))
 
 >>> raw_T = numpy.array([22, 23.5, 24])
 >>> processed_T = T_analyze(raw_T, temperature_config)
@@ -49,8 +49,8 @@ The relevant physical quantities are:
 /
   /T
     /T/config
-      <HDF5 dataset "default": shape (), type "|S3">
-        yes
+      <HDF5 dataset "default": shape (), type "|b1">
+        True
       <HDF5 dataset "units": shape (), type "|S7">
         Celsius
     <HDF5 dataset "processed": shape (3,), type "<f8">
@@ -84,13 +84,14 @@ except (ImportError, RuntimeError), e:
     _matplotlib = None
     _matplotlib_import_error = e
 
-from h5config.hdf5 import h5_create_group as _h5_create_group
+from h5config.storage.hdf5 import HDF5_Storage as _HDF5_Storage
+from h5config.storage.hdf5 import h5_create_group as _h5_create_group
 
 from . import LOG as _LOG
 from . import package_config as _package_config
 from .config import Celsius as _Celsius
 from .config import Kelvin as _Kelvin
-from .config import HDF5_TemperatureConfig as _HDF5_TemperatureConfig
+from .config import TemperatureConfig as _TemperatureConfig
 
 
 def T_analyze(T, temperature_config):
@@ -132,8 +133,8 @@ def T_load(filename, group='/'):
             raw_T = f[group+'raw'][...]
         except KeyError:
             pass
-        temperature_config = _HDF5_TemperatureConfig(
-            filename=filename, group=group+'config/')
+        temperature_config = _TemperatureConfig(storage=_HDF5_Storage(
+                filename=filename, group=group+'config/'))
         try:
             processed_T = f[group+'processed'][...]
         except KeyError:
index d32e7faf72ee8fbb0cdc8a4067a0a097b8b52385..e29d6c70f0fb016ada5356b35d6f844352445da9 100644 (file)
@@ -44,13 +44,14 @@ Which are related by the parameters:
 >>> import os
 >>> import tempfile
 >>> import numpy
->>> from h5config.hdf5 import pprint_HDF5
->>> from .config import HDF5_CalibrationConfig
+>>> from h5config.storage.hdf5 import HDF5_Storage, pprint_HDF5
+>>> from .config import CalibrationConfig
 
 >>> fd,filename = tempfile.mkstemp(suffix='.h5', prefix='calibcant-')
 >>> os.close(fd)
 
->>> calibration_config = HDF5_CalibrationConfig(filename, '/calib/config/')
+>>> calibration_config = CalibrationConfig(storage=HDF5_Storage(
+...         filename=filename, group='/calib/config/'))
 >>> bumps = numpy.array((15.9e6, 16.9e6, 16.3e6))
 >>> temperatures = numpy.array((295, 295.2, 294.8))
 >>> vibrations = numpy.array((2.20e-5, 2.22e-5, 2.21e-5))
@@ -79,15 +80,21 @@ photodiode sensitivity (bumps).
 /
   /calib
     /calib/config
-      <HDF5 dataset "num-bumps": shape (), type "|S2">
+      <HDF5 dataset "bump": shape (), type "|S1">
+<BLANKLINE>
+      <HDF5 dataset "num-bumps": shape (), type "<i4">
         10
-      <HDF5 dataset "num-temperatures": shape (), type "|S2">
+      <HDF5 dataset "num-temperatures": shape (), type "<i4">
         10
-      <HDF5 dataset "num-vibrations": shape (), type "|S2">
+      <HDF5 dataset "num-vibrations": shape (), type "<i4">
         20
-      <HDF5 dataset "temperature-sleep": shape (), type "|S1">
+      <HDF5 dataset "temperature": shape (), type "|S1">
+<BLANKLINE>
+      <HDF5 dataset "temperature-sleep": shape (), type "<i4">
         1
-      <HDF5 dataset "vibration-spacing": shape (), type "|S5">
+      <HDF5 dataset "vibration": shape (), type "|S1">
+<BLANKLINE>
+      <HDF5 dataset "vibration-spacing": shape (), type "<f8">
         5e-05
     /calib/processed
       /calib/processed/spring-constant
@@ -140,14 +147,15 @@ except (ImportError, RuntimeError), e:
     _matplotlib = None
     _matplotlib_import_error = e
 
-from h5config.hdf5 import h5_create_group as _h5_create_group
+from h5config.storage.hdf5 import HDF5_Storage as _HDF5_Storage
+from h5config.storage.hdf5 import h5_create_group as _h5_create_group
 
 from . import LOG as _LOG
 from . import package_config as _package_config
 from .bump_analyze import bump_analyze as _bump_analyze
 from .bump_analyze import bump_load as _bump_load
 from .bump_analyze import bump_save as _bump_save
-from .config import HDF5_CalibrationConfig as _HDF5_CalibrationConfig
+from .config import CalibrationConfig as _CalibrationConfig
 from .T_analyze import T_analyze as _temperature_analyze
 from .T_analyze import T_load as _temperature_load
 from .T_analyze import T_save as _temperature_save
@@ -303,8 +311,8 @@ def calib_load(filename, group='/'):
             k_s = f[group+'processed/spring-constant/standard-deviation'][...]
         except KeyError:
             pass
-    calibration_config = _HDF5_CalibrationConfig(
-        filename=filename, group=group+'config/')
+    calibration_config = _CalibrationConfig(storage=_HDF5_Storage(
+            filename=filename, group=group+'config/'))
     calibration_config.load()
     return (bumps, temperatures, vibrations, calibration_config, k, k_s)
 
index 8cf78ad34dd321b08a28612c7ed474aad1f31b2e..1e2a5b0f97009d3e001b72d2ccacffff1aa27961 100644 (file)
@@ -123,17 +123,17 @@ def bump(afm, bump_config, filename, group='/'):
 
     >>> import os
     >>> import tempfile
+    >>> from h5config.storage.hdf5 import HDF5_Storage, pprint_HDF5
     >>> from pycomedi.device import Device
     >>> from pycomedi.subdevice import StreamingSubdevice
     >>> from pycomedi.channel import AnalogChannel, DigitalChannel
     >>> from pycomedi.constant import AREF, IO_DIRECTION, SUBDEVICE_TYPE, UNIT
     >>> from pypiezo.afm import AFMPiezo
     >>> from pypiezo.base import PiezoAxis, InputChannel
-    >>> from pypiezo.config import (HDF5_ChannelConfig, HDF5_AxisConfig,
-    ...     pprint_HDF5)
+    >>> from pypiezo.config import ChannelConfig, AxisConfig
     >>> from stepper import Stepper
     >>> from pyafm import AFM
-    >>> from .config import HDF5_BumpConfig
+    >>> from .config import BumpConfig
 
     >>> fd,filename = tempfile.mkstemp(suffix='.h5', prefix='calibcant-')
     >>> os.close(fd)
@@ -161,13 +161,14 @@ def bump(afm, bump_config, filename, group='/'):
     first few surface approaching steps, which could lead to an
     `EdgeKink` error instead of a `FlatFit` error.
 
-    >>> axis_config = HDF5_AxisConfig(filename, '/bump/config/z/axis')
+    >>> axis_config = AxisConfig(storage=HDF5_Storage(
+    ...         filename=filename, group='/bump/config/z/axis'))
     >>> axis_config.update(
     ...     {'gain':20, 'sensitivity':8e-9, 'minimum':-9})
-    >>> axis_channel_config = HDF5_ChannelConfig(
-    ...     filename, '/bump/config/z/channel')
-    >>> input_channel_config = HDF5_ChannelConfig(
-    ...     filename, '/bump/config/deflection/channel')
+    >>> axis_channel_config = ChannelConfig(storage=HDF5_Storage(
+    ...         filename=filename, group='/bump/config/z/channel'))
+    >>> input_channel_config = ChannelConfig(storage=HDF5_Storage(
+    ...         filename=filename, group='/bump/config/deflection/channel'))
 
     >>> a = PiezoAxis(axis_config=axis_config,
     ...     axis_channel_config=axis_channel_config,
@@ -200,8 +201,8 @@ def bump(afm, bump_config, filename, group='/'):
 
     Test a bump:
 
-    >>> bump_config = HDF5_BumpConfig(
-    ...     filename=filename, group='/bump/config/bump')
+    >>> bump_config = BumpConfig(storage=HDF5_Storage(
+    ...         filename=filename, group='/bump/config/bump'))
     >>> bump(afm, bump_config, filename, group='/bump')
     TODO: replace skipped example data with real-world values
     >>> pprint_HDF5(filename)  # doctest: +ELLIPSIS, +REPORT_UDIFF
index 05ef0b0ab872b617d48805583543e6c4e781f60e..ab745b812db66439353bada260fd8744e72d0bb6 100644 (file)
@@ -46,20 +46,23 @@ measured slope `Vphoto/Vout` is converted to `photo_sensitivity` with
 >>> from pprint import pprint
 >>> import tempfile
 >>> import numpy
->>> from .config import HDF5_BumpConfig
->>> from h5config.hdf5 import pprint_HDF5, HDF5_ChannelConfig, HDF5_AxisConfig
+>>> from h5config.storage.hdf5 import pprint_HDF5
+>>> from pypiezo.config import ChannelConfig, AxisConfig
+>>> from .config import BumpConfig
 
 >>> fd,filename = tempfile.mkstemp(suffix='.h5', prefix='calibcant-')
 >>> os.close(fd)
 
->>> bump_config = HDF5_BumpConfig(filename=filename, group='/bump/config/')
->>> bump_config.save()
->>> z_channel_config = HDF5_ChannelConfig(filename=None)
+>>> bump_config = BumpConfig()
+>>> z_channel_config = ChannelConfig()
+>>> z_channel_config['name'] = 'z'
 >>> z_channel_config['maxdata'] = 200
 >>> z_channel_config['conversion-coefficients'] = (0,1)
 >>> z_channel_config['conversion-origin'] = 0
->>> z_axis_config = HDF5_AxisConfig(filename=None)
->>> deflection_channel_config = HDF5_ChannelConfig(filename=None)
+>>> z_axis_config = AxisConfig()
+>>> z_axis_config['channel'] = z_channel_config
+>>> deflection_channel_config = ChannelConfig()
+>>> deflection_channel_config['name'] = 'deflection'
 >>> deflection_channel_config['maxdata'] = 200
 >>> deflection_channel_config['conversion-coefficients'] = (0,1)
 >>> deflection_channel_config['conversion-origin'] = 0
@@ -70,11 +73,10 @@ measured slope `Vphoto/Vout` is converted to `photo_sensitivity` with
 ...     }
 >>> raw_bump['deflection'][:50] = 50
 >>> processed_bump = bump_analyze(
-...     raw_bump, bump_config, z_channel_config, z_axis_config,
-...     deflection_channel_config)
+...     raw_bump, bump_config, z_axis_config, deflection_channel_config)
 >>> bump_plot(data=raw_bump)  # TODO: convert to V and m
 >>> bump_save(filename=filename, group='/bump/', raw_bump=raw_bump,
-...     z_channel_config=z_channel_config, z_axis_config=z_axis_config,
+...     bump_config=bump_config, z_axis_config=z_axis_config,
 ...     deflection_channel_config=deflection_channel_config,
 ...     processed_bump=processed_bump)
 
@@ -82,80 +84,84 @@ measured slope `Vphoto/Vout` is converted to `photo_sensitivity` with
 /
   /bump
     /bump/config
+      /bump/config/bump
+        <HDF5 dataset "far-steps": shape (), type "<i4">
+          200
+        <HDF5 dataset "model": shape (), type "|S9">
+          quadratic
+        <HDF5 dataset "push-depth": shape (), type "<f8">
+          2e-07
+        <HDF5 dataset "push-speed": shape (), type "<f8">
+          1e-06
+        <HDF5 dataset "samples": shape (), type "<i4">
+          1024
+        <HDF5 dataset "setpoint": shape (), type "<f8">
+          2.0
       /bump/config/deflection
         /bump/config/deflection/channel
-          <HDF5 dataset "channel": shape (), type "|S1">
+          <HDF5 dataset "channel": shape (), type "<i4">
             0
-          <HDF5 dataset "conversion-coefficients": shape (), type "|S4">
-            0, 1
-          <HDF5 dataset "conversion-origin": shape (), type "|S1">
+          <HDF5 dataset "conversion-coefficients": shape (2,), type "<i4">
+            [0 1]
+          <HDF5 dataset "conversion-origin": shape (), type "<i4">
             0
           <HDF5 dataset "device": shape (), type "|S12">
             /dev/comedi0
           <HDF5 dataset "inverse-conversion-coefficients": shape (), type "|S1">
 <BLANKLINE>
-          <HDF5 dataset "inverse-conversion-origin": shape (), type "|S3">
+          <HDF5 dataset "inverse-conversion-origin": shape (), type "<f8">
             1.0
-          <HDF5 dataset "maxdata": shape (), type "|S3">
+          <HDF5 dataset "maxdata": shape (), type "<i4">
             200
-          <HDF5 dataset "range": shape (), type "|S1">
+          <HDF5 dataset "name": shape (), type "|S10">
+            deflection
+          <HDF5 dataset "range": shape (), type "<i4">
             1
-          <HDF5 dataset "subdevice": shape (), type "|S2">
+          <HDF5 dataset "subdevice": shape (), type "<i4">
             -1
-      <HDF5 dataset "far-steps": shape (), type "|S3">
-        200
-      <HDF5 dataset "initial-position": shape (), type "|S6">
-        -5e-08
-      <HDF5 dataset "model": shape (), type "|S9">
-        quadratic
-      <HDF5 dataset "push-depth": shape (), type "|S5">
-        2e-07
-      <HDF5 dataset "push-speed": shape (), type "|S5">
-        1e-06
-      <HDF5 dataset "samples": shape (), type "|S4">
-        1024
-      <HDF5 dataset "setpoint": shape (), type "|S3">
-        2.0
       /bump/config/z
         /bump/config/z/axis
-          <HDF5 dataset "gain": shape (), type "|S3">
+          /bump/config/z/axis/channel
+            <HDF5 dataset "channel": shape (), type "<i4">
+              0
+            <HDF5 dataset "conversion-coefficients": shape (2,), type "<i4">
+              [0 1]
+            <HDF5 dataset "conversion-origin": shape (), type "<i4">
+              0
+            <HDF5 dataset "device": shape (), type "|S12">
+              /dev/comedi0
+            <HDF5 dataset "inverse-conversion-coefficients": shape (), type "|S1">
+<BLANKLINE>
+            <HDF5 dataset "inverse-conversion-origin": shape (), type "<f8">
+              1.0
+            <HDF5 dataset "maxdata": shape (), type "<i4">
+              200
+            <HDF5 dataset "name": shape (), type "|S1">
+              z
+            <HDF5 dataset "range": shape (), type "<i4">
+              1
+            <HDF5 dataset "subdevice": shape (), type "<i4">
+              -1
+          <HDF5 dataset "gain": shape (), type "<f8">
             1.0
           <HDF5 dataset "maximum": shape (), type "|S4">
             None
           <HDF5 dataset "minimum": shape (), type "|S4">
             None
-          <HDF5 dataset "sensitivity": shape (), type "|S3">
-            1.0
-        /bump/config/z/channel
-          <HDF5 dataset "channel": shape (), type "|S1">
-            0
-          <HDF5 dataset "conversion-coefficients": shape (), type "|S4">
-            0, 1
-          <HDF5 dataset "conversion-origin": shape (), type "|S1">
-            0
-          <HDF5 dataset "device": shape (), type "|S12">
-            /dev/comedi0
-          <HDF5 dataset "inverse-conversion-coefficients": shape (), type "|S1">
+          <HDF5 dataset "monitor": shape (), type "|S1">
 <BLANKLINE>
-          <HDF5 dataset "inverse-conversion-origin": shape (), type "|S3">
+          <HDF5 dataset "sensitivity": shape (), type "<f8">
             1.0
-          <HDF5 dataset "maxdata": shape (), type "|S3">
-            200
-          <HDF5 dataset "range": shape (), type "|S1">
-            1
-          <HDF5 dataset "subdevice": shape (), type "|S2">
-            -1
     <HDF5 dataset "processed": shape (), type "<f8">
-      1.00000002115
+      1.00...
     /bump/raw
       <HDF5 dataset "deflection": shape (100,), type "<u2">
         [50 50 ... 50 51 52 ... 97 98 99]
       <HDF5 dataset "z": shape (100,), type "<u2">
         [ 0  1  2  3  ... 97 98 99]
 
->>> (raw_bump,bump_config,z_channel_config,z_axis_config,
-...  deflection_channel_config,processed_bump) = bump_load(
-...     filename=filename, group='/bump/')
+>>> (raw_bump,bump_config,z_axis_config,deflection_channel_config,
+...     processed_bump) = bump_load(filename=filename, group='/bump/')
 
 >>> pprint(raw_bump)  # doctest: +ELLIPSIS
 {'deflection': array([50, 50, ... 51, 52, 53, ..., 97, 98, 99], dtype=uint16),
@@ -178,27 +184,27 @@ except (ImportError, RuntimeError), e:
     _matplotlib = None
     _matplotlib_import_error = e
 
-from h5config.hdf5 import h5_create_group as _h5_create_group
+from h5config.storage.hdf5 import HDF5_Storage as _HDF5_Storage
+from h5config.storage.hdf5 import h5_create_group as _h5_create_group
 from pypiezo.base import convert_bits_to_volts as _convert_bits_to_volts
 from pypiezo.base import convert_bits_to_meters as _convert_bits_to_meters
-from pypiezo.config import HDF5_ChannelConfig as _HDF5_ChannelConfig
-from pypiezo.config import HDF5_AxisConfig as _HDF5_AxisConfig
+from pypiezo.config import ChannelConfig as _ChannelConfig
+from pypiezo.config import AxisConfig as _AxisConfig
 
 from . import LOG as _LOG
 from . import package_config as _package_config
 from .config import Linear as _Linear
 from .config import Quadratic as _Quadratic
-from .config import HDF5_BumpConfig as _HDF5_BumpConfig
+from .config import BumpConfig as _BumpConfig
 
 
-def bump_analyze(data, bump_config, z_channel_config, z_axis_config,
+def bump_analyze(data, bump_config, z_axis_config,
                  deflection_channel_config, plot=False):
     """Return the slope of the bump.
 
     Inputs:
       data              dictionary of data in DAC/ADC bits
       bump_config       `.config._BumpConfig` instance
-      z_channel_config  z `pypiezo.config.ChannelConfig` instance
       z_axis_config     z `pypiezo.config.AxisConfig` instance
       deflection_channel_config
                         deflection `pypiezo.config.ChannelConfig` instance
@@ -209,9 +215,11 @@ def bump_analyze(data, bump_config, z_channel_config, z_axis_config,
     Checks for strong correlation (r-value) and low randomness chance
     (p-value).
     """
-    z = _convert_bits_to_meters(z_channel_config, z_axis_config, data['z'])
+    z = _convert_bits_to_meters(z_axis_config, data['z'])
     deflection = _convert_bits_to_volts(
         deflection_channel_config, data['deflection'])
+    high_voltage_rail = _convert_bits_to_volts(
+        deflection_channel_config, deflection_channel_config['maxdata'])
     if bump_config['model'] == _Linear:
         kwargs = {
             'param_guesser': limited_linear_param_guess,
@@ -224,10 +232,12 @@ def bump_analyze(data, bump_config, z_channel_config, z_axis_config,
             'model': limited_quadratic,
             'sensitivity_from_fit_params': limited_quadratic_sensitivity,
             }
-    photo_sensitivity = bump_fit(z, deflection, plot=plot, **kwargs)
+    photo_sensitivity = bump_fit(
+        z, deflection, high_voltage_rail=high_voltage_rail, plot=plot,
+        **kwargs)
     return photo_sensitivity
 
-def limited_linear(x, params):
+def limited_linear(x, params, high_voltage_rail):
     """
     Model the bump as:
       flat region (off-surface)
@@ -238,9 +248,11 @@ def limited_linear(x, params):
       y_contact (y value for the surface-contact kink)
       slope (dy/dx at the surface-contact kink)
     """
-    high_voltage_rail = 2**16 - 1 # bits
     x_contact,y_contact,slope = params
-    y = slope*(x-x_contact) + y_contact
+    off_surface_mask = x <= x_contact
+    on_surface_mask = x > x_contact
+    y = (off_surface_mask * y_contact +
+         on_surface_mask * (y_contact + slope*(x-x_contact)))
     y = _numpy.clip(y, y_contact, high_voltage_rail)
     return y
 
@@ -277,7 +289,7 @@ def limited_linear_sensitivity(params):
     slope = params[2]
     return slope
 
-def limited_quadratic(x, params):
+def limited_quadratic(x, params, high_voltage_rail):
     """
     Model the bump as:
       flat region (off-surface)
@@ -289,9 +301,12 @@ def limited_quadratic(x, params):
       slope (dy/dx at the surface-contact kink)
       quad (d**2 y / dx**2, allow decreasing sensitivity with increased x)
     """
-    high_voltage_rail = 2**16 - 1 # bits
     x_contact,y_contact,slope,quad = params
-    y = slope*(x-x_contact) + quad*(x-x_contact)**2+ y_contact
+    off_surface_mask = x <= x_contact
+    on_surface_mask = x > x_contact
+    y = (off_surface_mask * y_contact +
+         on_surface_mask * (
+            y_contact + slope*(x-x_contact) + quad*(x-x_contact)**2))
     y = _numpy.clip(y, y_contact, high_voltage_rail)
     return y
 
@@ -321,7 +336,7 @@ def limited_quadratic_sensitivity(params):
     slope = params[2]
     return slope
 
-def bump_fit(z, deflection,
+def bump_fit(z, deflection, high_voltage_rail,
              param_guesser=limited_quadratic_param_guess,
              model=limited_quadratic,
              sensitivity_from_fit_params=limited_quadratic_sensitivity,
@@ -340,7 +355,7 @@ def bump_fit(z, deflection,
     """
     _LOG.debug('fit bump data with model %s' % model)
     def residual(p, deflection, z):
-        return model(z, p) - deflection
+        return model(z, p, high_voltage_rail=high_voltage_rail) - deflection
     param_guess = param_guesser(z, deflection)
     p,cov,info,mesg,ier = _leastsq(
         residual, param_guess, args=(deflection, z), full_output=True,
@@ -353,15 +368,15 @@ def bump_fit(z, deflection,
         _LOG.debug('solution converged')
     else:
         _LOG.debug('solution did not converge')
-    if plot or _package_config['matplotlib']:
-        yguess = model(z, param_guess)
-        yfit = model(z, p)
+    if plot or _package_config['matplotlib'] or True:
+        yguess = model(z, param_guess, high_voltage_rail=high_voltage_rail)
+        yfit = model(z, p, high_voltage_rail=high_voltage_rail)
         bump_plot({'z': z, 'deflection': deflection}, yguess=yguess, yfit=yfit)
     return sensitivity_from_fit_params(p)
 
 def bump_save(filename, group='/', raw_bump=None, bump_config=None,
-              z_channel_config=None, z_axis_config=None,
-              deflection_channel_config=None, processed_bump=None):
+              z_axis_config=None, deflection_channel_config=None,
+              processed_bump=None):
     with _h5py.File(filename, 'a') as f:
         cwg = _h5_create_group(f, group)
         if raw_bump is not None:
@@ -372,15 +387,15 @@ def bump_save(filename, group='/', raw_bump=None, bump_config=None,
                     pass
             cwg['raw/z'] = raw_bump['z']
             cwg['raw/deflection'] = raw_bump['deflection']
+        storage = _HDF5_Storage()
         for config,key in [(bump_config, 'config/bump'),
-                           (z_channel_config, 'config/z/channel'),
                            (z_axis_config, 'config/z/axis'),
                            (deflection_channel_config,
                             'config/deflection/channel')]:
             if config is None:
                 continue
             config_cwg = _h5_create_group(cwg, key)
-            config.save(group=config_cwg)
+            storage.save(config=config, group=config_cwg)
         if processed_bump is not None:
             try:
                 del cwg['processed']
@@ -400,11 +415,11 @@ def bump_load(filename, group='/'):
                 }
         except KeyError:
             pass
-        for Config,key in [(_HDF5_BumpConfig, 'config/bump'),
-                           (_HDF5_ChannelConfig, 'config/z/channel'),
-                           (_HDF5_AxisConfig, 'config/z/axis'),
-                           (_HDF5_ChannelConfig, 'config/deflection/channel')]:
-            config = Config(filename=filename, group=group+key)
+        for Config,key in [(_BumpConfig, 'config/bump'),
+                           (_AxisConfig, 'config/z/axis'),
+                           (_ChannelConfig, 'config/deflection/channel')]:
+            config = Config(storage=_HDF5_Storage(
+                    filename=filename, group=group+key))
             configs.append(config)
         try:
             processed_bump = f[group+'processed'][...]
index a3f70580b22f11c2144e0ad02a017756eb8e35c0..426abbf5b686f07143a80b54d2a153eea38cba51 100644 (file)
@@ -116,16 +116,12 @@ def move_far_from_surface(stepper, distance):
     _LOG.info('step back %d steps (~%g m)' % (steps, distance))
     stepper.step_relative(-steps)
 
-def calib_acquire(afm, calibration_config, bump_config, temperature_config,
-                  vibration_config, filename=None, group='/'):
+def calib_acquire(afm, calibration_config, filename=None, group='/'):
     """Acquire data for calibrating a cantilever in one function.
 
     Inputs:
       afm                 a pyafm.AFM instance
       calibration_config  a .config._CalibrationConfig instance
-      bump_config         a .config._BumpConfig instance
-      temperature_config            a .config._TConfig instance
-      vibration_config    a .config._VibrationConfig instance
 
     Outputs (all are arrays of recorded data):
       bumps measured (V_photodiode / nm_tip) proportionality constant
@@ -141,7 +137,7 @@ def calib_acquire(afm, calibration_config, bump_config, temperature_config,
     bumps = _zeros((calibration_config['num-bumps'],), dtype=_float)
     for i in range(calibration_config['num-bumps']):
         _LOG.info('acquire bump %d of %d' % (i, calibration_config['num-bumps']))
-        bumps[i] = _bump(afm=afm, bump_config=bump_config,
+        bumps[i] = _bump(afm=afm, bump_config=calibration_config['bump'],
                          filename=filename, group='%sbump/%d/' % (group, i))
     _LOG.debug('bumps: %s' % bumps)
 
@@ -153,7 +149,8 @@ def calib_acquire(afm, calibration_config, bump_config, temperature_config,
         _LOG.info('acquire T %d of %d'
                  % (i, calibration_config['num-temperatures']))
         Ts[i] = _T(
-            get_T=afm.get_temperature, temperature_config=temperature_config,
+            get_T=afm.get_temperature,
+            temperature_config=calibration_config['temperature'],
             filename=filename, group='%stemperature/%d/' % (group, i))
         _sleep(calibration_config['temperature-sleep'])
     _LOG.debug('temperatures: %s' % Ts)
@@ -162,14 +159,13 @@ def calib_acquire(afm, calibration_config, bump_config, temperature_config,
     vibs = _zeros((calibration_config['num-vibrations'],), dtype=_float)
     for i in range(calibration_config['num-vibrations']):
         vibs[i] = _vib(
-            piezo=afm.piezo, vibration_config=vibration_config,
+            piezo=afm.piezo, vibration_config=calibration_config['vibration'],
             filename=filename, group='%svibration/%d/' % (group, i))
     _LOG.debug('vibrations: %s' % vibs)
 
     return (bumps, Ts, vibs)
 
-def calib(afm, calibration_config, bump_config, temperature_config,
-          vibration_config, filename=None, group='/'):
+def calib(afm, calibration_config, filename=None, group='/'):
     """Calibrate a cantilever in one function.
 
     Inputs:
@@ -182,18 +178,18 @@ def calib(afm, calibration_config, bump_config, temperature_config,
     >>> import os
     >>> from pprint import pprint
     >>> import tempfile
+    >>> from h5config.storage.hdf5 import pprint_HDF5
     >>> from pycomedi.device import Device
     >>> from pycomedi.subdevice import StreamingSubdevice
     >>> from pycomedi.channel import AnalogChannel, DigitalChannel
     >>> from pycomedi.constant import AREF, IO_DIRECTION, SUBDEVICE_TYPE, UNIT
     >>> from pypiezo.afm import AFMPiezo
     >>> from pypiezo.base import PiezoAxis, InputChannel
-    >>> from pypiezo.config import (HDF5_ChannelConfig, HDF5_AxisConfig,
-    ...     pprint_HDF5)
+    >>> from pypiezo.config import ChannelConfig, AxisConfig
     >>> from stepper import Stepper
     >>> from pyafm import AFM
-    >>> from .config import (HDF5_CalibrationConfig, HDF5_BumpConfig,
-    ...     HDF5_TemperatureConfig, HDF5_VibrationConfig)
+    >>> from .config import (CalibrationConfig, BumpConfig,
+    ...     TemperatureConfig, VibrationConfig)
     >>> from .analyze import calib_load_all
 
     >>> fd,filename = tempfile.mkstemp(suffix='.h5', prefix='calibcant-')
@@ -222,13 +218,11 @@ def calib(afm, calibration_config, bump_config, temperature_config,
     first few surface approaching steps, which could lead to an
     `EdgeKink` error instead of a `FlatFit` error.
 
-    >>> axis_config = HDF5_AxisConfig(filename, '/bump/config/z/axis')
+    >>> axis_config = AxisConfig()
     >>> axis_config.update(
     ...     {'gain':20, 'sensitivity':8e-9, 'minimum':-9})
-    >>> axis_channel_config = HDF5_ChannelConfig(
-    ...     filename, '/bump/config/z/channel')
-    >>> input_channel_config = HDF5_ChannelConfig(
-    ...     filename, '/bump/config/deflection/channel')
+    >>> axis_channel_config = ChannelConfig()
+    >>> input_channel_config = ChannelConfig()
 
     >>> a = PiezoAxis(axis_config=axis_config,
     ...     axis_channel_config=axis_channel_config,
@@ -261,14 +255,10 @@ def calib(afm, calibration_config, bump_config, temperature_config,
 
     Test calibration:
 
-    >>> calibration_config = HDF5_CalibrationConfig(
-    ...     filename=filename, group='/bump/config/calibration/')
-    >>> bump_config = HDF5_BumpConfig(
-    ...     filename=filename, group='/bump/config/bump/')
-    >>> temperature_config = HDF5_TemperatureConfig(
-    ...     filename=filename, group='/bump/config/temperature/')
-    >>> vibration_config = HDF5_VibrationConfig(
-    ...     filename=filename, group='/bump/config/vibration')
+    >>> calibration_config = CalibrationConfig()
+    >>> bump_config = BumpConfig()
+    >>> temperature_config = TemperatureConfig()
+    >>> vibration_config = VibrationConfig()
     >>> calib(afm, calibration_config, bump_config, temperature_config,
     ...     vibration_config, filename=filename, group='/')
     TODO: replace skipped example data with real-world values
index 0a20c8f4fd131f43ec95b699bc6bacea4424919b..cffb58f86d369a404d86970ca6e31099ac01889a 100644 (file)
@@ -77,12 +77,6 @@ class Quadratic (_BumpModel):
 class BumpConfig (_config.Config):
     "Configure `calibcant` bump operation"
     settings = [
-        _config.FloatSetting(
-            name='initial-position',
-            help=('Position relative to surface for start of bump in meters.  '
-                  'Should be less than zero to ensure non-contact region '
-                  'before you hit the surface.'),
-            default=-50e-9),
         _config.FloatSetting(
             name='setpoint',
             help=('Maximum deflection in volts in case of stepper positioning '
@@ -116,6 +110,10 @@ class BumpConfig (_config.Config):
                 ]),
         ]
 
+class BumpResult (_config.Config):
+    "The result of a `calibcant` bump operation"
+    
+
 class _VibrationModel (object):
     pass
 class Variance (_VibrationModel):
@@ -174,14 +172,26 @@ class VibrationConfig (_config.Config):
 class CalibrationConfig (_config.Config):
     "Configure a full `calibcant` calibration run"
     settings = [
+        _config.ConfigSetting(
+            name='bump',
+            help='Configure the surface bumps',
+            config_class=BumpConfig),
         _config.IntegerSetting(
             name='num-bumps',
             help='Number of surface bumps.',
             default=10),
+        _config.ConfigSetting(
+            name='temperature',
+            help='Configure the temperature measurements',
+            config_class=TemperatureConfig),
         _config.IntegerSetting(
             name='num-temperatures',
             help='Number of temperature measurements.',
             default=10),
+        _config.ConfigSetting(
+            name='vibration',
+            help='Configure the temperature measurements',
+            config_class=VibrationConfig),
         _config.IntegerSetting(
             name='num-vibrations',
             help='Number of thermal vibration measurements.',
index e57e1bf73f72152ffe7b5385f9a30fcfcee2ce67..608b9b0db4d8e307c948fdff90bb941d0f0245a2 100644 (file)
@@ -89,15 +89,15 @@ def vib(piezo, vibration_config, filename, group='/'):
 
     >>> import os
     >>> import tempfile
-    >>> from h5config.hdf5 import pprint_HDF5
+    >>> from h5config.storage.hdf5 import pprint_HDF5
     >>> from pycomedi.device import Device
     >>> from pycomedi.subdevice import StreamingSubdevice
     >>> from pycomedi.channel import AnalogChannel
     >>> from pycomedi.constant import AREF, SUBDEVICE_TYPE, UNIT
     >>> from pypiezo.afm import AFMPiezo
     >>> from pypiezo.base import InputChannel
-    >>> from pypiezo.config import HDF5_ChannelConfig
-    >>> from .config import HDF5_VibrationConfig
+    >>> from pypiezo.config import ChannelConfig
+    >>> from .config import VibrationConfig
 
     Setup an `AFMPiezo` instance.
 
@@ -113,8 +113,7 @@ def vib(piezo, vibration_config, filename, group='/'):
     >>> channel = s_in.channel(0, factory=AnalogChannel, aref=AREF.diff)
     >>> channel.range = channel.find_range(
     ...     unit=UNIT.volt, min=-10, max=10)
-    >>> channel_config = HDF5_ChannelConfig(
-    ...     filename, group='/vibration/config/deflection/channel')
+    >>> channel_config = ChannelConfig()
 
     >>> c = InputChannel(
     ...     channel_config=channel_config, channel=channel,
@@ -125,8 +124,7 @@ def vib(piezo, vibration_config, filename, group='/'):
 
     Test a vibration:
 
-    >>> vibration_config = HDF5_VibrationConfig(
-    ...     filename=filename, group='/vibration/config/vibration')
+    >>> vibration_config = VibrationConfig()
     >>> vib(piezo, vibration_config, filename, group='/vibration')
     TODO: replace skipped example data with real-world values
     >>> pprint_HDF5(filename)  # doctest: +ELLIPSIS, +REPORT_UDIFF
index 38997a6c414e7809c5d4596750c86e8c3609beeb..6b5d682176fdd023be8c1470cbcedafff2d62d00 100644 (file)
@@ -31,23 +31,17 @@ The relevent physical quantities are :
 >>> import random
 >>> import tempfile
 >>> import numpy
->>> from .config import HDF5_VibrationConfig
->>> from h5config.hdf5 import pprint_HDF5, HDF5_ChannelConfig
+>>> from .config import VibrationConfig
+>>> from h5config.storage.hdf5 import pprint_HDF5
+>>> from pypiezo.test import get_piezo_config
 >>> from pypiezo.base import convert_volts_to_bits
 
 >>> fd,filename = tempfile.mkstemp(suffix='.h5', prefix='calibcant-')
 >>> os.close(fd)
 
->>> vibration_config = HDF5_VibrationConfig(
-...     filename=filename, group='/vibration/config/vibration')
+>>> piezo_config = get_piezo_config()
+>>> vibration_config = VibrationConfig()
 >>> vibration_config['frequency'] = 50e3
->>> vibration_config.save()
->>> deflection_channel_config = HDF5_ChannelConfig(filename=None)
->>> deflection_channel_config['maxdata'] = 200
->>> deflection_channel_config['conversion-coefficients'] = (0,1)
->>> deflection_channel_config['conversion-origin'] = 0
->>> deflection_channel_config['inverse-conversion-coefficients'] = (0,1)
->>> deflection_channel_config['inverse-conversion-origin'] = 0
 
 We'll be generating a test vibration time series with the following
 parameters.  Make sure these are all floats to avoid accidental
@@ -58,7 +52,7 @@ integer division in later steps.
 >>> k = 0.05        # N/m
 >>> T = 1/vibration_config['frequency']
 >>> T  # doctest: +ELLIPSIS
-2.00...e-05
+2...e-05
 >>> N = int(2**15)  # count
 >>> F_sigma = 1e3   # N
 
@@ -134,7 +128,8 @@ Rearranging and shifting to `j=i-1`
 Convert the simulated data to bits.
 
 >>> deflection = x
->>> deflection_bits = convert_volts_to_bits(deflection_channel_config, x)
+>>> deflection_bits = convert_volts_to_bits(
+...     piezo_config.select_config('inputs', 'deflection'), x)
 
 Analyze the simulated data.
 
@@ -145,14 +140,16 @@ Analyze the simulated data.
 True
 
 >>> processed_vibration = vib_analyze(
-...     deflection_bits, vibration_config, deflection_channel_config)
+...     deflection_bits, vibration_config,
+...     piezo_config.select_config('inputs', 'deflection'))
 >>> processed_vibration  # doctest: +SKIP
 136457906.25574699
 
 >>> vib_plot(deflection=deflection_bits, vibration_config=vibration_config)
 >>> vib_save(filename=filename, group='/vibration/',
 ...     raw_vibration=deflection_bits, vibration_config=vibration_config,
-...     deflection_channel_config=deflection_channel_config,
+...     deflection_channel_config=piezo_config.select_config(
+...         'inputs', 'deflection'),
 ...     processed_vibration=processed_vibration)
 
 >>> pprint_HDF5(filename)  # doctest: +ELLIPSIS, +REPORT_UDIFF
@@ -160,38 +157,40 @@ True
   /vibration
     /vibration/config
       /vibration/config/deflection
-        <HDF5 dataset "channel": shape (), type "|S1">
+        <HDF5 dataset "channel": shape (), type "<i4">
           0
-        <HDF5 dataset "conversion-coefficients": shape (), type "|S4">
-          0, 1
-        <HDF5 dataset "conversion-origin": shape (), type "|S1">
+        <HDF5 dataset "conversion-coefficients": shape (2,), type "<i4">
+          [0 1]
+        <HDF5 dataset "conversion-origin": shape (), type "<i4">
           0
         <HDF5 dataset "device": shape (), type "|S12">
           /dev/comedi0
-        <HDF5 dataset "inverse-conversion-coefficients": shape (), type "|S4">
-          0, 1
-        <HDF5 dataset "inverse-conversion-origin": shape (), type "|S1">
+        <HDF5 dataset "inverse-conversion-coefficients": shape (2,), type "<i4">
+          [0 1]
+        <HDF5 dataset "inverse-conversion-origin": shape (), type "<i4">
           0
-        <HDF5 dataset "maxdata": shape (), type "|S3">
-          200
-        <HDF5 dataset "range": shape (), type "|S1">
+        <HDF5 dataset "maxdata": shape (), type "<i4">
+          100
+        <HDF5 dataset "name": shape (), type "|S10">
+          deflection
+        <HDF5 dataset "range": shape (), type "<i4">
           1
-        <HDF5 dataset "subdevice": shape (), type "|S2">
+        <HDF5 dataset "subdevice": shape (), type "<i4">
           -1
       /vibration/config/vibration
-        <HDF5 dataset "chunk-size": shape (), type "|S4">
+        <HDF5 dataset "chunk-size": shape (), type "<i4">
           2048
-        <HDF5 dataset "frequency": shape (), type "|S7">
+        <HDF5 dataset "frequency": shape (), type "<f8">
           50000.0
-        <HDF5 dataset "maximum-fit-frequency": shape (), type "|S7">
+        <HDF5 dataset "maximum-fit-frequency": shape (), type "<f8">
           25000.0
-        <HDF5 dataset "minimum-fit-frequency": shape (), type "|S5">
+        <HDF5 dataset "minimum-fit-frequency": shape (), type "<f8">
           500.0
         <HDF5 dataset "model": shape (), type "|S12">
           Breit-Wigner
-        <HDF5 dataset "overlap": shape (), type "|S2">
-          no
-        <HDF5 dataset "sample-time": shape (), type "|S1">
+        <HDF5 dataset "overlap": shape (), type "|b1">
+          False
+        <HDF5 dataset "sample-time": shape (), type "<i4">
           1
         <HDF5 dataset "window": shape (), type "|S4">
           Hann
@@ -228,17 +227,18 @@ except (ImportError, RuntimeError), e:
     _matplotlib = None
     _matplotlib_import_error = e
 
-from h5config.hdf5 import h5_create_group as _h5_create_group
+from h5config.storage.hdf5 import HDF5_Storage as _HDF5_Storage
+from h5config.storage.hdf5 import h5_create_group as _h5_create_group
 import FFT_tools as _FFT_tools
 from pypiezo.base import convert_bits_to_volts as _convert_bits_to_volts
-from pypiezo.config import HDF5_ChannelConfig as _HDF5_ChannelConfig
+from pypiezo.config import ChannelConfig as _ChannelConfig
 
 from . import LOG as _LOG
 from . import package_config as _package_config
 from .config import Variance as _Variance
 from .config import BreitWigner as _BreitWigner
 from .config import OffsetBreitWigner as _OffsetBreitWigner
-from .config import HDF5_VibrationConfig as _HDF5_VibrationConfig
+from .config import VibrationConfig as _VibrationConfig
 
 
 def vib_analyze_naive(deflection):
@@ -459,13 +459,14 @@ def vib_save(filename, group='/', raw_vibration=None, vibration_config=None,
             except KeyError:
                 pass
             cwg['raw/deflection'] = raw_vibration
+        storage = _HDF5_Storage()
         for config,key in [(vibration_config, 'config/vibration'),
                            (deflection_channel_config,
                             'config/deflection')]:
             if config is None:
                 continue
             config_cwg = _h5_create_group(cwg, key)
-            config.save(group=config_cwg)
+            storage.save(config=config, group=config_cwg)
         if processed_vibration is not None:
             try:
                 del cwg['processed']
@@ -482,9 +483,10 @@ def vib_load(filename, group='/'):
             raw_vibration = f[group+'raw/deflection'][...]
         except KeyError:
             pass
-        for Config,key in [(_HDF5_VibrationConfig, 'config/vibration'),
-                           (_HDF5_ChannelConfig, 'config/deflection')]:
-            config = Config(filename=filename, group=group+key)
+        for Config,key in [(_VibrationConfig, 'config/vibration'),
+                           (_ChannelConfig, 'config/deflection')]:
+            config = Config(storage=_HDF5_Storage(
+                    filename=filename, group=group+key))
             configs.append(config)
         try:
             processed_vibration = f[group+'processed'][...]