from Instruments.devGlobalFunctions import devGlobal
import numpy as np
import struct
import wx
import math

import pyte16 as pyte

from wx.lib.pubsub import pub

#Simple panel
class graphPanel(wx.Panel):
    def __init__(self, parent, device):
        wx.Panel.__init__(self,parent)

        button_sizer = wx.BoxSizer(wx.VERTICAL)

        btnWidth  = 90
        btnHeight = 40
        blankBtnLabel = "&Blank"

        self.device = device

        #==============================================================================================================================================================
        # Buttons are created with labels, sizes, and positions. The names of the buttons are arbitrary but
        # it is a good practice to name them according to their function.
        ##Creating Buttons

        self.button = []
        rowSizer = wx.BoxSizer(wx.HORIZONTAL)
        rowCounter = 0
        buttonsInARow = 5
        buttonsInACol = 3
        for i in range(buttonsInARow*buttonsInACol):
            btnIndexCol = i%buttonsInARow + 1
            btnIndexRow = int(math.floor(i/buttonsInARow)) + 1
            self.button.append(wx.Button(self, label = blankBtnLabel + "\n(" + str(btnIndexRow) + "," + str(btnIndexCol) + ")", size = (btnWidth, btnHeight)))
            self.button[i].SetBackgroundColour("RED")
            rowSizer.Add(self.button[i], 0, wx.ALL, 1)

            if btnIndexCol == buttonsInARow:
                button_sizer.Add(wx.StaticLine(self), 0, wx.ALL, 1)
                button_sizer.Add(rowSizer,            0, wx.ALL, 0)
                rowSizer = wx.BoxSizer(wx.HORIZONTAL)

        self.SetSizerAndFit(button_sizer)

