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