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

Diff of /trunk/pygtk/diagnose.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

trunk/interface/diagnose.py revision 531 by johnpye, Mon Apr 24 02:04:02 2006 UTC trunk/pygtk/diagnose.py revision 3181 by jpye, Tue Feb 7 05:11:24 2017 UTC
# Line 1  Line 1 
 import gtk  
 import gtk.glade  
1  import ascpy  import ascpy
2  from itertools import groupby  from itertools import groupby
3  from operator import itemgetter  from operator import itemgetter
# Line 7  import math Line 5  import math
5  import re  import re
6    
7  import config  import config
8    from infodialog import *
9    from preferences import *
10    
11  ZOOM_RE = re.compile(r"([0-9]+)\s*%?")  ZOOM_RE = re.compile(r"([0-9]+)\s*%?")
12  MAX_ZOOM_SIZE = 2000  MAX_ZOOM_SIZE = float(2000) # float
13  MAX_ZOOM_RATIO = 16  MAX_ZOOM_RATIO = float(16) # float
14  AT_BOUND_TOL = 0.0001;  AT_BOUND_TOL = 0.0001;
15    
16  class DiagnoseWindow:  class DiagnoseWindow:
17      def __init__(self,browser,block=0):      def __init__(self,browser,block=0):
18            import gtk
19          self.browser=browser          self.browser=browser
20          _xml = gtk.glade.XML(browser.glade_file,"diagnosewin")          self.browser.builder.add_objects_from_file(self.browser.glade_file, ["diagnosewin"])
21          _xml.signal_autoconnect(self)            self.browser.builder.connect_signals(self)
22            self.window = self.browser.builder.get_object("diagnosewin")
23          self.window = _xml.get_widget("diagnosewin")          self.window.grab_focus()
24          self.window.set_transient_for(self.browser.window)          self.window.set_transient_for(self.browser.window)
25    
26          _icon = gtk.Image()          self.prefs = Preferences()
27          _iconpath = browser.assets_dir+'diagnose'+config.ICON_EXTENSION  
28          _icon.set_from_file(_iconpath)          try:
29          self.window.set_icon(_icon)              _icon = gtk.Image()
30                _iconpath = browser.assets_dir+'diagnose'+config.ICON_EXTENSION
31                print "ICON PATH =",_iconpath
32                _icon.set_from_file(_iconpath)
33                print "ICON = ",_icon
34                self.window.set_icon(_icon)
35            except:
36                pass
37                    
38          self.imagescroll = _xml.get_widget("imagescroll")          self.blockstatus = self.browser.builder.get_object("blockstatustext")
         self.image = _xml.get_widget("image")  
         self.blockentry = _xml.get_widget("blockentry")  
         self.zoomentry = _xml.get_widget("zoomentry")  
   
         self.varname = _xml.get_widget("varname");  
         self.varval = _xml.get_widget("varval");  
         self.relname = _xml.get_widget("relname");  
         self.relresid = _xml.get_widget("relresid");  
