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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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