class SuperFastClass(devGlobal):
    # Human readable name for the gui, note: Needs to be unique
    name = "Super Fast"
    def __init__(self, *args):
        devGlobal.__init__(self, *args)

        self.devComm.write("*CLS; *RST")

        self.devComm.write(":INST:SEL 1")
        self.devComm.write(":OUTPut:STATe OFF")
        self.devComm.write(":INST:SEL 2")
        self.devComm.write(":OUTPut:STATe OFF")
        self.devComm.write(":INST:SEL 3")
        self.devComm.write(":OUTPut:STATe OFF")
        self.devComm.write(":INST:SEL 4")
        self.devComm.write(":OUTPut:STATe OFF")
        self.devComm.write(":INST:SEL 1")

        self.ch1OnOff = 0
        self.ch2OnOff = 0
        self.ch3OnOff = 0
        self.ch4OnOff = 0

        self.numTabs = 2

        self.additionalPanels  = [(graphPanel, 'Graph Tab')]

        self.label_list = self.label_list + [
                           ('Gets Model\nOption',             self.GetModelOption,        ""),
                           ('Segment\nLength',                self.SegmentLength,         ""),
                           ('Tests',                          self.Tests,                 ""),
                           ('Sets Operating\nChannel',        self.SetOperatingChannel,   ""),
                           ('Standard\nSquare Wave',          self.SetStandardSquareWave, ""),
                           ('Sets Operating\nChannel On/Off', self.OutputOnOff,           ""),
                           ('Deletes\nAll Traces',            self.DeleteAllTraces,       ""),
                           ('Queries\nTrace Points',          self.TracePoints,           ""),
                           ('Ch1 Output\nOn/Off',             self.Ch1OnOff,              ""),  # 1
                           ('Ch2 Output\nOn/Off',             self.Ch2OnOff,              ""),  # 2
                           ('Sync\nCh1 and Ch2',              self.SyncChannels,          ""),  # 3
                           ('Ch1 Trigger\nInt/Ext',           self.Ch1TrigIntExt,         ""),  # 4
                           ('Ch2 Trigger\nInt/Ext',           self.Ch2TrigIntExt,         ""),  # 5
                           ('Ch1 Set\nWait Time',             self.Ch1setWaitTime,        ""),  # 6
                           ('Ch1 Set\nWait Time',             self.Ch1setWaitTime,        ""),  # 6
                           ('Ch1 Set\nWait Time',             self.Ch1setWaitTime,        ""),  # 6
                           ('Ch1 Set\nWait Time',             self.Ch1setWaitTime,        "")   # 6
                           ]

        for label, function, *_ in self.label_list:
            pub.subscribe(function, self.createTopic(label))

    def GetModelOption(self, msg):
        cmdString   = "Queries memory option on "
        self.answer = str(int(self.devComm.query("*OPT?")[2:4])*1e6)
        self.printOut(cmdString)
        done = 0
        while done != 1:
            print(self.devComm.query("*OPC?"))
            done = int(self.devComm.query("*OPC?"))

    def SegmentLength(self, msg):
        cmdString   = "Gets Segment Length on "
        self.answer = self.devComm.query(":TRACE:DEFine?")
        self.printOut(cmdString)

    def Tests(self, msg):
        cmdString = "Arbitrary waveform tests on "

        cycle_len = 1024
        num_cycles = 1
        seg_len = cycle_len * num_cycles

        wave1 = self.build_sine_wave(cycle_len,num_cycles, low_level=4000,
                          high_level=2 ** 14 - 4000)

        wave2 = self.build_square_wave(cycle_len, num_cycles)

        self.devComm.write(":INST:SEL 1")
        self.devComm.write(":TRAC:MODE SING")

        seg_nb = 1
        self.devComm.write(':TRAC:DEF {0:d},{1:d}'.format(seg_nb, seg_len))
        self.devComm.write(':TRAC:SEL {0:d}'.format(seg_nb))
        self.send_binary_data(pref=':TRAC:DATA', bin_dat=wave1)

        seg_nb = 2
        self.devComm.write(':TRAC:DEF {0:d},{1:d}'.format(seg_nb, seg_len))
        self.devComm.write(':TRAC:SEL {0:d}'.format(seg_nb))
        self.send_binary_data(pref=':TRAC:DATA', bin_dat=wave2)

        seg_num = [2, 1, 2, 1]
        repeats = [1, 5, 1, 4]
        jump    = [0, 0, 0, 0]
        seq_table = list(zip(repeats, seg_num, jump))

        self.devComm.write(':SEQ:SELect 1')
        self.download_sequencer_table(seq_table)

        self.devComm.write(':SOURce:FUNCtion:MODE SEQ')
        self.devComm.write(':SOUR:FREQ:RAST 1.0e9')

        self.printOut(cmdString)

        yNP = np.concatenate((wave1,wave2))

        pub.sendMessage('PrintData', msg=[self.panelId,yNP])

    def SetOperatingChannel(self, msg):
        param = self.GetParamVector()
        cmdString = "Sets the operating channel to " + param[0] + " on "
        visaCmd = ":INST:SEL " + param[0]
        self.devComm.write(visaCmd)
        self.printOut(cmdString)

    def SetStandardSquareWave(self, msg):
        param = self.GetParamVector()
        cmdString = "Sets a standard square wave with frequency " + param[2] + " on the operating channel on "
        self.devComm.write(':SOURce:FUNCtion:MODE FIX')
        self.devComm.write(":SOURce:FREQuency:CW " + param[2])
        self.devComm.write(":SOURce:FUNCtion:SHAPe SQU")
        self.devComm.write(":SOURce:SQUare:DCYC 50.0")
        self.printOut(cmdString)

    def OutputOnOff(self, msg):
        cmdString = "Sets active channel output to on/off on "

        if self.ch1OnOff == 0:
            self.ch1OnOff = 1
            self.devComm.write(":OUTPut:STATe ON")
        else:
            self.ch1OnOff = 0
            self.devComm.write(":OUTPut:STATe OFF")

        self.printOut(cmdString)

    def DeleteAllTraces(self, msg):
        cmdString = "Deletes all traces on "
        self.devComm.write(":TRACE:DELETE:ALL")
        self.printOut(cmdString)

    def TracePoints(self, msg):
        cmdString = "Queries trace points on "
        self.answer = self.devComm.query(":TRAC:POINts?")
        self.printOut(cmdString)

    def Ch1OnOff(self, msg):
        param = self.GetParamVector()
        cmdString = "Sets Ch1 Output to " + param[2] + " on "
        cmdString = cmdString + self.address + "\n"
        self.printOut(self.cmdString)

    def Ch2OnOff(self, msg):
        param = self.GetParamVector()
        cmdString = "Sets Ch2 Output to " + param[2] + " on "
        cmdString = cmdString + self.address + "\n"
        print(self.cmdString)

    def SyncChannels(self, msg):
        StringInit = "Sync Ch1 and Ch2 on "
        self.cmdString = StringInit + self.address
        print(self.cmdString)

    def Ch1TrigIntExt(self, msg):
        param = self.GetParamVector()
        cmdString = "Sets Ch1 Trigger to " + param[2] + " on "
        cmdString = cmdString + self.com_type + self.address + "\n"
        print(self.cmdString)

    def Ch2TrigIntExt(self, event):
        param = self.GetParamVector()
        StringInit = "Sets Ch2 Trigger to " + param[2] + " on "
        self.cmdString = StringInit + self.com_type + self.address
        print(self.cmdString)

    def Ch1setWaitTime(self, event):
        param = self.GetParamVector()
        StringInit = "Sets Ch1 Wait Time to " + param[2] + " on "
        self.cmdString = StringInit + self.com_type + self.address
        print(self.cmdString)

    def Ch2setWaitTime(self, event):
        param = self.GetParamVector()
        StringInit = "Sets Ch2 Wait Time to " + param[2] + " on "
        self.cmdString = StringInit + self.com_type + self.address
        print(self.cmdString)

    def Ch1Ena10MExtRef(self, event):
        StringInit = "Enable Ch1 10 MHz External Reference on "
        self.cmdString = StringInit + self.com_type + self.address
        print(self.cmdString)

    def Ch2Ena10MExtRef(self, event):
        StringInit = "Enable Ch2 10 MHz External Reference on "
        self.cmdString = StringInit + self.com_type + self.address
        print(self.cmdString)

    def build_sine_wave(self, cycle_len, num_cycles=1, phase_degree=0, low_level=0, high_level=2**14-1):
        cycle_len = int(cycle_len)
        num_cycles = int(num_cycles)

        if cycle_len <= 0 or num_cycles <= 0:
            return None

        dac_min = 0
        dac_max = 2**14-1

        wav_len = cycle_len * num_cycles

        phase = float(phase_degree) * np.pi / 180.0
        x = np.linspace(start=phase, stop=phase+2*np.pi, num=cycle_len, endpoint=False)

        zero_val = (low_level + high_level) / 2.0
        amplitude = (high_level - low_level) / 2.0
        y = np.sin(x) * amplitude + zero_val
        y = np.round(y)
        y = np.clip(y, dac_min, dac_max)

        y = y.astype(np.uint16)

        wav = np.empty(wav_len, dtype=np.uint16)
        for n in range(num_cycles):
            wav[n * cycle_len : (n + 1) * cycle_len] = y

        return wav

    def build_square_wave(self, cycle_len, num_cycles=1, duty_cycle=50.0, phase_degree=0, low_level=0,
                          high_level=2 ** 14 - 1):
        cycle_len = int(cycle_len)
        num_cycles = int(num_cycles)

        if cycle_len <= 0 or num_cycles <= 0:
            return None

        dac_min = 0
        dac_max = 2 ** 14 - 1

        wav_len = cycle_len * num_cycles

        duty_cycle = np.clip(duty_cycle, 0.0, 100.0)
        low_level = np.clip(low_level, dac_min, dac_max)
        high_level = np.clip(high_level, dac_min, dac_max)

        low_level = np.uint16(low_level)
        high_level = np.uint16(high_level)

        phase = float(phase_degree) * np.pi / 180.0
        x = np.linspace(start=phase, stop=phase + 2 * np.pi, num=cycle_len, endpoint=False)
        x = x <= 2 * np.pi * duty_cycle / 100.0
        y = np.full(x.shape, low_level, dtype=np.uint16)
        y[x] = high_level

        y = y.astype(np.uint16)

        wav = np.empty(wav_len, dtype=np.uint16)
        for n in range(num_cycles):
            wav[n * cycle_len: (n + 1) * cycle_len] = y

        return wav

    def download_sequencer_table(self, seq_table, pref=':SEQ:DATA'):
        tbl_len = len(seq_table)

        s = struct.Struct('< L H B x')
        s_size = s.size
        m = np.empty(s_size * tbl_len, dtype='uint8')
        for n in range(tbl_len):
            repeats, seg_nb, jump_flag = seq_table[n]
            s.pack_into(m, n * s_size, np.uint32(repeats), np.uint16(seg_nb), np.uint8(jump_flag))

        self.send_binary_data(pref, m)

    def send_binary_data(self, pref, bin_dat):
        pyte.download_binary_data(self.devComm, pref, bin_dat, bin_dat.nbytes)

