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

Contents of /trunk/pygtk/integrator.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2684 - (show annotations) (download) (as text)
Tue Feb 26 01:56:46 2013 UTC (6 years, 10 months ago) by sreenatha
File MIME type: text/x-python
File size: 11033 byte(s)
Merging GSOC2012 contributions from Sreenatha, after some modifications made to fix minor bugs -- jpye.
1 import ascpy
2 import time
3 import gtk
4 import time
5 from varentry import *
6 from preferences import *
7 from integratorreporter import *
8 from solverparameters import *
9 from infodialog import *
10 import tempfile
11
12 class IntegratorError(RuntimeError):
13 def __init__(self,msg):
14 self.msg = msg
15 def __str__(self):
16 return "Input Error: %s" % self.msg;
17
18 class IntegratorWindow:
19 def __init__(self,browser,sim):
20 # create a new integrator straight away
21 self.integrator = ascpy.Integrator(sim)
22 self.engines = self.integrator.getEngines()
23
24 self.browser=browser
25 self.prefs = Preferences()
26
27 try:
28 self.integrator.findIndependentVar()
29 self.indepvar = self.integrator.getIndependentVariable()
30 except RuntimeError,e:
31 self.browser.reporter.reportNote(str(e))
32 self.indepvar = None
33 return
34
35 # locate all the widgets
36 self.browser.builder.add_objects_from_file(self.browser.glade_file, ["integratorwin","list_of_td"])
37 self.browser.builder.connect_signals(self)
38
39 self.window = self.browser.builder.get_object("integratorwin")
40 self.window.set_transient_for(self.browser.window)
41
42 self.engineselect = self.browser.builder.get_object("engineselect")
43 self.beginentry = self.browser.builder.get_object("beginentry")
44 self.durationentry = self.browser.builder.get_object("durationentry")
45 self.nstepsentry = self.browser.builder.get_object("nstepsentry")
46 self.timedistributionselect = self.browser.builder.get_object("timedistributionselect")
47 self.settings = {
48 # input field: [pref name, default value, export-to-integrator function]
49 "initialstep": [1,lambda x:self.integrator.setInitialSubStep(float(x))]
50 ,"minstep":[0.001,lambda x:self.integrator.setMinSubStep(float(x))]
51 ,"maxstep":[1000,lambda x:self.integrator.setMaxSubStep(float(x))]
52 ,"maxsteps":[100,lambda x:self.integrator.setMaxSubSteps(int(x))]
53 }
54
55 self.integratorentries={}
56 for _k in self.settings.keys():
57 _w = self.browser.builder.get_object(_k+"entry")
58 if not _w:
59 raise RuntimeError("Couldn't find entry for"+_k)
60 self.integratorentries[_k]=_w
61
62 # fill values from user preferences, system values, etc
63 self.fill_values()
64
65 # set the engine initially
66 try:
67 self.integrator.setEngine(self.engines[self.engineselect.get_active()])
68 except:
69 # perhaps no integrators are available
70 pass
71
72 def fill_values(self):
73 _enginestore = gtk.ListStore(str)
74 self.engineselect.set_model(_enginestore)
75 _cell = gtk.CellRendererText()
76 self.engineselect.pack_start(_cell, True)
77 self.engineselect.add_attribute(_cell, 'text', 0)
78
79 _engpref = self.prefs.getStringPref("Integrator","engine","LSODE")
80 _engindex = 0
81 _i = 0
82 if len(self.engines):
83 for k in self.engines:
84 _row = _enginestore.append()
85 _enginestore.set(_row,0,k)
86 if k==_engpref:
87 _engindex=_i
88 _i += 1
89
90 # set preferred integrator
91 self.engineselect.set_active(_engindex)
92 self.engineselect.set_sensitive(True)
93 else:
94 _row = _enginestore.append()
95 _enginestore.set(_row,0,"No integrators available")
96 self.engineselect.set_active(0)
97 self.engineselect.set_sensitive(False)
98
99 # get the current time value as the beginentry...
100 print "SEARCHING FOR TIME VAR..."
101 try:
102 _u = self.indepvar.getInstance().getType().getPreferredUnits()
103 if _u is None:
104 _u = self.indepvar.getInstance().getType().getDimensions().getDefaultUnits()
105 #_t = self.integrator.getCurrentTime();
106 _t = str(self.indepvar.getInstance().getRealValue() / _u.getConversion())
107 self.beginentry.set_text(str(_t)+" "+_u.getName().toString())
108 self.parse_entry(self.beginentry)
109 _dur = self.prefs.getStringPref("Integrator","duration","100")
110 self.durationentry.set_text(_dur+" "+_u.getName().toString())
111 self.parse_entry(self.durationentry)
112 except RuntimeError,e:
113 self.browser.reporter.reportNote(str(e))
114 self.beginentry.set_text("0")
115
116 self.nstepsentry.set_text("100")
117
118 # set preferred timesteps etc
119 for _k,_v in self.settings.iteritems():
120 if _k!="maxsteps":
121 _a = _u.getName().toString()
122 self.integratorentries[_k].set_text(self.prefs.getStringPref("Integrator",_k,str(_v[0]))+" "+_a)
123 self.parse_entry(self.integratorentries[_k])
124 else :
125 self.integratorentries[_k].set_text(self.prefs.getStringPref("Integrator",_k,str(_v[0])))
126
127
128 def on_integratorcancel_clicked(self,*args):
129 self.browser.reporter.reportNote("CANCELLING");
130 self.window.response(gtk.RESPONSE_CANCEL)
131
132 def on_entry_key_press_event(self,widget,event):
133 keyname = gtk.gdk.keyval_name(event.keyval)
134 if keyname=="Return":
135 self.window.response(gtk.RESPONSE_OK)
136 return True
137 elif keyname=="Escape":
138 self.window.response(gtk.RESPONSE_CANCEL)
139 return True;
140 return False;
141
142 def on_engineselect_changed(self,widget,*args):
143 index = widget.get_active()
144 print "Setting engine to %d" % index
145 print "Engines are",self.engines
146 print "Selection is %s" % self.engines[index]
147 self.integrator.setEngine(self.engines[index])
148
149 def on_moreparametersbutton_clicked(self,*args):
150 print "ZO YOU WANT MORE PAHAMETERS EH!"
151 try:
152 _name = self.integrator.getName()
153 print "NAME = %s" % _name
154 _params = self.integrator.getParameters()
155 except RuntimeError,e:
156 self.browser.reporter.reportError(str(e))
157 return
158 print "CREATING SOLVERPARAMETERSWINDOW"
159 _paramswin = SolverParametersWindow(self.browser,_params,_name)
160 print "RUNNING SOLVERPARAMETERSWINDOW"
161 if _paramswin.run() == gtk.RESPONSE_OK:
162 print "GOT OK RESPONSE"
163 self.integrator.setParameters(_params)
164 print "PARAMETERS UPDATED"
165
166 def run(self):
167 if self.indepvar == None:
168 return
169 # focus the engine select box when we start...
170 self.engineselect.grab_focus()
171
172 # loop around unitil either cancelled or valid entries are input
173 _ok = False
174 while True:
175 try:
176 _res = self.window.run()
177 if _res == gtk.RESPONSE_OK:
178 self.check_inputs()
179 _ok=True
180 break
181 else:
182 #self.browser.reporter.reportNote("CANCEL event received");
183 break
184 except IntegratorError,e:
185 self.browser.reporter.reportError(str(e))
186 # continue
187
188 if _ok:
189 try:
190 self.integrator.analyse()
191 except RuntimeError,e:
192 self.browser.reporter.reportError(str(e))
193 self.window.destroy()
194 if self.prefs.getBoolPref("Integrator","debuganalyse",True):
195 fp = tempfile.TemporaryFile()
196 self.integrator.writeDebug(fp)
197 fp.seek(0)
198 text = fp.read()
199 fp.close()
200 title = "Integrator Analysis Failed"
201 _dialog = InfoDialog(self.browser,self.browser.window,text,title,tabs=(70,200,300,400,500))
202 _dialog.run()
203
204 return None
205 # if we're all ok, create the reporter window and close this one
206 _integratorreporter = IntegratorReporterPython(self.browser,self.integrator)
207 self.integrator.setReporter(_integratorreporter)
208 self.window.destroy()
209 return _integratorreporter # means proceed to solve
210
211 self.window.destroy()
212 return None # can't solve
213
214 def color_entry(self,entry,color):
215 # colour an input box if it doesn't have acceptable contents
216 # error messages would be reported by the 'errors panel' in the main win
217 entry.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
218 entry.modify_bg(gtk.STATE_ACTIVE, gtk.gdk.color_parse(color))
219 entry.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
220 entry.modify_base(gtk.STATE_ACTIVE, gtk.gdk.color_parse(color))
221
222 def taint_entry(self,entry,color):
223 # colour an input box if it doesn't have acceptable contents
224 # error messages would be reported by the 'errors panel' in the main win
225 entry.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
226 entry.modify_bg(gtk.STATE_ACTIVE, gtk.gdk.color_parse(color))
227 entry.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
228 entry.modify_base(gtk.STATE_ACTIVE, gtk.gdk.color_parse(color))
229 if color == "#FFBBBB":
230 entry.set_property("secondary-icon-stock", 'gtk-dialog-error')
231 elif color == "white":
232 entry.set_property("secondary-icon-stock", 'gtk-yes')
233 entry.set_property("secondary-icon-tooltip-text", "")
234
235 def parse_entry(self, entry):
236 # A simple function to get the real value from the entered text
237 # and taint the entry box accordingly
238 i = RealAtomEntry(self.indepvar.getInstance(), entry.get_text())
239 try:
240 i.checkEntry()
241 _value = i.getValue()
242 except InputError, e:
243 _value = None
244 _error = re.split('Input Error: ', str(e), 1)
245 entry.set_property("secondary-icon-tooltip-text", _error[1])
246
247 if _value is not None:
248 self.taint_entry(entry, "white")
249 else:
250 self.taint_entry(entry, "#FFBBBB")
251 return _value
252
253 def check_inputs(self):
254 # set the timesteps (samples)
255 _val = {}
256 units = ''
257 for _k,_v in {
258 self.beginentry:[lambda x:float(x),"begin"]
259 , self.durationentry:[lambda x:float(x),"duration"]
260 , self.nstepsentry:[lambda x:int(x),"num"]
261 }.iteritems():
262 x = RealAtomEntry(self.indepvar.getInstance(), _k.get_text())
263 x.checkEntry()
264 if _k == self.beginentry:
265 units = x.units
266 #self.indepvar.getInstance().setRealValueWithUnits()
267 if _k == self.nstepsentry:
268 _val[_v[1]] = _v[0](_k.get_text())
269 else :
270 _val[_v[1]]=_v[0](x.getValue()/ascpy.Units(units).getConversion())
271
272 self.integrator.setLinearTimesteps(ascpy.Units(units), _val["begin"], (_val["begin"]+_val["duration"]), _val["num"]);
273 self.begin=_val["begin"]
274 self.duration=_val["duration"]
275
276 self.prefs.setStringPref("Integrator","duration",str(self.duration))
277
278 # set substep parameters (ie settings common to any integrator engine)
279 _failed=False
280 x={}
281 for _k,_v in self.settings.iteritems():
282 try:
283 _f = self.integratorentries[_k];
284 # pass the substep setting to the integrator
285 x[_f] = RealAtomEntry(self.indepvar.getInstance(), _f.get_text())
286 x[_f].checkEntry()
287 if _k!="maxsteps":
288 self.taint_entry(_f,"white")
289 _v[1](x[_f].getValue()/ascpy.Units(units).getConversion())
290 else:
291 _v[1](_f.get_text())
292 self.color_entry(_f,"white")
293 except ValueError,e:
294 if _k!="maxsteps":
295 self.taint_entry(_f,"#FFBBBB")
296 else:
297 self.color_entry(_f,"#FFBBBB")
298 _failed=True
299
300 if _failed:
301 raise IntegratorError("Invalid step parameter(s)");
302
303 for _k,_v in self.settings.iteritems():
304 # store those inputs for next time
305 _f = self.integratorentries[_k]
306 if _k!="maxsteps":
307 self.prefs.setStringPref("Integrator",_k,str(x[_f].getValue()/ascpy.Units(units).getConversion()))
308 else:
309 self.prefs.setStringPref("Integrator",_k,str(_f.get_text()))
310
311 # set engine (and check that it's OK with this system)
312 engine=self.engineselect.get_active()
313 if engine==-1:
314 self.color_entry(self.engineselect,"#FFBBBB")
315 raise IntegratorError("No engine selected")
316
317 self.color_entry(self.engineselect,"white")
318
319 try:
320 self.prefs.setStringPref("Integrator","engine",self.engines[engine])
321 _res = self.integrator.setEngine(self.engines[engine])
322 except IndexError,e:
323 raise IntegratorError("Unable to set engine: %s" % e)

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