from rdkit import Chem
import pubchempy as pcp
from rdkit.Chem import AllChem
from rdkit import RDConfig
from rdkit.Chem.Draw import IPythonConsole
from rdkit.Chem import Draw
import numpy as np
from IPython.display import display,Image, SVG
Часть 1 - Найти формулу ибупрофена и предложить способ изменения его SMILES для эмуляции продукта Click Chemistry
Посмотрим как выглядит ибупрофен
ibu=Chem.MolFromSmiles('CC(C)CC1=CC=C(C=C1)C(C)C(=O)O')
AllChem.Compute2DCoords(ibu)
display(ibu)
Если мы хотим присоединить к нему азиды с помощью клик химии, то самый простой и понятный способ это сделать - добавить к ибупрофену алкильную группу https://en.wikipedia.org/wiki/Click_chemistry#Copper(I)-catalyzed_azide-alkyne_cycloaddition_(CuAAC) Такая реакция циклоприсоединения азидов к алкинам, катализируемая ионами меди по другому называется CuAAC (изображена ниже)
Забавно что аналоги ибупрофена интересны мировой науке не только как новые NSAID (https://www.future-science.com/doi/abs/10.4155/fmc-2018-0467?journalCode=fmc) но и как новые антибиотики (https://www.sciencedirect.com/science/article/abs/pii/S0960894X16310083)
display(Image("https://upload.wikimedia.org/wikipedia/commons/c/c0/CuAAC_Catalytic_Cycle.png",width=700,height=700))
Я предложу немного запутанный вариант получения терминального алкина из ибупрофена
1) Получаем ацилхлорид вот таким лабораторным способом
display(SVG(url="https://upload.wikimedia.org/wikipedia/commons/7/76/Formation_of_acyl_chloride.svg"))
Как же вылядит на этой стадии модифицированный ибупрофен
ibu1=Chem.MolFromSmiles('CC(C)CC1=CC=C(C=C1)C(C)C(=O)Cl')
AllChem.Compute2DCoords(ibu1)
display(ibu1)
2)
Получаем альдегид из ацилхлорида при помощи восстановления по Розенмунду
display(Image("https://upload.wikimedia.org/wikipedia/commons/e/e1/Rosenmund_Reduction_Scheme.png"))
Как выглядит теперь модифицированный ибупрофен?
ibu2=Chem.MolFromSmiles('CC(C)CC1=CC=C(C=C1)C(C)C=O')
AllChem.Compute2DCoords(ibu2)
display(ibu2)
3)
Получаем терминальный алкин из альдегида при помощи реакции Кори-Фукса
https://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%BA%D0%B8%D0%BD%D1%8B#cite_note-17
display(Image("https://upload.wikimedia.org/wikipedia/commons/b/b7/Corefuchs.png"))
display(Image("https://upload.wikimedia.org/wikipedia/commons/5/5d/Corey-Fuchs_carbene.png"))
Изобразим превращения ибупрофена после первой и второй стадии реакции Кори-Фукса
ibu3=Chem.MolFromSmiles('CC(C)CC1=CC=C(C=C1)C(C)C=C(Br)Br')
AllChem.Compute2DCoords(ibu3)
display(ibu3)
ibu4=Chem.MolFromSmiles('CC(C)CC1=CC=C(C=C1)C(C)C#C')
AllChem.Compute2DCoords(ibu4)
display(ibu4)
Вот то что изображено выше это и есть конечный вариант модифицированного ибупрофена к корому мы будем присоединять найденные азиды из PubChem
Как же выглядит сама реакция циклоприсоединения азидов к алкинам?
Изобразим продукт реакции азида и модифицированного азидобензена(ниже)
Изобразим продукт реакции азида и модифицированного ибупрофена на примере азидобензена(ниже)
protoazid=Chem.MolFromSmiles('[N-]=[N+]=[N]C1=CC=CC=C1')
AllChem.Compute2DCoords(protoazid)
display(protoazid)
ibumod=Chem.MolFromSmiles('C1=CC=CC=C1N2N=NC(C(C)C3=CC(C(C)C)=CC=C3)=C2')
AllChem.Compute2DCoords(ibumod)
display(ibumod)
Правда таким образом из ибупрофена исчезла карбоксильная группа, которая, конечно, важная функциональная часть молекулы и тем не менее часто при модификациях карбоксильная руппа пропадает
Часть 2 на сайте PubChem найти все радикалы c азидом для Click Chemistry и скачать их SMILES нотации или используйте pubchempy
Найти все радикалы с азидом Я придумала три способа записать азид, учитывая их мезомерию, некоторые из способов при поиске вручную в PubChem явно дают похожие результаты так что хорошо бы убрать одинаковые резултаты поиска. Правда pubchempy - вредный и не хочет обрабатывать любые мои запросы, но вроде бы три нижеперечисленные получились довольно адекватными и принимаются pubchempy
[N-;D1;H0;!R]=[N+;D2;H0;!R]=[N]
[N-;H0;D1;!R]=[N][N-] (вообще конечно максимально странный мезомер тут два '-' заряда но теоретически возможно и при ручном поиске дает что то адекватное)
[N;D1;!R;H0]#[N+][N-]
azides=["[N-;D1;H0;!R]=[N+;D2;H0;!R]=[N]","[N-;H0;D1;!R]=[N][N-]","[N;D1;!R;H0]#[N+][N-]"]
#Таким способом конечно скачается далеко не все что найдется но для примера хватит
compounds = []
per_page = 10**5
for azide in azides:
for i in range(2):
try:
a = pcp.get_properties(
properties="CanonicalSMILES",
identifier=azide, namespace="smiles",
searchtype="substructure",
RingsNotEmbedded=True,
listkey_count=per_page, listkey_start=i*per_page
)
except:
break
print("Retrieved page {} of {} search".format(i+1, azide))
compounds.extend(a)
len(compounds)
Часть 3 Присоединяем азиды к модифицированному ибупрофену и проверяем соответствие продукта правилу пяти Лепински
Проверим соответствие ибупрофена правилу пяти Лепински
import rdkit.Chem.Lipinski as Lipinksy
print(Lipinksy.NumHDonors(ibu))
print(Lipinksy.NumHAcceptors(ibu))
print(Lipinksy.rdMolDescriptors.CalcExactMolWt(ibu))
print(Lipinksy.rdMolDescriptors.CalcCrippenDescriptors(ibu)[0])
Видим что сам по себе ибупрофен удовлетворяет правилу, неудивительно что он такой популярный фармпрепарат
#формула для проверки удовлетворения правилу Лепински
def rule(mol):
return((Lipinksy.NumHDonors(mol)<=5)&(Lipinksy.NumHAcceptors(mol)<=10)&(Lipinksy.rdMolDescriptors.CalcExactMolWt(mol)<500)&(Lipinksy.rdMolDescriptors.CalcCrippenDescriptors(mol)[0]<=5))
Промодифицируем ибупрофен скачанными азидами. Если у молекулы было два азида записанные как N=[N+]=[N-], то ибупрофен присоединится к обоим, но что поделать. Напишем как выглядит template то есть то что появится на месте азида после циклоприсоединения
template="N2N=NC(C(C)C3=CC(C(C)C)=CC=C3)=C2"
template_pic=Chem.MolFromSmiles('N2N=NC(C(C)C3=CC(C(C)C)=CC=C3)=C2')
AllChem.Compute2DCoords(template_pic)
display(template_pic)
#вместо водорода при азоте в кольце будет соединение из PubChem
При замещении будем проверять наличие в соединении хотя бы одного атома углерода чтобы избежать poly-N структур
good_derivatives=[]
good_azides=[]
for compound in compounds[:1500]:
if 'N=[N+]=[N-]' in compound["CanonicalSMILES"] and ("c" in compound["CanonicalSMILES"] or "C" in compound["CanonicalSMILES"]):
new_compound=compound["CanonicalSMILES"].replace('N=[N+]=[N-]',template)
else:
continue
try:
newmol=Chem.MolFromSmiles(new_compound)
if rule(newmol):
good_azides.append(compound)
good_derivatives.append(newmol)
except:
pass
len(good_azides)
На всякий случай проверим, сколько среди них уникальных азидов
len(good_derivatives)-len(set(good_derivatives))
Все в этой подвыборке уникальные)
display(Draw.MolsToGridImage(good_derivatives, maxMols=15, molsPerRow=3, subImgSize=(400, 600)))
Видим что не все возможные азидные группировки заменились, потому что не все они видимо были записаны как N=[N+]=[N-], но это в целом нормально, потому что мы хотим присоединить азид к ибупрофену а не ибупрофен ко всем азидным группам в молекуле. Конечно пространство поиска потенциальных противовоспалительных и антибиотиков таким образом несколько обедняется, что наверняка решается путем более внимательного перебора и аккуратного замещения всех возможных форм записи азидов.
Нарисуем карты сходства.
from rdkit.Chem.Draw import SimilarityMaps
weights=[]
for i in range(5):
fig, maxweight = SimilarityMaps.GetSimilarityMapForFingerprint(ibu, good_derivatives[i], SimilarityMaps.GetMorganFingerprint)
print(maxweight)
Сходство не очень большое, что не удивительно, ведь мы присоединяем довольно большие куски органических молекул и изначальный ибупрофеновый фрагмент в составе соединения значит уже не так много.
Посмотрим на 3D структуру 5го производного
import nglview as nv
m3d=Chem.AddHs(good_derivatives[4])
Chem.AllChem.EmbedMolecule(m3d)
AllChem.MMFFOptimizeMolecule(m3d,maxIters=500,nonBondedThresh=200 )
pic=nv.show_rdkit(m3d)
nv.show_rdkit(m3d)
Действительно очень удобный способ быстро оценить 3d геометрию! (правда этого не видно в html), зато в html можно увидеть другое изображение
display(m3d)
Судя по правилу Лепински все полученные нами 119 модификаций ибупрофена, а в реальности и того больше (в полной базе данных) могут потенциально быть его аналогами