39    
40          self.varview = _xml.get_widget("varview")          self.imagescroll = self.browser.builder.get_object("imagescroll")
41            self.image = self.browser.builder.get_object("image")
42            self.blockentry = self.browser.builder.get_object("blockentry")
43            self.zoomentry = self.browser.builder.get_object("zoomentry")
44    
45            self.var = None; self.rel = None
46            self.varname = self.browser.builder.get_object("varname1")
47            self.varval = self.browser.builder.get_object("varval")
48            self.varinfobutton = self.browser.builder.get_object("varinfobutton")
49            self.relname = self.browser.builder.get_object("relname1")
50            self.relresid = self.browser.builder.get_object("relresid")
51            self.relinfobutton = self.browser.builder.get_object("relinfobutton")
52            self.preferred_units_check = self.browser.builder.get_object("preferred_units_check")
53            if self.prefs.getBoolPref("Diagnose","show_preferred_units")==True:
54                self.preferred_units_check.set_active(True)
55            else:
56                self.preferred_units_check.set_active(False)
57    
58            self.varview = self.browser.builder.get_object("varview")
59          self.varbuf = gtk.TextBuffer()          self.varbuf = gtk.TextBuffer()
60          self.varview.set_buffer(self.varbuf)          self.varview.set_buffer(self.varbuf)
61          self.varcollapsed = _xml.get_widget("varcollapsed")          self.varcollapsed = self.browser.builder.get_object("varcollapsed")
62          self.relview = _xml.get_widget("relview")            self.relview = self.browser.builder.get_object("relview")  
63          self.relcollapsed = _xml.get_widget("relcollapsed")          self.relcollapsed = self.browser.builder.get_object("relcollapsed")
64          self.relvalues = _xml.get_widget("relvalues")          self.relvalues = self.browser.builder.get_object("relvalues")
65          self.rellabels = _xml.get_widget("rellabels")          self.rellabels = self.browser.builder.get_object("rellabels")
66          self.relrels = _xml.get_widget("relrels")          self.relrels = self.browser.builder.get_object("relrels")
67          self.relresids = _xml.get_widget("relresids")          self.relresids = self.browser.builder.get_object("relresids")
68          self.relbuf = gtk.TextBuffer()          self.relbuf = gtk.TextBuffer()
69          self.relview.set_buffer(self.relbuf)          self.relview.set_buffer(self.relbuf)
   
70          self.im = None          self.im = None
71          self.block = 0          self.block = 0
72          self.apply_prefs()          self.apply_prefs()
# Line 70  class DiagnoseWindow: Line 87  class DiagnoseWindow:
87    
88      def prepare_data(self):      def prepare_data(self):
89          # convert incidence map to pylab numarray type:          # convert incidence map to pylab numarray type:
90          print "PREPARING DATA"          print "PREPARING DATA to be loaded"
91          self.im = self.browser.sim.getIncidenceMatrix()          self.im = self.browser.sim.getIncidenceMatrix()
92          self.data = self.im.getIncidenceData()          self.data = self.im.getIncidenceData()
93          print "DATA LOADED"          print "DATA LOADED"
# Line 80  class DiagnoseWindow: Line 97  class DiagnoseWindow:
97      def fill_values(self, block):      def fill_values(self, block):
98                    
99          try:          try:
100                if self.im.getNumBlocks()==0:
101                    print "NO BLOCKS!"
102                    self.image.set_from_stock(gtk.STOCK_DIALOG_ERROR
103                        ,gtk.ICON_SIZE_DIALOG
104                    )
105                    self.browser.reporter.reportError(
106                        "Can't 'Diagnose blocks' until solver has been used."
107                    )
108                    return;
109              rl,cl,rh,ch = self.im.getBlockLocation(block)              rl,cl,rh,ch = self.im.getBlockLocation(block)
110          except IndexError:          except IndexError:
111              if block >= self.im.getNumBlocks():              if block >= self.im.getNumBlocks():
# Line 105  class DiagnoseWindow: Line 131  class DiagnoseWindow:
131          nr = int(rh-rl+1);          nr = int(rh-rl+1);
132          nc = int(ch-cl+1);          nc = int(ch-cl+1);
133    
134          #print "STARTING IMAGE CREATION"          print "STARTING IMAGE CREATION"
135          # refer http://pygtk.org/pygtk2tutorial/sec-DrawingMethods.html          # refer http://pygtk.org/pygtk2tutorial/sec-DrawingMethods.html
136          c = chr(255)          c = chr(255)
137          b = nr*nc*3*[c]          b = nr*nc*3*[c]
# Line 157  class DiagnoseWindow: Line 183  class DiagnoseWindow:
183    
184          d = ''.join(b)          d = ''.join(b)
185    
186          #print "DONE IMAGE CREATION"          print "DONE IMAGE CREATION"
187            
188          self.pixbuf = gtk.gdk.pixbuf_new_from_data(d, gtk.gdk.COLORSPACE_RGB, False, 8 \          self.pixbuf = gtk.gdk.pixbuf_new_from_data(d, gtk.gdk.COLORSPACE_RGB, False, 8 \
189                  , nc, nr, rowstride);                  , nc, nr, rowstride);
# Line 167  class DiagnoseWindow: Line 193  class DiagnoseWindow:
193          self.zoom = -1 # to fit, up to max 16x          self.zoom = -1 # to fit, up to max 16x
194          self.do_zoom()          self.do_zoom()
195    
196          #print "DONE IMAGE TRANSFER TO SERVER"          print "DONE IMAGE TRANSFER TO SERVER"
197    
198          self.fill_var_names()          self.fill_var_names()
199          self.fill_rel_names()          self.fill_rel_names()
200            self.fill_block_status()
201            
202          self.varname.set_text("");          self.fill_selection_info()
         self.varval.set_text("");  
         self.relname.set_text("");  
         self.relresid.set_text("");  
