-
Notifications
You must be signed in to change notification settings - Fork 1
/
GUI.py
179 lines (153 loc) · 7.37 KB
/
GUI.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
import tkFileDialog
from Tkinter import *
import threading
import os
from Classifier import build_stacked_ae, build_binary_classifiers
class GUI(threading.Thread):
"""
This class implements the GUI windows of the program.
The GUI is implemented using the TKinter Python package.
"""
def __init__(self, master):
self.master = master
master.title("Classification of cell cycle phase of mESCs")
self.file_opt = {}
self.dataset_path1 = ""
self.dataset_path2 = ""
self.dataset_path3 = ""
self.path_label1 = Label(master, text="Path of mESC count (for G1, S, G2M):")
self.path_label2 = Label(master, text="Path of mESC count (for G1, S+G2/M):")
self.path_label3 = Label(master, text="Path of mESC count (for G1+S, G2M):")
dir_explain = "The dataset containing the labeled mouse embryonic stem cells."
self.text_dir_path1 = Text(master, width=50, height=1)
self.text_dir_path2 = Text(master, width=50, height=1)
self.text_dir_path3 = Text(master, width=50, height=1)
self.browse_button1 = Button(master, text="Browse", command=lambda: self.update("Browse1"),
height=1, width=10)
self.browse_button2 = Button(master, text="Browse", command=lambda: self.update("Browse2"),
height=1, width=10)
self.browse_button3 = Button(master, text="Browse", command=lambda: self.update("Browse3"),
height=1, width=10)
self.run_button = Button(master, text="Run", command=lambda: self.update("Run"),
height=1, width=10)
self.run_button.config(state=DISABLED)
self.entry_output = Text(master, height=20, width=102)
self.entry_output.config(state=NORMAL)
self.entry_output.pack()
# LAYOUT
master.minsize(width=850, height=650)
master.maxsize(width=850, height=650)
self.path_label1.grid(row=0, sticky=E)
self.path_label2.grid(row=1, sticky=E)
self.path_label3.grid(row=2, sticky=E)
self.text_dir_path1.grid(row=0, column=1, sticky=W, pady=10)
self.text_dir_path2.grid(row=1, column=1, sticky=W, pady=10)
self.text_dir_path3.grid(row=2, column=1, sticky=W, pady=10)
self.browse_button1.grid(row=0, column=2)
self.browse_button2.grid(row=1, column=2)
self.browse_button3.grid(row=2, column=2)
self.run_button.grid(row=5, column=1, rowspan=2)
self.entry_output.grid(row=8, sticky=W + E + N + S, column=0, rowspan=12, columnspan=12, padx=10, pady=10)
self.print_to_output("INSERT", dir_explain)
def validate_float(self, action, new_text):
"""
Validate float
:param action: 1 for an attempted deletion, 2 for an attempted insertion
:param new_text: The text to be validated as float
:return: True for valid, False for invalid.
"""
pattern = re.compile("^[0-9.]*$")
if action == '1':
if pattern.match(new_text):
try:
val = float(new_text)
self.run_button.config(state=NORMAL)
return True
except ValueError:
self.run_button.config(state=DISABLED)
return False
else:
return False
else:
self.run_button.config(state=NORMAL)
return True
def update(self, method):
"""
Initiates the command generated by pressing the Button object.
:param method: The intended action (Browse for file, Run the program)
"""
dataset_type = method[-1] # Browse which dataset
if method == "Run":
self.print_to_output("DELETE", "")
self.browse_button1.config(state=DISABLED)
self.browse_button2.config(state=DISABLED)
self.browse_button3.config(state=DISABLED)
self.run_button.config(state=DISABLED)
root.update()
th = threading.Thread(target=self.execute, args=())
th.start()
else:
if dataset_type == "1":
self.text_dir_path1.config(state=NORMAL)
self.text_dir_path1.delete(1.0, END)
self.dataset_path1 = self.askdirectory()
self.text_dir_path1.insert(END, self.dataset_path1)
self.text_dir_path1.config(state=DISABLED)
elif dataset_type == "2":
self.text_dir_path2.config(state=NORMAL)
self.text_dir_path2.delete(1.0, END)
self.dataset_path2 = self.askdirectory()
self.text_dir_path2.insert(END, self.dataset_path2)
self.text_dir_path2.config(state=DISABLED)
elif dataset_type == "3":
self.text_dir_path3.config(state=NORMAL)
self.text_dir_path3.delete(1.0, END)
self.dataset_path3 = self.askdirectory()
self.text_dir_path3.insert(END, self.dataset_path3)
self.text_dir_path3.config(state=DISABLED)
self.run_button.config(state=NORMAL)
def print_to_output(self, mode, text):
"""
:param mode: INSERT new text or clear the textbox (DELETE)
:param text: The output to be presented in the textbox.
"""
self.entry_output.config(state=NORMAL)
if mode == "INSERT":
self.entry_output.insert(END, text)
elif mode == "DELETE":
self.entry_output.delete('1.0', END)
self.entry_output.config(state=DISABLED)
def execute(self):
"""
Implements the execution of the algorithm and sends all entered parameters to preprocessing and then to the
algorithm method.
:param out_path: Path of generated processed CSV file representing the dataset
"""
self.print_to_output("INSERT", "Executing classification of cell cycle. This may take a while.\n")
accuracy = build_stacked_ae(self.dataset_path1)
accuracy = '{0:.2f}'.format(accuracy)
self.print_to_output("DELETE", "")
self.print_to_output("INSERT", "Accuracy of multi-class classification using stacked auto-encoder: " + str(accuracy)+ " %\n")
self.print_to_output("INSERT", "--------------------------------------\n")
res = build_binary_classifiers(self.dataset_path2, self.dataset_path3)
self.print_to_output("INSERT",
"Accuracy of binary classification using ordinal binary classifier:\n")
acc1 = '{0:.2f}'.format(res[0][0]*100)
acc2 = '{0:.2f}'.format(res[1][0]*100)
self.print_to_output("INSERT",
"Accuracy for binary classifier of G1 vs. S+G2/M :" + str(acc1) + " %\n")
self.print_to_output("INSERT",
"Accuracy for binary classifier of G1+S vs. G2/M :" + str(acc2) + " %\n")
self.run_button.config(state=NORMAL)
self.browse_button1.config(state=NORMAL)
self.browse_button2.config(state=NORMAL)
self.browse_button3.config(state=NORMAL)
def askdirectory(self):
"""
Opens the Browse window for selecting the path of file.
"""
return tkFileDialog.askopenfile(parent=root, mode='rb', title='Choose a file').name
if __name__ == '__main__':
root = Tk()
my_gui = GUI(root)
root.mainloop()