Skip to content
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
89 changes: 89 additions & 0 deletions qupulse/examples/VolatileParameters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
from qupulse.hardware.setup import HardwareSetup, PlaybackChannel, MarkerChannel
from qupulse.pulses import PointPT, RepetitionPT, TablePT


#%%
""" Connect and setup to your AWG. Change awg_address to the address of your awg and awg_name to the name of
your AWGs manufacturer (Zürich Instruments: ZI, TaborElectronics: Tabor).
"""

awg_name = 'TABOR'
awg_address = '127.0.0.1'

hardware_setup = HardwareSetup()

if awg_name == 'ZI':
from qupulse.hardware.awgs.zihdawg import HDAWGRepresentation
awg = HDAWGRepresentation(awg_address, 'USB')

channel_pairs = []
for pair_name in ('AB', 'CD', 'EF', 'GH'):
channel_pair = getattr(awg, 'channel_pair_%s' % pair_name)

for ch_i, ch_name in enumerate(pair_name):
playback_name = '{name}_{ch_name}'.format(name=awg_name, ch_name=ch_name)
hardware_setup.set_channel(playback_name,
PlaybackChannel(channel_pair, ch_i))
hardware_setup.set_channel(playback_name + '_MARKER_FRONT', MarkerChannel(channel_pair, 2 * ch_i))
hardware_setup.set_channel(playback_name + '_MARKER_BACK', MarkerChannel(channel_pair, 2 * ch_i + 1))
awg_channel = awg.channel_pair_AB

elif awg_name == 'TABOR':
from qupulse.hardware.awgs.tabor import TaborAWGRepresentation
awg = TaborAWGRepresentation(awg_address, reset=True)

channel_pairs = []
for pair_name in ('AB', 'CD'):
channel_pair = getattr(awg, 'channel_pair_%s' % pair_name)
channel_pairs.append(channel_pair)

for ch_i, ch_name in enumerate(pair_name):
playback_name = '{name}_{ch_name}'.format(name=awg_name, ch_name=ch_name)
hardware_setup.set_channel(playback_name, PlaybackChannel(channel_pair, ch_i))
hardware_setup.set_channel(playback_name + '_MARKER', MarkerChannel(channel_pair, ch_i))
awg_channel = channel_pairs[0]

else:
ValueError('Unknown AWG')

#%%
""" Create three simple pulses and put them together to a PulseTemplate called dnp """

plus = [(0, 0), ('ta', 'va', 'hold'), ('tb', 'vb', 'linear'), ('tend', 0, 'jump')]
minus = [(0, 0), ('ta', '-va', 'hold'), ('tb', '-vb', 'linear'), ('tend', 0, 'jump')]

zero_pulse = PointPT([(0, 0), ('tend', 0)], ('X', 'Y'))
plus_pulse = TablePT(entries={'X': plus, 'Y': plus})
minus_pulse = TablePT(entries={'X': minus, 'Y': minus})

dnp = RepetitionPT(minus_pulse, 'n_minus') @ RepetitionPT(zero_pulse, 'n_zero') @ RepetitionPT(plus_pulse, 'n_plus')

#%%
""" Create a program dnp with the number of pulse repetitions as volatile parameters """

sample_rate = awg_channel.sample_rate / 10**9
n_quant = 192
t_quant = n_quant / sample_rate

dnp_prog = dnp.create_program(parameters=dict(tend=float(t_quant), ta=float(t_quant/3), tb=float(2*t_quant/3),
va=0.12, vb=0.25, n_minus=3, n_zero=3, n_plus=3),
channel_mapping={'X': '{}_A'.format(awg_name), 'Y': '{}_B'.format(awg_name)},
volatile={'n_minus', 'n_zero', 'n_plus'})
dnp_prog.cleanup()

#%%
""" Upload this program to the AWG """

hardware_setup.register_program('dnp', dnp_prog)
hardware_setup.arm_program('dnp')

#%%
""" Run initial program """

awg_channel.run_current_program()

#%%
""" Change volatile parameters to new values and run the modified program """