203    
204            print "DONE FILL VALUES"
205    
206        def fill_selection_info(self):
207            if self.var:
208                self.varname.set_text(self.var.getName())
209                default_units = self.var.getInstance().getType().getDimensions().getDefaultUnits().getName().toString()
210                pref_units = self.var.getInstance().getType().getPreferredUnits()
211                if pref_units and self.prefs.getBoolPref("Diagnose","show_preferred_units",True):
212                    varval = str(self.var.getValue())+" "+pref_units.getName().toString()
213                else:
214                    if default_units=="?":
215                        varval = str(self.var.getValue())
216                    else:
217                        varval = str(self.var.getValue())+" "+default_units
218                self.varval.set_text(varval)
219                self.varinfobutton.set_sensitive(True)
220            else:
221                self.varname.set_text("")
222                self.varval.set_text("")
223                self.varinfobutton.set_sensitive(False)
224    
225            if self.rel:
226                self.relname.set_text(self.rel.getName())
227                self.relresid.set_text(str(self.rel.getResidual()))
228                self.relinfobutton.set_sensitive(True)
229            else:
230                self.relname.set_text("")
231                self.relresid.set_text("")
232                self.relinfobutton.set_sensitive(False)
233    
234      def do_zoom(self):      def do_zoom(self):
235          if self.zoom == -1:          if self.zoom == -1:
# Line 184  class DiagnoseWindow: Line 237  class DiagnoseWindow:
237              #print "SCALE TO FIX, w=%d, h=%d" % (w,h)              #print "SCALE TO FIX, w=%d, h=%d" % (w,h)
238              if self.nc/self.nr > w/h:              if self.nc/self.nr > w/h:
239                  # a 'wide' image                      # a 'wide' image    
240                  self.zoom = w / self.nc                  self.zoom = float(w) / self.nc
241              else:              else:
242                  self.zoom = h / self.nr                  self.zoom = float(h) / self.nr
243    
244            #self.browser.reporter.reportNote("Diagnose window: preliminary calculated zoom = %f (nr = %d, nc = %d)" % (self.zoom, self.nr, self.nc))
245            
246    
247          if self.zoom > MAX_ZOOM_RATIO:          if self.zoom > MAX_ZOOM_RATIO:
248              self.zoom = MAX_ZOOM_RATIO              self.zoom = MAX_ZOOM_RATIO
249    
250          if self.zoom * self.nc > MAX_ZOOM_SIZE or self.zoom * self.nr > MAX_ZOOM_SIZE:          if self.zoom * self.nc > MAX_ZOOM_SIZE or self.zoom * self.nr > MAX_ZOOM_SIZE:
251                self.browser.reporter.reportNote("image is too big, reducing to MAX_ZOOM_SIZE = %f" % MAX_ZOOM_SIZE);
252              self.zoom = MAX_ZOOM_SIZE / max(self.nc,self.nr)              self.zoom = MAX_ZOOM_SIZE / max(self.nc,self.nr)
253    
254            #self.browser.reporter.reportNote("Diagnose window: matrix zoom = %f" % self.zoom)
255          w = int(self.zoom * self.nc);          w = int(self.zoom * self.nc);
256          h = int(self.zoom * self.nr);          h = int(self.zoom * self.nr);
257                            
# Line 206  class DiagnoseWindow: Line 264  class DiagnoseWindow:
264                    
265          self.image.set_from_pixbuf(pb1)          self.image.set_from_pixbuf(pb1)
266    
267        def fill_block_status(self):
268            print "FILL BLOCK STATUS"
269            s = self.im.getBlockStatus(self.block)
270            ss = "Failed"
271            if s == ascpy.IM_CONVERGED:
272                ss = "Converged"
273            elif s == ascpy.IM_NOT_YET_ATTEMPTED:
274                ss = "Not attempted yet"
275            elif s == ascpy.IM_OVER_TIME:
276                ss += " (time limit)"
277            elif s == ascpy.IM_OVER_ITER:
278                ss += " (iter limit)"
279            self.blockstatus.set_text(ss);
280            
281    
282      def fill_var_names(self):      def fill_var_names(self):
283            print "FILL VAR NAMES"
284    
285          names = [str(i) for i in self.im.getBlockVars(self.block)]          names = [str(i) for i in self.im.getBlockVars(self.block)]
286    
287            #print "NAMES:",names
288    
289          if self.varcollapsed.get_active():          if self.varcollapsed.get_active():
290              res = reduce(names)              res = reduce(names)
291              rows = []              rows = []
# Line 222  class DiagnoseWindow: Line 300  class DiagnoseWindow:
300              text = "\n".join(names)              text = "\n".join(names)
301          self.varbuf.set_text(text)          self.varbuf.set_text(text)
302    
303            print "DONE VAR NAMES"
304    
305      def fill_rel_names(self):      def fill_rel_names(self):
306          names = [str(i) for i in self.im.getBlockRels(self.block)]          print "REL NAMES"
307    
308            rels = self.im.getBlockRels(self.block)
309    
310            print "GOT RELS, NOW GETTING NAMES"
311    
312            names = [str(i) for i in rels]
313    
314            #print "NAMES =",names
315    
316          if self.relcollapsed.get_active():          if self.relcollapsed.get_active():
317              res = reduce(names)              res = reduce(names)
318              rows = []              rows = []
# Line 238  class DiagnoseWindow: Line 327  class DiagnoseWindow:
327              text = "\n".join(names)              text = "\n".join(names)
328          self.relbuf.set_text(text)          self.relbuf.set_text(text)
329    
330            print "DONE REL NAMES"
331    
332      def set_block(self, block):      def set_block(self, block):
333          self.fill_values(block)          self.fill_values(block)
334    
# Line 251  class DiagnoseWindow: Line 342  class DiagnoseWindow:
342          if c > self.ch or r > self.rh:          if c > self.ch or r > self.rh:
343              #print "OUT OF RANGE"              #print "OUT OF RANGE"
344              return              return
345          var = self.im.getVariable(c)          self.var = self.im.getVariable(c)
346          self.varname.set_text(var.getName())          self.rel = self.im.getRelation(r)
347          self.varval.set_text(str(var.getValue()))          self.fill_selection_info()
         rel = self.im.getRelation(r)  
         self.relname.set_text(rel.getName())  
         self.relresid.set_text(str(rel.getResidual()))  
