def __call__(self, arg): res = list(arg) if self.verbose: sys.stderr.write('Render(%d): %s\n' % (self.smiCol, str(res[0]))) smi = res[self.smiCol] aspect = 1 width = self.width height = aspect * width try: mol = Chem.MolFromSmiles(smi) Chem.Kekulize(mol) canv = Canvas((width, height)) options = DrawingOptions() options.atomLabelMinFontSize = 3 options.bondLineWidth = 0.5 drawing = MolDrawing(options=options) if not mol.GetNumConformers(): rdDepictor.Compute2DCoords(mol) drawing.AddMol(mol, canvas=canv) ok = True except Exception: if self.verbose: import traceback traceback.print_exc() ok = False if ok: res[self.smiCol] = canv.drawing else: # FIX: maybe include smiles here in a Paragraph? res[self.smiCol] = 'Failed' return res
def MolToMPL(mol,size=(300,300),kekulize=True, wedgeBonds=True, imageType=None, fitImage=False, options=None, **kwargs): """ Generates a drawing of a molecule on a matplotlib canvas """ if not mol: raise ValueError('Null molecule provided') from rdkit.Chem.Draw.mplCanvas import Canvas canvas = Canvas(size) if options is None: options = DrawingOptions() options.bgColor=None if fitImage: drawingOptions.dotsPerAngstrom = int(min(size) / 10) options.wedgeDashedBonds=wedgeBonds drawer = MolDrawing(canvas=canvas, drawingOptions=options) omol=mol if kekulize: from rdkit import Chem mol = Chem.Mol(mol.ToBinary()) Chem.Kekulize(mol) if not mol.GetNumConformers(): from rdkit.Chem import AllChem AllChem.Compute2DCoords(mol) drawer.AddMol(mol,**kwargs) omol._atomPs=drawer.atomPs[mol] for k,v in iteritems(omol._atomPs): omol._atomPs[k]=canvas.rescalePt(v) canvas._figure.set_size_inches(float(size[0])/100,float(size[1])/100) return canvas._figure
def MolToQPixmap(mol, size=(300, 300), kekulize=True, wedgeBonds=True, fitImage=False, options=None, **kwargs): """ Generates a drawing of a molecule on a Qt QPixmap """ if not mol: raise ValueError('Null molecule provided') from rdkit.Chem.Draw.qtCanvas import Canvas canvas = Canvas(size) if options is None: options = DrawingOptions() options.bgColor = None if fitImage: options.dotsPerAngstrom = int(min(size) / 10) options.wedgeDashedBonds = wedgeBonds if kekulize: from rdkit import Chem mol = Chem.Mol(mol.ToBinary()) Chem.Kekulize(mol) if not mol.GetNumConformers(): from rdkit.Chem import AllChem AllChem.Compute2DCoords(mol) drawer = MolDrawing(canvas=canvas, drawingOptions=options) drawer.AddMol(mol, **kwargs) canvas.flush() return canvas.pixmap
def _legacyMolToFile(mol, fileName, size, kekulize, wedgeBonds, imageType, fitImage, options, **kwargs): """ Generates a drawing of a molecule and writes it to a file """ if options is None: options = DrawingOptions() useAGG, useCairo, Canvas = _getCanvas() if fitImage: options.dotsPerAngstrom = int(min(size) / 10) options.wedgeDashedBonds = wedgeBonds if useCairo or useAGG: canvas = Canvas(size=size, imageType=imageType, fileName=fileName) else: options.radicalSymbol = '.' # <- the sping canvas doesn't support unicode well canvas = Canvas(size=size, name=fileName, imageType=imageType) drawer = MolDrawing(canvas=canvas, drawingOptions=options) if kekulize: from rdkit import Chem mol = Chem.Mol(mol.ToBinary()) Chem.Kekulize(mol) if not mol.GetNumConformers(): from rdkit.Chem import AllChem AllChem.Compute2DCoords(mol) drawer.AddMol(mol, **kwargs) if useCairo or useAGG: canvas.flush() else: canvas.save()
def __call__(self,arg): res = list(arg) if self.verbose: sys.stderr.write('Render(%d): %s\n'%(self.smiCol,str(res[0]))) smi = res[self.smiCol] aspect = 1 width = self.width height = aspect*width try: mol = Chem.MolFromSmiles(smi) Chem.Kekulize(mol) canv = Canvas((width,height)) drawing = MolDrawing() drawing.atomLabelMinFontSize=3 drawing.minLabelPadding=(.5,.5) drawing.bondLineWidth=0.5 if not mol.GetNumConformers(): rdDepictor.Compute2DCoords(mol) drawing.AddMol(mol,canvas=canv) ok = True except: if self.verbose: import traceback traceback.print_exc() ok = False if ok: res[self.smiCol] = canv.drawing else: # FIX: maybe include smiles here in a Paragraph? res[self.smiCol] = 'Failed' return res
def __init__(self, parent=None, scene=None, size=(300, 300)): QtGui.QGraphicsView.__init__(self, scene, parent) scene = QtGui.QGraphicsScene(0, 0, size[0], size[1]) self.setRenderHints(QtGui.QPainter.Antialiasing | QtGui.QPainter.TextAntialiasing) self.setScene(scene) self._scenes = [scene] registerCanvas('sping') self.molDrawer = MolDrawing() self.molDrawer.atomLabelMinFontSize = 6 self.mols = []
def MolToFile(mol, fileName, size=(300, 300), kekulize=True, wedgeBonds=True, imageType=None, fitImage=False, options=None, **kwargs): """ Generates a drawing of a molecule and writes it to a file """ # original contribution from Uwe Hoffmann if not fileName: raise ValueError('no fileName provided') if not mol: raise ValueError('Null molecule provided') if imageType is None: imageType = os.path.splitext(fileName)[1][1:] if options is None: options = DrawingOptions() useAGG, useCairo, Canvas = _getCanvas() if fitImage: options.dotsPerAngstrom = int(min(size) / 10) options.wedgeDashedBonds = wedgeBonds if useCairo or useAGG: canvas = Canvas(size=size, imageType=imageType, fileName=fileName) else: options.radicalSymbol = '.' # <- the sping canvas doesn't support unicode well canvas = Canvas(size=size, name=fileName, imageType=imageType) drawer = MolDrawing(canvas=canvas, drawingOptions=options) if kekulize: from rdkit import Chem mol = Chem.Mol(mol.ToBinary()) Chem.Kekulize(mol) if not mol.GetNumConformers(): from rdkit.Chem import AllChem AllChem.Compute2DCoords(mol) drawer.AddMol(mol, **kwargs) if useCairo or useAGG: canvas.flush() else: canvas.save()
def __init__(self,parent=None,scene=None,size=(300,300)): QtGui.QGraphicsView.__init__(self,scene,parent) scene = QtGui.QGraphicsScene(0,0,size[0],size[1]) self.setRenderHints(QtGui.QPainter.Antialiasing|QtGui.QPainter.TextAntialiasing) self.setScene(scene) self._scenes=[scene] registerCanvas('sping') self.molDrawer=MolDrawing() self.molDrawer.atomLabelMinFontSize=6 self.mols=[]
def MolToJSON(mol, size=(300,300), kekulize=True, wedgeBonds=True, fitImage=False, options=None, **kwargs): if not mol: raise ValueError,'Null molecule provided' canvas = Canvas(size=size) if options is None: options = DrawingOptions() if fitImage: options.dotsPerAngstrom = int(min(size) / 10) options.wedgeDashedBonds = wedgeBonds try: drawer = MolDrawing(canvas=canvas,drawingOptions=options) except TypeError: drawer = MolDrawing(canvas=canvas) if kekulize: mol = Chem.Mol(mol.ToBinary()) Chem.Kekulize(mol) if not mol.GetNumConformers(): Compute2DCoords(mol) drawer.AddMol(mol,**kwargs) try: drawer.AddLegend(kwargs.get('legend', '')) except AttributeError: pass canvas.flush() return canvas.json #------------------------------------------------------------------------------
class MolCanvasView(QtGui.QGraphicsView): _mp = None selectingMols = True selectingAtoms = True atomSelectPadding = 5 def __init__(self, parent=None, scene=None, size=(300, 300)): QtGui.QGraphicsView.__init__(self, scene, parent) scene = QtGui.QGraphicsScene(0, 0, size[0], size[1]) self.setRenderHints(QtGui.QPainter.Antialiasing | QtGui.QPainter.TextAntialiasing) self.setScene(scene) self._scenes = [scene] registerCanvas('sping') self.molDrawer = MolDrawing() self.molDrawer.atomLabelMinFontSize = 6 self.mols = [] def clearMols(self): if self.mols: self.molDrawer.canvas.clear() self.scene().clear() self.mols = [] def addMol(self, mol): if not hasattr(self.molDrawer, 'canvas') or self.molDrawer.canvas is None: self.molDrawer.canvas = QtCanvas(self.scene()) confId = -1 if mol.HasProp('_2DConfId'): confId = int(mol.GetProp('_2DConfId')) self.molDrawer.AddMol(mol, confId=confId) mol._bbox = self.molDrawer.boundingBoxes[mol] mol._atomPs = self.molDrawer.atomPs[mol] self.mols.append(mol) def setMol(self, mol): self.clearMols() self.molDrawer.canvas = QtCanvas(self.scene()) self.addMol(mol) def setMols(self, mols): self.clearMols() nMols = len(mols) nCols = int(math.ceil(math.sqrt(nMols))) nRows = int(math.ceil(1. * nMols / nCols)) sz = self.size() self.scene().setSceneRect(0, 0, sz.width(), sz.height()) w = 0.9 * self.scene().width() / nCols h = 0.9 * self.scene().height() / nRows self.scene().clear() for i, mol in enumerate(mols): rowIdx = i // nCols colIdx = i % nCols self.molDrawer.canvas = QtCanvas(self.scene(), size=(w, h)) confId = -1 if mol.HasProp('_2DConfId'): confId = int(mol.GetProp('_2DConfId')) self.molDrawer.scaleAndCenter(mol, mol.GetConformer(confId), canvasSize=(w, h)) self.molDrawer.AddMol(mol, confId=confId, drawingTrans=(w * colIdx + w / 2, -h * rowIdx + h / 2), molTrans=self.molDrawer.molTrans, centerIt=False) mol._bbox = self.molDrawer.boundingBoxes[mol] mol._atomPs = self.molDrawer.atomPs[mol] self.mols.append(mol) def mousePressEvent(self, evt): if not self.selectingMols or not self.selectingAtoms: return self._mp = evt evt.accept() def mouseReleaseEvent(self, evt): if not self._mp: return else: mp = self._mp self._mp = None coords = self.mapToScene(mp.pos()) x, y = coords.x(), coords.y() for mol in self.mols: if x>mol._bbox[0] and x<mol._bbox[2] and \ y>mol._bbox[1] and y<mol._bbox[3] : if self.selectingAtoms: for atomIdx in range(mol.GetNumAtoms()): px, py = mol._atomPs[atomIdx] if x>px-self.atomSelectPadding and x<px+self.atomSelectPadding and\ y>py-self.atomSelectPadding and y<py+self.atomSelectPadding: self.emit( QtCore.SIGNAL( "atomSelected(PyQt_PyObject,int)"), mol, atomIdx) break if self.selectingMols: self.emit(QtCore.SIGNAL("molSelected(PyQt_PyObject)"), mol) break print(coords.x(), coords.y()) r = self.viewport().rect() img = QtGui.QImage(r.width(), r.height(), QtGui.QImage.Format_RGB32) img.fill(QtGui.QColor(255, 255, 255).rgb()) painter = QtGui.QPainter(img) painter.setRenderHints(QtGui.QPainter.Antialiasing | QtGui.QPainter.TextAntialiasing | QtGui.QPainter.SmoothPixmapTransform) self.render(painter) clip = QtGui.QApplication.clipboard() clip.setImage(img) painter = None img = None evt.accept()
def MolToImage(mol, size=(300, 300), kekulize=True, wedgeBonds=True, fitImage=False, options=None, canvas=None, **kwargs): """Returns a PIL image containing a drawing of the molecule ARGUMENTS: - kekulize: run kekulization routine on input `mol` (default True) - size: final image size, in pixel (default (300,300)) - wedgeBonds: draw wedge (stereo) bonds (default True) - highlightAtoms: list of atoms to highlight (default []) - highlightMap: dictionary of (atom, color) pairs (default None) - highlightBonds: list of bonds to highlight (default []) - highlightColor: RGB color as tuple (default [1, 0, 0]) NOTE: use 'matplotlib.colors.to_rgb()' to convert string and HTML color codes into the RGB tuple representation, eg. from matplotlib.colors import ColorConverter img = Draw.MolToImage(m, highlightAtoms=[1,2], highlightColor=ColorConverter().to_rgb('aqua')) img.save("molecule.png") RETURNS: a PIL Image object """ if not mol: raise ValueError('Null molecule provided') if canvas is None: img, canvas = _createCanvas(size) else: img = None options = options or DrawingOptions() if fitImage: options.dotsPerAngstrom = int(min(size) / 10) options.wedgeDashedBonds = wedgeBonds if 'highlightColor' in kwargs: color = kwargs.pop('highlightColor', (1, 0, 0)) options.selectColor = color drawer = MolDrawing(canvas=canvas, drawingOptions=options) if kekulize: from rdkit import Chem mol = Chem.Mol(mol.ToBinary()) Chem.Kekulize(mol) if not mol.GetNumConformers(): from rdkit.Chem import AllChem AllChem.Compute2DCoords(mol) if 'legend' in kwargs: legend = kwargs['legend'] del kwargs['legend'] else: legend = '' drawer.AddMol(mol, **kwargs) if legend: from rdkit.Chem.Draw.MolDrawing import Font bbox = drawer.boundingBoxes[mol] pos = size[0] / 2, int(.94 * size[1]), 0 # the 0.94 is extremely empirical # canvas.addCanvasPolygon(((bbox[0],bbox[1]),(bbox[2],bbox[1]),(bbox[2],bbox[3]),(bbox[0],bbox[3])), # color=(1,0,0),fill=False,stroke=True) # canvas.addCanvasPolygon(((0,0),(0,size[1]),(size[0],size[1]),(size[0],0) ), # color=(0,0,1),fill=False,stroke=True) font = Font(face='sans', size=12) canvas.addCanvasText(legend, pos, font) if kwargs.get('returnCanvas', False): return img, canvas, drawer else: canvas.flush() return img
class MolCanvasView(QtGui.QGraphicsView): _mp=None selectingMols=True selectingAtoms=True atomSelectPadding=5 def __init__(self,parent=None,scene=None,size=(300,300)): QtGui.QGraphicsView.__init__(self,scene,parent) scene = QtGui.QGraphicsScene(0,0,size[0],size[1]) self.setRenderHints(QtGui.QPainter.Antialiasing|QtGui.QPainter.TextAntialiasing) self.setScene(scene) self._scenes=[scene] registerCanvas('sping') self.molDrawer=MolDrawing() self.molDrawer.atomLabelMinFontSize=6 self.mols=[] def clearMols(self): if self.mols: self.molDrawer.canvas.clear() self.scene().clear() self.mols=[] def addMol(self,mol): if not hasattr(self.molDrawer,'canvas') or self.molDrawer.canvas is None: self.molDrawer.canvas=QtCanvas(self.scene()) confId=-1 if mol.HasProp('_2DConfId'): confId=int(mol.GetProp('_2DConfId')) self.molDrawer.AddMol(mol,confId=confId) mol._bbox=self.molDrawer.boundingBoxes[mol] mol._atomPs=self.molDrawer.atomPs[mol] self.mols.append(mol) def setMol(self,mol): self.clearMols() self.molDrawer.canvas=QtCanvas(self.scene()) self.addMol(mol) def setMols(self,mols): self.clearMols() nMols = len(mols) nCols = int(math.ceil(math.sqrt(nMols))) nRows = int(math.ceil(1.*nMols/nCols)) sz = self.size() self.scene().setSceneRect(0,0,sz.width(),sz.height()) w = 0.9*self.scene().width()/nCols h = 0.9*self.scene().height()/nRows self.scene().clear() for i,mol in enumerate(mols): rowIdx=i//nCols colIdx=i%nCols self.molDrawer.canvas=QtCanvas(self.scene(),size=(w,h)) confId=-1 if mol.HasProp('_2DConfId'): confId=int(mol.GetProp('_2DConfId')) self.molDrawer.scaleAndCenter(mol,mol.GetConformer(confId),canvasSize=(w,h)) self.molDrawer.AddMol(mol,confId=confId, drawingTrans=(w*colIdx+w/2,-h*rowIdx+h/2), molTrans=self.molDrawer.molTrans, centerIt=False) mol._bbox=self.molDrawer.boundingBoxes[mol] mol._atomPs=self.molDrawer.atomPs[mol] self.mols.append(mol) def mousePressEvent(self,evt): if not self.selectingMols or not self.selectingAtoms: return self._mp=evt evt.accept() def mouseReleaseEvent(self,evt): if not self._mp: return else: mp = self._mp self._mp=None coords = self.mapToScene(mp.pos()) x,y = coords.x(),coords.y() for mol in self.mols: if x>mol._bbox[0] and x<mol._bbox[2] and \ y>mol._bbox[1] and y<mol._bbox[3] : if self.selectingAtoms: for atomIdx in range(mol.GetNumAtoms()): px,py = mol._atomPs[atomIdx] if x>px-self.atomSelectPadding and x<px+self.atomSelectPadding and\ y>py-self.atomSelectPadding and y<py+self.atomSelectPadding: self.emit(QtCore.SIGNAL("atomSelected(PyQt_PyObject,int)"),mol,atomIdx) break if self.selectingMols: self.emit(QtCore.SIGNAL("molSelected(PyQt_PyObject)"),mol) break print coords.x(),coords.y() r=self.viewport().rect() img = QtGui.QImage(r.width(),r.height(),QtGui.QImage.Format_RGB32) img.fill(QtGui.QColor(255,255,255).rgb()) painter = QtGui.QPainter(img) painter.setRenderHints(QtGui.QPainter.Antialiasing|QtGui.QPainter.TextAntialiasing|QtGui.QPainter.SmoothPixmapTransform) self.render(painter) clip=QtGui.QApplication.clipboard() clip.setImage(img) painter = None img=None evt.accept()