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

Annotation of /trunk/pygtk/ascpy.i

Parent Directory Parent Directory | Revision Log Revision Log


Revision 966 - (hide annotations) (download)
Thu Dec 14 14:04:54 2006 UTC (15 years, 8 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 johnpye 225 /* : set syntax=cpp : */
2 johnpye 132 /*
3     SWIG interface routines to read a file into the library
4     */
5    
6 johnpye 463 %module(directors=1) ascpy
7 johnpye 132
8 johnpye 340 %include <python/std_string.i>
9     %include <python/std_except.i>
10     %include <python/std_vector.i>
11 johnpye 669 %include <python/std_map.i>
12 johnpye 132
13     %{
14     #include "library.h"
15 johnpye 770 #include "compiler.h"
16 johnpye 132 #include "type.h"
17     #include "instance.h"
18     #include "variable.h"
19 johnpye 238 #include "relation.h"
20 johnpye 132 #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 johnpye 212 #include "extmethod.h"
29 johnpye 175 #include "plot.h"
30     #include "curve.h"
31 johnpye 208 #include "solverparameters.h"
32 johnpye 307 #include "solverstatus.h"
33 johnpye 310 #include "solverreporter.h"
34 johnpye 233 #include "incidencematrix.h"
35 johnpye 869 #include "registry.h"
36 johnpye 897 #include "annotation.h"
37 johnpye 938
38 johnpye 966 extern "C"{
39     #include <compiler/importhandler.h>
40     #include <utilities/ascMalloc.h>
41     }
42    
43 johnpye 952 #ifdef ASC_WITH_DMALLOC
44     # include <dmalloc.h>
45     #endif
46    
47 johnpye 132 %}
48    
49     // All STL runtime_errors caught to Python
50    
51     %exception {
52     try {
53     $action
54     }
55 johnpye 319 catch (std::range_error &e) {
56     SWIG_exception(SWIG_IndexError,e.what());
57     }
58 johnpye 132 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 johnpye 212 %template(ExtMethodVector) std::vector<ExtMethod>;
112 johnpye 132 %template(SetInt) ASCXX_Set<long>;
113     %template(SetString) ASCXX_Set<SymChar>;
114 johnpye 175 %template(DoubleVector) std::vector<double>;
115 johnpye 283 %template(IntVector) std::vector<int>;
116 johnpye 175 %template(CurveVector) std::vector<Curve>;
117 johnpye 223 %template(StringVector) std::vector<std::string>;
118 johnpye 669 %template(IntStringMap) std::map<int,std::string>;
119 johnpye 897 %template(AnnotationVector) std::vector<Annotation>;
120 johnpye 132
121     %rename(Instance) Instanc;
122 johnpye 233 %rename(Name) Nam;#include "incidencematrix.h"
123 johnpye 132 %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 johnpye 341 %typemap(in) PyObject *pyfunc {
129 johnpye 278 if (!PyCallable_Check($input)) {
130 johnpye 132 PyErr_SetString(PyExc_TypeError, "Need a callable object!");
131     return NULL;
132     }
133 johnpye 278 $1 = $input;
134 johnpye 132 }
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 johnpye 529 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"%s", msg);
152 johnpye 132 }
153     void reportNote(const char *msg){
154 johnpye 529 ERROR_REPORTER_NOLINE(ASC_USER_NOTE,"%s",msg);
155 johnpye 132 }
156     void reportWarning(const char *msg){
157 johnpye 529 ERROR_REPORTER_NOLINE(ASC_USER_WARNING,"%s",msg);
158 johnpye 132 }
159     void reportSuccess(const char *msg){
160 johnpye 529 ERROR_REPORTER_NOLINE(ASC_USER_SUCCESS,"%s",msg);
161 johnpye 132 }
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 johnpye 966 %include "units.h"
189 johnpye 132
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 johnpye 481
237 johnpye 132 if len(numparts):
238     str = "*".join(numparts)
239     else:
240     str = "1"
241 johnpye 481
242 johnpye 132 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 johnpye 897 %typemap(in) const SymChar& {
263     $1 = new SymChar(PyString_AsString($input));
264     }
265 johnpye 132
266 johnpye 897 %include "library.h"
267 johnpye 132
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 johnpye 932 %include "method.h"
287 johnpye 132
288 johnpye 932 %ignore Method::getInternalType;
289     %ignore Method::getSym;
290    
291 johnpye 132 // Renamed in python as 'Name'
292     class Nam{
293     public:
294     Nam(const SymChar &);
295     const std::string getName() const;
296     };
297    
298 johnpye 770 %include "compiler.h"
299     /* we can always disown Compiler * as it's a singleton */
300     %apply SWIGTYPE *DISOWN { Compiler * };
301    
302 johnpye 932 %include "type.h"
303    
304 johnpye 132 %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 johnpye 481
322 johnpye 132 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 johnpye 481
326 johnpye 132 return _units;
327     }
328     }
329    
330 johnpye 255 typedef enum{
331 johnpye 258 ASCXX_VAR_STATUS_UNKNOWN=0, ASCXX_VAR_FIXED, ASCXX_VAR_UNSOLVED, ASCXX_VAR_ACTIVE, ASCXX_VAR_SOLVED
332 johnpye 255 } VarStatus;
333    
334 johnpye 132 class Instanc{
335     private:
336     Instanc();
337     public:
338     Instanc(Instance *);
339     Instanc(Instance *, SymChar &name);
340 johnpye 732 ~Instanc();
341 johnpye 132 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 johnpye 808 const bool isActive() const;
348 johnpye 132 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 johnpye 799 const bool isLogicalRelation() const;
354 johnpye 132 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 johnpye 952 const bool isArray() const;
360 johnpye 132 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 johnpye 774 const bool isModel() const;
366    
367 johnpye 132 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 johnpye 207 const std::string getValueAsString() const; ///< Use carefully: rounding will occur for doubles!
374 johnpye 273
375 johnpye 215 const std::string getRelationAsString(const Instanc &relative_to) const;
376 johnpye 273 const double getResidual() const;
377    
378 johnpye 176 Plot getPlot() const;
379    
380 johnpye 172 const bool isPlottable() const;
381 johnpye 132 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 johnpye 844 void setSymbolValue(const SymChar &sym);
389 johnpye 132 void write();
390 johnpye 255
391     const VarStatus getVarStatus() const;
392 johnpye 268
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 johnpye 271
400 johnpye 732 const std::vector<Instanc> getClique() const;
401 johnpye 132 };
402    
403     %extend Instanc{
404     const char *__repr__(){
405     return self->getName().toString();
406     }
407 johnpye 876 Instanc __getattr__(const char *name){
408     return self->getChild(SymChar(name));
409     }
410 johnpye 952 Instanc __getitem__(const long &index){
411     return self->getChild(index);
412     }
413 johnpye 877 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 johnpye 876
421 johnpye 132 %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 johnpye 875 #print "GETTING VALUE OF %s" % self.getName()
434 johnpye 132 if self.isCompound():
435     return ""
436 johnpye 273 elif self.isRelation():
437     return self.getResidual()
438     elif self.isWhen():
439     return "WHEN"
440 johnpye 132 elif self.isSet():
441     _s = set(self.getSetValue());
442     #for _v in self.getSetValue():
443     # _s.add( _v )
444     return _s
445 johnpye 481
446 johnpye 132 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 johnpye 875 return "UNKNOWN TYPE"
458     #raise RuntimeError("Unknown value model type="+self.getType().getName().toString()+", instance kind=".getKindStr())
459 johnpye 132
460     def getRealValueAndUnits(self):
461     if not self.isReal():
462     raise TypeError
463 johnpye 903 if self.isDimensionless() or self.isFund():
464 johnpye 132 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 johnpye 481 self.setFixed();
473 johnpye 132 # getReporter().reportError("Setting value of %s to %s" % (self.getName().toString(),val))
474     self.setRealValue(val);
475 johnpye 877
476     def __coerce__(self,other):
477     return (self.getValue(),other.getValue())
478 johnpye 481 }
479 johnpye 132 }
480    
481 johnpye 875 /*
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 johnpye 869 %include "registry.h"
487 johnpye 871 %extend Registry{
488     void set(const char *key, PyObject *obj){
489     self->setPyObject(key,obj);
490     }
491     }
492 johnpye 869
493 johnpye 966 void shutdown();
494    
495     %{
496     void shutdown(){
497     ascshutdown("Shutdown ASCEND...");
498     }
499     %}
500    
501 johnpye 221 %include "solver.i"
502 johnpye 132
503 johnpye 893 %include "extmethod.h"
504 johnpye 132
505 johnpye 897 %include "annotation.h"
506    
507 johnpye 176 %include "plot.i"
508 johnpye 175
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