Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Small alazar fixes #83

Merged
merged 15 commits into from
May 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions examples/Alazar/Alazar_simple_examples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# -*- coding: utf-8 -*-
"""
Simple examples of using the alazar meant to be used with the alazar station
config example
"""
import qcodes as qc
from qdev_wrappers.alazar_controllers.alazar_channel import AlazarChannel

alazar_ctrl.int_delay(2e-7)
alazar_ctrl.int_time(2e-6)

#%%

alazar_sample_chan.num_averages(1000)

alazar_sample_chan.alazar_channel('A')
alazar_sample_chan.prepare_channel()

# Measure this
data1 = qc.Measure(alazar_sample_chan.data).run()
qc.MatPlot(data1.AlazarController_AlazarSampleChannel_data)

#%%


alazar_records_chan.num_averages(1000)
alazar_records_chan.records_per_buffer(100)
alazar_records_chan.alazar_channel('A')
alazar_records_chan.prepare_channel()

# Measure this
data1 = qc.Measure(alazar_records_chan.data).run()
qc.MatPlot(data1.AlazarController_AlazarRecordChannel_data)

#%%


alazar_buffer_chan.num_averages(1000)
alazar_buffer_chan.buffers_per_acquisition(100)
alazar_buffer_chan.alazar_channel('A')
alazar_buffer_chan.prepare_channel()

# Measure this
data1 = qc.Measure(alazar_buffer_chan.data).run()
qc.MatPlot(data1.AlazarController_AlazarBufferChannel_data)

#%%


alazar_sample_record_chan.records_per_buffer(100)
alazar_sample_record_chan.num_averages(1000)
alazar_sample_record_chan.alazar_channel('A')
alazar_sample_record_chan.prepare_channel()

# Measure this
data1 = qc.Measure(alazar_sample_record_chan.data).run()
qc.MatPlot(data1.AlazarController_AlazarSampleRecordChannel_data)

#%%


alazar_sample_buffer_chan.buffers_per_acquisition(100)
alazar_sample_buffer_chan.num_averages(1000)
alazar_sample_buffer_chan.alazar_channel('A')
alazar_sample_buffer_chan.prepare_channel()

# Measure this
data1 = qc.Measure(alazar_sample_buffer_chan.data).run()
qc.MatPlot(data1.AlazarController_AlazarSampleBufferChannel_data)

#%%


alazar_record_buffer_chan.buffers_per_acquisition(100)
alazar_record_buffer_chan.records_per_buffer(100)
#alazar_record_buffer_chan.num_averages(1000)
alazar_record_buffer_chan.alazar_channel('A')
alazar_record_buffer_chan.prepare_channel()

# Measure this
data1 = qc.Measure(alazar_record_buffer_chan.data).run()
qc.MatPlot(data1.AlazarController_AlazarRecordBufferChannel_data)
310 changes: 243 additions & 67 deletions examples/Alazar/Qcodes example with Alazar ATS9360.ipynb

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""
This example illustrates how to use the StationConfigurator
When running it, make sure that your working directory is set to the path of
this file, or that you put the exampleConfig.yaml and the yaml file for the
simulated instrument (Agilent_34400A.yaml) into your current path.
If you don't like to have them there you can change the path in the init
function of the StationConfigurator, as well as the path in the yaml file(
everything befor the @-sign).
You also need to have the otpion 'enable_forced_reconnect' in your
qcodesrc.json, as it is the case for the example config file in this path.

A handy feature is that you can simply reëxecute the all the code, and should
stay in a consisten state. It will only fail for those instruments that you
have specified to not be simply reinstantiated (depending on the setting in
your qcdoesrc.json file and the auto reconnect option in the yaml file)

You can try starting the qcodes monitor and see how the parameters get added.
Currently a bug is that the parameters do not get removed once an instrument
is closed. So there will appear multiple copies of them.

