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