>>> 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,
/
/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">
/
/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">
>>> 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)
/
/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">
_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):
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:
>>> 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))
/
/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
_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
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)
>>> 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)
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,
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
>>> 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
... }
>>> 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)
/
/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),
_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
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,
'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)
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
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)
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
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,
"""
_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,
_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:
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']
}
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'][...]
_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
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)
_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)
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:
>>> 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-')
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,
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
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 '
]),
]
+class BumpResult (_config.Config):
+ "The result of a `calibcant` bump operation"
+
+
class _VibrationModel (object):
pass
class Variance (_VibrationModel):
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.',
>>> 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.
>>> 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,
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
>>> 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
>>> 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
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.
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
/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
_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):
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']
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'][...]