Package rdkit :: Package Chem :: Package Draw :: Module IPythonConsole

[hide private]
[frames] | no frames]

# Source Code for Module rdkit.Chem.Draw.IPythonConsole

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