From acbbcbfa9c51ee596eb6aadfd332c09b7c9f0195 Mon Sep 17 00:00:00 2001
From: Sander de Snoo <59472150+sldesnoo-Delft@users.noreply.github.com>
Date: Wed, 16 Aug 2023 12:07:19 +0200
Subject: [PATCH] Fixed after testing with M4i

---
 pulse_lib/tektronix/m4i_controller.py         | 28 +++++++++++------
 pulse_lib/tektronix/tektronix5014_uploader.py | 12 +++++---
 .../tests/configurations/configurations.yaml  | 28 ++++++++++++++---
 .../configurations/tektronix_test_sds.yaml    | 30 +++++++++++++++++++
 4 files changed, 81 insertions(+), 17 deletions(-)
 create mode 100644 pulse_lib/tests/configurations/tektronix_test_sds.yaml

diff --git a/pulse_lib/tektronix/m4i_controller.py b/pulse_lib/tektronix/m4i_controller.py
index 81f467a7..fc3cfc4a 100644
--- a/pulse_lib/tektronix/m4i_controller.py
+++ b/pulse_lib/tektronix/m4i_controller.py
@@ -127,13 +127,13 @@ class M4iControl:
         if self._data_sample_rate is None:
             data = np.mean(data, axis=-1)
         else:
-            step = self._sample_rate / self._data_sample_rate
-            boundaries = np.int(np.arange(0, self._samples_per_segment, step)+0.5)
+            step = self._eff_sample_rate / self._data_sample_rate
+            boundaries = np.floor(np.arange(0, self._samples_per_segment, step)+0.5).astype(int)
             if self._samples_per_segment - boundaries[-1] > 0.8*step:
                 boundaries = np.concatenate([boundaries, [-1]])
             res = np.empty(data.shape[:-1] + (len(boundaries)-1,))
             for i in range(len(boundaries)-1):
-                res[..., i] = data[..., boundaries[i]:boundaries[i+1]]
+                res[..., i] = np.mean(data[..., boundaries[i]:boundaries[i+1]], axis=-1)
             data = res
 
         # filter acquisitions: the number of acquisitions per channel can differ
@@ -143,13 +143,23 @@ class M4iControl:
                 sel = self._digitizer_triggers.get_channel_indices(ch)
                 if len(sel):
                     ch_data = data[i]
-                    ch_data = ch_data[..., sel]
-                    if self._average_repetitions:
-                        ch_data = np.mean(ch_data, axis=0)
-                    res.append(ch_data)
+                    if self._n_rep:
+                        ch_data = ch_data[:, sel]
+                        if self._average_repetitions:
+                            ch_data = np.mean(ch_data, axis=0)
+                    else:
+                        ch_data = ch_data[sel]
+                    res.append(ch_data.flatten())
         else:
-            res = list(data)
+            res = [d.flatten() for d in data]
 
         return res
 
-
+    def actual_acquisition_points(self, duration, sample_rate):
+        dig_sample_rate = self._cached_get('sample_rate')
+        divisor = self._box_averages if self._box_averages is not None else 1
+        eff_sample_rate = dig_sample_rate / divisor
+        n_dig_samples = round(eff_sample_rate * duration * 1e-9)
+        step = eff_sample_rate / sample_rate
+        n_samples = int(n_dig_samples / step + 0.2)
+        return n_samples, 1e9/eff_sample_rate
diff --git a/pulse_lib/tektronix/tektronix5014_uploader.py b/pulse_lib/tektronix/tektronix5014_uploader.py
index 54794c4b..d3902934 100644
--- a/pulse_lib/tektronix/tektronix5014_uploader.py
+++ b/pulse_lib/tektronix/tektronix5014_uploader.py
@@ -76,6 +76,10 @@ class Tektronix5014_Uploader:
         self.pending_deletes = dict()
         self.release_all_awg_memory()
 
+        # Currently support 1 digitizer
+        digitizer = list(self.digitizers.values())[0]
+        self.m4i_control = M4iControl(digitizer)
+
     def setup_slaves(self):
         logger.info(f'Configure slave AWGs: {self.awg_sync}')
         for slave in self.awg_sync.values():
