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

Contents of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 895 - (show annotations) (download) (as text)
Tue Oct 24 00:12:34 2006 UTC (13 years, 9 months ago) by johnpye
File MIME type: text/x-python
File size: 33172 byte(s)
Removed debug output (modelview.py)
Fixed bug in diagnose.py with large blocks
Removed debug output and improved error message in conopt.c
Removed debug output in lsode.c
Removed debup output in ascDynaload.c
1 #!/usr/bin/env python
2
3 import sys
4 def print_loading_status(status,msg=None):
5 sys.stderr.write("\r \r")
6 if msg!=None:
7 sys.stderr.write(msg+"\n")
8 sys.stderr.write(status+"...\r")
9 sys.stderr.flush()
10
11 try:
12 #print_loading_status("Loading PSYCO")
13 #try:
14 # import psyco
15 # psyco.full()
16 # print "Running with PSYCO optimisation..."
17 #except ImportError:
18 # pass
19
20
21 print_loading_status("Loading python standard libraries")
22
23 import re
24 import urlparse
25 import optparse
26 import platform
27 import sys
28 import os.path
29
30 if platform.system() != "Windows":
31 import dl
32 # This sets the flags for dlopen used by python so that the symbols in the
33 # ascend library are made available to libraries dlopened within ASCEND:
34 sys.setdlopenflags(dl.RTLD_GLOBAL|dl.RTLD_NOW)
35
36 print_loading_status("Loading LIBASCEND/ascpy")
37 import ascpy
38
39 print_loading_status("Loading PyGTK, glade, pango")
40
41 import pygtk
42 pygtk.require('2.0')
43 import gtk
44 import gtk.glade
45 import pango
46
47 print_loading_status("Loading python matplotlib")
48 try:
49 import matplotlib
50 matplotlib.use('GTKAgg')
51
52 try:
53 print_loading_status("Trying python numarray")
54 import numarray
55 matplotlib.rcParams['numerix'] = 'numarray'
56 print_loading_status("","Using python module numarray")
57 except ImportError:
58 try:
59 print_loading_status("Trying python numpy")
60 import numpy
61 matplotlib.rcParams['numerix'] = 'numpy'
62 print_loading_status("","Using python module numpy")
63 except ImportError:
64 try:
65 print_loading_status("Trying python Numeric")
66 import Numeric
67 matplotlib.rcParams['numerix'] = 'Numeric'
68 print_loading_status("","Using python module Numeric")
69 except ImportError:
70 print_loading_status("","FAILED TO LOAD A NUMERIC MODULE FOR PYTHON")
71
72 except ImportError,e:
73 print_loading_status("","FAILED TO LOAD MATPLOTLIB")
74 raise RuntimeError("Failed to load MATPLOTLIB (is it installed?). Details:"+str(e))
75
76 print_loading_status("Loading IPython")
77 import console;
78 if not console.have_ipython:
79 print_loading_status("","IPython couldn't be loaded")
80
81 print_loading_status("Loading ASCEND python modules")
82 from preferences import * # loading/saving of .ini options
83 from solverparameters import * # 'solver parameters' window
84 from help import * # viewing help files
85 from incidencematrix import * # incidence/sparsity matrix matplotlib window
86 from observer import * # observer tab support
87 from properties import * # solver_var properties dialog
88 from varentry import * # for inputting of variables with units
89 from diagnose import * # for diagnosing block non-convergence
90 from solverreporter import * # solver status reporting
91 from modelview import * # model browser
92 from integrator import * # integrator dialog
93 from infodialog import * # general-purpose textual information dialog
94 import config
95
96 except RuntimeError, e:
97 print "ASCEND had problems starting up. Please report the following"
98 print "error message at http://mantis.cruncher2.dyndns.org/."
99 print "\n\nFull error message:",str(e)
100 print "\n\nPress ENTER to close this window."
101 sys.stdout.flush()
102 sys.stdin.readline();
103 sys.exit();
104
105 except ImportError, e:
106 print "\n\n------------------ ERROR ---------------------"
107 print "ASCEND had problems importing required models."
108 print "\nPlease ensure you have all the runtime prerequisites installed."
109 print "Please then report a bug if you continue to have problems."
110 print "\nFull error message:",str(e)
111 if platform.system()=="Windows":
112 print "\nYou will also need to report the contents of any popup error"
113 print "messages from Windows if any were shown."
114 print "\n\nPress ENTER to close this window."
115 sys.stdout.flush()
116 sys.stdin.readline();
117 sys.exit();
118
119 print_loading_status("Starting GUI")
120
121 # This is my first ever GUI code so please be nice :)
122 # But I *have* at least read
123 # http://www.joelonsoftware.com/uibook/chapters/fog0000000057.html
124 # and leafed through
125 # http://developer.gnome.org/projects/gup/hig/
126
127 # The fancy tree-view gizmo is the GtkTreeView object. See the article
128 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/300304
129 # for the original source code on which my implementation was based.
130
131 ESCAPE_KEY = 65307
132
133 HELP_ROOT = None
134
135 #======================================
136 # Browser is the main ASCEND library/model browser window
137
138 class Browser:
139
140 # ---------------------------------
141 # SETUP
142
143 def __init__(self,librarypath=None,assetspath=None):
144
145 if assetspath==None:
146 assetspath=config.PYGTK_ASSETS
147
148 #--------
149 # load the file referenced in the command line, if any
150
151 print_loading_status("Parsing options","CONFIG = %s"%config.VERSION)
152
153 parser = optparse.OptionParser(usage="%prog [[-m typename] file]", version="gtkbrowser $rev$" )
154 # add options here if we want
155
156 parser.add_option("-m", "--model"
157 ,action="store", type="string", dest="model"
158 ,help="specify the model to instantiate upon loading modules")
159
160 parser.add_option("--pygtk-assets"
161 ,action="store", type="string", dest="assets_dir"
162 ,help="override the configuration value for the location of assets"\
163 +" required by PyGTK for the ASCEND GUI, optional"
164 ,default=assetspath
165 )
166
167 parser.add_option("--library"
168 ,action="store", type="string", dest="library_path"
169 ,help="override the configuration value for the library path"
170 ,default=librarypath
171 )
172
173 parser.add_option("--no-auto-sim"
174 ,action="store_false", dest="auto_sim"
175 ,help="disable auto-instantiation of MODEL named as the file stem"
176 ,default=True
177 )
178
179 (self.options, args) = parser.parse_args()
180
181 #print "OPTIONS_______________:",self.options
182
183 self.assets_dir = self.options.assets_dir
184
185 self.observers = []
186 self.clip = None
187
188 #--------
189 # load up the preferences ini file
190
191 print_loading_status("Loading preferences")
192
193 self.prefs = Preferences()
194
195 _prefpath = self.prefs.getStringPref("Directories","librarypath",None)
196 _preffileopenpath = self.prefs.getStringPref("Directories","fileopenpath",None)
197
198 #--------
199 # set up library path and the path to use for File->Open dialogs
200
201 if self.options.library_path != None:
202 _path = os.path.abspath(self.options.library_path)
203 _pathsrc = "command line options"
204 # when a special path is specified, use that as the file-open location
205 self.fileopenpath = _path
206 else:
207 if _prefpath:
208 _path = _prefpath
209 _pathsrc = "user preferences"
210 else:
211 _path = config.LIBRARY_PATH
212 _pathsrc = "default (config.py)"
213
214 if _preffileopenpath:
215 self.fileopenpath = _preffileopenpath
216 else:
217 self.fileopenpath = _path
218
219 #--------
220 # Create the ASCXX 'Library' object
221
222 print_loading_status("Creating ASCEND 'Library' object","PATH = "+_path+" FROM "+_pathsrc)
223 self.library = ascpy.Library(_path)
224
225 self.sim = None
226
227 #-------------------
228 # Set up the window and main widget actions
229
230 self.glade_file = os.path.join(self.assets_dir,config.GLADE_FILE)
231
232 print_loading_status("Setting up windows") #,"GLADE_FILE = %s" % self.glade_file)
233
234 glade = gtk.glade.XML(self.glade_file,"browserwin")
235
236 self.window = glade.get_widget("browserwin")
237
238
239 if not self.window:
240 raise RuntimeError("Couldn't load window from glade file")
241
242 _display = self.window.get_screen().get_display().get_name()
243 _geom=self.prefs.getGeometrySizePosition(_display,"browserwin")
244 if _geom:
245 self.window.resize(_geom[0],_geom[1])
246 self.window.move(_geom[2],_geom[3])
247
248 self.window.connect("delete_event", self.delete_event)
249
250 self.browserpaned=glade.get_widget("browserpaned")
251 _geom2=self.prefs.getGeometryValue(_display,"browserpaned")
252 if _geom2:
253 self.browserpaned.set_position(_geom2)
254
255 self.openbutton=glade.get_widget("openbutton")
256 self.openbutton.connect("clicked",self.open_click)
257
258 self.reloadbutton=glade.get_widget("reloadbutton")
259 self.reloadbutton.connect("clicked",self.reload_click)
260
261 self.solvebutton=glade.get_widget("solvebutton")
262 self.solvebutton.connect("clicked",self.solve_click)
263
264 self.integratebutton=glade.get_widget("integratebutton")
265 self.integratebutton.connect("clicked",self.integrate_click)
266
267 self.checkbutton=glade.get_widget("checkbutton")
268 self.checkbutton.connect("clicked",self.check_click)
269
270 self.autotoggle=glade.get_widget("autotoggle")
271 self.automenu = glade.get_widget("automenu")
272 self.autotoggle.connect("toggled",self.auto_toggle)
273
274 self.methodrunbutton=glade.get_widget("methodrunbutton")
275 self.methodrunbutton.connect("clicked",self.methodrun_click)
276
277 self.methodsel=glade.get_widget("methodsel")
278
279 self.maintabs = glade.get_widget("maintabs")
280
281 self.statusbar = glade.get_widget("statusbar")
282
283 self.menu = glade.get_widget("browsermenu")
284
285 self.show_solving_popup=glade.get_widget("show_solving_popup")
286 self.show_solving_popup.set_active(self.prefs.getBoolPref("SolverReporter","show_popup",True))
287 self.close_on_converged=glade.get_widget("close_on_converged")
288 self.close_on_converged.set_active(self.prefs.getBoolPref("SolverReporter","close_on_converged",True))
289 self.close_on_nonconverged=glade.get_widget("close_on_nonconverged")
290 self.close_on_nonconverged.set_active(self.prefs.getBoolPref("SolverReporter","close_on_nonconverged",True))
291 self.solver_engine=glade.get_widget("solver_engine")
292
293 self.use_relation_sharing=glade.get_widget("use_relation_sharing")
294 self.use_relation_sharing.set_active(self.prefs.getBoolPref("Compiler","use_relation_sharing",True))
295
296 glade.signal_autoconnect(self)
297
298 #-------
299 # Status icons
300
301 self.fixedimg = gtk.Image()
302 self.fixedimg.set_from_file(os.path.join(self.options.assets_dir,'locked.png'))
303
304 self.iconstatusunknown = None
305 self.iconfixed = self.fixedimg.get_pixbuf()
306 self.iconsolved = self.window.render_icon(gtk.STOCK_YES,gtk.ICON_SIZE_MENU)
307 self.iconactive = self.window.render_icon(gtk.STOCK_NO,gtk.ICON_SIZE_MENU)
308 self.iconunsolved = None
309
310 self.statusicons={
311 ascpy.ASCXX_VAR_STATUS_UNKNOWN: self.iconstatusunknown
312 ,ascpy.ASCXX_VAR_FIXED: self.iconfixed
313 ,ascpy.ASCXX_VAR_SOLVED: self.iconsolved
314 ,ascpy.ASCXX_VAR_ACTIVE: self.iconactive
315 ,ascpy.ASCXX_VAR_UNSOLVED: self.iconunsolved
316 }
317
318
319 self.statusmessages={
320 ascpy.ASCXX_VAR_STATUS_UNKNOWN: "Status unknown"
321 ,ascpy.ASCXX_VAR_FIXED: "Fixed"
322 ,ascpy.ASCXX_VAR_SOLVED: "Converged"
323 ,ascpy.ASCXX_VAR_ACTIVE: "Active (unconverged)"
324 ,ascpy.ASCXX_VAR_UNSOLVED: "Not yet visited"
325 }
326
327 #-------------------
328 # waitwin
329
330 self.waitwin = gtk.gdk.Window(self.window.window,
331 gtk.gdk.screen_width(),
332 gtk.gdk.screen_height(),
333 gtk.gdk.WINDOW_CHILD,
334 0,
335 gtk.gdk.INPUT_ONLY)
336
337 _cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
338 self.waitwin.set_cursor(_cursor)
339
340 #-------------------
341 # pixbufs to be used in the error listing
342
343 self.iconok = self.window.render_icon(gtk.STOCK_YES,gtk.ICON_SIZE_MENU)
344 self.iconinfo = self.window.render_icon(gtk.STOCK_DIALOG_INFO,gtk.ICON_SIZE_MENU)
345 self.iconwarning = self.window.render_icon(gtk.STOCK_DIALOG_WARNING,gtk.ICON_SIZE_MENU)
346 self.iconerror = self.window.render_icon(gtk.STOCK_DIALOG_ERROR,gtk.ICON_SIZE_MENU)
347
348 #--------------------
349 # pixbufs for solver_var status
350
351 #--------------------
352 # set up the error view
353
354 self.errorview = glade.get_widget("errorview")
355 errstorecolstypes = [gtk.gdk.Pixbuf,str,str,str,int]
356 self.errorstore = gtk.TreeStore(*errstorecolstypes)
357 errtitles = ["","Location","Message"];
358 self.errorview.set_model(self.errorstore)
359 self.errcols = [ gtk.TreeViewColumn() for _type in errstorecolstypes]
360
361 i = 0
362 for tvcolumn in self.errcols[:len(errtitles)]:
363 tvcolumn.set_title(errtitles[i])
364 self.errorview.append_column(tvcolumn)
365
366 if i>0:
367 _renderer = gtk.CellRendererText()
368 tvcolumn.pack_start(_renderer, True)
369 tvcolumn.add_attribute(_renderer, 'text', i)
370 if(i==2):
371 tvcolumn.add_attribute(_renderer, 'foreground', 3)
372 tvcolumn.add_attribute(_renderer, 'weight', 4)
373 else:
374 _renderer1 = gtk.CellRendererPixbuf()
375 tvcolumn.pack_start(_renderer1, False)
376 tvcolumn.add_attribute(_renderer1, 'pixbuf', int(0))
377
378 i = i + 1
379
380
381 #--------------------
382 # set up the error reporter callback
383 self.reporter = ascpy.getReporter()
384 self.reporter.setPythonErrorCallback(self.error_callback)
385
386
387 #-------
388 # Solver engine list
389
390 _slvlist = ascpy.getSolvers()
391 self.solver_engine_menu = gtk.Menu()
392 self.solver_engine_menu.show()
393 self.solver_engine.set_submenu(self.solver_engine_menu)
394 self.solver_engine_menu_dict = {}
395 _fmi = None
396 for _s in _slvlist:
397 _mi = gtk.RadioMenuItem(_fmi,_s.getName(),False)
398 if _fmi==None:
399 _fmi = _mi
400 _mi.show()
401 _mi.connect('toggled',self.on_select_solver_toggled,_s.getName())
402 self.solver_engine_menu.append(_mi)
403 self.solver_engine_menu_dict[_s.getName()]=_mi
404
405 _pref_solver = self.prefs.getStringPref("Solver","engine","QRSlv")
406 _mi = self.solver_engine_menu_dict.get(_pref_solver)
407 if _mi:
408 _mi.set_active(1)
409
410 #--------
411 # Assign an icon to the main window
412
413 self.icon = None
414 if config.ICON_EXTENSION:
415 _iconpath = ""
416 try:
417 _icon = gtk.Image()
418 _iconpath = os.path.join(self.assets_dir,'ascend'+config.ICON_EXTENSION)
419 _icon.set_from_file(_iconpath)
420 _iconpbuf = _icon.get_pixbuf()
421 self.window.set_icon(_iconpbuf)
422 self.icon = _iconpbuf
423 except Exception, e:
424 print "FAILED TO SET APPLICATION ICON PATH '%s': %s" % (_iconpath,str(e))
425 self.reporter.reportError("FAILED to set application icon '%s': %s"
426 % (_iconpath,str(e))
427 )
428
429 #-------------------
430 # set up the module view
431
432 self.modtank = {}
433 self.moduleview = glade.get_widget("moduleview")
434 modulestorecoltypes = [str, str, int] # bool=can-be-instantiated
435 self.modulestore = gtk.TreeStore(*modulestorecoltypes)
436 moduleviewtitles = ["Module name", "Filename"]
437 self.moduleview.set_model(self.modulestore)
438 self.modcols = [ gtk.TreeViewColumn() for _type in modulestorecoltypes]
439 i = 0
440 for modcol in self.modcols[:len(moduleviewtitles)]:
441 modcol.set_title(moduleviewtitles[i])
442 self.moduleview.append_column(modcol)
443 _renderer = gtk.CellRendererText()
444 modcol.pack_start(_renderer, True)
445 modcol.add_attribute(_renderer, 'text', i)
446 modcol.add_attribute(_renderer,'weight',2)
447 i = i + 1
448 self.moduleview.connect("row-activated", self.module_activated )
449
450 #--------------------
451 # set up the methods combobox
452
453 self.methodstore = gtk.ListStore(str)
454 self.methodsel.set_model(self.methodstore)
455 _methodrenderer = gtk.CellRendererText()
456 self.methodsel.pack_start(_methodrenderer, True)
457 self.methodsel.add_attribute(_methodrenderer, 'text',0)
458
459 #--------
460 # set up the instance browser view
461
462 self.modelview = ModelView(self, glade)
463
464 #--------
465 # set up the tabs
466 self.tabs = {}
467 self.activetab = None # most recent observer tab
468
469 #--------
470 # set the state of the 'auto' toggle
471
472 self.is_auto = self.prefs.getBoolPref("Browser","auto_solve",True)
473 self.autotoggle.set_active(self.is_auto)
474 self.automenu.set_active(self.is_auto)
475
476 #--------
477 # tell libascend about this 'browser' object
478
479 print dir(ascpy.Registry())
480 ascpy.Registry().set("browser",self)
481
482 #--------
483 # options
484
485 if(len(args)==1):
486 self.do_open(args[0])
487
488 print "Options: ",self.options
489
490 _model = None
491 if self.options.model:
492 _model = self.options.model
493 print "MODEL: '%s'" % _model
494 elif self.options.auto_sim:
495 _head, _tail = os.path.split(args[0])
496 if(_tail):
497 _model, _ext = os.path.splitext(_tail)
498
499 if _model:
500 try:
501 _t=self.library.findType(_model)
502 try:
503 self.do_sim(_t)
504 if not self.options.model:
505 self.reporter.reportNote("Instantiating self-titled model '%s'" %_model)
506 except RuntimeError, e:
507 self.reporter.reportError("Failed to create instance of '%s': %s"
508 %(_model, str(e))
509 );
510 except RuntimeError, e:
511 if self.options.model:
512 self.reporter.reportError("Unknown model type '%s': %s"
513 %(_model, str(e))
514 );
515
516 def run(self):
517 self.window.show()
518 print_loading_status("ASCEND is now running")
519 gtk.main()
520
521 # ------------------
522 # SOLVER LIST
523
524 def set_solver(self,solvername):
525 self.solver = ascpy.Solver(solvername)
526 self.prefs.setStringPref("Solver","engine",solvername)
527 self.reporter.reportNote("Set solver engine to '%s'" % solvername)
528
529 # --------------------------------------------
530 # MAJOR GUI COMMANDS
531
532 def on_fix_variable_activate(self,*args):
533 self.modelview.on_fix_variable_activate(*args)
534
535 def on_free_variable_activate(self,*args):
536 self.modelview.on_free_variable_activate(*args)
537
538 def on_select_solver_toggled(self,widget,solvername):
539 if widget.get_active():
540 self.set_solver(solvername)
541
542 def do_open(self,filename):
543 # TODO does the user want to lose their work?
544 # TODO do we need to chdir?
545
546 _context = self.statusbar.get_context_id("do_open")
547
548 self.errorstore.clear()
549 self.modelview.clear()
550
551 # self.library.clear()
552
553 print "Filename =",filename
554 self.statusbar.push(_context,"Loading '"+filename+"'")
555 self.library.load(filename)
556 print "Statusbar =",self.statusbar
557 try:
558 self.statusbar.pop(_context)
559 except TypeError,e:
560 print "For some reason, a type error (context=%s,filename=%s): %s" % (_context,filename,e)
561
562 self.filename = filename
563
564 # Load the current list of modules into self.modules
565 self.modtank = {}
566 self.modulestore.clear()
567 modules = self.library.getModules()
568 #self.library.listModules()
569 try:
570 _lll=len(modules)
571 except:
572 _msg = "UNABLE TO ACCESS MODULES LIST. This is bad.\n"+\
573 "Check your SWIG configuration (check for warnings during build)."
574
575 self.reporter.reportError(_msg)
576 raise RuntimeError(_msg)
577
578 for m in reversed(modules):
579 _n = str( m.getName() )
580 _f = str( m.getFilename() )
581 #print "ADDING ROW name %s, file = %s" % (_n, _f)
582 _r = self.modulestore.append(None, [ _n, _f, pango.WEIGHT_NORMAL ])
583 for t in self.library.getModuleTypes(m):
584 _n = t.getName()
585 _hasparams = t.hasParameters()
586 if _hasparams:
587 _w = pango.WEIGHT_NORMAL
588 else:
589 _w = pango.WEIGHT_BOLD
590
591 #print "ADDING TYPE %s" % _n
592 _piter = self.modulestore.append(_r , [ _n, "", _w ])
593 _path = self.modulestore.get_path(_piter)
594 self.modtank[_path]=t
595
596 #print "DONE ADDING MODULES"
597
598 self.sim = None;
599 self.maintabs.set_current_page(0);
600
601 # See http://www.daa.com.au/pipermail/pygtk/2005-October/011303.html
602 # for details on how the 'wait cursor' is done.
603 def start_waiting(self, message):
604 self.waitcontext = self.statusbar.get_context_id("waiting")
605 self.statusbar.push(self.waitcontext,message)
606
607 if self.waitwin:
608 self.waitwin.show()
609
610 while gtk.events_pending():
611 gtk.main_iteration()
612
613 def stop_waiting(self):
614 if self.waitwin:
615 self.statusbar.pop(self.waitcontext)
616 self.waitwin.hide()
617
618 def do_sim(self, type_object):
619 self.sim = None;
620 # TODO: clear out old simulation first!
621
622 print "DO_SIM(%s)" % str(type_object.getName())
623 self.start_waiting("Compiling...")
624
625 try:
626 _v = self.prefs.getBoolPref("Compiler","use_relation_sharing",True)
627 ascpy.getCompiler().setUseRelationSharing(_v)
628
629 self.sim = type_object.getSimulation(str(type_object.getName())+"_sim")
630 except RuntimeError, e:
631 self.stop_waiting()
632 self.reporter.reportError(str(e))
633 return
634
635 print "...DONE 'getSimulation'"
636 self.stop_waiting()
637
638 self.start_waiting("Building simulation...")
639 print "BUILDING SIMULATION"
640
641 try:
642 self.sim.build()
643 except RuntimeError, e:
644 self.stop_waiting()
645 self.reporter.reportError(str(e))
646 return;
647
648 print "DONE BUILDING"
649 self.stop_waiting()
650
651 self.sim.setSolver(self.solver)
652
653 # methods
654 self.methodstore.clear()
655 _methods = self.sim.getType().getMethods()
656 _activemethod = None;
657 for _m in _methods:
658 _i = self.methodstore.append([_m.getName()])
659 if _m.getName()=="on_load":
660 self.methodsel.set_active_iter(_i)
661
662 self.modelview.setSimulation(self.sim)
663
664 def do_solve_if_auto(self):
665 if self.is_auto:
666 self.sim.checkInstance()
667 self.do_solve()
668 else:
669 self.sim.processVarStatus()
670 self.modelview.refreshtree()
671
672 self.sync_observers()
673
674 def do_solve(self):
675 if not self.sim:
676 self.reporter.reportError("No model selected yet")
677 return
678
679 self.start_waiting("Solving with %s..." % self.solver.getName())
680
681 if self.prefs.getBoolPref("SolverReporter","show_popup",True):
682 reporter = PopupSolverReporter(self,self.sim.getNumVars())
683 else:
684 reporter = SimpleSolverReporter(self)
685
686 self.sim.solve(self.solver,reporter)
687
688 self.stop_waiting()
689
690 self.sim.processVarStatus()
691 self.modelview.refreshtree()
692
693 def do_integrate(self):
694 if not self.sim:
695 self.reporter.reportError("No model selected yet")
696 return
697 integwin = IntegratorWindow(self,self.sim)
698 _integratorreporter = integwin.run()
699 if _integratorreporter!=None:
700 _integratorreporter.run()
701 self.sim.processVarStatus()
702 self.modelview.refreshtree()
703
704
705 def do_check(self):
706 if not self.sim:
707 self.reporter.reportError("No simulation yet")
708 return
709
710 self.start_waiting("Checking system...")
711
712 try:
713 self.sim.checkInstance()
714 self.reporter.reportWarning("System instance check run, check above for error (if any).")
715 # the above gives output but doesn't throw errors or return a status.
716 # ... this is a problem (at the C level)
717
718 status = self.sim.checkDoF()
719 if status==ascpy.ASCXX_DOF_UNDERSPECIFIED:
720 self.on_show_fixable_variables_activate(None)
721 elif status==ascpy.ASCXX_DOF_OVERSPECIFIED:
722 self.on_show_freeable_variables_activate(None)
723 elif status==ascpy.ASCXX_DOF_STRUCT_SINGULAR:
724 if not self.sim.checkStructuralSingularity():
725 sing = self.sim.getSingularityInfo()
726 title = "Structural singularity"
727 text = title
728 text += "\n\nThe singularity can be reduced by freeing the following variables:"
729 msgs = {
730 "The singularity can be reduced by freeing the following variables" : sing.freeablevars
731 ,"Relations involved in the structural singularity" : sing.rels
732 ,"Variables involved in the structural singularity" : sing.vars
733 }
734 for k,v in msgs.iteritems():
735 text+="\n\n%s:" % k
736 if len(v):
737 _l = [j.getName() for j in v]
738 _l.sort()
739 text+= "\n\t" + "\n\t".join(_l)
740 else:
741 text += "\nnone"
742
743 _dialog = InfoDialog(self,self.window,text,title)
744 _dialog.run()
745
746 self.reporter.reportNote("System DoF check OK")
747
748 except RuntimeError, e:
749 self.stop_waiting()
750 self.reporter.reportError(str(e))
751 return
752
753 self.stop_waiting()
754
755 self.modelview.refreshtree()
756
757 def do_method(self,method):
758 if not self.sim:
759 self.reporter.reportError("No model selected yet")
760
761 self.sim.run(method)
762 self.modelview.refreshtree()
763
764 def do_quit(self):
765 print_loading_status("Saving window location")
766 self.reporter.clearPythonErrorCallback()
767
768 _w,_h = self.window.get_size()
769 _t,_l = self.window.get_position()
770 _display = self.window.get_screen().get_display().get_name()
771 self.prefs.setGeometrySizePosition(_display,"browserwin",_w,_h,_t,_l );
772
773 _p = self.browserpaned.get_position()
774 self.prefs.setGeometryValue(_display,"browserpaned",_p);
775
776 print_loading_status("Saving current directory")
777 self.prefs.setStringPref("Directories","fileopenpath",self.fileopenpath)
778
779 self.prefs.setBoolPref("Browser","auto_solve",self.is_auto)
780
781 print_loading_status("Saving preferences")
782 # causes prefs to be saved unless they are still being used elsewher
783 del(self.prefs)
784
785 print_loading_status("Closing down GTK")
786 gtk.main_quit()
787
788 print_loading_status("Clearing error callback")
789 self.reporter.clearPythonErrorCallback()
790
791 print_loading_status("Quitting")
792 return False
793
794 def on_tools_sparsity_click(self,*args):
795
796 self.reporter.reportNote("Preparing incidence matrix...")
797 _im = self.sim.getIncidenceMatrix();
798
799 self.reporter.reportNote("Plotting incidence matrix...")
800
801 _sp = IncidenceMatrixWindow(_im);
802 _sp.run();
803
804 def on_diagnose_blocks_click(self,*args):
805 try:
806 _bl = self.sim.getActiveBlock()
807 except RuntimeError, e:
808 self.reporter.reportError(str(e))
809 return
810 _db = DiagnoseWindow(self,_bl)
811 _db.run();
812
813 def on_add_observer_click(self,*args):
814 self.create_observer()
815
816 def on_keep_observed_click(self,*args):
817 print "KEEPING..."
818 if len(self.observers) <= 0:
819 self.reporter.reportError("No observer defined!")
820 return
821 self.tabs[self.currentobservertab].do_add_row()
822
823 def on_copy_observer_matrix_click(self,*args):
824 if self.clip == None:
825 self.clip = gtk.Clipboard()
826
827 if len(self.observers) <= 0:
828 self.reporter.reportError("No observer defined!")
829 return
830 self.tabs[self.currentobservertab].copy_to_clipboard(self.clip)
831
832 def on_use_relation_sharing_toggle(self,checkmenuitem,*args):
833 _v = checkmenuitem.get_active()
834 self.prefs.setBoolPref("Compiler","use_relation_sharing",_v)
835 self.reporter.reportNote("Relation sharing set to "+str(_v))
836
837 def on_show_solving_popup_toggle(self,checkmenuitem,*args):
838 _v = checkmenuitem.get_active()
839 self.prefs.setBoolPref("SolverReporter","show_popup",_v)
840 print "SET TO",_v
841
842 def on_close_on_converged_toggle(self,checkmenuitem,*args):
843 _v = checkmenuitem.get_active()
844 self.prefs.setBoolPref("SolverReporter","close_on_converged",_v)
845
846 def on_close_on_nonconverged_toggle(self,checkmenuitem,*args):
847 _v = checkmenuitem.get_active()
848 self.prefs.setBoolPref("SolverReporter","close_on_nonconverged",_v)
849
850 def on_show_variables_near_bounds_activate(self,*args):
851 _epsilon = 1e-4;
852 text = "Variables Near Bounds"
853 title=text;
854 text += "\n"
855 _vars = self.sim.getVariablesNearBounds(_epsilon)
856 if len(_vars):
857 for _v in _vars:
858 text += "\n%s"%_v.getName()
859 else:
860 text +="\nnone"
861 _dialog = InfoDialog(self,self.window,text,title)
862 _dialog.run()
863
864 # --------------------------------------------
865 # MODULE LIST
866
867 def module_activated(self, treeview, path, column, *args):
868 modules = self.library.getModules()
869 print "PATH",path
870 if len(path)==1:
871 self.reporter.reportNote("Launching of external editor not yet implemented")
872 elif len(path)==2:
873 if(self.modtank.has_key(path)):
874 _type = self.modtank[path];
875 self.reporter.reportNote("Creating simulation for type %s" % str(_type.getName()) )
876 self.do_sim(_type)
877 else:
878 self.reporter.reportError("Didn't find type corresponding to row")
879
880 # ----------------------------------
881 # ERROR PANEL
882
883 def get_error_row_data(self,sev,filename,line,msg):
884 _sevicon = {
885 0: self.iconok
886 ,1: self.iconinfo
887 ,2: self.iconwarning
888 ,3: self.iconerror
889 ,4: self.iconinfo
890 ,5: self.iconwarning
891 ,6: self.iconerror
892 }[sev]
893
894 _fontweight = pango.WEIGHT_NORMAL
895 if sev==6:
896 _fontweight = pango.WEIGHT_BOLD
897
898 _fgcolor = "black"
899 if sev==4:
900 _fgcolor = "#888800"
901 elif sev==5:
902 _fgcolor = "#884400"
903 elif sev==6:
904 _fgcolor = "#880000"
905 elif sev==0:
906 _fgcolor = BROWSER_FIXED_COLOR
907
908 if not filename and not line:
909 _fileline = ""
910 else:
911 if(len(filename) > 25):
912 filename = "..."+filename[-22:]
913 _fileline = filename + ":" + str(line)
914
915 _res = [_sevicon,_fileline,msg.rstrip(),_fgcolor,_fontweight]
916 #print _res
917 return _res
918
919 def error_callback(self,sev,filename,line,msg):
920 try:
921 pos = self.errorstore.append(None, self.get_error_row_data(sev, filename,line,msg))
922 path = self.errorstore.get_path(pos)
923 col = self.errorview.get_column(3)
924 self.errorview.scroll_to_cell(path,col)
925 except Exception,e:
926 print "UNABLE TO DISPLAY ERROR MESSAGE '%s'"%msg
927
928 return 0;
929
930 # --------------------------------
931 # BUTTON METHODS
932
933 def open_click(self,*args):
934 #print_loading_status("CURRENT FILEOPENPATH is",self.fileopenpath)
935 dialog = gtk.FileChooserDialog("Open ASCEND model...",
936 self.window,
937 gtk.FILE_CHOOSER_ACTION_OPEN,
938 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)
939 )
940 dialog.set_current_folder(self.fileopenpath)
941 dialog.set_default_response(gtk.RESPONSE_OK)
942 dialog.set_transient_for(self.window)
943 dialog.set_modal(True)
944
945 filter = gtk.FileFilter()
946 filter.set_name("*.a4c, *.a4l")
947 filter.add_pattern("*.[Aa]4[Cc]")
948 filter.add_pattern("*.[Aa]4[Ll]")
949 dialog.add_filter(filter)
950
951 filter = gtk.FileFilter()
952 filter.set_name("All files")
953 filter.add_pattern("*")
954 dialog.add_filter(filter)
955
956 response = dialog.run()
957 _filename = dialog.get_filename()
958 print "\nFILENAME SELECTED:",_filename
959
960 _path = dialog.get_current_folder()
961 if _path:
962 self.fileopenpath = _path
963
964 dialog.hide()
965
966 if response == gtk.RESPONSE_OK:
967 self.reporter.reportNote("File %s selected." % dialog.get_filename() )
968 self.library.clear()
969 self.do_open( _filename)
970
971 def reload_click(self,*args):
972 _type = None
973 if(self.sim):
974 _type = self.sim.getType().getName().toString();
975
976 self.library.clear()
977 self.do_open(self.filename)
978
979 if _type:
980 _t = self.library.findType(_type)
981 self.do_sim(_t)
982
983 def props_activate(self,widget,*args):
984 return self.modelview.props_activate(self,widget,*args)
985
986 def observe_activate(self,widget,*args):
987 return self.modelview.observe_activate(self,widget,*args)
988
989 def solve_click(self,*args):
990 #self.reporter.reportError("Solving simulation '" + self.sim.getName().toString() +"'...")
991 self.do_solve()
992
993 def console_click(self,*args):
994 try:
995 console.start(self)
996 except RuntimeError,e:
997 self.reporter.reportError("Unable to start console: "+str(e));
998
999 def integrate_click(self,*args):
1000 self.do_integrate()
1001
1002 def check_click(self,*args):
1003 self.do_check()
1004 #self.reporter.reportError("CHECK clicked")
1005
1006 def preferences_click(self,*args):
1007 if not self.sim:
1008 self.reporter.reportError("No simulation created yet!");
1009
1010 _paramswin = SolverParametersWindow(self)
1011 _paramswin.show()
1012
1013 def methodrun_click(self,*args):
1014 _sel = self.methodsel.get_active_text()
1015 if _sel:
1016 _method = None
1017 _methods = self.sim.getType().getMethods()
1018 for _m in _methods:
1019 if _m.getName()==_sel:
1020 _method = _m
1021 if not _method:
1022 self.reporter.reportError("Method is not valid")
1023 return
1024 self.do_method(_method)
1025 else:
1026 self.reporter.reportError("No method selected")
1027
1028 def auto_toggle(self,button,*args):
1029 self.is_auto = button.get_active()
1030 if hasattr(self,'automenu'):
1031 self.automenu.set_active(self.is_auto)
1032 else:
1033 raise RuntimeError("no automenu")
1034
1035 #if self.is_auto:
1036 # self.reporter.reportSuccess("Auto mode is now ON")
1037 #else:
1038 # self.reporter.reportSuccess("Auto mode is now OFF")
1039
1040 def on_file_quit_click(self,*args):
1041 self.do_quit()
1042
1043 def on_tools_auto_toggle(self,checkmenuitem,*args):
1044 self.is_auto = checkmenuitem.get_active()
1045 self.autotoggle.set_active(self.is_auto)
1046
1047 def on_help_about_click(self,*args):
1048 _xml = gtk.glade.XML(self.glade_file,"aboutdialog")
1049 _about = _xml.get_widget("aboutdialog")
1050 _about.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
1051 _about.set_transient_for(self.window);
1052 _about.set_version(config.VERSION)
1053 _about.run()
1054 _about.destroy()
1055
1056 def on_help_contents_click(self,*args):
1057 _help = Help(HELP_ROOT)
1058 _help.run()
1059
1060 def on_show_fixable_variables_activate(self,*args):
1061 v = self.sim.getFixableVariables()
1062 text = "Fixable Variables"
1063 title = text
1064 text += "\n"
1065 if len(v):
1066 for var in v:
1067 text += "\n%s"%var
1068 else:
1069 text += "\nnone"
1070 _dialog = InfoDialog(self,self.window,text,title)
1071 _dialog.run()
1072
1073 def on_show_freeable_variables_activate(self,*args):
1074 v = self.sim.getFreeableVariables()
1075
1076 text = "Freeable Variables"
1077 title = text
1078 text += "\n"
1079 if len(v):
1080 for var in v:
1081 text += "\n%s" % var
1082 else:
1083 text += "\nnone"
1084 _dialog = InfoDialog(self,self.window,text,title)
1085 _dialog.run()
1086
1087 def on_show_external_functions_activate(self,*args):
1088 v = self.library.getExtMethods()
1089 text = "External Functions"
1090 title = text
1091 text +="\nHere is the list of external functions currently present in"
1092 text +=" the Library:"
1093
1094 if len(v):
1095 for ext in v:
1096 text += "\n\n%s (%d inputs, %d outputs):" % \
1097 (ext.getName(), ext.getNumInputs(), ext.getNumOutputs())
1098 text += "\n%s" % ext.getHelp()
1099 else:
1100 text +="\n\nNone"
1101 _dialog = InfoDialog(self,self.window,text,title)
1102 _dialog.run()
1103
1104 def on_maintabs_switch_page(self,notebook,page,pagenum):
1105 print("Page switched to %d" % pagenum)
1106 if pagenum in self.tabs.keys():
1107 self.currentobservertab = pagenum
1108
1109 def create_observer(self,name=None):
1110 _xml = gtk.glade.XML(self.glade_file,"observervbox");
1111 _label = gtk.Label();
1112 _tab = self.maintabs.append_page(_xml.get_widget("observervbox"),_label);
1113 _obs = ObserverTab(xml=_xml, name=name, browser=self, tab=_tab)
1114 _label.set_text(_obs.name)
1115 self.observers.append(_obs)
1116 self.tabs[_tab] = _obs
1117 self.currentobservertab = _tab
1118 return _obs
1119
1120 def sync_observers(self):
1121 for _o in self.observers:
1122 _o.sync()
1123
1124 def delete_event(self, widget, event):
1125 self.do_quit()
1126 return False
1127
1128 def observe(self,instance):
1129 if len(self.observers) ==0:
1130 self.create_observer()
1131 _observer = self.tabs[self.currentobservertab]
1132 _observer.add_instance(instance)
1133
1134 if __name__ == "__main__":
1135 b = Browser();
1136 b.run()

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