blob: c31a1cd51024bebbb41732ec5d0386726aa67a1d [file] [log] [blame]
emayecs5656b2b2021-08-04 12:44:13 -04001#!/usr/bin/env python3
emayecs5966a532021-07-29 10:07:02 -04002#
3#-----------------------------------------------------------
emayecs14748312021-08-05 14:21:26 -04004# Parameter editing for the characterization tool
emayecs5966a532021-07-29 10:07:02 -04005#-----------------------------------------------------------
6# Written by Tim Edwards
7# efabless, inc.
8# March 28, 2017
9# Version 0.1
10#--------------------------------------------------------
11
12import os
13import re
14import tkinter
15from tkinter import ttk
16
17class Condition(object):
18 def __init__(self, parent = None):
19 self.min = tkinter.StringVar(parent)
20 self.typ = tkinter.StringVar(parent)
21 self.max = tkinter.StringVar(parent)
22 self.step = tkinter.StringVar(parent)
23 self.steptype = tkinter.StringVar(parent)
24 self.unit = tkinter.StringVar(parent)
25 self.condition = tkinter.StringVar(parent)
26 self.display = tkinter.StringVar(parent)
27
28class Limit(object):
29 def __init__(self, parent = None):
30 self.target = tkinter.StringVar(parent)
31 self.penalty = tkinter.StringVar(parent)
32 self.calc = tkinter.StringVar(parent)
33 self.limit = tkinter.StringVar(parent)
34
35class EditParam(tkinter.Toplevel):
36 """Characterization tool electrical parameter editor."""
37
38 def __init__(self, parent=None, fontsize = 11, *args, **kwargs):
39 '''See the __init__ for Tkinter.Toplevel.'''
40 tkinter.Toplevel.__init__(self, parent, *args, **kwargs)
41
42 s = ttk.Style()
43 s.configure('normal.TButton', font=('Helvetica', fontsize), border = 3, relief = 'raised')
44 s.configure('bg.TFrame', background='gray40')
45 self.parent = parent
46 self.withdraw()
47 self.title('Electrical parameter editor')
48 self.sframe = tkinter.Frame(self)
49 self.sframe.grid(column = 0, row = 0, sticky = "news")
50
51 # Keep current parameter
52 self.param = None
53
54 #-------------------------------------------------------------
55 # Add the entries that are common to all electrical parameters
56
57 self.selmethod = tkinter.StringVar(self)
58 self.display = tkinter.StringVar(self)
59 self.unit = tkinter.StringVar(self)
60 self.minrec = Limit(self)
61 self.typrec = Limit(self)
62 self.maxrec = Limit(self)
63 self.cond = []
64
65 #--------------------------------------------------------
66
67 self.bbar = ttk.Frame(self)
68 self.bbar.grid(column = 0, row = 2, sticky = "news")
69
70 self.bbar.apply_button = ttk.Button(self.bbar, text='Apply',
71 command=self.apply, style = 'normal.TButton')
72 self.bbar.apply_button.grid(column=0, row=0, padx = 5)
73
74 self.bbar.close_button = ttk.Button(self.bbar, text='Close',
75 command=self.close, style = 'normal.TButton')
76 self.bbar.close_button.grid(column=1, row=0, padx = 5)
77
78 self.rowconfigure(0, weight = 1)
79 self.rowconfigure(1, weight = 0)
80 self.columnconfigure(0, weight = 1)
81
82 self.protocol("WM_DELETE_WINDOW", self.close)
83
84 def grid_configure(self, padx, pady):
85 return
86
87 def redisplay(self):
88 return
89
90 def populate(self, param):
91 # Remove all existing contents
92 for widget in self.sframe.winfo_children():
93 widget.destroy()
94
95 # Add major frames
96
97 frame1 = ttk.Frame(self.sframe)
98 frame1.grid(column = 0, row = 0, sticky = 'news')
99 frame2 = ttk.Frame(self.sframe)
100 frame2.grid(column = 0, row = 1, sticky = 'news')
101 frame3 = ttk.Frame(self.sframe)
102 frame3.grid(column = 0, row = 2, sticky = 'news')
103
104 # The Conditions area is the one that grows
105 self.sframe.rowconfigure(2, weight=1)
106 self.sframe.columnconfigure(0, weight=1)
107
108 ttk.Separator(frame3, orient='horizontal').grid(row = 0, column = 0,
109 sticky = 'news')
110
111 # The conditions list can get very big, so build out a
112 # scrolled canvas.
113
114 frame3.canvas = tkinter.Canvas(frame3)
115 frame3.canvas.grid(row = 1, column = 0, sticky = 'nswe')
116 frame3.canvas.dframe = ttk.Frame(frame3.canvas, style='bg.TFrame')
117 # Save the canvas widget, as we need to access it from places like
118 # the scrollbar callbacks.
119 self.canvas = frame3.canvas
120 # Place the frame in the canvas
121 frame3.canvas.create_window((0,0), window=frame3.canvas.dframe,
122 anchor="nw")
123 # Make sure the main window resizes, not the scrollbars.
124 frame3.rowconfigure(1, weight=1)
125 frame3.columnconfigure(0, weight = 1)
126 # X scrollbar for conditions list
127 main_xscrollbar = ttk.Scrollbar(frame3, orient = 'horizontal')
128 main_xscrollbar.grid(row = 2, column = 0, sticky = 'nswe')
129 # Y scrollbar for conditions list
130 main_yscrollbar = ttk.Scrollbar(frame3, orient = 'vertical')
131 main_yscrollbar.grid(row = 1, column = 1, sticky = 'nswe')
132 # Attach console to scrollbars
133 frame3.canvas.config(xscrollcommand = main_xscrollbar.set)
134 main_xscrollbar.config(command = frame3.canvas.xview)
135 frame3.canvas.config(yscrollcommand = main_yscrollbar.set)
136 main_yscrollbar.config(command = frame3.canvas.yview)
137
138 # Make sure that scrollwheel pans the window
139 frame3.canvas.bind_all("<Button-4>", self.on_mousewheel)
140 frame3.canvas.bind_all("<Button-5>", self.on_mousewheel)
141
142 # Set up configure callback
143 frame3.canvas.dframe.bind("<Configure>", self.frame_configure)
144
145 # Get list of methods from testbench folder
146 dspath = os.path.split(self.parent.cur_datasheet)[0]
147 tbpath = dspath + '/testbench'
148 tbfiles = os.listdir(tbpath)
149 methods = []
150 for spifile in tbfiles:
151 if os.path.splitext(spifile)[1] == '.spi':
152 methods.append(os.path.splitext(spifile)[0].upper())
153
154 # Get list of pins from parent datasheet
155 dsheet = self.parent.datatop['data-sheet']
156 pins = dsheet['pins']
157 pinlist = []
158 for pin in pins:
159 pinlist.append(pin['name'])
160 pinlist.append('(none)')
161
162 # Add common elements
163 frame1.ldisplay = ttk.Label(frame1, text='Description:',
164 style= 'blue.TLabel', anchor = 'e')
165 frame1.lmethod = ttk.Label(frame1, text='Method:',
166 style= 'blue.TLabel', anchor = 'e')
167 frame1.lunit = ttk.Label(frame1, text='Unit:',
168 style= 'blue.TLabel', anchor = 'e')
169
170 # If 'pin' exists (old style), append it to 'condition' and remove.
171 if 'pin' in param:
172 if 'method' in param and ':' not in param['method']:
173 param['method'] += ':' + param['pin']
174 param.pop('pin', 0)
175
176 # Find method and apply to OptionMenu
177 if 'method' in param:
178 self.selmethod.set(param['method'])
179 else:
180 self.selmethod.set('(none)')
181
182
183 frame1.display = ttk.Entry(frame1, textvariable = self.display)
184 frame1.method = ttk.OptionMenu(frame1, self.selmethod, self.selmethod.get(), *methods)
185 frame1.unit = ttk.Entry(frame1, textvariable = self.unit)
186
187 frame1.ldisplay.grid(column = 0, row = 0, sticky = 'news', padx=5, pady=5)
188 frame1.display.grid(column = 1, row = 0, sticky = 'news', padx=5, pady=3)
189 frame1.lmethod.grid(column = 0, row = 1, sticky = 'news', padx=5, pady=5)
190 frame1.method.grid(column = 1, row = 1, sticky = 'news', padx=5, pady=3)
191 frame1.lunit.grid(column = 0, row = 2, sticky = 'news', padx=5, pady=5)
192 frame1.unit.grid(column = 1, row = 2, sticky = 'news', padx=5, pady=3)
193
194 frame1.columnconfigure(0, weight = 0)
195 frame1.columnconfigure(1, weight = 1)
196
197 frame1.display.delete(0, 'end')
198 if 'display' in param:
199 frame1.display.insert(0, param['display'])
200 else:
201 frame1.display.insert(0, '(none)')
202
203 frame1.unit.delete(0, 'end')
204 if 'unit' in param:
205 frame1.unit.insert(0, param['unit'])
206 else:
207 frame1.unit.insert(0, '(none)')
208
209 ttk.Separator(frame1, orient='horizontal').grid(row = 4, column = 0,
210 columnspan = 2, sticky = 'nsew')
211
212 # Calculation types
213 calctypes = ["min", "max", "avg", "diffmin", "diffmax", "(none)"]
214 limittypes = ["above", "below", "exact", "legacy", "(none)"]
215
216 # Add min/typ/max (To-do: Add plot)
217
218 frame2min = ttk.Frame(frame2, borderwidth = 2, relief='groove')
219 frame2min.grid(row = 0, column = 0, padx = 2, pady = 2, sticky = 'news')
220 ttk.Label(frame2min, text="Minimum:", style = 'blue.TLabel',
221 anchor = 'w').grid(row = 0, column = 0, padx = 5,
222 sticky = 'news')
223 if 'min' in param:
224 minrec = param['min']
225 else:
226 minrec = {}
227 ttk.Label(frame2min, text="Target:", anchor = 'e',
228 style = 'normal.TLabel').grid(row = 1, column = 0, padx = 5,
229 sticky = 'news')
230 frame2min.tmin = ttk.Entry(frame2min, textvariable = self.minrec.target)
231 frame2min.tmin.grid(row = 1, column = 1, padx = 5, sticky = 'news')
232 frame2min.tmin.delete(0, 'end')
233 if 'target' in minrec:
234 frame2min.tmin.insert(0, minrec['target'])
235 ttk.Label(frame2min, text="Penalty:", anchor = 'e',
236 style = 'normal.TLabel').grid(row = 2, column = 0, padx = 5,
237 sticky = 'news')
238 frame2min.pmin = ttk.Entry(frame2min, textvariable = self.minrec.penalty)
239 frame2min.pmin.grid(row = 2, column = 1, padx = 5, sticky = 'news')
240 frame2min.pmin.delete(0, 'end')
241 if 'penalty' in minrec:
242 frame2min.pmin.insert(0, minrec['penalty'])
243 if 'calc' in minrec:
244 calcrec = minrec['calc']
245 try:
246 calctype, limittype = calcrec.split('-')
247 except ValueError:
248 calctype = calcrec
249 if calctype == 'min':
250 limittype = 'above'
251 elif calctype == 'max':
252 limittype = 'below'
253 elif calctype == 'avg':
254 limittype = 'exact'
255 elif calctype == 'diffmin':
256 limittype = 'above'
257 elif calctype == 'diffmax':
258 limittype = 'below'
259 else:
260 limittype = '(none)'
261 else:
262 calctype = 'min'
263 limittype = 'above'
264
265 ttk.Label(frame2min, text="Calculation:", anchor = 'e',
266 style = 'normal.TLabel').grid(row = 3, column = 0, padx = 5,
267 sticky = 'news')
268 self.cmin = tkinter.StringVar(self)
269 self.cmin.set(calctype)
270 frame2min.cmin = ttk.OptionMenu(frame2min, self.cmin, calctype, *calctypes)
271 frame2min.cmin.grid(row = 3, column = 1, padx = 5, sticky = 'news')
272 ttk.Label(frame2min, text="Limit:", anchor = 'e',
273 style = 'normal.TLabel').grid(row = 4, column = 0, padx = 5,
274 sticky = 'news')
275 self.lmin = tkinter.StringVar(self)
276 self.lmin.set(limittype)
277 frame2min.lmin = ttk.OptionMenu(frame2min, self.lmin, limittype, *limittypes)
278 frame2min.lmin.grid(row = 4, column = 1, padx = 5, sticky = 'news')
279
280 frame2typ = ttk.Frame(frame2, borderwidth = 2, relief='groove')
281 frame2typ.grid(row = 0, column = 1, padx = 2, pady = 2, sticky = 'news')
282 ttk.Label(frame2typ, text="Typical:", style = 'blue.TLabel',
283 anchor = 'w').grid(row = 0, column = 0, padx = 5,
284 sticky = 'news')
285 if 'typ' in param:
286 typrec = param['typ']
287 else:
288 typrec = {}
289 ttk.Label(frame2typ, text="Target:", anchor = 'e',
290 style = 'normal.TLabel').grid(row = 1, column = 0, padx = 5,
291 sticky = 'news')
292 frame2typ.ttyp = ttk.Entry(frame2typ, textvariable = self.typrec.target)
293 frame2typ.ttyp.grid(row = 1, column = 1, padx = 5, sticky = 'news')
294 frame2typ.ttyp.delete(0, 'end')
295 if 'target' in typrec:
296 frame2typ.ttyp.insert(0, typrec['target'])
297 ttk.Label(frame2typ, text="Penalty:", anchor = 'e',
298 style = 'normal.TLabel').grid(row = 2, column = 0, padx = 5,
299 sticky = 'news')
300 frame2typ.ptyp = ttk.Entry(frame2typ, textvariable = self.typrec.penalty)
301 frame2typ.ptyp.grid(row = 2, column = 1, padx = 5, sticky = 'news')
302 frame2typ.ptyp.delete(0, 'end')
303 if 'penalty' in typrec:
304 frame2typ.ptyp.insert(0, typrec['penalty'])
305 if 'calc' in typrec:
306 calcrec = typrec['calc']
307 try:
308 calctype, limittype = calcrec.split('-')
309 except ValueError:
310 calctype = calcrec
311 if calctype == 'min':
312 limittype = 'above'
313 elif calctype == 'max':
314 limittype = 'below'
315 elif calctype == 'avg':
316 limittype = 'exact'
317 elif calctype == 'diffmin':
318 limittype = 'above'
319 elif calctype == 'diffmax':
320 limittype = 'below'
321 else:
322 limittype = '(none)'
323 else:
324 calctype = 'avg'
325 limittype = 'exact'
326
327 ttk.Label(frame2typ, text="Calculation:", anchor = 'e',
328 style = 'normal.TLabel').grid(row = 3, column = 0, padx = 5,
329 sticky = 'news')
330 self.ctyp = tkinter.StringVar(self)
331 self.ctyp.set(calctype)
332 frame2typ.ctyp = ttk.OptionMenu(frame2typ, self.ctyp, calctype, *calctypes)
333 frame2typ.ctyp.grid(row = 3, column = 1, padx = 5, sticky = 'news')
334 ttk.Label(frame2typ, text="Limit:", anchor = 'e',
335 style = 'normal.TLabel').grid(row = 4, column = 0, padx = 5,
336 sticky = 'news')
337 self.ltyp = tkinter.StringVar(self)
338 self.ltyp.set(limittype)
339 frame2typ.ltyp = ttk.OptionMenu(frame2typ, self.ltyp, limittype, *limittypes)
340 frame2typ.ltyp.grid(row = 4, column = 1, padx = 5, sticky = 'news')
341
342 frame2max = ttk.Frame(frame2, borderwidth = 2, relief='groove')
343 frame2max.grid(row = 0, column = 2, padx = 2, pady = 2, sticky = 'news')
344 ttk.Label(frame2max, text="Maximum:", style = 'blue.TLabel',
345 anchor = 'w').grid(row = 0, column = 0, padx = 5,
346 sticky = 'news')
347 if 'max' in param:
348 maxrec = param['max']
349 else:
350 maxrec = {}
351 ttk.Label(frame2max, text="Target:", anchor = 'e',
352 style = 'normal.TLabel').grid(row = 1, column = 0, padx = 5,
353 sticky = 'news')
354 frame2max.tmax = ttk.Entry(frame2max, textvariable = self.maxrec.target)
355 frame2max.tmax.grid(row = 1, column = 1, padx = 5, sticky = 'news')
356 frame2max.tmax.delete(0, 'end')
357 if 'target' in maxrec:
358 frame2max.tmax.insert(0, maxrec['target'])
359 ttk.Label(frame2max, text="Penalty:", anchor = 'e',
360 style = 'normal.TLabel').grid(row = 2, column = 0, padx = 5,
361 sticky = 'news')
362 frame2max.pmax = ttk.Entry(frame2max, textvariable = self.maxrec.penalty)
363 frame2max.pmax.grid(row = 2, column = 1, padx = 5, sticky = 'news')
364 frame2max.pmax.delete(0, 'end')
365 if 'penalty' in maxrec:
366 frame2max.pmax.insert(0, maxrec['penalty'])
367 if 'calc' in maxrec:
368 calcrec = maxrec['calc']
369 try:
370 calctype, limittype = calcrec.split('-')
371 except ValueError:
372 calctype = calcrec
373 if calctype == 'min':
374 limittype = 'above'
375 elif calctype == 'max':
376 limittype = 'below'
377 elif calctype == 'avg':
378 limittype = 'exact'
379 elif calctype == 'diffmin':
380 limittype = 'above'
381 elif calctype == 'diffmax':
382 limittype = 'below'
383 else:
384 limittype = '(none)'
385 else:
386 calctype = 'max'
387 limittype = 'below'
388
389 ttk.Label(frame2max, text="Calculation:", anchor = 'e',
390 style = 'normal.TLabel').grid(row = 3, column = 0, padx = 5,
391 sticky = 'news')
392 self.cmax = tkinter.StringVar(self)
393 self.cmax.set(calctype)
394 frame2max.cmax = ttk.OptionMenu(frame2max, self.cmax, calctype, *calctypes)
395 frame2max.cmax.grid(row = 3, column = 1, padx = 5, sticky = 'news')
396 ttk.Label(frame2max, text="Limit:", anchor = 'e',
397 style = 'normal.TLabel').grid(row = 4, column = 0, padx = 5,
398 sticky = 'news')
399 self.lmax = tkinter.StringVar(self)
400 self.lmax.set(limittype)
401 frame2max.lmax = ttk.OptionMenu(frame2max, self.lmax, limittype, *limittypes)
402 frame2max.lmax.grid(row = 4, column = 1, padx = 5, sticky = 'news')
403
404 dframe = frame3.canvas.dframe
405
406 ttk.Label(dframe, text="Conditions:", style = 'blue.TLabel',
407 anchor='w').grid(row = 0, column = 0, padx = 5, sticky = 'news', columnspan = 5)
408
409 # Add conditions
410
411 condtypes = ["VOLTAGE", "DIGITAL", "CURRENT", "RISETIME", "FALLTIME",
412 "RESISTANCE", "CAPACITANCE", "TEMPERATURE", "FREQUENCY",
413 "CORNER", "SIGMA", "ITERATIONS", "(none)"]
414
415 steptypes = ['linear', 'log', '(none)']
416
417 n = 0
418 r = 1
419 self.crec = []
420 self.cond = []
421 for cond in param['conditions']:
422 # If over 5 columns of conditions, create a new row.
423 if n >= 5:
424 r += 1
425 n = 0
426 # New column
427 frame3c = ttk.Frame(dframe, borderwidth = 2, relief='groove')
428 frame3c.grid(row = r, column = n, padx = 2, pady = 2, sticky = 'news')
429
430 crec = Condition(self)
431 # Condition description
432 ttk.Label(frame3c, text='Description:', style='normal.TLabel',
433 anchor='e').grid(row = 0, column = 0, padx = 5, sticky = 'news')
434 c1 = ttk.Entry(frame3c, textvariable = crec.display)
435 c1.grid(row = 0, column = 1, padx = 5, sticky = 'news')
436 c1.delete(0, 'end')
437 if 'display' in cond:
438 c1.insert(0, cond['display'])
439 else:
440 c1.insert(0, '(none)')
441 # Condition type (pulldown menu)
442 if 'condition' in cond:
443 crec.condition.set(cond['condition'])
444 else:
445 crec.condition.set('(none)')
446 ttk.Label(frame3c, text='Condition:', style='normal.TLabel',
447 anchor='e').grid(row = 1, column = 0, padx = 5, sticky = 'news')
448 c2 = ttk.OptionMenu(frame3c, crec.condition, crec.condition.get(), *condtypes)
449 c2.grid(row = 1, column = 1, padx = 5, sticky = 'news')
450 # Condition unit
451 ttk.Label(frame3c, text='Unit:', style='normal.TLabel',
452 anchor='e').grid(row = 3, column = 0, padx = 5, sticky = 'news')
453 c4 = ttk.Entry(frame3c, textvariable = crec.unit)
454 c4.grid(row = 3, column = 1, padx = 5, sticky = 'news')
455 c4.delete(0, 'end')
456 if 'unit' in cond:
457 c4.insert(0, cond['unit'])
458 else:
459 c4.insert(0, '(none)')
460 # Condition min
461 ttk.Label(frame3c, text='Minimum:', style='normal.TLabel',
462 anchor='e').grid(row = 4, column = 0, padx = 5, sticky = 'news')
463 c5 = ttk.Entry(frame3c, textvariable = crec.min)
464 c5.grid(row = 4, column = 1, padx = 5, sticky = 'news')
465 c5.delete(0, 'end')
466 if 'min' in cond:
467 c5.insert(0, cond['min'])
468 else:
469 c5.insert(0, '(none)')
470 # Condition typ
471 ttk.Label(frame3c, text='Typical:', style='normal.TLabel',
472 anchor='e').grid(row = 5, column = 0, padx = 5, sticky = 'news')
473 c6 = ttk.Entry(frame3c, textvariable = crec.typ)
474 c6.grid(row = 5, column = 1, padx = 5, sticky = 'news')
475 c6.delete(0, 'end')
476 if 'typ' in cond:
477 c6.insert(0, cond['typ'])
478 else:
479 c6.insert(0, '(none)')
480 # Condition max
481 ttk.Label(frame3c, text='Maximum:', style='normal.TLabel',
482 anchor='e').grid(row = 6, column = 0, padx = 5, sticky = 'news')
483 c7 = ttk.Entry(frame3c, textvariable = crec.max)
484 c7.grid(row = 6, column = 1, padx = 5, sticky = 'news')
485 c7.delete(0, 'end')
486 if 'max' in cond:
487 c7.insert(0, cond['max'])
488 else:
489 c7.insert(0, '(none)')
490 # Condition steptype
491 ttk.Label(frame3c, text='Step type:', style='normal.TLabel',
492 anchor='e').grid(row = 7, column = 0, padx = 5, sticky = 'news')
493 c8 = ttk.OptionMenu(frame3c, crec.steptype, crec.steptype.get(), *steptypes)
494 c8.grid(row = 7, column = 1, padx = 5, sticky = 'news')
495 if 'linstep' in cond:
496 crec.steptype.set('linear')
497 elif 'logstep' in cond:
498 crec.steptype.set('log')
499 else:
500 crec.steptype.set('(none)')
501 # Condition step
502 ttk.Label(frame3c, text='Step:', style='normal.TLabel',
503 anchor='e').grid(row = 8, column = 0, padx = 5, sticky = 'news')
504 c9 = ttk.Entry(frame3c, textvariable = crec.step)
505 c9.grid(row = 8, column = 1, padx = 5, sticky = 'news')
506 c9.delete(0, 'end')
507 if 'linstep' in cond:
508 c9.insert(0, cond['linstep'])
509 elif 'logstep' in cond:
510 c9.insert(0, cond['logstep'])
511 else:
512 c9.insert(0, '(none)')
513
514 n += 1
515 self.cond.append(crec)
516 # Condition remove
517 c10 = ttk.Button(frame3c, text='Remove', style='normal.TButton',
518 command = lambda cond=cond: self.remove_condition(cond))
519 c10.grid(row = 9, column = 1, padx = 5, sticky = 'news')
520
521 # Add 'add condition' button
522 dframe.bcond = ttk.Button(dframe, text="Add Condition",
523 style = 'blue.TButton', command = self.add_condition)
524 if n >= 5:
525 dframe.bcond.grid(row = r + 1, column = 0, padx = 5, pady = 3, sticky = 'nsw')
526 else:
527 dframe.bcond.grid(row = r, column = n, padx = 5, pady = 3, sticky = 'new')
528
529 # Set the current parameter
530 self.param = param
531
532 def on_mousewheel(self, event):
533 if event.num == 5:
534 self.canvas.yview_scroll(1, "units")
535 elif event.num == 4:
536 self.canvas.yview_scroll(-1, "units")
537
538 def frame_configure(self, event):
539 self.update_idletasks()
540 self.canvas.configure(scrollregion=self.canvas.bbox("all"))
541
542 def add_condition(self):
543 # Add a new condition
544 newcond = {}
545 newcond['condition'] = '(none)'
546 self.param['conditions'].append(newcond)
547 self.populate(self.param)
548
549 def remove_condition(self, cond):
550 # Remove and existing condition
551 condlist = self.param['conditions']
552 eidx = condlist.index(cond)
553 condlist.pop(eidx)
554 self.populate(self.param)
555
556 def apply(self):
557 # Apply the values back to the parameter record
558 self.param['method'] = self.selmethod.get()
559 unit = self.unit.get()
560 if not (unit == '(none)' or unit == ''):
561 self.param['unit'] = unit
562 display = self.display.get()
563 if not (display == '(none)' or display == ''):
564 self.param['display'] = display
565 targmin = self.minrec.target.get()
566 if not (targmin == '(none)' or targmin == ''):
567 pmin = {}
568 pmin['target'] = targmin
569 pmin['penalty'] = self.minrec.penalty.get()
570 cmin = self.minrec.calc.get()
571 if not (cmin == '(none)' or cmin == ''):
572 lmin = self.minrec.limit.get()
573 if not (lmin == '(none)' or lmin == ''):
574 pmin['calc'] = cmin + '-' + lmin
575 else:
576 pmin['calc'] = cmin
577 self.param['min'] = pmin
578 targtyp = self.typrec.target.get()
579 if not (targtyp == '(none)' or targtyp == ''):
580 ptyp= {}
581 ptyp['target'] = targtyp
582 ptyp['penalty'] = self.typrec.penalty.get()
583 ctyp = self.typrec.calc.get()
584 if not (ctyp == '(none)' or ctyp == ''):
585 ltyp = self.typrec.limit.get()
586 if not (ltyp == '(none)' or ltyp == ''):
587 ptyp['calc'] = ctyp + '-' + ltyp
588 else:
589 ptyp['calc'] = ctyp
590 self.param['typ'] = ptyp
591 targmax = self.maxrec.target.get()
592 if not (targmax == '(none)' or targmax == ''):
593 pmax= {}
594 pmax['target'] = targmax
595 pmax['penalty'] = self.maxrec.penalty.get()
596 cmax = self.maxrec.calc.get()
597 if not (cmax == '(none)' or cmax == ''):
598 lmax = self.maxrec.limit.get()
599 if not (lmax == '(none)' or lmax == ''):
600 pmax['calc'] = cmax + '-' + lmax
601 else:
602 pmax['calc'] = cmax
603 self.param['max'] = pmax
604
605 condlist = []
606 for crec in self.cond:
607 cond = {}
608 cname = crec.condition.get()
609 if cname == '(none)' or cname == '':
610 continue
611 cond['condition'] = cname
612 display = crec.display.get()
613 if not (display == '(none)' or display == ''):
614 cond['display'] = display
615 min = crec.min.get()
616 if not (min == '(none)' or min == ''):
617 cond['min'] = min
618 typ = crec.typ.get()
619 if not (typ == '(none)' or typ == ''):
620 cond['typ'] = typ
621 max = crec.max.get()
622 if not (max == '(none)' or max == ''):
623 cond['max'] = max
624 unit = crec.unit.get()
625 if not (unit == '(none)' or unit == ''):
626 cond['unit'] = unit
627 steptype = crec.steptype.get()
628 step = crec.step.get()
629 if not (step == '(none)' or step == ''):
630 if steptype == 'linear':
631 cond['linstep'] = step
632 elif steptype == 'log':
633 cond['logstep'] = step
634 condlist.append(cond)
635 self.param['conditions'] = condlist
636
637 self.parent.create_datasheet_view()
638 return
639
640 def close(self):
641 # pop down settings window
642 self.withdraw()
643
644 def open(self):
645 # pop up settings window
646 self.deiconify()
647 self.lift()