@@ -277,9 +281,6 @@ class Tektronix5014_Uploader:
         '''
         acq_conf = job.acquisition_conf
 
-        # Currently support 1 digitizer
-        digitizer = list(self.digitizers.values())[0]
-        self.m4i_control = M4iControl(digitizer)
         self.m4i_control.configure_acquisitions(
                 job.digitizer_triggers,
                 job.n_rep,
@@ -288,6 +289,9 @@ class Tektronix5014_Uploader:
         self.acq_description = AcqDescription(job.seq_id, job.index,
                                               job.digitizer_triggers)
 
+    def actual_acquisition_points(self, channel_name, duration, sample_rate):
+        return self.m4i_control.actual_acquisition_points(duration, sample_rate)
+
     def get_channel_data(self, seq_id, index):
         acq_desc = self.acq_description
         if (acq_desc.seq_id != seq_id
@@ -295,7 +299,7 @@ class Tektronix5014_Uploader:
             raise Exception(f'Data for index {index} not available')
 
         dig_data = self.m4i_control.get_data()
-        data = {i:np.zeros(0) for i in [1,2,3,4]}
+        data = {i:np.zeros(0) for i in [0,1,2,3]}
         for i,ch in enumerate(acq_desc.digitizer_triggers.active_channels):
             data[ch] = dig_data[i]
 
diff --git a/pulse_lib/tests/configurations/configurations.yaml b/pulse_lib/tests/configurations/configurations.yaml
index 5eb42bf6..0d2c3153 100644
--- a/pulse_lib/tests/configurations/configurations.yaml
+++ b/pulse_lib/tests/configurations/configurations.yaml
@@ -89,6 +89,24 @@ TektronixMocked:
             startup_time: 500
     runner: qcodes
 
+TektronixSdS:
+    station: tektronix_test_sds.yaml
+    backend: Tektronix_5014
+    schedule: TektronixM4i
+    awg_channels:
+        AWG1: [P1,P2,I1,Q1]
+    markers:
+        M1: [AWG1,[1,1]]
+        M_M4i: [AWG1,[1,2]]
+        M_IQ1: [AWG1,[2,1]]
+    sensors:
+        SD1: [Dig1,0]
+        SD2: [Dig1,1]
+    rf:
+        SD2:
+            output: M1
+            startup_time: 500
+    runner: qcodes
 
 QbloxV1:
     station: qblox_v1.yaml
@@ -113,8 +131,9 @@ QbloxGS1:
         Qblox_module2: [P1,P2,P3,]
         Qblox_module4: [P4,P5,P6,P7]
         Qblox_module6: [I1,Q1,I2,Q2]
+        Qblox_module8: [P9,P10,P11,P12]
     markers:
-        M1: [Qblox_module2,1]
+        M1: [Qblox_module2,0]
         M_IQ1: [Qblox_module6,0]
         M_IQ2: [Qblox_module6,2]
     sensors:
@@ -123,8 +142,9 @@ QbloxGS1:
     runner: core_tools
 
 KeysightSdS:
-    station: keysight_test_sds.yaml
-    backend: Keysight
+#    station: keysight_test_sds.yaml
+    station: keysight_test_sds_qs.yaml
+    backend: Keysight_QS
     schedule: HVI2
     # P1,P3,P6,P7 are connected to SD1-SD4
     awg_channels:
@@ -144,4 +164,4 @@ KeysightSdS:
         SD2:
             output: M1
             startup_time: 500
-    runner: qcodes
+    runner: core_tools
diff --git a/pulse_lib/tests/configurations/tektronix_test_sds.yaml b/pulse_lib/tests/configurations/tektronix_test_sds.yaml
new file mode 100644
index 00000000..b888f292
--- /dev/null
+++ b/pulse_lib/tests/configurations/tektronix_test_sds.yaml
@@ -0,0 +1,30 @@
+instruments:
+
+  sig_gen1:
+    type: qcodes.tests.instrument_mocks.DummyInstrument
+    enable_forced_reconnect: true
+    init:
+      gates: ['frequency','power']
+    parameters:
+      frequency:
+        limits: [0,20e9]
+
+  sig_gen2:
+    type: qcodes.tests.instrument_mocks.DummyInstrument
+    enable_forced_reconnect: true
+    init:
+      gates: ['frequency','power']
+    parameters:
+      frequency:
+        limits: [0,20e9]
+
+  AWG1:
+    type: qcodes.instrument_drivers.tektronix.AWG5014.Tektronix_AWG5014
+    enable_forced_reconnect : True
+    init:
+      address: 'TCPIP0::192.168.0.204::inst0::INSTR'
+
+
+  Dig1:
+    type: qcodes_contrib_drivers.drivers.Spectrum.M4i.M4i
+    enable_forced_reconnect: true
-- 
GitLab