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

Contents of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 900 - (show annotations) (download) (as text)
Wed Oct 25 06:03:04 2006 UTC (13 years, 11 months ago) by johnpye
File MIME type: text/x-python
File size: 33640 byte(s)
The 'sim' object is correctly accessible from script methods now, even if run during on_load.
Added 'getSimulation' to registry.cpp, added 'runDefaultMethod' to Simulation, added 'getMethod' to Type.
Running of 'on_load' is instigated at the Python level now, so that relevent python variables are set at simulations are built, etc. This appears to have cause some changes to the way the solver behaves, possibly.
Added SearchProcList to exports in libascend.

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 """ this sets the active solver in the GUI, which is the default applied to newly instantiated models """
526 self.solver = ascpy.Solver(solvername)
527 self.prefs.setStringPref("Solver","engine",solvername)
528 self.reporter.reportNote("Set solver engine to '%s'" % solvername)
529
530 # --------------------------------------------
531 # MAJOR GUI COMMANDS
532
533 def on_fix_variable_activate(self,*args):
534 self.modelview.on_fix_variable_activate(*args)
535
536 def on_free_variable_activate(self,*args):
537 self.modelview.on_free_variable_activate(*args)
538
539 def on_select_solver_toggled(self,widget,solvername):
540 if widget.get_active():
541 self.set_solver(solvername)
542
543 def do_open(self,filename):
544 # TODO does the user want to lose their work?
545 # TODO do we need to chdir?
546
547 _context = self.statusbar.get_context_id("do_open")
548
549 self.errorstore.clear()
550 self.modelview.clear()
551
552 # self.library.clear()
553
554 print "Filename =",filename
555 self.statusbar.push(_context,"Loading '"+filename+"'")
556 self.library.load(filename)
557 print "Statusbar =",self.statusbar
558 try:
559 self.statusbar.pop(_context)
560 except TypeError,e:
561 print "For some reason, a type error (context=%s,filename=%s): %s" % (_context,filename,e)
562
563 self.filename = filename
564
565 # Load the current list of modules into self.modules
566 self.modtank = {}
567 self.modulestore.clear()
568 modules = self.library.getModules()
569 #self.library.listModules()
570 try:
571 _lll=len(modules)
572 except:
573 _msg = "UNABLE TO ACCESS MODULES LIST. This is bad.\n"+\
574 "Check your SWIG configuration (check for warnings during build)."
575
576 self.reporter.reportError(_msg)
577 raise RuntimeError(_msg)
578
579 for m in reversed(modules):
580 _n = str( m.getName() )
581 _f = str( m.getFilename() )
582 #print "ADDING ROW name %s, file = %s" % (_n, _f)
583 _r = self.modulestore.append(None, [ _n, _f, pango.WEIGHT_NORMAL ])
584 for t in self.library.getModuleTypes(m):
585 _n = t.getName()
586 _hasparams = t.hasParameters()
587 if _hasparams:
588 _w = pango.WEIGHT_NORMAL
589 else:
590 _w = pango.WEIGHT_BOLD
591
592 #print "ADDING TYPE %s" % _n
593 _piter = self.modulestore.append(_r , [ _n, "", _w ])
594 _path = self.modulestore.get_path(_piter)
595 self.modtank[_path]=t
596
597 #print "DONE ADDING MODULES"
598
599 self.sim = None;
600 self.maintabs.set_current_page(0);
601
602 # See http://www.daa.com.au/pipermail/pygtk/2005-October/011303.html
603 # for details on how the 'wait cursor' is done.
604 def start_waiting(self, message):
605 self.waitcontext = self.statusbar.get_context_id("waiting")
606 self.statusbar.push(self.waitcontext,message)
607
608 if self.waitwin:
609 self.waitwin.show()
610
611 while gtk.events_pending():
612 gtk.main_iteration()
613
614 def stop_waiting(self):
615 if self.waitwin:
616 self.statusbar.pop(self.waitcontext)
617 self.waitwin.hide()
618
619 def do_sim(self, type_object):
620 self.sim = None;
621 # TODO: clear out old simulation first!
622
623 print "DO_SIM(%s)" % str(type_object.getName())
624 self.start_waiting("Compiling...")
625
626 try:
627 _v = self.prefs.getBoolPref("Compiler","use_relation_sharing",True)
628 ascpy.getCompiler().setUseRelationSharing(_v)
629
630 self.sim = type_object.getSimulation(str(type_object.getName())+"_sim")
631
632 self.reporter.reportNote("SIMULATION ASSIGNED")
633 except RuntimeError, e:
634 self.stop_waiting()
635 self.reporter.reportError(str(e))
636 return
637
638 print "...DONE 'getSimulation'"
639 self.stop_waiting()
640
641 self.start_waiting("Building simulation...")
642 print "BUILDING SIMULATION"
643
644 try:
645 self.sim.build()
646 except RuntimeError, e:
647 self.stop_waiting()
648 self.reporter.reportError(str(e))
649 return
650
651 print "DONE BUILDING"
652 self.stop_waiting()
653
654 self.sim.setSolver(self.solver)
655
656 self.start_waiting("Running default method...")
657
658 try:
659 print "SIMULATION CREATED, RUNNING DEFAULT METHOD NOW..."
660 self.sim.runDefaultMethod()
661 except RuntimeError, e:
662 self.stop_waiting()
663 self.reporter.reportError(str(e))
664 return
665
666 self.stop_waiting()
667
668 # get method names and load them into the GUI
669 self.methodstore.clear()
670 _methods = self.sim.getType().getMethods()
671 _activemethod = None;
672 for _m in _methods:
673 _i = self.methodstore.append([_m.getName()])
674 if _m.getName()=="on_load":
675 self.methodsel.set_active_iter(_i)
676
677 self.modelview.setSimulation(self.sim)
678
679 def do_solve_if_auto(self):
680 if self.is_auto:
681 self.sim.checkInstance()
682 self.do_solve()
683 else:
684 self.sim.processVarStatus()
685 self.modelview.refreshtree()
686
687 self.sync_observers()
688
689 def do_solve(self):
690 if not self.sim:
691 self.reporter.reportError("No model selected yet")
692 return
693
694 self.start_waiting("Solving with %s..." % self.solver.getName())
695
696 if self.prefs.getBoolPref("SolverReporter","show_popup",True):
697 reporter = PopupSolverReporter(self,self.sim.getNumVars())
698 else:
699 reporter = SimpleSolverReporter(self)
700
701 self.sim.solve(self.solver,reporter)
702
703 self.stop_waiting()
704
705 self.sim.processVarStatus()
706 self.modelview.refreshtree()
707
708 def do_integrate(self):
709 if not self.sim:
710 self.reporter.reportError("No model selected yet")
711 return
712 integwin = IntegratorWindow(self,self.sim)
713 _integratorreporter = integwin.run()
714 if _integratorreporter!=None:
715 _integratorreporter.run()
716 self.sim.processVarStatus()
717 self.modelview.refreshtree()
718
719
720 def do_check(self):
721 if not self.sim:
722 self.reporter.reportError("No simulation yet")
723 return
724
725 self.start_waiting("Checking system...")
726
727 try:
728 self.sim.checkInstance()
729 self.reporter.reportWarning("System instance check run, check above for error (if any).")
730 # the above gives output but doesn't throw errors or return a status.
731 # ... this is a problem (at the C level)
732
733 status = self.sim.checkDoF()
734 if status==ascpy.ASCXX_DOF_UNDERSPECIFIED:
735 self.on_show_fixable_variables_activate(None)
736 elif status==ascpy.ASCXX_DOF_OVERSPECIFIED:
737 self.on_show_freeable_variables_activate(None)
738 elif status==ascpy.ASCXX_DOF_STRUCT_SINGULAR:
739 if not self.sim.checkStructuralSingularity():
740 sing = self.sim.getSingularityInfo()
741 title = "Structural singularity"
742 text = title
743 text += "\n\nThe singularity can be reduced by freeing the following variables:"
744 msgs = {
745 "The singularity can be reduced by freeing the following variables" : sing.freeablevars
746 ,"Relations involved in the structural singularity" : sing.rels
747 ,"Variables involved in the structural singularity" : sing.vars
748 }
749 for k,v in msgs.iteritems():
750 text+="\n\n%s:" % k
751 if len(v):
752 _l = [j.getName() for j in v]
753 _l.sort()
754 text+= "\n\t" + "\n\t".join(_l)
755 else:
756 text += "\nnone"
757
758 _dialog = InfoDialog(self,self.window,text,title)
759 _dialog.run()
760
761 self.reporter.reportNote("System DoF check OK")
762
763 except RuntimeError, e:
764 self.stop_waiting()
765 self.reporter.reportError(str(e))
766 return
767
768 self.stop_waiting()
769
770 self.modelview.refreshtree()
771
772 def do_method(self,method):
773 if not self.sim:
774 self.reporter.reportError("No model selected yet")
775
776 self.sim.run(method)
777 self.modelview.refreshtree()
778
779 def do_quit(self):
780 print_loading_status("Saving window location")
781 self.reporter.clearPythonErrorCallback()
782
783 _w,_h = self.window.get_size()
784 _t,_l = self.window.get_position()
785 _display = self.window.get_screen().get_display().get_name()
786 self.prefs.setGeometrySizePosition(_display,"browserwin",_w,_h,_t,_l );
787
788 _p = self.browserpaned.get_position()
789 self.prefs.setGeometryValue(_display,"browserpaned",_p);
790
791 print_loading_status("Saving current directory")
792 self.prefs.setStringPref("Directories","fileopenpath",self.fileopenpath)
793
794 self.prefs.setBoolPref("Browser","auto_solve",self.is_auto)
795
796 print_loading_status("Saving preferences")
797 # causes prefs to be saved unless they are still being used elsewher
798 del(self.prefs)
799
800 print_loading_status("Closing down GTK")
801 gtk.main_quit()
802
803 print_loading_status("Clearing error callback")
804 self.reporter.clearPythonErrorCallback()
805
806 print_loading_status("Quitting")
807 return False
808
809 def on_tools_sparsity_click(self,*args):
810
811 self.reporter.reportNote("Preparing incidence matrix...")
812 _im = self.sim.getIncidenceMatrix();
813
814 self.reporter.reportNote("Plotting incidence matrix...")
815
816 _sp = IncidenceMatrixWindow(_im);
817 _sp.run();
818
819 def on_diagnose_blocks_click(self,*args):
820 try:
821 _bl = self.sim.getActiveBlock()
822 except RuntimeError, e:
823 self.reporter.reportError(str(e))
824 return
825 _db = DiagnoseWindow(self,_bl)
826 _db.run();
827
828 def on_add_observer_click(self,*args):
829 self.create_observer()
830
831 def on_keep_observed_click(self,*args):
832 print "KEEPING..."
833 if len(self.observers) <= 0:
834 self.reporter.reportError("No observer defined!")
835 return
836 self.tabs[self.currentobservertab].do_add_row()
837
838 def on_copy_observer_matrix_click(self,*args):
839 if self.clip == None:
840 self.clip = gtk.Clipboard()
841
842 if len(self.observers) <= 0:
843 self.reporter.reportError("No observer defined!")
844 return
845 self.tabs[self.currentobservertab].copy_to_clipboard(self.clip)
846
847 def on_use_relation_sharing_toggle(self,checkmenuitem,*args):
848 _v = checkmenuitem.get_active()
849 self.prefs.setBoolPref("Compiler","use_relation_sharing",_v)
850 self.reporter.reportNote("Relation sharing set to "+str(_v))
851
852 def on_show_solving_popup_toggle(self,checkmenuitem,*args):
853 _v = checkmenuitem.get_active()
854 self.prefs.setBoolPref("SolverReporter","show_popup",_v)
855 print "SET TO",_v
856
857 def on_close_on_converged_toggle(self,checkmenuitem,*args):
858 _v = checkmenuitem.get_active()
859 self.prefs.setBoolPref("SolverReporter","close_on_converged",_v)
860
861 def on_close_on_nonconverged_toggle(self,checkmenuitem,*args):
862 _v = checkmenuitem.get_active()
863 self.prefs.setBoolPref("SolverReporter","close_on_nonconverged",_v)
864
865 def on_show_variables_near_bounds_activate(self,*args):
866 _epsilon = 1e-4;
867 text = "Variables Near Bounds"
868 title=text;
869 text += "\n"
870 _vars = self.sim.getVariablesNearBounds(_epsilon)
871 if len(_vars):
872 for _v in _vars:
873 text += "\n%s"%_v.getName()
874 else:
875 text +="\nnone"
876 _dialog = InfoDialog(self,self.window,text,title)
877 _dialog.run()
878
879 # --------------------------------------------
880 # MODULE LIST
881
882 def module_activated(self, treeview, path, column, *args):
883 modules = self.library.getModules()
884 print "PATH",path
885 if len(path)==1:
886 self.reporter.reportNote("Launching of external editor not yet implemented")
887 elif len(path)==2:
888 if(self.modtank.has_key(path)):
889 _type = self.modtank[path];
890 self.reporter.reportNote("Creating simulation for type %s" % str(_type.getName()) )
891 self.do_sim(_type)
892 else:
893 self.reporter.reportError("Didn't find type corresponding to row")
894
895 # ----------------------------------
896 # ERROR PANEL
897
898 def get_error_row_data(self,sev,filename,line,msg):
899 _sevicon = {
900 0: self.iconok
901 ,1: self.iconinfo
902 ,2: self.iconwarning
903 ,3: self.iconerror
904 ,4: self.iconinfo
905 ,5: self.iconwarning
906 ,6: self.iconerror
907 }[sev]
908
909 _fontweight = pango.WEIGHT_NORMAL
910 if sev==6:
911 _fontweight = pango.WEIGHT_BOLD
912
913 _fgcolor = "black"
914 if sev==4:
915 _fgcolor = "#888800"
916 elif sev==5:
917 _fgcolor = "#884400"
918 elif sev==6:
919 _fgcolor = "#880000"
920 elif sev==0:
921 _fgcolor = BROWSER_FIXED_COLOR
922
923 if not filename and not line:
924 _fileline = ""
925 else:
926 if(len(filename) > 25):
927 filename = "..."+filename[-22:]
928 _fileline = filename + ":" + str(line)
929
930 _res = [_sevicon,_fileline,msg.rstrip(),_fgcolor,_fontweight]
931 #print _res
932 return _res
933
934 def error_callback(self,sev,filename,line,msg):
935 try:
936 pos = self.errorstore.append(None, self.get_error_row_data(sev, filename,line,msg))
937 path = self.errorstore.get_path(pos)
938 col = self.errorview.get_column(3)
939 self.errorview.scroll_to_cell(path,col)
940 except Exception,e:
941 print "UNABLE TO DISPLAY ERROR MESSAGE '%s'"%msg
942
943 return 0;
944
945 # --------------------------------
946 # BUTTON METHODS
947
948 def open_click(self,*args):
949 #print_loading_status("CURRENT FILEOPENPATH is",self.fileopenpath)
950 dialog = gtk.FileChooserDialog("Open ASCEND model...",
951 self.window,
952 gtk.FILE_CHOOSER_ACTION_OPEN,
953 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)
954 )
955 dialog.set_current_folder(self.fileopenpath)
956 dialog.set_default_response(gtk.RESPONSE_OK)
957 dialog.set_transient_for(self.window)
958 dialog.set_modal(True)
959
960 filter = gtk.FileFilter()
961 filter.set_name("*.a4c, *.a4l")
962 filter.add_pattern("*.[Aa]4[Cc]")
963 filter.add_pattern("*.[Aa]4[Ll]")
964 dialog.add_filter(filter)
965
966 filter = gtk.FileFilter()
967 filter.set_name("All files")
968 filter.add_pattern("*")
969 dialog.add_filter(filter)
970
971 response = dialog.run()
972 _filename = dialog.get_filename()
973 print "\nFILENAME SELECTED:",_filename
974
975 _path = dialog.get_current_folder()
976 if _path:
977 self.fileopenpath = _path
978
979 dialog.hide()
980
981 if response == gtk.RESPONSE_OK:
982 self.reporter.reportNote("File %s selected." % dialog.get_filename() )
983 self.library.clear()
984 self.do_open( _filename)
985
986 def reload_click(self,*args):
987 _type = None
988 if(self.sim):
989 _type = self.sim.getType().getName().toString();
990
991 self.library.clear()
992 self.do_open(self.filename)
993
994 if _type:
995 _t = self.library.findType(_type)
996 self.do_sim(_t)
997
998 def props_activate(self,widget,*args):
999 return self.modelview.props_activate(self,widget,*args)
1000
1001 def observe_activate(self,widget,*args):
1002 return self.modelview.observe_activate(self,widget,*args)
1003
1004 def solve_click(self,*args):
1005 #self.reporter.reportError("Solving simulation '" + self.sim.getName().toString() +"'...")
1006 self.do_solve()
1007
1008 def console_click(self,*args):
1009 try:
1010 console.start(self)
1011 except RuntimeError,e:
1012 self.reporter.reportError("Unable to start console: "+str(e));
1013
1014 def integrate_click(self,*args):
1015 self.do_integrate()
1016
1017 def check_click(self,*args):
1018 self.do_check()
1019 #self.reporter.reportError("CHECK clicked")
1020
1021 def preferences_click(self,*args):
1022 if not self.sim:
1023 self.reporter.reportError("No simulation created yet!");
1024
1025 _paramswin = SolverParametersWindow(self)
1026 _paramswin.show()
1027
1028 def methodrun_click(self,*args):
1029 _sel = self.methodsel.get_active_text()
1030 if _sel:
1031 _method = None
1032 _methods = self.sim.getType().getMethods()
1033 for _m in _methods:
1034 if _m.getName()==_sel:
1035 _method = _m
1036 if not _method:
1037 self.reporter.reportError("Method is not valid")
1038 return
1039 self.do_method(_method)
1040 else:
1041 self.reporter.reportError("No method selected")
1042
1043 def auto_toggle(self,button,*args):
1044 self.is_auto = button.get_active()
1045 if hasattr(self,'automenu'):
1046 self.automenu.set_active(self.is_auto)
1047 else:
1048 raise RuntimeError("no automenu")
1049
1050 #if self.is_auto:
1051 # self.reporter.reportSuccess("Auto mode is now ON")
1052 #else:
1053 # self.reporter.reportSuccess("Auto mode is now OFF")
1054
1055 def on_file_quit_click(self,*args):
1056 self.do_quit()
1057
1058 def on_tools_auto_toggle(self,checkmenuitem,*args):
1059 self.is_auto = checkmenuitem.get_active()
1060 self.autotoggle.set_active(self.is_auto)
1061
1062 def on_help_about_click(self,*args):
1063 _xml = gtk.glade.XML(self.glade_file,"aboutdialog")
1064 _about = _xml.get_widget("aboutdialog")
1065 _about.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
1066 _about.set_transient_for(self.window);
1067 _about.set_version(config.VERSION)
1068 _about.run()
1069 _about.destroy()
1070
1071 def on_help_contents_click(self,*args):
1072 _help = Help(HELP_ROOT)
1073 _help.run()
1074
1075 def on_show_fixable_variables_activate(self,*args):
1076 v = self.sim.getFixableVariables()
1077 text = "Fixable Variables"
1078 title = text
1079 text += "\n"
1080 if len(v):
1081 for var in v:
1082 text += "\n%s"%var
1083 else:
1084 text += "\nnone"
1085 _dialog = InfoDialog(self,self.window,text,title)
1086 _dialog.run()
1087
1088 def on_show_freeable_variables_activate(self,*args):
1089 v = self.sim.getFreeableVariables()
1090
1091 text = "Freeable Variables"
1092 title = text
1093 text += "\n"
1094 if len(v):
1095 for var in v:
1096 text += "\n%s" % var
1097 else:
1098 text += "\nnone"
1099 _dialog = InfoDialog(self,self.window,text,title)
1100 _dialog.run()
1101
1102 def on_show_external_functions_activate(self,*args):
1103 v = self.library.getExtMethods()
1104 text = "External Functions"
1105 title = text
1106 text +="\nHere is the list of external functions currently present in"
1107 text +=" the Library:"
1108
1109 if len(v):
1110 for ext in v:
1111 text += "\n\n%s (%d inputs, %d outputs):" % \
1112 (ext.getName(), ext.getNumInputs(), ext.getNumOutputs())
1113 text += "\n%s" % ext.getHelp()
1114 else:
1115 text +="\n\nNone"
1116 _dialog = InfoDialog(self,self.window,text,title)
1117 _dialog.run()
1118
1119 def on_maintabs_switch_page(self,notebook,page,pagenum):
1120 print("Page switched to %d" % pagenum)
1121 if pagenum in self.tabs.keys():
1122 self.currentobservertab = pagenum
1123
1124 def create_observer(self,name=None):
1125 _xml = gtk.glade.XML(self.glade_file,"observervbox");
1126 _label = gtk.Label();
1127 _tab = self.maintabs.append_page(_xml.get_widget("observervbox"),_label);
1128 _obs = ObserverTab(xml=_xml, name=name, browser=self, tab=_tab)
1129 _label.set_text(_obs.name)
1130 self.observers.append(_obs)
1131 self.tabs[_tab] = _obs
1132 self.currentobservertab = _tab
1133 return _obs
1134
1135 def sync_observers(self):
1136 for _o in self.observers:
1137 _o.sync()
1138
1139 def delete_event(self, widget, event):
1140 self.do_quit()
1141 return False
1142
1143 def observe(self,instance):
1144 if len(self.observers) ==0:
1145 self.create_observer()
1146 _observer = self.tabs[self.currentobservertab]
1147 _observer.add_instance(instance)
1148
1149 if __name__ == "__main__":
1150 b = Browser();
1151 b.run()

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