If you're installing by hand or packaging calibcant for another
distribution, you'll need the following dependencies:
-=========== ================= =====================
+=========== ================= ============================
Package Debian_ Gentoo_
-=========== ================= =====================
+=========== ================= ============================
Numpy_ python-numpy dev-python/numpy
Scipy_ python-scipy sci-libs/scipy
+H5config_ dev-python/h5config [#wtk]_
H5Py_ python-h5py dev-python/h5py
Matplotlib_ python-matplotlib dev-python/matplotlib
Nose_ python-nose dev-python/nose
-FFT_tools_ dev-python/FFT-tools
-Pypiezo_ sci-libs/pypiezo
-=========== ================= =====================
+FFT_tools_ dev-python/FFT-tools [#wtk]_
+Pypiezo_ sci-libs/pypiezo [#wtk]_
+=========== ================= ============================
+
+.. [#wtk] In the `wtk overlay`_.
You'll also need my pyafm_ and stepper_ packages, or suitable
replacements.
Calibcant is available as a Git_ repository::
- $ git clone http://www.physics.drexel.edu/~wking/code/git/calibcant.git
+ $ git clone http://physics.drexel.edu/~wking/code/git/calibcant.git
See the homepage_ for details. To install the checkout, run the
standard::
.. _layman: http://layman.sourceforge.net/
.. _wtk overlay:
- http://www.physics.drexel.edu/~wking/unfolding-disasters/posts/Gentoo_overlay
+ http://physics.drexel.edu/~wking/unfolding-disasters/posts/Gentoo_overlay/
.. _Debian: http://www.debian.org/
.. _Gentoo: http://www.gentoo.org/
.. _NumPy: http://numpy.scipy.org/
.. _SciPy: http://www.scipy.org/
+.. _H5config:
+ http://physics.drexel.edu/~wking/unfolding-disasters/posts/h5config/
.. _H5Py: http://code.google.com/p/h5py/
.. _Matplotlib: http://matplotlib.sourceforge.net/
.. _Nose: http://somethingaboutorange.com/mrl/projects/nose/
.. _FFT_tools:
- http://www.physics.drexel.edu/~wking/unfolding-disasters/posts/FFT-tools/
+ http://physics.drexel.edu/~wking/unfolding-disasters/posts/FFT-tools/
.. _Pypiezo:
- http://www.physics.drexel.edu/~wking/unfolding-disasters/posts/pypiezo/
+ http://physics.drexel.edu/~wking/unfolding-disasters/posts/pypiezo/
.. _pyafm:
- http://www.physics.drexel.edu/~wking/unfolding-disasters/posts/pyafm/
+ http://physics.drexel.edu/~wking/unfolding-disasters/posts/pyafm/
.. _stepper:
- http://www.physics.drexel.edu/~wking/unfolding-disasters/posts/stepper/
+ http://physics.drexel.edu/~wking/unfolding-disasters/posts/stepper/
.. _Git: http://git-scm.com/
.. _homepage:
- http://www.physics.drexel.edu/~wking/unfolding-disasters/posts/calibcant/
+ http://physics.drexel.edu/~wking/unfolding-disasters/posts/calibcant/
.. _GNU General Public License Version 3: http://www.gnu.org/licenses/gpl.txt
# We just wrap that to provide a consistent interface.
from . import LOG as _LOG
-from . import base_config as _base_config
+from . import package_config as _package_config
from .T_analyze import T_analyze as _T_analyze
from .T_analyze import T_save as _T_save
"""Measure the current temperature of the sample,
If `get_T` is `None`, fake it by returning
- `base_config['temperature']`.
+ `package_config['temperature']`.
"""
if get_T:
_LOG.info('measure temperature')
else:
T = None
if T is None:
- _LOG.info('fake temperature %g' % _base_config['temperature'])
- T = _base_config['temperature']
+ _LOG.info('fake temperature %g' % _package_config['temperature'])
+ T = _package_config['temperature']
return T
def T(get_T, temperature_config, filename, group='/'):
>>> import os
>>> import tempfile
- >>> from pypiezo.config import pprint_HDF5
+ >>> from h5config.hdf5 import pprint_HDF5
>>> from .config import HDF5_TemperatureConfig
>>> fd,filename = tempfile.mkstemp(suffix='.h5', prefix='calibcant-')
... filename=filename, group='/T/config/')
>>> def get_T():
... return 19.2
-
>>> t = T(get_T=get_T, temperature_config=temperature_config,
... filename=filename, group='/T/')
>>> pprint_HDF5(filename) # doctest: +ELLIPSIS, +REPORT_UDIFF
>>> os.remove(filename)
"""
T_raw = T_acquire(get_T)
+ _LOG.debug('got T: %s' % T_raw)
T_ret = _T_analyze(T_raw, temperature_config)
temperature_config['default'] = not get_T
_T_save(filename, group=group, raw_T=T_raw,
>>> import tempfile
>>> import numpy
>>> from .config import HDF5_TemperatureConfig
->>> from pypiezo.config import pprint_HDF5
+>>> from h5config.hdf5 import pprint_HDF5
>>> fd,filename = tempfile.mkstemp(suffix='.h5', prefix='calibcant-')
>>> os.close(fd)
_matplotlib = None
_matplotlib_import_error = e
-from pypiezo.config import h5_create_group as _h5_create_group
+from h5config.hdf5 import h5_create_group as _h5_create_group
from . import LOG as _LOG
-from . import base_config as _base_config
+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
# License along with calibcant. If not, see
# <http://www.gnu.org/licenses/>.
-import logging as _logging
-import logging.handlers as _logging_handlers
+from .config import PackageConfig as _PackageConfig
-__version__ = '0.6'
+__version__ = '0.7'
-LOG = _logging.getLogger('calibcant')
-"Calibcant logger"
-
-LOG.setLevel(_logging.WARN)
-_formatter = _logging.Formatter(
- '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
-
-_stream_handler = _logging.StreamHandler()
-_stream_handler.setLevel(_logging.DEBUG)
-_stream_handler.setFormatter(_formatter)
-LOG.addHandler(_stream_handler)
-
-_syslog_handler = None
-
-
-from .config import _BaseConfig
-from .config import find_base_config as _find_base_config
-
-
-def setup_base_config(config):
- global base_config, _syslog_handler
- base_config = config
-
- LOG.setLevel(base_config['log-level'])
-
- if base_config['syslog']:
- if not _syslog_handler:
- _syslog_handler = _logging_handlers.SysLogHandler()
- _syslog_handler.setLevel(_logging.DEBUG)
- LOG.handlers = [_syslog_handler]
- else:
- LOG.handlers = [_stream_handler]
-
- LOG.info('setup base_config:\n%s' % config.dump())
-
-def clear_base_config():
- setup_base_config(_BaseConfig())
-
-base_config = _find_base_config()
-setup_base_config(base_config)
+package_config = _PackageConfig(package_name=__name__)
+package_config.load_system()
>>> import os
>>> import tempfile
>>> import numpy
->>> from pypiezo.config import pprint_HDF5
+>>> from h5config.hdf5 import pprint_HDF5
>>> from .config import HDF5_CalibrationConfig
>>> fd,filename = tempfile.mkstemp(suffix='.h5', prefix='calibcant-')
_matplotlib = None
_matplotlib_import_error = e
-from pypiezo.config import h5_create_group as _h5_create_group
+from h5config.hdf5 import h5_create_group as _h5_create_group
from . import LOG as _LOG
-from . import base_config as _base_config
+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
_LOG.info('vibration variance (V^2) : %g +/- %g (%g)'
% (v2_m, v2_s, v2_s/v2_m))
- if _base_config['matplotlib']:
+ if _package_config['matplotlib']:
calib_plot(bumps, temperatures, vibrations)
return (k, k_s)
A family name without any _* extension (e.g. `bump()`), runs `*_acquire()`,
`*_save()`, `*_analyze()`.
-If `base_config['matplotlib']` is `True`, `*_analyze()` will call
+If `package_config['matplotlib']` is `True`, `*_analyze()` will call
`*_plot()` internally.
"""
>>> import tempfile
>>> import numpy
>>> from .config import HDF5_BumpConfig
->>> from pypiezo.config import pprint_HDF5, HDF5_ChannelConfig, HDF5_AxisConfig
+>>> from h5config.hdf5 import pprint_HDF5, HDF5_ChannelConfig, HDF5_AxisConfig
>>> fd,filename = tempfile.mkstemp(suffix='.h5', prefix='calibcant-')
>>> os.close(fd)
_matplotlib = None
_matplotlib_import_error = e
+from h5config.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 h5_create_group as _h5_create_group
from . import LOG as _LOG
-from . import base_config as _base_config
+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
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
+ z_channel_config z `pypiezo.config.ChannelConfig` instance
+ z_axis_config z `pypiezo.config.AxisConfig` instance
deflection_channel_config
- deflection `pypiezo.config._ChannelConfig` instance
+ deflection `pypiezo.config.ChannelConfig` instance
plot boolean overriding matplotlib config setting.
Returns:
photo_sensitivity (Vphoto/Zcant) in Volts/m
_LOG.debug('solution converged')
else:
_LOG.debug('solution did not converge')
- if plot or _base_config['matplotlib']:
+ if plot or _package_config['matplotlib']:
yguess = model(z, param_guess)
yfit = model(z, p)
bump_plot({'z': z, 'deflection': deflection}, yguess=yguess, yfit=yfit)
with _h5py.File(filename, 'a') as f:
cwg = _h5_create_group(f, group)
if raw_bump is not None:
- try:
- del cwg['raw/z']
- except KeyError:
- pass
- try:
- del cwg['raw/deflection']
- except KeyError:
- pass
+ for k in ['z', 'deflection']:
+ try:
+ del cwg['raw/{}'.format(k)]
+ except KeyError:
+ pass
cwg['raw/z'] = raw_bump['z']
cwg['raw/deflection'] = raw_bump['deflection']
for config,key in [(bump_config, 'config/bump'),
A family name without any `_*` extension (e.g. `bump()`), runs
`*_acquire()`, `*_analyze()`, and `*_save()`. `*_analyze()` will run
-`*_plot()` if `matplotlib` is set in `calibcant.base_config`.
+`*_plot()` if `matplotlib` is set in `calibcant.package_config`.
"""
from numpy import zeros as _zeros
"""Define some variables to configure the package for a particular lab
and workflow."""
-import logging as _logging
-import os.path as _os_path
import sys as _sys
from FFT_tools import window_hann as _window_hann
-from pypiezo.config import (
- _ChoiceSetting, _BooleanSetting, _IntegerSetting, _FloatSetting,
- _FloatListSetting, _Config, _BackedConfig, _HDF5Config, _YAMLConfig)
+import h5config.config as _config
+import h5config.tools as _h5config_tools
-from . import LOG as _LOG
-
-class _BaseConfig (_Config):
+class PackageConfig (_h5config_tools.PackageConfig):
"Configure `calibcant` module operation"
- settings = [
- _ChoiceSetting(
- name='log-level',
- help='Module logging level.',
- default=_logging.WARN,
- choices=[
- ('critical', _logging.CRITICAL),
- ('error', _logging.ERROR),
- ('warn', _logging.WARN),
- ('info', _logging.INFO),
- ('debug', _logging.DEBUG),
- ]),
- _BooleanSetting(
- name='syslog',
- help='Log to syslog (otherwise log to stderr).',
- default=False),
- _BooleanSetting(
+ settings = _h5config_tools.PackageConfig.settings + [
+ _config.BooleanSetting(
name='matplotlib',
help='Plot piezo motion using `matplotlib`.',
default=False),
- _FloatSetting(
+ _config.FloatSetting(
name='temperature',
help=('Default temperature for thermal calibration in degrees '
'Celsius.'),
class Kelvin (_TemperatureUnit):
pass
-class _TemperatureConfig (_Config):
+class TemperatureConfig (_config.Config):
"Configure `calibcant` temperature operation"
settings = [
- _ChoiceSetting(
+ _config.ChoiceSetting(
name='units',
help='Units of raw temperature measurements.',
default=Celsius,
('Celsius', Celsius),
('Kelvin', Kelvin),
]),
- _BooleanSetting(
+ _config.BooleanSetting(
name='default',
help=('The temperature values are defaults (vs. real '
'measurements).'),
class Quadratic (_BumpModel):
pass
-class _BumpConfig (_Config):
+class BumpConfig (_config.Config):
"Configure `calibcant` bump operation"
settings = [
- _FloatSetting(
+ _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),
- _FloatSetting(
+ _config.FloatSetting(
name='setpoint',
help=('Maximum deflection in volts in case of stepper positioning '
'to achieve the initial position.'),
default=2.0),
- _IntegerSetting(
+ _config.IntegerSetting(
name='far-steps',
help=('Number of stepper steps to move "far" away from the '
'surface. For possible stepper adjustments while initially '
'locating the surface.'),
default=200),
- _FloatSetting(
+ _config.FloatSetting(
name='push-depth',
help='Distance to approach in meters.',
default=200e-9),
- _FloatSetting(
+ _config.FloatSetting(
name='push-speed',
help='Approach/retract speed in meters/second.',
default=1e-6),
- _FloatSetting(
+ _config.FloatSetting(
name='samples',
help='Number of samples during approach and during retreat.',
default=1024),
- _ChoiceSetting(
+ _config.ChoiceSetting(
name='model',
help='Bump deflection model.',
default=Quadratic,
class OffsetBreitWigner (_VibrationModel):
pass
-class _VibrationConfig (_Config):
+class VibrationConfig (_config.Config):
"Configure `calibcant` vibration operation"
settings = [
- _FloatSetting(
+ _config.FloatSetting(
name='frequency',
help='Sampling frequency in Hz.',
default=50e3),
- _FloatSetting(
+ _config.FloatSetting(
name='sample-time',
help=('Aquisition time in seconds. This is rounded up as required '
'so the number of samples will be an integer power of two.'),
default=1),
- _ChoiceSetting(
+ _config.ChoiceSetting(
name='model',
help='Vibration model.',
default=BreitWigner,
('Breit-Wigner', BreitWigner),
('offset Breit-Wigner', OffsetBreitWigner),
]),
- _IntegerSetting(
+ _config.IntegerSetting(
name='chunk-size',
help='FFT chunk size (for PSD fits).',
default=2048),
- _BooleanSetting(
+ _config.BooleanSetting(
name='overlap',
help='Overlap FFT chunks (for PSD fits).'),
- _ChoiceSetting(
+ _config.ChoiceSetting(
name='window',
help='FFT chunk window (for PSD fits).',
default=_window_hann,
choices=[
('Hann', _window_hann),
]),
- _FloatSetting(
+ _config.FloatSetting(
name='minimum-fit-frequency',
help='Lower bound of Lorentzian fitting region.',
default=500.),
- _FloatSetting(
+ _config.FloatSetting(
name='maximum-fit-frequency',
help='Upper bound of Lorentzian fitting region.',
default=25e3),
]
-class _CalibrationConfig (_Config):
+class CalibrationConfig (_config.Config):
"Configure a full `calibcant` calibration run"
settings = [
- _IntegerSetting(
+ _config.IntegerSetting(
name='num-bumps',
help='Number of surface bumps.',
default=10),
- _IntegerSetting(
+ _config.IntegerSetting(
name='num-temperatures',
help='Number of temperature measurements.',
default=10),
- _IntegerSetting(
+ _config.IntegerSetting(
name='num-vibrations',
help='Number of thermal vibration measurements.',
default=20),
- _FloatSetting(
+ _config.FloatSetting(
name='temperature-sleep',
help=('Time between temperature measurements (in seconds) to get '
'independent measurements when reading from slow sensors.'),
default=1),
- _FloatSetting(
+ _config.FloatSetting(
name='vibration-spacing',
help=('Approximate distance from the surface in meters for the '
'vibration measurements. This should be large enough that '
'surface effects are negligable.'),
default=50e-6),
]
-
-
-# Define HDF5- and YAML-backed subclasses of the basic _Config types.
-for name,obj in locals().items():
- if (obj != _Config and
- type(obj) == type and
- issubclass(obj, _Config) and
- not issubclass(obj, _BackedConfig)):
- for prefix,base in [('HDF5', _HDF5Config), ('YAML', _YAMLConfig)]:
- _name = '%s%s' % (prefix, name)
- _bases = (base, obj)
- _dict = {}
- _class = type(_name, _bases, _dict)
- setattr(_sys.modules[__name__], _name, _class)
-
-del name, obj, prefix, base, _name, _bases, _dict, _class
-
-
-def find_base_config():
- "Return the best `_BaseConfig` match after scanning the filesystem"
- _LOG.info('looking for base_config file')
- user_basepath = _os_path.join(_os_path.expanduser('~'), '.calibcantrc')
- system_basepath = _os_path.join('/etc', 'calibcant', 'config')
- distributed_basepath = _os_path.join(
- '/usr', 'share', 'calibcant', 'config')
- for basepath in [user_basepath, system_basepath, distributed_basepath]:
- for (extension, config) in [('.h5', HDF5_BaseConfig),
- ('.yaml', YAML_BaseConfig)]:
- filename = basepath + extension
- if _os_path.exists(filename):
- _LOG.info('base_config file found at %s' % filename)
- base_config = config(filename)
- base_config.load()
- return base_config
- else:
- _LOG.debug('no base_config file at %s' % filename)
- _LOG.info('new base_config file at %s' % filename)
- basepath = user_basepath
- filename = basepath + extension
- return config(filename)
>>> import os
>>> import tempfile
+ >>> from h5config.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, pprint_HDF5
+ >>> from pypiezo.config import HDF5_ChannelConfig
>>> from .config import HDF5_VibrationConfig
Setup an `AFMPiezo` instance.
>>> import tempfile
>>> import numpy
>>> from .config import HDF5_VibrationConfig
->>> from pypiezo.config import pprint_HDF5, HDF5_ChannelConfig
+>>> from h5config.hdf5 import pprint_HDF5, HDF5_ChannelConfig
>>> from pypiezo.base import convert_volts_to_bits
>>> fd,filename = tempfile.mkstemp(suffix='.h5', prefix='calibcant-')
_matplotlib = None
_matplotlib_import_error = e
+from h5config.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 h5_create_group as _h5_create_group
from . import LOG as _LOG
-from . import base_config as _base_config
+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
deflection Vphoto deflection input in bits.
vibration_config `.config._VibrationConfig` instance
deflection_channel_config
- deflection `pypiezo.config._ChannelConfig` instance
+ deflection `pypiezo.config.ChannelConfig` instance
plot boolean overriding matplotlib config setting.
The conversion to frequency space generates an average power
_LOG.debug('fit PSD(f) = C / ((A**2-f**2)**2 + (f*B)**2) with '
'A = %g, B = %g, C = %g, D = %g' % (A, B, C, D))
- if plot or _base_config['matplotlib']:
+ if plot or _package_config['matplotlib']:
vib_plot(deflection, freq_axis, power, A, B, C, D,
vibration_config=vibration_config)
_LOG.debug('fitted deflection variance: %g V**2' % fitted_variance)
- if _base_config['matplotlib']:
+ if _package_config['matplotlib']:
vib_plot(deflection, freq_axis, power, A, B, C, D,
vibration_config=vibration_config)
packages=packages,
scripts=scripts,
provides=['calibcant (%s)' % __version__],
- requires=['pypiezo (>= 0.4)'],
+ requires=['pypiezo (>= 0.5)'],
)