引き続きpyscfの計算実施用アプリについて紹介したいと思います。
今回は計算実行部分の関数とTkinter設定部分のコードになります。
基本的なコードは以前に紹介したPsi4のアプリのコードと同様になりますがPyscf用に一部変更しています。計算用のインプットデータですが、Pyscfではxyzファイルでの入力に対応していますので、mol ファイルの場合はrdkitを利用して配座探索を行った後にxyz を作成し、インプットデータ(comp_geo)としています。もともとxyzファイルの場合はそのままインプットデータとしています(配座探索が現時点では組み込まれていないので留意が必要です)。以前のアプリと同様に変数によってはglobal定義にしないとエラーが出ましたのでここではglobal宣言をしていますが、他のやり方もあるのかもしれません。
def calc_run(self): global meth global func global base global svname meth=method_sv.get() func=function_sv.get() base=baseset_sv.get() svname=savename_sv.get() global chr global mul chr=charge.get() mul=multi.get() global mem global thre mem=memory.get() thre=threads.get() global fname fname=filename_sv.get() # Conformer search by rdkit then make xyz file # 計算のgeometry file(xyz)は comp_geo で設定 global comp_geo with open (fname) as f: if '.mol' in fname: mol_H=f.read() confs = AllChem.EmbedMultipleConfs(mol_H, 10, pruneRmsThresh=1) prop = AllChem.MMFFGetMoleculeProperties(mol_H) energy=[] for conf in confs: mmff = AllChem.MMFFGetMoleculeForceField(mol_H, prop,confId=conf) mmff.Minimize() energy.append((mmff.CalcEnergy(), conf)) conflist = np.array(energy) sortconf=conflist[np.argsort(conflist[:,0]) ] stconfid=sortconf[0,1] stconfid2=int(stconfid) stconfgeom=mol_H.GetConformer(stconfid2) xyz = chr, mul for atom, (x,y,z) in zip(mol_H.GetAtoms(), stconfgeom.GetPositions()): xyz += '\n' xyz += '{}\t{}\t{}\t{}'.format(atom.GetSymbol(), x, y, z) with open ('geomerty_for_calc.xyz', mode='w') as f: f.write(xyz) comp_geo='geomerty_for_calc.xyz' # 上記xyxデータをファイルとして保存 # Setting input file elif '.xyz' in fname: comp_geo=fname # 計算関数内のgto(atom=###)に設定できるxyzファイルとして設定 # Select calculation task task=task_sv.get() if task=='Geometry optimization': Geom_Opt() elif task=='Vibration analysis': Vib_Calc() elif task=='Geom opt + Vib analysis': Geom_Opt_Vib_Anal() elif task=='Molecular orbitals analysis': MO_anal() elif task=='UV-Vis spectrum': UV_VIS_Spec() elif task=='Muliken charges': Mul_Charge() elif task=='Dipole moment': Dip_Moment() elif task=='Polarizability': Polar() elif task=='Infrared Spectrum': infrared_spect() # finish program def scry_finish(): exit()
以下はTkinter の設定部のコードになります。
GUIのタイトルと枠(大きさの設定)、Label, Entry, Button, Comboboxなどの設定を行っていますが、選択項目の少しの変更以外はPsi4のアプリの際と大きな変更点はありません。
Tkinter main root = tk.Tk() root.title("Pyscf Calculation Setup") root.geometry('800x650') # Select molecule file Label1=ttk.Label(root, text=u'Molecule',font=("Times","14","bold")) Label1.place(x=20, y=60) filename_sv = tk.StringVar() filenameEntry = ttk.Entry(width=60, text="", textvariable=filename_sv) filenameEntry.place(x=20, y= 90) Button1 = ttk.Button(text=u'Select',width=10) Button1.bind("<Button-1>", data_import) Button1.place(x=600, y=90) # Select calculation task Label2=ttk.Label(text=u'Task', font=("Times","14","bold")) Label2.place(x=20, y=140) task_sv = tk.StringVar() task_contents=('Geometry optimization','Vibration analysis','Geom opt + Vib analysis', 'Molecular orbitals analysis', 'UV-Vis spectrum','Muliken charges','Dipole moment', 'Polarizability', 'Infrared Spectrum' ) comboBox2=ttk.Combobox(root, height=5, width=20, state='readonly', values=task_contents, textvariable=task_sv) comboBox2.place(x=20, y=170) # Select calculation methods Label3=ttk.Label(text=u'Calculation Method', font=("Times","14","bold")) Label3.place(x=20, y=220) Label3_1=ttk.Label(root, text=u'Method',font=("Times","12")) Label3_1.place(x=20, y=240) method_sv = tk.StringVar() methods=('HF','DFT', 'MP2') comboBox3_1=ttk.Combobox(root, height=5, width=10, state='readonly', values=methods, textvariable=method_sv) comboBox3_1.place(x=20, y=260) Label3_2=ttk.Label(root, text=u'Function',font=("Times","12")) Label3_2.place(x=200, y=240) function_sv = tk.StringVar() functions=('','b3lyp','cam-b3lyp', 'edf2','m06', 'pbe','wb97x-d') comboBox3_2=ttk.Combobox(root, height=5, width=10, state='readonly', values=functions, textvariable=function_sv) comboBox3_2.place(x=200, y=260) Label3_3=ttk.Label(root, text=u'Basis set',font=("Times","12")) Label3_3.place(x=400, y=240) baseset_sv = tk.StringVar() base_sets=('3-21g','6-31g', '6-31g(d)','6-311g', 'aug-cc-pvtz') comboBox3_3=ttk.Combobox(root, height=5, width=10, state='readonly', values=base_sets, textvariable=baseset_sv) comboBox3_3.place(x=400, y=260) # Select options Label4=ttk.Label(text=u'Options', font=("Times","14","bold")) Label4.place(x=20, y=300) Label4_1=ttk.Label(root, text=u'Tread',font=("Times","12")) Label4_1.place(x=30, y=320) threads=tk.IntVar(value=2) textBox1_1=ttk.Entry(root, width=5, textvariable=threads) textBox1_1.place(x=30, y=340) Label4_2=ttk.Label(root, text=u'Memory/MB',font=("Times","12")) Label4_2.place(x=130, y=320) memory=tk.IntVar(value=500) textBox1_2=ttk.Entry(root, width=5, textvariable=memory) textBox1_2.place(x=130, y=340) Label4_3=ttk.Label(root, text=u'Charge',font=("Times","12")) Label4_3.place(x=30, y=370) charge=tk.IntVar(value=0) textBox2_1=ttk.Entry(root, width=5, textvariable=charge) textBox2_1.place(x=30, y=390) # spinのカウントは不対電子の数を数えるため通常(一重項)spin=0, ラジカルspin=1, 三重項 spin=2 Label4_4=ttk.Label(root, text=u'Multiplicity',font=("Times","12")) Label4_4.place(x=130, y=370) multi=tk.IntVar(value=0) textBox2_2=ttk.Entry(root, width=5, textvariable=multi) textBox2_2.place(x=130, y=390) # Input the name of calculated output files Label5=ttk.Label(text=u'Name of output files', font=("Times","14","bold")) Label5.place(x=20, y=470) savename_sv = tk.StringVar() textBox3=ttk.Entry(root, width=30, textvariable=savename_sv) textBox3.place(x=30, y=500) # Calculation Run Button2=ttk.Button(text=u'Run',width=20) Button2.bind("<Button-1>", calc_run) Button2.place(x=300, y=540) Label6=ttk.Label(text=u'Finish the program') Label6.place(x=630, y=560) Button3 = ttk.Button(text=u'Quit',width=10, command=scry_finish) Button3.place(x=630, y=580) root.mainloop()
以上、今回は計算実行部分とTkinterの入力部の続きについて紹介してきました。次回は実際のアプリの入力の様子の説明を行いたいと思います。