import pybel
from subprocess import Popen, PIPE
import threading
import nglview
def create_3d(form, meth = "PM6", mop_name = "mop.mop", pdf_file_name = "temp.pdb"):
proc = Popen(
"export MOPAC_LICENSE='/home/preps/golovin/progs/mopac/'",
shell=True,
stdout=PIPE, stderr=PIPE
)
proc.wait()
mol=pybel.readstring('smi', form)
mol.addh()
mol.make3D(steps=10000)
mop=mol.write(format='mopin',filename=mop_name, opt={'k':'{} CHARGE={}'.format(meth, mol.charge)}, overwrite=True)
proc = Popen(
"/home/preps/golovin/progs/mopac/MOPAC2016.exe {}".format(mop_name),
shell=True,
stdout=PIPE, stderr=PIPE
)
_ = proc.communicate()
opt=pybel.readfile('mopout', mop_name[:-3] + "out")
mol = opt.next()
print pdf_file_name
mol.write(format='pdb',filename= pdf_file_name, overwrite=True)
return mol
class MolThread(threading.Thread):
def __init__(self, **kwargs):
self.kwargs = kwargs
threading.Thread.__init__(self)
def run(self):
self.mol = create_3d(**self.kwargs)
from IPython import display
processes = list()
for meth in ("PM6", "AM1"):
e = MolThread(**{"form" : "C1=CC2=CC3=CC=C(N3)C=C4C=CC(=N4)C=C5C=CC(=N5)C=C1N2",
"meth" : meth,
"mop_name" : "hem_{}_mop.mop".format(meth),
"pdf_file_name" : "hem_{}.pdb".format(meth)
}
)
e.start()
processes.append(e)
for proc in processes:
proc.join()
for proc in processes:
display.display(proc.mol)
from IPython.display import Image
Сравним изображение, полученное при использовании AM1:
Image(filename="hem_AM1.png")
И использовании PM6
Image(filename="hem_PM6.png")
Видим, что в случае PM6 структура получилось плоской, что корректно.
Построим приблизительный спектр поглощения молекулы, используя формулу $E=hv$
%%bash
cp hem_PM6_mop.mop hem_PM6_mop_mod.mop
echo "" >> hem_PM6_mop_mod.mop
echo "cis c.i.=4 meci oldgeo" >> hem_PM6_mop_mod.mop
echo "some description" >> hem_PM6_mop_mod.mop
%%bash
export MOPAC_LICENSE='/home/preps/golovin/progs/mopac/'
/home/preps/golovin/progs/mopac/MOPAC2016.exe hem_PM6_mop_mod.mop
with open('hem_PM6_mop_mod.out', 'r') as in_file:
start = False
end = False
energies = []
for line in in_file:
if "ABSOLUTE RELATIVE X Y Z" in line:
start = True
elif "The \"+\" symbol indicates the root used" in line:
end = True
elif start and not end and line.strip():
energies.append(line)
energies = [float(energy_info.split()[1]) for energy_info in energies]
energies = energies[1:]
lengths = [1239.84193/e for e in energies]
import matplotlib.pyplot as plt
plt.figure(figsize=(10,10))
plt.bar(lengths, energies, align='center', alpha=0.5)
plt.xticks(lengths, ["{:.00f}".format(x) for x in lengths])
plt.ylabel('Energy')
plt.title('Spectrum')
plt.xticks(rotation=90)
plt.show()
Попробуем теперь промоделировать переход тиминового димера в отдельные тимины при возбуждении
td_file_name= "td.pdb"
init_file_name = "td_init.mop"
middle_file_name = "td_middle.mop"
end_file_name = "td_end.mop"
init_out_file_name = "td_init.out"
middle_out_file_name = "td_middle.out"
end_out_file_name = "td_end.out"
init_pdb_file = "td_init.pdb"
middle_pdb_file = "td_middle.pdb"
end_pdb_file = "td_end.pdb"
Изначальная структура
Image(filename="td.png")
Оптимизируем изначальную структуру
td = pybel.readfile("pdb", td_file_name).next()
td.write(format='mop',filename=init_file_name,opt={"k":"PM6 CHARGE={}".format(0)},overwrite=True)
proc = Popen(
"/home/preps/golovin/progs/mopac/MOPAC2016.exe {}".format(init_file_name),
shell=True,
stdout=PIPE, stderr=PIPE
)
_ = proc.communicate()
td = pybel.readfile("mopout", init_out_file_name).next()
td.write(format="pdb", filename=init_pdb_file, overwrite=True)
Ничего особо не изменилось
Image("td_init.png")
Имитируем возбуждение системы, ставя ее заряд равным $+2$
td.write(format="mop",filename=middle_file_name,opt={"k":"PM6 CHARGE={}".format(2)},overwrite=True)
proc = Popen(
"/home/preps/golovin/progs/mopac/MOPAC2016.exe {}".format(middle_file_name),
shell=True,
stdout=PIPE, stderr=PIPE
)
_ = proc.communicate()
td = pybel.readfile("mopout", middle_out_file_name).next()
td.write(format="pdb", filename=middle_pdb_file, overwrite=True)
После оптимизации получаем тимины, соединенные уже одной связью
Image("td_middle.png")
Ставим заряд системы опять 0 и оптимизируем
td.write(format='mop',filename=end_file_name,opt={"k":"PM6 CHARGE={}".format(0)},overwrite=True)
proc = Popen(
"/home/preps/golovin/progs/mopac/MOPAC2016.exe {}".format(end_file_name),
shell=True,
stdout=PIPE, stderr=PIPE
)
td = pybel.readfile("mopout", end_out_file_name).next()
td.write(format="pdb", filename=end_pdb_file, overwrite=True)
Получаем отдельные тимины
Image("td_end.png")
Смотрим на энергию каждого состояния, указанную в файлах
%%bash
echo "Init state"
grep "TOTAL ENERGY" "td_init.out"
echo "Middle state"
grep "TOTAL ENERGY" "td_middle.out"
echo "End state"
grep "TOTAL ENERGY" "td_end.out"
Видим, что состояния почти эквивалентны и после возбуждения наша молекула может перейти как в состояние димера, так и в состояниие двух отдельных тиминов