# -*- coding: utf-8 -*-
"""
Created on Tue Mar 12 11:28:20 2019

@author: sileme01
"""
import struct
from Tkinter import *
import ttk
from binascii import hexlify
from binascii import unhexlify
import scandir
import math
import time
import re
import numpy as np
import os
#from pathlib import Path #pathlib2 in python 2.7
import shutil
import subprocess
import asyncore, socket
import threading
from datetime import datetime as date 
cts = date.now()
dt_string = cts.strftime("%d_%m_%Y_%H_%M_%S")

import tkinter.font as font
import matplotlib
matplotlib.use("TkAgg")
matplotlib.rcParams['agg.path.chunksize'] = 10000
imagedpi = 70
#from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk) #try the line below if error occurs
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
print('matplotlib: {}'.format(matplotlib.__version__))
print('numpy: {}'.format(np.__version__))
from matplotlib import pyplot as plt
import scandir
import ctypes


from datetime import datetime
class MainClass:
   def __init__(self,master):
        self.master = master
#-----------------------------Ethernet Settings---------------------------------------------#
        self.TCP_IP = "192.168.101.253"
        self.TCP_PORT = 7001
        self.BUFFER_SIZE = 1024
        self.data                   = "XXXX"
        self.s                      = None
#-----------------------------Flags for internal checks-------------------------------------#
        self.sending                = False
        self.sendingInit            = True
        self.exitSignal             = False
        self.customFileFlag         = False
