1 %module openbabel
2 
3 %begin %{
4 #define SWIG_PYTHON_2_UNICODE
5 %}
6 
7 %{
8 // used to set import/export for Cygwin DLLs
9 #ifdef WIN32
10 #define USING_OBDLL
11 #endif
12 
13 #include <openbabel/obutil.h>
14 #include <openbabel/math/vector3.h>
15 #include <openbabel/math/matrix3x3.h>
16 #include <openbabel/math/transform3d.h>
17 #include <openbabel/math/spacegroup.h>
18 
19 #include <openbabel/generic.h>
20 #include <openbabel/griddata.h>
21 #include <openbabel/elements.h>
22 
23 #include <openbabel/base.h>
24 #include <openbabel/mol.h>
25 #include <openbabel/atom.h>
26 #include <openbabel/bond.h>
27 #include <openbabel/reaction.h>
28 #include <openbabel/reactionfacade.h>
29 #include <openbabel/residue.h>
30 #include <openbabel/internalcoord.h>
31 #include <openbabel/bondtyper.h>
32 
33 #include <openbabel/ring.h>
34 #include <openbabel/obconversion.h>
35 #include <openbabel/obfunctions.h>
36 #include <openbabel/oberror.h>
37 #include <openbabel/plugin.h>
38 #include <openbabel/fingerprint.h>
39 #include <openbabel/descriptor.h>
40 #include <openbabel/format.h>
41 
42 #include <openbabel/forcefield.h>
43 #include <openbabel/builder.h>
44 #include <openbabel/op.h>
45 
46 #include <openbabel/bitvec.h>
47 #include <openbabel/data.h>
48 #include <openbabel/parsmart.h>
49 #include <openbabel/alias.h>
50 
51 #include <openbabel/kinetics.h>
52 #include <openbabel/rotor.h>
53 #include <openbabel/rotamer.h>
54 #include <openbabel/spectrophore.h>
55 
56 #include <openbabel/chargemodel.h>
57 #include <openbabel/phmodel.h>
58 #include <openbabel/graphsym.h>
59 #include <openbabel/isomorphism.h>
60 #include <openbabel/query.h>
61 #include <openbabel/canon.h>
62 
63 #include <openbabel/stereo/tetrahedral.h>
64 #include <openbabel/stereo/cistrans.h>
65 #include <openbabel/stereo/squareplanar.h>
66 #include <openbabel/stereo/bindings.h>
67 
68 #include <openbabel/chains.h>
69 #include <openbabel/obiter.h>
70 %}
71 
72 // Set and reset dlopenflags so that plugin loading works fine for "import _openbabel"
73 %pythonbegin %{
74 import sys
75 if sys.platform.find("linux") != -1:
76     dlflags = sys.getdlopenflags()
77     import ctypes
78     sys.setdlopenflags(dlflags | ctypes.RTLD_GLOBAL)
79 %}
80 %pythoncode %{
81 if sys.platform.find("linux") != -1:
82     sys.setdlopenflags(dlflags)
83 %}
84 
85 
86 // Ignore methods that require std::vector of OBAtom.
87 %ignore OpenBabel::OBMol::FindChildren(std::vector< OBAtom * > &, OBAtom *, OBAtom *);
88 %ignore OpenBabel::OBResidue::GetAtoms;
89 
90 #ifdef HAVE_EIGEN
91 %{
92 #include <openbabel/conformersearch.h>
93 #include <openbabel/math/align.h>
94 %}
95 #else
96 %ignore OpenBabel::OBForceField::FastRotorSearch;
97 %ignore OpenBabel::OBForceField::DiverseConfGen;
98 #endif
99 
100 %include "std_list.i"
101 %include "std_map.i"
102 %include "std_vector.i"
103 %include "std_string.i"
104 %include "std_pair.i"
105 
106 namespace std {
107 
108 %define VVTEMPLATE_WRAP(name, T)
109 %feature("ignore") vector< vector<T> >::append;
110 %feature("ignore") vector< vector<T> >::assign;
111 %feature("ignore") vector< vector<T> >::back;
112 %feature("ignore") vector< vector<T> >::begin;
113 %feature("ignore") vector< vector<T> >::capacity;
114 %feature("ignore") vector< vector<T> >::empty;
115 %feature("ignore") vector< vector<T> >::end;
116 %feature("ignore") vector< vector<T> >::erase;
117 %feature("ignore") vector< vector<T> >::front;
118 %feature("ignore") vector< vector<T> >::get_allocator;
119 %feature("ignore") vector< vector<T> >::insert;
120 %feature("ignore") vector< vector<T> >::pop;
121 %feature("ignore") vector< vector<T> >::pop_back;
122 %feature("ignore") vector< vector<T> >::push_back;
123 %feature("ignore") vector< vector<T> >::rbegin;
124 %feature("ignore") vector< vector<T> >::rend;
125 %feature("ignore") vector< vector<T> >::reserve;
126 %feature("ignore") vector< vector<T> >::resize;
127 %feature("ignore") vector< vector<T> >::size;
128 %feature("ignore") vector< vector<T> >::swap;
129 %template(vectorv ## name) vector< vector<T> >;
130 %enddef
131 
132 %define VECTORTEMPLATE_WRAP(vectorname, T)
133 %feature("ignore") vector<T>::append;
134 %feature("ignore") vector<T>::assign;
135 %feature("ignore") vector<T>::back;
136 %feature("ignore") vector<T>::begin;
137 %feature("ignore") vector<T>::capacity;
138 %feature("ignore") vector<T>::empty;
139 %feature("ignore") vector<T>::end;
140 %feature("ignore") vector<T>::erase;
141 %feature("ignore") vector<T>::front;
142 %feature("ignore") vector<T>::get_allocator;
143 %feature("ignore") vector<T>::insert;
144 %feature("ignore") vector<T>::pop;
145 %feature("ignore") vector<T>::pop_back;
146 %feature("ignore") vector<T>::push_back;
147 %feature("ignore") vector<T>::rbegin;
148 %feature("ignore") vector<T>::rend;
149 %feature("ignore") vector<T>::reserve;
150 %feature("ignore") vector<T>::resize;
151 %feature("ignore") vector<T>::size;
152 %feature("ignore") vector<T>::swap;
153 %template(vector ## vectorname) vector<T>;
154 %enddef
155 
156 %define VECTORPAIRTEMPLATE_WRAP(vectorname, T1, T2)
157 %feature("ignore") vector< pair<T1, T2> >::append;
158 %feature("ignore") vector< pair<T1, T2> >::assign;
159 %feature("ignore") vector< pair<T1, T2> >::back;
160 %feature("ignore") vector< pair<T1, T2> >::begin;
161 %feature("ignore") vector< pair<T1, T2> >::capacity;
162 %feature("ignore") vector< pair<T1, T2> >::empty;
163 %feature("ignore") vector< pair<T1, T2> >::end;
164 %feature("ignore") vector< pair<T1, T2> >::erase;
165 %feature("ignore") vector< pair<T1, T2> >::front;
166 %feature("ignore") vector< pair<T1, T2> >::get_allocator;
167 %feature("ignore") vector< pair<T1, T2> >::insert;
168 %feature("ignore") vector< pair<T1, T2> >::pop;
169 %feature("ignore") vector< pair<T1, T2> >::pop_back;
170 %feature("ignore") vector< pair<T1, T2> >::push_back;
171 %feature("ignore") vector< pair<T1, T2> >::rbegin;
172 %feature("ignore") vector< pair<T1, T2> >::rend;
173 %feature("ignore") vector< pair<T1, T2> >::reserve;
174 %feature("ignore") vector< pair<T1, T2> >::resize;
175 %feature("ignore") vector< pair<T1, T2> >::size;
176 %feature("ignore") vector< pair<T1, T2> >::swap;
177 %template(vpair ## vectorname) vector< pair<T1, T2> >;
178 %enddef
179 
180 VECTORTEMPLATE_WRAP(Int, int)
181 VECTORTEMPLATE_WRAP(UnsignedInt, unsigned int)
182 VVTEMPLATE_WRAP(Int, int)
183 VECTORTEMPLATE_WRAP(Double, double)
184 VECTORTEMPLATE_WRAP(ULong, unsigned long)
185 VECTORTEMPLATE_WRAP(String, std::string)
186 VECTORTEMPLATE_WRAP(Vector3, OpenBabel::vector3)
187 VVTEMPLATE_WRAP(Vector3, OpenBabel::vector3)
188 VECTORTEMPLATE_WRAP(OBMol, OpenBabel::OBMol)
189 VECTORTEMPLATE_WRAP(OBBond, OpenBabel::OBBond)
190 VECTORTEMPLATE_WRAP(OBResidue, OpenBabel::OBResidue)
191 VECTORTEMPLATE_WRAP(OBRing, OpenBabel::OBRing)
192 VECTORTEMPLATE_WRAP(pOBRing, OpenBabel::OBRing*)
193 VECTORTEMPLATE_WRAP(pOBGenericData, OpenBabel::OBGenericData*)
194 VECTORTEMPLATE_WRAP(pOBInternalCoord, OpenBabel::OBInternalCoord*)
195 
196 %template(pairUIntUInt) pair<unsigned int, unsigned int>;
197 VECTORPAIRTEMPLATE_WRAP(UIntUInt, unsigned int, unsigned int);
198 %template(vvpairUIntUInt) vector< vector< pair<unsigned int, unsigned int> > >;
199 }
200 
201 %define CAST_GENERICDATA_TO(subclass)
202 %inline %{
subclass(OpenBabel::OBGenericData * data)203 OpenBabel::OB ## subclass *to ## subclass(OpenBabel::OBGenericData *data) {
204     return (OpenBabel::OB ## subclass *) data;
205 }
206 %}
207 %enddef
208 %inline %{ /* can't use macro -- AliasData not OBAliasData */
toAliasData(OpenBabel::OBGenericData * data)209 OpenBabel::AliasData *toAliasData(OpenBabel::OBGenericData *data) {
210     return (OpenBabel::AliasData*) data;
211 }
212 %}
213 CAST_GENERICDATA_TO(AngleData)
214 CAST_GENERICDATA_TO(CommentData)
215 CAST_GENERICDATA_TO(ConformerData)
216 CAST_GENERICDATA_TO(ExternalBondData)
217 CAST_GENERICDATA_TO(GridData)
218 CAST_GENERICDATA_TO(MatrixData)
219 CAST_GENERICDATA_TO(NasaThermoData)
220 CAST_GENERICDATA_TO(PairData)
221 CAST_GENERICDATA_TO(PairInteger)
222 CAST_GENERICDATA_TO(PairFloatingPoint)
223 // CAST_GENERICDATA_TO(PairTemplate)
224 CAST_GENERICDATA_TO(RateData)
225 CAST_GENERICDATA_TO(RotamerList)
226 CAST_GENERICDATA_TO(RotationData)
227 CAST_GENERICDATA_TO(SerialNums)
228 CAST_GENERICDATA_TO(SetData)
229 CAST_GENERICDATA_TO(SymmetryData)
230 CAST_GENERICDATA_TO(TorsionData)
231 CAST_GENERICDATA_TO(UnitCell)
232 CAST_GENERICDATA_TO(VectorData)
233 CAST_GENERICDATA_TO(VibrationData)
234 CAST_GENERICDATA_TO(VirtualBond)
235 CAST_GENERICDATA_TO(StereoBase)
236 CAST_GENERICDATA_TO(TetrahedralStereo)
237 CAST_GENERICDATA_TO(CisTransStereo)
238 CAST_GENERICDATA_TO(SquarePlanarStereo)
239 
240 // This method is renamed to a valid Python method name, as otherwise
241 // it cannot be used from Python
242 %rename(inc)   *::operator++;
243 %ignore *::operator=;
244 %ignore *::operator[];
245 
246 %import <openbabel/babelconfig.h>
247 
248 %include <openbabel/data.h>
249 %include <openbabel/obutil.h>
250 %include <openbabel/math/vector3.h>
251 %warnfilter(503) OpenBabel::matrix3x3; // Not wrapping any of the overloaded operators
252 %include <openbabel/math/matrix3x3.h>
253 %include <openbabel/math/transform3d.h>
254 %include <openbabel/math/spacegroup.h>
255 %warnfilter(503) OpenBabel::OBBitVec; // Not wrapping any of the overloaded operators
256 %include <openbabel/bitvec.h>
257 
258 // CloneData should be used instead of the following method
259 %ignore OpenBabel::OBBase::SetData;
260 %include <openbabel/base.h>
261 
262 %include <openbabel/generic.h>
263 %template(OBPairInteger) OpenBabel::OBPairTemplate<int>;
264 %template(OBPairFloatingPoint) OpenBabel::OBPairTemplate<float>;
265 %include <openbabel/griddata.h>
266 
267 %include <openbabel/chains.h>
268 %include <openbabel/typer.h>
269 
270 // To avoid warning in plugin.h about "Nothing known about std::binary_function"
271 namespace std {
272         template <T1, T2, T3>
273         class binary_function {};
274 }
275 %template(dummy) std::binary_function <const char *, const char *, bool>;
276 %include <openbabel/plugin.h>
277 
278 // To avoid warning in oberror.h about "Nothing known about std::stringbuf"
279 namespace std { class stringbuf {}; }
280 %warnfilter(503) OpenBabel::OBError; // Not wrapping any of the overloaded operators
281 %include <openbabel/oberror.h>
282 %include <openbabel/format.h>
283 %include <openbabel/obconversion.h>
284 %include <openbabel/obfunctions.h>
285 
286 //avoid conflicts with OBElement; for consistency prefix all single
287 //character residue abbreviations with res
288 %rename(resA) OpenBabel::OBResidueIndex::A;
289 %rename(resC) OpenBabel::OBResidueIndex::C;
290 %rename(resG) OpenBabel::OBResidueIndex::G;
291 %rename(resT) OpenBabel::OBResidueIndex::T;
292 %rename(resI) OpenBabel::OBResidueIndex::I;
293 %rename(resU) OpenBabel::OBResidueIndex::U;
294 
295 %include <openbabel/elements.h>
296 %include <openbabel/residue.h>
297 %include <openbabel/internalcoord.h>
298 %include <openbabel/atom.h>
299 %include <openbabel/bond.h>
300 %include <openbabel/reaction.h>
301 %include <openbabel/reactionfacade.h>
302 
303 // Remove C++ iterators
304 %pythoncode %{
305 def exceptionIter(*args):
306     raise Exception("""\nThis method can only be used from C++. To iterate from Python
307 use the Iter classes (OBMolAtomIter, etc.) as described at
308 http://openbabel.org/wiki/Python""")
309 %}
310 %define IGNORE_ITER(parent, iteree)
311 %ignore OpenBabel::parent::Begin ## iteree ## s;
312 %ignore OpenBabel::parent::End ## iteree ## s;
313 %ignore OpenBabel::parent::Begin ## iteree;
314 %ignore OpenBabel::parent::Next ## iteree;
315 %enddef
316 IGNORE_ITER(OBMol, Bond)
317 IGNORE_ITER(OBMol, Atom)
318 IGNORE_ITER(OBMol, Residue)
319 %include <openbabel/mol.h>
320 %pythoncode %{
321 OBMol.BeginAtoms = OBMol.EndAtoms = OBMol.BeginAtom = OBMol.EndAtom = exceptionIter
322 OBMol.BeginBonds = OBMol.EndBonds = OBMol.BeginBond = OBMol.EndBond = exceptionIter
323 OBMol.BeginResidues = OBMol.EndResidues = OBMol.BeginResidue = OBMol.EndResidue = exceptionIter
324 %}
325 
326 %include <openbabel/ring.h>
327 %include <openbabel/parsmart.h>
328 %include <openbabel/alias.h>
329 %ignore OpenBabel::FptIndex;
330 %include <openbabel/fingerprint.h>
331 %ignore OpenBabel::OBDescriptor::LessThan;
332 %include <openbabel/descriptor.h>
333 // wrap GetRGB parameters
334 %include "typemaps.i"
335 %apply double *OUTPUT { double *r, double *g, double *b };
336 
337 // void GetRGB(unsigned int atomic_number, double *r, double *g, double *b);
338 %clear double *r, double *g, double *b;
339 
340 // Ignore shadowed methods
341 %ignore OpenBabel::OBForceField::VectorSubtract(const double *const, const double *const, double *);
342 %ignore OpenBabel::OBForceField::VectorMultiply(const double *const, const double, double *);
343 %include <openbabel/forcefield.h>
344 
345 %include <openbabel/builder.h>
346 %include <openbabel/op.h>
347 
348 %include <openbabel/chargemodel.h>
349 %apply std::string& INPUT { std::string &start } // Required for OBChemTsfm.Init
350 %apply std::string& INPUT { std::string &end }   // Required for OBChemTsfm.Init
351 %include <openbabel/phmodel.h>
352 %include <openbabel/graphsym.h>
353 %include <openbabel/isomorphism.h>
354 %include <openbabel/query.h>
355 %include <openbabel/canon.h>
356 
357 %include <openbabel/stereo/stereo.h>
358 
359 // Ignore shadowed method
360 %ignore OpenBabel::OBRotor::GetRotAtoms() const;
361 %include <openbabel/rotor.h>
362 %ignore OpenBabel::Swab;
363 %include <openbabel/rotamer.h>
364 %include <openbabel/spectrophore.h>
365 #ifdef HAVE_EIGEN
366 %include <openbabel/conformersearch.h>
367 %include <openbabel/math/align.h>
368 #endif
369 
370 // The following %ignores avoid warning messages due to shadowed classes.
371 // This does not imply a loss of functionality as (in this case)
372 // the shadowed class is identical (from the point of view of SWIG) to
373 // the shadowing class.
374 // This is because C++ references (&) are transformed by SWIG back into
375 // pointers, so that OBAtomIter(OBMol &) would be treated the same as
376 // OBAtomIter(OBMol *).
377 
378 %ignore OBAtomAtomIter(OBAtom &);
379 %ignore OBAtomBondIter(OBAtom &);
380 %ignore OBMolAngleIter(OBMol &);
381 %ignore OBMolAtomIter(OBMol &);
382 %ignore OBMolAtomBFSIter(OBMol &);
383 %ignore OBMolAtomDFSIter(OBMol &);
384 %ignore OBMolAtomBFSIter(OBMol &, int);
385 %ignore OBMolAtomDFSIter(OBMol &, int);
386 %ignore OBMolBondIter(OBMol &);
387 %ignore OBMolBondBFSIter(OBMol &);
388 %ignore OBMolBondBFSIter(OBMol &, int);
389 %ignore OBMolPairIter(OBMol &);
390 %ignore OBMolRingIter(OBMol &);
391 %ignore OBMolTorsionIter(OBMol &);
392 %ignore OBResidueIter(OBMol &);
393 %ignore OBResidueAtomIter(OBResidue &);
394 
395 // SWIG treats operator-> specially (see 6.24 "Smart pointers and operator->()").
396 // If we leave this in, it adds
397 // all of the methods of the underlying object (e.g. OBAtom) to the
398 // iterator object, causing bloat.
399 %ignore OpenBabel::OBAtomAtomIter::operator->;
400 %ignore OpenBabel::OBAtomBondIter::operator->;
401 %ignore OpenBabel::OBMolAngleIter::operator->;
402 %ignore OpenBabel::OBMolAtomIter::operator->;
403 %ignore OpenBabel::OBMolAtomBFSIter::operator->;
404 %ignore OpenBabel::OBMolAtomDFSIter::operator->;
405 %ignore OpenBabel::OBMolAtomBFSIter::operator->;
406 %ignore OpenBabel::OBMolAtomDFSIter::operator->;
407 %ignore OpenBabel::OBMolBondIter::operator->;
408 %ignore OpenBabel::OBMolBondBFSIter::operator->;
409 %ignore OpenBabel::OBMolBondBFSIter::operator->;
410 %ignore OpenBabel::OBMolPairIter::operator->;
411 %ignore OpenBabel::OBMolRingIter::operator->;
412 %ignore OpenBabel::OBMolTorsionIter::operator->;
413 %ignore OpenBabel::OBResidueIter::operator->;
414 %ignore OpenBabel::OBResidueAtomIter::operator->;
415 
416 // These classes are renamed so that they can be replaced by Python
417 // classes of the same name which provide Pythonic iterators
418 // (see %pythoncode section below)
419 
420 %rename(_OBAtomAtomIter) OpenBabel::OBAtomAtomIter;
421 %rename(_OBAtomBondIter) OpenBabel::OBAtomBondIter;
422 %rename(_OBMolAngleIter) OpenBabel::OBMolAngleIter;
423 %rename(_OBMolAtomIter) OpenBabel::OBMolAtomIter;
424 %rename(_OBMolAtomBFSIter) OpenBabel::OBMolAtomBFSIter;
425 %rename(_OBMolAtomDFSIter) OpenBabel::OBMolAtomDFSIter;
426 %rename(_OBMolBondIter) OpenBabel::OBMolBondIter;
427 %rename(_OBMolPairIter) OpenBabel::OBMolPairIter;
428 %rename(_OBMolRingIter) OpenBabel::OBMolRingIter;
429 %rename(_OBMolTorsionIter) OpenBabel::OBMolTorsionIter;
430 %rename(_OBResidueIter) OpenBabel::OBResidueIter;
431 %rename(_OBResidueAtomIter) OpenBabel::OBResidueAtomIter;
432 %rename(_OBFingerprintIter) OpenBabel::PluginIter<OBFingerprint>;
433 
434 
435 %include <openbabel/obiter.h>
436 
437 // The following class, OBiter, is subclassed to provide Python iterators
438 // equivalent to the C++ iterators in obiter.h and the plugin iterators
439 
440 %pythoncode %{
441 class OBIter(object):
442     OBiterator = None # This is defined by the subclasses
443 
444     def __init__(self, *params):
445         self.iter = self.OBiterator(*params)
446         self.finished = False
447         if not self.iter.__bool__():
448             self.finished = True
449 
450     def __iter__(self):
451         return self
452 
453     def next(self):
454         if not self.finished:
455             b = self.iter.__ref__()
456             self.iter.inc()
457             if not self.iter.__bool__():
458                 # There is nothing left to iterate over
459                 self.finished = True
460             return b
461         else:
462             raise StopIteration
463 
464     __next__ = next
465 
466 class OBIterWithDepth(OBIter):
467     def next(self):
468         if not self.finished:
469             b = self.iter.__ref__()
470             depth = self.iter.CurrentDepth()
471             self.iter.inc()
472             if not self.iter.__bool__():
473                 # There is nothing left to iterate over
474                 self.finished = True
475             return b, depth
476         else:
477             raise StopIteration
478 
479     __next__ = next
480 
481 class OBAtomAtomIter(OBIter):
482     """Iterator over the atoms attached to an atom."""
483     OBiterator = _OBAtomAtomIter
484 class OBAtomBondIter(OBIter):
485     """Iterator over the bonds attached to an atom."""
486     OBiterator = _OBAtomBondIter
487 class OBMolAngleIter(OBIter):
488     """Iterator over the angles in a molecule."""
489     OBiterator = _OBMolAngleIter
490 class OBMolAtomIter(OBIter):
491     """Iterator over the atoms in a molecule."""
492     OBiterator = _OBMolAtomIter
493 class OBMolAtomBFSIter(OBIterWithDepth):
494     """Iterator over the atoms in a molecule in a breadth-first manner."""
495     OBiterator = _OBMolAtomBFSIter
496 class OBMolAtomDFSIter(OBIter):
497     """Iterator over the atoms in a molecule in a depth-first manner."""
498     OBiterator = _OBMolAtomDFSIter
499 class OBMolBondIter(OBIter):
500     """Iterator over the bonds in a molecule."""
501     OBiterator = _OBMolBondIter
502 class OBMolPairIter(OBIter):
503     """Iterator over pairs of atoms in a molecule."""
504     OBiterator = _OBMolPairIter
505 class OBMolRingIter(OBIter):
506     """Iterator over the rings in a molecule."""
507     OBiterator = _OBMolRingIter
508 class OBMolTorsionIter(OBIter):
509     """Iterator over the torsion angles in a molecule."""
510     OBiterator = _OBMolTorsionIter
511 class OBResidueIter(OBIter):
512     """Iterator over the residues in a molecule."""
513     OBiterator = _OBResidueIter
514 class OBResidueAtomIter(OBIter):
515     """Iterator over the atoms in a residue."""
516     OBiterator = _OBResidueAtomIter
517 %}
518 
519 %include "carrays.i"
520 %array_class(double, doubleArray)
521 %pythoncode %{
522 def double_array(mylist):
523     """Create a C array of doubles from a list."""
524     c = doubleArray(len(mylist))
525     for i,v in enumerate(mylist):
526         c[i] = v
527     return c
528 %}
529 
530 // Copy some of the global variables in cvar into the openbabel namespace
531 
532 %pythoncode %{
533 obErrorLog = cvar.obErrorLog
534 ttab = cvar.ttab
535 atomtyper = cvar.atomtyper
536 aromtyper = cvar.aromtyper
537 %}
538 
539 
540 // Functions to set the log file to std::cout and std::cerr
541 
542 %ignore OBForceField::SetLogFile(std::ostream *pos);
543 %extend OpenBabel::OBForceField {
544   void SetLogToStdOut()
545   {
546     self->SetLogFile(&std::cout);
547   }
548 
549   void SetLogToStdErr()
550   {
551     self->SetLogFile(&std::cerr);
552   }
553 };
554 
555 %extend OpenBabel::OBMol {
556   void SetTorsion(int i, int j, int k, int l, double ang)
557   {
558     self->SetTorsion(self->GetAtom(i), self->GetAtom(j),
559                      self->GetAtom(k), self->GetAtom(l), ang);
560   }
561 };
562 
563 
564 %pythoncode %{
565 def exception(*args):
566     raise Exception("Use OBMol.CloneData instead. OBMol.SetData is only for use from C++.")
567 OBMol.SetData = exception
568 %}
569 
570 %include "stereo.i"
571