"""
from qdev_wrappers.station_configurator import StationConfigurator
import qcodes as qc

# scfg = StationConfigurator('exampleConfig.yaml')
scfg = StationConfigurator('testSetupConfig.yaml')

# Configure all settings in the Alazar card

alazar = scfg.load_instrument('Alazar')
alazar.sync_settings_to_card()
#alazar.config(clock_source='INTERNAL_CLOCK',
# sample_rate=1_000_000_000,
# clock_edge='CLOCK_EDGE_RISING',
# decimation=1,
# coupling=['DC','DC'],
# channel_range=[.4,.4],
# impedance=[50,50],
# trigger_operation='TRIG_ENGINE_OP_J',
# trigger_engine1='TRIG_ENGINE_J',
# trigger_source1='EXTERNAL',
# trigger_slope1='TRIG_SLOPE_POSITIVE',
# trigger_level1=160,
# trigger_engine2='TRIG_ENGINE_K',
# trigger_source2='DISABLE',
# trigger_slope2='TRIG_SLOPE_POSITIVE',
# trigger_level2=128,
# external_trigger_coupling='DC',
# external_trigger_range='ETR_2V5',
# trigger_delay=0,
# timeout_ticks=0,
# aux_io_mode='AUX_IN_AUXILIARY', # AUX_IN_TRIGGER_ENABLE for seq mode on
# aux_io_param='NONE' # TRIG_SLOPE_POSITIVE for seq mode on
# )
alazar_ctrl = scfg.load_instrument('AlazarController')

alazar_sample_chan = scfg.load_instrument('AlazarSampleChannel', parent=alazar_ctrl)

alazar_records_chan = scfg.load_instrument('AlazarRecordChannel', parent=alazar_ctrl)

alazar_buffer_chan = scfg.load_instrument('AlazarBufferChannel', parent=alazar_ctrl)

alazar_sample_record_chan = scfg.load_instrument('AlazarSampleRecordChannel', parent=alazar_ctrl)

alazar_sample_buffer_chan = scfg.load_instrument('AlazarSampleBufferChannel', parent=alazar_ctrl)

alazar_record_buffer_chan = scfg.load_instrument('AlazarRecordBufferChannel', parent=alazar_ctrl)
80 changes: 79 additions & 1 deletion examples/station_configurator/testSetupConfig.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,84 @@ instruments:
address: 'TCPIP0::192.168.15.118::inst0::INSTR'
enable_forced_reconnect: true

YokogawaGS200:
driver: qcodes.instrument_drivers.yokogawa.GS200
type: GS200
address: 'USB0::0x0B21::0x0039::91RB18716::INSTR'
enable_forced_reconnect: true

Alazar:
driver: qcodes.instrument_drivers.AlazarTech.ATS9360
type: AlazarTech_ATS9360
enable_forced_reconnect: true
parameters:
clock_source: {initial_value: 'INTERNAL_CLOCK'}
sample_rate: {initial_value: 1_000_000_000}
trigger_operation: {initial_value: 'TRIG_ENGINE_OP_J'}
trigger_engine1: {initial_value: 'TRIG_ENGINE_J'}
trigger_source1: {initial_value: 'EXTERNAL'}
trigger_slope1: {initial_value: 'TRIG_SLOPE_POSITIVE'}
trigger_level1: {initial_value: 160}
trigger_engine2: {initial_value: 'TRIG_ENGINE_K'}
trigger_source2: {initial_value: 'DISABLE'}
external_trigger_coupling: {initial_value: 'DC'}
external_trigger_range: {initial_value: 'ETR_2V5'}
trigger_delay: {initial_value: 0}
timeout_ticks: {initial_value: 0}

AlazarController:
driver: qdev_wrappers.alazar_controllers.ATSChannelController
type: ATSChannelController
enable_forced_reconnect: true
init:
alazar_name: 'Alazar'
auto_reconnect: true

AlazarSampleChannel:
driver: qdev_wrappers.alazar_controllers.alazar_channel
type: AlazarChannel
init:
demod: false
integrate_samples: false

AlazarRecordChannel:
driver: qdev_wrappers.alazar_controllers.alazar_channel
type: AlazarChannel
init:
demod: false
average_records: false

AlazarBufferChannel:
driver: qdev_wrappers.alazar_controllers.alazar_channel
type: AlazarChannel
init:
demod: false
average_buffers: false

AlazarSampleRecordChannel:
driver: qdev_wrappers.alazar_controllers.alazar_channel
type: AlazarChannel
init:
demod: false
integrate_samples: false
average_records: false

AlazarSampleBufferChannel:
driver: qdev_wrappers.alazar_controllers.alazar_channel
type: AlazarChannel
init:
demod: false
integrate_samples: false
average_buffers: false

AlazarRecordBufferChannel:
driver: qdev_wrappers.alazar_controllers.alazar_channel
type: AlazarChannel
init:
demod: false
average_records: false
average_buffers: false

# SR860_1 192.168.15.119 00:19:B3:0A:0C:EB
# KS33622A 192.168.15.115 80:09:02:03:53:35
# KS33522B 192.168.15.108 80:09:02:03:E2:22
Expand All @@ -123,4 +201,4 @@ instruments:
# AWG5208 192.168.15.118 00:04:5F:9E:44:89
# SR860_2 192.168.15.120 00:19:B3:0A:0C:2B
# SR860_3 192.168.15.121 00:19:B3:0A:0C:82
# SR860_4 192.168.15.122 00:19:B3:0A:0C:30
# SR860_4 192.168.15.122 00:19:B3:0A:0C:30
25 changes: 16 additions & 9 deletions qdev_wrappers/alazar_controllers/ATSChannelController.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,16 +318,23 @@ def handle_alazar_channel(channelData,
data.append(np.squeeze(recordA))
# do demodulation
if demod_freqs:
magA, phaseA = self.demodulators[channel_number].demodulate(recordA, self.int_delay(), self.int_time())
for i, type in enumerate(demod_types):
if type=='magnitude':
mydata = np.squeeze(magA[i])
elif type == 'phase':
mydata = np.squeeze(phaseA[i])
else:
raise RuntimeError("unknown demodulator type")
re_limited, im_limited = self.demodulators[channel_number].demodulate(recordA, self.int_delay(), self.int_time())
for i, demodtype in enumerate(demod_types):
Real_data = np.squeeze(re_limited[i])
Imag_data = np.squeeze(im_limited[i])
if settings['integrate_samples']:
mydata = np.mean(mydata, axis=-1)
Real_data = np.mean(Real_data, axis=-1)
Imag_data = np.mean(Imag_data, axis=-1)
if demodtype=='magnitude':
mydata = abs(Real_data+1j*Imag_data)
elif demodtype == 'phase':
mydata = np.angle(Real_data+1j*Imag_data, deg=True)
elif demodtype == 'real':
mydata = Real_data
elif demodtype == 'imag':
mydata = Imag_data
else:
raise RuntimeError(f"Unknown demodulator type {demodtype} supplied")
data.append(mydata)
return data

Expand Down
2 changes: 1 addition & 1 deletion qdev_wrappers/alazar_controllers/alazar_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def __init__(self, parent, name: str, demod: bool=False, alazar_channel: str='A'
self.add_parameter('demod_type',
label='demod type',
initial_value='magnitude',
vals=vals.Enum('magnitude', 'phase'),
vals=vals.Enum('magnitude', 'phase', 'real', 'imag'),
get_cmd=None, set_cmd=None)

self.add_parameter('alazar_channel',
Expand Down
13 changes: 4 additions & 9 deletions qdev_wrappers/alazar_controllers/demodulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,15 @@ def demodulate(self, volt_rec, int_delay, int_time):
to ifantegration limits shape = (samples_taken, )

Returns:
magnitude (numpy array): shape = (demod_length, samples_after_limiting)
phase (numpy array): shape = (demod_length, samples_after_limiting)
re_limited (numpy array): shape = (demod_length, samples_after_limiting)
im_limited (numpy array): shape = (demod_length, samples_after_limiting)
"""

