Package nMOLDYN :: Package GUI :: Module AnalysisBenchmarkDialog
[hide private]
[frames] | no frames]

Source Code for Module nMOLDYN.GUI.AnalysisBenchmarkDialog

  1  """This modules implements I{Help-->nMOLDYN benchmark} dialog. 
  2   
  3  Classes: 
  4      * AnalysisBenchmarkDialog: creates I{Help-->nMOLDYN benchmark} dialog used to run the stability tests  
  5        between nMOLDYN v2.2.5 and the current version of nMOLDYN. 
  6  """ 
  7   
  8  # The python distribution modules 
  9  import copy 
 10  import os 
 11  import re 
 12   
 13  # The Tcl/Tk modules 
 14  from Tkinter import * 
 15  from tkMessageBox import showinfo 
 16   
 17  # The nMOLDYN modules 
 18  import nMOLDYN 
 19  from nMOLDYN.Core.Error import Error 
 20  from nMOLDYN.GUI.Widgets import * 
 21  from nMOLDYN.Tests.StabilityTests import * 
 22   
23 -class AnalysisBenchmarkDialog(Toplevel):
24 """Builds the dialog for nMOLDYN analysis benchmarks. 25 26 These benchmarks will guarantee the stability of the current version with a reference one that is the 27 version 2.2.5 the last official release of nMOLDYN. 28 29 @note: these benchmarks should be performed every time the code source of nMOLDYN has been touched for 30 any reason. 31 """ 32
33 - def __init__(self, parent, title = None):
34 """The constructor. 35 36 @param parent: the parent widget. 37 38 @param title: a string specifying the title of the dialog. 39 @type title: string 40 """ 41 42 Toplevel.__init__(self, parent) 43 self.transient(parent) 44 45 if title: 46 self.title(title) 47 48 self.parent = parent 49 50 # List of the test sets available. 51 self.availableTestSets = sorted(availableTests + ['ALL']) 52 53 # This is the tag counter to allow the user to click on each failing test id to get more informations. 54 self.tagCounter = 1 55 56 body = Frame(self) 57 self.initial_focus = self.body(body) 58 body.grid(row = 0, column = 0, sticky = EW) 59 60 self.buttonbox() 61 62 self.grab_set() 63 64 if not self.initial_focus: 65 self.initial_focus = self 66 67 self.protocol("WM_DELETE_WINDOW", self.cancel) 68 69 self.resizable(width = NO, height = NO) 70 71 self.geometry("+%d+%d" % (parent.winfo_rootx()+50, parent.winfo_rooty()+50)) 72 73 self.initial_focus.focus_set() 74 75 self.wait_window(self)
76
77 - def body(self, master):
78 """Creates dialog body. Returns widget that should have initial focus. 79 """ 80 81 settingsFrame = LabelFrame(master, text = 'Settings', bd = 2, relief = GROOVE) 82 settingsFrame.grid(row = 0, column = 0, sticky = EW, padx = 3, pady = 3) 83 settingsFrame.grid_columnconfigure(0, weight = 1) 84 settingsFrame.grid_rowconfigure(0, weight = 1) 85 86 # The combo listbox that will contain the list of the available tests. 87 self.testListLb = ComboListbox(settingsFrame,'Available tests',[]) 88 self.testListLb.grid(row = 0, column = 0, padx = 2, pady = 2, sticky = 'NS') 89 self.testListLb.grid_rowconfigure(0, weight = 1) 90 self.testListLb.lb.config({'selectmode' : MULTIPLE}) 91 self.testListLb.lb.bind('<Button-3>',self.infoAboutTest) 92 93 # The available test sets are inserted in the listboxes. 94 for testSet in self.availableTestSets: 95 self.testListLb.lb.insert(END, testSet) 96 97 self.testResultsText = ComboText(settingsFrame,\ 98 frameLabel = 'Results for the selected benchmark(s)') 99 self.testResultsText.grid(row = 0, column = 1, padx = 2, pady = 2, sticky = 'NS') 100 self.testResultsText.config({'relief' : SUNKEN, 'bd' : 2}) 101 self.testResultsText.grid_rowconfigure(0, weight = 1) 102 self.testResultsText.text.config({'wrap' : WORD}) 103 104 self.testResultsText.text.tag_config('12', foreground = 'black', font = ('Courier','12')) 105 self.testResultsText.text.tag_config('g12', foreground = 'green', font = ('Courier','12')) 106 self.testResultsText.text.tag_config('12B', foreground = 'black', font = ('Courier','12','bold')) 107 108 return None
109
110 - def buttonbox(self):
111 """Adds standard button box.""" 112 113 # The frame that contains the 'Cancel' and 'OK' buttons. 114 box = LabelFrame(self, text = 'Actions', bd = 2, relief = GROOVE) 115 box.grid(row = 1, column = 0, sticky = EW, padx = 3, pady = 3) 116 box.grid_columnconfigure(0, weight = 1) 117 118 w = Button(box, text = "Cancel", width=10, command = self.cancel) 119 w.grid(row = 0, column = 0, sticky = E) 120 w = Button(box, text = "Clear", width=10, command = self.clearResults) 121 w.grid(row = 0, column = 1, sticky = E) 122 w = Button(box, text = "OK", width=10, command = self.ok, default=ACTIVE) 123 w.grid(row = 0, column = 2, sticky = E) 124 125 self.bind("<Return>", self.ok) 126 self.bind("<Escape>", self.cancel)
127 128 # Standard button semantics.
129 - def ok(self, event = None):
130 if not self.validate(): 131 self.initial_focus.focus_set() 132 return 133 134 self.update_idletasks() 135 136 self.apply()
137
138 - def cancel(self, event = None):
139 140 # Put focus back to the parent window 141 self.parent.focus_set() 142 self.destroy()
143 144 # Command hooks
145 - def validate(self):
146 147 # This is the list of the test sets selected by the |checkSimulationsDialog| dialog. 148 self.selectedTestSets = [self.testListLb.lb.get(int(testSet)) for testSet in self.testListLb.lb.curselection()] 149 150 if not self.selectedTestSets: 151 raise Error('No Test selected.') 152 153 return True
154
155 - def apply(self):
156 157 # The tests results is switched to NORMAL state. Some informations can be written in. 158 self.testResultsText.text.config(state = NORMAL) 159 160 try: 161 162 if 'ALL' in self.selectedTestSets: 163 self.selectedTestSets = availableTests 164 165 comp = 1 166 # Loop over each selected set of test (e.g. MSD, AT ...). 167 for test in self.selectedTestSets: 168 169 t = eval(test+'Tests()') 170 t.run() 171 172 self.testResultsText.insert(END, t.summary) 173 174 self.testResultsText.tag('#', 'g12') 175 176 [self.testResultsText.tag(p, '12B') for p in re.findall('Summary.*\n', t.summary)] 177 178 [self.testResultsText.tag(p, '12B') for p in re.findall('Number of.*\n', t.summary)] 179 180 [self.testResultsText.tag(p, 'success%s' % comp) for p in re.findall('Successful tests:.*\n', t.summary)] 181 182 [self.testResultsText.tag(p, 'failure%s' % comp) for p in re.findall('Failing tests:.*\n', t.summary)] 183 184 self.testResultsText.text.tag_config('success%s' % comp, foreground = 'blue', font = ('Courier','10','bold')) 185 186 self.testResultsText.text.tag_config('failure%s' % comp, foreground = 'red', font = ('Courier','10','bold')) 187 188 [self.testResultsText.tag(p, '12B') for p in re.findall('Percentage.*\n', t.summary)] 189 190 [self.testResultsText.tag(p, '12B') for p in re.findall('Time to run.*\n', t.summary)] 191 192 # This binding displays the contents of the successful tests when the user click on it with the mouse left button. 193 self.testResultsText.text.tag_bind('success%s' % comp,\ 194 '<Button-1>',\ 195 lambda event, p = t.successes : self.displayTest(event, p)) 196 197 # This binding changes the mouse icon to a question when the user passes over a failing test. 198 self.testResultsText.text.tag_bind('success%s' % comp, '<Motion>', lambda event : changeMouseCursor(event,'question_arrow'), '+') 199 200 # This binding returns the mouse icon to its default value when the user passes out a failing test. 201 self.testResultsText.text.tag_bind('success%s' % comp, '<Leave>', lambda event : changeMouseCursor(event,'arrow'), '+') 202 203 # Some tag bindings for the failing tests. 204 # This binding displays the contents of the failing tests when the user click on it with the mouse left button. 205 self.testResultsText.text.tag_bind('failure%s' % comp,\ 206 '<Button-1>',\ 207 lambda event, p = t.failures : self.displayTest(event, p)) 208 209 # This binding changes the mouse icon to a question when the user passes over a failing test. 210 self.testResultsText.text.tag_bind('failure%s' % comp,'<Motion>', lambda event : changeMouseCursor(event,'question_arrow'), '+') 211 212 # This binding returns the mouse icon to its default value when the user passes out a failing test. 213 self.testResultsText.text.tag_bind('failure%s' % comp,'<Leave>', lambda event : changeMouseCursor(event,'arrow'), '+') 214 215 comp += 1 216 217 except: 218 raise Error('Error when running test benchmark.') 219 220 finally: 221 # The tests results is switched to DISABLED state. Nothing can be written in. 222 self.testResultsText.text.config(state = DISABLED)
223
224 - def infoAboutTest(self, event):
225 """This callback displays basic information about a selected test before running it by clicking on 226 the right mouse button. 227 """ 228 229 selectedInd = self.testListLb.lb.nearest(event.y) 230 selectedTest = self.testListLb.lb.get(selectedInd) 231 t = eval(selectedTest+'Tests()') 232 showinfo('Information',t.info) 233 del(t)
234
235 - def displayTest(self, event, parameters):
236 """Displays in a text widget the nMOLDYN v2.2.5 input file of a selected failing test. 237 238 Arguments: 239 - event: the mouse left button click Tkinter event that will trigger the opening of the window. 240 - testSet: the test set to which belong the failing test. 241 """ 242 243 # The text index of the event. 244 first = event.widget.index('@%d,%d' % (event.x, event.y)) 245 c = self.testResultsText.text.get(first) 246 247 try: 248 i = int(c) 249 250 while c not in [' ','\n']: 251 first = first + '-1c' 252 c = self.testResultsText.text.get(first) 253 if c == '\n': 254 break 255 256 first = first + '+1c' 257 c = self.testResultsText.text.get(first) 258 259 last = first 260 while c not in [' ','\n']: 261 last = last + '+1c' 262 c = self.testResultsText.text.get(last) 263 if c == '\n': 264 break 265 266 selectedTest = int(self.testResultsText.text.get(first, last).strip()) 267 268 except: 269 return 270 271 # Creation of a toplevel window that will display the reference and current 272 # nMOLDYN input files of the failing test. 273 self.detailsDialog = Toplevel(self) 274 self.detailsDialog.transient(self.parent) 275 276 # The text combo widget that will display the contents of the reference version of the input file. 277 referenceContents = ComboText(self.detailsDialog,\ 278 frameLabel = 'nMOLDYN reference version parameters') 279 referenceContents.grid(row = 0, column = 0) 280 281 referenceContents.config({'width' : 100,\ 282 'height' : 20,\ 283 'relief' : SUNKEN,\ 284 'bd' : 2}) 285 referenceContents.text.config({'wrap' : WORD,\ 286 'font' : ('Courier', 10, 'normal'),\ 287 'width' : 80,\ 288 'height' : 10,\ 289 'bg' : 'salmon'}) 290 291 for k, v in parameters[selectedTest]['REF'].items(): 292 referenceContents.insert(END, '%s = %s\n' % (repr(k), repr(v))) 293 referenceContents.text.config(state = DISABLED) 294 295 # The text combo widget that will display the contents of the current version of the input file. 296 currentContents = ComboText(self.detailsDialog,\ 297 frameLabel = 'nMOLDYN version %s parameters' % nMOLDYN.__version__) 298 currentContents.grid(row = 1, column = 0) 299 300 currentContents.config({'width' : 100,\ 301 'height' : 20,\ 302 'relief' : SUNKEN,\ 303 'bd' : 2}) 304 currentContents.text.config({'wrap' : WORD,\ 305 'width' : 80,\ 306 'height' : 10,\ 307 'bg' : '#ffff80',\ 308 'font' : ('Arial', 10, 'normal')}) 309 310 for k, v in parameters[selectedTest]['NEW'].items(): 311 currentContents.insert(END, '%s = %s\n' % (repr(k), repr(v))) 312 currentContents.text.config(state = DISABLED) 313 314 self.detailsDialog.grab_set() 315 316 self.detailsDialog.bind("<Escape>", self.cancel1) 317 self.detailsDialog.protocol("WM_DELETE_WINDOW", self.cancel1) 318 319 self.detailsDialog.resizable(width = NO, height = NO) 320 321 self.detailsDialog.geometry("+%d+%d" % (self.winfo_rootx()+50, self.winfo_rooty()+50)) 322 323 self.detailsDialog.title('Details about the test %s.' % selectedTest) 324 325 self.detailsDialog.focus_set() 326 327 self.detailsDialog.wait_window(self.detailsDialog)
328
329 - def cancel1(self, event = None):
330 331 # Put focus back to the parent window 332 self.grab_set() 333 334 # Put focus back to the parent window 335 self.focus_set() 336 337 self.detailsDialog.destroy()
338
339 - def clearResults(self):
340 """ 341 This methods clears up all the results about the evaluated test sets. 342 """ 343 344 self.testResultsText.cleanup()
345