Markus,

Here's a somewhat longer and more detailed answer to your question
about directionality of feature points.

First a couple of remarks about features themselves (mainly repeating
section 7 of the "Getting Started with the RDKit in Python" document:
The class for pharmacophore features is MolChemicalFeature (found in
the module Chem.rdMolChemicalFeatures). These features are normally
built using a MolChemicalFeatureFactory (same module). A feature
factory uses a series of SMARTS-based definitions to define chemical
features. There's a sample file in $RDBASE/Data/BaseFeatures.fdef and
the format of the files is defined in
$RDBASE/Docs/Programs/RDPharm3D/FDefFile.htm

Here's some sample code for finding chemical features:
>>> import Chem
>>> from Chem import ChemicalFeatures
>>> import RDConfig
>>> import os
>>> fdefName = os.path.join(RDConfig.RDDataDir,'Base.fdef')
>>> factory = ChemicalFeatures.BuildFeatureFactory(fdefName)
>>> m = Chem.MolFromMolFile('test.mol')
>>> feats = factory.GetFeaturesForMol(m)
>>> feats[0].GetFamily()
'Donor'
>>> feats[0].GetType()
'SingleAtomDonor'
>>> feats[0].GetPos()
<Geometry.rdGeometry.Point3D object at 0x00B33190>

You see that the positions of the features are defined by Point3D
objects. These are what we can use to calculate feature directions
(a.k.a. Projected Pharmacophore Points).

>  I wonder how to do that. I read the .cpp files (not very funny for a
>  scripting-newbie :-) ) and found a lot of functions for related problems.

Yes, I can imagine that wasn't much fun at all. You're better off
reading the .h files or looking through the api documentation for the
c++, but that's only marginally easier.

>  I guess that there are already some  functions, that calculate the
>  cartesian coordinates for a point, that is defined by angles and
>  distances towards some other points.

Indeed! The code to handle geometry is part of the Point3D object:

[6]>>> help(Geometry.Point3D)
Help on class Point3D in module Geometry.rdGeometry:

class Point3D(Boost.Python.instance)
 |  A class to represent a three-dimensional point
 |  The x, y, and z coordinates can be read and written using either attributes
 |  (i.e. pt.x = 4) or indexing (i.e. pt[0] = 4).
 |
 |  Method resolution order:
 |      Point3D
 |      Boost.Python.instance
 |      __builtin__.object
 |
 |  Methods defined here:
 |
 |  AngleTo(...)
 |      AngleTo( (Point3D)arg1, (Point3D)arg2) -> float :
 |          determines the angle between a vector to this point
(between 0 and PI)
 |
 |          C++ signature :
 |              double AngleTo(RDGeom::Point3D {lvalue},RDGeom::Point3D)
 |
 |  CrossProduct(...)
 |      CrossProduct( (Point3D)arg1, (Point3D)arg2) -> Point3D :
 |          Get the cross product between two points
 |
 |          C++ signature :
 |              RDGeom::Point3D CrossProduct(RDGeom::Point3D
{lvalue},RDGeom::Point3D)
 |
 |  DirectionVector(...)
 |      DirectionVector( (Point3D)arg1, (Point3D)arg2) -> Point3D :
 |          return a normalized direction vector from this point to another
 |
 |          C++ signature :
 |              RDGeom::Point3D DirectionVector(RDGeom::Point3D
{lvalue},RDGeom::Point3D)
 |
 |  Distance(...)
 |      Distance( (Point3D)arg1, (Point3D)arg2) -> float :
 |          Distance from this point to another point
 |
 |          C++ signature :
 |              double Distance(RDGeom::Point3D,RDGeom::Point3D)
 |
 |  DotProduct(...)
 |      DotProduct( (Point3D)arg1, (Point3D)arg2) -> float :
 |          Dot product with another point
 |
 |          C++ signature :
 |              double DotProduct(RDGeom::Point3D {lvalue},RDGeom::Point3D)
 |
 |  Length(...)
 |      Length( (Point3D)arg1) -> float :
 |          Length of the vector
 |
 |          C++ signature :
 |              double Length(RDGeom::Point3D {lvalue})
 |
 |  LengthSq(...)
 |      LengthSq( (Point3D)arg1) -> float :
 |          Square of the length
 |
 |          C++ signature :
 |              double LengthSq(RDGeom::Point3D {lvalue})
 |
 |  Normalize(...)
 |      Normalize( (Point3D)arg1) -> None :
 |          Normalize the vector (using L2 norm)
 |
 |          C++ signature :
 |              void Normalize(RDGeom::Point3D {lvalue})
 |
 |  SignedAngleTo(...)
 |      SignedAngleTo( (Point3D)arg1, (Point3D)arg2) -> float :
 |          determines the signed angle between a vector to this point
(between 0 and 2*PI)
 |
 |          C++ signature :
 |              double SignedAngleTo(RDGeom::Point3D {lvalue},RDGeom::Point3D)

You also need to know how to get the vector between two Point3Ds (also
a Point3D):
[9]>>> p1 = Geometry.Point3D(1.0,2.0,4.0)
[10]>>> p2 = Geometry.Point3D(-1.0,0,4.0)
[11]>>> p2-p1
Out[11] <Geometry.rdGeometry.Point3D object at 0x844af7c>
[12]>>> p3=p2-p1
[13]>>> list(p3)
Out[13] [-2.0, -2.0, 0.0]

>  As to my understanding I could just for example take a C=O fragment,
>  feed the cartesians of the two atoms, define the angles between the C=O
>  bond and the free lone pairs of the oxygen plus some tetrahedral as well
>  as the optimal distance of a H-Bond and thus get the coordinates of the
>  projected point. Sounds simple, but how to implement it using the RDKit
>  python Library?

As I mentioned on Friday: there's already code in the RDKit for
calculating feature directions that can help you get started here.
It's in $RDBASE/Python/Chem/Features/FeatDirUtilsRD.py. One thing to
know about this file is that it's a quick port of some work I did for
feature directions using another cheminformatics system, so it's not
the prettiest code. Apologies in advance for that.

If you have PyMol installed on your machine (highly recommended, it's
a great visualizer) and start it using the -R argument (this causes
PyMol to run an xml-rpc server so that it can be easily controlled
from other software), you can use
$RDBASE/Python/Chem.Features/ShowFeats.py to display the features and
their directions on a molecule:
% python $RDBASE/Python/Chem/Features/ShowFeats.py
--fdef=$RDBASE/Data/BaseFeatures.fdef test.mol

I hope this is enough to get you started. Feel free to post with questions.

-greg

Reply via email to