From b3accc6bdb80d8071cfcba239ec2d386f643388c Mon Sep 17 00:00:00 2001 From: You Lu Date: Tue, 6 Aug 2019 18:24:47 +0100 Subject: [PATCH] Tool plugin for Py-ChemShell finished; removed all changes to commands and gui --- .gitignore | 10 + src/plugins/CMakeLists.txt | 1 + src/plugins/io_chemshell/chemshell_funcs.cpp | 39 +- src/plugins/tool_chemshell/CMakeLists.txt | 52 ++ src/plugins/tool_chemshell/chemshelltool.hui | 127 ++++ .../tool_chemshell/chemshelltool_funcs.cpp | 540 ++++++++++++++++ .../tool_chemshell/chemshelltool_icons.qrc | 5 + .../tool_chemshell/chemshelltooldialog.h | 97 +++ .../tool_chemshell/chemshelltooldialog.ui | 603 ++++++++++++++++++ .../chemshelltooldialog_funcs.cpp | 309 +++++++++ src/plugins/tool_chemshell/icon.svg | 218 +++++++ 11 files changed, 1999 insertions(+), 2 deletions(-) create mode 100644 src/plugins/tool_chemshell/CMakeLists.txt create mode 100644 src/plugins/tool_chemshell/chemshelltool.hui create mode 100644 src/plugins/tool_chemshell/chemshelltool_funcs.cpp create mode 100644 src/plugins/tool_chemshell/chemshelltool_icons.qrc create mode 100644 src/plugins/tool_chemshell/chemshelltooldialog.h create mode 100644 src/plugins/tool_chemshell/chemshelltooldialog.ui create mode 100644 src/plugins/tool_chemshell/chemshelltooldialog_funcs.cpp create mode 100644 src/plugins/tool_chemshell/icon.svg diff --git a/.gitignore b/.gitignore index cf4487326..e96a99029 100644 --- a/.gitignore +++ b/.gitignore @@ -26,7 +26,17 @@ src/aten Aten.desktop .kdev4/ build/ +bin # Miscellaneous *swp changes + +#CMake +cmake_install.cmake +CMakeFiles +CMakeCache.txt + +# QRC +*.qrc.depends +qrc_*.cpp diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index e6904765a..ead137b49 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -38,4 +38,5 @@ add_subdirectory(io_vfield) add_subdirectory(io_xyz) add_subdirectory(method_mopac71) add_subdirectory(tool_springs) +add_subdirectory(tool_chemshell) add_subdirectory(tool_test) diff --git a/src/plugins/io_chemshell/chemshell_funcs.cpp b/src/plugins/io_chemshell/chemshell_funcs.cpp index 04bc4b8ee..e64ec9891 100644 --- a/src/plugins/io_chemshell/chemshell_funcs.cpp +++ b/src/plugins/io_chemshell/chemshell_funcs.cpp @@ -29,6 +29,12 @@ ChemShellModelPlugin::ChemShellModelPlugin() { // Setup plugin options pluginOptions_.add("useTypeNames", "false"); + pluginOptions_.add("py-chemsh_input", "false"); + // YL 06/08/2019: strings for PY-ChemShell input script + pluginOptions_.add("_frag" , ""); + pluginOptions_.add("_qm_region", ""); + pluginOptions_.add("_theory" , ""); + pluginOptions_.add("_task" , ""); } // Destructor @@ -145,6 +151,8 @@ bool ChemShellModelPlugin::importData() for (i = 0; i < nRecords; ++i) { if (!fileParser_.parseLine()) break; atom = createAtom(targetModel(), fileParser_.argc(0), fileParser_.arg3d(1)*ANGBOHR); + ForcefieldAtom* ffa = targetModel()->addAtomName(atom->element(), fileParser_.argc(0)); + atom->setType(ffa); } break; case (ChemShellModelPlugin::AtomChargesBlock): @@ -202,6 +210,26 @@ bool ChemShellModelPlugin::exportData() // Get the current model pointer containing the data we are to export Model* sourceModel = targetModel(); + // YL 06/08/2019: we have to use io_chemshell to write out since tool_chemshell cannot access I/O + if(pluginOptions_.value("py-chemsh_input") == "true") { + + if(!fileParser_.writeLine("# Py-ChemShell input script generated by Aten")) return false; + if(!fileParser_.writeLine("# www.chemshell.org")) return false; + if(!fileParser_.writeLine("# Cite: J. Chem. Theory Comput. 2019, 15, 1317-1328\n")) return false; + if(!fileParser_.writeLine("from chemsh import *\n")) return false; + if(!fileParser_.writeLine(pluginOptions_.value("_frag"))) return false; + if(!fileParser_.writeLine(pluginOptions_.value("_pun_filename"))) return false; + if(!fileParser_.writeLine(pluginOptions_.value("_qm_region"))) return false; + if(!fileParser_.writeLine(pluginOptions_.value("_theory"))) return false; + if(!fileParser_.writeLine(pluginOptions_.value("_task"))) return false; + if(!fileParser_.writeLine("my_task.run()\n")) return false; + if(!fileParser_.writeLine("energy = my_task.result.energy\n")) return false; + + Messenger::print("Py-ChemShell input script '%s' generated", qPrintable(fileParser_.filename())); + return true; + + } + // Header if (!fileParser_.writeLine("block = fragment records = 0")) return false; if (!fileParser_.writeLine("block = title records = 1")) return false; @@ -210,10 +238,17 @@ bool ChemShellModelPlugin::exportData() // Atom coordinates if (!fileParser_.writeLineF("block = coordinates records = %d", sourceModel->nAtoms())) return false; for ( Atom* i = sourceModel->atoms(); i != NULL; i = i->next ) { - if (!fileParser_.writeLineF("%s %20.14e %20.14e %20.14e ", ElementMap::symbol(i->element()), - i->r().x/ANGBOHR, i->r().y/ANGBOHR, i->r().z/ANGBOHR)) return false; + // YL 02/08/2019: changed to print ff types rather than element symbols + if (!fileParser_.writeLineF("%s %20.14e %20.14e %20.14e ", i->type()->name().toUtf8().constData(), + i->r().x/ANGBOHR, i->r().y/ANGBOHR, i->r().z/ANGBOHR)) return false; +// if (!fileParser_.writeLineF("%s %20.14e %20.14e %20.14e ", ElementMap::symbol(i->element()), +// i->r().x/ANGBOHR, i->r().y/ANGBOHR, i->r().z/ANGBOHR)) return false; } + // total charge + if (!fileParser_.writeLine("block = charge records = 1")) return false; + if (!fileParser_.writeLineF("%20.5e", 0.00000)) return false; + // Atom charges hasCharges = false; tiny = 1.0e-10; diff --git a/src/plugins/tool_chemshell/CMakeLists.txt b/src/plugins/tool_chemshell/CMakeLists.txt new file mode 100644 index 000000000..0e1e88449 --- /dev/null +++ b/src/plugins/tool_chemshell/CMakeLists.txt @@ -0,0 +1,52 @@ +# Meta-Objects +set(chemshelltool_MOC_HDRS + chemshelltool.hui + chemshelltooldialog.h +) +QT5_WRAP_CPP(chemshelltool_MOC_SRCS ${chemshelltool_MOC_HDRS} OPTIONS -I${PROJECT_SOURCE_DIR}/src) + +SET(chemshelltool_UIS + chemshelltooldialog.ui +) +QT5_WRAP_UI(chemshelltool_UIS_H ${chemshelltool_UIS}) + +# Resources +set(chemshelltool_RES_QRC + chemshelltool_icons.qrc +) +QT5_ADD_RESOURCES(chemshelltool_RES ${chemshelltool_RES_QRC}) + +add_library(chemshelltool MODULE + chemshelltool_funcs.cpp + chemshelltooldialog_funcs.cpp + ${chemshelltool_RES} + ${chemshelltool_MOC_SRCS} + ${chemshelltool_UIS_H} +) +target_link_libraries(chemshelltool + plugins + ${PLUGIN_LINK_LIBS} +) +set_target_properties(chemshelltool PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${Aten_BINARY_DIR}/data/plugins + COMPILE_DEFINITIONS "QT_PLUGIN" + PREFIX "" +) + +# Install Targets +if(UNIX AND NOT APPLE) +install(TARGETS chemshelltool + RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}/aten/plugins COMPONENT RuntimePlugins + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/aten/plugins COMPONENT RuntimePlugins +) +endif(UNIX AND NOT APPLE) + +# Includes +target_include_directories(chemshelltool PRIVATE + ${PROJECT_SOURCE_DIR}/src + ${PROJECT_BINARY_DIR}/src + ${Qt5Core_INCLUDE_DIRS} + ${Qt5Gui_INCLUDE_DIRS} + ${Qt5Widgets_INCLUDE_DIRS} +) + diff --git a/src/plugins/tool_chemshell/chemshelltool.hui b/src/plugins/tool_chemshell/chemshelltool.hui new file mode 100644 index 000000000..b388038a6 --- /dev/null +++ b/src/plugins/tool_chemshell/chemshelltool.hui @@ -0,0 +1,127 @@ +/* + *** ChemShell Tool Plugin + *** src/plugins/tool_chemshell/chemshelltool.hui + Copyright T. Youngs 2016-2018 + + This file is part of Aten. + + Aten is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Aten is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Aten. If not, see . +*/ + +#ifndef ATEN_CHEMSHELLPLUGIN_H +#define ATEN_CHEMSHELLPLUGIN_H + +#include "plugins/interfaces/toolplugin.h" +#include "plugins/interfaces/fileplugin.h" +#include "gui/mainwindow.h" +#include "main/aten.h" +#include +#include "base/kvmap.h" +#include "base/prefs.h" +#include "base/encoderdefinition.h" +#include "model/bundle.h" +#include "model/fragment.h" +#include "model/fragmentgroup.h" +#include "templates/list.h" +#include "parser/program.h" +#include "parser/variablelist.h" +#include "methods/partitioningscheme.h" +#include "gui/useractions.h" +#include "plugins/pluginstore.h" +#include "base/namespace.h" + +// forward declarations +class AtenWindow; +class FileParser; + +ATEN_BEGIN_NAMESPACE + +// ChemShell Tool Plugin +class ChemShellToolPlugin : public QObject, public ToolPluginInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "com.projectaten.Aten.CSToolPluginInterface.v1") + Q_INTERFACES(AtenSpace::ToolPluginInterface) + + + public: + // Constructor + ChemShellToolPlugin(); + // Destructor + ~ChemShellToolPlugin(); + + + private: + AtenWindow* atenWindow(); + + /* + * Instance Handling + */ + private: + // Return a copy of the plugin object + BasePluginInterface* makeCopy() const; + void renameKeywords(); + + + /* + * Definition + */ + public: + // Return type of plugin + PluginTypes::PluginType type() const; + // Return category of plugin + int category() const; + // Return name of plugin + QString name() const; + // Return nickname of plugin + QString nickname() const; + // Return whether plugin is enabled + bool enabled() const; + // Return description (long name) of plugin + QString description() const; + + + /* + * Tool Definition + */ + public: + // Return button label to use in GUI + QString buttonLabel() const; + // Return icon for button in GUI + QIcon buttonIcon() const; + // Return group name for tool (used to group similar tools together) + QString groupName() const; + // Return whether the tool is enabled (appears in the GUI) + bool isEnabled() const; + // Return whether the tool has a dialog + bool hasDialog() const; + // Show the dialog for the tool + bool showDialog(); + // Run the tool with the current settings + bool runTool(); + + /* + * QObject / Signals + */ + public: + // Return interface as QObject + QObject* object(); + + signals: + void updateWidgets(int); +}; + +ATEN_END_NAMESPACE + +#endif diff --git a/src/plugins/tool_chemshell/chemshelltool_funcs.cpp b/src/plugins/tool_chemshell/chemshelltool_funcs.cpp new file mode 100644 index 000000000..93cb10298 --- /dev/null +++ b/src/plugins/tool_chemshell/chemshelltool_funcs.cpp @@ -0,0 +1,540 @@ +/* + *** ChemShell Tool Functions + *** src/plugins/tool_chemshell/chemshelltool_funcs.cpp + Copyright T. Youngs 2016-2018 + + This file is part of Aten. + + Aten is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Aten is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Aten. If not, see . +*/ + +#include "plugins/tool_chemshell/chemshelltool.hui" +#include "plugins/io_chemshell/chemshell.hui" +#include "plugins/tool_chemshell/chemshelltooldialog.h" +#include "gui/qcustomplot/qcustomplot.hui" +#include "model/model.h" +#include "model/clipboard.h" +#include "base/pattern.h" + +#include "plugins/interfaces/fileplugin.h" + +ATEN_USING_NAMESPACE + +// Constructor +// YL: to be processed by Qt marcros this constructor should not contain any argments for initialising +ChemShellToolPlugin::ChemShellToolPlugin() { + // Setup plugin options + pluginOptions_.add("selected_as_qm", "true"); + pluginOptions_.add("replace_suffix", "true"); + + + // Create dialog if the tool has one + if (hasDialog()) dialog_ = new ChemShellToolDialog(*this, pluginOptions_); + else dialog_ = NULL; +} + +// Destructor +ChemShellToolPlugin::~ChemShellToolPlugin() +{ +} + +/* + * Instance Handling + */ + +// Return a copy of the plugin object +BasePluginInterface* ChemShellToolPlugin::makeCopy() const +{ + return new ChemShellToolPlugin; +} + +/* + * Definition + */ + +// Return type of plugin +PluginTypes::PluginType ChemShellToolPlugin::type() const +{ + return PluginTypes::ToolPlugin; +} + +// Return category of plugin +int ChemShellToolPlugin::category() const +{ + return PluginTypes::GeneralToolPlugin; +} + +// Name of plugin +QString ChemShellToolPlugin::name() const +{ + return QString("ChemShell Tool Plugin"); +} + +// Nickname of plugin +QString ChemShellToolPlugin::nickname() const +{ + return QString("chemshell"); +} + +// Return whether the plugin is enabled +bool ChemShellToolPlugin::enabled() const +{ + return true; +} + +// Description (long name) of plugin +QString ChemShellToolPlugin::description() const +{ + return QString("Py-ChemShell tools"); +} + +/* + * Tool Definition + */ + +// Return button label to use in GUI +QString ChemShellToolPlugin::buttonLabel() const +{ + return QString("ChemShell"); +} + +// Return icon for button in GUI +QIcon ChemShellToolPlugin::buttonIcon() const +{ + return QIcon(":/chemshelltool_icons/icon.svg"); +} + +// Return group name for tool (used to group similar tools together) +QString ChemShellToolPlugin::groupName() const +{ + return QString("ChemShell"); +} + +// Return whether the tool is enabled (appears in the GUI) +bool ChemShellToolPlugin::isEnabled() const +{ + return true; +} + +// Return whether the tool has a dialog +bool ChemShellToolPlugin::hasDialog() const +{ + return true; +} + +// Show the dialog for the tool +bool ChemShellToolPlugin::showDialog() { + + // get the target models + RefList targets; + if (pluginOptions_.value("applyToAll") == "true") { + targets = allModels(); + } else { + targets.add(currentModelOrFrame()); + } + // guess a new filename for the edited model to save + for (RefListItem* ri = targets.first(); ri != NULL; ri = ri->next) { + Model* sourceModel = ri->item; + QString model_filename = sourceModel->filename(); + QFileInfo fileInfo(sourceModel->filename()); + pluginOptions_.add("new_punch", fileInfo.baseName()+QString("_relabelled.pun")); + } + // Check if a dialog actually exists + if (dialog_ == NULL) + { + Messenger::error("No dialog is associated to the tool '%s'\n", qPrintable(name())); + return false; + } + + // Cast the dialog_ pointer into our custom class + ChemShellToolDialog* testToolDialog = (ChemShellToolDialog*) dialog_; + if (!testToolDialog) + { + Messenger::error("Error casting tool dialog into custom class for the tool '%s'\n", qPrintable(name())); + return false; + } + testToolDialog->applyPluginOptions(); + testToolDialog->exec(); + + return true; +} + + +// Select by QM/MM region number ('selecttype ') +bool Commands::function_SelectRegion(CommandNode* c, Bundle& obj, ReturnValue& rv) +{ + if (obj.notifyNull(Bundle::ModelPointer)) return false; + int nselected = obj.rs()->nSelected(); + + QRegExp re("*["+c->argc(0)+"]"); + re.setPatternSyntax(QRegExp::Wildcard); + + obj.rs()->beginUndoState("Select atoms by QM/MM region number"); + for (Atom* i = obj.rs()->atoms(); i != NULL; i = i->next) + { + if (!i->type()) continue; + if (re.exactMatch(i->type()->name())) obj.rs()->selectAtom(i); + } + obj.rs()->endUndoState(); + + rv.set(obj.rs()->nSelected() - nselected); + return true; +} + +void ChemShellToolPlugin::renameKeywords() { + if(pluginOptions_.value("qm_theory") == "GAMESS-UK") { + pluginOptions_.add("qm_theory", "GAMESS_UK"); + } else if(pluginOptions_.value("qm_theory") == "DFTB+") { + pluginOptions_.add("qm_theory", "DFTBplus"); + } + if(pluginOptions_.value("mm_theory") == "DL_POLY 4") { + pluginOptions_.add("mm_theory", "DL_POLY"); + } + if(pluginOptions_.value("mm_ff") == "All-atom CHARMM") { + pluginOptions_.add("mm_ff", "CHARMM"); + } else if(pluginOptions_.value("mm_ff") == "CHARMM22 for proteins") { + pluginOptions_.add("mm_ff", "CHARMM22_prot"); + } else if(pluginOptions_.value("mm_ff") == "CHARMM36 for proteins") { + pluginOptions_.add("mm_ff", "CHARMM36_prot"); + } else if(pluginOptions_.value("mm_ff") == "CHARMM36 for lipids") { + pluginOptions_.add("mm_ff", "CHARMM36_lipid"); + } else if(pluginOptions_.value("mm_ff") == "CHARMM36 for carbonhydrates") { + pluginOptions_.add("mm_ff", "CHARMM36_carb"); + } else if(pluginOptions_.value("mm_ff") == "CHARMM general forcefield") { + pluginOptions_.add("mm_ff", "CHARMM36_cgenff"); + } else if(pluginOptions_.value("mm_ff") == "United-atom for CHARMM") { + pluginOptions_.add("mm_ff", "CHARMM19"); + } else if(pluginOptions_.value("mm_ff") == "All-atom Amber") { + pluginOptions_.add("mm_ff", "AMBER"); + } else if(pluginOptions_.value("mm_ff") == "Amber general forcefield") { + pluginOptions_.add("mm_ff", "AMBER16_gaff"); + } else if(pluginOptions_.value("mm_ff") == "OPLS-AA") { + pluginOptions_.add("mm_ff", "OPLSAA"); + } else if(pluginOptions_.value("mm_ff") == "OPLS_2005") { + pluginOptions_.add("mm_ff", "OPLS2005"); + } else if(pluginOptions_.value("mm_ff") == "OPLS AA/M for proteins") { + pluginOptions_.add("mm_ff", "OPLS_AAM"); + } else if(pluginOptions_.value("mm_ff") == "DREIDING") { + pluginOptions_.add("mm_ff", "DREIDING"); + } else if(pluginOptions_.value("mm_ff") == "Polymer consistent forcefield") { + pluginOptions_.add("mm_ff", "PCFF"); + } else if(pluginOptions_.value("mm_ff") == "Consistent valence forcefield") { + pluginOptions_.add("mm_ff", "CVFF"); + } else if(pluginOptions_.value("mm_ff") == "Gromos united atom G54A7") { + pluginOptions_.add("mm_ff", "G54A7"); + } else if(pluginOptions_.value("mm_ff") == "Inorganic forcefield") { + pluginOptions_.add("mm_ff", "INORGANIC"); + } else if(pluginOptions_.value("mm_ff") == "Inorganic forcefield for binary oxides") { + pluginOptions_.add("mm_ff", "INORGANIC_binary_oxide"); + } else if(pluginOptions_.value("mm_ff") == "Inorganic forcefield for ternary oxides") { + pluginOptions_.add("mm_ff", "INORGANIC_ternary_oxide"); + } else if(pluginOptions_.value("mm_ff") == "Inorganic forcefield for binary halides") { + pluginOptions_.add("mm_ff", "INORGANIC_binary_halide"); + } else if(pluginOptions_.value("mm_ff") == "Inorganic forcefield for glass") { + pluginOptions_.add("mm_ff", "IORGANIC_glass"); + } else if(pluginOptions_.value("mm_ff") == "Inorganic forcefield for clay") { + pluginOptions_.add("mm_ff", "IORGANIC_glass"); + } else if(pluginOptions_.value("mm_ff") == "Multiple potential") { + pluginOptions_.add("mm_ff", "multiple"); + } + if(pluginOptions_.value("task") == "Single-Point") { + pluginOptions_.add("task", "SP"); + } else if(pluginOptions_.value("task") == "Geometry Optimisation") { + pluginOptions_.add("task", "Opt"); + } else if(pluginOptions_.value("task") == "Molecular Dynamics") { + pluginOptions_.add("task", "MD"); + } else if(pluginOptions_.value("task") == "Charge Fitting") { + pluginOptions_.add("task", "ChargeFitting"); + } else if(pluginOptions_.value("task") == "Scan") { + pluginOptions_.add("task", "Scan"); + } else if(pluginOptions_.value("task") == "Parameterisation") { + pluginOptions_.add("task", "Parameterise"); + } + if(pluginOptions_.value("qmmm_embedding") == "Electrostatical") { + pluginOptions_.add("qmmm_embedding", "electrostatic"); + } else if(pluginOptions_.value("qmmm_embedding") == "Mechanical") { + pluginOptions_.add("qmmm_embedding", "mechanical"); + } + if(pluginOptions_.value("qmmm_coupling") == "Covalent") { + pluginOptions_.add("qmmm_coupling", "covalent"); + } else if(pluginOptions_.value("qmmm_coupling") == "Ionic") { + pluginOptions_.add("qmmm_coupling", "ionic"); + } + if(pluginOptions_.value("qmmm_scheme") == "Additive") { + pluginOptions_.add("qmmm_scheme", "additive"); + } else if(pluginOptions_.value("qmmm_scheme") == "Subtractive") { + pluginOptions_.add("qmmm_scheme", "subtractive"); + } +} + + +// Run the tool with the current settings +bool ChemShellToolPlugin::runTool() { + + bool ierror; + LineParser parser; + + // Get the target models + RefList targets; + if (pluginOptions_.value("applyToAll") == "true") { + targets = allModels(); + } else { + targets.add(currentModelOrFrame()); + } + + // it seems all buttons should function via the runTool() function + // rename the selected atoms by attaching the given character(s) + bool relabel_ = pluginOptions_.value("_relabel") == "true"; + if(relabel_) { + + for (RefListItem* ri = targets.first(); ri != NULL; ri = ri->next) { + Model* sourceModel = ri->item; + const int nselected = sourceModel->nSelected(); + Atom* selected[nselected]; + if(nselected == 0) { + Messenger::print("\nNo atoms yet selected\n"); + } else { + if(sourceModel->selectedAtoms(nselected, selected)) { + for(int i=0; iatom(selected[i]->id()); + if(iatom->type() != NULL) { + + // regular expression for existing labels + QRegularExpression re_qt5(pluginOptions_.value("regex")); + QRegExp re_qt4(pluginOptions_.value("regex")); + + QString newtype; + // if checkbox is ticked + if(pluginOptions_.value("replace_suffix") == "true") { + if(re_qt5.isValid()) { + newtype = iatom->type()->name(); + newtype.replace(re_qt5, pluginOptions_.value("type_suffix")); + } else if(re_qt4.isValid()) { + newtype = iatom->type()->name().replace(re_qt4, pluginOptions_.value("type_suffix")); + } else { + Messenger::print(QString("Error: invalid regular expression: "+pluginOptions_.value("regex"))); + } + } else { + newtype = iatom->type()->name()+pluginOptions_.value("type_suffix"); + } + Messenger::print(QString("renamed atom %1's type \"%2\" to \"%3\"").arg(selected[i]->id()).arg(iatom->type()->name()).arg(newtype)); + // everytime create a new FFA type since in Aten an FFA type is shared by multiple atoms (then associate unselected atoms' type are also changed) + ForcefieldAtom* ffa = sourceModel->addAtomName(iatom->element(), newtype); + sourceModel->setAtomType(iatom, ffa, false); + } else { + Messenger::print(QString("Cannot rename type of atom %1").arg(selected[i]->id())); + } + } + } else { + Messenger::print("\nInvalid selection\n"); + } + } + + // write to punch + const FilePluginInterface* plugin = pluginStore_->findFilePluginByNickname(PluginTypes::ModelFilePlugin, PluginTypes::ExportPlugin, QString("chemshell")); + if(plugin != NULL) { + FilePluginInterface* pluginInterface = (FilePluginInterface*) plugin->duplicate(); + if(!pluginInterface->openOutput(pluginOptions_.value("new_punch"))) { + Messenger::print("\nChemShell cannot open file %s to write\n", pluginOptions_.value("new_punch").toUtf8().constData()); + Messenger::exit("ChemShellToolPlugin::runTool"); + return false; + } + KVMap IOPluginOptions; + IOPluginOptions.add("py-chemsh_input", "false"); + pluginInterface->setParentModel(sourceModel); + pluginInterface->setOptions(IOPluginOptions); + if(!pluginInterface->exportData()) { + sourceModel->setFilename(pluginOptions_.value("new_punch")); + sourceModel->setPlugin(pluginInterface); + sourceModel->updateSavePoint(); + pluginInterface->closeFiles(); + } + } + } + // Update the display + emit(updateWidgets(0)); + return true; + + } else { + + bool selected_as_qm = pluginOptions_.value("selected_as_qm") == "true"; + bool labelled_as_qm = pluginOptions_.value("labelled_as_qm") == "true"; + bool radius_as_qm = pluginOptions_.value("radius_as_qm") == "true"; + + KVMap IOPluginOptions; + IOPluginOptions.add("py-chemsh_input", "true"); + + // Loop over targets + for(RefListItem* ri = targets.first(); ri != NULL; ri = ri->next) { + + Model* sourceModel = ri->item; + const int nselected = sourceModel->nSelected(); + Atom* selected[nselected]; + QString qm_region = ""; + // only for QM/MM and ticked option + if(pluginOptions_.value("theory") == "QM/MM") { + qm_region.append("qm_region = "); + // selection + if(pluginOptions_.value("selected_as_qm") == "true") { + if(nselected == 0) { + Messenger::print("\nNo atoms yet selected\n"); + qm_region.append("[]\n"); + } else { + if(sourceModel->selectedAtoms(nselected, selected)) { + qm_region.append("[ "); + for(int i=0; iatom(selected[i]->id()); + QString s = QString::number(selected[i]->id()); + qm_region.append(s); + qm_region.append(", "); + } + // the last selected atom + QString s = QString::number(selected[nselected-1]->id()); + qm_region.append(s); + qm_region.append(" ]\n\n"); + } else { + qm_region.append("[]\n"); + } + } + } + if(pluginOptions_.value("labelled_as_qm") == "true") { + qm_region.append(QString("my_frag.getRegion(%1)\n").arg(pluginOptions_.value("qm_label"))); + } + if(pluginOptions_.value("radius_as_qm") == "true") { + qm_region.append(QString("my_frag.selectByRadius(%1, centre=None, unit='a.u.')\n").arg(pluginOptions_.value("qm_radius"))); + } + } + // pass to io_chemshell + IOPluginOptions.add("_qm_region", qm_region); + + // rename items to Py-ChemShell names + renameKeywords(); + + // fragment + QString frag_strbuff = ""; + frag_strbuff.append(QString("my_frag = Fragment(coords='%1')\n\n").arg(pluginOptions_.value("new_punch"))); + // pass to io_chemshell + IOPluginOptions.add("_frag", frag_strbuff); + + // theory + QString strbuff = ""; + + // QM + QString qm_method_strbuff = ""; + strbuff.append("qm_charge = int(my_frag.totalcharge)\n\n"); + // indentation + QString qm_offset = QString(" ").repeated(pluginOptions_.value("qm_theory").length() + 9); + if(pluginOptions_.value("qm_method") == "DFT") { + qm_method_strbuff.append("'dft',\n"); + qm_method_strbuff.append(QString("%1functional='%2',\n").arg(qm_offset).arg(pluginOptions_.value("qm_functional"))); + } else if(pluginOptions_.value("qm_method") == "HF") { + qm_method_strbuff.append("'hf',\n"); + } + qm_method_strbuff.append(QString("%1basis='%2',\n").arg(qm_offset).arg(pluginOptions_.value("qm_basis"))); + qm_method_strbuff.append(QString("%1direct=True,\n").arg(qm_offset)); + qm_method_strbuff.append(QString("%1ecp='',\n").arg(qm_offset)); + qm_method_strbuff.append(QString("%1harmonic=False,\n").arg(qm_offset)); + qm_method_strbuff.append(QString("%1mult=1,\n").arg(qm_offset)); + qm_method_strbuff.append(QString("%1charge=qm_charge,\n").arg(qm_offset)); + qm_method_strbuff.append(QString("%1scftype='rhf',\n").arg(qm_offset)); + qm_method_strbuff.append(QString("%1maxiter=100)\n\n").arg(qm_offset)); + + // MM + QString mm_method_strbuff = ""; + if(pluginOptions_.value("mm_ff_custom") == "false" && pluginOptions_.value("theory") != "QM") { + strbuff.append(QString("my_ff = DL_FIELD(ff='%1')\n\n").arg(pluginOptions_.value("mm_ff"))); + mm_method_strbuff.append(QString("my_ff")); + } else { + mm_method_strbuff.append(pluginOptions_.value("mm_ff")); + } + + // + QString my_theory = ""; + if(pluginOptions_.value("theory") == "QM/MM") { + my_theory.append("my_qmmm"); + strbuff.append(QString("my_qm = %1(method=%2").arg(pluginOptions_.value("qm_theory")).arg(qm_method_strbuff)); + strbuff.append(QString("my_mm = %1(ff='%2')\n\n").arg(pluginOptions_.value("mm_theory")).arg(pluginOptions_.value("mm_ff"))); + strbuff.append("my_qmmm = QMMM(frag=my_frag,\n"); + strbuff.append(" qm_regiom=qm_region,\n"); + strbuff.append(" qm=my_qm,\n"); + strbuff.append(" mm=my_mm,\n"); + strbuff.append(" separate_ecps=False,\n"); + strbuff.append(QString(" embeddig='%1',\n").arg(pluginOptions_.value("qmmm_embedding"))); + strbuff.append(QString(" coupling='%1',\n").arg(pluginOptions_.value("qmmm_coupling"))); + strbuff.append(QString(" scheme='%1')\n\n").arg(pluginOptions_.value("qmmm_scheme"))); + QString model_filename = sourceModel->filename(); + QFileInfo fileInfo(sourceModel->filename()); + strbuff.append(QString("my_qmmm.qm.frag.save('%1')\n\n").arg(fileInfo.baseName()+QString("_partitioned_qm_only.pun"))); + } else if(pluginOptions_.value("theory") == "QM") { + my_theory.append("my_qm"); + strbuff.append(QString("my_qm = %1(method=%2").arg(pluginOptions_.value("qm_theory")).arg(qm_method_strbuff)); + } else if(pluginOptions_.value("theory") == "MM") { + my_theory.append("my_mm"); + strbuff.append(QString("my_mm = %1(ff='%2')\n\n").arg(pluginOptions_.value("mm_theory")).arg(mm_method_strbuff)); + } + // pass to io_chemshell + IOPluginOptions.add("_theory", strbuff); + + // task + QString task_strbuff = ""; + QString task_offset = QString(" ").repeated(pluginOptions_.value("task").length() + 11); + QString opt_strbuff = ""; + if(pluginOptions_.value("task") == "Opt") { + opt_strbuff.append(",\n"); + opt_strbuff.append(QString("%1active_region=my_frag.selectByRadius(%2, centre=None, unit='a.u.')").arg(task_offset).arg(pluginOptions_.value("active_radius"))); + } + task_strbuff.append(QString("my_task = %1(theory=%2,\n").arg(pluginOptions_.value("task")).arg(my_theory)); + task_strbuff.append(QString("%1dump=5,\n").arg(task_offset)); + task_strbuff.append(QString("%1restart=False%2)\n\n").arg(task_offset).arg(opt_strbuff)); + // pass to io_chemshell + IOPluginOptions.add("_task", task_strbuff); + + // get a handle of io_chemshell as the current tool plugin has no access to I/O + const FilePluginInterface* plugin = pluginStore_->findFilePluginByNickname(PluginTypes::ModelFilePlugin, PluginTypes::ExportPlugin, QString("chemshell")); + QString filename = pluginOptions_.value("filename"); + if(plugin != NULL) { + + // cast const pointer to pointer + FilePluginInterface* pluginInterface = (FilePluginInterface*) plugin->duplicate(); + if(!pluginInterface->openOutput(filename)) { + Messenger::print("\nChemShell cannot open file %s to write\n", filename.toUtf8().constData()); + Messenger::exit("ChemShellToolPlugin::runTool"); + return false; + } + + pluginInterface->setOptions(IOPluginOptions); + if(pluginInterface->exportData()) { + ri->item->setFilename(filename); + ri->item->setPlugin(pluginInterface); + ri->item->updateSavePoint(); + pluginInterface->closeFiles(); + } + + } else { + printf("\n### plugin == NULL\n"); + } + + } + + } + + // Update the display + emit(updateWidgets(0)); + return true; +} + +// Return interface as QObject +QObject* ChemShellToolPlugin::object() { + return this; +} diff --git a/src/plugins/tool_chemshell/chemshelltool_icons.qrc b/src/plugins/tool_chemshell/chemshelltool_icons.qrc new file mode 100644 index 000000000..bd70ff8c2 --- /dev/null +++ b/src/plugins/tool_chemshell/chemshelltool_icons.qrc @@ -0,0 +1,5 @@ + + + icon.svg + + diff --git a/src/plugins/tool_chemshell/chemshelltooldialog.h b/src/plugins/tool_chemshell/chemshelltooldialog.h new file mode 100644 index 000000000..9960f9353 --- /dev/null +++ b/src/plugins/tool_chemshell/chemshelltooldialog.h @@ -0,0 +1,97 @@ +/* + *** ChemShell Tool Dialog + *** src/plugins/tool_chemshell/chemshelltooldialog.h + Copyright T. Youngs 2007-2018 + + This file is part of Aten. + + Aten is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Aten is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Aten. If not, see . +*/ + +#ifndef ATEN_RINGSTOOLDIALOG_H +#define ATEN_RINGSTOOLDIALOG_H + +#include "base/kvmap.h" +#include "plugins/interfaces/toolplugin.h" +#include "plugins/tool_chemshell/ui_chemshelltooldialog.h" + + +// Forward Declarations (Qt) +#include "gui/mainwindow.h" +#include "main/aten.h" + +ATEN_USING_NAMESPACE + +// Forward Declarations (Aten) +/* None */ + +// ChemShell Tool Dialog +class ChemShellToolDialog : public QDialog +{ + // All Qt declarations derived from QObject must include this macro + Q_OBJECT + + public: + // Constructor + ChemShellToolDialog(ToolPluginInterface& targetInterface, KVMap& pluginOptions); + // Main form declaration + Ui::ChemShellToolDialog ui; + + private: + // Reference to the source plugin calling the dialog + ToolPluginInterface& targetInterface_; + // Reference to KVMap of plugin options stored in plugin + KVMap& pluginOptions_; + + /* + * Widget Functions + */ + private slots: + // Cancel / OK buttons + void on_RunButton_clicked(bool checked); + void on_CloseButton_clicked(bool checked); + void on_RelabelButton_clicked(bool checked); + void switchTheories(int index); + void switchQMMethods(int index); + void chooseActiveRadius(int index); + void setCustomFF(); + void unsetCustomFF(int index); + void selectedQMRegion(bool toggled); + void labelledQMRegion(bool toggled); + void radiusQMRegion(bool toggled); + + private: + // Set plugin options from UI controls + void setPluginOptions(); + void addQMMMItems(); + void addQMItems(); + void addQMFunctionalItems(); + void addMMItems(); + void clearQMMMItems(); + void clearQMItems(); + void clearMMItems(); + void clearQMFunctionalItems(); + void clearItems(); + + public: + // Apply plugin options to UI controls + void applyPluginOptions(); + + // return a the referencto to AtenWindow + AtenWindow& getAtenWindow(); + Aten& getAten(); + +}; + +#endif diff --git a/src/plugins/tool_chemshell/chemshelltooldialog.ui b/src/plugins/tool_chemshell/chemshelltooldialog.ui new file mode 100644 index 000000000..4318d85f1 --- /dev/null +++ b/src/plugins/tool_chemshell/chemshelltooldialog.ui @@ -0,0 +1,603 @@ + + + + +ChemShellToolDialog + + + + 0 + 0 + 792 + 414 + + + + + 8 + + + + ChemShell Tool + + + + :/chemshelltool_icons/icon.svg:/chemshelltool_icons/icon.svg + + + + 4 + + + 4 + + + 4 + + + 4 + + + + + This tool helps generate a template input script for Py-ChemShell + + + true + + + + + + + Py-ChemShell is a computational chemistry environment: www.chemshell.org (J. Chem. Theory Comput. 2019, 15, 1317-1328) + + + true + + + + + + + + + + + + 1 + 0 + + + + Specify a filename for input script: + + + + + + + + 1 + 0 + + + + my_input.py + + + + + + + + + Relabel selected atoms by attaching: + + + true + + + + + + + Replace existing labels: + + + Tick to replace with given new label if selected atoms are already labelled (e.g., "O2" will become "O1", given 1). Specified label will be directly attached to the end if this option is unticked (e.g, "O2" will become "O21", given 1). + + + + 145 + 30 + + + + + + + + + + + + + + + 1 + 1 + + + + 1 + + + + 140 + 30 + + + + Typically a region label is an integer to be attached to atoms' names (e.g., "O" will be labelled as "O1", given 1). + + + + + + + + 1 + 1 + + + + [0-9]+ + + + + 140 + 30 + + + + Optional: define your own regular expression for existing region label to replace. default: digits (i.e., "123" from "O_123" will be replaced). Either Qt4 or Qt5 is supported. + + + + + + + + + + + + + And save to: + + + true + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 1 + 1 + + + + + 280 + 30 + + + + Specify a filename to save the edited model. This will be used as the input fragment for your Py-ChemShell script to generate (by clicking the "Save" button below). + + + + + + + + + + + + 250 + 30 + + + + + + + + + 75 + true + + + + &Click to Relabel and Save + + + false + + + true + + + false + + + Relabelling can be done multiple times and the saved punch file contains the final form. + + + + 150 + 30 + + + + + 1 + 0 + + + + + + + + + + + + + + Select theory: + + + + + + + + 1 + 0 + + + + Select QM theory: + + + + + + + + 1 + 0 + + + + Select MM theory: + + + + + + + QComboBox::AdjustToContentsOnFirstShow + + + + + + + QComboBox::AdjustToContentsOnFirstShow + + + + + + + QComboBox::AdjustToContentsOnFirstShow + + + + + + + Select embedding method: + + + + + + + Select QM method: + + + + + + + Select forcefield: + + + + + + + QComboBox::AdjustToContentsOnFirstShow + + + + + + + QComboBox::AdjustToContentsOnFirstShow + + + + + + + QComboBox::AdjustToContentsOnFirstShow + + + true + + + Input your forcefield filename or choose a predefined scheme to let DL_FIELD generate the forcefield. + + + + + + + Select coupling method: + + + + + + + Select DFT functional: + + + + + + + QComboBox::AdjustToContentsOnFirstShow + + + + + + + QComboBox::AdjustToContentsOnFirstShow + + + true + + + Input your functional name or choose one from the list. + + + + + + + Select scheme: + + + + + + + Select basis set: + + + + + + + QComboBox::AdjustToContentsOnFirstShow + + + + + + + QComboBox::AdjustToContentsOnFirstShow + + + true + + + Input your basis set filename or choose a predefined one from the list. + + + + + + + Select the task: + + + + + + + Choose active region's radius (a.u.): + + + + + + + QComboBox::AdjustToContentsOnFirstShow + + + + + + + + + + + + Way to define QM region: + + + + + + + Selected atoms + + + + + + + Atoms labelled with + + + + + + + + 1 + 0 + + + + 1 + + + + 140 + 30 + + + + + + + + Atoms within radius (a.u.) + + + + + + + + + + + + Qt::Horizontal + + + + 37 + 24 + + + + + + + + + + + + Qt::Horizontal + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 75 + true + + + + &Save + + + false + + + true + + + + + + + + 75 + true + + + + &Close + + + false + + + true + + + + + + + + + + TPlotWidget + QWidget +
gui/qcustomplot/tplotwidget.hui
+ 1 +
+
+ + + +
diff --git a/src/plugins/tool_chemshell/chemshelltooldialog_funcs.cpp b/src/plugins/tool_chemshell/chemshelltooldialog_funcs.cpp new file mode 100644 index 000000000..f8577b141 --- /dev/null +++ b/src/plugins/tool_chemshell/chemshelltooldialog_funcs.cpp @@ -0,0 +1,309 @@ +/* + *** SPRings Tool Dialog Functions + *** src/gui/tool_chemshell/chemshelltooldialog_funcs.cpp + Copyright T. Youngs 2007-2018 + + This file is part of Aten. + + Aten is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Aten is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Aten. If not, see . +*/ + +#include "plugins/tool_chemshell/chemshelltooldialog.h" +#include "gui/qcustomplot/qcustomplot.hui" + +// Constructor +ChemShellToolDialog::ChemShellToolDialog(ToolPluginInterface& targetInterface, + KVMap& pluginOptions + ) : QDialog(NULL), + targetInterface_(targetInterface), + pluginOptions_(pluginOptions) +{ + ui.setupUi(this); + + // Initialise the icon resource + Q_INIT_RESOURCE(chemshelltool_icons); + +} + +/* + * Widget Functions + */ + +void ChemShellToolDialog::on_CloseButton_clicked(bool checked) { + // Close the dialog, storing UI options before we close + setPluginOptions(); + accept(); + clearItems(); +} + +void ChemShellToolDialog::on_RunButton_clicked(bool checked) { + // Set options before we call the run method + setPluginOptions(); + pluginOptions_.add("_relabel", "false"); + targetInterface_.runTool(); +} + +void ChemShellToolDialog::on_RelabelButton_clicked(bool checked) { + setPluginOptions(); + pluginOptions_.add("_relabel", "true"); + targetInterface_.runTool(); +} + + +void ChemShellToolDialog::clearItems() { + ui.theory->clear(); + ui.task->clear(); + clearQMMMItems(); + clearQMItems(); + clearMMItems(); +} + +void ChemShellToolDialog::addQMFunctionalItems() { + ui.qm_functional->addItem("BLYP"); + ui.qm_functional->addItem("B3LYP"); + ui.qm_functional->addItem("LDA"); + ui.qm_functional->setEditable(true);; +} + +void ChemShellToolDialog::clearQMFunctionalItems() { + ui.qm_functional->clear(); +} + +void ChemShellToolDialog::addQMMMItems() { + clearQMMMItems(); + ui.qmmm_embedding->addItem("Electrostatical"); + ui.qmmm_embedding->addItem("Mechanical"); + ui.qmmm_coupling->addItem("Covalent"); + ui.qmmm_coupling->addItem("Ionic"); + ui.qmmm_scheme->addItem("Additive"); + ui.qmmm_scheme->addItem("Subtractive"); + ui.qm_radius->setRange(0.0, 99.99); + ui.qm_radius->setValue(15.0); +} + +void ChemShellToolDialog::addQMItems() { + clearQMItems(); + ui.qm_theory->addItem("NWChem"); + ui.qm_theory->addItem("GAMESS-UK"); + ui.qm_theory->addItem("ORCA"); + ui.qm_theory->addItem("LSDalton"); + ui.qm_theory->addItem("DFTB+"); + ui.qm_theory->addItem("CP2K"); + ui.qm_basis->addItem("STO-3G"); + ui.qm_basis->addItem("3-21G"); + ui.qm_basis->addItem("3-21G*"); + ui.qm_basis->addItem("6-31G*"); + ui.qm_basis->addItem("TZVP"); + ui.qm_basis->addItem("def2-SVP"); + ui.qm_basis->addItem("def2-TZVP"); + ui.qm_basis->setEditable(true);; + ui.qm_method->addItem("HF"); + ui.qm_method->addItem("DFT"); + ui.qm_basis->setCurrentIndex(2); + ui.qm_method->setCurrentIndex(0); +} + +void ChemShellToolDialog::addMMItems() { + clearMMItems(); + ui.mm_theory->addItem("DL_POLY 4"); + ui.mm_theory->addItem("GULP"); + ui.mm_ff->addItem("All-atom CHARMM"); + ui.mm_ff->addItem("CHARMM22 for proteins"); + ui.mm_ff->addItem("CHARMM36 for proteins"); + ui.mm_ff->addItem("CHARMM36 for lipids"); + ui.mm_ff->addItem("CHARMM36 for carbonhydrates"); + ui.mm_ff->addItem("CHARMM general forcefield"); + ui.mm_ff->addItem("United-atom for CHARMM"); + ui.mm_ff->addItem("All-atom Amber"); + ui.mm_ff->addItem("Amber general forcefield"); + ui.mm_ff->addItem("OPLS-AA"); + ui.mm_ff->addItem("OPLS_2005"); + ui.mm_ff->addItem("OPLS AA/M for proteins"); + ui.mm_ff->addItem("DREIDING"); + ui.mm_ff->addItem("Polymer consistent forcefield"); + ui.mm_ff->addItem("Consistent valence forcefield"); + ui.mm_ff->addItem("Gromos united atom G54A7"); + ui.mm_ff->addItem("Inorganic forcefield"); + ui.mm_ff->addItem("Inorganic forcefield for binary oxides"); + ui.mm_ff->addItem("Inorganic forcefield for ternary oxides"); + ui.mm_ff->addItem("Inorganic forcefield for binary halides"); + ui.mm_ff->addItem("Inorganic forcefield for glass"); + ui.mm_ff->addItem("Inorganic forcefield for clay"); + ui.mm_ff->addItem("Multiple potential"); + ui.mm_ff->setEditable(true);; +} + +void ChemShellToolDialog::clearQMMMItems() { + ui.qmmm_embedding->clear(); + ui.qmmm_coupling->clear(); + ui.qmmm_scheme->clear(); +} + +void ChemShellToolDialog::clearQMItems() { + ui.qm_theory->clear(); + ui.qm_basis->clear(); + ui.qm_functional->clear(); + ui.qm_method->clear(); + ui.qm_basis->setEditable(false);; + ui.qm_functional->setEditable(false);; +} + +void ChemShellToolDialog::clearMMItems() { + ui.mm_theory->clear(); + ui.mm_ff->clear(); + ui.mm_ff->setEditable(false);; +} + +// Apply plugin options to UI controls +void ChemShellToolDialog::applyPluginOptions() { + pluginOptions_.add("mm_ff_custom", "false"); + ui.selected_as_qm->setChecked(pluginOptions_.value("selected_as_qm") == "true"); + ui.replace_suffix->setChecked(pluginOptions_.value("replace_suffix") == "true"); + ui.theory->addItem("QM/MM"); + ui.theory->addItem("QM"); + ui.theory->addItem("MM"); + addQMMMItems(); + addQMItems(); + addMMItems(); + ui.task->addItem("Single-Point"); + ui.task->addItem("Geometry Optimisation"); + ui.task->addItem("Molecular Dynamics"); + ui.task->addItem("Charge Fitting"); + ui.task->addItem("Scan"); + ui.task->addItem("Parameterisation"); + ui.active_radius->setRange(0.0, 99.99); + ui.active_radius->setValue(15.0); + ui.new_punch->setText(pluginOptions_.value("new_punch")); + chooseActiveRadius(ui.task->currentIndex()); + selectedQMRegion(true); + + connect(ui.theory , SIGNAL(currentIndexChanged(int)), this, SLOT(switchTheories(int))); + connect(ui.qm_method, SIGNAL(currentIndexChanged(int)), this, SLOT(switchQMMethods(int))); + connect(ui.task , SIGNAL(currentIndexChanged(int)), this, SLOT(chooseActiveRadius(int))); + connect(ui.mm_ff , SIGNAL(editTextChanged(const QString)), this, SLOT(setCustomFF())); + connect(ui.mm_ff , SIGNAL(currentIndexChanged(int)), this, SLOT(unsetCustomFF(int))); + connect(ui.labelled_as_qm, SIGNAL(toggled(bool)), this, SLOT(labelledQMRegion(bool))); + connect(ui.selected_as_qm, SIGNAL(toggled(bool)), this, SLOT(selectedQMRegion(bool))); + connect(ui.radius_as_qm , SIGNAL(toggled(bool)), this, SLOT(radiusQMRegion(bool))); +} + + +void ChemShellToolDialog::selectedQMRegion(bool toggled) { + if(toggled) { + ui.qm_label->setDisabled(true); + ui.qm_radius->setDisabled(true); + } +} + +void ChemShellToolDialog::labelledQMRegion(bool toggled) { + if(toggled) { + ui.qm_label->setDisabled(false); + ui.qm_radius->setDisabled(true); + } +} + +void ChemShellToolDialog::radiusQMRegion(bool toggled) { + if(toggled) { + ui.qm_label->setDisabled(true); + ui.qm_radius->setDisabled(false); + } +} + +void ChemShellToolDialog::unsetCustomFF(int) { + pluginOptions_.add("mm_ff_custom", "false"); +} + +void ChemShellToolDialog::setCustomFF() { + pluginOptions_.add("mm_ff_custom", "true"); +} + +void ChemShellToolDialog::chooseActiveRadius(int index) { + + if(index == 1 || index == 2) { + ui.active_radius->setRange(0.0, 99.99); + ui.active_radius->setValue(15.0); + } else { + ui.active_radius->setRange(0.0, 0.0); + } + +} + +void ChemShellToolDialog::switchQMMethods(int index) { + clearQMFunctionalItems(); + // DFT + if(index == 1) { + addQMFunctionalItems(); + } +} + +void ChemShellToolDialog::switchTheories(int index) { + clearQMMMItems(); + clearQMItems(); + clearMMItems(); + // if QM selected + if(index == 1) { + addQMItems(); + // if MM selected + } else if(index == 2) { + addMMItems(); + // if QM/MM selected + } else { + addQMMMItems(); + addQMItems(); + addMMItems(); + } + + +// QComboBox *combo1 = new QComboBox; +// QComboBox *combo2 = new QComboBox; +// if (sender() == combo1) +// { +// combo2->blockSignals(true); +// combo2->setCurrentIndex(index); +// combo2->blockSignals(false); +// } +// else if (sender() == combo2) +// { +// combo1->blockSignals(true); +// combo1->setCurrentIndex(index); +// combo1->blockSignals(false); +// } +} + +// Set plugin options from UI controls +void ChemShellToolDialog::setPluginOptions() +{ + pluginOptions_.add("selected_as_qm", ui.selected_as_qm->isChecked() ? "true" : "false"); + pluginOptions_.add("labelled_as_qm", ui.labelled_as_qm->isChecked() ? "true" : "false"); + pluginOptions_.add("radius_as_qm" , ui.radius_as_qm->isChecked() ? "true" : "false"); + pluginOptions_.add("qm_label" , ui.qm_label->text()); + pluginOptions_.add("qm_radius" , QString::number(ui.qm_radius->value(), 'f', 2)); + pluginOptions_.add("replace_suffix", ui.replace_suffix->isChecked() ? "true" : "false"); + pluginOptions_.add("theory" , ui.theory->currentText()); + pluginOptions_.add("qmmm_embedding", ui.qmmm_embedding->currentText()); + pluginOptions_.add("qmmm_coupling" , ui.qmmm_coupling->currentText()); + pluginOptions_.add("qmmm_scheme" , ui.qmmm_scheme->currentText()); + pluginOptions_.add("qm_theory" , ui.qm_theory->currentText()); + pluginOptions_.add("qm_method" , ui.qm_method->currentText()); + pluginOptions_.add("qm_basis" , ui.qm_basis->currentText()); + pluginOptions_.add("qm_functional" , ui.qm_functional->currentText()); + pluginOptions_.add("mm_theory" , ui.mm_theory->currentText()); + pluginOptions_.add("mm_ff" , ui.mm_ff->currentText()); + pluginOptions_.add("task" , ui.task->currentText()); + pluginOptions_.add("active_radius" , QString::number(ui.active_radius->value(), 'f', 2)); + pluginOptions_.add("type_suffix" , ui.type_suffix->text()); + pluginOptions_.add("new_punch" , ui.new_punch->text()); + pluginOptions_.add("regex" , ui.regex->text()); + pluginOptions_.add("filename" , ui.filename->text()); +} diff --git a/src/plugins/tool_chemshell/icon.svg b/src/plugins/tool_chemshell/icon.svg new file mode 100644 index 000000000..713a5f24f --- /dev/null +++ b/src/plugins/tool_chemshell/icon.svg @@ -0,0 +1,218 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + +