Вопрос или проблема
Инструмент cheminformatics RDKit включает в себя RDKit Cookbook с примером кода для различных приложений. Одним из них является выделение различий между 2 молекулами, здесь с использованием fMCS для отображения сходств, а затем для маркировки тех остатков, которые не являются общими. Этот пример работает хорошо, код здесь
Мне нужно изменить цвет выделения, но у меня не получается. Основываясь на коде по ссылке выше, я пробовал следующее:
from rdkit import Chem
from rdkit.Chem import Draw
from rdkit.Chem.Draw import rdMolDraw2D
from rdkit.Chem.Draw import IPythonConsole
from rdkit.Chem import rdFMCS
from rdkit.Chem.Draw import rdDepictor
rdDepictor.SetPreferCoordGen(True)
IPythonConsole.drawOptions.minFontSize=20
IPythonConsole.drawOptions.setHighlightColour=(0,1,0)
from collections import defaultdict
Это не дало никакого эффекта, изображение было нарисовано с выделением по умолчанию.
d2g = Draw.MolsToGridImage([mol1, mol2])
opts = d2g.drawOptions()
opts.setHighlightColour = (0,1,0)
d2g([mol1, mol2],highlightAtomLists=[target_atm1, target_atm2])
Это выдает ошибку
AttributeError: ‘Image’ object has no attribute ‘drawOptions’
Затем я смог заставить это работать с помощью этого кода:
from rdkit import Chem
from rdkit.Chem import Draw
from rdkit.Chem.Draw import rdMolDraw2D
from rdkit.Chem.Draw import IPythonConsole
from rdkit.Chem import rdFMCS
from rdkit.Chem.Draw import rdDepictor
rdDepictor.SetPreferCoordGen(True)
IPythonConsole.drawOptions.minFontSize=20
from collections import defaultdict
mol1 = Chem.MolFromSmiles('FC1=CC=C2C(=C1)C=NN2')
mol2 = Chem.MolFromSmiles('CCC1=C2NN=CC2=CC(Cl)=C1')
from PIL import Image
from io import BytesIO
def show_mol(d2d,mol,legend='',highlightAtoms=[]):
d2d.DrawMolecule(mol,legend=legend, highlightAtoms=highlightAtoms)
d2d.FinishDrawing()
bio = BytesIO(d2d.GetDrawingText())
return Image.open(bio)
def show_images(imgs,buffer=5):
height = 0
width = 0
for img in imgs:
height = max(height,img.height)
width += img.width
width += buffer*(len(imgs)-1)
res = Image.new("RGBA",(width,height))
x = 0
for img in imgs:
res.paste(img,(x,0))
x += img.width + buffer
return res
mcs = rdFMCS.FindMCS([mol1,mol2])
mcs_mol = Chem.MolFromSmarts(mcs.smartsString)
match1 = mol1.GetSubstructMatch(mcs_mol)
target_atm1 = []
for atom in mol1.GetAtoms():
if atom.GetIdx() not in match1:
target_atm1.append(atom.GetIdx())
match2 = mol2.GetSubstructMatch(mcs_mol)
target_atm2 = []
for atom in mol2.GetAtoms():
if atom.GetIdx() not in match2:
target_atm2.append(atom.GetIdx())
img1 = []
d2dx = Draw.MolDraw2DCairo(350,300)
doptsx = d2dx.drawOptions()
doptsx.setHighlightColour((1,0.84,0,.5))
img1.append(show_mol(d2dx,mol1,highlightAtoms=target_atm1))
d2dx = Draw.MolDraw2DCairo(350,300)
doptsx = d2dx.drawOptions()
doptsx.setHighlightColour((1,0.84,0,.5))
img1.append(show_mol(d2dx,mol2, highlightAtoms=target_atm2))
pic = show_images(img1)
pic.save('hallo.png')
pic
Проблемы заключаются в том, что 1) мне нужен выход в формате svg и, 2) если молекулы имеют разные размеры или используется другая конфигурация SMILE, только MolsToGrid размещает их правильно рядом в пределах одних и тех же границ подпанели. Так что мне нужно использовать MolsToGrid для качественных изображений для научных публикаций.
Я новичок в python, использую jupyter lab на ПК с Windows 11.
Python 3.8.18 (по умолчанию, 11 сен 2023, 13:39:12) [MSC v.1916 64 бита
(AMD64)] :: Anaconda, Inc. на win32
Я буду очень признателен за любую помощь в этом вопросе. Спасибо заранее! 🙂
Ответ или решение
Для изменения цвета выделения при использовании функции MolsToGridImage
из библиотеки RDKit в Python, можно параметризовать цвета прежде, чем передать молекулы для рисования. Ваша проблема заключается в попытке изменить параметр цвета после создания объекта изображения, что вызывает ошибку.
Приведу пример кода, который будет изменять цвет выделения и использовать MolsToGridImage
для генерации изображения в формате SVG.
from rdkit import Chem
from rdkit.Chem import Draw
from rdkit.Chem import rdFMCS
# Задайте SMILES для двух молекул
mol1 = Chem.MolFromSmiles('FC1=CC=C2C(=C1)C=NN2')
mol2 = Chem.MolFromSmiles('CCC1=C2NN=CC2=CC(Cl)=C1')
# Определите максимальную общую подструктуру
mcs = rdFMCS.FindMCS([mol1, mol2])
mcs_mol = Chem.MolFromSmarts(mcs.smartsString)
# Находим несоответствующие атомы для выделения
match1 = mol1.GetSubstructMatch(mcs_mol)
target_atm1 = [atom.GetIdx() for atom in mol1.GetAtoms() if atom.GetIdx() not in match1]
match2 = mol2.GetSubstructMatch(mcs_mol)
target_atm2 = [atom.GetIdx() for atom in mol2.GetAtoms() if atom.GetIdx() not in match2]
# Используем MolsToGridImage для отображения
highlight_colors = [(1, 0.84, 0, 0.5)] # Цвет выделения в формате RGBA (жёлтый полупрозрачный)
# Генерация изображения в формате SVG с выделением
d2g = Draw.MolsToGridImage(
[mol1, mol2],
highlightAtomLists=[target_atm1, target_atm2],
highlightColour=highlight_colors,
legends=["Молекула 1", "Молекула 2"]) # Подписи для каждой молекулы
# Сохранение изображения в формате SVG
d2g.save("highlighted_molecules.svg")
Объяснение кода:
-
Импорт необходимых модулей: Мы импортируем все необходимые модули из RDKit.
-
Задание молекул: Используем SMILES для создания двух молекул.
-
Определение максимальной общей подструктуры (MCS): Используем
rdFMCS.FindMCS
для нахождения общей подструктуры обеих молекул и ищем атомы, которые нужно выделить. -
Использование
MolsToGridImage
: Создаём изображение с выделением ненайденных атомов и задаём желаемый цвет выделения. -
Сохранение в формате SVG: В конце мы сохраняем изображение в формате SVG, что важно для публикаций и отчётов.
Теперь ваше изображение будет включать выделенные атомы с заданным цветом, и оно будет сохранено в формате SVG. Не забывайте, что для установки RDKit необходимо создать подходящую среду, так как он не может быть установлен с использованием стандартного pip.