# IMPORTANT Don't forget this line (and remember to use the class name above)
instrument = SuperFastClass


from Instruments.devGlobalFunctions import devGlobal
import numpy as np
import struct
import wx
import math

import pyte16 as pyte

from wx.lib.pubsub import pub

#Simple panel
class graphPanel(wx.Panel):
    def __init__(self, parent, device):
        wx.Panel.__init__(self,parent)

        button_sizer = wx.BoxSizer(wx.VERTICAL)

        btnWidth  = 90
        btnHeight = 40
        blankBtnLabel = "&Blank"

        self.device = device

        #==============================================================================================================================================================
        # Buttons are created with labels, sizes, and positions. The names of the buttons are arbitrary but
        # it is a good practice to name them according to their function.
        ##Creating Buttons

        self.button = []
        rowSizer = wx.BoxSizer(wx.HORIZONTAL)
        rowCounter = 0
        buttonsInARow = 5
        buttonsInACol = 3
        for i in range(buttonsInARow*buttonsInACol):
            btnIndexCol = i%buttonsInARow + 1
            btnIndexRow = int(math.floor(i/buttonsInARow)) + 1
            self.button.append(wx.Button(self, label = blankBtnLabel + "\n(" + str(btnIndexRow) + "," + str(btnIndexCol) + ")", size = (btnWidth, btnHeight)))
            self.button[i].SetBackgroundColour("RED")
            rowSizer.Add(self.button[i], 0, wx.ALL, 1)

            if btnIndexCol == buttonsInARow:
                button_sizer.Add(wx.StaticLine(self), 0, wx.ALL, 1)
                button_sizer.Add(rowSizer,            0, wx.ALL, 0)
                rowSizer = wx.BoxSizer(wx.HORIZONTAL)

        self.SetSizerAndFit(button_sizer)