hardware_setup.update_parameters('dnp', dict(n_zero=1, n_plus=5))
awg_channel.run_current_program()
10 changes: 3 additions & 7 deletions qupulse/hardware/setup.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from typing import NamedTuple, Set, Callable, Dict, Tuple, Union, Iterable, Any
from typing import NamedTuple, Set, Callable, Dict, Tuple, Union, Iterable, Any, Mapping
from collections import defaultdict
import warnings
import numbers

from qupulse.pulses.parameters import Parameter, ConstantParameter
from qupulse.hardware.awgs.base import AWG
from qupulse.hardware.dacs import DAC
from qupulse._program._loop import Loop
Expand Down Expand Up @@ -282,13 +282,9 @@ def rm_channel(self, identifier: ChannelID) -> None:
def registered_channels(self) -> Dict[ChannelID, Set[_SingleChannel]]:
return self._channel_map

def update_parameters(self, name: str, parameters):
def update_parameters(self, name: str, parameters: Mapping[str, numbers.Real]):
*_, awgs, dacs = self._registered_programs[name]

for parameter_name, value in parameters.items():
if not isinstance(value, Parameter):
parameters[parameter_name] = ConstantParameter(value)

for awg in self.known_awgs:
if awg in awgs:
awg.set_volatile_parameters(name, parameters)
Expand Down
28 changes: 28 additions & 0 deletions tests/hardware/setup_tests.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import unittest
from unittest import mock

import numpy as np

Expand Down Expand Up @@ -363,6 +364,33 @@ def test_known_awgs(self) -> None:
expected = {awg1, awg2}
self.assertEqual(expected, setup.known_awgs)

def test_update_parameters(self) -> None:
setup = HardwareSetup()
awg1 = DummyAWG(num_channels=2, num_markers=0)
awg2 = DummyAWG(num_channels=1, num_markers=1)
dac1 = DummyDAC()
dac2 = DummyDAC()
setup.set_channel('A', PlaybackChannel(awg1, 0))
setup.set_channel('B', PlaybackChannel(awg1, 1))
setup.set_channel('C', PlaybackChannel(awg2, 0))
setup.set_measurement('m1', MeasurementMask(dac1, 'DAC_1'))
setup.set_measurement('m2', MeasurementMask(dac2, 'DAC_2'))
loop1, loop2, _ = self.get_test_loops()
name1 = 'prog1'
name2 = 'prog2'
setup.register_program(name1, loop1)
setup.register_program(name2, loop2)

parameters = dict(a=1, b=5)

with mock.patch.object(DummyAWG, 'set_volatile_parameters') as setpara:
setup.update_parameters(name1, parameters)
setpara.assert_called_once_with(name1, parameters)
with mock.patch.object(DummyAWG, 'set_volatile_parameters') as setpara:
setup.update_parameters(name2, parameters)
assert setpara.call_count == 2
setpara.assert_called_with(name2, parameters)

def test_clear_programs(self) -> None:
setup = HardwareSetup()
awg1 = DummyAWG(num_channels=2, num_markers=0)
Expand Down
1 change: 0 additions & 1 deletion tests/hardware/tabor_dummy_based_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from qupulse.hardware.awgs.base import AWGAmplitudeOffsetHandling
from qupulse.hardware.awgs.tabor import TaborProgram, TaborAWGRepresentation, TaborProgramMemory
from qupulse._program.tabor import TableDescription, TimeType, TableEntry
from qupulse.pulses.parameters import ConstantParameter
from tests.hardware.dummy_modules import import_package


Expand Down
1 change: 0 additions & 1 deletion tests/hardware/tabor_simulator_based_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

from qupulse.hardware.awgs.tabor import TaborAWGRepresentation, TaborChannelPair
from qupulse._program.tabor import TaborSegment, PlottableProgram, TaborException, TableDescription, TableEntry
from qupulse.pulses.parameters import ConstantParameter
from typing import List, Tuple, Optional, Any

class TaborSimulatorManager:
Expand Down