A series of Python3 script to lower the barrier of computing and simulating molecular and material systems.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

276 lines
13 KiB

2 years ago
#!/usr/bin/env python3
# pylint: disable=missing-function-docstring
from __future__ import print_function
import panel as pn
from panel_chemistry.widgets import JSMEEditor
from panel.interact import interact
import os
import sys
from panel_chemistry.pane import NGLViewer
from panel_chemistry.pane.ngl_viewer import EXTENSIONS
import py3Dmol
from panel_chemistry.pane import Py3DMol
import subprocess
import uuid
2 years ago
# from iodata import IOData
def test_can_construct():
JSMEEditor()
def cmmde_gui():
geom = ''
pn.extension("jsme", sizing_mode="stretch_width")
editor = JSMEEditor(value = " ",height=500,format="smiles",subscriptions=['smiles'])
# Terminal widget
2 years ago
TextArea= pn.widgets.TextAreaInput(value = "Computational Molecular and Material Design Environment\n Authors:\n Universitas Pertamina\n Institut Teknologi Sumatera\n Masyarakat Komputasi Indonesia\n\nSupported by:\n Konsorsium Pengembangan Sains Komputasi\n",
2 years ago
height = 500, disabled=True
2 years ago
)
# CMMDE software options
software_btn = pn.widgets.Select(name="Software selections",value='Orca',options=['Orca','GROMACS','Dcdftbmd','Quantum Espresso'])
2 years ago
software = {'Orca':'orca','GROMACS':'gromacs','Dcdftbmd':'dcdftb','Quantum Espresso':'qe'}
# CMMDE job options
job_btn = pn.widgets.MultiSelect(name="Job selections",value=['Single point calculation'],options=['Single point calculation','Geometry optimization','Frequency calculation','Molecular dynamics','Metadynamics'])
2 years ago
job = {'Single point calculation':'sp','Geometry optimization':'opt','Frequency calculation':'freq','Molecular dynamics':'md','Metadynamics':'mtd'}
2 years ago
# CMMDE method options
2 years ago
method_btn = pn.widgets.Select(name="Method selections",value='GFN2-xTB',options=['GFN2-xTB','GFN1-xTB','DFTB2','DFTB2-gammah','DFTB3','DFTB3-diag','B3LYP/def2-svp'])
method = {'GFN2-xTB':'XTB2', 'GFN1-xTB':'XTB1','DFTB2':'DFTB2','DFTB2-gammah':'DFTB2_gammah','DFTB3':'DFTB3','DFTB3-diag':'DFTB3-diag','B3LYP/def2-svp':'B3LYP def2-svp'}
2 years ago
2 years ago
# Name your molecule/Material
2 years ago
Molecule_input = pn.widgets.TextInput(name="Molecule name")
2 years ago
id_input = pn.widgets.TextInput(name="Input your name")
workdir = os.getenv("HOME") + "/" + "scr"
# File input (if you don't want to draw the structure)
2 years ago
FileInput = pn.widgets.FileInput(title='Input structure',accept='.xyz,.vasp,.pdb')
2 years ago
def fileinput(event):
if FileInput.value is not None:
FileInput.save("geom.xyz")
FileInput.param.watch(fileinput,'value')
2 years ago
# CMMDE running button
Run_btn = pn.widgets.Button(name="Run CMMDE!",button_type='primary')
# RunMessage = pn.widgets.StaticText()
2 years ago
charge = pn.widgets.TextInput(name="Charge",value="0")
mult = pn.widgets.TextInput(name="Spin multiplicity",value="1")
2 years ago
def run(event):
# RunMessage.value = " "
# terminal.clear()
2 years ago
# unik = str(uuid.uuid4().hex)
2 years ago
Folder = workdir + "/" + id_input.value + "/" + Molecule_input.value
os.chdir(Folder)
job_list = [job[i] for i in job_btn.value]
jobs = ",".join(job_list)
2 years ago
if editor.value == "":
FileInput.save("geom.xyz")
geom = "geom.xyz"
2 years ago
else:
geom = editor.value
2 years ago
2 years ago
TextArea.value = TextArea.value + "\n" + "Mempersiapkan Struktur 3 Dimensi!"
cmd = subprocess.run(["cmmde.py","-i","{}".format(geom),"-s","{}".format(software[software_btn.value]),"-j","{}".format(jobs),"-m","{}".format(method[method_btn.value]),"-c","{}".format(charge.value),"-mult","{}".format(mult.value)],capture_output=True,text=True)
#terminal.subprocess.run("cmmde.py","-i{}".format(editor.value),"-s{}".format(software[software_btn.value]), "-j{}".format(jobs), "-m{}".format(method[method_btn.value]))
2 years ago
TextArea.value = TextArea.value + "\n" + "Perhitungan anda telah tersubmit!"
# RunMessage.value = "Perhitungan telah tersubmit!"
2 years ago
Run_btn.on_click(run)
2 years ago
# Check directory button
checkdir_btn = pn.widgets.Button(name="Generate work directory",type="primary")
TextWarning = pn.widgets.StaticText()
def checkdir(event):
2 years ago
Folder = workdir + "/" + id_input.value + "/" + Molecule_input.value
2 years ago
isExist = os.path.exists(Folder)
TextWarning.value = ""
if isExist:
TextWarning.value = "Directory exists! Change the molecule name!"
else:
os.makedirs(Folder)
TextWarning.value = "Successfully create the directory!"
checkdir_btn.on_click(checkdir)
2 years ago
2 years ago
2 years ago
# Post calculations
2 years ago
post_calc = {'Frequency calculation':'freq', 'Radial distribution function':'rdf','Mean Square Displacement':'msd','Time-dependent calculation':'td','Thermochemistry calculation':'thermo','Optimized energy':'opt'}
post_btn = pn.widgets.Select(name="Job Selection",value='Frequency calculation', options=['Frequency calculation','Radial distribution function', 'Mean Square Displacement','Time-dependent calculation','Thermochemistry calculation','Optimized energy'])
# Post Calculation CMMDE software options
post_software_btn = pn.widgets.Select(name="Software selections for post calculations",value='Orca',options=['Orca','GROMACS','Dcdftbmd','Quantum Espresso'])
post_software = {'Orca':'orca','GROMACS':'gromacs','Dcdftbmd':'dcdftb','Quantum Espresso':'qe'}
# Post CMMDE method options
post_method_btn = pn.widgets.Select(name="Method selections for post calculations",value='GFN2-xTB',options=['GFN2-xTB','GFN1-xTB','DFTB2','DFTB2-gammah','DFTB3','DFTB3-diag'])
post_method = {'GFN2-xTB':'XTB2', 'GFN1-xTB':'XTB1','DFTB2':'DFTB2','DFTB2-gammah':'DFTB2_gammah','DFTB3':'DFTB3','DFTB3-diag':'DFTB3-diag'}
2 years ago
def post_calculation(event):
# terminal.clear()
if post_calc[post_btn.value] == 'thermo' and post_software[post_software_btn.value] == 'orca':
cmd = subprocess.run(["cmmdepost.py","-j","{}".format(post_calc[post_btn.value]),"-s","{}".format(post_software[post_software_btn.value])],capture_output=True,text=True)
TextArea.value = TextArea.value + "\n" + cmd.stdout
2 years ago
# terminal.subprocess.run("cmmdepost.py","-j{}".format(post_calc[post_btn.value]),"-s{}".format(post_software[post_software_btn.value]))
elif post_calc[post_btn.value] == 'opt' and post_software[post_software_btn.value] == 'orca':
cmd = subprocess.run(["cmmdepost.py","-j","{}".format(post_calc[post_btn.value]),"-s","{}".format(post_software[post_software_btn.value]),"-m","{}".format(post_method[post_method_btn.value])],capture_output=True,text=True)
TextArea.value = TextArea.value + "\n" + cmd.stdout
2 years ago
else:
2 years ago
Folder = workdir + "/" + id_input.value + "/" + Molecule_input.value
2 years ago
os.chdir(Folder)
os.makedirs(post_calc[post_btn.value])
os.chdir(post_calc[post_btn.value])
cmd = subprocess.run(["cmmde.py","-i","{}".format("../cmmd.xyz"),"-s","{}".format(post_software[post_software_btn.value]),"-j","{}".format(post_calc[post_btn.value]),"-m","{}".format(post_method[post_method_btn.value])],capture_output=True,text=True)
# terminal.subprocess.run("cmmde.py","-i{}".format("../cmmd.xyz"),"-s{}".format(post_software[post_software_btn.value]), "-j{}".format(post_calc[post_btn.value]), "-m{}".format(post_method[post_method_btn.value]))
TextArea.value = TextArea.value + "\n" + cmd.stdout
2 years ago
runpost_btn = pn.widgets.Button(name="Run post calculation!",button_type='primary')
runpost_btn.on_click(post_calculation)
2 years ago
# Check the queue progress
2 years ago
def progress(event):
# terminal.clear()
# terminal.subprocess.run("squeue")
cmd = subprocess.run(["squeue"],capture_output=True,text=True)
TextArea.value = TextArea.value + "\n" + cmd.stdout
2 years ago
Progress_btn = pn.widgets.Button(name="Check queue",button_type='primary')
2 years ago
Progress_btn.on_click(progress)
2 years ago
# Check the calculation progress
def calc_progress(event):
cmd = subprocess.run(["tail", "-n", "10", "cmmd.out"],capture_output=True,text=True)
TextArea.value = TextArea.value + "\n" + cmd.stdout
Checkcalc_btn = pn.widgets.Button(name="Check calculation",button_type='primary')
Checkcalc_btn.on_click(calc_progress)
# # Download Button
download_xyz = pn.widgets.FileDownload(file="cmmd.xyz",filename="cmmd.xyz")
download_slab = pn.widgets.FileDownload(file="slab.vasp",filename="slab.vasp")
# Slab Builder
hkl_input = pn.widgets.TextInput(name="Miller index (hkl)",placeholder="Example: 100")
size_input = pn.widgets.TextInput(name="Dimension",placeholder="Example: 2x2")
layer_input = pn.widgets.TextInput(name="Layer",placeholder="Example: 2")
slabbuilder_btn = pn.widgets.Button(name="Build it!",button_type="primary")
2 years ago
Material_input = pn.widgets.TextInput(name="Material name")
2 years ago
Material_upload = pn.widgets.FileInput(title='Input structure')
def materialinput(event):
if Material_upload.value is not None:
Material_upload.save("POSCAR")
Material_upload.param.watch(materialinput,'value')
2 years ago
# Generate material folder button
materialdir_btn = pn.widgets.Button(name="Generate work directory",type="primary")
2 years ago
2 years ago
def materialgen(event):
Folder = workdir + "/" + id_input.value + "/" + Material_input.value
isExist = os.path.exists(Folder)
TextWarning.value = ""
if isExist:
TextWarning.value = "Directory exists! Change the material name!"
else:
os.makedirs(Folder)
TextWarning.value = "Successfully create the directory!"
materialdir_btn.on_click(materialgen)
2 years ago
def slab_builder(event):
2 years ago
Folder = workdir + "/" + id_input.value + "/" + Material_input.value
2 years ago
os.chdir(Folder)
2 years ago
# os.system("mv geom.xyz POSCAR")
2 years ago
hkl = hkl_input.value
size = size_input.value
layer = layer_input.value
cmd = subprocess.run(["cmmdepre.py","-j","surface","-hkl","{}".format(hkl),"-s","{}".format(size),"-n","{}".format(layer),"-i","POSCAR"])
os.system("mv slab_{}.xyz cmmd.xyz".format(hkl))
os.system("mv slab_{}.vasp slab.vasp".format(hkl))
cmd = subprocess.run(["echo","({})-surface construction done!".format(hkl)],capture_output=True,text=True)
TextArea.value = TextArea.value + "\n" + cmd.stdout
# xyzview = py3Dmol.view()
# with open('slab_{}.xyz'.format(hkl),'r') as f:
# xyz = f.read()
# xyzview.addModel(xyz,'xyz')
# xyzview.setStyle('stick')
# xyzviewer.object = xyzview
slabbuilder_btn.on_click(slab_builder)
# Solution Builder
# fileinput_solute = pn.widgets.FileInput(accept=".xyz",multiple=True)
# fileinput_solvent = pn.widgets.FileInput(accept=".xyz")
# def SolutionBuilder(event):
# solute = fileinput_solute.value
# solvent = fileinput_solute.value
2 years ago
2 years ago
2 years ago
# Visualize the results
xyzview = py3Dmol.view()
2 years ago
2 years ago
xyzviewer = Py3DMol(xyzview, height=400, sizing_mode="stretch_width",name="CMMDE viewer")
def visualize(event):
2 years ago
xyzview = py3Dmol.view()
2 years ago
Folder = workdir + "/" + id_input.value + "/" + Molecule_input.value
2 years ago
os.chdir(Folder)
2 years ago
with open('cmmd.xyz','r') as f:
xyz = f.read()
xyzview.addModel(xyz,'xyz')
xyzview.setStyle('stick')
xyzviewer.object = xyzview
visual_btn = pn.widgets.Button(name="Visualize!", button_type='primary')
visual_btn.on_click(visualize)
def set_background(color='0xeeeeee'):
xyzview.setBackgroundColor(color)
xyzviewer.param.trigger("object")
set_background("#e6f6ff")
accent = "#0072B5"
# background = pn.widgets.ColorPicker(value="#e6f6ff", name="Background")
# pn.bind(set_background, color=background, watch=True)
# def set_style(style="stick"):
# xyzview.setStyle({style: {}})
# xyzview.zoomTo()
# xyzviewer.param.trigger("object")
# set_style("stick")
# style=pn.widgets.RadioButtonGroup(value="stick", options=["stick", "sphere"], name="Style", button_type="success")
# set_style=pn.bind(set_style, style=style, watch=True)
#### Wrap them all together ##########
return pn.template.MaterialTemplate(
2 years ago
site="CMMDE-GUI",
title="CMMDE Editor",
2 years ago
main=[TextArea, editor, xyzviewer],
sidebar=[pn.Card(id_input,title="User Information",collapsed=True),pn.Card(Molecule_input,charge,mult,checkdir_btn,TextWarning,pn.Card(FileInput,title="Upload molecule",collapsed=True),title="Molecule Information",collapsed=True),pn.Card(Material_input, materialdir_btn,TextWarning, pn.Card(FileInput,title="Unit cell",collapsed=True),hkl_input,size_input,layer_input,pn.Row(slabbuilder_btn,visual_btn),pn.Row(download_xyz,download_slab),title="Surface Builder",collapsed=True),pn.Card(software_btn,job_btn,method_btn,pn.Row(Run_btn,Progress_btn),pn.Row(Checkcalc_btn,visual_btn),title="Main Calculation",collapsed=True),pn.Card(post_software_btn,post_btn,post_method_btn,pn.Row(runpost_btn,Progress_btn),pn.Row(Checkcalc_btn,visual_btn),title="Post-Calculation",collapsed=True)],
2 years ago
header_background=accent, accent_base_color=accent
)
if __name__.startswith("bokeh"):
cmmde_gui().servable()