348    
349      # GUI EVENT HOOKS-----------------------------------------------------------      # GUI EVENT HOOKS-----------------------------------------------------------
350    
351        def on_diagnosewin_close(self,*args):
352            self.window.response(gtk.RESPONSE_CLOSE);
353    
354        def on_preferred_units_toggle(self,widget):
355            _v = widget.get_active()
356            self.prefs.setBoolPref("Diagnose","show_preferred_units",_v)
357            self.fill_selection_info()
358    
359        # incidence data view
360    
361      def on_varcollapsed_toggled(self,*args):      def on_varcollapsed_toggled(self,*args):
362          vc = self.varcollapsed.get_active()          vc = self.varcollapsed.get_active()
363          self.browser.prefs.setBoolPref("Diagnose","varcollapsed",vc)              self.browser.prefs.setBoolPref("Diagnose","varcollapsed",vc)    
# Line 272  class DiagnoseWindow: Line 370  class DiagnoseWindow:
370          if self.im:          if self.im:
371              self.fill_rel_names()              self.fill_rel_names()
372    
373        # detailed information about vars and rels (solver-side information!)
374    
375        def on_varinfobutton_clicked(self,*args):
376            title = "Variable '%s'" % self.var
377            text = "%s\n%s\n" % (title,"(from the solver's view)")
378            units = " "
379            default_units = self.var.getInstance().getType().getDimensions().getDefaultUnits().getName().toString()
380            pref_units = self.var.getInstance().getType().getPreferredUnits()
381            if pref_units and self.prefs.getBoolPref("Diagnose","show_preferred_units",True):
382                units += pref_units.getName().toString()
383            else:
384                if default_units!="?":
385                    units += default_units
386            _rows = {
387                "Value": self.var.getValue()
388                ,"Nominal": self.var.getNominal()
389                ,"Lower bound": self.var.getLowerBound()
390                ,"Upper bound": self.var.getUpperBound()
391            }
392            for k,v in _rows.iteritems():
393                text += "\n  %s\t%s" % (k,value_human(v)+units)
394            
395            text += "\n\nIncident with %d relations:" % self.var.getNumIncidentRelations()
396            for r in self.var.getIncidentRelations():
397                text += "\n  %s" % r.getName()
398    
399            _dialog = InfoDialog(self.browser,self.window,text,title,tabs=(150,300))
400            _dialog.run()
401    
402        def on_relinfobutton_clicked(self,*args):
403            title = "Relation '%s'" % self.rel
404            text = "%s\n%s\n" % (title,"(from the solver's view)")
405            text += "\n  %s\t%15f" % ("Residual", self.rel.getResidual())
406    
407            text += "\n\nRelation expression:\n"
408            text += self.rel.getRelationAsString()
409    
410            text += "\n\nIncident with %d variables:" % self.rel.getNumIncidentVariables()
411            for v in self.rel.getIncidentVariables():
412                units = " "
413                default_units = v.getInstance().getType().getDimensions().getDefaultUnits().getName().toString()
414                pref_units = v.getInstance().getType().getPreferredUnits()
415                if pref_units and self.prefs.getBoolPref("Diagnose","show_preferred_units",True):
416                    units += pref_units.getName().toString()
417                else:
418                    if default_units != "?" :
419                        units += default_units
420                text += "\n  %s\t= %s" % ( v.getName(),value_human(v.getValue())+units )
421    
422            _dialog = InfoDialog(self.browser,self.window,text,title,tabs=(150,300))
423            _dialog.run()
424            
425    
426        # block navigation
427    
428      def on_nextbutton_clicked(self,*args):      def on_nextbutton_clicked(self,*args):
429          self.set_block(self.block + 1)          self.set_block(self.block + 1)
430    
# Line 284  class DiagnoseWindow: Line 437  class DiagnoseWindow:
437              rl,cl,rh,ch = self.im.getBlockLocation(b)              rl,cl,rh,ch = self.im.getBlockLocation(b)
438              if rh-rl > 0 or ch-cl>0:              if rh-rl > 0 or ch-cl>0:
439                  self.set_block(b)                  self.set_block(b)
440                    return
441              b = b - 1              b = b - 1
442          print "NO PRECEDING 'BIG' BLOCKS"          print "NO PRECEDING 'BIG' BLOCKS"
443                    
# Line 294  class DiagnoseWindow: Line 448  class DiagnoseWindow:
448              rl,cl,rh,ch = self.im.getBlockLocation(b)              rl,cl,rh,ch = self.im.getBlockLocation(b)
449              if rh-rl > 0 or ch-cl>0:              if rh-rl > 0 or ch-cl>0:
450                  self.set_block(b)                  self.set_block(b)
451                    return
452              b = b + 1              b = b + 1
453          print "NO FOLLOWING 'BIG' BLOCKS"          print "NO FOLLOWING 'BIG' BLOCKS"
454            
# Line 303  class DiagnoseWindow: Line 458  class DiagnoseWindow:
458          if keyname=="Return":          if keyname=="Return":
459              self.set_block( int(self.blockentry.get_text()) )              self.set_block( int(self.blockentry.get_text()) )
460    
461        # zoom in and out
462    
463      def on_zoominbutton_clicked(self,*args):      def on_zoominbutton_clicked(self,*args):
464          z = int( math.log(self.zoom)/math.log(2) )          z = int( math.log(self.zoom)/math.log(2) )
465          z = pow(2,z + 1);          z = pow(2,z + 1);
# Line 325  class DiagnoseWindow: Line 482  class DiagnoseWindow:
482                  print m                  print m
483              self.set_zoom( int(self.zoomentry.get_text()) )              self.set_zoom( int(self.zoomentry.get_text()) )
484    
485        # clicking in incidence matrix to get updated information at RHS
486    
487      def on_imageevent_motion_notify_event(self,widget,event):      def on_imageevent_motion_notify_event(self,widget,event):
488          self.show_cursor(event.x, event.y)          self.show_cursor(event.x, event.y)
489    
# Line 332  class DiagnoseWindow: Line 491  class DiagnoseWindow:
491          self.show_cursor(event.x, event.y)          self.show_cursor(event.x, event.y)
492    
493    
494  # The following is from  def value_human(v):
495        if v==0 or abs( math.log10(abs(v)) )<8:
496            return "%f" % v
497        return "%e" % v
498    
499    #---------------------------------------
500    # Procedures to 'fold' a list of items from a hierarchy
501  # http://www.experts-exchange.com/Programming/Programming_Languages/Python/Q_21719649.html  # http://www.experts-exchange.com/Programming/Programming_Languages/Python/Q_21719649.html
502  # it's still buggy.  # It's still buggy, I think
503    
504  def fold(data):  def fold(data):
505      """ fold sorted numeric sequence data into ranged representation:      """ fold sorted numeric sequence data into ranged representation:
# Line 365  def reduce(names): Line 530  def reduce(names):
530      for k, g in groupby(data, lambda x: len(x)):      for k, g in groupby(data, lambda x: len(x)):
531          if k == 1:          if k == 1:
532              indexed = {}              indexed = {}
533              seq = set(get(indexed, item) for item in g)              seq = set([get(indexed, item) for item in g])
534              res['[global]'] = [ i+fold(indexed.get(i, [])) for i in sorted(seq) ]              res['[global]'] = [ i+fold(indexed.get(i, [])) for i in sorted(seq) ]
535          else:          else:
536              for key, g1 in groupby(g, lambda x: '.'.join(x[:-1])):              for key, g1 in groupby(g, lambda x: '.'.join(x[:-1])):
# Line 380  def get(indexed, item): Line 545  def get(indexed, item):
545          item, idx = item[:-1].split('[')          item, idx = item[:-1].split('[')
546          indexed.setdefault(item, []).append(int(idx))          indexed.setdefault(item, []).append(int(idx))
547      return item      return item
548    

Legend:
Removed from v.531  
changed lines
  Added in v.3181

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