Package rdkit :: Package Chem :: Package Draw :: Module IPythonConsole
[hide private]
[frames] | no frames]

Source Code for Module rdkit.Chem.Draw.IPythonConsole

  1  import IPython 
  2   
  3  if IPython.release.version < '0.11': 
  4      raise ImportError('this module requires at least v0.11 of IPython') 
  5  elif IPython.release.version < '2.0': 
  6      install_nbextension=None 
  7      _canUse3D=False 
  8  else: 
  9      try: 
 10          try: 
 11              from notebook.nbextensions import install_nbextension 
 12              _canUse3D=True 
 13          except ImportError: 
 14              #  Older IPythonVersion location 
 15              from IPython.html.nbextensions import install_nbextension 
 16              _canUse3D=True 
 17      except ImportError: 
 18          # can't find notebook extensions for integrating javascript 
 19          #  with Jupyter/IPython, disable widgets. 
 20          _canUse3D=False 
 21          sys.stderr.write("*"*44) 
 22          sys.stderr.write("\nCannot import nbextensions\n") 
 23          sys.stderr.write("Current IPython/Jupyter version is %s\n"% 
 24                           IPython.release.version) 
 25          sys.stderr.write("Disabling 3D rendering\n") 
 26          sys.stderr.write("*"*44) 
 27          sys.stderr.write("\n") 
 28          import traceback 
 29          traceback.print_exc() 
 30   
 31  from rdkit import Chem 
 32  from rdkit.Chem import rdchem, rdChemReactions 
 33  from rdkit.Chem import Draw 
 34  from rdkit.Chem.Draw import rdMolDraw2D 
 35  from rdkit.six import BytesIO,StringIO 
 36  import copy 
 37  import os 
 38  import json 
 39  import uuid 
 40  import numpy 
 41  try: 
 42      import Image 
 43  except ImportError: 
 44      from PIL import Image 
 45   
 46  from IPython.display import SVG 
 47   
 48  molSize = (450, 150) 
 49  highlightSubstructs = True 
 50  kekulizeStructures = True 
 51   
 52  ipython_useSVG = False 
 53  ipython_3d = False 
 54  molSize_3d = (450, 450) 
 55  drawing_type_3d = "ball and stick" 
 56  camera_type_3d = "perspective" 
 57  shader_3d = "lambert" 
 58   
 59  # expose RDLogs to Python StdErr so they are shown 
 60  #  in the IPythonConsole not the server logs. 
 61  Chem.WrapLogs() 
 62   
