rdkit.Dbase.DbReport

Package rdkit :: Package Dbase :: Module DbReport |
[hide private]
[frames] | no frames]

# Source Code for Module rdkit.Dbase.DbReport

      1  # $Id$
      2  #
      3  #  Copyright (C) 2003-2006  Rational Discovery LLC
      4  #
      5  #   @@ All Rights Reserved @@
      6  #  This file is part of the RDKit.
      7  #  The contents are covered by the terms of the BSD license
      8  #  which is included in the file license.txt, found at the root
      9  #  of the RDKit source tree.
     10  #
     11  from __future__ import print_function
     12
     13  try:
     14    from reportlab import platypus
     15  except ImportError:
     16    import sys
     17    sys.stderr.write('ReportLab module could not be imported.  Db->PDF functionality not available')
     18    GetReportlabTable = None
     19    QuickReport = None
     20  else:
     21    from rdkit import Chem
     22    try:
     23      from pyRDkit.utils import chemdraw
     24    except ImportError:
     25      hasCDX = 0
     26    else:
     27      hasCDX = 1
     28    from rdkit.utils import cactvs
     29    from rdkit.Chem import rdDepictor
     30    from rdkit.Chem.Draw import DrawUtils
     31    from rdkit.Dbase.DbConnection import DbConnect
     32    from rdkit.Dbase import DbInfo
     33    from rdkit.Reports.PDFReport import PDFReport, ReportUtils
     34    from rdkit.sping.ReportLab.pidReportLab import RLCanvas as Canvas
     35    from rdkit.Chem.Draw.MolDrawing import MolDrawing, DrawingOptions
     36    from reportlab.lib import colors
     37    from reportlab.lib.units import inch
     38    import sys
     39
     40 -  def GetReportlabTable(self, *args, **kwargs):
     41      """ this becomes a method of DbConnect  """
     42      dbRes = self.GetData(*args, **kwargs)
     43      rawD = [dbRes.GetColumnNames()]
     44      colTypes = dbRes.GetColumnTypes()
     45      binCols = []
     46      for i in range(len(colTypes)):
     47        if colTypes[i] in DbInfo.sqlBinTypes or colTypes[i] == 'binary':
     48          binCols.append(i)
     49      nRows = 0
     50      for entry in dbRes:
     51        nRows += 1
     52        for col in binCols:
     53          entry = list(entry)
     54          entry[col] = 'N/A'
     55        rawD.append(entry)
     56
     57      res = platypus.Table(rawD)
     58      return res
     59
     60 -  class CDXImageTransformer(object):
     61
     62 -    def __init__(self, smiCol, width=1, verbose=1, tempHandler=None):
     63        self.smiCol = smiCol
     64        if tempHandler is None:
     65          tempHandler = ReportUtils.TempFileHandler()
     66        self.tempHandler = tempHandler
     67        self.width = width * inch
     68        self.verbose = verbose
     69
     70 -    def __call__(self, arg):
     71        res = list(arg)
     72        if self.verbose:
     73          print('Render:', res[0])
     74        if hasCDX:
     75          smi = res[self.smiCol]
     76          tmpName = self.tempHandler.get('.jpg')
     77          try:
     78            img = chemdraw.SmilesToPilImage(smi)
     79            w, h = img.size
     80            aspect = float(h) / w
     81            img.save(tmpName)
     82            img = platypus.Image(tmpName)
     83            img.drawWidth = self.width
     84            img.drawHeight = aspect * self.width
     85            res[self.smiCol] = img
     86          except Exception:
     87            import traceback
     88            traceback.print_exc()
     89            res[self.smiCol] = 'Failed'
     90        return res
     91
     92 -  class CactvsImageTransformer(object):
     93
     94 -    def __init__(self, smiCol, width=1., verbose=1, tempHandler=None):
     95        self.smiCol = smiCol
     96        if tempHandler is None:
     97          tempHandler = ReportUtils.TempFileHandler()
     98        self.tempHandler = tempHandler
     99        self.width = width * inch
    100        self.verbose = verbose
    101
    102 -    def __call__(self, arg):
    103        res = list(arg)
    104        if self.verbose:
    105          sys.stderr.write('Render(%d): %s\n' % (self.smiCol, str(res[0])))
    106        smi = res[self.smiCol]
    107        tmpName = self.tempHandler.get('.gif')
    108        aspect = 1
    109        width = 300
    110        height = aspect * width
    111        ok = cactvs.SmilesToGif(smi, tmpName, (width, height))
    112        if ok:
    113          try:
    114            img = platypus.Image(tmpName)
    115            img.drawWidth = self.width
    116            img.drawHeight = aspect * self.width
    117          except Exception:
    118            ok = 0
    119        if ok:
    120          res[self.smiCol] = img
    121        else:
    122          # FIX: maybe include smiles here in a Paragraph?
    123          res[self.smiCol] = 'Failed'
    124        return res
    125
    126 -  class ReportLabImageTransformer(object):
    127
    128 -    def __init__(self, smiCol, width=1., verbose=1, tempHandler=None):
    129        self.smiCol = smiCol
    130        self.width = width * inch
    131        self.verbose = verbose
    132
    133 -    def __call__(self, arg):
    134        res = list(arg)
    135        if self.verbose:
    136          sys.stderr.write('Render(%d): %s\n' % (self.smiCol, str(res[0])))
    137        smi = res[self.smiCol]
    138        aspect = 1
    139        width = self.width
    140        height = aspect * width
    141        try:
    142          mol = Chem.MolFromSmiles(smi)
    143          Chem.Kekulize(mol)
    144          canv = Canvas((width, height))
    145          options = DrawingOptions()
    146          options.atomLabelMinFontSize = 3
    147          options.bondLineWidth = 0.5
    148          drawing = MolDrawing(options=options)
    149          if not mol.GetNumConformers():
    150            rdDepictor.Compute2DCoords(mol)
    151          drawing.AddMol(mol, canvas=canv)
    152          ok = True
    153        except Exception:
    154          if self.verbose:
    155            import traceback
    156            traceback.print_exc()
    157          ok = False
    158
    159        if ok:
    160          res[self.smiCol] = canv.drawing
    161        else:
    162          # FIX: maybe include smiles here in a Paragraph?
    163          res[self.smiCol] = 'Failed'
    164        return res
    165
    166 -  class RDImageTransformer(object):
    167
    168 -    def __init__(self, smiCol, width=1., verbose=1, tempHandler=None):
    169        self.smiCol = smiCol
    170        if tempHandler is None:
    171          tempHandler = ReportUtils.TempFileHandler()
    172        self.tempHandler = tempHandler
    173        self.width = width * inch
    174        self.verbose = verbose
    175
    176 -    def __call__(self, arg):
    177        res = list(arg)
    178        if self.verbose:
    179          sys.stderr.write('Render(%d): %s\n' % (self.smiCol, str(res[0])))
    180        smi = res[self.smiCol]
    181        tmpName = self.tempHandler.get('.jpg')
    182        aspect = 1
    183        width = 300
    184        height = aspect * width
    185        ok = DrawUtils.SmilesToJpeg(smi, tmpName, size=(width, height))
    186        if ok:
    187          try:
    188            img = platypus.Image(tmpName)
    189            img.drawWidth = self.width
    190            img.drawHeight = aspect * self.width
    191          except Exception:
    192            ok = 0
    193        if ok:
    194          res[self.smiCol] = img
    195        else:
    196          # FIX: maybe include smiles here in a Paragraph?
    197          res[self.smiCol] = 'Failed'
    198        return res
    199
    200 -  def QuickReport(conn, fileName, *args, **kwargs):
    201      title = 'Db Report'
    202      if 'title' in kwargs:
    203        title = kwargs['title']
    204        del kwargs['title']
    205
    206      names = [x.upper() for x in conn.GetColumnNames()]
    207      try:
    208        smiCol = names.index('SMILES')
    209      except ValueError:
    210        try:
    211          smiCol = names.index('SMI')
    212        except ValueError:
    213          smiCol = -1
    214      if smiCol > -1:
    215        if hasCDX:
    216          tform = CDXImageTransformer(smiCol)
    217        elif 1:
    218          tform = ReportLabImageTransformer(smiCol)
    219        else:
    220          tform = CactvsImageTransformer(smiCol)
    221
    222      else:
    223        tform = None
    224      kwargs['transform'] = tform
    225      tbl = conn.GetReportlabTable(*args, **kwargs)
    226      tbl.setStyle(
    227        platypus.TableStyle([('GRID', (0, 0), (-1, -1), 1, colors.black),
    228                             ('FONT', (0, 0), (-1, -1), 'Times-Roman', 8), ]))
    229
    230      if smiCol > -1 and tform:
    231        tbl._argW[smiCol] = tform.width * 1.2
    232      elements = [tbl]
    233      reportTemplate = PDFReport()
    234      reportTemplate.pageHeader = title
    235
    236      doc = platypus.SimpleDocTemplate(fileName)
    237      doc.build(elements, onFirstPage=reportTemplate.onPage, onLaterPages=reportTemplate.onPage)
    238
    239    DbConnect.GetReportlabTable = GetReportlabTable
    240
    241  if __name__ == '__main__':
    242    dbName = sys.argv[1]
    243    tblName = sys.argv[2]
    244    fName = 'report.pdf'
    245    conn = DbConnect(dbName, tblName)
    246    QuickReport(conn, fName, where="where mol_id in ('1','100','104','107')")
    247