# -*- 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)