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

Contents of /trunk/pygtk/ascpy.i

Parent Directory Parent Directory | Revision Log Revision Log


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

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