rdkit.Chem.Pharm3D.Pharmacophore

Package rdkit :: Package Chem :: Package Pharm3D :: Module Pharmacophore |
[hide private]
[frames] | no frames]

# Source Code for Module rdkit.Chem.Pharm3D.Pharmacophore

      1  #
      2  # Copyright (C) 2004-2008 Greg Landrum and Rational Discovery LLC
      3  #
      4  #   @@ All Rights Reserved @@
      5  #  This file is part of the RDKit.
      6  #  The contents are covered by the terms of the BSD license
      7  #  which is included in the file license.txt, found at the root
      8  #  of the RDKit source tree.
      9  #
     10  import numpy
     11
     12  from rdkit import Geometry
     13  from rdkit.Chem import ChemicalFeatures
     14  from rdkit.RDLogger import logger
     15
     16  logger = logger()
     17
     18
     19 -class Pharmacophore:
     20
     21 -  def __init__(self, feats, initMats=True):
     22      self._initializeFeats(feats)
     23      nf = len(feats)
     24      self._boundsMat = numpy.zeros((nf, nf), numpy.float)
     25      self._boundsMat2D = numpy.zeros((nf, nf), numpy.int)
     26      if initMats:
     27        self._initializeMatrices()
     28
     29 -  def _initializeFeats(self, feats):
     30      self._feats = []
     31      for feat in feats:
     32        if isinstance(feat, ChemicalFeatures.MolChemicalFeature):
     33          pos = feat.GetPos()
     34          newFeat = ChemicalFeatures.FreeChemicalFeature(feat.GetFamily(), feat.GetType(),
     35                                                         Geometry.Point3D(pos[0], pos[1], pos[2]))
     36          self._feats.append(newFeat)
     37        else:
     38          self._feats.append(feat)
     39
     40 -  def _initializeMatrices(self):
     41      # initialize the bounds matrix with distances to start with
     42      nf = len(self._feats)
     43      for i in range(1, nf):
     44        loci = self._feats[i].GetPos()
     45        for j in range(i):
     46          locj = self._feats[j].GetPos()
     47          dist = loci.Distance(locj)
     48          self._boundsMat[i, j] = dist
     49          self._boundsMat[j, i] = dist
     50      for i in range(nf):
     51        for j in range(i + 1, nf):
     52          self._boundsMat2D[i, j] = 1000
     53
     54 -  def getFeatures(self):
     55      return self._feats
     56
     57 -  def getFeature(self, i):
     58      return self._feats[i]
     59
     60 -  def getUpperBound(self, i, j):
     61      if i > j:
     62        j, i = i, j
     63      return self._boundsMat[i, j]
     64
     65 -  def getLowerBound(self, i, j):
     66      if j > i:
     67        j, i = i, j
     68      return self._boundsMat[i, j]
     69
     70 -  def _checkBounds(self, i, j):
     71      " raises ValueError on failure "
     72      nf = len(self._feats)
     73      if (0 <= i < nf) and (0 <= j < nf):
     74        return True
     75      raise ValueError("Index out of bound")
     76
     77 -  def setUpperBound(self, i, j, val, checkBounds=False):
     78      if checkBounds:
     79        self._checkBounds(i, j)
     80      if i > j:
     81        j, i = i, j
     82      self._boundsMat[i, j] = val
     83
     84 -  def setLowerBound(self, i, j, val, checkBounds=False):
     85      if checkBounds:
     86        self._checkBounds(i, j)
     87      if j > i:
     88        j, i = i, j
     89      self._boundsMat[i, j] = val
     90
     91 -  def getUpperBound2D(self, i, j):
     92      if i > j:
     93        j, i = i, j
     94      return self._boundsMat2D[i, j]
     95
     96 -  def getLowerBound2D(self, i, j):
     97      if j > i:
     98        j, i = i, j
     99      return self._boundsMat2D[i, j]
    100
    101 -  def setUpperBound2D(self, i, j, val, checkBounds=False):
    102      if checkBounds:
    103        self._checkBounds(i, j)
    104      if i > j:
    105        j, i = i, j
    106      self._boundsMat2D[i, j] = val
    107
    108 -  def setLowerBound2D(self, i, j, val, checkBounds=False):
    109      if checkBounds:
    110        self._checkBounds(i, j)
    111      if j > i:
    112        j, i = i, j
    113      self._boundsMat2D[i, j] = val
    114
    115 -  def __str__(self):
    116      res = ' ' * 14
    117      for i, iFeat in enumerate(self._feats):
    118        res += '%13s ' % iFeat.GetFamily()
    119      res += '\n'
    120      for i, iFeat in enumerate(self._feats):
    121        res += '%13s ' % iFeat.GetFamily()
    122        for j, _ in enumerate(self._feats):
    123          if j < i:
    124            res += '%13.3f ' % self.getLowerBound(i, j)
    125          elif j > i:
    126            res += '%13.3f ' % self.getUpperBound(i, j)
    127          else:
    128            res += '% 13.3f ' % 0.0
    129        res += '\n'
    130      return res
    131
    132
    133 -class ExplicitPharmacophore:
    134    """ this is a pharmacophore with explicit point locations and radii
    135    """
    136
    137 -  def __init__(self, feats=None, radii=None):
    138      if feats and radii:
    139        self._initializeFeats(feats, radii)
    140
    141 -  def _initializeFeats(self, feats, radii):
    142      if len(feats) != len(radii):
    143        raise ValueError('len(feats)!=len(radii)')
    144      self._feats = []
    145      self._radii = []
    146      for feat, rad in zip(feats, radii):
    147        if isinstance(feat, ChemicalFeatures.MolChemicalFeature):
    148          pos = feat.GetPos()
    149          newFeat = ChemicalFeatures.FreeChemicalFeature(feat.GetFamily(), feat.GetType(),
    150                                                         Geometry.Point3D(pos[0], pos[1], pos[2]))
    151        else:
    152          newFeat = feat
    153        self._feats.append(newFeat)
    154        self._radii.append(rad)
    155
    156 -  def getFeatures(self):
    157      return self._feats
    158
    159 -  def getRadii(self):
    160      return self._radii
    161
    162 -  def getFeature(self, i):
    163      return self._feats[i]
    164
    165 -  def getRadius(self, i):
    166      return self._radii[i]
    167
    168 -  def setRadius(self, i, rad):
    169      self._radii[i] = rad
    170
    171 -  def initFromString(self, text):
    172      lines = text.split(r'\n')
    173      self.initFromLines(lines)
    174
    175 -  def initFromFile(self, inF):
    176      self.initFromLines(inF.readlines())
    177
    178 -  def initFromLines(self, lines):
    179      import re
    180      spaces = re.compile('[\ \t]+')
    181
    182      feats = []
    183      rads = []
    184      for lineNum, line in enumerate(lines):
    185        txt = line.split('#')[0].strip()
    186        if txt:
    187          splitL = spaces.split(txt)
    188          if len(splitL) < 5:
    189            logger.error('Input line %d only contains %d fields, 5 are required. Read failed.' %
    190                         (lineNum, len(splitL)))
    191            return
    192          fName = splitL[0]
    193          try:
    194            xP = float(splitL[1])
    195            yP = float(splitL[2])
    196            zP = float(splitL[3])
    197            rad = float(splitL[4])
    198          except ValueError:
    199            logger.error('Error parsing a number of line %d. Read failed.' % (lineNum))
    200            return
    201          feats.append(
    202            ChemicalFeatures.FreeChemicalFeature(fName, fName, Geometry.Point3D(xP, yP, zP)))
    203          rads.append(rad)
    204      self._initializeFeats(feats, rads)
    205
    206 -  def __str__(self):
    207      res = ''
    208      for feat, rad in zip(self._feats, self._radii):
    209        res += '% 12s ' % feat.GetFamily()
    210        p = feat.GetPos()
    211        res += '   % 8.4f % 8.4f % 8.4f    ' % (p.x, p.y, p.z)
    212        res += '% 5.2f' % rad
    213        res += '\n'
    214      return res
    215