rdkit.Chem.Draw.IPythonConsole

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