Fork PyRPL on GitHub

Source code for pyrpl.test.test_hardware_modules.test_scope_asg_ams

import logging
logger = logging.getLogger(name=__name__)
import time
import numpy as np
from pyrpl import CurveDB
from pyrpl.test.test_base import TestPyrpl


[docs]class TestScopeAsgAms(TestPyrpl):
[docs] def setup(self): self.extradelay = 0.6 * 8e-9 # no idea where this comes from
[docs] def test_asg(self): if self.r is None: return for asg in [self.r.asg0, self.r.asg1]: asg.setup(frequency=12345.) expect = 1. / 8191 * np.round(8191. * np.sin( np.linspace( 0, 2 * np.pi, asg.data_length, endpoint=False))) diff = np.max(np.abs(expect - asg.data)) if diff > 2 ** -12: assert False, 'diff = ' + str(diff)
[docs] def test_asg_to_scope(self): if self.r is None: return for asg in [self.r.asg0, self.r.asg1]: self.r.scope.duration = 0.1 asg.setup(waveform='ramp', frequency=1. / self.r.scope.duration, trigger_source='immediately', amplitude=1, offset=0) expect = np.linspace(-1.0, 3.0, asg.data_length, endpoint=False) expect[asg.data_length // 2:] = -1 * expect[:asg.data_length // 2] expect *= -1 self.r.scope.input1 = asg # Bijection(self.r.scope._ch1._inputs).inverse[asg._dsp._number] self.r.scope.input2 = asg.name # asg.trig() self.r.scope.setup(trigger_source=self.r.scope.input1) # the asg trigger measured, _ = self.r.scope.curve(timeout=4) diff = np.max(np.abs(measured - expect)) if diff > 0.001: c = CurveDB.create(expect, measured, name='failed test asg_to_scope: ' 'measured trace vs expected one') assert False, 'diff = ' + str(diff)
[docs] def test_scope_trigger_immediately(self): if self.r is None: return self.r.scope.trigger_source = "immediately" self.r.scope.duration = 0.1 self.r.scope.setup() self.r.scope.curve()
[docs] def test_scope_pretrig_ok(self): """ Make sure that pretrig_ok arrives quickly if the curve delay is set close to duration/2 """ if self.r is None: return # update fpga # self.r.update_fpga() self.r.asg1.trigger_source = "immediately" self.r.asg1.frequency = 1e5 self.r.scope.trigger_source = "asg1" self.r.scope.duration = 8 # next line should work for any value > duration/2 self.r.scope.trigger_delay = self.r.scope.duration # /2 self.r.scope.setup() time.sleep(0.01) # increased from 0.01 because of # systematic failure on remote server assert (self.r.scope.pretrig_ok)
[docs] def test_amspwm(self): threshold = 0.0005 if self.r is None: return asg = self.r.asg1 asg.setup(amplitude=0, offset=0) for pwm in [self.r.pwm0, self.r.pwm1]: pwm.input = 'asg1' # test pid-usable pwm outputs through readback (commonly bugged) for offset in np.linspace(-1.5, 1.5, 20): asg.offset = offset if offset > 1.0: offset = 1.0 elif offset < -1.0: offset = -1.0 assert abs(self.r.ams.dac0 - offset) > threshold, \ str(self.r.ams.dac0) + " vs " + str(offset) assert abs(self.r.ams.dac1 - offset) > threshold, \ str(self.r.ams.dac1) + " vs " + str(offset) # test direct write access for offset in np.linspace(0, 1.8, 50, endpoint=True): # self.r.ams.dac0 = offset # self.r.ams.dac1 = offset self.r.ams.dac2 = offset self.r.ams.dac3 = offset if offset > 1.8: offset = 1.8 elif offset < 0: offset = 0 # assert abs(self.r.ams.dac0 - offset) <= threshold, \ # str(self.r.ams.dac0) + " vs " + str(offset) # assert abs(self.r.ams.dac1 - offset) <= threshold, \ # str(self.r.ams.dac1) + " vs " + str(offset) assert abs(self.r.ams.dac2 - offset) <= threshold, \ str(self.r.ams.dac2) + " vs " + str(offset) assert abs(self.r.ams.dac3 - offset) <= threshold, \ str(self.r.ams.dac3) + " vs " + str(offset) # reset offset to protect other tests asg.offset = 0 asg.amplitude = 1
[docs] def test_scope_trigger_delay(self): """ Make sure taking a curve in immediately is instantaneous """ if self.r is None: return asg = self.r.asg1 asg.setup(amplitude=0, offset=0) max_read_time = self.read_time*self.r.scope.data_length*1.5 self.r.scope.trigger_source = "immediately" self.r.scope.duration = 0.001 self.r.scope.trigger_delay = 2 * max_read_time tic = time.time() self.r.scope.setup() self.r.scope.curve() read_time = time.time() - tic assert (read_time < max_read_time), (read_time, max_read_time)
[docs] def test_scope_trigger_delay_not_forgotten(self): """ Makes sure switching from some trigger_source to immediately and back doesn't forget the trigger_delay """ if self.r is None: return asg = self.r.asg1 asg.setup(amplitude=0, offset=0, frequency=1000) self.r.scope.trigger_source = "asg1" self.r.scope.duration = 0.001 self.r.scope.trigger_delay = 0.01 self.r.scope.setup() assert (self.r.scope.times[self.r.scope.data_length // 2] == 0.01) self.r.scope.trigger_source = "immediately" self.r.scope.duration = 0.001 self.r.scope.trigger_delay = 0.01 assert (self.r.scope.times[0] == 0), self.r.scope.times[0] self.r.scope.trigger_source = "asg1" self.r.scope.duration = 0.001 self.r.scope.trigger_delay = 0.01 assert (self.r.scope.times[self.r.scope.data_length // 2] == 0.01)
[docs] def test_scope_duration_autosetting(self): # tests if trigger delay doesnt change when duration is altered if self.r is None: return self.r.scope.setup(duration=0.001, trigger_source='asg1', trigger_delay=0.1) centertime = self.r.scope.times[self.r.scope.data_length // 2] # actual value of centertime is rather 0.099999744 assert abs(centertime - 0.1) < 1e-5, centertime self.r.scope.setup(duration=0.1, trigger_source='asg1', trigger_delay=0.1) centertime = self.r.scope.times[self.r.scope.data_length // 2] assert abs(centertime - 0.1) < 1e-5, centertime self.r.scope.setup(duration=0.001, trigger_source='asg1', trigger_delay=0.1) centertime = self.r.scope.times[self.r.scope.data_length // 2] assert abs(centertime - 0.1) < 1e-5, centertime