Source code for qcodes_contrib_drivers.drivers.StanfordResearchSystems.DG645

import logging
log = logging.getLogger(__name__)

from qcodes import VisaInstrument
import qcodes.utils.validators as vals

[docs] class DG645(VisaInstrument): """Qcodes driver for SRS DG645 digital delay generator. """ CHANNEL_MAPPING = { 'T0': 0, 'T1': 1, 'A': 2, 'B': 3, 'C': 4, 'D': 5, 'E': 6, 'F': 7, 'G': 8, 'H': 9 } OUTPUT_MAPPING = {'T0': 0, 'AB': 1, 'CD': 2, 'EF': 3, 'GH': 4} PRESCALE_MAPPING = {'trig': 0, 'AB': 1, 'CD': 2, 'EF': 3, 'GH': 4} TRIGGER_MAPPING = { 'internal': 0, 'ext_rising': 1, 'ext_falling': 2, 'single_ext_rising': 3, 'single_ext_falling': 4, 'single': 5, 'line': 6, } POLARITY_MAPPING = {'-': 0, '+': 1} DISPLAY_MAPPING = { 'trig_rate': 0, 'trig_thresh': 1, 'trig_single_shot': 2, 'trig_line': 3, 'advanced_trig_enable': 4, 'trig_holdoff': 5, 'prescale_config': 6, 'burst_mode': 7, 'burst_delay': 8, 'burst_count': 9, 'burst_period': 10, 'channel_delay': 11, 'channel_output_levels': 12, 'channel_output_polarity': 13, 'burst_T0_config': 14 } def __init__(self, name, address, **kwargs): super().__init__(name, address, terminator='\r\n', timeout=10, **kwargs) self.add_parameter('trig_holdoff', label='Trigger holdoff', unit='s', get_cmd='HOLD?', get_parser=float, set_cmd='HOLD {}' ) # Prescale parameters for channel, idx in self.PRESCALE_MAPPING.items(): if idx > 0: self.add_parameter( f'phase_{channel}', label=f'{channel} prescale phase factor {k}', get_cmd=f'PHAS?{idx}', get_parser=int, set_cmd=f'PHAS {idx},{{}}', vals=vals.Ints(min_value=0), docstring="""\ The prescale phase factor determines the phase at which the associated output is enabled. The output is enabled when the prescaler counter equals the phase factor. """ ) self.add_parameter( f'prescale_{channel}', label=f'{channel} prescale factor', get_cmd=f'PRES?{idx}', get_parser=int, set_cmd=f'PRES {idx},{{}}', vals=vals.Ints(min_value=0), docstring="""\ A prescaler on the trigger input enables one to generate delay cycles at a sub-multiple of the trigger input frequency. """ ) # Trigger parameters self.add_parameter( 'trigger_level', label='Trigger level', unit='V', get_cmd='TLVL?', get_parser=float, set_cmd='TLVL {}', vals=vals.Numbers() ) self.add_parameter( 'trigger_rate', label='Trigger rate', unit='Hz', get_cmd='TRAT?', get_parser=float, set_cmd='TRAT {}', vals=vals.Numbers(min_value=0) ) self.add_parameter( 'trigger_source', label='Trigger source', get_cmd=self._get_trigger_source, get_parser=str, set_cmd=self._set_trigger_source, vals=vals.Enum(*tuple(self.TRIGGER_MAPPING)) ) # Burst parameters self.add_parameter( 'burst_count', label='Burst count', get_cmd='BURC?', get_parser=int, set_cmd='BURC {}', vals=vals.Ints(min_value=0) ) self.add_parameter( 'burst_delay', label='Burst delay', unit='s', get_cmd='BURD?', get_parser=float, set_cmd='BURD {}', vals=vals.Numbers(min_value=0) ) self.add_parameter( 'burst_period', label='Burst period', unit='s', get_cmd='BURP?', get_parser=float, set_cmd='BURC {}', vals=vals.Numbers(min_value=100e-9, max_value=2000-10e-9) ) self.add_parameter( 'burst_T0_config', label='Burst T0 configuration', get_cmd='BURT?', get_parser=int, set_cmd='BURT {}', vals=vals.Enum(0,1) ) # Channel parameters for ch, idx in self.CHANNEL_MAPPING.items(): if idx > 1: self.add_parameter( f'delay_{ch}', label=f'{ch} delay', unit='s', get_cmd=f'DLAY?{idx}', get_parser=str, set_cmd=lambda src_delay, channel=ch: self._set_delay(src_delay, channel), vals=vals.Strings(), docstring="""\ Set/query they delay of this channel relative to another. Arguments/returned values strings of the form '{index_of_other_channel},{delay_in_seconds}'. For example, '2,+0.001' indicates that this channel is delayed from channel A by 1 ms, since self.CHANNEL_MAPPING['A'] == 2. """ ) self.add_parameter( f'channel_link_{ch}', label=f'Channel linked to {ch}', get_cmd=f'LINK?{idx}', get_parser=int, set_cmd=lambda target, source=ch: self._set_link(target, source), vals=vals.Enum(*tuple(k for k in self.CHANNEL_MAPPING if k != 'T1')) ) # Output parameters for out, idx in self.OUTPUT_MAPPING.items(): self.add_parameter( f'amp_out_{out}', label=f'Output {out} amplitude', unit='V', get_cmd=f'LAMP?{idx}', get_parser=float, set_cmd=f'LAMP {idx},{{}}', vals=vals.Numbers() ) self.add_parameter( f'offset_out_{out}', label=f'Output {out} offset', unit='V', get_cmd=f'LOFF?{idx}', get_parser=float, set_cmd=f'LOFF {idx},{{}}', vals=vals.Numbers() ) self.add_parameter( f'polarity_out_{out}', label=f'Output {out} polarity', get_cmd=f'LPOL?{idx}', get_parser=int, set_cmd=f'LPOL {idx},{{}}', vals=vals.Enum(0,1), docstring='0 -> negative polarity, 1 -> positive polarity.' ) self.snapshot(update=True) self.connect_message()
[docs] def self_calibrate(self) -> None: """Run auto-calibration routine. """ self.write('*CAL?') self.wait()
[docs] def self_test(self) -> None: """Run self-test routine. """ self.write('*TST?') self.wait()
[docs] def reset(self) -> None: """Reset instrument. """ log.info(f'Resetting {self.name}.') self.write('*RST')
[docs] def save_settings(self, location: int) -> None: """Save instrument settings to given location. Args: location: Location to which to save the settings (in [1..9]). """ log.info(f'Saving instrument settings to location {location}.') self.write(f'*SAV {location}')
[docs] def trigger(self) -> None: """Initiates a single trigger if instrument is in single shot mode. """ self.write('*TRG')
[docs] def wait(self) -> None: """Wait for all prior commands to execute before continuing. """ self.write('*WAI')
[docs] def local(self) -> None: """Go to local. """ self.write('LCAL')
[docs] def remote(self) -> None: """Go to remote. """ self.write('REMT')
def _set_trigger_source(self, src: str) -> None: self.write(f'TSRC {self.TRIGGER_MAPPING[src]}') def _get_trigger_source(self) -> str: response = self.ask('TSRC?') keys = self.TRIGGER_MAPPING.keys() values = self.TRIGGER_MAPPING.values() return list(keys)[list(values).index(int(response))] def _set_delay(self, src_delay: str, target: str) -> None: source, delay = [s.strip() for s in src_delay.split(',')] self.write('DLAY {},{},{}'.format(self.CHANNEL_MAPPING[target], self.CHANNEL_MAPPING[source], delay)) def _set_link(self, target: str, source: str) -> None: self.write('LINK {},{}'.format(self.CHANNEL_MAPPING[target], self.CHANNEL_MAPPING[source]))