# volt_rec to matrix and multiply with demodulation signal matrices
demod_length = len(self.demod_freqs)
volt_rec_mat = np.outer(np.ones(demod_length), volt_rec).reshape(self.mat_shape)
re_mat = np.multiply(volt_rec_mat, self.cos_mat)
im_mat = np.multiply(volt_rec_mat, self.sin_mat)*0
im_mat = np.multiply(volt_rec_mat, self.sin_mat)

# filter out higher freq component
cutoff = max(self.demod_freqs)/10
Expand Down Expand Up @@ -145,12 +145,7 @@ def demodulate(self, volt_rec, int_delay, int_time):
re_limited = re_filtered
im_limited = im_filtered

# convert to magnitude and phase
complex_mat = re_limited + im_limited * 1j
magnitude = abs(complex_mat)
phase = np.angle(complex_mat, deg=True)

return magnitude, phase
return re_limited, im_limited

@staticmethod
def verify_demod_freq(value, sample_rate, int_time):
Expand Down
3 changes: 0 additions & 3 deletions qdev_wrappers/templates/dummy_initialisation_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@
dmm = DummyInstrument(name="dmm", gates=['voltage']) # The DMM voltage reader
dc = DummyChannelInstrument(name='dc')

the default dummy instrument returns always a constant value,
in the following line we make it random
just for the looks 💅
import random
dmm.voltage.get = lambda: random.randint(0, 100)

Expand Down