#---------------------------------------------------------------------------------#
        self.dstPathName  = "Measurements1" 
        self.dirIndex     = 1 
        self.workingDir   = os.getcwd()
        self.FileCheckRate          = float(0.05)
   def StartGui(self,master):
        self.e1 = Entry(master)
        self.e1.delete(0,END)
        self.e1.insert(0,"347")  
        self.e2 = Entry(master)
        self.e2.delete(0,END)
        self.e2.insert(0,"499")
        self.e3 = Entry(master)
        self.e3.delete(0,END)
        self.e3.insert(0,"76")
        self.e4 = Entry(master)
        self.e4.delete(0,END)
        self.e4.insert(0,"54")    
        self.e5 = Entry(master)
        self.e5.delete(0,END)
        self.e5.insert(0,"204")    
        self.e6 = Entry(master)
        self.e6.delete(0,END)
        self.e6.insert(0,"75")    
        self.e7 = Entry(master)
        self.e7.delete(0,END)
        self.e7.insert(0,"287")    
        self.e8 = Entry(master)
        self.e8.delete(0,END)
        self.e8.insert(0,"287")
        self.e9 = Entry(master)
        self.e9.delete(0,END)
        self.e9.insert(0,"1")
        self.e10 = Entry(master)
        self.e10.delete(0,END)
        self.e10.insert(0,"7001")

        def doExit():
            self.exitSignal = True
            time.sleep(0.5)
            master.quit()
            master.destroy()

        self.l = 0
        self.m = 0
        self.colormap = "jet" # coolwarm
        def arrangeData(arg0):
          while 1:
              isAmpFileExits = os.path.isfile(str(arg0))
              if(isAmpFileExits):
                  if(arg0 == "OP.dat"):
                      file_object  = open(arg0, "r")
                      data_op_field = file_object.readlines() #Open the file of the receiver.
                      x = 0 
                      SignalAvg  = np.array(np.zeros((5)))
                      for i in range(540,545):                #Get an average of a few data points. To be displayed in the GUI
                            raw = re.split("(\s+)",data_op_field[i])
                            SignalAvg[x] = raw[4]
                            x = x +1
                      self.mean_op1[self.l,self.m] = np.mean(SignalAvg)
                      file_object.close()
                      self.op_plt.imshow(self.mean_op1,self.colormap,vmin=0, vmax=np.amax(self.mean_cp2),origin='lower') #Display the data in the corresponding point
                      self.op_canvas.draw() #Update the GUI
                      shutil.move(arg0,self.workingDir+ "/" +self.dstPathName+"/"+str(self.dirIndex)) #we are done with the data. Move it to a corresponding directory
                      return "OK"
                  elif(arg0 == "CP.dat"):                   #Get an average of a few data points. To be displayed in the GUI
                      file_object  = open(arg0, "r")
                      data_cp_field = file_object.readlines()
                      SignalAvg  = np.array(np.zeros((5)))
                      x = 0
                      for i in range(540,545):
                            raw = re.split("(\s+)",data_cp_field[i])
                            SignalAvg[x] = raw[4]
                            x = x +1
                      self.mean_cp2[self.l,self.m] = np.mean(SignalAvg)

                      file_object.close()
                      self.cp_plt.imshow(self.mean_cp2,self.colormap,vmin=0, vmax=np.amax(self.mean_cp2),origin='lower') #Display the data in the corresponding point
                      self.cp_canvas.draw()
                      shutil.move(arg0,self.workingDir+ "/" +self.dstPathName+"/"+str(self.dirIndex)) #we are done with the data. Move it to a corresponding directory
                      return "OK"

                  elif(arg0 == "WC.dat"): #Repeat it for the worst case part
                      file_object  = open(arg0, "r")
                      data_wc_field = file_object.readlines()
                      SignalAvg  = np.array(np.zeros((5)))
                      x = 0
                      for i in range(540,545):
                            raw = re.split("(\s+)",data_wc_field[i])
                            SignalAvg[x] = raw[4]
                            x = x +1
                      self.mean_wc[self.l,self.m] = np.mean(SignalAvg)
                      file_object.close()
                      self.wc_plt.imshow(self.mean_wc,self.colormap,vmin=0, vmax=np.amax(self.mean_cp2),origin='lower')
                      self.wc_canvas.draw()
                      shutil.move(arg0,self.workingDir+ "/" +self.dstPathName+"/"+str(self.dirIndex))
                      shutil.move("wcvec.dat",self.workingDir+ "/" +self.dstPathName+"/"+str(self.dirIndex)) #save the worstcase vector file. We are done with the point
                      #This part is for the snake path. When one line finishes, it slides to the next location. 
                      if (self.m % 2 == 0):
                         self.l = self.l + 1
                         if self.l == self.a:
                            self.l = self.a-1
                            self.m = self.m + 1
                      else:
                        self.l = self.l -1
                        if(self.l== -1):
                            self.l = 0 
                            self.m = self.m +1
                            if self.m == self.b:
                                self.m=0
                      return "OK" 
                  elif(arg0 == "Dmatrix.dat"):
                      #goTMaTcalc()
                      shutil.move(arg0,self.workingDir+ "/" +self.dstPathName+"/"+str(self.dirIndex))
                      return "OK" 
                  time.sleep(self.FileCheckRate)
                  

        def sendCoordinates():
            print(self.currCoorIndex)
            if(int(coordinatesPassFileX[self.currCoorIndex]) != 999):
                rawCoX = [int(d) for d in str(int(coordinatesPassFileX[self.currCoorIndex]))]
                rawCoY = [int(d) for d in str(int(coordinatesPassFileY[self.currCoorIndex]))]
                rawCoZ = [int(d) for d in str(int(coordinatesPassFileZ[self.currCoorIndex]))]
                #Save coordinates
                file_object = open(workingDir+dt_string+'coordinatefile.dat', 'a')
                file_object.write("X"+str(int(coordinatesPassFileX[self.currCoorIndex]))+" Y"+  str(int(coordinatesPassFileY[self.currCoorIndex]))+ " Z"+  str(int(coordinatesPassFileZ[self.currCoorIndex])))
                file_object.close()
                if((coordinatesPassFileX[self.currCoorIndex]<100) and (coordinatesPassFileX[self.currCoorIndex] > 9)):
                    self.x1 = str(0)
                    self.x2 = str(rawCoX[0])
                    self.x3 = str(rawCoX[1])
                elif(coordinatesPassFileX[self.currCoorIndex]>99):
                    self.x3 = str(rawCoX[2])
                    self.x2 = str(rawCoX[1])
                    self.x1 = str(rawCoX[0])
                elif(coordinatesPassFileX[self.currCoorIndex]<10):
                    self.x1 = str(0)
                    self.x2 = str(0)
                    self.x3 = str(rawCoX[0])
                if((coordinatesPassFileY[self.currCoorIndex]<100) and (coordinatesPassFileY[self.currCoorIndex] > 9)):
                    self.y1 = str(0)
                    self.y2 = str(rawCoY[0])
                    self.y3 = str(rawCoY[1])
                elif(coordinatesPassFileY[self.currCoorIndex]>99):
                    self.y3 = str(rawCoY[2])
                    self.y2 = str(rawCoY[1])
                    self.y1 = str(rawCoY[0])
                elif(coordinatesPassFileY[self.currCoorIndex]<10):
                    self.y2 = str(0)
                    self.y1 = str(0)
                    self.y3 = str(rawCoY[0])
                if((coordinatesPassFileZ[self.currCoorIndex]<100) and (coordinatesPassFileZ[self.currCoorIndex] > 9)):
                    self.z1 = str(0)
                    self.z2 = str(rawCoZ[0])
                    self.z3 = str(rawCoZ[1])
                elif(coordinatesPassFileZ[self.currCoorIndex]>99):
                    self.z3 = str(rawCoZ[2])
                    self.z2 = str(rawCoZ[1])
                    self.z1 = str(rawCoZ[0])
                elif(coordinatesPassFileZ[self.currCoorIndex]<10):
                    self.z2 = str(0)
                    self.z1 = str(0)
                    self.z3 = str(rawCoZ[0])
                print("Waiting for Cosi to complete operation")
                if(self.sendingInit == True):
                    self.s.send("MOV" + self.x1 + self.x2 + self.x3 + self.y1 + self.y2 + self.y3 + self.z1 + self.z2 + self.z3)
                    self.sendingInit = False
                    self.currCoorIndex = self.currCoorIndex + 1
                self.data = self.s.recv(self.BUFFER_SIZE)
                self.sending = False
                #startPath()
            else:
                print("Finished!")
                self.currCoorIndex = 0
        def pathFromFile():
            self.file_object  = open("PathFile.txt", "r")
            self.coordinatesPassFile  = self.file_object.readlines()
            global coordinatesPassFileX,coordinatesPassFileY,coordinatesPassFileZ
            coordinatesPassFileX = np.array(np.zeros(len(self.coordinatesPassFile)+1))
            coordinatesPassFileY = np.array(np.zeros(len(self.coordinatesPassFile)+1))
            coordinatesPassFileZ = np.array(np.zeros(len(self.coordinatesPassFile)+1))

            self.currCoorIndex          = 0
            self.dirIndex               = 1  
            for i in range(len(self.coordinatesPassFile)):
                raw = re.split("(\s+)",self.coordinatesPassFile[i])
                coordinatesPassFileZ[i] = raw[4]
                coordinatesPassFileY[i] = raw[2]
                coordinatesPassFileX[i] = raw[0]
            coordinatesPassFileZ[-1] = "999"
            coordinatesPassFileY[-1] = "999"
            coordinatesPassFileX[-1] = "999"
            self.cp_mat =  np.zeros((len(xCorr), len(yCorr)),dtype = float)
            self.op_mat =  np.zeros((len(xCorr), len(yCorr)),dtype = float)
            self.wc_mat =  np.zeros((len(xCorr), len(yCorr)),dtype = float)
            
            self.mean_cp2 =  np.zeros((len(xCorr), len(yCorr)),dtype = float)
            self.mean_op1 =  np.zeros((len(xCorr), len(yCorr)),dtype = float)
            self.mean_wc  =  np.zeros((len(xCorr), len(yCorr)),dtype = float)

            colormap = "jet" 
            self.wc_plt.imshow(self.wc_mat,colormap)
            self.op_plt.imshow(self.op_mat,colormap)
            self.cp_plt.imshow(self.cp_mat,colormap)
        def preparePath():
            xCorrStart  = int(self.e1.get())
            xCorrStop   = int(self.e2.get())
            xResolution = int(self.e3.get())
            yCorrStart  = int(self.e4.get())
            yCorrStop   = int(self.e5.get())
            yResolution = int(self.e6.get())
            zCorrStart  = int(self.e7.get())
            zCorrStop   = int(self.e8.get())
            zResolution = int(self.e9.get())
            xCorr = np.arange(xCorrStart,xCorrStop+1,xResolution)
            self.a = len(xCorr)
            yCorr = np.arange(yCorrStart,yCorrStop+1,yResolution)
            self.b = len(yCorr)
            zCorr = np.arange(zCorrStart,zCorrStop+1,zResolution)
            z = 0
            passListSize = len(xCorr)*len(yCorr)*len(zCorr)
            self.passList = ["" for x in range(passListSize)]
            offset = len(yCorr) - 1
            for k in range (len(zCorr)):
                for  i in range(len(yCorr)):
                  for  j in range(len(xCorr)):
                    if(i % 2 == 0):
                        self.passList[z] = (str(xCorr[j])+ " "+ str(yCorr[i])+ " " + str(zCorr[k])) # +"\n")
                    else:
                        self.passList[z] = (str(xCorr[len(xCorr)-1-j])+ " "+ str(yCorr[i])+ " " + str(zCorr[k])) #+"\n")
                    z = z + 1
            
            self.cp_mat =  np.zeros((len(xCorr), len(yCorr)),dtype = float)
            self.op_mat =  np.zeros((len(xCorr), len(yCorr)),dtype = float)
            self.wc_mat =  np.zeros((len(xCorr), len(yCorr)),dtype = float)
            
            self.mean_cp2 =  np.zeros((len(xCorr), len(yCorr)),dtype = float)
            self.mean_op1 =  np.zeros((len(xCorr), len(yCorr)),dtype = float)
            self.mean_wc  =  np.zeros((len(xCorr), len(yCorr)),dtype = float)

            colormap = "jet" # coolwarm
            self.wc_plt.imshow(self.wc_mat,colormap)
            self.op_plt.imshow(self.op_mat,colormap)
            self.cp_plt.imshow(self.cp_mat,colormap)
            self.coordinatesPassFile  = self.passList
            global coordinatesPassFileX,coordinatesPassFileY,coordinatesPassFileZ
            coordinatesPassFileX = np.array(np.zeros(len(self.coordinatesPassFile)+1))
            coordinatesPassFileY = np.array(np.zeros(len(self.coordinatesPassFile)+1))
            coordinatesPassFileZ = np.array(np.zeros(len(self.coordinatesPassFile)+1))
            self.currCoorIndex          = 0
            self.dirIndex               = 1  
            for i in range(len(self.coordinatesPassFile)):
                raw = re.split("(\s+)",self.coordinatesPassFile[i])
                coordinatesPassFileZ[i] = raw[4]
                coordinatesPassFileY[i] = raw[2]
                coordinatesPassFileX[i] = raw[0]
            coordinatesPassFileZ[-1] = "999"
            coordinatesPassFileY[-1] = "999"
            coordinatesPassFileX[-1] = "999"
        def printPath():
            for i in range (len(self.passList)):
                print(self.passList[i])
            ##TODO Write Path to a file

        def connectToCosi():
            self.TCP_PORT = 7001 
            self.s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            self.s.connect((self.TCP_IP, self.TCP_PORT))
        def SendOK():
           self.s.send("OK")
           self.data = self.s.recv(self.BUFFER_SIZE)
           print ("received data:"), self.data
        def CloseConn():
           self.s.send("CLOSECONN")
           self.data = self.s.recv(self.BUFFER_SIZE)
           print ("Response from the COSI:"), self.data
           self.s.close()
        def startPath():
            while self.sending == False:
                if ("MOVOK"== self.data) and (self.sendingInit == False):
                    self.sending = True
                    self.s.send("MOV" + self.x1 + self.x2 + self.x3 + self.y1 + self.y2 + self.y3 + self.z1 + self.z2 + self.z3)
                    self.currCoorIndex = self.currCoorIndex + 1
                    sendCoordinates()
                    break;
                elif("MOVOK"== self.data) and (self.sendingInit == True):
                    self.sending = True
                    #self.currCoorIndex = self.currCoorIndex + 1
                    sendCoordinates()
                    break;

 
        def DmatrixLoop():
            #Check and assure Ethernet Connection with COSI
            if self.s :
                print("Cosi seems to be connectted")
            else:
                connectToCosi()
            #Prepare Path File
            #Check the key. if the path is from a custom file the keys should match. Otherwise take them from the GUI
            #Key: 347 499 76 54 204 75 287 287 1
            if ((int(self.e1.get())== 347) and (int(self.e2.get())== 499) and (int(self.e3.get())== 76) and (int(self.e4.get())== 54) and (int(self.e5.get())== 204) and (int(self.e6.get())== 75) and (int(self.e7.get())== 287) and (int(self.e8.get())== 287) and (int(self.e9.get())== 1)):
                customFileFlag = True
            else: 
                customFileFlag = False
            if(customFileFlag):
                pathFromFile()
            else:
                preparePath()
            self.currCoorIndex = 0
            
            SendOK() #Ping COSI
            print("Send OK OK")
            if ("MOVOK" == self.data): #wait for ACK
                #LoopStart
                print("Starting Mapping")
                for i in range (len(self.passList)):

                    #Save files to here
                    os.makedirs(self.workingDir+ "/" +self.dstPathName+"/"+str(self.dirIndex))

                    #MOV to Position
                    startPath()
                    time.sleep(1) # For safety, decrease vibration etc. This can be adjusted. This is an emprical setting.
                    
                    #Send the composite pulse and obtain 'wcvec.dat'
                    subprocess.Popen('./rec_m4i_tdfilter_2ch_tds 297233750. 297233750.',shell=True)
                    
                    time.sleep(2) #Receiver needs some time to settle (2 second is for safety. It can run much faster. This part can be optimized)
                    
                    #Start transmitter
                    p = subprocess.Popen('./pex_m4i_CP 0 0.5',shell=True)
       
                    p.communicate() # Wait for transmitter from the system. This is more safer than an emprical timing
                    time.sleep(1.2) # The reveiver code may still need some time to complete file writing operation.
                    
                    #Start the receiver first
                    subprocess.Popen('./rec_m4i_tdfilter_2ch_tds 297233750. 297233750. > CP.dat',shell=True)
                    
                    time.sleep(2) #Receiver needs some time to settle (2 second is safer)
                    
                    #Start transmitter
                    p = subprocess.Popen('./pex_m4i_CP 1 0.5',shell=True)
       
                    p.communicate() # Wait for transmitter from the system. This is more safer than an emprical timing
                    time.sleep(1.2) # The reveiver code may still need some time to complete file writing operation.
                    arrangeData("CP.dat") #check the file and copy to a relevant place.
                    #Start the receiver first
                    subprocess.Popen('./rec_m4i_tdfilter_2ch_tds 297233750. 297233750. > OP.dat',shell=True)
                    
                    time.sleep(2) #Receiver needs some time to settle (2 second is safer)
                    
                    #Start transmitter
                    p = subprocess.Popen('./pex_m4i_OP 1 0.5',shell=True)
       
                    p.communicate() # Wait for transmitter from the system. This is more safer than an emprical timing
                    time.sleep(1.2) # The reveiver code may still need some time to complete file writing operation.
                    arrangeData("OP.dat") #check the file and copy to a relevant place.
                    #Start the receiver first
                    subprocess.Popen('./rec_m4i_tdfilter_2ch_tds 297233750. 297233750. > WC.dat',shell=True)
                    
                    time.sleep(2) #Receiver needs some time to settle (2 second is safer)
                    
                    #Start transmitter
                    p = subprocess.Popen('./pex_m4i_WC 1 0.5',shell=True)
       
                    p.communicate() # Wait for transmitter from the system. This is more safer than an emprical timing
                    time.sleep(1.2) # The reveiver code may still need some time to complete file writing operation.
                    arrangeData("WC.dat") #check the file and copy to a relevant place.
                    self.dirIndex = self.dirIndex + 1 
            CloseConn() #Finished the loop. Close the connection. 
        def DmatrixLoopTHR():
          self.thrGetSeqStats = threading.Thread(name='DThread',target=DmatrixLoop) #Set the thread. Threading is nesc. to see the GUI updates
          self.thrGetSeqStats.start() 
