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

Contents of /trunk/pygtk/ascpy.i

Parent Directory Parent Directory | Revision Log Revision Log


Revision 979 - (show annotations) (download)
Wed Dec 20 14:34:16 2006 UTC (13 years, 1 month ago) by johnpye
File size: 12719 byte(s)
Added simplified ASC_PANIC call that uses var-args, added throughout relation_util.c.
Fixed var_filter_t stuff in djex and fvex.
More assertions in integrator.c
Added output of initial state from lsode.c (hoping that's a good idea?)
Fixed output code from relman_diff2.
Added asc_panic_nofunc for non var-arg CPPs.
Disabled -O3 flag in building C++ API
Added __getitem__ and __getattr__ methods in Simuluation for simplified python syntax (eg M.x instead M.sim.x)
Integrator::analyse throws exceptions on error now.

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

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