|
| 1 | +#!/usr/bin/python |
| 2 | + |
| 3 | +# guiHelper has functions that help build the gui and connect to della. The functions are called by submitWorm analysis codes. |
| 4 | +# |
| 5 | + |
| 6 | + |
| 7 | +try: |
| 8 | + import Tkinter as tk |
| 9 | + import tkFileDialog |
| 10 | +except ImportError: |
| 11 | + import tkinter as tk |
| 12 | + import tkinter.filedialog as tkFileDialog |
| 13 | +import paramiko |
| 14 | +import socket |
| 15 | +import os |
| 16 | +import pickle |
| 17 | +import getpass |
| 18 | + |
| 19 | + |
| 20 | +#server jobs willb e submitted to |
| 21 | +SERVER ='della.princeton.edu' |
| 22 | +#location of the ssh key file shared by lefierdata |
| 23 | +KEYPATH='/tigress/LEIFER/.ssh/id_rsa' |
| 24 | + |
| 25 | +#load the pickle files for default values to put into fields. The pickle files store your previous entries in the pickles2.p file in ~. |
| 26 | +def pickle_load(): |
| 27 | + # get ready for pickled variables |
| 28 | + pickle_path = (os.path.expanduser('~') + "/platypusTemp/") |
| 29 | + pickle_file = pickle_path + "pickles2.p" |
| 30 | + if not os.path.exists(pickle_path): |
| 31 | + os.makedirs(pickle_path) |
| 32 | + |
| 33 | + if not os.path.exists(pickle_file): |
| 34 | + storedUsername = { "username": getpass.getuser() } |
| 35 | + pickle.dump( storedUsername, open(pickle_file, "wb" ) ) |
| 36 | + |
| 37 | + # return the dictionary with all previous values stored. |
| 38 | + try: |
| 39 | + prevUser = pickle.load( open( pickle_file, "rb" ) ) |
| 40 | + except: |
| 41 | + prevUser = {'username': getpass.getuser()} |
| 42 | + |
| 43 | + |
| 44 | + #fill in default values |
| 45 | + if 'username' not in prevUser: |
| 46 | + prevUser['username'] = "USER" |
| 47 | + if 'time' not in prevUser: |
| 48 | + prevUser['time'] = "180" |
| 49 | + if 'mem' not in prevUser: |
| 50 | + prevUser['mem'] = "16000" |
| 51 | + if 'date' not in prevUser: |
| 52 | + prevUser['date'] = "testing_sets" |
| 53 | + if 'folderName' not in prevUser: |
| 54 | + prevUser['folderName'] = "Brain_working_dataset" |
| 55 | + if 'frameNumber' not in prevUser: |
| 56 | + prevUser['frameNumber'] = "1000" |
| 57 | + if 'refNumber' not in prevUser: |
| 58 | + prevUser['refNumber'] = "100" |
| 59 | + if 'neuronNumber' not in prevUser: |
| 60 | + prevUser['neuronNumber'] = "150" |
| 61 | + if 'checkNumber' not in prevUser: |
| 62 | + prevUser['checkNumber'] = "500" |
| 63 | + if 'matlab_command' not in prevUser: |
| 64 | + prevUser['matlab_command']='Put your code here!' |
| 65 | + if 'code_path' not in prevUser: |
| 66 | + prevUser['code_path']='Put the path to the .path file here!' |
| 67 | + |
| 68 | + |
| 69 | + return prevUser |
| 70 | + |
| 71 | + |
| 72 | +#read the submissionParameters.txt file in the data folder to get the number of frames. |
| 73 | +def get_nframes(client,fullPath): |
| 74 | + |
| 75 | + print('Getting number of frames from GUI') |
| 76 | + subDataFile = fullPath + '/submissionParameters.txt' |
| 77 | + client2 = client.open_sftp() |
| 78 | + sub_data={} |
| 79 | + # read each line, saving key-values pairs into a dictionary |
| 80 | + try: |
| 81 | + with client2.open(subDataFile) as remote_file: |
| 82 | + for lines in remote_file: |
| 83 | + lines=lines.split(" ") |
| 84 | + print(lines) |
| 85 | + sub_data[lines[0]]=lines[1] |
| 86 | + except Exception: |
| 87 | + raise NameError("Remote File not found") |
| 88 | + |
| 89 | + if sub_data.get('NFrames') != None: |
| 90 | + print('Getting number of frames from Remote') |
| 91 | + NFrames=sub_data['NFrames'] |
| 92 | + return NFrames |
| 93 | + else: |
| 94 | + raise NameError("Cannot connect to get number of Frames") |
| 95 | + |
| 96 | + |
| 97 | +def dellaConnect(username,password=None): |
| 98 | + #use the username to connect to della, if password is provided, use it, otherwise, use ssh keys |
| 99 | + if socket.gethostname()=='tigressdata.princeton.edu': |
| 100 | + #if on tigressdata, use path to key file file in /tigress/LEIFEr |
| 101 | + key = paramiko.RSAKey.from_private_key_file(KEYPATH) |
| 102 | + elif socket.gethostname()=='tigressdata2.princeton.edu': |
| 103 | + #key = paramiko.RSAKey.from_private_key_file(KEYPATH) |
| 104 | + key = paramiko.RSAKey.from_private_key_file("/home/"+username+"/.ssh/id_rsa") |
| 105 | + else: |
| 106 | + key = None |
| 107 | + # connect and submit job via sbatch |
| 108 | + client = paramiko.SSHClient() |
| 109 | + client.load_system_host_keys() |
| 110 | + client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) |
| 111 | + if not password: |
| 112 | + client.connect(SERVER, 22, username,pkey=key) |
| 113 | + else: |
| 114 | + try: |
| 115 | + client.connect(SERVER, 22, username, password) |
| 116 | + except Exception: |
| 117 | + raise Exception('Cannont connect, problem with username password combo') |
| 118 | + return client |
| 119 | + |
| 120 | +def passwordReqCheck(username): |
| 121 | + # check if a password is required for a given username |
| 122 | + # try to see if a password is needed |
| 123 | + try: |
| 124 | + dellaConnect(username) |
| 125 | + isNeedsPassword = False |
| 126 | + except paramiko.AuthenticationException: |
| 127 | + isNeedsPassword = True |
| 128 | + return isNeedsPassword |
| 129 | + |
| 130 | +def selectFolder(master=None): |
| 131 | + # select a folder using a popup window |
| 132 | + folder=tkFileDialog.askdirectory(mustexist=False , initialdir= '/tigress/LEIFER/PanNeuronal/') |
| 133 | + if folder: |
| 134 | + #parse the folder path and populate the filed on the gui. |
| 135 | + path,folderName=os.path.split(folder) |
| 136 | + path,date=os.path.split(path) |
| 137 | + master.e['parent_path'].delete(0,tk.END) |
| 138 | + master.e['parent_path'].insert(0,path) |
| 139 | + master.e['date'].delete(0,tk.END) |
| 140 | + master.e['date'].insert(0,date) |
| 141 | + master.e['folder_name'].delete(0,tk.END) |
| 142 | + master.e['folder_name'].insert(0,folderName) |
| 143 | + print(folder) |
| 144 | + |
| 145 | +def selectPath(master=None): |
| 146 | + filename = tkFileDialog.askopenfilename(initialdir= '/tigress/LEIFER/communalCode/ ') |
| 147 | + master.e['code_path'].delete(0,tk.END) |
| 148 | + master.e['code_path'].insert(0,filename) |
| 149 | +# |
| 150 | +# #class for building the gui and populating the rows |
| 151 | +class submitTK(tk.Tk): |
| 152 | + #build the gui with some number of max rows and cols, |
| 153 | + #submitTK is a subclass of tkinter's Tk(). |
| 154 | + def __init__(self, rows=10, cols=2): |
| 155 | + |
| 156 | + tk.Tk.__init__(self) |
| 157 | + #build rows and cols |
| 158 | + for i in range(rows): |
| 159 | + self.columnconfigure(i,pad=3) |
| 160 | + for j in range(cols): |
| 161 | + self.rowconfigure(j, pad=3) |
| 162 | + # make counter for the row being populated |
| 163 | + self.row_count=0 |
| 164 | + # self.e will have all the values of the rows stored |
| 165 | + self.e=dict() |
| 166 | + |
| 167 | + self.title("Options") |
| 168 | + |
| 169 | + # add a text row to the field, the row will have a text label, |
| 170 | + # row is added to the next open row. |
| 171 | + # field name for using in the e, |
| 172 | + # default field entry |
| 173 | + # show, for passwords, use '*' |
| 174 | + |
| 175 | + def addGuiField(self,label,name,default="",show=None): |
| 176 | + master_label = tk.Label(self, text=label) |
| 177 | + master_label.grid(row=self.row_count, column=0,sticky=tk.W+tk.E) |
| 178 | + self.e[name] = tk.Entry(self,show=show) |
| 179 | + self.e[name].insert(0, default) |
| 180 | + self.e[name].grid(row=self.row_count, column=1,sticky=tk.W+tk.E) |
| 181 | + self.row_count+=1 |
| 182 | + |
| 183 | + # make checkbox, again with label and field name |
| 184 | + def addGuiCheck(self,label,name,default=1): |
| 185 | + master_label = tk.Label(self, text=label) |
| 186 | + master_label.grid(row=self.row_count, column=0, sticky=tk.W+tk.E) |
| 187 | + var1= tk.IntVar() |
| 188 | + self.e[name]= tk.Checkbutton(self, text=None, variable=var1) |
| 189 | + self.e[name].var = var1 |
| 190 | + self.e[name].grid(row=self.row_count, column=1,sticky=tk.W+tk.E) |
| 191 | + self.e[name].var.set(default) |
| 192 | + self.row_count+=1 |
| 193 | + |
| 194 | + # add a button with a text label and a function callback handle. |
| 195 | + def addGuiButton(self,label,b_command=None): |
| 196 | + self.b = tk.Button(self, text=label, width=10, command=b_command) |
| 197 | + self.b.grid(row=self.row_count,columnspan=2,sticky=tk.W+tk.E) |
| 198 | + self.row_count+=1 |
| 199 | + |
| 200 | + #save values fo fields for defaults during next call |
| 201 | + def pickleDump(self): |
| 202 | + pickle_path = (os.path.expanduser('~') + "/platypusTemp/") |
| 203 | + pickle_file = pickle_path + "pickles2.p" |
| 204 | + prevUser=pickle_load() |
| 205 | + #refill prevUser dict with master entries |
| 206 | + if 'user_name' in self.e: |
| 207 | + prevUser['username']=self.e['user_name'].get() |
| 208 | + if 'time' in self.e: |
| 209 | + prevUser['time']=self.e['time'].get() |
| 210 | + if 'mem' in self.e: |
| 211 | + prevUser['mem']=self.e['mem'].get() |
| 212 | + if 'date' in self.e: |
| 213 | + prevUser['date'] = self.e['date'].get() |
| 214 | + if 'folder_name' in self.e: |
| 215 | + prevUser['folderName']=self.e['folder_name'].get() |
| 216 | + if 'nframes' in self.e: |
| 217 | + prevUser['frameNumber']=self.e['nframes'].get() |
| 218 | + if 'n_ref' in self.e: |
| 219 | + prevUser['refNumber']=self.e['n_ref'].get() |
| 220 | + if 'n_neurons' in self.e: |
| 221 | + prevUser['neuronNumber']=self.e['n_neurons'].get() |
| 222 | + if 'n_checks' in self.e: |
| 223 | + prevUser['checkNumber']=self.e['n_checks'].get() |
| 224 | + if 'matlab_command' in self.e: |
| 225 | + prevUser['matlab_command']=self.e['matlab_command'].get() |
| 226 | + if 'code_path' in self.e: |
| 227 | + prevUser['code_path']=self.e['code_path'].get() |
| 228 | + |
| 229 | + #save prevUser as pickle |
| 230 | + pickle.dump(prevUser, open(pickle_file, "wb" ) ) |
| 231 | + |
| 232 | + |
| 233 | + # run the main loop. |
| 234 | + def run(self): |
| 235 | + tk.mainloop() |
| 236 | + |
0 commit comments