/[ascend]/trunk/pygtk/ascpy.i
ViewVC logotype

Contents of /trunk/pygtk/ascpy.i

Parent Directory Parent Directory | Revision Log Revision Log


Revision 966 - (show annotations) (download)
Thu Dec 14 14:04:54 2006 UTC (13 years, 10 months ago) by johnpye
File size: 12317 byte(s)
Cleaned up code comments in units.h
Fixed a bug with starting timesteps in LSODE (i think)
Added function to output a SampleList to the console (for debugging)
Removed debug output from base/generic/test/SConscript.
Removed 'custom' headers for UnitsM in ascpy.i
Made a sane default ctor for UnitsM
Added some more test cases to the Python unittest suite (still a problem running multiple solver-based tests in a single run)
1 /* : set syntax=cpp : */
2 /*
3 SWIG interface routines to read a file into the library
4 */
5
6 %module(directors=1) ascpy
7
8 %include <python/std_string.i>
9 %include <python/std_except.i>
10 %include <python/std_vector.i>
11 %include <python/std_map.i>
12
13 %{
14 #include "library.h"
15 #include "compiler.h"
16 #include "type.h"
17 #include "instance.h"
18 #include "variable.h"
19 #include "relation.h"
20 #include "name.h"
21 #include "reporter.h"
22 #include "simulation.h"
23 #include "solver.h"
24 #include "symchar.h"
25 #include "set.h"
26 #include "dimensions.h"
27 #include "units.h"
28 #include "extmethod.h"
29 #include "plot.h"
30 #include "curve.h"
31 #include "solverparameters.h"
32 #include "solverstatus.h"
33 #include "solverreporter.h"
34 #include "incidencematrix.h"
35 #include "registry.h"
36 #include "annotation.h"
37
38 extern "C"{
39 #include <compiler/importhandler.h>
40 #include <utilities/ascMalloc.h>
41 }
42
43 #ifdef ASC_WITH_DMALLOC
44 # include <dmalloc.h>
45 #endif
46
47 %}
48
49 // All STL runtime_errors caught to Python
50
51 %exception {
52 try {
53 $action
54 }
55 catch (std::range_error &e) {
56 SWIG_exception(SWIG_IndexError,e.what());
57 }
58 catch (std::runtime_error &e) {
59 SWIG_exception(SWIG_RuntimeError,e.what());
60 }
61 }
62
63 // Import the preferences module
64 %pythoncode {
65 import preferences;
66 }
67
68 // Set-valued instance variable
69 %pythoncode {
70 class SetIter:
71 def __init__(self,set):
72 self.set=set
73 self.index=0
74 def next(self):
75 if self.index==self.set.length():
76 raise StopIteration
77 self.index = self.index + 1
78 return self.set[self.index]
79 }
80
81 template<class T>
82 class ASCXX_Set{
83 private:
84 ASCXX_Set();
85 public:
86 const T at(const unsigned long&) const;
87 const unsigned long length() const;
88 };
89 %extend ASCXX_Set<long>{
90 %pythoncode {
91 def __getitem__(self, index):
92 return self.at(index)
93 def __iter__(self):
94 return SetIter(self)
95 }
96 }
97 %extend ASCXX_Set<SymChar>{
98 %pythoncode {
99 def __getitem__(self, index):
100 return self.at(index)
101 def __iter__(self):
102 return SetIter(self)
103 }
104 }
105
106
107 %template(ModuleVector) std::vector<Module>;
108 %template(TypeVector) std::vector<Type>;
109 %template(MethodVector) std::vector<Method>;
110 %template(InstancVector) std::vector<Instanc>;
111 %template(ExtMethodVector) std::vector<ExtMethod>;
112 %template(SetInt) ASCXX_Set<long>;
113 %template(SetString) ASCXX_Set<SymChar>;
114 %template(DoubleVector) std::vector<double>;
115 %template(IntVector) std::vector<int>;
116 %template(CurveVector) std::vector<Curve>;
117 %template(StringVector) std::vector<std::string>;
118 %template(IntStringMap) std::map<int,std::string>;
119 %template(AnnotationVector) std::vector<Annotation>;
120
121 %rename(Instance) Instanc;
122 %rename(Name) Nam;#include "incidencematrix.h"
123 %rename(getSetIntValue) Instanc::getSetValue<long>;
124 %rename(getSetStringValue) Instanc::getSetValue<SymChar>;
125 %rename(Units) UnitsM;
126
127 // Grab a Python function object as a Python object.
128 %typemap(in) PyObject *pyfunc {
129 if (!PyCallable_Check($input)) {
130 PyErr_SetString(PyExc_TypeError, "Need a callable object!");
131 return NULL;
132 }
133 $1 = $input;
134 }
135
136 //----------------------------
137 // REPORTER: callbacks to python
138 class Reporter{
139 private:
140 ~Reporter();
141 Reporter();
142 public:
143 // use 'getReporter' instead of 'Reporter::Instance()' in python
144 void setErrorCallback(error_reporter_callback_t callback, void *client_data);
145 void setPythonErrorCallback(PyObject *pyfunc);
146 void clearPythonErrorCallback();
147 };
148
149 %extend Reporter {
150 void reportError(const char *msg){
151 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"%s", msg);
152 }
153 void reportNote(const char *msg){
154 ERROR_REPORTER_NOLINE(ASC_USER_NOTE,"%s",msg);
155 }
156 void reportWarning(const char *msg){
157 ERROR_REPORTER_NOLINE(ASC_USER_WARNING,"%s",msg);
158 }
159 void reportSuccess(const char *msg){
160 ERROR_REPORTER_NOLINE(ASC_USER_SUCCESS,"%s",msg);
161 }
162 }
163
164 // There are problems with Instance(), so use this instead:
165 Reporter *getReporter();
166
167 //----------------------------------------
168 // UNITS AND DIMENSIONS
169
170
171 class UnitsM;
172
173 class Dimensions{
174 public:
175 static const unsigned MAX_DIMS;
176 static const std::string getBaseUnit(const unsigned &);
177
178 const bool operator==(const Dimensions &) const;
179 const bool operator!=(const Dimensions &) const;
180 const bool operator<(const Dimensions &) const;
181 Dimensions(const Dimensions &);
182 const bool isWild() const;
183 const bool isDimensionless() const;
184 const short getFractionNumerator(const unsigned &) const;
185 const short getFractionDenominator(const unsigned &) const;
186 };
187
188 %include "units.h"
189
190 %extend UnitsM{
191 %pythoncode{
192 def getConvertedValue(self,si_value):
193 _u_value = si_value / self.getConversion()
194 return str(_u_value) + " " + self.getName().toString();
195 }
196 }
197
198 /*
199 This function creates default (SI) units for any dimension given. Most
200 of the time you will want to use custom units in place of these, eg
201 'N' instead of 'kg*m/s^2'.
202 */
203 %extend Dimensions{
204 %pythoncode {
205
206 def getDefaultUnits(self):
207 if self.isDimensionless():
208 return Units("");
209
210 if self.isWild():
211 return Units("?");
212
213 # create a string representation of the current dimensions
214 numparts=[]
215 denparts=[]
216 for i in range(0, self.MAX_DIMS):
217 baseunit = self.getBaseUnit(i);
218 num = self.getFractionNumerator(i)
219 den = self.getFractionDenominator(i)
220 if num > 0:
221 if den == 1:
222 if num == 1:
223 numparts.append(baseunit)
224 else:
225 numparts.append("%s^%d" % (baseunit, num) )
226 else:
227 numparts.append("%s^(%d/%d)" % (baseunit, num, den) )
228 elif num < 0:
229 if den == 1:
230 if num == -1:
231 denparts.append(baseunit)
232 else:
233 denparts.append("%s^%d" % (baseunit, -num) )
234 else:
235 denparts.append("%s^(%d/%d)" % (baseunit, -num, den) )
236
237 if len(numparts):
238 str = "*".join(numparts)
239 else:
240 str = "1"
241
242 if len(denparts):
243 str = str + "/" + "/".join(denparts)
244
245 return Units(str)
246
247 }
248 }
249
250 /*
251 some python code for nice unicode unit strings, need to extend the units.c code as well though.
252
253 elif num == 2:
254 numparts.append(baseunit + ur'\u00b2')
255 elif num == 3:
256 numparts.append(baseunit + ur'\u00b3')
257
258 str = ur'\u00b7'.join(numparts)
259 */
260 //----------------------------
261
262 %typemap(in) const SymChar& {
263 $1 = new SymChar(PyString_AsString($input));
264 }
265
266 %include "library.h"
267
268 class SymChar{
269 public:
270 SymChar(const std::string &);
271 const char *toString() const;
272 };
273 %extend SymChar{
274 const char *__repr__(){
275 return self->toString();
276 }
277 }
278
279 class Module{
280 public:
281 const char *getName() const;
282 const char *getFilename() const;
283 const struct tm *getMtime() const;
284 };
285
286 %include "method.h"
287
288 %ignore Method::getInternalType;
289 %ignore Method::getSym;
290
291 // Renamed in python as 'Name'
292 class Nam{
293 public:
294 Nam(const SymChar &);
295 const std::string getName() const;
296 };
297
298 %include "compiler.h"
299 /* we can always disown Compiler * as it's a singleton */
300 %apply SWIGTYPE *DISOWN { Compiler * };
301
302 %include "type.h"
303
304 %extend Type{
305 const char *__repr__(){
306 return self->getName().toString();
307 }
308
309 %pythoncode{
310 def getPreferredUnits(self):
311 if not self.isRefinedReal():
312 return None
313
314 _pref = preferences.Preferences()
315 #print "Checking for preferred units for %s" % self.getName()
316 _u = _pref.getPreferredUnits(self.getName().toString())
317 if _u == None:
318 # no preferred units set
319 return None
320 _units = Units(_u);
321
322 if _units.getDimensions() != self.getDimensions():
323 getReporter().reportWarning("Preferred units '%s' for type '%s' are not dimensionally correct: ignoring." % (_u, self.getName()) );
324 return None
325
326 return _units;
327 }
328 }
329
330 typedef enum{
331 ASCXX_VAR_STATUS_UNKNOWN=0, ASCXX_VAR_FIXED, ASCXX_VAR_UNSOLVED, ASCXX_VAR_ACTIVE, ASCXX_VAR_SOLVED
332 } VarStatus;
333
334 class Instanc{
335 private:
336 Instanc();
337 public:
338 Instanc(Instance *);
339 Instanc(Instance *, SymChar &name);
340 ~Instanc();
341 std::vector<Instanc> getChildren();
342 const std::string getKindStr() const;
343 const SymChar &getName();
344 const Type getType() const;
345 const bool isAtom() const;
346 const bool isFixed() const;
347 const bool isActive() const;
348 const bool isFund() const;
349 const bool isConst() const;
350 const bool isAssigned() const;
351 const bool isCompound() const;
352 const bool isRelation() const;
353 const bool isLogicalRelation() const;
354 const bool isWhen() const;
355 const bool isSet() const; // a set (group) of things
356 const bool isSetInt() const;
357 const bool isSetString() const;
358 const bool isSetEmpty() const;
359 const bool isArray() const;
360 const bool isDefined() const;
361 const bool isBool() const;
362 const bool isInt() const;
363 const bool isSymbol() const;
364 const bool isReal() const;
365 const bool isModel() const;
366
367 const double getRealValue() const;
368 const bool isDimensionless() const;
369 const Dimensions getDimensions() const;
370 const bool getBoolValue() const;
371 const long getIntValue() const;
372 const SymChar getSymbolValue() const;
373 const std::string getValueAsString() const; ///< Use carefully: rounding will occur for doubles!
374
375 const std::string getRelationAsString(const Instanc &relative_to) const;
376 const double getResidual() const;
377
378 Plot getPlot() const;
379
380 const bool isPlottable() const;
381 const ASCXX_Set<long> getSetValue<long>() const;
382 const ASCXX_Set<SymChar> getSetValue<SymChar>() const;
383 const bool isChildless() const;
384 void setFixed(const bool &val=true);
385 void setRealValue(const double &val);
386 void setRealValueWithUnits(const double &, const char *);
387 void setBoolValue(const bool &val);
388 void setSymbolValue(const SymChar &sym);
389 void write();
390
391 const VarStatus getVarStatus() const;
392
393 void setLowerBound(const double &);
394 void setUpperBound(const double &);
395 void setNominal(const double &);
396 const double getLowerBound() const;
397 const double getUpperBound() const;
398 const double getNominal() const;
399
400 const std::vector<Instanc> getClique() const;
401 };
402
403 %extend Instanc{
404 const char *__repr__(){
405 return self->getName().toString();
406 }
407 Instanc __getattr__(const char *name){
408 return self->getChild(SymChar(name));
409 }
410 Instanc __getitem__(const long &index){
411 return self->getChild(index);
412 }
413 double __float__(){
414 if(self->isReal()){
415 return self->getRealValue();
416 }else{
417 throw std::runtime_error("Can't cast this instance to float");
418 }
419 }
420
421 %pythoncode {
422 def getSetValue(self):
423 if self.isSetInt():
424 return self.getSetIntValue()
425 elif self.isSetString():
426 return self.getSetStringValue()
427 elif self.isSetEmpty():
428 return set()
429 else:
430 raise RuntimeError("getSetValue: unknown set type");
431
432 def getValue(self):
433 #print "GETTING VALUE OF %s" % self.getName()
434 if self.isCompound():
435 return ""
436 elif self.isRelation():
437 return self.getResidual()
438 elif self.isWhen():
439 return "WHEN"
440 elif self.isSet():
441 _s = set(self.getSetValue());
442 #for _v in self.getSetValue():
443 # _s.add( _v )
444 return _s
445
446 elif ( self.isAtom() or self.isFund() ) and not self.isDefined():
447 return "undefined"
448 elif self.isReal():
449 return self.getRealValueAndUnits()
450 elif self.isBool():
451 return self.getBoolValue()
452 elif self.isInt():
453 return self.getIntValue()
454 elif self.isSymbol():
455 return self.getSymbolValue()
456 else:
457 return "UNKNOWN TYPE"
458 #raise RuntimeError("Unknown value model type="+self.getType().getName().toString()+", instance kind=".getKindStr())
459
460 def getRealValueAndUnits(self):
461 if not self.isReal():
462 raise TypeError
463 if self.isDimensionless() or self.isFund():
464 return self.getRealValue();
465 _u = self.getType().getPreferredUnits();
466 if _u == None:
467 return str(self.getRealValue()) + ' ' + self.getDimensions().getDefaultUnits().getName().toString()
468 return _u.getConvertedValue(self.getRealValue())
469
470 def setFixedValue(self,val):
471 if not self.isFixed():
472 self.setFixed();
473 # getReporter().reportError("Setting value of %s to %s" % (self.getName().toString(),val))
474 self.setRealValue(val);
475
476 def __coerce__(self,other):
477 return (self.getValue(),other.getValue())
478 }
479 }
480
481 /*
482 This 'registry' thing is a bit of a hack that allows interface pointers to
483 be registered with libascend so that they can be accessed from external
484 script methods
485 */
486 %include "registry.h"
487 %extend Registry{
488 void set(const char *key, PyObject *obj){
489 self->setPyObject(key,obj);
490 }
491 }
492
493 void shutdown();
494
495 %{
496 void shutdown(){
497 ascshutdown("Shutdown ASCEND...");
498 }
499 %}
500
501 %include "solver.i"
502
503 %include "extmethod.h"
504
505 %include "annotation.h"
506
507 %include "plot.i"
508
509 class Curve : public Instanc{
510 public:
511 std::vector<double> x;
512 std::vector<double> y;
513 const std::string getLegend() const;
514 };

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