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

Contents of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2275 - (show annotations) (download) (as text)
Wed Aug 11 13:58:25 2010 UTC (13 years, 10 months ago) by jpye
File MIME type: text/x-python
File size: 39247 byte(s)
Fixing error return from asc_helmholtz function.
The bug with 'defaultall' functionality is still here... see boiler_simple_test mode in models/johnpye/fprops/rankine_fprops.a4c.
1 import sys
2 try:
3 import loading
4 #loading.print_status("Loading PSYCO")
5 #try:
6 # import psyco
7 # psyco.full()
8 # print "Running with PSYCO optimisation..."
9 #except ImportError:
10 # pass
11
12 loading.print_status("Loading python standard libraries")
13
14 import pygtk
15 pygtk.require('2.0')
16 import gtk
17
18 import gtkexcepthook
19
20 import re
21 import urlparse
22 import optparse
23 import platform
24 import sys
25
26 if platform.system() != "Windows":
27 try:
28 import dl
29 _dlflags = dl.RTLD_GLOBAL|dl.RTLD_NOW
30 except:
31 # On platforms that unilaterally refuse to provide the 'dl' module
32 # we'll just set the value and see if it works.
33 loading.print_status("Setting dlopen flags","Python 'dl' module not available on this system")
34 _dlflags = 258
35 # This sets the flags for dlopen used by python so that the symbols in the
36 # ascend library are made available to libraries dlopened within ASCEND:
37 sys.setdlopenflags(_dlflags)
38
39
40
41 loading.print_status("Loading LIBASCEND/ascpy")
42 import ascpy
43 import os.path
44
45 loading.print_status("Loading PyGTK, glade, pango")
46
47 import gtk.glade
48 import pango
49
50 loading.load_matplotlib()
51
52 loading.print_status("Loading ASCEND python modules")
53 from preferences import * # loading/saving of .ini options
54 from solverparameters import * # 'solver parameters' window
55 from help import * # viewing help files
56 from incidencematrix import * # incidence/sparsity matrix matplotlib window
57 from imagewindow import * # image viewer window
58 from observer import * # observer tab support
59 from properties import * # solver_var properties dialog
60 from varentry import * # for inputting of variables with units
61 from diagnose import * # for diagnosing block non-convergence
62 from solverreporter import * # solver status reporting
63 from moduleview import * # module browser
64 from modelview import * # model browser
65 from integrator import * # integrator dialog
66 from infodialog import * # general-purpose textual information dialog
67 from versioncheck import * # version check (contacts ascend.cruncher2.dyndns.org)
68 from unitsdialog import * # general-purpose textual information dialog
69 from solverhooks import * # solver hooks for use from Python layer
70 import config
71
72 #loading.complete();
73
74 except RuntimeError, e:
75 print "ASCEND had problems starting up. Please report the following"
76 print "error message on ASCEND bug tracker."
77 print "\n\nFull error message:",str(e)
78 print "\n\nPress ENTER to close this window."
79 sys.stdout.flush()
80 sys.stdin.readline();
81 sys.exit();
82
83 except ImportError, e:
84 print "\n\n------------------ ERROR ---------------------"
85 print "ASCEND had problems importing required Python modules."
86 print "\nPlease ensure you have all the runtime prerequisites installed."
87 print "Please then report a bug if you continue to have problems."
88 print "\nFull error message:",str(e)
89 if platform.system()=="Windows":
90 print "\nYou will also need to report the contents of any popup error"
91 print "messages from Windows if any were shown."
92 print "\n\nPress ENTER to close this window."
93 sys.stdout.flush()
94 sys.stdin.readline();
95 sys.exit();
96
97 loading.print_status("Starting GUI")
98
99 # This is my first ever GUI code so please be nice :)
100 # But I *have* at least read
101 # http://www.joelonsoftware.com/uibook/chapters/fog0000000057.html
102 # and leafed through
103 # http://developer.gnome.org/projects/gup/hig/
104
105 # The fancy tree-view gizmo is the GtkTreeView object. See the article
106 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/300304
107 # for the original source code on which my implementation was based.
108
109 ESCAPE_KEY = 65307
110
111 HELP_ROOT = None
112
113 #======================================
114 # Browser is the main ASCEND library/model browser window
115
116 class Browser:
117
118 # ---------------------------------
119 # SETUP
120
121 def __init__(self,librarypath=None,assetspath=None):
122
123 if assetspath==None:
124 assetspath=config.PYGTK_ASSETS
125
126 #--------
127 # load the file referenced in the command line, if any
128
129 loading.print_status("Parsing options","CONFIG = %s"%config.VERSION)
130
131 #print "Command-line options:",sys.argv
132
133 parser = optparse.OptionParser(usage="%prog [[-m typename] file]", version="gtkbrowser $rev$" )
134 # add options here if we want
135
136 #print "About to parse..."
137
138 if platform.system() == "Darwin":
139 parser.add_option("-p", "--silly-mac-thing"
140 ,action="store", type="string", dest="process_number"
141 ,help="Launch Services for Mac passes in a -psn-NNNNN argument that we need to swallow.")
142
143 parser.add_option("-m", "--model"
144 ,action="store", type="string", dest="model"
145 ,help="specify the model to instantiate upon loading modules")
146
147 parser.add_option("--pygtk-assets"
148 ,action="store", type="string", dest="assets_dir"
149 ,help="override the configuration value for the location of assets"\
150 +" required by PyGTK for the ASCEND GUI, optional"
151 ,default=assetspath
152 )
153
154 parser.add_option("--library"
155 ,action="store", type="string", dest="library_path"
156 ,help="override the configuration value for the library path"
157 ,default=librarypath
158 )
159
160 parser.add_option("--no-auto-sim"
161 ,action="store_false", dest="auto_sim"
162 ,help="disable auto-instantiation of MODEL named as the file stem"
163 ,default=True
164 )
165
166 (self.options, args) = parser.parse_args()
167
168 #print "OPTIONS_______________:",self.options
169
170 self.assets_dir = self.options.assets_dir
171 #loading.create_window(self.assets_dir)
172
173 self.observers = []
174 self.clip = None
175
176 #--------
177 # load up the preferences ini file
178
179 loading.print_status("Loading preferences")
180
181 self.prefs = Preferences()
182
183 _prefpath = self.prefs.getStringPref("Directories","librarypath",None)
184 _preffileopenpath = self.prefs.getStringPref("Directories","fileopenpath",None)
185 self.filename = None
186
187 #--------
188 # set up library path and the path to use for File->Open dialogs
189
190 if self.options.library_path != None:
191 _path = os.path.abspath(self.options.library_path)
192 _pathsrc = "command line options"
193 # when a special path is specified, use the last path component as the file-open location
194 if platform.system()=="Windows":
195 self.fileopenpath = _path.split(":").pop()
196 else:
197 self.fileopenpath = _path.split(":").pop()
198 else:
199 if _prefpath:
200 _path = _prefpath
201 _pathsrc = "user preferences"
202 else:
203 # default setting, but override with Windows registry if present
204 _path = config.LIBRARY_PATH
205 _pathsrc = "default (config.py)"
206
207 if platform.system()=="Windows":
208 # use the registry
209 try:
210 import _winreg
211 x=_winreg.ConnectRegistry(None,_winreg.HKEY_LOCAL_MACHINE)
212 y= _winreg.OpenKey(x,r"SOFTWARE\ASCEND")
213 _regpath,t = _winreg.QueryValueEx(y,"ASCENDLIBRARY")
214 _winreg.CloseKey(y)
215 _winreg.CloseKey(x)
216 _path = _regpath
217 os.environ['ASCENDLIBRARY'] = _regpath
218 _pathsrc = "Windows registry"
219 except:
220 # otherwise keep using the default
221 pass
222
223 if _preffileopenpath:
224 self.fileopenpath = _preffileopenpath
225 else:
226 self.fileopenpath = _path
227
228 #--------
229 # Create the ASCXX 'Library' object
230
231 loading.print_status("Creating ASCEND 'Library' object","ASCENDLIBRARY = "+_path+" FROM "+_pathsrc)
232 self.library = ascpy.Library(str(_path))
233
234 self.sim = None
235
236 #-------------------
237 # Set up the window and main widget actions
238
239 self.glade_file = os.path.join(self.assets_dir,config.GLADE_FILE)
240
241 loading.print_status("Setting up windows") #,"GLADE_FILE = %s" % self.glade_file)
242
243 glade = gtk.glade.XML(self.glade_file,"browserwin")
244
245 self.window = glade.get_widget("browserwin")
246
247
248 if not self.window:
249 raise RuntimeError("Couldn't load window from glade file")
250
251 _display = self.window.get_screen().get_display().get_name()
252 _geom=self.prefs.getGeometrySizePosition(_display,"browserwin")
253 if _geom:
254 self.window.resize(_geom[0],_geom[1])
255 self.window.move(_geom[2],_geom[3])
256
257 self.window.connect("delete_event", self.delete_event)
258
259 self.browserpaned=glade.get_widget("browserpaned")
260 _geom2=self.prefs.getGeometryValue(_display,"browserpaned")
261 if _geom2:
262 self.browserpaned.set_position(_geom2)
263
264 buttons = ["open","reload","solve","integrate","check","methodrun"]
265 for n in buttons:
266 name = "%sbutton"%n
267 setattr(self,name,glade.get_widget(name))
268 getattr(self,name).connect("clicked",getattr(self,"%s_click"%n))
269
270 widgets = ["autotoggle","automenu","methodsel","maintabs","lowertabs","consolescroll","statusbar","browsermenu"]
271 for n in widgets:
272 setattr(self,n,glade.get_widget(n))
273
274 self.autotoggle.connect("toggled",self.auto_toggle)
275
276 self.show_solving_popup=glade.get_widget("show_solving_popup")
277 self.show_solving_popup.set_active(self.prefs.getBoolPref("SolverReporter","show_popup",True))
278 self.close_on_converged=glade.get_widget("close_on_converged")
279 self.close_on_converged.set_active(self.prefs.getBoolPref("SolverReporter","close_on_converged",True))
280 self.close_on_nonconverged=glade.get_widget("close_on_nonconverged")
281 self.close_on_nonconverged.set_active(self.prefs.getBoolPref("SolverReporter","close_on_nonconverged",True))
282 self.solver_engine=glade.get_widget("solver_engine")
283
284 self.use_relation_sharing=glade.get_widget("use_relation_sharing")
285 self.use_relation_sharing.set_active(self.prefs.getBoolPref("Compiler","use_relation_sharing",True))
286
287 self.use_binary_compilation=glade.get_widget("use_binary_compilation")
288 self.use_binary_compilation.set_active(self.prefs.getBoolPref("Compiler","use_binary_compilation",False))
289 self.use_binary_compilation.set_sensitive(self.use_relation_sharing.get_active())
290
291 glade.signal_autoconnect(self)
292
293 #-------
294 # Status icons
295
296 self.fixedimg = gtk.Image()
297 _fixedimgpath = os.path.join(self.options.assets_dir,'locked.png')
298
299 # this stuff catches some strange environment-variable related problems on Mac OSX.
300 try:
301 if not os.path.exists(_fixedimgpath):
302 raise RuntimeError("Image file '%s' could not be found" % _fixedimgpath)
303 _fixedpixbuf = gtk.gdk.pixbuf_new_from_file(_fixedimgpath)
304 self.fixedimg.set_from_pixbuf(_fixedpixbuf)
305 except Exception,e:
306 raise RuntimeError("Failed to load pixbuf '%s' (%s)" % (_fixedimgpath, str(e)))
307
308 self.inactiveimg = gtk.Image()
309 self.inactiveimg.set_from_file(os.path.join(self.options.assets_dir,'unattached.png'))
310
311 self.iconstatusunknown = None
312 self.iconfixed = self.fixedimg.get_pixbuf()
313 self.iconsolved = self.window.render_icon(gtk.STOCK_YES,gtk.ICON_SIZE_MENU)
314 self.iconactive = self.window.render_icon(gtk.STOCK_NO,gtk.ICON_SIZE_MENU)
315 self.iconinactive = self.inactiveimg.get_pixbuf()
316 self.iconunsolved = None
317
318 self.statusicons={
319 ascpy.ASCXX_INST_STATUS_UNKNOWN: self.iconstatusunknown
320 ,ascpy.ASCXX_VAR_FIXED: self.iconfixed
321 ,ascpy.ASCXX_VAR_SOLVED: self.iconsolved
322 ,ascpy.ASCXX_VAR_ACTIVE: self.iconactive
323 ,ascpy.ASCXX_VAR_UNSOLVED: self.iconunsolved
324 ,ascpy.ASCXX_REL_INACTIVE: self.iconinactive
325 }
326
327
328 self.statusmessages={
329 ascpy.ASCXX_INST_STATUS_UNKNOWN: "Status unknown"
330 ,ascpy.ASCXX_VAR_FIXED: "Fixed"
331 ,ascpy.ASCXX_VAR_SOLVED: "Converged"
332 ,ascpy.ASCXX_VAR_ACTIVE: "Active (unconverged)"
333 ,ascpy.ASCXX_VAR_UNSOLVED: "Not yet visited"
334 ,ascpy.ASCXX_REL_INACTIVE: "Inactive"
335 }
336
337 #-------------------
338 # waitwin
339
340 self.waitwin = gtk.gdk.Window(self.window.window,
341 gtk.gdk.screen_width(),
342 gtk.gdk.screen_height(),
343 gtk.gdk.WINDOW_CHILD,
344 0,
345 gtk.gdk.INPUT_ONLY)
346
347 _cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
348 self.waitwin.set_cursor(_cursor)
349
350 #-------------------
351 # pixbufs to be used in the error listing
352
353 self.iconok = self.window.render_icon(gtk.STOCK_YES,gtk.ICON_SIZE_MENU)
354 self.iconinfo = self.window.render_icon(gtk.STOCK_DIALOG_INFO,gtk.ICON_SIZE_MENU)
355 self.iconwarning = self.window.render_icon(gtk.STOCK_DIALOG_WARNING,gtk.ICON_SIZE_MENU)
356 self.iconerror = self.window.render_icon(gtk.STOCK_DIALOG_ERROR,gtk.ICON_SIZE_MENU)
357
358 #--------------------
359 # pixbufs for solver_var status
360
361 #--------------------
362 # set up the error view
363
364 self.errorview = glade.get_widget("errorview")
365 errstorecolstypes = [gtk.gdk.Pixbuf,str,str,str,int]
366 self.errorstore = gtk.TreeStore(*errstorecolstypes)
367 errtitles = ["","Location","Message"];
368 self.errorview.set_model(self.errorstore)
369 self.errcols = [ gtk.TreeViewColumn() for _type in errstorecolstypes]
370
371 i = 0
372 for tvcolumn in self.errcols[:len(errtitles)]:
373 tvcolumn.set_title(errtitles[i])
374 self.errorview.append_column(tvcolumn)
375
376 if i>0:
377 _renderer = gtk.CellRendererText()
378 tvcolumn.pack_start(_renderer, True)
379 tvcolumn.add_attribute(_renderer, 'text', i)
380 if(i==2):
381 tvcolumn.add_attribute(_renderer, 'foreground', 3)
382 tvcolumn.add_attribute(_renderer, 'weight', 4)
383 else:
384 _renderer1 = gtk.CellRendererPixbuf()
385 tvcolumn.pack_start(_renderer1, False)
386 tvcolumn.add_attribute(_renderer1, 'pixbuf', int(0))
387
388 i = i + 1
389
390
391 #--------------------
392 # set up the error reporter callback
393 self.reporter = ascpy.getReporter()
394 self.reporter.setPythonErrorCallback(self.error_callback)
395
396
397 #-------
398 # Solver engine list
399
400 _slvlist = ascpy.getSolvers()
401 self.solver_engine_menu = gtk.Menu()
402 self.solver_engine_menu.show()
403 self.solver_engine.set_submenu(self.solver_engine_menu)
404 self.solver_engine_menu_dict = {}
405 _fmi = None
406 for _s in _slvlist:
407 _mi = gtk.RadioMenuItem(_fmi,_s.getName(),False)
408 if _fmi==None:
409 _fmi = _mi
410 _mi.show()
411 _mi.connect('toggled',self.on_select_solver_toggled,_s.getName())
412 self.solver_engine_menu.append(_mi)
413 self.solver_engine_menu_dict[_s.getName()]=_mi
414
415 _pref_solver = self.prefs.getStringPref("Solver","engine","QRSlv")
416 _mi = self.solver_engine_menu_dict.get(_pref_solver)
417 if _mi:
418 _mi.set_active(1)
419
420 #--------
421 # Assign an icon to the main window
422
423 self.icon = None
424 if config.ICON_EXTENSION:
425 _iconpath = ""
426 try:
427 _icon = gtk.Image()
428 _iconpath = os.path.join(self.assets_dir,'ascend'+config.ICON_EXTENSION)
429 _icon.set_from_file(_iconpath)
430 _iconpbuf = _icon.get_pixbuf()
431 self.window.set_icon(_iconpbuf)
432 self.icon = _iconpbuf
433 except Exception, e:
434 print "FAILED TO SET APPLICATION ICON PATH '%s': %s" % (_iconpath,str(e))
435 self.reporter.reportError("FAILED to set application icon '%s': %s"
436 % (_iconpath,str(e))
437 )
438
439 #-------------------
440 # set up the module view
441
442 self.modtank = {}
443 self.moduleview = ModuleView(self,glade, self.library)
444
445 #--------------------
446 # set up the methods combobox
447
448 self.methodstore = gtk.ListStore(str)
449 self.methodsel.set_model(self.methodstore)
450 _methodrenderer = gtk.CellRendererText()
451 self.methodsel.pack_start(_methodrenderer, True)
452 self.methodsel.add_attribute(_methodrenderer, 'text',0)
453
454 #--------
455 # set up the instance browser view
456
457 self.modelview = ModelView(self, glade)
458
459 #--------
460 # set up the tabs
461 self.tabs = {}
462 self.activetab = None # most recent observer tab
463
464 #--------
465 # set the state of the 'auto' toggle
466
467 self.is_auto = self.prefs.getBoolPref("Browser","auto_solve",True)
468 self.autotoggle.set_active(self.is_auto)
469 self.automenu.set_active(self.is_auto)
470
471 #--------
472 # tell libascend about this 'browser' object
473
474 #print dir(ascpy.Registry())
475 ascpy.Registry().set("browser",self)
476
477 #--------
478 # Set up SolverHooks
479
480 print "PYTHON: SETTING UP SOLVER HOOKS"
481 self.solverhooks = SolverHooksPythonBrowser(self)
482 ascpy.SolverHooksManager_Instance().setHooks(self.solverhooks)
483
484 #--------
485 # options
486
487 if(len(args)==1):
488 try:
489 self.do_open(args[0])
490 except RuntimeError,e:
491 self.reporter.reportError(str(e))
492 return
493
494 #print "Options: ",self.options
495
496 _model = None
497 if self.options.model:
498 _model = self.options.model
499 print "MODEL: '%s'" % _model
500 elif self.options.auto_sim:
501 _head, _tail = os.path.split(args[0])
502 if(_tail):
503 _model, _ext = os.path.splitext(_tail)
504
505 if _model:
506 try:
507 _t=self.library.findType(_model)
508 if not _t.isModel():
509 if self.options.auto_sim:
510 self.reporter.reportError("Won't auto-instantiate with type '%s': not a MODEL." % _model)
511 elif _t.hasParameters():
512 if self.options.auto_sim:
513 self.reporter.reportError("Won't auto-instantiate MODEL %s: model requires parameters." % _model)
514 else:
515 try:
516 self.do_sim(_t)
517 if not self.options.model:
518 self.reporter.reportNote("Instantiated self-titled model '%s'" %_model)
519 except RuntimeError, e:
520 self.reporter.reportError("Failed to create instance of '%s': %s"
521 %(_model, str(e))
522 );
523 except RuntimeError, e:
524 if self.options.model:
525 self.reporter.reportError("Unknown model type '%s': %s"
526 %(_model, str(e))
527 );
528
529
530 #--------
531 # report absence of solvers if nec.
532
533 if not len(ascpy.getSolvers()):
534 print "NO SOLVERS LOADED!"
535 self.reporter.reportError( "No solvers were loaded! ASCEND is probably not configured correctly." )
536
537 #--------
538 # IPython console, if available
539
540 import console
541 console.create_widget(self)
542
543 def run(self):
544 self.window.show()
545 loading.print_status("ASCEND is now running")
546 loading.complete()
547 gtk.main()
548
549 # ------------------
550 # SOLVER LIST
551
552 def set_solver(self,solvername):
553 """ this sets the active solver in the GUI, which is the default applied to newly instantiated models """
554 self.solver = ascpy.Solver(solvername)
555 self.prefs.setStringPref("Solver","engine",solvername)
556 self.reporter.reportNote("Set solver engine to '%s'" % solvername)
557
558 # --------------------------------------------
559 # MAJOR GUI COMMANDS
560
561 def on_fix_variable_activate(self,*args):
562 if not self.sim:
563 self.reporter.reportError("No model selected yet")
564 return
565 self.modelview.on_fix_variable_activate(*args)
566
567 def on_free_variable_activate(self,*args):
568 if not self.sim:
569 self.reporter.reportError("No model selected yet")
570 return
571 self.modelview.on_free_variable_activate(*args)
572
573 def on_select_solver_toggled(self,widget,solvername):
574 if widget.get_active():
575 self.set_solver(solvername)
576
577 def do_open(self,filename):
578 # TODO does the user want to lose their work?
579 # TODO do we need to chdir?
580
581 _context = self.statusbar.get_context_id("do_open")
582
583 self.errorstore.clear()
584 self.modelview.clear()
585
586 # self.library.clear()
587
588 #print "Filename =",filename
589 self.statusbar.push(_context,"Loading '"+filename+"'")
590 try:
591 self.filename = filename
592 # call the low-level 'load' command...
593 self.library.load(filename)
594 except RuntimeError,e:
595 self.statusbar.pop(_context)
596 raise
597
598 try:
599 self.statusbar.pop(_context)
600 except TypeError,e:
601 print "For some reason, a type error (context=%s,filename=%s): %s" % (_context,filename,e)
602
603 # Load the current list of modules into self.modules
604 self.moduleview.refresh(self.library)
605
606 self.sim = None;
607 self.maintabs.set_current_page(0);
608
609 # See http://www.daa.com.au/pipermail/pygtk/2005-October/011303.html
610 # for details on how the 'wait cursor' is done.
611 def start_waiting(self, message):
612 self.waitcontext = self.statusbar.get_context_id("waiting")
613 self.statusbar.push(self.waitcontext,message)
614
615 if self.waitwin:
616 self.waitwin.show()
617
618 while gtk.events_pending():
619 gtk.main_iteration()
620
621 def stop_waiting(self):
622 if self.waitwin:
623 self.statusbar.pop(self.waitcontext)
624 self.waitwin.hide()
625
626 def do_sim(self, type_object):
627 self.sim = None;
628 # TODO: clear out old simulation first!
629
630 #print "DO_SIM(%s)" % str(type_object.getName())
631 self.start_waiting("Compiling...")
632
633 try:
634 _v = self.prefs.getBoolPref("Compiler","use_relation_sharing",True)
635 ascpy.getCompiler().setUseRelationSharing(_v)
636
637 _v = self.prefs.getBoolPref("Compiler","use_binary_compilation",True)
638 ascpy.getCompiler().setBinaryCompilation(True)
639
640 self.sim = type_object.getSimulation(str(type_object.getName())+"_sim",False)
641
642 #self.reporter.reportNote("SIMULATION ASSIGNED")
643 except RuntimeError, e:
644 self.stop_waiting()
645 self.reporter.reportError(str(e))
646 return
647
648 self.stop_waiting()
649
650 # get method names and load them into the GUI
651 self.methodstore.clear()
652 _methods = self.sim.getType().getMethods()
653 _activemethod = None;
654 for _m in _methods:
655 _i = self.methodstore.append([_m.getName()])
656 if _m.getName()=="on_load":
657 self.methodsel.set_active_iter(_i)
658
659 self.modelview.setSimulation(self.sim)
660
661 # run the 'on_load' method
662 self.start_waiting("Running default method...")
663 try:
664 self.reporter.reportNote("SIMULATION CREATED, RUNNING DEFAULT METHOD NOW...")
665 self.sim.runDefaultMethod()
666 except RuntimeError, e:
667 self.stop_waiting()
668 self.reporter.reportError(str(e))
669 return
670 self.stop_waiting()
671
672 self.modelview.refreshtree()
673
674 def do_solve_if_auto(self):
675 if self.is_auto:
676 self.sim.checkInstance()
677 self.do_solve()
678 else:
679 try:
680 self.sim.processVarStatus()
681 except RuntimeError,e:
682 self.reporter.reportError(str(e))
683 self.modelview.refreshtree()
684
685 self.sync_observers()
686
687 def do_solve(self):
688 if not self.sim:
689 self.reporter.reportError("No model selected yet")
690 return
691
692 try:
693 self.sim.build()
694 except RuntimeError,e:
695 self.reporter.reportError("Couldn't build system: %s" % str(e));
696 return
697
698 if not hasattr(self,'solver'):
699 self.reporter.reportError("No solver assigned!")
700 return
701
702 self.start_waiting("Solving with %s..." % self.solver.getName())
703
704 if self.prefs.getBoolPref("SolverReporter","show_popup",True):
705 reporter = PopupSolverReporter(self,self.sim.getNumVars())
706 else:
707 reporter = SimpleSolverReporter(self)
708
709 try:
710 self.sim.solve(self.solver,reporter)
711 except RuntimeError,e:
712 self.reporter.reportError(str(e))
713
714 self.stop_waiting()
715
716 self.modelview.refreshtree()
717
718 def do_integrate(self):
719 if not self.sim:
720 self.reporter.reportError("No model selected yet")
721 return
722
723 try:
724 self.sim.build()
725 except RuntimeError,e:
726 self.reporter.reportError("Couldn't build system: %s",str(e))
727 return
728
729 integwin = IntegratorWindow(self,self.sim)
730 _integratorreporter = integwin.run()
731 if _integratorreporter!=None:
732 _integratorreporter.run()
733 self.sim.processVarStatus()
734 self.modelview.refreshtree()
735
736
737 def do_check(self):
738 if not self.sim:
739 self.reporter.reportError("No model selected yet")
740 return
741
742 try:
743 self.sim.build()
744 except RuntimeError,e:
745 self.reporter.reportError("Couldn't build system: %s",str(e));
746 return
747
748 self.start_waiting("Checking system...")
749
750 try:
751 self.sim.checkInstance()
752 self.reporter.reportWarning("System instance check run, check above for error (if any).")
753 # the above gives output but doesn't throw errors or return a status.
754 # ... this is a problem (at the C level)
755
756 status = self.sim.checkDoF()
757 if status==ascpy.ASCXX_DOF_UNDERSPECIFIED:
758 self.on_show_fixable_variables_activate(None)
759 elif status==ascpy.ASCXX_DOF_OVERSPECIFIED:
760 self.on_show_freeable_variables_activate(None)
761 elif status==ascpy.ASCXX_DOF_STRUCT_SINGULAR:
762 if not self.sim.checkStructuralSingularity():
763 sing = self.sim.getSingularityInfo()
764 title = "Structural singularity"
765 text = title
766 msgs = {
767 "The singularity can be reduced by freeing the following variables" : sing.freeablevars
768 ,"Relations involved in the structural singularity" : sing.rels
769 ,"Variables involved in the structural singularity" : sing.vars
770 }
771 for k,v in msgs.iteritems():
772 text+="\n\n%s:" % k
773 if len(v):
774 _l = [j.getName() for j in v]
775 _l.sort()
776 text+= "\n\t" + "\n\t".join(_l)
777 else:
778 text += "\nnone"
779
780 _dialog = InfoDialog(self,self.window,text,title)
781 _dialog.run()
782 else:
783 self.reporter.reportNote("System DoF check OK")
784
785 except RuntimeError, e:
786 self.stop_waiting()
787 self.reporter.reportError(str(e))
788 return
789
790 self.stop_waiting()
791 self.modelview.refreshtree()
792
793 def do_method(self,method):
794 if not self.sim:
795 self.reporter.reportError("No model selected yet")
796
797 try:
798 self.sim.build()
799 except RuntimeError,e:
800 self.reporter.reportError("Couldn't build system: %s" % str(e));
801 return
802
803 try:
804 self.sim.run(method)
805 except RuntimeError,e:
806 self.reporter.reportError(str(e))
807
808 self.sim.processVarStatus()
809 self.modelview.refreshtree()
810
811 def do_quit(self):
812 loading.print_status("Saving window location")
813 self.reporter.clearPythonErrorCallback()
814
815 _w,_h = self.window.get_size()
816 _t,_l = self.window.get_position()
817 _display = self.window.get_screen().get_display().get_name()
818 self.prefs.setGeometrySizePosition(_display,"browserwin",_w,_h,_t,_l );
819
820 _p = self.browserpaned.get_position()
821 self.prefs.setGeometryValue(_display,"browserpaned",_p);
822
823 loading.print_status("Saving current directory")
824 self.prefs.setStringPref("Directories","fileopenpath",self.fileopenpath)
825
826 self.prefs.setBoolPref("Browser","auto_solve",self.is_auto)
827
828 loading.print_status("Saving preferences")
829 # causes prefs to be saved unless they are still being used elsewher
830 del(self.prefs)
831
832 loading.print_status("Clearing error callback")
833 self.reporter.clearPythonErrorCallback()
834
835 loading.print_status("Closing down GTK")
836 gtk.main_quit()
837
838 loading.print_status("Clearing library")
839 self.library.clear()
840
841 loading.print_status("Quitting")
842
843 return False
844
845 def on_tools_sparsity_click(self,*args):
846
847 self.reporter.reportNote("Preparing incidence matrix...")
848 try:
849 _im = self.sim.getIncidenceMatrix()
850 self.reporter.reportNote("Plotting incidence matrix...")
851 _sp = IncidenceMatrixWindow(_im)
852 _sp.run()
853 except RuntimeError,e:
854 self.reporter.reportError(str(e))
855
856 def on_units_click(self,*args):
857 T = self.modelview.get_selected_type()
858 _un = UnitsDialog(self,T)
859 _un.run()
860
861 def on_tools_incidencegraph_click(self,*args):
862 self.reporter.reportNote("Preparing incidence graph...")
863 import tempfile
864 f,fname = tempfile.mkstemp(suffix=".png")
865 f = file(fname,'wb')
866 self.reporter.reportNote("temp file name = %s" % fname)
867 self.reporter.reportNote("file = %s" % f)
868 self.start_waiting("Creating incidence graph...")
869 try:
870 self.sim.write(f,'dot') # create a PNG file in f
871 except Exception,e:
872 self.stop_waiting()
873 self.reporter.reportError("Faile-d to create incidence graph: %s" % str(e))
874 return
875 f.close()
876 self.stop_waiting()
877 _ig = ImageWindow(self, self.window, fname, title="Incidence Graph", delete=True)
878 _ig.run()
879
880 def on_tools_repaint_tree_activate(self,*args):
881 self.reporter.reportNote("Repainting model view...")
882 self.modelview.refreshtree()
883
884 def on_diagnose_blocks_click(self,*args):
885 try:
886 _bl = self.sim.getActiveBlock()
887 _db = DiagnoseWindow(self,_bl)
888 _db.run();
889 except RuntimeError, e:
890 self.reporter.reportError(str(e))
891 return
892
893 def on_add_observer_click(self,*args):
894 self.create_observer()
895
896 def on_keep_observed_click(self,*args):
897 print "KEEPING..."
898 if len(self.observers) <= 0:
899 self.reporter.reportError("No observer defined!")
900 return
901 self.tabs[self.currentobservertab].do_add_row()
902
903 def on_copy_observer_matrix_click(self,*args):
904 if self.clip == None:
905 self.clip = gtk.Clipboard()
906
907 if len(self.observers) <= 0:
908 self.reporter.reportError("No observer defined!")
909 return
910 self.tabs[self.currentobservertab].copy_to_clipboard(self.clip)
911
912 def on_use_relation_sharing_toggle(self,checkmenuitem,*args):
913 _v = checkmenuitem.get_active()
914 self.prefs.setBoolPref("Compiler","use_relation_sharing",_v)
915 self.reporter.reportNote("Relation sharing set to "+str(_v))
916 self.use_binary_compilation.set_sensitive(_v);
917
918 def on_use_binary_compilation_toggle(self,checkmenuitem,*args):
919 _v = checkmenuitem.get_active()
920 self.prefs.setBoolPref("Compiler","use_binary_compilation",_v)
921 self.reporter.reportNote("Binary compilation set to "+str(_v))
922
923 def on_show_solving_popup_toggle(self,checkmenuitem,*args):
924 _v = checkmenuitem.get_active()
925 self.prefs.setBoolPref("SolverReporter","show_popup",_v)
926 print "SET TO",_v
927
928 def on_close_on_converged_toggle(self,checkmenuitem,*args):
929 _v = checkmenuitem.get_active()
930 self.prefs.setBoolPref("SolverReporter","close_on_converged",_v)
931
932 def on_close_on_nonconverged_toggle(self,checkmenuitem,*args):
933 _v = checkmenuitem.get_active()
934 self.prefs.setBoolPref("SolverReporter","close_on_nonconverged",_v)
935
936 def on_show_variables_near_bounds_activate(self,*args):
937 _epsilon = 1e-4;
938 try:
939 _vars = self.sim.getVariablesNearBounds(_epsilon)
940 except RuntimeError,e:
941 self.reporter.reportError("Unable to show variables near bounds:\n%s"%str(e))
942 return
943 text = "Variables Near Bounds"
944 title=text;
945 text += "\n"
946 if len(_vars):
947 for _v in _vars:
948 text += "\n%s"%_v.getName()
949 else:
950 text +="\nnone"
951 _dialog = InfoDialog(self,self.window,text,title)
952 _dialog.run()
953
954 def on_show_vars_far_from_nominals_activate(self,*args):
955 _bignum = self.prefs.getRealPref("Browser","far_from_nominals",10);
956 try:
957 _vars = self.sim.getVariablesFarFromNominals(_bignum)
958 except RuntimeError,e:
959 self.reporter.reportError("Unable to show variables far from nominals:\n%s"%str(e))
960 return
961 text = "Variables Far from Nominals"
962 title=text;
963 text += "\n"
964 if len(_vars):
965 for _v in _vars:
966 text += "\n%s"%_v.getName()
967 else:
968 text +="\nnone"
969
970 text+="\n\nAbove calculated using a relative error of %f" % float(_bignum)
971 text+="\nModify this value in .ascend.ini, section '[Browser]', key 'far_from_nominals'."
972 _dialog = InfoDialog(self,self.window,text,title)
973 _dialog.run()
974
975 # ----------------------------------
976 # ERROR PANEL
977
978 def get_error_row_data(self,sev,filename,line,msg):
979 try:
980 _sevicon = {
981 0 : self.iconok
982 ,1 : self.iconinfo
983 ,2 : self.iconwarning
984 ,4 : self.iconerror
985 ,8 : self.iconinfo
986 ,16 : self.iconwarning
987 ,32 : self.iconerror
988 ,64 : self.iconerror
989 }[sev]
990 except KeyError:
991 _sevicon = self.iconerror
992
993 _fontweight = pango.WEIGHT_NORMAL
994 if sev==32 or sev==64:
995 _fontweight = pango.WEIGHT_BOLD
996
997 _fgcolor = "black"
998 if sev==8:
999 _fgcolor = "#888800"
1000 elif sev==16:
1001 _fgcolor = "#884400"
1002 elif sev==32 or sev==64:
1003 _fgcolor = "#880000"
1004 elif sev==0:
1005 _fgcolor = BROWSER_FIXED_COLOR
1006
1007 if not filename and not line:
1008 _fileline = ""
1009 else:
1010 if(len(filename) > 25):
1011 filename = "..."+filename[-22:]
1012 _fileline = filename + ":" + str(line)
1013
1014 _res = (_sevicon,_fileline,msg.rstrip(),_fgcolor,_fontweight)
1015 #print _res
1016 return _res
1017
1018 def error_callback(self,sev,filename,line,msg):
1019 #print "SEV =",sev
1020 #print "FILENAME =",filename
1021 #print "LINE =",line
1022 #print "MSG =",msg
1023 pos = self.errorstore.append(None, self.get_error_row_data(sev, filename,line,msg))
1024 path = self.errorstore.get_path(pos)
1025 col = self.errorview.get_column(3)
1026 self.errorview.scroll_to_cell(path,col)
1027 return 0;
1028
1029 # --------------------------------
1030 # BUTTON METHODS
1031
1032 def open_click(self,*args):
1033 #loading.print_status("CURRENT FILEOPENPATH is",self.fileopenpath)
1034 dialog = gtk.FileChooserDialog("Open ASCEND model...",
1035 self.window,
1036 gtk.FILE_CHOOSER_ACTION_OPEN,
1037 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)
1038 )
1039 dialog.set_current_folder(self.fileopenpath)
1040 dialog.set_default_response(gtk.RESPONSE_OK)
1041 dialog.set_transient_for(self.window)
1042 dialog.set_modal(True)
1043
1044 filter = gtk.FileFilter()
1045 filter.set_name("*.a4c, *.a4l")
1046 filter.add_pattern("*.[Aa]4[Cc]")
1047 filter.add_pattern("*.[Aa]4[Ll]")
1048 dialog.add_filter(filter)
1049
1050 filter = gtk.FileFilter()
1051 filter.set_name("All files")
1052 filter.add_pattern("*")
1053 dialog.add_filter(filter)
1054
1055 response = dialog.run()
1056 _filename = dialog.get_filename()
1057 print "\nFILENAME SELECTED:",_filename
1058
1059 _path = dialog.get_current_folder()
1060 if _path:
1061 self.fileopenpath = _path
1062
1063 dialog.hide()
1064
1065 if response == gtk.RESPONSE_OK:
1066 self.reporter.reportNote("File %s selected." % dialog.get_filename() )
1067 self.library.clear()
1068 try:
1069 self.do_open( _filename)
1070 except RuntimeError,e:
1071 self.reporter.reportError(str(e))
1072
1073 def reload_click(self,*args):
1074 _type = None
1075
1076 if not self.filename:
1077 self.reporter.reportError("No file loaded yet!")
1078 return
1079
1080 if self.sim:
1081 _type = self.sim.getType().getName().toString();
1082
1083 self.library.clear()
1084
1085 try:
1086 self.do_open(self.filename)
1087 if _type:
1088 _t = self.library.findType(_type)
1089 self.do_sim(_t)
1090 except RuntimeError,e:
1091 self.reporter.reportError(str(e))
1092
1093 def props_activate(self,widget,*args):
1094 return self.modelview.props_activate(self,widget,*args)
1095
1096 def observe_activate(self,widget,*args):
1097 return self.modelview.observe_activate(self,widget,*args)
1098
1099 def solve_click(self,*args):
1100 #self.reporter.reportError("Solving simulation '" + self.sim.getName().toString() +"'...")
1101 self.do_solve()
1102
1103 def console_click(self,*args):
1104 self.lowertabs.set_current_page(1)
1105 self.consoletext.grab_focus()
1106
1107 def integrate_click(self,*args):
1108 self.do_integrate()
1109
1110 def check_click(self,*args):
1111 self.do_check()
1112 #self.reporter.reportError("CHECK clicked")
1113
1114 def preferences_click(self,*args):
1115 if not self.sim:
1116 self.reporter.reportError("No simulation created yet!");
1117 self.sim.setSolver(self.solver)
1118 _params = self.sim.getParameters()
1119 _paramswin = SolverParametersWindow(
1120 browser=self
1121 ,params=_params
1122 ,name=self.solver.getName()
1123 )
1124 if _paramswin.run() == gtk.RESPONSE_OK:
1125 print "PARAMS UPDATED"
1126 self.sim.setParameters(_paramswin.params)
1127 else:
1128 print "PARAMS NOT UPDATED"
1129
1130 def methodrun_click(self,*args):
1131 _sel = self.methodsel.get_active_text()
1132 if _sel:
1133 _method = None
1134 _methods = self.sim.getType().getMethods()
1135 for _m in _methods:
1136 if _m.getName()==_sel:
1137 _method = _m
1138 if not _method:
1139 self.reporter.reportError("Method is not valid")
1140 return
1141 self.do_method(_method)
1142 else:
1143 self.reporter.reportError("No method selected")
1144
1145 def auto_toggle(self,button,*args):
1146 self.is_auto = button.get_active()
1147 if hasattr(self,'automenu'):
1148 self.automenu.set_active(self.is_auto)
1149 else:
1150 raise RuntimeError("no automenu")
1151
1152 #if self.is_auto:
1153 # self.reporter.reportSuccess("Auto mode is now ON")
1154 #else:
1155 # self.reporter.reportSuccess("Auto mode is now OFF")
1156
1157 def on_file_quit_click(self,*args):
1158 self.do_quit()
1159
1160 def on_tools_auto_toggle(self,checkmenuitem,*args):
1161 self.is_auto = checkmenuitem.get_active()
1162 self.autotoggle.set_active(self.is_auto)
1163
1164 def on_help_about_click(self,*args):
1165 _xml = gtk.glade.XML(self.glade_file,"aboutdialog")
1166 _about = _xml.get_widget("aboutdialog")
1167 _about.set_transient_for(self.window);
1168 _about.set_version(config.VERSION)
1169 _about.run()
1170 _about.destroy()
1171
1172 def on_help_contents_click(self,*args):
1173 _help = Help(HELP_ROOT)
1174 _help.run()
1175
1176 def on_report_a_bug_click(self,*args):
1177 import urllib
1178 import platform
1179 _plat = str(platform.system())
1180 _version = config.VERSION
1181 _help = Help(
1182 url="http://ascendbugs.cheme.cmu.edu/report/?project_id=ascend&platform=%s&build=%s"
1183 % (_plat,_version)
1184 )
1185 _help.run()
1186
1187 def on_help_check_for_updates_click(self,*args):
1188 v = VersionCheck()
1189 title = "Check for updates"
1190 text = "Your version is %s\n" % config.VERSION
1191 try:
1192 v.check()
1193 if config.VERSION==v.latest:
1194 text += "You are running the latest released version"
1195 else:
1196 text += "Latest version is %s\n" % v.latest
1197 if v.info:
1198 text += "Get more info at %s\n" % v.info
1199 if v.download:
1200 text += "Download from %s\n" % v.download
1201 except Exception, e:
1202 text += "\nUnable to check version\n"
1203 text += str(e)
1204
1205 _dialog = InfoDialog(self,self.window,text,title)
1206 _dialog.run()
1207
1208 def on_show_fixable_variables_activate(self,*args):
1209 try:
1210 v = self.sim.getFixableVariables()
1211 except Exception,e:
1212 self.reporter.reportError("Unable to show fixable variables: %s"%str(e))
1213 return
1214 text = "Fixable Variables"
1215 title = text
1216 text += "\n"
1217 if len(v):
1218 for var in v:
1219 text += "\n%s"%var
1220 else:
1221 text += "\nnone"
1222 _dialog = InfoDialog(self,self.window,text,title)
1223 _dialog.run()
1224
1225 def on_show_fixed_vars_activate(self,*args):
1226 try:
1227 v = self.sim.getFixedVariables()
1228 except RuntimeError,e:
1229 self.reporter.reportError("Unable to show fixed variables: %s"%str(e))
1230 return
1231 text = "%d fixed variables:" % len(v)
1232 title = "Fixed Variables"
1233 text += "\n"
1234 if len(v):
1235 for var in v:
1236 text += "\n%s\t= %f"%(str(var),var.getValue())
1237 else:
1238 text += "\nnone"
1239 _dialog = InfoDialog(self,self.window,text,title,tabs=[100,200])
1240 _dialog.run()
1241
1242 def on_show_freeable_variables_activate(self,*args):
1243 try:
1244 v = self.sim.getFreeableVariables()
1245 except RuntimeError,e:
1246 self.reporter.reportError("Unable to show freeable variables: %s"%str(e))
1247 return
1248 text = "Freeable Variables"
1249 title = text
1250 text += "\n"
1251 if len(v):
1252 for var in v:
1253 text += "\n%s" % var
1254 else:
1255 text += "\nnone"
1256 _dialog = InfoDialog(self,self.window,text,title)
1257 _dialog.run()
1258
1259 def on_show_external_functions_activate(self,*args):
1260 v = self.library.getExtMethods()
1261 text = "External Functions"
1262 title = text
1263 text +="\nHere is the list of external functions currently present in"
1264 text +=" the Library:"
1265
1266 if len(v):
1267 for ext in v:
1268 text += "\n\n%s (%d inputs, %d outputs):" % \
1269 (ext.getName(), ext.getNumInputs(), ext.getNumOutputs())
1270 text += "\n%s" % ext.getHelp()
1271 else:
1272 text +="\n\nNone"
1273 _dialog = InfoDialog(self,self.window,text,title)
1274 _dialog.run()
1275
1276 def on_notes_view_activate(self,*args):
1277 t = None
1278 try:
1279 D = self.library.getAnnotationDatabase()
1280 i = self.modelview.get_selected_instance()
1281 if i and i.isModel():
1282 t = i.getType()
1283 else:
1284 self.reporter.reportError("First select a MODEL instance");
1285 return
1286 v = D.getNotes(t)
1287 except RuntimeError,e:
1288 self.reporter.reportError("Unable to show notes: %s"%str(e))
1289 return
1290 text = "Notes for '%s'" % t.getName()
1291 title = text
1292 text += "\nHere are all notes defined within this MODEL:"
1293 nn = {}
1294 if len(v):
1295 for n in v:
1296 text += "\n\n%s (%s):" % (n.getId(), n.getLanguage())
1297 text += "\n\t%s" % n.getText()
1298 else:
1299 text += "\n\nThere are no noted defined locally within in this model"
1300
1301 _dialog = InfoDialog(self,self.window,text,title)
1302 _dialog.run()
1303
1304 def on_maintabs_switch_page(self,notebook,page,pagenum):
1305 #print("Page switched to %d" % pagenum)
1306 if pagenum in self.tabs.keys():
1307 self.currentobservertab = pagenum
1308
1309 def create_observer(self,name=None):
1310 _xml = gtk.glade.XML(self.glade_file,"observervbox");
1311 _label = gtk.Label();
1312 _tab = self.maintabs.append_page(_xml.get_widget("observervbox"),_label);
1313 _obs = ObserverTab(xml=_xml, name=name, browser=self, tab=_tab)
1314 _label.set_text(_obs.name)
1315 self.observers.append(_obs)
1316 self.tabs[_tab] = _obs
1317 self.currentobservertab = _tab
1318 return _obs
1319
1320 def sync_observers(self):
1321 for _o in self.observers:
1322 _o.sync()
1323
1324 def delete_event(self, widget, event):
1325 self.do_quit()
1326 return False
1327
1328 def observe(self,instance):
1329 if len(self.observers) ==0:
1330 self.create_observer()
1331 _observer = self.tabs[self.currentobservertab]
1332 _observer.add_instance(instance)
1333
1334 if __name__ == "__main__":
1335 b = Browser();
1336 b.run()

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