#-----------------------GUI Arrangement Data------------------------
        buttonRowValue = 17
        xTextColVal    = 0
        yTextColVal    = 3
        zTextColVal    = 6
        xtextRowValue  = 13
        ytextRowValue  = 13
        ztextRowValue  = 13
        xEntryRowValue = xtextRowValue
        yEntryRowValue = ytextRowValue
        zEntryRowValue = ztextRowValue
        xEntryColValue = xTextColVal + 1
        yEntryColValue = yTextColVal + 1
        zEntryColValue = zTextColVal + 1
#-----------------------End Gui arrangements--------------------------------#
        self.e1.grid(row=xEntryRowValue  , column=xEntryColValue)#,sticky=W)
        self.e2.grid(row=xEntryRowValue+1, column=xEntryColValue)#,sticky=W)
        self.e3.grid(row=xEntryRowValue+2, column=xEntryColValue)#,sticky=W)
        self.e4.grid(row=yEntryRowValue  , column=yEntryColValue,sticky=E)
        self.e5.grid(row=yEntryRowValue+1, column=yEntryColValue,sticky=E)
        self.e6.grid(row=yEntryRowValue+2, column=yEntryColValue,sticky=E)
        self.e7.grid(row=zEntryRowValue  , column=zEntryColValue)#,sticky=W)
        self.e8.grid(row=zEntryRowValue+1, column=zEntryColValue)#,sticky=W)
        self.e9.grid(row=zEntryRowValue+2, column=zEntryColValue)#,sticky=W)
        self.refRate = 10
        #Initialize the matrices and do a dummy fill.
        self.cp_mat  =  np.zeros((17, 17),dtype = float)
        self.op_mat  =  np.zeros((17, 17),dtype = float)
        self.wc_mat  =  np.zeros((17, 17),dtype = float)
        self.cp_mat.fill(0.5)
        self.op_mat.fill(0.5)
        self.wc_mat.fill(0.5)
        plt.rcParams.update({'font.size': 20})
        
        #Create the figures and their canvas
        #CP
        cp_fig = plt.figure(figsize=(6,6), dpi=imagedpi)
        self.cp_plt = cp_fig.add_subplot(111)
        plt.title("Circular Polarization")
        self.cp_plt.imshow(self.cp_mat,"coolwarm")
        self.cp_canvas = FigureCanvasTkAgg(cp_fig, master)
        self.cp_canvas.draw()
        self.cp_canvas.get_tk_widget().grid(row=0, column=0,columnspan=3, rowspan=12,sticky=W+E+N+S)

        #OP
        OP_fig = plt.figure(figsize=(6,6), dpi=imagedpi)
        self.op_plt = OP_fig.add_subplot(111)
        self.op_plt.imshow(self.op_mat,"coolwarm")
        plt.title("Orthogonal Projection")
        self.op_canvas = FigureCanvasTkAgg(OP_fig, master)
        self.op_canvas.draw()
        self.op_canvas.get_tk_widget().grid(row=0, column=3,columnspan=3, rowspan=12,sticky=W+E+N+S)
        
        #WC
        WC_fig = plt.figure(figsize=(6,6), dpi=imagedpi)
        self.wc_plt = WC_fig.add_subplot(111)
        self.wc_plt.imshow(self.wc_mat,"coolwarm")
        plt.title("Worst Case")
        self.wc_canvas = FigureCanvasTkAgg(WC_fig, master)
        self.wc_canvas.draw()
        self.wc_canvas.get_tk_widget().grid(row=0, column=6,columnspan=3, rowspan=12,sticky=W+E+N+S)
        
        #Some font settings for appearance
        CloseConnbuttonFont = font.Font(size=11, weight='bold') # Font Family family='Courier',
        exitbuttonFont      = font.Font(size=12, weight='bold') # Font Family family='Courier',
        mappingbuttonFont   = font.Font(size=12, weight='bold') # Font Family family='Courier',
        #Label settings for the path 
        Label(master, text  = "xCorrStart").grid          (row = xtextRowValue  , column=xTextColVal,sticky=W)
        Label(master, text  = "xCorrStop").grid           (row = xtextRowValue+1, column=xTextColVal,sticky=W)
        Label(master, text  = "xResolution").grid         (row = xtextRowValue+2, column=xTextColVal,sticky=W)
        Label(master, text  = "yCorrStart").grid          (row = ytextRowValue  , column=yTextColVal)
        Label(master, text  = "yCorrStop").grid           (row = ytextRowValue+1, column=yTextColVal)
        Label(master, text  = "yResolution").grid         (row = ytextRowValue+2, column=yTextColVal)
        Label(master, text  = "zCorrStart").grid          (row = ztextRowValue  , column=zTextColVal)
        Label(master, text  = "zCorrStop").grid           (row = ztextRowValue+1, column=zTextColVal)
        Label(master, text  = "zResolution").grid         (row = ztextRowValue+2, column=zTextColVal)
        ####Buttons####
        Button(master, text = "Close Connection"      ,  command=CloseConn      ,font=CloseConnbuttonFont, bg='#12FF00').grid(row                   =buttonRowValue, column = 4)
        Button(master, text = "Start Mapping"         ,  command=DmatrixLoopTHR ,font=mappingbuttonFont  , bg='#0052cc', fg='#ffffff').grid(row     =buttonRowValue, column = 7)
        Button(master, text = "Exit"                  ,  command=doExit         ,font=exitbuttonFont     , bg='#FF0000', fg='#ffffff').grid(row     =buttonRowValue, column = 0)
        #Seperators
        sep1= ttk.Separator(master                    ,  orient  =HORIZONTAL).grid(row        =ztextRowValue+3, column = 0, columnspan= 99        , sticky = "ewns")
        sepx= ttk.Separator(master                    ,  orient  =VERTICAL).grid(row          =ztextRowValue  , column = xTextColVal+2, rowspan= 3, sticky = "nse")
        sepy= ttk.Separator(master                    ,  orient  =VERTICAL).grid(row          =ztextRowValue  , column = yTextColVal+2, rowspan= 3, sticky = "nse")
        sepz= ttk.Separator(master                    ,  orient  =VERTICAL).grid(row          =ztextRowValue  , column = zTextColVal+2, rowspan= 3, sticky = "nse")
        mainloop()
master = Tk()
test = MainClass(master)
test.StartGui(master)