Deriving new instances of OEUnaryFunctions and OEUnaryPredicates requires C++, but for many cases, a special case of these has been instantiated for atoms and bonds. OEPyAtomPredicate and OEPyBondPredicate are special case predicates that take a Python function as the single argument. In essence, we are creating a callback that itself holds a callback. This Python function must be defined a certain way. First, it can only take a single argument, an atom for an OEPyAtomPredicate and a bond for an OEPyBondPredicate. Second, it must return 1 if the atom(bond) satisifies the condition and 0 otherwise. Since it may sometimes be necessary to create predicates that hold state, a class instance method can be used. Just make sure that the method (to which a pointer will be stored inside the C++ predicate) stays in scope while the predicate is used.
The following example shows a user defined functor which screens for atoms whose atomic mass is greater than 15.
#!/usr/bin/env python # ch21-2.py from openeye.oechem import * def AtomWgtGT15(atom): if OEGetAverageWeight(atom.GetAtomicNum())>15: return 1 return 0 WeightGT15 = PyAtomPredicate(AtomWgtGT15) mol = OEGraphMol() OEParseSmiles(mol, "c1c(O)c(O)c(Cl)cc1CCCBr") OETriposAtomNames(mol) for atom in mol.GetAtoms(WeightGT15): print atom.GetName(), "has weight > 15."