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 _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 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 show(smi, save_dir): opts = DrawingOptions() opts.includeAtomNumbers = True acceptor = Chem.MolFromSmiles(smi) img = Draw.MolToImage(acceptor, options=opts) save_path = os.path.join(save_dir, smi + '.jpg') img.save(save_path)
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 GenerateImageFile(ValidMols, MolNames, AtomLists, BondLists): """Generate a non SVG image file.""" Outfile = OptionsInfo["Outfile"] NumOfMolsPerRow = OptionsInfo["NumOfMolsPerRow"] Width = OptionsInfo["MolImageWidth"] Height = OptionsInfo["MolImageHeight"] # Setup drawing options... UpdatedDrawingOptions = DrawingOptions() UpdatedDrawingOptions.atomLabelFontSize = int( OptionsInfo["AtomLabelFontSize"]) UpdatedDrawingOptions.bondLineWidth = float(OptionsInfo["BondLineWidth"]) MolsImage = Draw.MolsToGridImage(ValidMols, molsPerRow=NumOfMolsPerRow, subImgSize=(Width, Height), legends=MolNames, highlightAtomLists=AtomLists, highlightBondLists=BondLists, useSVG=False, kekulize=OptionsInfo["Kekulize"], options=UpdatedDrawingOptions) MiscUtil.PrintInfo("\nGenerating image file %s..." % Outfile) if MiscUtil.CheckFileExt(Outfile, "pdf"): if MolsImage.mode == 'RGBA': MolsImage = MolsImage.convert('RGB') MolsImage.save(Outfile)
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 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 #------------------------------------------------------------------------------
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 Keyword 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 []) """ if not mol: raise ValueError('Null molecule provided') if canvas is None: img,canvas=_createCanvas(size) else: img=None if options is None: options = DrawingOptions() if fitImage: options.dotsPerAngstrom = int(min(size) / 10) options.wedgeDashedBonds = wedgeBonds 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
def _mols2imageStream(mols, f, format, size, legend, highlightMatch=None): """Return an input stream for the molecule as drawn""" highlights = None if highlightMatch: pattern = MolFromSmarts(highlightMatch) highlights = [mol.GetSubstructMatch(pattern) for mol in mols] kek = True if mols[0].HasProp("_drawingBondsWedged"): kek=False fit = False options = DrawingOptions() subim = (size,size) if size >150: subim = (size *2,size *2) options.coordScale = 3 options.bondLineWidth = 3.6 options.dblBondOffset = 0.435 options.atomLabelFontSize = 60 if kek: options.bondLineWidth = 4.5 options.dblBondOffset = 0.6 options.atomLabelFontSize = 150 fit = True elif kek: options.dblBondOffset = 0.4 image = Draw.MolsToGridImage(mols,molsPerRow=min(len(mols),4),subImgSize=subim, kekulize=kek,highlightAtomLists=highlights, fitImage=fit, options=options ) image.save(f, format)
def generate_png(mol, pngpath, logfile=devnull, size=300): with stdout_redirected(to=sys.stdout, stdout=sys.stderr): with stdout_redirected(to=logfile, stdout=sys.stdout): nhmol = RemoveHs(mol, implicitOnly=False, updateExplicitCount=True, sanitize=False) SanitizeMol(nhmol, catchErrors=True) op = DrawingOptions() op.atomLabelFontSize = size / 25 MolToFile(PrepareMolForDrawing(nhmol,forceCoords=True,addChiralHs=True),\ pngpath,fitImage=True,size=(size, size),options=op)
def draw_mol(mol_file, save_mol_path): opts = DrawingOptions() opts.includeAtomNumbers = True opts.includeAtomNumbers = True opts.bondLineWidth = 2.8 Draw.MolToFile( mol_file, # mol对象 save_mol_path, # 图片存储地址 size=(4000, 2000), kekulize=True, wedgeBonds=True, imageType=None, fitImage=False, options=opts, )
def draw_mol_to_svg(mol, filename): """ Draw a single molecule to an SVG file with transparent BG. """ # change BG to transperent # (https://sourceforge.net/p/rdkit/mailman/message/31637105/) o = DrawingOptions() o.bgColor = None # Use copy of molecule to avoid changing instance of mol. new_mol = rdkit.MolFromMolBlock(rdkit.MolToMolBlock(mol)) rdkit.Compute2DCoords(new_mol) Draw.MolToFile(new_mol, filename, fitImage=True, imageType='svg', options=o)
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 draw_smiles_to_svg(smiles, filename): """ Draw a single molecule to an SVG file with transparent BG. """ mol = Chem.MolFromSmiles(smiles) # change BG to transperent # (https://sourceforge.net/p/rdkit/mailman/message/31637105/) o = DrawingOptions() o.bgColor = None Chem.Compute2DCoords(mol) Draw.MolToFile( mol, filename, fitImage=True, imageType='svg', options=o )
def convert_smis(dir): opts = DrawingOptions() opts.includeAtomNumbers = True for file in os.listdir(dir): file_path = os.path.join(dir, file) if os.path.isdir(file_path): convert_smis(file_path) else: if file.endswith('smi'): with open(file_path) as f: line = f.read() smi = line.split('\t')[0] m = Chem.MolFromSmiles(smi) try: img = Draw.MolToImage(m, options=opts) save_path = file_path + '.png' img.save(save_path) except ValueError: print('Null molecule provided: ' + file)
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: # <- the sping canvas doesn't support unicode well options.radicalSymbol = '.' 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 _mols2imageStream(mols, f, format, size, legend, highlightMatch=None): """Return an input stream for the molecule as drawn""" highlights = None if highlightMatch: pattern = MolFromSmarts(highlightMatch) highlights = [mol.GetSubstructMatch(pattern) for mol in mols] kek = True if mols[0].HasProp("_drawingBondsWedged"): kek = False fit = False options = DrawingOptions() subim = (size, size) if size > 150: subim = (size * 2, size * 2) options.coordScale = 3 options.bondLineWidth = 3.6 options.dblBondOffset = 0.435 options.atomLabelFontSize = 60 if kek: options.bondLineWidth = 4.5 options.dblBondOffset = 0.6 options.atomLabelFontSize = 150 fit = True elif kek: options.dblBondOffset = 0.4 image = Draw.MolsToGridImage(mols, molsPerRow=min(len(mols), 4), subImgSize=subim, kekulize=kek, highlightAtomLists=highlights, fitImage=fit, options=options) image.save(f, format)
def concat_donor_donor_acceptor(acceptor_donor_smi, donors_smi, save_dir, count): m = Chem.MolFromSmiles(acceptor_donor_smi) opts = DrawingOptions() opts.includeAtomNumbers = True #print("m1 Smiles:", Chem.MolToSmiles(m)) #Draw.MolToImage(m, options=opts).show() m = Chem.AddHs(m) acceptor_smi_h = Chem.MolToSmiles(m) #print("m2 Smiles:", acceptor_smi_h) #Draw.MolToImage(m, options=opts).show() patt = Chem.MolFromSmarts('[H]') repsmis = donors_smi mols = [] mols.append(m) for r in repsmis: rep = Chem.MolFromSmarts(r) res = AllChem.ReplaceSubstructs(m, patt, rep) mols.extend(res) smis = [Chem.MolToSmiles(mol) for mol in mols] smis = list(set(smis)) smis.remove(acceptor_smi_h) mols = [Chem.MolFromSmiles(smi) for smi in smis] count = count + len(mols) if not os.path.exists(save_dir): os.mkdir(save_dir) # for i in range(len(mols)): # img = Draw.MolToImage(mols[i], options=opts) # save_path = os.path.join(save_dir, acceptor_donor_smi + '_' + str(i) + '.jpg') # # # save combined TADF # img.save(save_path) return count
def gen_plot(QCA, fnm): try: d = np.loadtxt(fnm, usecols=(5, 2, 6), skiprows=3) if d.size == 0: return except StopIteration: print("No data for", fnm) return entry = np.genfromtxt(fnm, usecols=(0, ), skip_header=HEADER_LEN, dtype=np.dtype("str"))[0] smiles = np.genfromtxt(fnm, usecols=(7, ), skip_header=HEADER_LEN, dtype=np.dtype("str"), comments=None)[0] scanned = np.genfromtxt(fnm, usecols=(4, ), skip_header=HEADER_LEN, dtype=np.dtype("str"))[0] scanned = eval('[' + scanned.replace('-', ',') + ']') scanned = [x + 1 for x in scanned] #print(scanned) print(fnm, smiles) mol_id = np.genfromtxt(fnm, usecols=(1, ), skip_header=HEADER_LEN, dtype=np.dtype("str")) with open(fnm, 'r') as fd: ds_name = fd.readline().strip("\n") method = fd.readline().strip("\n") basis = fd.readline().strip("\n") scan = d[:, 0] qm_abs_min = d[:, 1].min() qmene = d[:, 1] * const.hartree2kcalmol qmene -= qmene.min() mmene = d[:, 2] mmene -= mmene.min() mm_min_pt = scan[np.argsort(mmene)[0]] qm_min_pt = scan[np.argsort(qmene)[0]] qcmol = QCA.db.get(mol_id[0]).get("data") try: mol = rdutil.mol.build_from_smiles(smiles) molnoindex = rdutil.mol.build_from_smiles( re.sub(":[1-9][0-9]*", "", smiles)) except Exception as e: print(e) return AllChem.ComputeGasteigerCharges(mol) totalcharge = 0.0 for i, atom in enumerate(mol.GetAtoms()): totalcharge += float(atom.GetProp('_GasteigerCharge')) atom_map = rdutil.mol.atom_map(mol) inv = {val: key for key, val in atom_map.items()} #print(atom_map) scanned = [inv[i] for i in scanned] #scanned = [rdutil.mol.atom_map_invert( atom_map)[i] for i in scanned] #print(scanned) molflat = rdutil.mol.build_from_smiles(smiles) try: ret = rdutil.mol.embed_qcmol_3d(mol, qcmol) #print("EMBED WAS RET:", ret) #AllChem.GenerateDepictionMatching3DStructure(molflat, mol) AllChem.Compute2DCoords(molnoindex) except Exception as e: print("Could not generate conformation:") print(e) return options = DrawingOptions() options.atomLabelFontSize = 110 options.atomLabelFontFace = "sans" options.dotsPerAngstrom = 400 options.bondLineWidth = 8 options.coordScale = 1 png = Draw.MolToImage(molnoindex, highlightAtoms=scanned, highlightColor=[0, .8, 0], size=(500 * 12, 500 * 4), fitImage=True, options=options) fig = plt.figure(figsize=(8, 3.5), dpi=300, constrained_layout=True) matplotlib.rc("font", **{"size": 10}) gs = GridSpec(2, 2, figure=fig) ax1 = fig.add_subplot(gs[:2, 0]) ax1.plot(scan, qmene, 'bo-', lw=1, ms=2, label="QM") ax1.plot(scan, mmene, 'ro-', lw=1, ms=2, label="MM") ax1.set_ylabel("Energy (kcal/mol)") ax1.set_xlabel("Scan value") ax1.spines['top'].set_visible(False) ax1.spines['right'].set_visible(False) ax1.legend(loc='best') ax2 = fig.add_subplot(gs[0, 1]) ax2.imshow(png) ax2.axis('off') ax3 = fig.add_subplot(gs[1, 1]) kwargs = {"fontsize": 8, "fontname": "Monospace"} #ax3.text(.5,1.1,"{:^60s}".format(re.sub(":[1-9][0-9]*","",smiles)), fontsize=4, fontname="Monospace", ha='center') ax3.text(0, .9, "{:<16s}{:>39s}".format("QCA Dataset:", ds_name), **kwargs) ax3.text(0, .8, "{:<16s}{:>39s}".format("QCA Entry:", entry.split("-")[1]), **kwargs) ax3.text(0, .7, "{:<16s}{:>39s}".format("MM spec:", "Parsley unconstrained"), **kwargs) ax3.text(0, .6, "{:<16s}{:>39s}".format("MM charges:", "ANTECHAMBER AM1-BCC"), **kwargs) ax3.text( 0, .5, "{:<16s}{:>39s}".format("Total charge", "{:6.2f}".format(totalcharge)), **kwargs) ax3.text( 0, .4, "{:<16s}{:>39s}".format("QM spec:", "{}/{}".format(method, basis)), **kwargs) ax3.text( 0, .3, "{:<16s}{:>39s}".format("QM Absolute min:", "{:16.13e} au".format(qm_abs_min)), **kwargs) ax3.text( 0, .2, "{:<16s}{:>39s}".format("QM Min point:", "{:8.2f}".format(qm_min_pt)), **kwargs) ax3.text( 0, .1, "{:<16s}{:>39s}".format("MM Min point:", "{:8.2f}".format(mm_min_pt)), **kwargs) ax3.text(0, .0, "{:<16s}{:>39s}".format("OFFSB ver", "1.0"), **kwargs) ax3.axis('off') fig.savefig(re.sub("\.*$", ".png", fnm)) fig = None plt.close("all") return
def MolToImage(mol, size=(300, 300), kekulize=True, wedgeBonds=True, fitImage=False, options=None, canvas=None, background='white', values=None, index=None, canvas_creater=MycreateCanvas, mol_adder=MyAddMol, **kwargs): """ returns a PIL image containing a drawing of the molecule Keyword 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 []) background: can be given as a string (default = 'white') or as a color code: (250,0,0,0) """ if not mol: raise ValueError('Null molecule provided') if canvas is None: img, canvas = canvas_creater(size, color='white') else: img = None if options is None: options = DrawingOptions() if fitImage: options.dotsPerAngstrom = int(min(size) / 10) options.wedgeDashedBonds = wedgeBonds drawer = MolDrawing(canvas=canvas, drawingOptions=options) if kekulize: from rdkit import Chem mol = Chem.Mol(mol.ToBinary()) Chem.Kekulize(mol) # noinspection PyArgumentList if not mol.GetNumConformers(): from rdkit.Chem import AllChem AllChem.Compute2DCoords(mol) if 'legend' in kwargs: legend = kwargs['legend'] del kwargs['legend'] else: legend = '' if 'symbol' in kwargs: symbol = kwargs['symbol'] del kwargs['symbol'] else: symbol = '' # Add a colored border if not background == 'white': position = [(0, 0), (size[0], 0), (size[0], size[1]), (0, size[1])] canvas.addCanvasPolygon(position, fill=True, color=background) position = [(5, 5), (size[0] - 5, 5), (size[0] - 5, size[1] - 5), (5, size[1] - 5)] canvas.addCanvasPolygon(position, fill=True, color=(250, 250, 250)) mol_adder(drawer, mol, **kwargs) if legend: # noinspection PyUnusedLocal 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 symbol: # Let's put it (them) in the top left corner of the canas pos = size[0] / 10, size[1] / 10, 0 font = Font(face='sans', size=12) canvas.addCanvasText(symbol, pos, font) if kwargs.get('returnCanvas', False): return img, canvas, drawer else: canvas.flush() return img
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
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 if options is None: options = 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
def generate_fragemnts(self): # Clear class level list del self.molecule[:] # Get text input from LineEdit widget self.smile = str(self.NTPS_smiles_entry.text()) # Append cStructure mol to class level list self.molecule.append( cStructure('precursor', self.smile, 'precursor.png')) # SMARTS string for bond disconnection self.patt = Chem.MolFromSmarts( '[!$([NH]!@C(=O))&!D1&!$(*#*)]-&!@[!$([NH]!@C(=O))&!D1&!$(*#*)]') # Init parent mol object self.mol = Chem.MolFromSmiles(self.smile) # find the rotatable bonds self.bonds = self.mol.GetSubstructMatches(self.patt) # create an editable molecule, break the bonds, and add dummies: self.all_smis = [self.smile] # disconnect rotatable bonds for a, b in self.bonds: self.em = Chem.EditableMol(self.mol) self.nAts = self.mol.GetNumAtoms() self.em.RemoveBond(a, b) self.em.AddAtom(Chem.Atom(0)) self.em.AddBond(a, self.nAts, Chem.BondType.SINGLE) self.em.AddAtom(Chem.Atom(0)) self.em.AddBond(b, self.nAts + 1, Chem.BondType.SINGLE) self.nAts += 2 self.p = self.em.GetMol() Chem.SanitizeMol(self.p) self.smis = [ Chem.MolToSmiles(x, True) for x in Chem.GetMolFrags(self.p, asMols=True) ] for self.smi in self.smis: self.all_smis.append(self.smi) # draw molecules and save png images for display in structure viewer widget # --> there's probably a better way to do this... self.draw = 0 for i, self.smi in enumerate(self.all_smis): if i == 0: struct_type = 'precursor' img_path = 'precursor.png' else: struct_type, img_path = 'fragment', 'fragment_%s.png' % self.draw self.molecule.append(cStructure(struct_type, self.smi, img_path)) self.template = Chem.MolFromSmiles(self.smi) drawOptions = DrawingOptions() drawOptions.bgColor = (0, 0, 0) Draw.MolToFile(self.template, img_path, options=drawOptions) # append to class level list self.structures.append(img_path) # append to GUI fragments listbox - file name only self.NTPS_frag_list.addItem( QtGui.QListWidgetItem( img_path.split('/')[-1].strip().split('.')[0])) self.draw += 1 self.autocomplete_mod_properties() # add image of first structure to graphicsview scene = QtGui.QGraphicsScene() scene.addPixmap(QtGui.QPixmap(self.structures[0])) self.NTPS_structure_view.setScene(scene) self.NTPS_structure_view.show() return
from rdkit import Chem from rdkit.Chem import Draw from rdkit.Chem import AllChem from rdkit.Chem.Draw.MolDrawing import MolDrawing, DrawingOptions # Only needed if modifying defaults from itertools import permutations import math opts = DrawingOptions() opts.includeAtomNumbers = True opts.bondLineWidth = 2.8 def maximum_curvature(smi): mols = [] m = Chem.MolFromSmiles(smi) # Draw.MolToImage(m, options=opts).save('m3d.png') # Draw.MolToImage(m).save('m3d1.png') mols.append(m) m3d = Chem.AddHs(m) AllChem.EmbedMolecule(m3d, randomSeed=1) # Draw.MolToImage(m3d, size=(250, 250)).show() m3d_without_h = Chem.RemoveHs(m3d) mols.append(m3d_without_h) bonds = m3d.GetBonds() single_bonds_id = [] # find all single bonds without 'H' as end atom for bond in bonds: bond_type = bond.GetBondType() # print(bond_type) begin_atom = bond.GetBeginAtom()
# from rdkit.Chem.Draw import IPythonConsole from rdkit.Chem.Draw.MolDrawing import MolDrawing, DrawingOptions # 二、芳香性 芳香性是一个简单又复杂的话题。无论是实验化学家还是理论化学家都无法给出一个明确的定义 rdkit除了通过模式匹配已知的芳香体系进行识别 , 还定义了一些识别方向体系的规则 。 这些具体规则如下 : 1.芳香性仅仅和环上的原子和键有关 。 2.芳香性键必须由2两个芳香性原子组成 。 3.由2个芳香性原子组成的键不一定就是芳香键。 m = Chem.MolFromSmiles('C1=CC2=C(C=C1)C1=CC=CC=C21') opts = DrawingOptions() opts.atomLabelFontSize = 400 opts.includeAtomNumbers = True opts.dblBondLengthFrac = 0.8 opts.includeAtomNumbers = True opts.dotsPerAngstrom = 1000 img = Draw.MolToImage(m, options=opts, size=(500, 500)) img.save( '/drug_development/studyRdkit/st_rdcit/img/mol41.jpg' ) # 基于RDKit方向模型判断其上的原子和键的芳香性 atom3 = m.GetAtomWithIdx(3).GetIsAromatic() atom6 = m.GetAtomWithIdx(6).GetIsAromatic() bond_36 = m.GetBondBetweenAtoms(3, 6).GetIsAromatic()