/[ascend]/trunk/pygtk/diagnose.py
ViewVC logotype

Contents of /trunk/pygtk/diagnose.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 455 - (show annotations) (download) (as text)
Wed Apr 5 07:50:22 2006 UTC (13 years, 3 months ago) by johnpye
Original Path: trunk/pygtk/interface/diagnose.py
File MIME type: text/x-python
File size: 10822 byte(s)
Tidying up some debug output
Fixing up use of icon filenames on Windows
Removing reference to .svg file in glade/ascend.glade
1 import gtk
2 import gtk.glade
3 import ascend
4 from itertools import groupby
5 from operator import itemgetter
6 import math
7 import re
8
9 import config
10
11 ZOOM_RE = re.compile(r"([0-9]+)\s*%?")
12 MAX_ZOOM_SIZE = 2000
13 MAX_ZOOM_RATIO = 16
14 AT_BOUND_TOL = 0.0001;
15
16 class DiagnoseWindow:
17 def __init__(self,browser,block=0):
18 self.browser=browser
19 _xml = gtk.glade.XML(browser.glade_file,"diagnosewin")
20 _xml.signal_autoconnect(self)
21
22 self.window = _xml.get_widget("diagnosewin")
23 self.window.set_transient_for(self.browser.window)
24
25 _icon = gtk.Image()
26 _iconpath = browser.assets_dir+'diagnose'+config.ICON_EXTENSION
27 _icon.set_from_file(_iconpath)
28 self.window.set_icon(_icon)
29
30 self.imagescroll = _xml.get_widget("imagescroll")
31 self.image = _xml.get_widget("image")
32 self.blockentry = _xml.get_widget("blockentry")
33 self.zoomentry = _xml.get_widget("zoomentry")
34
35 self.varname = _xml.get_widget("varname");
36 self.varval = _xml.get_widget("varval");
37 self.relname = _xml.get_widget("relname");
38 self.relresid = _xml.get_widget("relresid");
39
40 self.varview = _xml.get_widget("varview")
41 self.varbuf = gtk.TextBuffer()
42 self.varview.set_buffer(self.varbuf)
43 self.varcollapsed = _xml.get_widget("varcollapsed")
44 self.relview = _xml.get_widget("relview")
45 self.relcollapsed = _xml.get_widget("relcollapsed")
46 self.relvalues = _xml.get_widget("relvalues")
47 self.rellabels = _xml.get_widget("rellabels")
48 self.relrels = _xml.get_widget("relrels")
49 self.relresids = _xml.get_widget("relresids")
50 self.relbuf = gtk.TextBuffer()
51 self.relview.set_buffer(self.relbuf)
52
53 self.im = None
54 self.block = 0
55 self.apply_prefs()
56
57 self.prepare_data()
58 self.fill_values(block) # block zero
59
60 def run(self):
61 self.window.run()
62 self.window.hide()
63
64 def apply_prefs(self):
65 vc = self.browser.prefs.getBoolPref("Diagnose","varcollapsed",True)
66
67 print "VARCOLLAPSED =",vc
68 self.varcollapsed.set_active(vc)
69 self.relcollapsed.set_active(self.browser.prefs.getBoolPref("Diagnose","relcollapsed",True))
70
71 def prepare_data(self):
72 # convert incidence map to pylab numarray type:
73 print "PREPARING DATA"
74 self.im = self.browser.sim.getIncidenceMatrix()
75 self.data = self.im.getIncidenceData()
76 print "DATA LOADED"
77
78 self.zoom=1;
79
80 def fill_values(self, block):
81
82 try:
83 rl,cl,rh,ch = self.im.getBlockLocation(block)
84 except IndexError:
85 if block >= self.im.getNumBlocks():
86 block = self.im.getNumBlocks() - 1
87 rl,cl,rh,ch = self.im.getBlockLocation(block)
88 else:
89 print "BLOCK INDEX ERROR: block =",block
90 self.blockentry.set_text(str(self.block))
91 return
92 except RuntimeError,e:
93 print "ERROR GETTING BLOCK LOCATION:",str(e)
94 self.blockentry.set_text(str(self.block))
95 return
96
97 self.block = block
98 self.blockentry.set_text(str(block))
99
100 self.rl = rl
101 self.cl = cl
102 self.rh = rh
103 self.ch = ch
104
105 nr = int(rh-rl+1);
106 nc = int(ch-cl+1);
107
108 #print "STARTING IMAGE CREATION"
109 # refer http://pygtk.org/pygtk2tutorial/sec-DrawingMethods.html
110 c = chr(255)
111 b = nr*nc*3*[c]
112 rowstride = 3 * nc
113
114 blackdot = [chr(0)]*3;
115 reddot = [chr(255), chr(0), chr(0)]
116 pinkdot = [chr(255), chr(127), chr(127)]
117 skydot = [chr(127), chr(127), chr(255)]
118 bluedot = [chr(0), chr(0), chr(255)]
119 hotpinkdot = [chr(255), chr(47), chr(179)] # very big (+/-)
120 brightbluedot = [chr(71), chr(157), chr(255)] # very small (+/-)
121 greendot = [chr(87), chr(193), chr(70)] # close to 1
122 orangedot = [chr(255), chr(207), chr(61)] # 10-1000
123 bluegreendot = [chr(70), chr(221), chr(181)] # 0.001 - 0.1
124 for i in self.data:
125 if i.row < rl or i.row > rh or i.col < cl or i.col > ch:
126 continue
127 r = i.row - rl;
128 c = i.col - cl;
129 pos = rowstride*r + 3*c
130 dot = blackdot;
131 var = self.im.getVariable(i.col);
132 if abs( (var.getValue()-var.getUpperBound())/ var.getNominal() ) < AT_BOUND_TOL:
133 dot = reddot
134 elif abs( var.getValue() - var.getLowerBound() ) / var.getNominal() < AT_BOUND_TOL:
135 dot = reddot
136 else:
137 rat = var.getValue() / var.getNominal()
138 if rat!=0:
139 try:
140 val = abs(rat)
141 if abs(rat) > 1000:
142 dot = hotpinkdot
143 elif abs(rat) > 10:
144 dot = orangedot
145 elif abs(rat) < 0.001:
146 dot = brightbluedot
147 elif abs(rat) < 10 and abs(rat) > 0.1:
148 dot = greendot
149 elif abs(rat) > 0.001 and abs(rat) < 0.1:
150 dot = bluegreendot
151 else:
152 dot = blackdot
153 except ValueError, e:
154 pass
155 #print "DOT: ",dot
156 b[pos], b[pos+1], b[pos+2] = dot
157
158 d = ''.join(b)
159
160 #print "DONE IMAGE CREATION"
161
162 self.pixbuf = gtk.gdk.pixbuf_new_from_data(d, gtk.gdk.COLORSPACE_RGB, False, 8 \
163 , nc, nr, rowstride);
164
165 self.nr = nr
166 self.nc = nc
167 self.zoom = -1 # to fit, up to max 16x
168 self.do_zoom()
169
170 #print "DONE IMAGE TRANSFER TO SERVER"
171
172 self.fill_var_names()
173 self.fill_rel_names()
174
175 self.varname.set_text("");
176 self.varval.set_text("");
177 self.relname.set_text("");
178 self.relresid.set_text("");
179
180
181 def do_zoom(self):
182 if self.zoom == -1:
183 w, h = self.imagescroll.size_request()
184 #print "SCALE TO FIX, w=%d, h=%d" % (w,h)
185 if self.nc/self.nr > w/h:
186 # a 'wide' image
187 self.zoom = w / self.nc
188 else:
189 self.zoom = h / self.nr
190
191 if self.zoom > MAX_ZOOM_RATIO:
192 self.zoom = MAX_ZOOM_RATIO
193
194 if self.zoom * self.nc > MAX_ZOOM_SIZE or self.zoom * self.nr > MAX_ZOOM_SIZE:
195 self.zoom = MAX_ZOOM_SIZE / max(self.nc,self.nr)
196
197 w = int(self.zoom * self.nc);
198 h = int(self.zoom * self.nr);
199
200 self.zoomentry.set_text("%d %%" % (int(self.zoom*100)) )
201
202 if self.zoom < 2:
203 pb1 = self.pixbuf.scale_simple(w,h,gtk.gdk.INTERP_BILINEAR)
204 else:
205 pb1 = self.pixbuf.scale_simple(w,h,gtk.gdk.INTERP_NEAREST)
206
207 self.image.set_from_pixbuf(pb1)
208
209 def fill_var_names(self):
210 names = [str(i) for i in self.im.getBlockVars(self.block)]
211 if self.varcollapsed.get_active():
212 res = reduce(names)
213 rows = []
214 for k in res:
215 if k=="":
216 for r in res[k]:
217 rows.append(r)
218 else:
219 rows.append( '%s:\n\t%s' % (k, "\n\t".join(res[k])) )
220 text = "\n".join(rows)
221 else:
222 text = "\n".join(names)
223 self.varbuf.set_text(text)
224
225 def fill_rel_names(self):
226 names = [str(i) for i in self.im.getBlockRels(self.block)]
227 if self.relcollapsed.get_active():
228 res = reduce(names)
229 rows = []
230 for k in res:
231 if k=="":
232 for r in res[k]:
233 rows.append(r)
234 else:
235 rows.append( '%s:\n\t%s' % (k, "\n\t".join(res[k])) )
236 text = "\n".join(rows)
237 else:
238 text = "\n".join(names)
239 self.relbuf.set_text(text)
240
241 def set_block(self, block):
242 self.fill_values(block)
243
244 def set_zoom(self,zoom):
245 self.zoom = zoom
246 self.do_zoom()
247
248 def show_cursor(self,x,y):
249 c = self.cl + int(x/self.zoom)
250 r = self.rl + int(y / self.zoom)
251 if c > self.ch or r > self.rh:
252 #print "OUT OF RANGE"
253 return
254 var = self.im.getVariable(c)
255 self.varname.set_text(var.getName())
256 self.varval.set_text(str(var.getValue()))
257 rel = self.im.getRelation(r)
258 self.relname.set_text(rel.getName())
259 self.relresid.set_text(str(rel.getResidual()))
260
261 # GUI EVENT HOOKS-----------------------------------------------------------
262
263 def on_varcollapsed_toggled(self,*args):
264 vc = self.varcollapsed.get_active()
265 self.browser.prefs.setBoolPref("Diagnose","varcollapsed",vc)
266 if self.im:
267 self.fill_var_names()
268
269 def on_relcollapsed_toggled(self,*args):
270 rc = self.varcollapsed.get_active()
271 self.browser.prefs.setBoolPref("Diagnose","relcollapsed",rc)
272 if self.im:
273 self.fill_rel_names()
274
275 def on_nextbutton_clicked(self,*args):
276 self.set_block(self.block + 1)
277
278 def on_prevbutton_clicked(self,*args):
279 self.set_block(self.block - 1)
280
281 def on_prevbigbutton_clicked(self,*args):
282 b = self.block - 1
283 while b >= 0:
284 rl,cl,rh,ch = self.im.getBlockLocation(b)
285 if rh-rl > 0 or ch-cl>0:
286 self.set_block(b)
287 b = b - 1
288 print "NO PRECEDING 'BIG' BLOCKS"
289
290 def on_nextbigbutton_clicked(self,*args):
291 b = self.block + 1
292 n = self.im.getNumBlocks()
293 while b < n:
294 rl,cl,rh,ch = self.im.getBlockLocation(b)
295 if rh-rl > 0 or ch-cl>0:
296 self.set_block(b)
297 b = b + 1
298 print "NO FOLLOWING 'BIG' BLOCKS"
299
300 def on_blockentry_key_press_event(self,widget,event):
301 keyname = gtk.gdk.keyval_name(event.keyval)
302 print "KEY ",keyname
303 if keyname=="Return":
304 self.set_block( int(self.blockentry.get_text()) )
305
306 def on_zoominbutton_clicked(self,*args):
307 z = int( math.log(self.zoom)/math.log(2) )
308 z = pow(2,z + 1);
309 self.set_zoom(z)
310
311 def on_zoomoutbutton_clicked(self,*args):
312 z = int( math.log(self.zoom)/math.log(2) + 0.999)
313 z = pow(2,z - 1);
314 self.set_zoom(z)
315
316 def on_zoomentry_key_press_event(self,widget,event):
317 keyname = gtk.gdk.keyval_name(event.keyval)
318 print "KEY ",keyname
319 if keyname=="Return":
320 t = self.zoomentry.get_text()
321 m = ZOOM_RE.match(t)
322 if not m:
323 self.zoomentry.set_text("%d %%" % int(self.zoom*100))
324 for mm in m:
325 print m
326 self.set_zoom( int(self.zoomentry.get_text()) )
327
328 def on_imageevent_motion_notify_event(self,widget,event):
329 self.show_cursor(event.x, event.y)
330
331 def on_imageevent_button_press_event(self,widget,event):
332 self.show_cursor(event.x, event.y)
333
334
335 # The following is from
336 # http://www.experts-exchange.com/Programming/Programming_Languages/Python/Q_21719649.html
337 # it's still buggy.
338
339 def fold(data):
340 """ fold sorted numeric sequence data into ranged representation:
341 >>> fold([1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28])
342 '[1,4-6,10,15-18,22,25-28]'
343 """
344 folded = []
345 for k, g in groupby(enumerate(sorted(data)), lambda (i,x):i-x):
346 seq = map(itemgetter(1), g)
347 if len(seq) > 1:
348 x = '%s-%s' % (seq[0], seq[-1])
349 else:
350 x = str(seq[0])
351 folded.append(x)
352 return folded and '[%s]' % ','.join(folded) or ''
353
354 def reduce(names):
355 """reduce a list of items nto something more readable:
356 >>> data = 'C.x C.p C.T C.delta[1] C.delta[2] C.delta[3] C.sat.x C.sat.p C.h C.delta[5]'.split()
357 >>> res = reduce(data)
358 >>> for k in sorted(res):
359 ... print '%s: %s' % (k, res[k])
360 C: T, delta[1-3,5], h, p, x
361 C.sat: p, x
362 """
363 data = sorted([n.split('.') for n in sorted(names)], key=len)
364 res = {}
365 for k, g in groupby(data, lambda x: len(x)):
366 if k == 1:
367 indexed = {}
368 seq = set(get(indexed, item) for item in g)
369 res['[global]'] = [ i+fold(indexed.get(i, [])) for i in sorted(seq) ]
370 else:
371 for key, g1 in groupby(g, lambda x: '.'.join(x[:-1])):
372 indexed = {}
373 seq = set(get(indexed, item) for item in g1)
374 res[key] = [ i+fold(indexed.get(i, [])) for i in sorted(seq) ]
375 return res
376
377 def get(indexed, item):
378 item = item[-1]
379 if item.endswith(']'):
380 item, idx = item[:-1].split('[')
381 indexed.setdefault(item, []).append(int(idx))
382 return item

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22