Beispiel #1
0
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']
Beispiel #2
0
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']
Beispiel #3
0
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')
Beispiel #4
0
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']
Beispiel #5
0
    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)
Beispiel #6
0
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
Beispiel #7
0
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']
Beispiel #8
0
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']
Beispiel #9
0
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