From: Noel O'B. <bao...@gm...> - 2006-12-12 12:55:18
|
obiter.h exposes a number of C++ convenience functions for iterating over atoms, bonds, etc. e.g. OBMolAtomIter iterates over the atoms in a molecule. However, these iterator methods don't work very well from scripting languages (I'm not even sure if it's possible to use them as they were designed to be used). It's much easier to use the built-in iterator methods present in the various languages. In Python, the easiest way to do this is to create a list of the atoms of a molecule and then iterate over these: obAtoms = [obMol.GetAtom(i+1) for i in range(obMol.NumAtoms())] for obAtom in obAtoms: # Do something with obAtom It would be very useful to collect such OpenBabel idioms from different scripting languages and put them on the scripting pages (or even include them in the interface files as convenience functions). Could anyone suggest similar code for Perl/Ruby/Java? Noel |
From: richard a. <ric...@ya...> - 2006-12-12 15:29:28
|
--- Noel O'Boyle <bao...@gm...> wrote: > obiter.h exposes a number of C++ convenience > functions for iterating > over atoms, bonds, etc. e.g. OBMolAtomIter iterates > over the atoms in > a molecule. > > However, these iterator methods don't work very well > from scripting > languages (I'm not even sure if it's possible to use > them as they were > designed to be used). It's much easier to use the > built-in iterator > methods present in the various languages. In Python, > the easiest way > to do this is to create a list of the atoms of a > molecule and then > iterate over these: > > obAtoms = [obMol.GetAtom(i+1) for i in > range(obMol.NumAtoms())] > for obAtom in obAtoms: > # Do something with obAtom > > It would be very useful to collect such OpenBabel > idioms from > different scripting languages and put them on the > scripting pages (or > even include them in the interface files as > convenience functions). > Could anyone suggest similar code for > Perl/Ruby/Java? Interesting idea. In Ruby, I'd like to just do something like this: mol.each_atom do |atom| # do something with atom end And similar methods for other iterable collections. There are a few ways to get there. One would be throught the SWIG interface file or C bridge it generates. Another would be to just define a Ruby class with the iterators built-in. Another would be through Ruby metaprogramming. This has the advantage over the other methods that it can be very concise. It comes with a potential decrease in speed. cheers, Rich ____________________________ Richard Apodaca Blog: http://depth-first.com ____________________________________________________________________________________ Any questions? Get answers on any topic at www.Answers.yahoo.com. Try it now. |
From: Noel O'B. <bao...@gm...> - 2006-12-13 09:44:59
|
I spoke too soon - after playing around with the OBMolAtomIter class for a while I found that it *is* in working order (from Python's point of view). It does require some wrapping to make it into a real Python iterator though. If you look at the interface files (.i), you can see that Geoff has renamed some methods to good(), deref() and inc(). Using these, it's possible to create a class that behaves as an iterator. (Note that .next() and __iter__() are magic methods that Python uses to create an iterator. Presumably other languages have their own ways of creating iterators.) ================ import openbabel as ob import pybel class Testiter(object): def __init__(self, mol): self.iter = ob.OBMolAtomIter(mol) self.finished = False def __iter__(self): return self def next(self): obAtom = self.iter.deref() self.iter.inc() if not self.finished: if not self.iter.good(): self.finished = True return obAtom else: raise StopIteration mol = pybel.readstring("smi", "CNC").OBMol for atom in Testiter(mol): print atom.GetAtomicMass() ================ I'll move this into the SWIG interface file somehow; I think it's possible to replace the existing OBMolAtomIter class with a Python class of the same name. Hopefully it's also possible to create these classes at runtime (or have a Factory method) as there are now about 10 iterators of similar structure in obiter.h. Regards, Noel On 12/12/06, richard apodaca <ric...@ya...> wrote: > > --- Noel O'Boyle <bao...@gm...> wrote: > > > obiter.h exposes a number of C++ convenience > > functions for iterating > > over atoms, bonds, etc. e.g. OBMolAtomIter iterates > > over the atoms in > > a molecule. > > > > However, these iterator methods don't work very well > > from scripting > > languages (I'm not even sure if it's possible to use > > them as they were > > designed to be used). It's much easier to use the > > built-in iterator > > methods present in the various languages. In Python, > > the easiest way > > to do this is to create a list of the atoms of a > > molecule and then > > iterate over these: > > > > obAtoms = [obMol.GetAtom(i+1) for i in > > range(obMol.NumAtoms())] > > for obAtom in obAtoms: > > # Do something with obAtom > > > > It would be very useful to collect such OpenBabel > > idioms from > > different scripting languages and put them on the > > scripting pages (or > > even include them in the interface files as > > convenience functions). > > Could anyone suggest similar code for > > Perl/Ruby/Java? > > Interesting idea. In Ruby, I'd like to just do > something like this: > > mol.each_atom do |atom| > # do something with atom > end > > And similar methods for other iterable collections. > > There are a few ways to get there. One would be > throught the SWIG interface file or C bridge it > generates. Another would be to just define a Ruby > class with the iterators built-in. > > Another would be through Ruby metaprogramming. This > has the advantage over the other methods that it can > be very concise. It comes with a potential decrease in > speed. > > cheers, > Rich > > > > ____________________________ > Richard Apodaca > Blog: http://depth-first.com > > > > ____________________________________________________________________________________ > Any questions? Get answers on any topic at www.Answers.yahoo.com. Try it now. > > ------------------------------------------------------------------------- > Take Surveys. Earn Cash. Influence the Future of IT > Join SourceForge.net's Techsay panel and you'll get the chance to share your > opinions on IT & business topics through brief surveys - and earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > _______________________________________________ > OpenBabel-scripting mailing list > Ope...@li... > https://lists.sourceforge.net/lists/listinfo/openbabel-scripting > |
From: Geoffrey H. <ge...@ge...> - 2006-12-13 13:24:40
|
On Dec 13, 2006, at 4:44 AM, Noel O'Boyle wrote: > that Geoff has renamed some methods to good(), deref() and inc(). > Using these, it's possible to create a class that behaves as an > iterator. Don't look at me. Those were contributed. :-) > classes at runtime (or have a Factory method) as there are now about > 10 iterators of similar structure in obiter.h. As both Rich and Noel have mentioned, iterating doesn't necessarily work the same in C++ as in scripting languages. (Heck, in C++ people often have different ways of doing iteration.) If you think it would be a good idea to have methods to just pass a list of atoms or bonds, residues, etc. please let me know. Many of these methods already exist, although I haven't checked for "completeness" in the API. SWIG doesn't always make it easy to inject code into the C++ interface file or the scripting language module that it generates. Of course that's why we've put hacks into the Makefiles. So if there are bits we'd like to put in either place, let me know and I'll figure out an appropriate way to get it done. Cheers, -Geoff |
From: Noel O'B. <bao...@gm...> - 2006-12-13 13:37:37
|
I've just checked in some changes to openbabel-python.i based on the code in my earlier email on this topic. You can see the file here: http://openbabel.svn.sourceforge.net/viewvc/openbabel/openbabel/trunk/scripts/openbabel-python.i?revision=1656&view=markup Now it's possible to use OBMolAtomIter as if it's a Python iterator: ================== import openbabel import pybel mol = pybel.readstring("smi", "CNC").OBMol for atom in openbabel.OBMolAtomIter(mol): print atom.GetAtomicMass() ===================== Hopefully, we can get similar methods together for the other language bindings. Noel On 13/12/06, Geoffrey Hutchison <ge...@ge...> wrote: > > On Dec 13, 2006, at 4:44 AM, Noel O'Boyle wrote: > > > that Geoff has renamed some methods to good(), deref() and inc(). > > Using these, it's possible to create a class that behaves as an > > iterator. > > Don't look at me. Those were contributed. :-) > > > classes at runtime (or have a Factory method) as there are now about > > 10 iterators of similar structure in obiter.h. > > As both Rich and Noel have mentioned, iterating doesn't necessarily > work the same in C++ as in scripting languages. (Heck, in C++ people > often have different ways of doing iteration.) > > If you think it would be a good idea to have methods to just pass a > list of atoms or bonds, residues, etc. please let me know. Many of > these methods already exist, although I haven't checked for > "completeness" in the API. > > SWIG doesn't always make it easy to inject code into the C++ > interface file or the scripting language module that it generates. Of > course that's why we've put hacks into the Makefiles. So if there are > bits we'd like to put in either place, let me know and I'll figure > out an appropriate way to get it done. > > Cheers, > -Geoff > > |