def test_add_component(): bob = DummyInstrument('bob', gates=['one']) station = Station() station.add_component(bob, 'bob') assert ['bob'] == list(station.components.keys()) assert bob == station.components['bob']
def test_add_component_without_specifying_name(): """ Test that station looks for 'name' attribute in the component and uses it """ bob = DummyInstrument('bob', gates=['one']) assert hasattr(bob, 'name') assert 'bob' == bob.name station = Station() station.add_component(bob) assert ['bob'] == list(station.components.keys()) assert bob == station.components['bob']
def test_remove_component(): bob = DummyInstrument('bob', gates=['one']) station = Station() station.add_component(bob, 'bob') assert ['bob'] == list(station.components.keys()) assert bob == station.components['bob'] bob2 = station.remove_component('bob') with pytest.raises(KeyError, match='bob'): _ = station.components['bob'] assert bob == bob2 with pytest.raises(KeyError, match='Component bobby is not part of the ' 'station'): _ = station.remove_component('bobby')
def test_add_component_with_no_name(): """ Test that station comes up with a name for components without 'name' attribute """ bob = {'name', 'bob'} station = Station() station.add_component(bob) assert ['component0'] == list(station.components.keys()) assert bob == station.components['component0'] jay = {'name', 'jay'} station.add_component(jay) assert ['component0', 'component1'] == list(station.components.keys()) assert jay == station.components['component1']
def test_loop_writing_2D(self): # pass station = Station() MockPar = MockParabola(name='Loop_writing_test_2D') station.add_component(MockPar) loop = Loop(MockPar.x[-100:100:20]).loop(MockPar.y[-50:50:10]).each( MockPar.skewed_parabola) data1 = loop.run(name='MockLoop_hdf5_test', formatter=self.formatter) data2 = DataSet(location=data1.location, formatter=self.formatter) data2.read() for key in data2.arrays.keys(): self.checkArraysEqual(data2.arrays[key], data1.arrays[key]) metadata_equal, err_msg = compare_dictionaries(data1.metadata, data2.metadata, 'original_metadata', 'loaded_metadata') self.assertTrue(metadata_equal, msg='\n' + err_msg) self.formatter.close_file(data1) self.formatter.close_file(data2)
def test_station_snapshot_during_measurement(experiment, dac, dmm, pass_station): station = Station() station.add_component(dac) station.add_component(dmm, 'renamed_dmm') snapshot_of_station = station.snapshot() if pass_station: measurement = Measurement(experiment, station) else: # in this branch of the `if` we expect that `Measurement` object # will be initialized with `Station.default` which is equal to the # station object that is instantiated above measurement = Measurement(experiment) measurement.register_parameter(dac.ch1) measurement.register_parameter(dmm.v1, setpoints=[dac.ch1]) with measurement.run() as data_saver: data_saver.add_result((dac.ch1, 7), (dmm.v1, 5)) # 1. Test `get_metadata('snapshot')` method json_snapshot_from_dataset = data_saver.dataset.get_metadata('snapshot') snapshot_from_dataset = json.loads(json_snapshot_from_dataset) expected_snapshot = {'station': snapshot_of_station} assert expected_snapshot == snapshot_from_dataset # 2. Test `snapshot_raw` property assert json_snapshot_from_dataset == data_saver.dataset.snapshot_raw # 3. Test `snapshot` property assert expected_snapshot == data_saver.dataset.snapshot
def test_snapshot(): station = Station() empty_snapshot = station.snapshot() assert { 'instruments': {}, 'parameters': {}, 'components': {}, 'config': None, } == empty_snapshot instrument = DummyInstrument('instrument', gates=['one']) station.add_component(instrument) instrument_snapshot = instrument.snapshot() parameter = Parameter('parameter', label='Label', unit='m') station.add_component(parameter) parameter_snapshot = parameter.snapshot() excluded_parameter = Parameter('excluded_parameter', snapshot_exclude=True) station.add_component(excluded_parameter) component = DumyPar('component') component.metadata['smth'] = 'in the way she moves' station.add_component(component) component_snapshot = component.snapshot() snapshot = station.snapshot() assert isinstance(snapshot, dict) assert [ 'instruments', 'parameters', 'components', 'config', ] == list(snapshot.keys()) assert ['instrument'] == list(snapshot['instruments'].keys()) assert instrument_snapshot == snapshot['instruments']['instrument'] # the list should not contain the excluded parameter assert ['parameter'] == list(snapshot['parameters'].keys()) assert parameter_snapshot == snapshot['parameters']['parameter'] assert ['component'] == list(snapshot['components'].keys()) assert component_snapshot == snapshot['components']['component']
def test_snapshot(): station = Station() empty_snapshot = station.snapshot() assert {'instruments': {}, 'parameters': {}, 'components': {}, 'config': None, 'default_measurement': [] } == empty_snapshot instrument = DummyInstrument('instrument', gates=['one']) station.add_component(instrument) instrument_snapshot = instrument.snapshot() parameter = Parameter('parameter', label='Label', unit='m') station.add_component(parameter) parameter_snapshot = parameter.snapshot() component = DumyPar('component') component.metadata['smth'] = 'in the way she moves' station.add_component(component) component_snapshot = component.snapshot() snapshot = station.snapshot() assert isinstance(snapshot, dict) assert ['instruments', 'parameters', 'components', 'config', 'default_measurement' ] == list(snapshot.keys()) assert ['instrument'] == list(snapshot['instruments'].keys()) assert instrument_snapshot == snapshot['instruments']['instrument'] assert ['parameter'] == list(snapshot['parameters'].keys()) assert parameter_snapshot == snapshot['parameters']['parameter'] assert ['component'] == list(snapshot['components'].keys()) assert component_snapshot == snapshot['components']['component'] assert [] == snapshot['default_measurement']
class FPGA_ave(VisaInstrument): ''' This is the python driver for the FPGA averaging, it communicates with the FPGA to get an average of a pulse Usage: Initialize with <name> = instruments.create('name', 'FPGA_AVE', address='<COM PORT>') <COM PORT> = COM5 e.g. ''' def __init__(self, name, address, mirrorfactors=[1, 1], verbose=1, **kwargs): logging.debug(__name__ + ' : Initializing instrument') super().__init__(name, address, **kwargs) self.station = Station() self._address = address self._values = {} self.verbose = verbose self._total_cycle_num = 100 self._sampling_frequency = 1000e3 self.visa_handle.baud_rate = 57600 self.set_sampling_frequency(self._sampling_frequency) self.mirrorfactors = mirrorfactors # Add parameters #self.add_parameter('mode', # set_cmd=functools.partial(self.write_to_serial, 130)) #self.add_parameter('ch1_cycle_num', # get_cmd=functools.partial(self.ask_from_serial, 1)) #self.add_parameter('ch2_cycle_num', # get_cmd=functools.partial(self.ask_from_serial, 5)) #self.add_parameter('measurement_done', # get_cmd=self.get_measurement_done) #self.add_parameter('total_cycle_num', # get_cmd=self.get_total_cycle_num, # set_cmd=self.set_total_cycle_num) #self.add_parameter('ch1_datapoint_num', # get_cmd=self.get_ch1_datapoint_num) #self.add_parameter('ch2_datapoint_num', # get_cmd=self.get_ch2_datapoint_num) #self.add_parameter('data', # get_cmd=self.station.alazar.data.get()) #self.add_parameter('ch1=_data', # get_cmd=self.channel.data.get()) #self.add_parameter('sampling_frequency', # get_cmd=self.station.alazar.get_sample_rate, # set_cmd=self.station.alazar.set_sample_rate) v = self.visa_handle # make sure term characters are ignored logging.debug(__name__ + ' : set termchar settings') v.set_visa_attribute(visa.constants.VI_ATTR_TERMCHAR_EN, 0) v.set_visa_attribute(visa.constants.VI_ATTR_ASRL_END_IN, 0) logging.debug(__name__ + ' : completed initialization') def get_idn(self): logging.debug(__name__ + ' : FPGA_ave: get_idn') IDN = { 'vendor': None, 'model': 'FPGA', 'serial': None, 'firmware': None } return IDN def alazar_setup(self): alazar = ATSdriver.AlazarTech_ATS9360(name='Alazar') with alazar.syncing(): alazar.clock_source('INTERNAL_CLOCK') alazar.sample_rate(1_000_000_000) alazar.clock_edge('CLOCK_EDGE_RISING') alazar.decimation(1) alazar.coupling1('DC') alazar.coupling2('DC') alazar.channel_range1(.4) alazar.channel_range2(.4) alazar.impedance1(50) alazar.impedance2(50) alazar.trigger_operation('TRIG_ENGINE_OP_J') alazar.trigger_engine1('TRIG_ENGINE_J') alazar.trigger_source1('EXTERNAL') alazar.trigger_slope1('TRIG_SLOPE_POSITIVE') alazar.trigger_level1(160) alazar.trigger_engine2('TRIG_ENGINE_K') alazar.trigger_source2('DISABLE') alazar.trigger_slope2('TRIG_SLOPE_POSITIVE') alazar.trigger_level2(128) alazar.external_trigger_coupling('DC') alazar.external_trigger_range('ETR_2V5') alazar.trigger_delay(0) alazar.timeout_ticks(0) alazar.aux_io_mode( 'AUX_IN_AUXILIARY') # AUX_IN_TRIGGER_ENABLE for seq mode on alazar.aux_io_param('NONE') # TRIG_SLOPE_POSITIVE for seq mode on alazar.get_idn() self.station.add_component(alazar) def setup_controller(self): myctrl = ATSChannelController(name='myctrl', alazar_name='Alazar') self.station.add_component(myctrl) def set_int_delay(self, int_delay): self.station.myctrl.int_delay(int_delay) def set_int_time(self, int_time): self.station.myctrl.int_time(int_time) def setup_channel(self, channel, num_averages): self.station.myctrl.channels chan = AlazarChannel(self.station.myctrl, 'mychan', demod=False, integrate_samples=False) self.station.myctrl.channels.append(chan) chan.num_averages(num_averages) chan.alazar_channel(channel) chan.prepare_channel() self.channel = chan # def get_all(self): # for cnt in self.get_parameter_names(): # self.get(cnt) def serial(self, here): self.visa_handle.write_raw(here) def start(self): self.write_to_serial(129, 1) def write_to_serial(self, address, value): # register=chr(address) # first_byte=chr(value>>8) # last_byte=chr(value&255) self.visa_handle.write_raw(bytes([address])) self.visa_handle.write_raw(bytes([value >> 8])) self.visa_handle.write_raw(bytes([value & 255])) def ask_from_serial(self, address, register=255): self.visa_handle.write_raw(bytes([register])) self.visa_handle.write_raw(bytes([0])) self.visa_handle.write_raw(bytes([address])) readresult = self.read_raw_bytes(size=3) result = (int(readresult[1]) << 8) | int(readresult[2]) return result def ask_from_serial_signed(self, address, register=255): self.visa_handle.write_raw(chr(register)) self.visa_handle.write_raw(chr(0)) self.visa_handle.write_raw(chr(address)) readresult = self.read_raw_bytes(size=3) if int(readresult[0]) == address: unsigned = (int(readresult[1]) << 8) | int(readresult[2]) signed = unsigned - 256 if unsigned > 127 else unsigned return signed else: raise Exception('Wrong address returned') def read_raw_bytes(self, size=None): ''' Returns the values that are in the FPGA buffer. Replacement for read_raw in messagebased.py, also see: https://github.com/hgrecco/pyvisa/issues/93 https://github.com/hgrecco/pyvisa/issues/190 ''' size = self.visa_handle.chunk_size if size is None else size with self.visa_handle.ignore_warning( visa.constants.VI_SUCCESS_MAX_CNT): chunk, status = self.visa_handle.visalib.read( self.visa_handle.session, size) if not len(chunk) == size: raise Exception('Visa received incorrect number of bytes') return chunk def set_(self, value): ''' Set the number of traces over which pulse events will be counted ''' self.write_to_serial(129, value) def get_total_cycle_num(self): ''' Get the total number of cycles which are averaged in FPGA ''' return self._total_cycle_num def set_total_cycle_num(self, value): ''' Set the total number of cycles which are averaged in FPGA ''' self._total_cycle_num = value self.write_to_serial(131, value) def get_ch1_datapoint_num(self): ''' Get the total number of cycles which are averaged in FPGA ''' return self.ask_from_serial(3) - 1 def get_ch2_datapoint_num(self): ''' Get the total number of cycles which are averaged in FPGA ''' return self.ask_from_serial(7) - 1 def get_measurement_done(self, ch=[1, 2]): ''' Returns one if the measurement is done, else returns zero ''' meas_done = True for ch_name in ch: meas_tmp = self.get('ch%i_cycle_num' % ch_name) meas_done = meas_done and (meas_tmp == self._total_cycle_num) return meas_done def get_data(self, address=2): ''' Read data ch1, unsigned ''' if not self.get_measurement_done(): return False self.visa_handle.write_raw(chr(255)) self.visa_handle.write_raw(chr(0)) self.visa_handle.write_raw(chr(address)) result = [] for x in range(0, 1000, 1): readresult = self.read_raw_bytes(size=3) result.append((int(readresult[1]) << 8) | int(readresult[2])) self._data = result return result def get_ch1_data(self, address=2, checkdone=True, buf=True): ''' Reads signed data out of the FPGA ''' Npoint = self.get_ch1_datapoint_num() if checkdone: if not self.get_measurement_done(ch=[1]): return False self.visa_handle.write_raw(bytes([255])) self.visa_handle.write_raw(bytes([0])) self.visa_handle.write_raw(bytes([address])) signed = [] if Npoint == 0: raise ValueError( 'There is no fpga output, the number of data points recorded for ch1 is 0 ' ) if buf: readresultbuf = self.read_raw_bytes(3 * Npoint) if len(readresultbuf) != 3 * Npoint: print('Npoint %d' % Npoint) raise Exception('get_ch1_data: error reading data') for x in range(0, Npoint, 1): readresult = readresultbuf[3 * x:3 * (x + 1)] unsigned = (int(readresult[0]) << 16) | ( int(readresult[1]) << 8) | int(readresult[2]) signed_temp = unsigned - 16777215 if unsigned > 8388607 else unsigned if x < Npoint: signed.append(signed_temp) else: for x in range(0, Npoint, 1): readresult = self.read_raw_bytes(size=3) unsigned = (int(readresult[0]) << 16) | ( int(readresult[1]) << 8) | int(readresult[2]) signed_temp = unsigned - 16777215 if unsigned > 8388607 else unsigned if x < Npoint: signed.append(signed_temp) self._data_signed = signed self.visa_handle.flush(16) signed = [x * self.mirrorfactors[0] for x in signed] return signed def get_ch2_data(self, address=6, checkdone=True): ''' Reads signed data out of the FPGA ''' Npoint = self.get_ch2_datapoint_num() if checkdone: if not self.get_measurement_done(ch=[2]): return False self.visa_handle.write_raw(bytes([255])) self.visa_handle.write_raw(bytes([0])) self.visa_handle.write_raw(bytes([address])) signed = [] if Npoint == 0: raise ValueError( 'There is no fpga output, the number of data points recorded for ch2 is 0 ' ) readresultbuf = self.read_raw_bytes(3 * Npoint) for x in range(0, Npoint, 1): readresult = readresultbuf[3 * x:3 * (x + 1)] unsigned = (int(readresult[0]) << 16) | ( int(readresult[1]) << 8) | int(readresult[2]) signed_temp = unsigned - 16777215 if unsigned > 8388607 else unsigned if x < Npoint: signed.append(signed_temp) self._data_signed = signed self.visa_handle.flush(16) signed = [x * self.mirrorfactors[1] for x in signed] return signed def set_sampling_frequency(self, value): ''' Set the total number of cycles which are averaged in FPGA, maximum samp freq=1 MHz and minimum is freq=763. ''' if value > 1e6: raise ValueError( 'The sampling frequency can not be set higher than 1 MHz.') internal_clock = 50e6 Ndivision = round(internal_clock * 1.0 / value) fs = internal_clock / Ndivision self._sampling_frequency = fs if self.verbose: print( 'FPGA internal clock is 50MHz, dividing it by %d, yields samp. freq. is %d Hz' % (Ndivision, self._sampling_frequency)) return self.write_to_serial(132, int(Ndivision)) def get_sampling_frequency(self): ''' Get the total number of cycles which are averaged in FPGA ''' return self._sampling_frequency def get_sampling_frequency_ratio(self): ''' Get the total number of cycles which are averaged in FPGA ''' return self.ask_from_serial(132) def readFPGA(self, FPGA_mode=0, ReadDevice=['FPGA_ch1', 'FPGA_ch2'], Naverage=1, verbose=1, waittime=0): ''' Basic function to read the data from the FPGA memory. ''' t0 = time.clock() #self.set('mode', FPGA_mode) #self.set('total_cycle_num', Naverage) #self.start() if verbose >= 2: print(' readFPGA: dt %.3f [ms], after start' % (1e3 * (time.clock() - t0))) time.sleep(waittime) if verbose >= 2: print(' readFPGA: dt %.3f [ms], after wait' % (1e3 * (time.clock() - t0))) #cc = [] #if 'FPGA_ch1' in ReadDevice: # cc += [1] #if 'FPGA_ch2' in ReadDevice: # cc += [2] #for c in cc: # loop = 0 # while not self.get_measurement_done(ch=[c]): # if verbose >= 2: # print('readFPGA: waiting for FPGA for 7.5 ms longer time (channel %d)' % c) # time.sleep(0.0075) # loop = loop + 1 # if loop * .0075 > 1: # pass # raise Exception('readFPGA: error') #if verbose >= 2: # print(' readFPGA: dt %.3f [ms], after dynamic wait' % (1e3 * (time.clock() - t0))) DataRead_ch1 = [] if 'FPGA_ch1' in ReadDevice: DataRead_ch1 = self.channel.data.get() DataRead_ch2 = [] if 'FPGA_ch2' in ReadDevice: DataRead_ch2 = self.get_ch2_data(checkdone=False) if verbose >= 2: print(' readFPGA: dt %.3f [ms]' % (1e3 * (time.clock() - t0))) if verbose >= 2: print(' readFPGA: DataRead_ch1 %d, DataRead_ch2 %d' % (len(DataRead_ch1), len(DataRead_ch2))) totalpoints = max(len(DataRead_ch1), len(DataRead_ch2)) return totalpoints, DataRead_ch1, DataRead_ch2