class SuperFastClass(devGlobal):
    # Human readable name for the gui, note: Needs to be unique
    name = "Super Fast"
    def __init__(self, *args):
        devGlobal.__init__(self, *args)

        self.devComm.write("*CLS; *RST")

        self.devComm.write(":INST:SEL 1")
        self.devComm.write(":OUTPut:STATe OFF")
        self.devComm.write(":INST:SEL 2")
        self.devComm.write(":OUTPut:STATe OFF")
        self.devComm.write(":INST:SEL 3")
        self.devComm.write(":OUTPut:STATe OFF")
        self.devComm.write(":INST:SEL 4")
        self.devComm.write(":OUTPut:STATe OFF")
        self.devComm.write(":INST:SEL 1")

        self.ch1OnOff = 0
        self.ch2OnOff = 0
        self.ch3OnOff = 0
        self.ch4OnOff = 0

        self.numTabs = 2

        self.additionalPanels  = [(graphPanel, 'Graph Tab')]

        self.label_list = self.label_list + [
                           ('Gets Model\nOption',             self.GetModelOption,        ""),
                           ('Segment\nLength',                self.SegmentLength,         ""),
                           ('Tests',                          self.Tests,                 ""),
                           ('Sets Operating\nChannel',        self.SetOperatingChannel,   ""),
                           ('Standard\nSquare Wave',          self.SetStandardSquareWave, ""),
                           ('Sets Operating\nChannel On/Off', self.OutputOnOff,           ""),
                           ('Deletes\nAll Traces',            self.DeleteAllTraces,       ""),
                           ('Queries\nTrace Points',          self.TracePoints,           ""),
                           ('Ch1 Output\nOn/Off',             self.Ch1OnOff,              ""),  # 1
                           ('Ch2 Output\nOn/Off',             self.Ch2OnOff,              ""),  # 2
                           ('Sync\nCh1 and Ch2',              self.SyncChannels,          ""),  # 3
                           ('Ch1 Trigger\nInt/Ext',           self.Ch1TrigIntExt,         ""),  # 4
                           ('Ch2 Trigger\nInt/Ext',           self.Ch2TrigIntExt,         ""),  # 5
                           ('Ch1 Set\nWait Time',             self.Ch1setWaitTime,        ""),  # 6
                           ('Ch1 Set\nWait Time',             self.Ch1setWaitTime,        ""),  # 6
                           ('Ch1 Set\nWait Time',             self.Ch1setWaitTime,        ""),  # 6
                           ('Ch1 Set\nWait Time',             self.Ch1setWaitTime,        "")   # 6
                           ]

        for label, function, *_ in self.label_list:
            pub.subscribe(function, self.createTopic(label))

    def GetModelOption(self, msg):
        cmdString   = "Queries memory option on "
        self.answer = str(int(self.devComm.query("*OPT?")[2:4])*1e6)
        self.printOut(cmdString)
        done = 0
        while done != 1:
            print(self.devComm.query("*OPC?"))
            done = int(self.devComm.query("*OPC?"))

    def SegmentLength(self, msg):
        cmdString   = "Gets Segment Length on "
        self.answer = self.devComm.query(":TRACE:DEFine?")
        self.printOut(cmdString)

    def Tests(self, msg):
        cmdString = "Arbitrary waveform tests on "

        cycle_len = 1024
        num_cycles = 1
        seg_len = cycle_len * num_cycles

        wave1 = self.build_sine_wave(cycle_len,num_cycles, low_level=4000,
                          high_level=2 ** 14 - 4000)

        wave2 = self.build_square_wave(cycle_len, num_cycles)

        self.devComm.write(":INST:SEL 1")
        self.devComm.write(":TRAC:MODE SING")

        seg_nb = 1
        self.devComm.write(':TRAC:DEF {0:d},{1:d}'.format(seg_nb, seg_len))
        self.devComm.write(':TRAC:SEL {0:d}'.format(seg_nb))
        self.send_binary_data(pref=':TRAC:DATA', bin_dat=wave1)

        seg_nb = 2
        self.devComm.write(':TRAC:DEF {0:d},{1:d}'.format(seg_nb, seg_len))
        self.devComm.write(':TRAC:SEL {0:d}'.format(seg_nb))
        self.send_binary_data(pref=':TRAC:DATA', bin_dat=wave2)

        seg_num = [2, 1, 2, 1]
        repeats = [1, 5, 1, 4]
        jump    = [0, 0, 0, 0]
        seq_table = list(zip(repeats, seg_num, jump))

        self.devComm.write(':SEQ:SELect 1')
        self.download_sequencer_table(seq_table)

        self.devComm.write(':SOURce:FUNCtion:MODE SEQ')
        self.devComm.write(':SOUR:FREQ:RAST 1.0e9')

        self.printOut(cmdString)

        yNP = np.concatenate((wave1,wave2))

        pub.sendMessage('PrintData', msg=[self.panelId,yNP])

    def SetOperatingChannel(self, msg):
        param = self.GetParamVector()
        cmdString = "Sets the operating channel to " + param[0] + " on "
        visaCmd = ":INST:SEL " + param[0]
        self.devComm.write(visaCmd)
        self.printOut(cmdString)

    def SetStandardSquareWave(self, msg):
        param = self.GetParamVector()
        cmdString = "Sets a standard square wave with frequency " + param[2] + " on the operating channel on "
        self.devComm.write(':SOURce:FUNCtion:MODE FIX')
        self.devComm.write(":SOURce:FREQuency:CW " + param[2])
        self.devComm.write(":SOURce:FUNCtion:SHAPe SQU")
        self.devComm.write(":SOURce:SQUare:DCYC 50.0")
        self.printOut(cmdString)

    def OutputOnOff(self, msg):
        cmdString = "Sets active channel output to on/off on "

        if self.ch1OnOff == 0:
            self.ch1OnOff = 1
            self.devComm.write(":OUTPut:STATe ON")
        else:
            self.ch1OnOff = 0
            self.devComm.write(":OUTPut:STATe OFF")

        self.printOut(cmdString)

    def DeleteAllTraces(self, msg):
        cmdString = "Deletes all traces on "
        self.devComm.write(":TRACE:DELETE:ALL")
        self.printOut(cmdString)

    def TracePoints(self, msg):
        cmdString = "Queries trace points on "
        self.answer = self.devComm.query(":TRAC:POINts?")
        self.printOut(cmdString)

    def Ch1OnOff(self, msg):
        param = self.GetParamVector()
        cmdString = "Sets Ch1 Output to " + param[2] + " on "
        cmdString = cmdString + self.address + "\n"
        self.printOut(self.cmdString)

    def Ch2OnOff(self, msg):
        param = self.GetParamVector()
        cmdString = "Sets Ch2 Output to " + param[2] + " on "
        cmdString = cmdString + self.address + "\n"
        print(self.cmdString)

    def SyncChannels(self, msg):
        StringInit = "Sync Ch1 and Ch2 on "
        self.cmdString = StringInit + self.address
        print(self.cmdString)

    def Ch1TrigIntExt(self, msg):
        param = self.GetParamVector()
        cmdString = "Sets Ch1 Trigger to " + param[2] + " on "
        cmdString = cmdString + self.com_type + self.address + "\n"
        print(self.cmdString)

    def Ch2TrigIntExt(self, event):
        param = self.GetParamVector()
        StringInit = "Sets Ch2 Trigger to " + param[2] + " on "
        self.cmdString = StringInit + self.com_type + self.address
        print(self.cmdString)

    def Ch1setWaitTime(self, event):
        param = self.GetParamVector()
        StringInit = "Sets Ch1 Wait Time to " + param[2] + " on "
        self.cmdString = StringInit + self.com_type + self.address
        print(self.cmdString)

    def Ch2setWaitTime(self, event):
        param = self.GetParamVector()
        StringInit = "Sets Ch2 Wait Time to " + param[2] + " on "
        self.cmdString = StringInit + self.com_type + self.address
        print(self.cmdString)

    def Ch1Ena10MExtRef(self, event):
        StringInit = "Enable Ch1 10 MHz External Reference on "
        self.cmdString = StringInit + self.com_type + self.address
        print(self.cmdString)

    def Ch2Ena10MExtRef(self, event):
        StringInit = "Enable Ch2 10 MHz External Reference on "
        self.cmdString = StringInit + self.com_type + self.address
        print(self.cmdString)

    def build_sine_wave(self, cycle_len, num_cycles=1, phase_degree=0, low_level=0, high_level=2**14-1):
        cycle_len = int(cycle_len)
        num_cycles = int(num_cycles)

        if cycle_len <= 0 or num_cycles <= 0:
            return None

        dac_min = 0
        dac_max = 2**14-1

        wav_len = cycle_len * num_cycles

        phase = float(phase_degree) * np.pi / 180.0
        x = np.linspace(start=phase, stop=phase+2*np.pi, num=cycle_len, endpoint=False)

        zero_val = (low_level + high_level) / 2.0
        amplitude = (high_level - low_level) / 2.0
        y = np.sin(x) * amplitude + zero_val
        y = np.round(y)
        y = np.clip(y, dac_min, dac_max)

        y = y.astype(np.uint16)

        wav = np.empty(wav_len, dtype=np.uint16)
        for n in range(num_cycles):
            wav[n * cycle_len : (n + 1) * cycle_len] = y

        return wav

    def build_square_wave(self, cycle_len, num_cycles=1, duty_cycle=50.0, phase_degree=0, low_level=0,
                          high_level=2 ** 14 - 1):
        cycle_len = int(cycle_len)
        num_cycles = int(num_cycles)

        if cycle_len <= 0 or num_cycles <= 0:
            return None

        dac_min = 0
        dac_max = 2 ** 14 - 1

        wav_len = cycle_len * num_cycles

        duty_cycle = np.clip(duty_cycle, 0.0, 100.0)
        low_level = np.clip(low_level, dac_min, dac_max)
        high_level = np.clip(high_level, dac_min, dac_max)

        low_level = np.uint16(low_level)
        high_level = np.uint16(high_level)

        phase = float(phase_degree) * np.pi / 180.0
        x = np.linspace(start=phase, stop=phase + 2 * np.pi, num=cycle_len, endpoint=False)
        x = x <= 2 * np.pi * duty_cycle / 100.0
        y = np.full(x.shape, low_level, dtype=np.uint16)
        y[x] = high_level

        y = y.astype(np.uint16)

        wav = np.empty(wav_len, dtype=np.uint16)
        for n in range(num_cycles):
            wav[n * cycle_len: (n + 1) * cycle_len] = y

        return wav

    def download_sequencer_table(self, seq_table, pref=':SEQ:DATA'):
        tbl_len = len(seq_table)

        s = struct.Struct('< L H B x')
        s_size = s.size
        m = np.empty(s_size * tbl_len, dtype='uint8')
        for n in range(tbl_len):
            repeats, seg_nb, jump_flag = seq_table[n]
            s.pack_into(m, n * s_size, np.uint32(repeats), np.uint16(seg_nb), np.uint8(jump_flag))

        self.send_binary_data(pref, m)

    def send_binary_data(self, pref, bin_dat):
        pyte.download_binary_data(self.devComm, pref, bin_dat, bin_dat.nbytes)

# IMPORTANT Don't forget this line (and remember to use the class name above)
instrument = SuperFastClass


#Simple panel #============================================================================================================================================================== # Buttons are created with labels, sizes, and positions. The names of the buttons are arbitrary but # it is a good practice to name them according to their function. ##Creating Buttons # Human readable name for the gui, note: Needs to be unique # 1 # 2 # 3 # 4 # 5 # 6 # 6 # 6 # 6 # IMPORTANT Don't forget this line (and remember to use the class name above)