63 -def _toJSON(mol):
64 """For IPython notebook, renders 3D webGL objects.""" 65 66 if not ipython_3d or not mol.GetNumConformers(): 67 return None 68 69 try: 70 import imolecule 71 except ImportError: 72 raise ImportError("Cannot import 3D rendering. Please install " 73 "with `pip install imolecule`.") 74 75 conf = mol.GetConformer() 76 if not conf.Is3D(): 77 return None 78 79 mol = Chem.Mol(mol) 80 try: 81 Chem.Kekulize(mol) 82 except Exception: 83 mol = Chem.Mol(mol) 84 size = molSize_3d 85 86 # center the molecule: 87 atomps = numpy.array([list(conf.GetAtomPosition(x)) 88 for x in range(mol.GetNumAtoms())]) 89 avgP = numpy.average(atomps, 0) 90 atomps -= avgP 91 92 # Convert the relevant parts of the molecule into JSON for rendering 93 atoms = [{"element": atom.GetSymbol(), 94 "location": list(atomps[atom.GetIdx()])} 95 for atom in mol.GetAtoms()] 96 bonds = [{"atoms": [bond.GetBeginAtomIdx(), 97 bond.GetEndAtomIdx()], 98 "order": int(bond.GetBondTypeAsDouble())} 99 for bond in mol.GetBonds()] 100 mol = {"atoms": atoms, "bonds": bonds} 101 return imolecule.draw({"atoms": atoms, "bonds": bonds}, format="json", 102 size=molSize_3d, drawing_type=drawing_type_3d, 103 camera_type=camera_type_3d, shader=shader_3d, 104 display_html=False)
105 106
107 -def _toPNG(mol):
108 if hasattr(mol,'__sssAtoms'): 109 highlightAtoms=mol.__sssAtoms 110 else: 111 highlightAtoms=[] 112 try: 113 mol.GetAtomWithIdx(0).GetExplicitValence() 114 except RuntimeError: 115 mol.UpdatePropertyCache(False) 116 117 if not hasattr(rdMolDraw2D,'MolDraw2DCairo'): 118 mc = copy.deepcopy(mol) 119 try: 120 img = Draw.MolToImage(mc,size=molSize,kekulize=kekulizeStructures, 121 highlightAtoms=highlightAtoms) 122 except ValueError: # <- can happen on a kekulization failure 123 mc = copy.deepcopy(mol) 124 img = Draw.MolToImage(mc,size=molSize,kekulize=False, 125 highlightAtoms=highlightAtoms) 126 bio = BytesIO() 127 img.save(bio,format='PNG') 128 return bio.getvalue() 129 else: 130 nmol = rdMolDraw2D.PrepareMolForDrawing(mol,kekulize=kekulizeStructures) 131 d2d = rdMolDraw2D.MolDraw2DCairo(molSize[0],molSize[1]) 132 d2d.DrawMolecule(nmol,highlightAtoms=highlightAtoms) 133 d2d.FinishDrawing() 134 return d2d.GetDrawingText()
135
136 -def _toSVG(mol):
137 if not ipython_useSVG: 138 return None 139 if hasattr(mol, '__sssAtoms'): 140 highlightAtoms = mol.__sssAtoms 141 else: 142 highlightAtoms = [] 143 try: 144 mol.GetAtomWithIdx(0).GetExplicitValence() 145 except RuntimeError: 146 mol.UpdatePropertyCache(False) 147 148 try: 149 mc = rdMolDraw2D.PrepareMolForDrawing(mol,kekulize=kekulizeStructures) 150 except ValueError: # <- can happen on a kekulization failure 151 mc = rdMolDraw2D.PrepareMolForDrawing(mol,kekulize=False) 152 d2d = rdMolDraw2D.MolDraw2DSVG(molSize[0],molSize[1]) 153 d2d.DrawMolecule(mc,highlightAtoms=highlightAtoms) 154 d2d.FinishDrawing() 155 svg = d2d.GetDrawingText() 156 return svg.replace("svg:","")
157 158
159 -def _toReactionPNG(rxn):
160 rc = copy.deepcopy(rxn) 161 img = Draw.ReactionToImage(rc,subImgSize=(int(molSize[0]/3), molSize[1])) 162 bio = BytesIO() 163 img.save(bio,format='PNG') 164 return bio.getvalue()
165
166 -def _GetSubstructMatch(mol, query, **kwargs):
167 res = mol.__GetSubstructMatch(query, **kwargs) 168 if highlightSubstructs: 169 mol.__sssAtoms = list(res) 170 else: 171 mol.__sssAtoms = [] 172 return res
173 174
175 -def _GetSubstructMatches(mol, query, **kwargs):
176 res = mol.__GetSubstructMatches(query, **kwargs) 177 mol.__sssAtoms = [] 178 if highlightSubstructs: 179 for entry in res: 180 mol.__sssAtoms.extend(list(entry)) 181 return res
182 183 184 # code for displaying PIL images directly,
185 -def display_pil_image(img):
186 """displayhook function for PIL Images, rendered as PNG""" 187 bio = BytesIO() 188 img.save(bio,format='PNG') 189 return bio.getvalue()
190 191 _MolsToGridImageSaved = None
192 -def ShowMols(mols,**kwargs):
193 global _MolsToGridImageSaved 194 if 'useSVG' not in kwargs: 195 # use SVG by default 196 kwargs['useSVG'] = True 197 if _MolsToGridImageSaved is not None: 198 fn = _MolsToGridImageSaved 199 else: 200 fm = Draw.MolsToGridImage 201 res = fn(mols,**kwargs) 202 if kwargs['useSVG']: 203 return SVG(res) 204 else: 205 return res
206
207 -def InstallIPythonRenderer():
208 global _MolsToGridImageSaved 209 rdchem.Mol._repr_png_ = _toPNG 210 rdchem.Mol._repr_svg_ = _toSVG 211 if _canUse3D: 212 rdchem.Mol._repr_html_ = _toJSON 213 rdChemReactions.ChemicalReaction._repr_png_ = _toReactionPNG 214 if not hasattr(rdchem.Mol, '__GetSubstructMatch'): 215 rdchem.Mol.__GetSubstructMatch = rdchem.Mol.GetSubstructMatch 216 rdchem.Mol.GetSubstructMatch = _GetSubstructMatch 217 if not hasattr(rdchem.Mol, '__GetSubstructMatches'): 218 rdchem.Mol.__GetSubstructMatches = rdchem.Mol.GetSubstructMatches 219 rdchem.Mol.GetSubstructMatches = _GetSubstructMatches 220 Image.Image._repr_png_ = display_pil_image 221 _MolsToGridImageSaved = Draw.MolsToGridImage 222 Draw.MolsToGridImage = ShowMols
223 224 InstallIPythonRenderer() 225 226
227 -def UninstallIPythonRenderer():
228 global _MolsToGridImageSaved 229 del rdchem.Mol._repr_svg_ 230 del rdchem.Mol._repr_png_ 231 if _canUse3D: 232 del rdchem.Mol._repr_html_ 233 del rdChemReactions.ChemicalReaction._repr_png_ 234 if hasattr(rdchem.Mol, '__GetSubstructMatch'): 235 rdchem.Mol.GetSubstructMatch = rdchem.Mol.__GetSubstructMatch 236 del rdchem.Mol.__GetSubstructMatch 237 if hasattr(rdchem.Mol, '__GetSubstructMatches'): 238 rdchem.Mol.GetSubstructMatches = rdchem.Mol.__GetSubstructMatches 239 del rdchem.Mol.__GetSubstructMatches 240 del Image.Image._repr_png_ 241 if _MolsToGridImageSaved is not None: 242 Draw.MolsToGridImage = _MolsToGridImageSaved
243