_matplotlib = None
_matplotlib_import_error = e
+try:
+ import h5py as _h5py
+ import h5config as _h5config
+ from h5config.storage.hdf5 import HDF5_Storage as _HDF5_Storage
+ from h5config.storage.hdf5 import h5_create_group as _h5_create_group
+except ImportError, e:
+ _h5py = None
+ _h5py_import_error = e
+
from curses_check_for_keypress import CheckForKeypress as _CheckForKeypress
from . import LOG as _LOG
{'deflection': array([32655, 33968, 35281, 36593], dtype=uint16),
'z': array([32767, 34077, 35387, 36697], dtype=uint16)}
- >>> p.wiggle_for_interference('z', offset=p.last_output['z'],
- ... laser_wavelength=650e-9, keypress_test_mode=True)
+ >>> wiggle_config = config.WiggleConfig()
+ >>> wiggle_config['offset'] = p.last_output['z']
+ >>> wiggle_config['wavelength'] = 650e-9
+ >>> p.wiggle_for_interference(config=wiggle_config,
+ ... keypress_test_mode=True)
Press any key to continue
>>> try:
got FlatFit
>>> print e # doctest: +SKIP
slopes not sufficiently different: 1.0021 and 1.0021
+ >>> e.right_slope
>>> abs(e.right_slope-1) < 0.1
True
+ >>> e.left_slope
>>> abs(e.left_slope-1) < 0.1
True
return data
def wiggle_for_interference(
- self, axis_name, wiggle_frequency=2, n_samples=1024, amplitude=None,
- offset=None, laser_wavelength=None, plot=True,
+ self, config, plot=True, filename=None, group='/',
keypress_test_mode=False):
"""Output a sine wave and measure interference.
"""
if _package_config['matplotlib']:
plot = True
- if laser_wavelength and amplitude:
+ if config['wavelength'] and config['amplitude']:
log_string = \
'use either laser_wavelength or amplitude, but not both'
_LOG.warn(log_string)
- if None in (amplitude, offset):
- output_axis = self.axis_by_name(axis_name)
+ if None in (config['amplitude'], config['offset']):
+ output_axis = self.axis_by_name(config['axis'])
maxdata = output_axis.axis_channel.get_maxdata()
midpoint = int(maxdata/2)
- if offset == None:
+ if config['offset'] is None:
offset = midpoint
- log_string = (
- 'generated offset for interference wiggle: %g' % offset)
- _LOG.debug(log_string)
- if amplitude == None:
- if offset <= midpoint:
- max_amplitude = int(offset)
+ _LOG.debug(('generated offset for interference wiggle: {}'
+ ).format(config['offset']))
+ if config['amplitude'] is None:
+ if config['offset'] <= midpoint:
+ max_amplitude = int(config['offset'])
else:
- max_amplitude = int(maxdata-offset)
+ max_amplitude = int(maxdata-config['offset'])
offset_meters = _base.convert_bits_to_meters(
- output_axis.config, offset)
- if laser_wavelength is None:
- amplitude = 0.5*max_amplitude
+ output_axis.config, config['offset'])
+ if config['wavelength'] is None:
+ config['amplitude'] = 0.5*max_amplitude
else:
bit_wavelength = _base.convert_meters_to_bits(
- output_axis.config, offset_meters + laser_wavelength
- ) - offset
- amplitude = 2*bit_wavelength
- log_string = (
- 'generated amplitude for interference wiggle: %g'
- % amplitude)
- _LOG.debug(log_string)
- if amplitude > max_amplitude:
+ output_axis.config,
+ offset_meters + config['wavelength']
+ ) - config['offset']
+ config['amplitude'] = 2*bit_wavelength
+ _LOG.debug(('generated amplitude for interference wiggle: {}'
+ ).format(config['amplitude']))
+ if config['amplitude'] > max_amplitude:
raise ValueError('no room for a two wavelength wiggle')
- scan_frequency = wiggle_frequency * n_samples
- out = (amplitude * _numpy.sin(
- _numpy.arange(n_samples) * 4 * _numpy.pi / float(n_samples))
- + offset)
- # 4 for 2 periods, so you can judge precision
+ n = config['samples'] # samples in a single oscillation
+ scan_frequency = config['frequency'] * n
+ out = (config['amplitude']
+ * _numpy.sin(_numpy.arange(2*n)*2*_numpy.pi/n)
+ + config['offset'])
+ # 2*n for 2 periods, so you can judge precision
out = out.reshape((len(out), 1)).astype(
- self.channel_dtype(axis_name, direction='output'))
-
- _LOG.debug('oscillate for interference wiggle')
- log_string = (
- 'amplitude: %d bits, offset: %d bits, scan frequency: %g Hz'
- % (amplitude, offset, scan_frequency))
- _LOG.debug(log_string)
-
+ self.channel_dtype(config['axis'], direction='output'))
+
+ _LOG.debug('oscillate for interference wiggle ({})'.format(config))
+
+ if filename:
+ if not _h5py:
+ raise _h5py_import_error
+ if not output_axis: # from amplitude/offset setup
+ output_axis = afm.piezo.axis_by_name(config['axis'])
+ input_channel = afm.piezo.input_channel_by_name(config['input'])
+ with _h5py.File(filename, 'w') as f:
+ cwg = _h5_create_group(f, group)
+ storage = _HDF5_Storage()
+ for config_,key in [
+ (config, 'config/wiggle'),
+ (output.axis.config,
+ 'config/{}/axis'.format(config['axis'])),
+ (input_channel.config,
+ 'config/{}/channel'.format(config['input']))]:
+ if config_ is None:
+ continue
+ config_cwg = _h5_create_group(cwg, key)
+ storage.save(config=config, group=config_cwg)
if plot:
if not _matplotlib:
raise _matplotlib_import_error
axes.set_title('wiggle for interference %s' % timestamp)
plot_p = axes.plot(out, out, 'b.-')
figure.show()
+ cycle = 0
c = _CheckForKeypress(test_mode=keypress_test_mode)
while c.input() == None:
# input will need processing for multi-segment AFMs...
- data = self.ramp(out, scan_frequency, output_names=[axis_name],
- input_names=['deflection'])
+ data = self.ramp(
+ out, scan_frequency, output_names=[config['axis']],
+ input_names=[config['input']])
_LOG.debug('completed a wiggle round')
+ if filename:
+ timestamp = ('{0}-{1:02d}-{2:02d}T{3:02d}-{4:02d}-{5:02d}'
+ ).format(*_time.localtime())
+ with _h5py.File(filename, 'a') as f:
+ wiggle_group = _h5_create_group(f, group)
+ cwg = _h5_create_group(
+ wiggle_group, 'wiggle/{}'.format(cycle))
+ cwg['time'] = timestamp
+ cwg['raw/{}'.format(config['axis'])] = out
+ cwg['raw/{}'.format(config['input'])] = data
if plot:
plot_p[0].set_ydata(data[:,0])
axes.set_ylim([data.min(), data.max()])
#_flush_plot()
- self.last_output[axis_name] = out[-1,0]
+ cycle += 1
+ self.last_output[config['axis']] = out[-1,0]
_LOG.debug('interference wiggle complete')
get_surface_position = _surface.get_surface_position