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

Contents of /trunk/pygtk/diagnose.py

Parent Directory Parent Directory | Revision Log Revision Log


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

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