Skip to content
This repository was archived by the owner on Dec 15, 2023. It is now read-only.

Commit 3801e31

Browse files
[DEM-943] Resolved review comments.
1 parent a7873fc commit 3801e31

File tree

8 files changed

+130
-38
lines changed

8 files changed

+130
-38
lines changed

docs/notebooks/unfinished/example_UHFLI_measurements.py

+24-20
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def update_stimulus(is_enabled: bool, signal_output: int = 1, signal_input: Opti
2626
Args:
2727
is_enabled: True to enable and False to disable.
2828
signal_output: One of the two outputs on the device.
29-
signal_intput: One of the two inputs on the device.
29+
signal_input: One of the two inputs on the device.
3030
amplitude: Amplitude in volts, allowed values are 0.0 - 1.5 V.
3131
demodulator: Which demodulator used to connect to the signal output to.
3232
"""
@@ -56,7 +56,7 @@ def set_stimulus_oscillator_frequency(frequency: float, oscillator: int = 1) ->
5656

5757

5858
def update_scope(period: Optional[float] = None, sample_rate: Optional[float] = 27e3,
59-
input_channels : Optional[Dict[int, str]] = {'Demod 1 R': 1},
59+
input_channels : Optional[Dict[str, int]] = None,
6060
input_ranges: Optional[Tuple[float, float]] = (1.0, 1.0),
6161
limits: Optional[Tuple[float, float]] = (0.0, 1.0),
6262
trigger_enabled: Optional[bool] = False, trigger_level: Optional[float] = 0.5):
@@ -71,6 +71,12 @@ def update_scope(period: Optional[float] = None, sample_rate: Optional[float] =
7171
trigger_enabled: Will enable the external triggering on 'Trigger input 1' if True.
7272
trigger_level: The level of the trigger in Volt.
7373
"""
74+
if period is not None:
75+
scope_reader.period = period
76+
77+
if input_channels is None:
78+
input_channels = {'Demod 1 R': 1}
79+
7480
nearest_sample_rate = scope_reader.get_nearest_sample_rate(sample_rate)
7581
scope_reader.sample_rate = nearest_sample_rate
7682

@@ -80,8 +86,6 @@ def update_scope(period: Optional[float] = None, sample_rate: Optional[float] =
8086

8187
[scope_reader.set_channel_limits(channel, *limits) for channel in unique_channels]
8288
[scope_reader.set_input_signal(channel, attribute) for (attribute, channel) in input_channels.items()]
83-
if period:
84-
scope_reader.period = period
8589

8690
scope_reader.trigger_enabled = trigger_enabled
8791
scope_reader.trigger_channel = 'Trig Input 1'
@@ -90,7 +94,7 @@ def update_scope(period: Optional[float] = None, sample_rate: Optional[float] =
9094
scope_reader.trigger_delay = 0
9195

9296

93-
## Settings
97+
# Settings
9498

9599
class HardwareSettings(Instrument):
96100

@@ -109,25 +113,25 @@ def __init__(self, name='settings'):
109113

110114
working_directory = "D:\\Workspace\\TNO\\git\\DEM-943\\qtt\\docs\\notebooks\\unfinished"
111115

112-
## Lock-in Amplifier
116+
# Lock-in Amplifier
113117

114-
UHFLI_id = 'dev2338'
115-
file_path_UHFLI = os.path.join(working_directory, f'UHFLI_{UHFLI_id}.dat')
116-
UHFLI_configuration = load_configuration(file_path_UHFLI)
118+
uhfli_id = 'dev2338'
119+
file_path_UHFLI = os.path.join(working_directory, f'UHFLI_{uhfli_id}.dat')
120+
uhfli_configuration = load_configuration(file_path_UHFLI)
117121

118-
stimulus = UHFLIStimulus(UHFLI_id)
119-
stimulus.initialize(UHFLI_configuration)
120-
scope_reader = UHFLIScopeReader(UHFLI_id)
122+
stimulus = UHFLIStimulus(uhfli_id)
123+
stimulus.initialize(uhfli_configuration)
124+
scope_reader = UHFLIScopeReader(uhfli_id)
121125

122126

123-
## AWG
127+
# AWG
124128

125-
HDAWG8_id = 'dev8048'
126-
file_path_HDAWG8 = os.path.join(working_directory, f'HDAWG8_{HDAWG8_id}.dat')
127-
HDAWG8_configuration = load_configuration(file_path_HDAWG8)
129+
hdawg8_id = 'dev8048'
130+
file_path_HDAWG8 = os.path.join(working_directory, f'HDAWG8_{hdawg8_id}.dat')
131+
hdawg8_configuration = load_configuration(file_path_HDAWG8)
128132

129-
awg_adapter = InstrumentAdapterFactory.get_instrument_adapter('ZIHDAWG8InstrumentAdapter', HDAWG8_id)
130-
awg_adapter.apply(HDAWG8_configuration)
133+
awg_adapter = InstrumentAdapterFactory.get_instrument_adapter('ZIHDAWG8InstrumentAdapter', hdawg8_id)
134+
awg_adapter.apply(hdawg8_configuration)
131135

132136
awg_adapter.instrument.warnings_as_errors.append(WARNING_ANY)
133137

@@ -144,7 +148,7 @@ def __init__(self, name='settings'):
144148
awg_adapter.instrument.awgs_0_time(awg_sampling_rate_586KHz)
145149

146150

147-
## Virtual AWG
151+
# Virtual AWG
148152

149153
settings = HardwareSettings()
150154
virtual_awg = VirtualAwg([awg_adapter.instrument], settings)
@@ -156,7 +160,7 @@ def __init__(self, name='settings'):
156160
virtual_awg.digitizer_marker_uptime(marker_uptime)
157161

158162

159-
## Station
163+
# Station
160164

161165
gates = VirtualIVVI('gates', gates=['P1', 'P2'], model=None)
162166
station = Station(virtual_awg, scope_reader.adapter.instrument, awg_adapter.instrument, gates)

docs/notebooks/unfinished/example_process_sawtooth_2d.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,8 @@ def create_dummy_data_array(width: float, processing: str, sawteeth_count: int,
3232
scope_data = sawtooth(2 * np.pi * (sawteeth_count * time / period), width)
3333
offset = {'left': 1 - width, 'center': (1 - width /2), 'right': 0}
3434
scope_data = np.roll(scope_data, int(offset[processing] * len(scope_data)))
35-
3635
return DataArray(identifier, label, preset_data=scope_data, set_arrays=[set_array])
3736

38-
3937
data_set = DataSet()
4038
data_set.user_data = {'resolution': resolution, 'width': width, 'processing': processing}
4139

@@ -46,14 +44,14 @@ def create_dummy_data_array(width: float, processing: str, sawteeth_count: int,
4644
data_set.add_array(data_array_y)
4745

4846

49-
## EXAMPLE PRCCESSING 2D SAWTOOTH
47+
# EXAMPLE PRCCESSING 2D SAWTOOTH
5048

5149
signal_processor = SignalProcessorRunner()
5250
signal_processor.add_signal_processor(ProcessSawtooth2D())
5351
processed_data_set = signal_processor.run(data_set)
5452

5553

56-
## PLOTTING
54+
# PLOTTING
5755

5856
color_cycler = cycle('bgrcmk')
5957

src/qtt/measurements/acquisition/interfaces/acquisition_interface.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
""" Interface for devices to acquire data."""
22

33
from abc import ABC, abstractmethod
4-
from typing import List
4+
from typing import List, Optional
55

66
from qilib.data_set import DataArray
77
from qilib.utils import PythonJsonStructure
@@ -36,7 +36,7 @@ def start_acquisition(self) -> None:
3636
"""
3737

3838
@abstractmethod
39-
def acquire(self, number_of_averages: int, timeout: float) -> List[DataArray]:
39+
def acquire(self, number_of_averages: int, timeout: Optional[float] = 30) -> List[DataArray]:
4040
""" Reads raw-data from the acquisition device.
4141
4242
This method should be called after initialising and starting the acquisition.

src/qtt/measurements/acquisition/interfaces/acquisition_scope_interface.py

+90
Original file line numberDiff line numberDiff line change
@@ -14,51 +14,141 @@ class AcquisitionScopeInterface(AcquisitionInterface, ABC):
1414
def input_range(self) -> Tuple[float, float]:
1515
""" The input range of the channels."""
1616

17+
@input_range.setter
18+
@abstractmethod
19+
def input_range(self, value: Tuple[float, float]) -> None:
20+
""" Gets the amplitude input range of the channels.
21+
22+
Args:
23+
value: The input range amplitude in Volts.
24+
"""
25+
1726
@property
1827
@abstractmethod
1928
def sample_rate(self) -> float:
2029
""" The sample rate of the acquisition device."""
2130

31+
@sample_rate.setter
32+
@abstractmethod
33+
def sample_rate(self, value: float) -> None:
34+
""" Sets the sample rate of the acquisition device.
35+
36+
Args:
37+
value: The sample rate in samples per second.
38+
"""
39+
2240
@property
2341
@abstractmethod
2442
def period(self) -> float:
2543
""" The measuring period of the acquisition."""
2644

45+
@period.setter
46+
@abstractmethod
47+
def period(self, value: float) -> None:
48+
""" Sets the measuring period of the acquisition.
49+
50+
Args:
51+
value: The measuring period in seconds.
52+
"""
53+
2754
@property
2855
@abstractmethod
2956
def number_of_samples(self) -> int:
3057
""" The number of samples to take during a acquisition."""
3158

59+
@number_of_samples.setter
60+
@abstractmethod
61+
def number_of_samples(self, value: int) -> None:
62+
""" Sets the sample count to take during a acquisition.
63+
64+
Args:
65+
value: The number of samples.
66+
"""
67+
3268
@property
3369
@abstractmethod
3470
def trigger_enabled(self) -> bool:
3571
""" The setter sets the external triggering on or off. The getter returns the current trigger value."""
3672

73+
@trigger_enabled.setter
74+
@abstractmethod
75+
def trigger_enabled(self, value: bool) -> None:
76+
""" Turns the external triggering on or off.
77+
78+
Args:
79+
value: The trigger on/off value.
80+
"""
81+
3782
@property
3883
@abstractmethod
3984
def trigger_channel(self) -> str:
4085
""" The input signal to trigger the acquisition on."""
4186

87+
@trigger_channel.setter
88+
@abstractmethod
89+
def trigger_channel(self, channel: str) -> None:
90+
""" Sets the external triggering channel.
91+
92+
Args:
93+
channel: The trigger channel value.
94+
"""
95+
4296
@property
4397
@abstractmethod
4498
def trigger_level(self) -> float:
4599
""" The trigger-level of the trigger in Volts."""
46100

101+
@trigger_level.setter
102+
@abstractmethod
103+
def trigger_level(self, level: float) -> None:
104+
""" Sets the external triggering level.
105+
106+
Args:
107+
level: The external trigger level in Volts.
108+
"""
109+
47110
@property
48111
@abstractmethod
49112
def trigger_slope(self) -> str:
50113
""" The edge of the trigger signal to trigger on."""
51114

115+
@trigger_slope.setter
116+
@abstractmethod
117+
def trigger_slope(self, slope: str) -> None:
118+
""" Sets the external triggering slope.
119+
120+
Args:
121+
slope: The external trigger slope.
122+
"""
123+
52124
@property
53125
@abstractmethod
54126
def trigger_delay(self) -> float:
55127
""" The delay between getting a trigger and acquiring in seconds."""
56128

129+
@trigger_delay.setter
130+
@abstractmethod
131+
def trigger_delay(self, delay: float) -> None:
132+
""" Sets the delay in seconds between the external trigger and acquisition.
133+
134+
Args:
135+
delay: The scope trigger delay in seconds.
136+
"""
137+
57138
@property
58139
@abstractmethod
59140
def enabled_channels(self) -> Tuple[int, ...]:
60141
""" Reports the enabled input channels."""
61142

143+
@enabled_channels.setter
144+
@abstractmethod
145+
def enabled_channels(self, value: Tuple[int, ...]):
146+
""" Sets the given channels to enabled and turns off all others.
147+
148+
Args:
149+
value: The channels which needs to be enabled.
150+
"""
151+
62152
@abstractmethod
63153
def set_input_signal(self, channel: int, attribute: Optional[str]) -> None:
64154
""" Adds an input channel to the scope.

src/qtt/measurements/acquisition/uhfli_scope_reader.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@ def period(self, value: float) -> None:
136136
"""
137137
self.__uhfli.scope_duration.set(value)
138138

139-
140139
@property
141140
def number_of_samples(self) -> int:
142141
""" Gets the sample count to take during a acquisition.
@@ -330,9 +329,9 @@ def __get_uhfli_scope_records(self, number_of_averages: int, timeout: float) ->
330329
traces = self.__uhfli.scope.read(True)
331330
wave_nodepath = f'/{self._address}/scopes/0/wave'
332331
scope_traces = traces[wave_nodepath][:number_of_averages]
333-
return self.__convert_scope_data(scope_traces, number_of_averages)
332+
return self.__convert_scope_data(scope_traces)
334333

335-
def __convert_scope_data(self, scope_traces: np.ndarray, number_of_averages: int) -> List[DataArray]:
334+
def __convert_scope_data(self, scope_traces: np.ndarray) -> List[DataArray]:
336335
data = []
337336
acquisition_counter = 0
338337
for channel_index, _ in enumerate(self.enabled_channels):

src/qtt/measurements/scans.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -1687,18 +1687,20 @@ def measure_segment_uhfli(zi, waveform, channels, number_of_averages=100):
16871687
return [avarage]
16881688

16891689

1690-
def measure_segment_scope_reader(minstrhandle, waveform, Naverage, process=True):
1690+
def measure_segment_scope_reader(scope_reader, waveform, number_of_averages, process=True):
16911691
""" Measure block data with scope reader.
16921692
16931693
Args:
1694-
minstrhandle (AcquisitionScopeInterface): Instance of scope reader.
1694+
scope_reader (AcquisitionScopeInterface): Instance of scope reader.
16951695
waveform (dict): Information about the waveform that is to be collected.
16961696
number_of_averages (int) : Number of times the sample is collected.
1697+
process (bool): If True, cut off the downward sawtooth slopes from the data.
1698+
16971699
Returns:
16981700
data (numpy array): An array of arrays, one array per input channel.
16991701
17001702
"""
1701-
data_arrays = minstrhandle.acquire(number_of_averages=Naverage)
1703+
data_arrays = scope_reader.acquire(number_of_averages)
17021704
raw_data = np.array(data_arrays)
17031705
if not process:
17041706
return raw_data
@@ -1710,7 +1712,7 @@ def measure_segment_scope_reader(minstrhandle, waveform, Naverage, process=True)
17101712

17111713
resolution = waveform.get('resolution', None)
17121714
start_zero = waveform.get('start_zero', False)
1713-
sample_rate = minstrhandle.sample_rate
1715+
sample_rate = scope_reader.sample_rate
17141716
period = waveform['period']
17151717

17161718
if len(width) == 2:

src/qtt/measurements/videomode.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,7 @@ def run(self, start_readout=True):
477477
scan_channels = self.scanparams['minstrument'][1]
478478
channel_attributes = self.scanparams['minstrument'][2]
479479
self.minstrumenthandle.enabled_channels = tuple(scan_channels)
480-
for item in zip(scan_channels, channel_attributes):
481-
self.minstrumenthandle.set_input_signal(item[0], item[1])
480+
map(self.minstrumenthandle.set_input_signal, scan_channels, channel_attributes)
482481
self.minstrumenthandle.start_acquisition()
483482
self.startreadout()
484483

src/tests/measurements/test_scans.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def test_measure_segment_scope_reader_2D(self):
131131
result_data = measure_segment_scope_reader(mock_scope, waveform, average_count)
132132

133133
array_mock.assert_called_once_with(mock_data_arrays)
134-
mock_scope.acquire.assert_called_once_with(number_of_averages=average_count)
134+
mock_scope.acquire.assert_called_once_with(average_count)
135135
process_mock.assert_called_with(raw_data_mock, period, sample_rate,
136136
resolution, width, fig=None, start_zero=False)
137137
self.assertEqual(data_mock, result_data)
@@ -156,7 +156,7 @@ def test_measure_segment_scope_reader_1D(self):
156156
result_data = measure_segment_scope_reader(mock_scope, waveform, average_count)
157157

158158
array_mock.assert_called_once_with(mock_data_arrays)
159-
mock_scope.acquire.assert_called_once_with(number_of_averages=average_count)
159+
mock_scope.acquire.assert_called_once_with(average_count)
160160
process_mock.assert_called_with(raw_data_mock, [width], period, sample_rate,
161161
resolution=None, start_zero=False, fig=None)
162162
self.assertEqual(data_mock, result_data)
@@ -169,5 +169,5 @@ def test_measure_segment_scope_reader_no_processing(self):
169169
numpy_array_mock = MagicMock()
170170
with patch('numpy.array', return_value=numpy_array_mock):
171171
result_data = measure_segment_scope_reader(mock_scope, None, average_count, process=False)
172-
mock_scope.acquire.assert_called_once_with(number_of_averages=average_count)
172+
mock_scope.acquire.assert_called_once_with(average_count)
173173
self.assertEqual(numpy_array_mock, result_data)

0 commit comments

Comments
 (0)