diff --git a/pulse_lib/keysight/M3202A_uploader.py b/pulse_lib/keysight/M3202A_uploader.py
index af26465f97cb4956e87d5427430b4969d0597060..eed7020fbefba8b6f517a5abd3774d6eb4d9c3e0 100644
--- a/pulse_lib/keysight/M3202A_uploader.py
+++ b/pulse_lib/keysight/M3202A_uploader.py
@@ -78,10 +78,19 @@ class M3202A_Uploader:
         awg = list(self.AWGs.values())[0]
         return awg.convert_prescaler_to_sample_rate(awg.convert_sample_rate_to_prescaler(sample_rate))
 
-    def get_num_samples(self, acquisition_channel, t_measure, sample_rate):
+    def actual_acquisition_points(self, acquisition_channel, t_measure, sample_rate):
+        '''
+        Returns the actual number of points and interval of an acquisition.
+        '''
         dig_ch = self.digitizer_channels[acquisition_channel]
         digitizer = self.digitizers[dig_ch.module_name]
-        return digitizer.get_samples_per_measurement(t_measure, sample_rate)
+        if hasattr(digitizer, 'actual_acquisition_points'):
+            n_samples, interval = digitizer.actual_acquisition_points(dig_ch, t_measure, sample_rate)
+        else:
+            # use old function and assume the digitizer is NOT in MODES.NORMAL
+            n_samples = digitizer.get_samples_per_measurement(t_measure, sample_rate)
+            interval = int(max(1, round(100e6 / sample_rate))) * 10
+        return n_samples, interval
 
     def create_job(self, sequence, index, seq_id, n_rep, sample_rate, neutralize=True, alignment=None):
         # TODO @@@ implement alignment
diff --git a/pulse_lib/keysight/qs_uploader.py b/pulse_lib/keysight/qs_uploader.py
index e94c311699e2fce9459f3ae3a65895c358b33553..b0369d5ccf1b2095caea7ee5ca5f45604e6eb960 100644
--- a/pulse_lib/keysight/qs_uploader.py
+++ b/pulse_lib/keysight/qs_uploader.py
@@ -75,7 +75,7 @@ class QsUploader:
         awg = list(self.AWGs.values())[0]
         return awg.convert_prescaler_to_sample_rate(awg.convert_sample_rate_to_prescaler(sample_rate))
 
-    def get_num_samples(self, acquisition_channel, t_measure, sample_rate):
+    def actual_acquisition_points(self, acquisition_channel, t_measure, sample_rate):
         raise NotImplementedError()
 
     def get_roundtrip_latency(self):
diff --git a/pulse_lib/qblox/pulsar_uploader.py b/pulse_lib/qblox/pulsar_uploader.py
index 503bfa6f61ec2eacc5acf268db18d13456b47539..63113d5004560fb2c328f5e138faf53f726691aa 100644
--- a/pulse_lib/qblox/pulsar_uploader.py
+++ b/pulse_lib/qblox/pulsar_uploader.py
@@ -151,13 +151,8 @@ class PulsarUploader:
         """
         return 1e9
 
-    def get_num_samples(self, acquisition_channel, t_measure, sample_rate):
-        # todo: remove code duplication with add_acquisition_channel
-        trigger_period = PulsarConfig.align(1e9/sample_rate)
-        n_samples = max(1, iround(t_measure / trigger_period))
-        # @@@ n_repeat not taken into account
-        # @@@ always minimum 1 sample: UploadAggregator raises an exception for 0 cycles.
-        return n_samples
+    def actual_acquisition_points(self, acquisition_channel, t_measure, sample_rate):
+        return _actual_acquisition_points(t_measure, sample_rate)
 
     def create_job(self, sequence, index, seq_id, n_rep, sample_rate,
                    neutralize=True, alignment=None):
@@ -449,6 +444,13 @@ class SegmentRenderInfo:
         return self.t_start + self.npt
 
 
+def _actual_acquisition_points(t_measure, sample_rate):
+    trigger_period = PulsarConfig.align(1e9/sample_rate)
+    t_measure = PulsarConfig.align(t_measure)
+    n_samples = t_measure // trigger_period
+    return n_samples, trigger_period
+
+
 class UploadAggregator:
     verbose = False
 
@@ -750,11 +752,6 @@ class UploadAggregator:
 
         acq_conf = job.acquisition_conf
 
-        if acq_conf.sample_rate is not None:
-            trigger_period = PulsarConfig.align(1e9/acq_conf.sample_rate)
-        else:
-            trigger_period = None
-
         if acq_conf.average_repetitions or not job.n_rep:
             n_rep = 1
         else:
@@ -790,8 +787,8 @@ class UploadAggregator:
                                          PulsarConfig.align(acquisition.interval))
                     if acq_conf.sample_rate is not None:
                         logging.info(f'Acquisition sample_rate is ignored when n_repeat is set')
-                elif trigger_period:
-                    n_cycles = iround(t_measure / trigger_period)
+                elif acq_conf.sample_rate is not None:
+                    n_cycles, trigger_period = _actual_acquisition_points(t_measure, acq_conf.sample_rate)
                     if n_cycles < 1:
                         raise Exception(f'{channel_name} acquisition t_measure ({t_measure}) < 1/sample_rate ({trigger_period})')
                     seq.repeated_acquire(t, trigger_period, n_cycles, trigger_period)
diff --git a/pulse_lib/sequencer.py b/pulse_lib/sequencer.py
index 5030d94b97507ca620f1afc4351b455a2e0f2694..a49ae532d31a4440d949396dacec3893da248961 100644
--- a/pulse_lib/sequencer.py
+++ b/pulse_lib/sequencer.py
@@ -177,7 +177,6 @@ class sequencer():
                 effective_rate = self.uploader.get_effective_sample_rate(seg_container.sample_rate)
                 msg = f"effective sampling rate for {seg_container.name} is set to {si_format(effective_rate, precision=1)}Sa/s"
                 logging.info(msg)
-                print("Info : " + msg)
 
         # update dimensionality of all sequence objects
         logging.debug('Enter pre-rendering')
@@ -364,9 +363,15 @@ class sequencer():
                     t_measure = m.t_measure
                 else:
                     raise Exception(f't_measure must be number and not a {type(m.t_measure)} for time traces')
-                m.n_samples = self.uploader.get_num_samples(
-                        m.acquisition_channel, t_measure, sample_rate) # @@@ implement QS, Tektronix
-                m.interval = round(1e9/sample_rate)
+                # @@@ implement QS, Tektronix
+                if hasattr(self.uploader, 'actual_acquisition_points'):
+                    m.n_samples, m.interval = self.uploader.actual_acquisition_points(m.acquisition_channel,
+                                                                                      t_measure, sample_rate)
+                else:
+                    print(f'WARNING {type(self.uploader)} is missing method actual_acquisition_points(); using old computation')
+                    m.n_samples = self.uploader.get_num_samples(
+                            m.acquisition_channel, t_measure, sample_rate)
+                    m.interval = round(1e9/sample_rate)
             else:
                 m.n_samples = 1