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

Contents of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


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

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