Пример #1
0
def test_write_readline_fail(unused_tcp_port):
    sock = TCP('0', unused_tcp_port)
    assert not sock.connected
    assert sock.connection_counter == 0

    with pytest.raises(ConnectionRefusedError):
        sock.write_readline(IDN_REQ)
    assert not sock.connected
    assert sock.connection_counter == 0
Пример #2
0
def test_open_fail(unused_tcp_port):
    sock = TCP('0', unused_tcp_port)
    assert not sock.connected
    assert sock.connection_counter == 0

    with pytest.raises(ConnectionRefusedError):
        sock.open()
    assert not sock.connected
    assert sock.connection_counter == 0
Пример #3
0
    def __init__(self, inst, props, *args, **kwargs):
        """Class initialization."""
        CounterTimerController.__init__(self, inst, props, *args, **kwargs)
        self._log.debug("__init__(%s, %s): Entering...", repr(inst),
                        repr(props))

        try:
            self.pandabox = PandA(self.PandaboxHost)
            self.pandabox.connect_to_panda()
        except (NameError, socket.gaierror):
            raise Exception('Unable to connect to PandABox.')

        # make sure PCAP block is reset
        self.pandabox.query('PCAP.ENABLE=ZERO')
        self.pandabox.query('*PCAP.DISARM=')

        try:
            self.data_socket = TCP(self.PandaboxHost, 8889, timeout=3)
            self.data_socket.open()
        except:
            raise Exception('Unable to open PandABox data stream.')

        # check if data stream starts correctly
        ack = self.data_socket.write_readline('\n')
        if "OK" not in ack:
            raise Exception('Acknowledge to data stream failed!')
        print "PandaboxCoTiCtrl: data stream listener starts...", ack
        self.data_buffer = ""
        self.header_okay_flag = False
        self.data_end_flag = False

        self.attributes = {}
        self.hw_trigger_cfg = {}
        self.hw_trigger_cfg['enable'] = self.PcapEnable
        self.hw_trigger_cfg['gate'] = self.PcapGate
        self.hw_trigger_cfg['trig'] = self.PcapTrig

        self.channels_order = []

        # channels and modes available
        self._modes = ['Value', 'Diff', 'Min', 'Max', 'Sum', 'Mean']
        self._channels = [
            'INENC1.VAL', 'INENC2.VAL', 'INENC3.VAL', 'INENC4.VAL',
            'CALC1.OUT', 'CALC2.OUT', 'COUNTER1.OUT', 'COUNTER2.OUT',
            'COUNTER3.OUT', 'COUNTER4.OUT', 'COUNTER5.OUT', 'COUNTER6.OUT',
            'COUNTER7.OUT', 'COUNTER8.OUT', 'FILTER1.OUT', 'FILTER2.OUT',
            'PGEN1.OUT', 'PGEN2.OUT', 'QDEC.OUT', 'FMC_IN.VAL1', 'FMC_IN.VAL2',
            'FMC_IN.VAL3', 'FMC_IN.VAL4', 'FMC_IN.VAL5', 'FMC_IN.VAL6',
            'FMC_IN.VAL7', 'FMC_IN.VAL8', 'PCAP.SAMPLES'
        ]

        self.index = 0
        self._repetitions = 0
Пример #4
0
def test_socket_creation():
    sock = TCP("example.com", 34567)
    assert sock.host == "example.com"
    assert sock.port == 34567
    assert not sock.connected()
    assert sock.connection_counter == 0
