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

Contents of /trunk/pygtk/interface/diagnose.py

Parent Directory Parent Directory | Revision Log Revision Log


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

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