Пример #5
0
class PandaboxCoTiCtrl(CounterTimerController):

    MaxDevice = 28  # TODO remove this or check pandabox maximum number of channels

    ctrl_properties = {
        'PandaboxHost': {
            'Description': 'Pandabox Host name',
            'Type': 'PyTango.DevString'
        },
        'PcapEnable': {
            'Description': 'Hardware trigger config: PCAP.ENABLE',
            'Type': 'PyTango.DevString'
        },
        'PcapGate': {
            'Description': 'Hardware trigger config: PCAP.GATE',
            'Type': 'PyTango.DevString'
        },
        'PcapTrig': {
            'Description': 'Hardware trigger config: PCAP.TRIG',
            'Type': 'PyTango.DevString'
        },
    }

    ctrl_attributes = {}

    axis_attributes = {
        "ChannelName": {
            Type: str,
            Description: 'Channel name from pandabox',
            Memorize: Memorized,
            Access: DataAccess.ReadWrite,
        },
        "AcquisitionMode": {
            Type: str,
            Description: 'Acquisition mode: value, mean, min, max,...',
            Memorize: Memorized,
            DefaultValue: 'Value',
            Access: DataAccess.ReadWrite,
        },
    }

    def __init__(self, inst, props, *args, **kwargs):
        """Class initialization."""
        CounterTimerController.__init__(self, inst, props, *args, **kwargs)
        self._log.debug("__init__(%s, %s): Entering...", repr(inst),
                        repr(props))

        try:
            self.pandabox = PandA(self.PandaboxHost)
            self.pandabox.connect_to_panda()
        except (NameError, socket.gaierror):
            raise Exception('Unable to connect to PandABox.')

        # make sure PCAP block is reset
        self.pandabox.query('PCAP.ENABLE=ZERO')
        self.pandabox.query('*PCAP.DISARM=')

        try:
            self.data_socket = TCP(self.PandaboxHost, 8889, timeout=3)
            self.data_socket.open()
        except:
            raise Exception('Unable to open PandABox data stream.')

        # check if data stream starts correctly
        ack = self.data_socket.write_readline('\n')
        if "OK" not in ack:
            raise Exception('Acknowledge to data stream failed!')
        print "PandaboxCoTiCtrl: data stream listener starts...", ack
        self.data_buffer = ""
        self.header_okay_flag = False
        self.data_end_flag = False

        self.attributes = {}
        self.hw_trigger_cfg = {}
        self.hw_trigger_cfg['enable'] = self.PcapEnable
        self.hw_trigger_cfg['gate'] = self.PcapGate
        self.hw_trigger_cfg['trig'] = self.PcapTrig

        self.channels_order = []

        # channels and modes available
        self._modes = ['Value', 'Diff', 'Min', 'Max', 'Sum', 'Mean']
        self._channels = [
            'INENC1.VAL', 'INENC2.VAL', 'INENC3.VAL', 'INENC4.VAL',
            'CALC1.OUT', 'CALC2.OUT', 'COUNTER1.OUT', 'COUNTER2.OUT',
            'COUNTER3.OUT', 'COUNTER4.OUT', 'COUNTER5.OUT', 'COUNTER6.OUT',
            'COUNTER7.OUT', 'COUNTER8.OUT', 'FILTER1.OUT', 'FILTER2.OUT',
            'PGEN1.OUT', 'PGEN2.OUT', 'QDEC.OUT', 'FMC_IN.VAL1', 'FMC_IN.VAL2',
            'FMC_IN.VAL3', 'FMC_IN.VAL4', 'FMC_IN.VAL5', 'FMC_IN.VAL6',
            'FMC_IN.VAL7', 'FMC_IN.VAL8', 'PCAP.SAMPLES'
        ]

        self.index = 0
        self._repetitions = 0

    def AddDevice(self, axis):
        """Add device to controller."""
        self._log.debug("AddDevice(%d): Entering...", axis)
        self.attributes[axis - 1] = {
            'ChannelName': None,
            'AcquisitionMode': 'Value'
        }
        # count buffer for the continuous scan
        if axis != 1:
            self.index = 0

    def DeleteDevice(self, axis):
        """Delete device from the controller."""
        self._log.debug("DeleteDevice(%d): Entering...", axis)
        self.data_socket.close()
        self.pandabox.disconnect_from_panda()

    def StateAll(self):
        """Read state of all axis."""
        # self._log.debug("StateAll(): Entering...")
        state = self.pandabox.query('*PCAP.STATUS?')

        if "Busy" in state:
            self.state = State.Moving
        elif "Idle" in state:
            self.state = State.On
        elif "OK" not in state:
            self.state = State.Fault
        else:
            self.state = State.Fault
            self._log.debug(
                "StateAll(): %r %r UNKNWON STATE: %s" %
                (self.state, self.status), state)
        self.status = state
        # self._log.debug("StateAll(): %r %r" %(self.state, self.status))

    def StateOne(self, axis):
        """Read state of one axis."""
        # self._log.debug("StateOne(%d): Entering...", axis)
        return self.state, self.status

    def LoadOne(self, axis, value, repetitions):
        # self._log.debug("LoadOne(%d, %f, %d): Entering...", axis, value,
        #                 repetitions)
        if axis != 1:
            raise Exception('The master channel should be the axis 1')

        self.itime = value
        self.index = 0

        # Set Integration time in s per point
        self.pandabox.query('PULSE1.WIDTH.UNITS=s')
        if value < 8e-08:  # minimum reliable integration time is
            # 10 FPGA clock ticks 125 MHz -> 80 ns
            self._log.debug("The minimum integration time is 80 ns")
            value = 8e-08
        self.pandabox.query('PULSE1.WIDTH=%.9f' % (value))

        # Set falling edge capture to have
        # "gate signal that marks the capture boundaries"
        # in order to respect the integration time
        # see PCAP block documentation
        self.pandabox.query('PCAP.TRIG_EDGE=Falling')

        if self._synchronization in [
                AcqSynch.SoftwareTrigger, AcqSynch.SoftwareGate
        ]:
            # self._log.debug("SetCtrlPar(): setting synchronization "
            #                 "to SoftwareTrigger")
            self._repetitions = 1
            self.pandabox.query('PULSE1.PULSES=1')

            # link blocks for software acquisition
            trig = 'PULSE1.OUT'
        else:
            # self._log.debug("SetCtrlPar(): setting synchronization "
            #                 "to HardwareTrigger")
            self._repetitions = repetitions
            # link blocks for hardware acquisition
            trig = self.hw_trigger_cfg['trig']

        # create links to PCAP block
        # TODO: separate gated mode?
        #self.pandabox.query('PCAP.GATE=ONE')
        self.pandabox.query('PCAP.GATE=' + trig)
        self.pandabox.query('PCAP.TRIG=' + trig)

        # reset data buffer and header flag
        self.header_okay_flag = False
        self.data_end_flag = False
        self.data_buffer = ''

    def PreStartOneCT(self, axis):
        # self._log.debug("PreStartOneCT(%d): Entering...", axis)
        if axis != 1:
            self.index = 0
        return True

    def StartAllCT(self):
        """
        Starting the acquisition is done only if before was called
        PreStartOneCT for master channel.
        """
        # self._log.debug("StartAllCT(): Entering...")
        ret = self.pandabox.query('*PCAP.ARM=')
        if "OK" not in ret:
            print "Pandabox arm PCAP failed. Disarm and arm again..."
            ret = self.pandabox.query('*PCAP.DISARM=')
            ret = self.pandabox.query('*PCAP.ARM=')

        # start acquisition by enabling PCAP
        self.pandabox.query('PCAP.ENABLE=ONE')

        # trig acquisition
        if self._synchronization in [
                AcqSynch.SoftwareTrigger, AcqSynch.SoftwareGate
        ]:
            self.pandabox.query(
                'PULSE1.ENABLE=ONE')  # make sure block is enabled
            self.pandabox.query('PULSE1.TRIG=ZERO')
            self.pandabox.query('PULSE1.TRIG=ONE')
        # else wait for triggers (hardware mode)

        # THIS PROTECTION HAS TO BE REVIEWED
        # FAST INTEGRATION TIMES MAY RAISE WRONG EXCEPTIONS
        # e.g. 10ms ACQTIME -> self.state MAY BE NOT MOVING BECAUSE
        # FINISHED, NOT FAILED
        self.StateAll()
        t0 = time.time()
        while (self.state != State.Moving):
            if time.time() - t0 > 3:
                raise Exception('The HW did not start the acquisition')
            self.StateAll()
        return True

    def ReadAll(self):
        # self._log.debug("ReadAll(): Entering...")
        self.data_ready = int(self.pandabox.numquery('*PCAP.CAPTURED?'))
        #print "Points acquired: %d"%self.data_ready

        self.new_data = []
        #self.index = 0

        if self.data_ready == 0:
            print "Pandabox: No data available yet."
            self._ParseHeader()
            return
        elif self.data_ready <= self._repetitions:
            if self.data_ready == self._repetitions:
                print "Pandabox data acquisition has finished, disabling PCAP..."
                self.pandabox.query('PCAP.ENABLE=ZERO')  # it disarms PCAP too
            try:
                if not self.data_end_flag:
                    data = self.data_socket.readline()
                    if 'END' not in data:
                        self.data_buffer += data
                    else:
                        print "Pandabox data acquisition ENDs okay!"
                        self.data_end_flag = True
            except socket.error, e:
                print "Pandabox: data socket error: ", e
                self.data_socket.close()

            data_only = np.genfromtxt(StringIO(self.data_buffer),
                                      dtype='float64')

            # TODO: hw scan mode fails with int time < 100 ms
            # we have only one line per execution of this method, fix it
            if data_only.ndim > 1:  # crop to get only new data
                data_only = data_only[self.index:self.data_ready + 1]

            if self.index <= self.data_ready:  # mandatory to avoid extra lines
                self.new_data = np.ndarray.tolist(data_only.transpose())
                if type(self.new_data[0]) != list:
                    one_line_data = []
                    for value in self.new_data:
                        one_line_data.append([value])
                    self.new_data = one_line_data

                time_data = [self.itime] * len(self.new_data[0])
                self.new_data.insert(0, time_data)

                if self._repetitions != 1:
                    self.index += len(time_data)
Пример #6
0
def test_socket_creation():
    sock = TCP('example.com', 34567)
    assert sock.host == 'example.com'
    assert sock.port == 34567
    assert not sock.connected
    assert sock.connection_counter == 0