1 /******************************************************************************
2
3 This source file is part of the Avogadro project.
4
5 Copyright 2018 Kitware, Inc.
6
7 This source code is released under the New BSD License, (the "License").
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14
15 ******************************************************************************/
16
17 #include "openmminputdialog.h"
18
19 #include <avogadro/core/atom.h>
20 #include <avogadro/core/bond.h>
21 #include <avogadro/core/elements.h>
22
23 #include <avogadro/io/fileformat.h>
24 #include <avogadro/io/fileformatmanager.h>
25
26 #include <avogadro/qtgui/molecule.h>
27
28 #include <QtWidgets/QFileDialog>
29 #include <QtWidgets/QMessageBox>
30 #include <QtWidgets/QTextEdit>
31
32 #include <QtCore/QDebug>
33 #include <QtCore/QDir>
34 #include <QtCore/QFile>
35 #include <QtCore/QHash>
36 #include <QtCore/QPointer>
37 #include <QtCore/QString>
38 #include <QtCore/QTextStream>
39
40 namespace Avogadro {
41 namespace QtPlugins {
42
OpenMMInputDialog(QWidget * parent,Qt::WindowFlags flag)43 OpenMMInputDialog::OpenMMInputDialog(QWidget* parent, Qt::WindowFlags flag)
44 : QDialog(parent, flag), m_molecule(nullptr),
45
46 m_forceFieldType(amber99sbildn), m_title("Title"), m_savePath(""),
47 m_waterModelType(tip3p), m_nonBondedType(PME),
48
49 m_constraintType(HBonds), m_integratorType(Langevin),
50 m_barostatType(NoBarostat),
51
52 m_deviceIndex(1), m_openclPlatformIndex(1), m_rigidWater(0),
53 m_temperature(298.15), m_generationTemperature(298.15),
54 m_nonBondedCutoff(1.0),
55
56 m_timeStep(2.0), m_ewaldTolerance(0.0005), m_constraintTolerance(0.00001),
57 m_reportInterval(1000), m_equilibriationSteps(100), m_productionSteps(1000),
58 m_errorTolerance(0.0001), m_collisionRate(1.0), m_pressure(1.0),
59 m_barostatInterval(25),
60
61 m_dumpStep(1),
62
63 m_velocityDistRandom(0), m_platformType(CUDA),
64 m_precisionType(mixedPrecision), m_thermoInterval(50),
65
66 m_minimize(0), m_minimizeSteps(1000), m_DCDReporter(true),
67 m_PDBReporter(false), m_stateDataReporter(true),
68
69 m_output(), m_dirty(false), m_warned(false), readData(false),
70
71 m_jobEdit(nullptr), m_moleculeEdit(nullptr)
72 {
73 ui.setupUi(this);
74 m_jobFileName =
75 (ui.jobScriptEdit->text().isEmpty() ? ui.jobScriptEdit->placeholderText()
76 : ui.jobScriptEdit->text()) +
77 ".py";
78 m_inputCoordFileName =
79 (ui.inputCoordEdit->text().isEmpty() ? ui.inputCoordEdit->placeholderText()
80 : ui.inputCoordEdit->text());
81 m_topologyFileName =
82 (ui.inputTopEdit->text().isEmpty() ? ui.inputTopEdit->placeholderText()
83 : ui.inputTopEdit->text());
84
85 // Connect the GUI elements to the correct slots
86 connect(ui.jobScriptEdit, SIGNAL(textChanged(QString)), this,
87 SLOT(setScriptName()));
88 connect(ui.inputCoordEdit, SIGNAL(textChanged(QString)), this,
89 SLOT(setInputCoordName()));
90 connect(ui.forceFieldCombo, SIGNAL(currentIndexChanged(int)), this,
91 SLOT(setForceField(int)));
92 connect(ui.constraintsCombo, SIGNAL(currentIndexChanged(int)), this,
93 SLOT(setConstraintType(int)));
94 connect(ui.waterModelCombo, SIGNAL(currentIndexChanged(int)), this,
95 SLOT(setWaterModelType(int)));
96 connect(ui.nonBondedMethodCombo, SIGNAL(currentIndexChanged(int)), this,
97 SLOT(setNonBondedType(int)));
98 connect(ui.integratorCombo, SIGNAL(currentIndexChanged(int)), this,
99 SLOT(setIntegratorType(int)));
100 connect(ui.barostatCombo, SIGNAL(currentIndexChanged(int)), this,
101 SLOT(setBarostatType(int)));
102 connect(ui.inputTopEdit, SIGNAL(textChanged(QString)), this,
103 SLOT(setTopologyName()));
104 connect(ui.rigidWaterCombo, SIGNAL(currentIndexChanged(int)), this,
105 SLOT(setRigidWater(int)));
106 connect(ui.temperatureSpin, SIGNAL(valueChanged(double)), this,
107 SLOT(setTemperature(double)));
108 connect(ui.generationTemperatureSpin, SIGNAL(valueChanged(double)), this,
109 SLOT(setGenerationTemperature(double)));
110 connect(ui.nonBondedCutoffSpin, SIGNAL(valueChanged(double)), this,
111 SLOT(setNonBondedCutoff(double)));
112 connect(ui.stepSpin, SIGNAL(valueChanged(double)), this,
113 SLOT(setTimeStep(double)));
114 connect(ui.ewaldToleranceSpin, SIGNAL(valueChanged(double)), this,
115 SLOT(setEwaldTolerance(double)));
116 connect(ui.constraintToleranceSpin, SIGNAL(valueChanged(double)), this,
117 SLOT(setConstraintTolerance(double)));
118 connect(ui.reportIntervalSpin, SIGNAL(valueChanged(int)), this,
119 SLOT(setReportInterval(int)));
120 connect(ui.equilibriationStepsSpin, SIGNAL(valueChanged(int)), this,
121 SLOT(setEquilibriationSteps(int)));
122 connect(ui.productionStepsSpin, SIGNAL(valueChanged(int)), this,
123 SLOT(setProductionSteps(int)));
124 connect(ui.deviceIndexSpin, SIGNAL(valueChanged(int)), this,
125 SLOT(setDeviceIndex(int)));
126 connect(ui.openCLIndexSpin, SIGNAL(valueChanged(int)), this,
127 SLOT(setOpenCLPlatformIndex(int)));
128 connect(ui.errorTolSpin, SIGNAL(valueChanged(double)), this,
129 SLOT(setErrorTolerance(double)));
130 connect(ui.collisionRateSpin, SIGNAL(valueChanged(double)), this,
131 SLOT(setCollisionRate(double)));
132 connect(ui.pressureSpin, SIGNAL(valueChanged(double)), this,
133 SLOT(setPressure(double)));
134 connect(ui.barostatIntervalSpin, SIGNAL(valueChanged(int)), this,
135 SLOT(setBarostatInterval(int)));
136 connect(ui.minimizeCombo, SIGNAL(currentIndexChanged(int)), this,
137 SLOT(setMinimize(int)));
138 connect(ui.minimizeStepsSpin, SIGNAL(valueChanged(int)), this,
139 SLOT(setMinimizeSteps(int)));
140 connect(ui.initVelCombo, SIGNAL(currentIndexChanged(int)), this,
141 SLOT(setVelocityDistRandom(int)));
142 connect(ui.platformCombo, SIGNAL(currentIndexChanged(int)), this,
143 SLOT(setPlatformType(int)));
144 connect(ui.precisionCombo, SIGNAL(currentIndexChanged(int)), this,
145 SLOT(setPrecisionType(int)));
146 connect(ui.dcdCheck, SIGNAL(toggled(bool)), this, SLOT(setDCDReporter(bool)));
147 connect(ui.pdbCheck, SIGNAL(toggled(bool)), this, SLOT(setPDBReporter(bool)));
148 connect(ui.stateDataCheck, SIGNAL(toggled(bool)), this,
149 SLOT(setStateDataReporter(bool)));
150
151 connect(ui.stepIndexCheck, SIGNAL(toggled(bool)), this,
152 SLOT(setStepIndexBoolean(bool)));
153 connect(ui.timeCheck, SIGNAL(toggled(bool)), this,
154 SLOT(setTimeBoolean(bool)));
155 connect(ui.speedCheck, SIGNAL(toggled(bool)), this,
156 SLOT(setSpeedBoolean(bool)));
157 connect(ui.progressCheck, SIGNAL(toggled(bool)), this,
158 SLOT(setProgressBoolean(bool)));
159 connect(ui.potentialEnergyCheck, SIGNAL(toggled(bool)), this,
160 SLOT(setPotentialEnergyBoolean(bool)));
161 connect(ui.kineticEnergyCheck, SIGNAL(toggled(bool)), this,
162 SLOT(setKineticEnergyBoolean(bool)));
163 connect(ui.totalEnergyCheck, SIGNAL(toggled(bool)), this,
164 SLOT(setTotalEnergyBoolean(bool)));
165 connect(ui.temperatureCheck, SIGNAL(toggled(bool)), this,
166 SLOT(setTemperatureBoolean(bool)));
167 connect(ui.volumeCheck, SIGNAL(toggled(bool)), this,
168 SLOT(setVolumeBoolean(bool)));
169 connect(ui.densityCheck, SIGNAL(toggled(bool)), this,
170 SLOT(setDensityBoolean(bool)));
171
172 connect(ui.generateButton, SIGNAL(clicked()), this, SLOT(generateClicked()));
173 connect(ui.resetButton, SIGNAL(clicked()), this, SLOT(resetClicked()));
174
175 connect(ui.enableFormButton, SIGNAL(clicked()), this,
176 SLOT(enableFormClicked()));
177
178 QSettings settings;
179 readSettings(settings);
180
181 resetClicked();
182
183 // Generate an initial preview of the input deck
184 updatePreviewText();
185 addMoleculeDataTab();
186 }
187
~OpenMMInputDialog()188 OpenMMInputDialog::~OpenMMInputDialog()
189 {
190 QSettings settings;
191 writeSettings(settings);
192 }
193
showEvent(QShowEvent *)194 void OpenMMInputDialog::showEvent(QShowEvent*)
195 {
196 updatePreviewText();
197 addMoleculeDataTab();
198 }
199
updatePreviewText()200 void OpenMMInputDialog::updatePreviewText()
201 {
202 if (!isVisible())
203 return;
204
205 int jobTabPosition = 0;
206
207 // Store the currently displayed tab
208 int currIndex = ui.tabWidget->currentIndex();
209
210 // Generate the input deck and display it
211 if (m_dirty) {
212 QString message =
213 tr("Would you like to update the preview text, losing all "
214 "changes made in the OpenMM input deck preview pane?");
215 int response = QMessageBox::question(
216 this, tr("Overwrite modified input files?"), message,
217 QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
218
219 if (static_cast<QMessageBox::StandardButton>(response) == QMessageBox::No) {
220 return;
221 }
222 }
223
224 ui.tabWidget->removeTab(jobTabPosition);
225
226 m_jobEdit = new QTextEdit(this);
227 m_jobEdit->setObjectName(m_jobFileName);
228 m_jobEdit->setFontFamily("monospace");
229 connect(m_jobEdit, SIGNAL(textChanged()), this, SLOT(textEditModified()));
230 m_jobEdit->setText(generateInputDeck());
231 ui.tabWidget->insertTab(jobTabPosition, m_jobEdit, m_jobFileName);
232 deckDirty(false);
233
234 // Restore current tab
235 ui.tabWidget->setCurrentIndex(currIndex);
236 }
237
addMoleculeDataTab()238 void OpenMMInputDialog::addMoleculeDataTab()
239 {
240 int molTabPosition = 1;
241 if (m_molecule) {
242 ui.tabWidget->removeTab(molTabPosition);
243 std::string molOutput,
244 extension = m_inputCoordFileName.split(".").back().toStdString();
245
246 bool writeSDF = Io::FileFormatManager::instance().writeString(
247 *m_molecule, molOutput, extension);
248 if (writeSDF) {
249 m_moleculeEdit = new QTextEdit(this);
250 m_moleculeEdit->setObjectName(m_inputCoordFileName);
251 m_moleculeEdit->setFontFamily("monospace");
252 m_moleculeEdit->setText(QString::fromStdString(molOutput));
253 ui.tabWidget->insertTab(molTabPosition, m_moleculeEdit,
254 m_inputCoordFileName);
255 }
256 }
257 }
258
textEditModified()259 void OpenMMInputDialog::textEditModified()
260 {
261 if (QTextEdit* edit = qobject_cast<QTextEdit*>(sender())) {
262 if (edit->document()->isModified()) {
263 deckDirty(true);
264 } else {
265 deckDirty(false);
266 }
267 }
268 }
269
resetClicked()270 void OpenMMInputDialog::resetClicked()
271 {
272 // Reset the form to defaults
273 deckDirty(false);
274
275 // 1st subdivision
276 ui.precisionCombo->setCurrentIndex(1);
277 ui.forceFieldCombo->setCurrentIndex(2);
278 ui.waterModelCombo->setCurrentIndex(1);
279 ui.platformCombo->setCurrentIndex(3);
280 setPlatformType(3);
281
282 // 2nd subdivision
283 ui.ewaldToleranceSpin->setValue(0.0005);
284 ui.constraintToleranceSpin->setValue(0.00001);
285 ui.nonBondedCutoffSpin->setValue(1.0);
286 ui.generationTemperatureSpin->setValue(298.15);
287 ui.nonBondedMethodCombo->setCurrentIndex(4);
288 setNonBondedType(4);
289 ui.constraintsCombo->setCurrentIndex(1);
290 setConstraintType(1);
291 ui.rigidWaterCombo->setCurrentIndex(0);
292 setRigidWater(0);
293 ui.initVelCombo->setCurrentIndex(0);
294 setVelocityDistRandom(0);
295
296 // 3rd subdivision
297 ui.stepSpin->setValue(2.0);
298 ui.errorTolSpin->setValue(0.0001);
299 ui.collisionRateSpin->setValue(1.0);
300 ui.temperatureSpin->setValue(298.15);
301 ui.pressureSpin->setValue(1.0);
302 ui.barostatIntervalSpin->setValue(25);
303 ui.barostatCombo->setCurrentIndex(0);
304 setBarostatType(0);
305 ui.integratorCombo->setCurrentIndex(0);
306 setIntegratorType(0);
307
308 // 4th subdivision
309 ui.minimizeCombo->setCurrentIndex(0);
310 ui.reportIntervalSpin->setValue(1000);
311 ui.minimizeStepsSpin->setValue(1000);
312 ui.productionStepsSpin->setValue(1000);
313 ui.equilibriationStepsSpin->setValue(100);
314 ui.stepIndexCheck->setChecked(true);
315 ui.timeCheck->setChecked(false);
316 ui.speedCheck->setChecked(true);
317 ui.progressCheck->setChecked(true);
318 ui.potentialEnergyCheck->setChecked(true);
319 ui.kineticEnergyCheck->setChecked(false);
320 ui.totalEnergyCheck->setChecked(false);
321 ui.temperatureCheck->setChecked(true);
322 ui.volumeCheck->setChecked(false);
323 ui.densityCheck->setChecked(false);
324 // Unfortunately, setChecked() does not emit toggled() signal
325 // So the slots have to be invoked
326 setStepIndexBoolean(true);
327 setTimeBoolean(false);
328 setSpeedBoolean(true);
329 setProgressBoolean(true);
330 setPotentialEnergyBoolean(true);
331 setKineticEnergyBoolean(false);
332 setTotalEnergyBoolean(false);
333 setTemperatureBoolean(true);
334 setVolumeBoolean(false);
335 setDensityBoolean(false);
336
337 ui.stateDataCheck->setChecked(true);
338 ui.dcdCheck->setChecked(true);
339 ui.pdbCheck->setChecked(false);
340
341 updatePreviewText();
342 addMoleculeDataTab();
343 }
344
generateClicked()345 void OpenMMInputDialog::generateClicked()
346 {
347 QSettings settings;
348 QString directory =
349 settings.value("openmmInput/outputDirectory", QDir::homePath()).toString();
350 if (directory.isEmpty())
351 directory = QDir::homePath();
352 directory = QFileDialog::getExistingDirectory(
353 this, tr("Select output directory"), directory);
354
355 // User cancel:
356 if (directory.isNull())
357 return;
358
359 settings.setValue("openmmInput/outputDirectory", directory);
360 QDir dir(directory);
361
362 // Check for problems:
363 QStringList errors;
364 bool fatalError = false;
365
366 do { // Do/while to break on fatal errors
367 if (!dir.exists()) {
368 errors << tr("%1: Directory does not exist!").arg(dir.absolutePath());
369 fatalError = true;
370 break;
371 }
372
373 if (!dir.isReadable()) {
374 errors << tr("%1: Directory cannot be read!").arg(dir.absolutePath());
375 fatalError = true;
376 break;
377 }
378
379 QFileInfo jobFileInfo(dir.absoluteFilePath(m_jobFileName));
380
381 if (jobFileInfo.exists()) {
382 errors << tr("%1: File will be overwritten.")
383 .arg(jobFileInfo.absoluteFilePath());
384 }
385
386 // Attempt to open the file for writing
387 if (!QFile(jobFileInfo.absoluteFilePath()).open(QFile::WriteOnly)) {
388 errors
389 << tr("%1: File is not writable.").arg(jobFileInfo.absoluteFilePath());
390 fatalError = true;
391 break;
392 }
393
394 QFileInfo molFileInfo(dir.absoluteFilePath(m_inputCoordFileName));
395
396 if (molFileInfo.exists()) {
397 errors << tr("%1: File will be overwritten.")
398 .arg(molFileInfo.absoluteFilePath());
399 }
400
401 // Attempt to open the file for writing
402 if (!QFile(molFileInfo.absoluteFilePath()).open(QFile::WriteOnly)) {
403 errors
404 << tr("%1: File is not writable.").arg(molFileInfo.absoluteFilePath());
405 fatalError = true;
406 break;
407 }
408 } while (false); // only run once
409
410 // Handle fatal errors:
411 if (fatalError) {
412 QString formattedError;
413 switch (errors.size()) {
414 case 0:
415 formattedError =
416 tr("The input files cannot be written due to an unknown error.");
417 break;
418 case 1:
419 formattedError =
420 tr("The input files cannot be written:\n\n%1").arg(errors.first());
421 break;
422 default: {
423 // If a fatal error occured, it will be last one in the list. Pop it off
424 // and tell the user that it was the reason we had to stop.
425 QString fatal = errors.last();
426 QStringList tmp(errors);
427 tmp.pop_back();
428 formattedError =
429 tr("The input files cannot be written:\n\n%1\n\nWarnings:\n\n%2")
430 .arg(fatal, tmp.join("\n"));
431 break;
432 }
433 }
434 QMessageBox::critical(this, tr("Output Error"), formattedError);
435 return;
436 }
437
438 // Non-fatal errors:
439 if (!errors.isEmpty()) {
440 QString formattedError = tr("Warning:\n\n%1\n\nWould you like to continue?")
441 .arg(errors.join("\n"));
442
443 QMessageBox::StandardButton reply =
444 QMessageBox::warning(this, tr("Write input files"), formattedError,
445 QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
446
447 if (reply != QMessageBox::Yes)
448 return;
449 }
450
451 bool success = false;
452
453 if (m_jobEdit && m_moleculeEdit) {
454 QFile jobFile(dir.absoluteFilePath(m_jobFileName));
455 if (jobFile.open(QFile::WriteOnly | QFile::Text)) {
456 if (jobFile.write(m_jobEdit->toPlainText().toLocal8Bit()) > 0) {
457 success = true;
458 }
459 jobFile.close();
460 }
461
462 if (!success) {
463 QMessageBox::critical(
464 this, tr("Output Error"),
465 tr("Failed to write to file %1.").arg(jobFile.fileName()));
466 }
467
468 QFile molFile(dir.absoluteFilePath(m_inputCoordFileName));
469 if (molFile.open(QFile::WriteOnly | QFile::Text)) {
470 if (molFile.write(m_moleculeEdit->toPlainText().toLocal8Bit()) > 0) {
471 success = true;
472 }
473 molFile.close();
474 }
475
476 if (!success) {
477 QMessageBox::critical(
478 this, tr("Output Error"),
479 tr("Failed to write to file %1.").arg(molFile.fileName()));
480 }
481 }
482 }
483
enableFormClicked()484 void OpenMMInputDialog::enableFormClicked()
485 {
486 updatePreviewText();
487 }
488
setScriptName()489 void OpenMMInputDialog::setScriptName()
490 {
491 m_jobFileName =
492 (ui.jobScriptEdit->text().isEmpty() ? ui.jobScriptEdit->placeholderText()
493 : ui.jobScriptEdit->text()) +
494 ".py";
495 updatePreviewText();
496 }
497
setInputCoordName()498 void OpenMMInputDialog::setInputCoordName()
499 {
500 ui.inputCoordEdit->setStyleSheet("");
501 m_inputCoordFileName =
502 (ui.inputCoordEdit->text().isEmpty() ? ui.inputCoordEdit->placeholderText()
503 : ui.inputCoordEdit->text());
504 QString ext = m_inputCoordFileName.split(".").back();
505 if (ext == tr("inpcrd") || ext == tr("gro")) {
506 ui.forceFieldCombo->setEnabled(false);
507 ui.inputTopEdit->setEnabled(true);
508 if (ext == tr("inpcrd"))
509 ui.inputTopEdit->setPlaceholderText(tr("input.prmtop"));
510 else if (ext == tr("gro")) {
511 ui.inputTopEdit->setPlaceholderText(tr("input.top"));
512 }
513 updatePreviewText();
514 } else if (ext == tr("pdb")) {
515 ui.forceFieldCombo->setEnabled(true);
516 ui.inputTopEdit->setEnabled(false);
517 updatePreviewText();
518 } else {
519 ui.forceFieldCombo->setEnabled(false);
520 ui.inputTopEdit->setEnabled(false);
521 ui.inputCoordEdit->setStyleSheet("color: #FF0000");
522 }
523 addMoleculeDataTab();
524 }
525
setTopologyName()526 void OpenMMInputDialog::setTopologyName()
527 {
528 ui.inputCoordEdit->setStyleSheet("");
529 m_topologyFileName =
530 (ui.inputTopEdit->text().isEmpty() ? ui.inputTopEdit->placeholderText()
531 : ui.inputTopEdit->text());
532 QString ext = m_topologyFileName.split(".").back();
533 QString extCoord = m_inputCoordFileName.split(".").back();
534 if (extCoord == tr("inpcrd")) {
535 if (ext != tr("prmtop")) {
536 ui.inputCoordEdit->setStyleSheet("color: #FF0000");
537 }
538 } else if (extCoord == tr("gro")) {
539 if (ext != tr("top")) {
540 ui.inputCoordEdit->setStyleSheet("color: #FF0000");
541 }
542 }
543 updatePreviewText();
544 }
545
setForceField(int n)546 void OpenMMInputDialog::setForceField(int n)
547 {
548 m_forceFieldType = (OpenMMInputDialog::forceFieldType)n;
549 ui.forceFieldCombo->setEnabled(true);
550 updatePreviewText();
551 }
552
setConstraintType(int n)553 void OpenMMInputDialog::setConstraintType(int n)
554 {
555 m_constraintType = static_cast<OpenMMInputDialog::constraintType>(n);
556 ui.constraintsCombo->setEnabled(true);
557 if (m_constraintType == None) {
558 ui.constraintToleranceSpin->setEnabled(false);
559 } else {
560 ui.constraintToleranceSpin->setEnabled(true);
561 }
562 updatePreviewText();
563 }
564
setWaterModelType(int n)565 void OpenMMInputDialog::setWaterModelType(int n)
566 {
567 m_waterModelType = static_cast<OpenMMInputDialog::waterModelType>(n);
568 ui.waterModelCombo->setEnabled(true);
569 updatePreviewText();
570 }
571
setNonBondedType(int n)572 void OpenMMInputDialog::setNonBondedType(int n)
573 {
574 m_nonBondedType = static_cast<OpenMMInputDialog::nonBondedType>(n);
575 ui.nonBondedMethodCombo->setEnabled(true);
576 if (m_nonBondedType == NoCutoff) {
577 ui.nonBondedCutoffSpin->setEnabled(false);
578 ui.ewaldToleranceSpin->setEnabled(false);
579 } else if (m_nonBondedType == CutoffPeriodic ||
580 m_nonBondedType == CutoffNonPeriodic) {
581 ui.nonBondedCutoffSpin->setEnabled(true);
582 ui.ewaldToleranceSpin->setEnabled(false);
583 } else if (m_nonBondedType == Ewald || m_nonBondedType == PME) {
584 ui.nonBondedCutoffSpin->setEnabled(true);
585 ui.ewaldToleranceSpin->setEnabled(true);
586 }
587 updatePreviewText();
588 }
589
setIntegratorType(int n)590 void OpenMMInputDialog::setIntegratorType(int n)
591 {
592 m_integratorType = static_cast<OpenMMInputDialog::integratorType>(n);
593 ui.integratorCombo->setEnabled(true);
594 if (m_integratorType == Langevin || m_integratorType == Brownian ||
595 m_integratorType == VariableLangevin) {
596 if (m_integratorType == Langevin || m_integratorType == Brownian) {
597 ui.stepSpin->setEnabled(true);
598 ui.errorTolSpin->setEnabled(false);
599 } else if (m_integratorType == VariableLangevin) {
600 ui.stepSpin->setEnabled(false);
601 ui.errorTolSpin->setEnabled(true);
602 }
603 ui.collisionRateSpin->setEnabled(true);
604 ui.temperatureSpin->setEnabled(true);
605 ui.barostatCombo->setEnabled(true);
606 if (m_barostatType == NoBarostat) {
607 ui.pressureSpin->setEnabled(false);
608 ui.barostatIntervalSpin->setEnabled(false);
609 } else {
610 ui.pressureSpin->setEnabled(true);
611 ui.barostatIntervalSpin->setEnabled(true);
612 }
613 } else if (m_integratorType == Verlet || m_integratorType == VariableVerlet) {
614 if (m_integratorType == Verlet) {
615 ui.stepSpin->setEnabled(true);
616 ui.errorTolSpin->setEnabled(false);
617 } else if (m_integratorType == VariableVerlet) {
618 ui.stepSpin->setEnabled(false);
619 ui.errorTolSpin->setEnabled(true);
620 }
621 ui.collisionRateSpin->setEnabled(false);
622 ui.temperatureSpin->setEnabled(false);
623 ui.barostatCombo->setEnabled(false);
624 ui.pressureSpin->setEnabled(false);
625 ui.barostatIntervalSpin->setEnabled(false);
626 }
627 updatePreviewText();
628 }
629
setBarostatType(int n)630 void OpenMMInputDialog::setBarostatType(int n)
631 {
632 m_barostatType = static_cast<OpenMMInputDialog::barostatType>(n);
633 ui.barostatCombo->setEnabled(true);
634 if (m_barostatType == NoBarostat) {
635 ui.pressureSpin->setEnabled(false);
636 ui.barostatIntervalSpin->setEnabled(false);
637 } else {
638 ui.pressureSpin->setEnabled(true);
639 ui.barostatIntervalSpin->setEnabled(true);
640 }
641 updatePreviewText();
642 }
643
setMolecule(QtGui::Molecule * molecule)644 void OpenMMInputDialog::setMolecule(QtGui::Molecule* molecule)
645 {
646 // Disconnect the old molecule first...
647 if (molecule == m_molecule)
648 return;
649
650 if (m_molecule)
651 m_molecule->disconnect(this);
652
653 m_molecule = molecule;
654 // Update the preview text whenever primitives are changed
655 connect(molecule, SIGNAL(changed(unsigned int)), SLOT(updatePreviewText()));
656 updatePreviewText();
657 }
658
setRigidWater(int n)659 void OpenMMInputDialog::setRigidWater(int n)
660 {
661 m_rigidWater = n;
662 ui.rigidWaterCombo->setEnabled(true);
663 updatePreviewText();
664 }
665
setMinimize(int n)666 void OpenMMInputDialog::setMinimize(int n)
667 {
668 m_minimize = n;
669 ui.minimizeCombo->setEnabled(true);
670 updatePreviewText();
671 }
672
setMinimizeSteps(int n)673 void OpenMMInputDialog::setMinimizeSteps(int n)
674 {
675 m_minimizeSteps = n;
676 ui.minimizeStepsSpin->setEnabled(true);
677 updatePreviewText();
678 }
679
setTemperature(double n)680 void OpenMMInputDialog::setTemperature(double n)
681 {
682 m_temperature = n;
683 ui.temperatureSpin->setEnabled(true);
684 updatePreviewText();
685 }
686
setNonBondedCutoff(double n)687 void OpenMMInputDialog::setNonBondedCutoff(double n)
688 {
689 m_nonBondedCutoff = n;
690 ui.nonBondedCutoffSpin->setEnabled(true);
691 updatePreviewText();
692 }
693
setTimeStep(double n)694 void OpenMMInputDialog::setTimeStep(double n)
695 {
696 m_timeStep = n;
697 ui.stepSpin->setEnabled(true);
698 updatePreviewText();
699 }
700
setEwaldTolerance(double n)701 void OpenMMInputDialog::setEwaldTolerance(double n)
702 {
703 m_ewaldTolerance = n;
704 ui.ewaldToleranceSpin->setEnabled(true);
705 updatePreviewText();
706 }
707
setConstraintTolerance(double n)708 void OpenMMInputDialog::setConstraintTolerance(double n)
709 {
710 m_constraintTolerance = n;
711 ui.constraintToleranceSpin->setEnabled(true);
712 updatePreviewText();
713 }
714
setReportInterval(int n)715 void OpenMMInputDialog::setReportInterval(int n)
716 {
717 m_reportInterval = n;
718 ui.reportIntervalSpin->setEnabled(true);
719 updatePreviewText();
720 }
721
setEquilibriationSteps(int n)722 void OpenMMInputDialog::setEquilibriationSteps(int n)
723 {
724 m_equilibriationSteps = n;
725 ui.equilibriationStepsSpin->setEnabled(true);
726 updatePreviewText();
727 }
728
setProductionSteps(int n)729 void OpenMMInputDialog::setProductionSteps(int n)
730 {
731 m_productionSteps = n;
732 ui.productionStepsSpin->setEnabled(true);
733 updatePreviewText();
734 }
735
setDeviceIndex(int n)736 void OpenMMInputDialog::setDeviceIndex(int n)
737 {
738 m_deviceIndex = n;
739 ui.deviceIndexSpin->setEnabled(true);
740 updatePreviewText();
741 }
742
setOpenCLPlatformIndex(int n)743 void OpenMMInputDialog::setOpenCLPlatformIndex(int n)
744 {
745 m_openclPlatformIndex = n;
746 ui.openCLIndexSpin->setEnabled(true);
747 updatePreviewText();
748 }
749
setErrorTolerance(double n)750 void OpenMMInputDialog::setErrorTolerance(double n)
751 {
752 m_errorTolerance = n;
753 ui.errorTolSpin->setEnabled(true);
754 updatePreviewText();
755 }
756
setCollisionRate(double n)757 void OpenMMInputDialog::setCollisionRate(double n)
758 {
759 m_collisionRate = n;
760 ui.collisionRateSpin->setEnabled(true);
761 updatePreviewText();
762 }
763
setPressure(double n)764 void OpenMMInputDialog::setPressure(double n)
765 {
766 m_pressure = n;
767 ui.pressureSpin->setEnabled(true);
768 updatePreviewText();
769 }
770
setBarostatInterval(int n)771 void OpenMMInputDialog::setBarostatInterval(int n)
772 {
773 m_barostatInterval = n;
774 ui.barostatIntervalSpin->setEnabled(true);
775 updatePreviewText();
776 }
777
setVelocityDistRandom(int n)778 void OpenMMInputDialog::setVelocityDistRandom(int n)
779 {
780 m_velocityDistRandom = n;
781 ui.initVelCombo->setEnabled(true);
782 if (m_velocityDistRandom == 1) {
783 ui.generationTemperatureSpin->setEnabled(false);
784 } else {
785 ui.generationTemperatureSpin->setEnabled(true);
786 }
787 updatePreviewText();
788 }
789
setGenerationTemperature(double n)790 void OpenMMInputDialog::setGenerationTemperature(double n)
791 {
792 m_generationTemperature = n;
793 ui.generationTemperatureSpin->setEnabled(true);
794 updatePreviewText();
795 }
796
setDCDReporter(bool state)797 void OpenMMInputDialog::setDCDReporter(bool state)
798 {
799 m_DCDReporter = state;
800 ui.dcdCheck->setEnabled(true);
801 updatePreviewText();
802 }
803
setPDBReporter(bool state)804 void OpenMMInputDialog::setPDBReporter(bool state)
805 {
806 m_PDBReporter = state;
807 ui.pdbCheck->setEnabled(true);
808 updatePreviewText();
809 }
810
setStepIndexBoolean(bool state)811 void OpenMMInputDialog::setStepIndexBoolean(bool state)
812 {
813 m_stepIndex = state;
814 ui.stepIndexCheck->setEnabled(true);
815 updatePreviewText();
816 }
setTimeBoolean(bool state)817 void OpenMMInputDialog::setTimeBoolean(bool state)
818 {
819 m_time = state;
820 ui.timeCheck->setEnabled(true);
821 updatePreviewText();
822 }
setSpeedBoolean(bool state)823 void OpenMMInputDialog::setSpeedBoolean(bool state)
824 {
825 m_speed = state;
826 ui.speedCheck->setEnabled(true);
827 updatePreviewText();
828 }
setProgressBoolean(bool state)829 void OpenMMInputDialog::setProgressBoolean(bool state)
830 {
831 m_progress = state;
832 ui.progressCheck->setEnabled(true);
833 updatePreviewText();
834 }
setPotentialEnergyBoolean(bool state)835 void OpenMMInputDialog::setPotentialEnergyBoolean(bool state)
836 {
837 m_potentialEnergy = state;
838 ui.potentialEnergyCheck->setEnabled(true);
839 updatePreviewText();
840 }
setKineticEnergyBoolean(bool state)841 void OpenMMInputDialog::setKineticEnergyBoolean(bool state)
842 {
843 m_kineticEnergy = state;
844 ui.kineticEnergyCheck->setEnabled(true);
845 updatePreviewText();
846 }
setTotalEnergyBoolean(bool state)847 void OpenMMInputDialog::setTotalEnergyBoolean(bool state)
848 {
849 m_totalEnergy = state;
850 ui.totalEnergyCheck->setEnabled(true);
851 updatePreviewText();
852 }
setTemperatureBoolean(bool state)853 void OpenMMInputDialog::setTemperatureBoolean(bool state)
854 {
855 m_temperature = state;
856 ui.temperatureCheck->setEnabled(true);
857 updatePreviewText();
858 }
setVolumeBoolean(bool state)859 void OpenMMInputDialog::setVolumeBoolean(bool state)
860 {
861 m_volume = state;
862 ui.volumeCheck->setEnabled(true);
863 updatePreviewText();
864 }
setDensityBoolean(bool state)865 void OpenMMInputDialog::setDensityBoolean(bool state)
866 {
867 m_density = state;
868 ui.densityCheck->setEnabled(true);
869 updatePreviewText();
870 }
871
setStateDataReporter(bool state)872 void OpenMMInputDialog::setStateDataReporter(bool state)
873 {
874 ui.stepIndexCheck->setEnabled(state);
875 ui.timeCheck->setEnabled(state);
876 ui.speedCheck->setEnabled(state);
877 ui.progressCheck->setEnabled(state);
878 ui.potentialEnergyCheck->setEnabled(state);
879 ui.kineticEnergyCheck->setEnabled(state);
880 ui.totalEnergyCheck->setEnabled(state);
881 ui.temperatureCheck->setEnabled(state);
882 ui.volumeCheck->setEnabled(state);
883 ui.densityCheck->setEnabled(state);
884
885 m_stateDataReporter = state;
886 ui.stateDataCheck->setEnabled(true);
887 updatePreviewText();
888 }
889
setPlatformType(int n)890 void OpenMMInputDialog::setPlatformType(int n)
891 {
892 m_platformType = static_cast<OpenMMInputDialog::platformType>(n);
893 ui.platformCombo->setEnabled(true);
894 if (m_platformType == Reference || m_platformType == CPU) {
895 ui.precisionCombo->setEnabled(false);
896 ui.deviceIndexSpin->setEnabled(false);
897 ui.openCLIndexSpin->setEnabled(false);
898 } else {
899 ui.precisionCombo->setEnabled(true);
900 ui.deviceIndexSpin->setEnabled(true);
901 if (m_platformType == OpenCL)
902 ui.openCLIndexSpin->setEnabled(true);
903 else
904 ui.openCLIndexSpin->setEnabled(false);
905 }
906 updatePreviewText();
907 }
908
setPrecisionType(int n)909 void OpenMMInputDialog::setPrecisionType(int n)
910 {
911 m_precisionType = static_cast<OpenMMInputDialog::precisionType>(n);
912 ui.precisionCombo->setEnabled(true);
913 updatePreviewText();
914 }
915
generateInputDeck()916 QString OpenMMInputDialog::generateInputDeck()
917 {
918 // Generate an input deck based on the settings of the dialog
919 QString buffer;
920 QTextStream scriptStream(&buffer);
921
922 scriptStream << "############################################################"
923 "##############\n";
924 scriptStream << "# OpenMM input script generated by Avogadro.\n";
925 scriptStream << "# Builder adapted from OpenMM script builder "
926 "http://builder.openmm.org.\n";
927 scriptStream << "############################################################"
928 "##############\n\n";
929 scriptStream << "from __future__ import print_function\n";
930 scriptStream << "from simtk.openmm import app\n";
931 scriptStream << "import simtk.openmm as mm\n";
932 scriptStream << "from simtk import unit\n";
933 scriptStream << "from sys import stdout\n";
934
935 // first two or three lines, that load up the FF and the pdb
936 // these lines end with the start of the function something.createSystem(
937 QString ext = m_inputCoordFileName.split(".").back();
938 if (ext == tr("pdb")) {
939 scriptStream << "\npdb = app.PDBFile(\'" << m_inputCoordFileName << "\')\n";
940 scriptStream << "forcefield = app.ForceField(\'"
941 << getForceFieldType(m_forceFieldType) << ".xml\'";
942 scriptStream << ", \'" << getWaterModelType(m_waterModelType) << ".xml\'";
943 scriptStream << ")\n\n";
944 scriptStream << "system = forcefield.createSystem(pdb.topology, ";
945 } else if (ext == tr("inpcrd")) {
946 scriptStream << "\nprmtop = app.AmberPrmtopFile(\'" << m_topologyFileName
947 << "\')\n";
948 scriptStream << "inpcrd = app.AmberInpcrdFile(\'" << m_inputCoordFileName
949 << "\')\n\n";
950 scriptStream << "system = prmtop.createSystem(";
951 if (m_waterModelType == implicit) {
952 scriptStream << "implicitSolvent=app.OBC2, ";
953 }
954 } else if (ext == tr("gro")) {
955 scriptStream << "\ngro = app.GromacsGroFile(\'" << m_inputCoordFileName
956 << "\')\n";
957 scriptStream << "top = app.GromacsTopFile(\'" << m_topologyFileName
958 << "\')\n\n";
959 scriptStream << "system = top.createSystem(";
960 if (m_waterModelType == implicit) {
961 scriptStream << "implicitSolvent=app.OBC2, ";
962 }
963 } else {
964 // TODO
965 }
966
967 // options for the system
968 scriptStream << "nonbondedMethod="
969 << "app." << getNonBondedType(m_nonBondedType) << ",";
970 if (m_nonBondedCutoff > 0) {
971 scriptStream << " nonbondedCutoff=" << fixed << qSetRealNumberPrecision(4)
972 << m_nonBondedCutoff << "*unit.nanometers,";
973 }
974 if (m_constraintType == None) {
975 scriptStream << " constraints=" << getConstraintType(m_constraintType);
976 } else {
977 scriptStream << " constraints="
978 << "app." << getConstraintType(m_constraintType);
979 }
980 scriptStream << ", rigidWater=" << getRigidWater(m_rigidWater);
981 if (m_nonBondedType == Ewald || m_nonBondedType == PME) {
982 scriptStream << ", ewaldErrorTolerance=" << fixed
983 << qSetRealNumberPrecision(5) << m_ewaldTolerance;
984 }
985 scriptStream << ")\n";
986
987 // set the integrator
988 scriptStream << "integrator = mm." << getIntegratorType(m_integratorType)
989 << "Integrator(";
990 if (m_integratorType == Langevin || m_integratorType == Brownian) {
991 scriptStream << m_temperature << "*unit.kelvin, ";
992 scriptStream << m_collisionRate << "/unit.picoseconds, ";
993 }
994 if (m_integratorType == VariableLangevin ||
995 m_integratorType == VariableVerlet) {
996 scriptStream << m_errorTolerance << ")\n";
997 } else {
998 scriptStream << m_timeStep << "*unit.femtoseconds)\n";
999 }
1000 if (m_constraintType != None && m_constraintTolerance > 0) {
1001 scriptStream << "integrator.setConstraintTolerance("
1002 << m_constraintTolerance << ")\n";
1003 }
1004
1005 // add a barostat
1006 if (m_barostatType == MonteCarlo) {
1007 scriptStream << "system.addForce(mm.MonteCarloBarostat(" << m_pressure
1008 << "*unit.atmospheres";
1009 scriptStream << ", " << m_temperature << "*unit.kelvin";
1010 if (m_barostatInterval > 0) {
1011 scriptStream << ", " << m_barostatInterval;
1012 }
1013 scriptStream << "))\n";
1014 }
1015
1016 // // add a thermostat
1017 // if (m_thermostatType == Andersen) {
1018 // scriptStream << "system.addForce(mm.AndersenThermostat(" <<
1019 // m_temperature << "*unit.kelvin"; scriptStream << ", " <<
1020 // m_collisionRate << "/unit.picoseconds" << "))\n";
1021 // }
1022
1023 scriptStream << "\n";
1024
1025 // set the platform options
1026 scriptStream << "platform = mm.Platform.getPlatformByName(\'"
1027 << getPlatformType(m_platformType) << "\')\n";
1028 if (m_platformType == CUDA) {
1029 scriptStream << "properties = {\'CudaPrecision\': \'"
1030 << getPrecisionType(m_precisionType) << "\'";
1031 if (m_deviceIndex > 0) {
1032 scriptStream << ", \'CudaDeviceIndex\': \'" << m_deviceIndex << "\'";
1033 }
1034 scriptStream << "}\n";
1035 } else if (m_platformType == OpenCL) {
1036 scriptStream << "properties = {\'OpenCLPrecision\': \'"
1037 << getPrecisionType(m_precisionType) << "\'";
1038 if (m_openclPlatformIndex > 0) {
1039 scriptStream << ", \'OpenCLPlatformIndex\': \'" << m_openclPlatformIndex
1040 << "\'";
1041 }
1042 if (m_deviceIndex > 0) {
1043 scriptStream << ", ";
1044 if (m_openclPlatformIndex > 0) {
1045 scriptStream << "\n ";
1046 }
1047 scriptStream << "\'OpenCLDeviceIndex\': \'" << m_deviceIndex << "\'";
1048 }
1049 scriptStream << "}\n";
1050 }
1051
1052 // create the simulation object
1053 scriptStream << "simulation = app.Simulation("
1054 << (ext == tr("pdb") ? "pdb" : "prmtop")
1055 << ".topology, system, integrator, platform";
1056 if (m_platformType == CUDA || m_platformType == OpenCL) {
1057 scriptStream << ", properties";
1058 }
1059 scriptStream << ")\n";
1060
1061 if (ext == tr("pdb")) {
1062 scriptStream << "simulation.context.setPositions(pdb.positions)\n\n";
1063 } else if (ext == tr("inpcrd")) {
1064 scriptStream << "simulation.context.setPositions(inpcrd.positions)\n\n";
1065 } else if (ext == tr("gro")) {
1066 scriptStream << "simulation.context.setPositions(gro.positions)\n\n";
1067 } else {
1068 // TODO
1069 }
1070
1071 // minimize
1072 if (getMinimize(m_minimize) == tr("True")) {
1073 scriptStream << "print('Minimizing...\')\n";
1074 if (m_minimizeSteps == 0) {
1075 scriptStream << "simulation.minimizeEnergy()\n";
1076 } else {
1077 scriptStream << "simulation.minimizeEnergy(maxIterations="
1078 << m_minimizeSteps << ")\n";
1079 }
1080 }
1081 if (getVelocityDistRandom(m_velocityDistRandom) == tr("True")) {
1082 scriptStream << "\nsimulation.context.setVelocitiesToTemperature("
1083 << m_generationTemperature << "*unit.kelvin)\n";
1084 }
1085
1086 // equilibrate
1087 if (m_equilibriationSteps > 0) {
1088 scriptStream << "print(\'Equilibrating...\')\n";
1089 scriptStream << "simulation.step(" << m_equilibriationSteps << ")\n\n";
1090 }
1091
1092 // add reporters
1093 // if (d.simulation.dcd_reporter == 'True' &&
1094 // d.simulation.statedata_opts.length > 0) {
1095 if (m_DCDReporter) {
1096 scriptStream
1097 << "simulation.reporters.append(app.DCDReporter(\'trajectory.dcd\'";
1098 scriptStream << ", " << m_reportInterval << "))\n";
1099 scriptStream << "\n";
1100 }
1101 if (m_PDBReporter) {
1102 scriptStream
1103 << "simulation.reporters.append(app.PDBReporter(\'trajectory.pdb\'";
1104 scriptStream << ", " << m_reportInterval << "))\n";
1105 scriptStream << "\n";
1106 }
1107 if (m_stateDataReporter) {
1108 scriptStream << "simulation.reporters.append(app.StateDataReporter(";
1109 scriptStream << "stdout";
1110 scriptStream << ", " << m_reportInterval;
1111 if (m_stepIndex)
1112 scriptStream << ", step=True";
1113 if (m_time)
1114 scriptStream << ", time=True";
1115 if (m_potentialEnergy)
1116 scriptStream << ", potentialEnergy=True";
1117 if (m_kineticEnergy)
1118 scriptStream << ", kineticEnergy=True";
1119 if (m_totalEnergy)
1120 scriptStream << ", totalEnergy=True";
1121 if (m_temperatureCheck)
1122 scriptStream << ", temperature=True";
1123 if (m_volume)
1124 scriptStream << ", volume=True";
1125 if (m_density)
1126 scriptStream << ", density=True";
1127 if (m_progress)
1128 scriptStream << ", progress=True, remainingTime=True";
1129 if (m_speed)
1130 scriptStream << ", speed=True";
1131 // if using progress (which also implies remaining time), totalSteps
1132 // is required.
1133 if (m_progress)
1134 scriptStream << ", totalSteps=" << m_productionSteps;
1135 scriptStream << ", separator=\'\\t\'))\n";
1136 scriptStream << "\n";
1137 }
1138
1139 // run
1140 scriptStream << "print(\'Running Production...\')\n";
1141 scriptStream << "simulation.step(" << m_productionSteps << ")\n";
1142 scriptStream << "print(\'Done!\')\n";
1143
1144 return buffer;
1145 }
1146
getForceFieldType(forceFieldType t)1147 QString OpenMMInputDialog::getForceFieldType(forceFieldType t)
1148 {
1149 // Translate the enum to text for the output generation
1150 switch (t) {
1151 case amber96:
1152 return "amber96";
1153 case amber99sb:
1154 return "amber99sb";
1155 case amber99sbildn:
1156 return "amber99sbildn";
1157 case amber99sbnmr:
1158 return "amber99sbnmr";
1159 case amber03:
1160 return "amber03";
1161 case amber10:
1162 return "amber10";
1163 default:
1164 return "amber99sbildn";
1165 }
1166 }
1167
getImplicitSolventType(forceFieldType t)1168 QString OpenMMInputDialog::getImplicitSolventType(forceFieldType t)
1169 {
1170 // Translate the enum to text for the output generation
1171 switch (t) {
1172 case amber96:
1173 return "amber96_obc";
1174 case amber99sb:
1175 return "amber99_obc";
1176 case amber99sbildn:
1177 return "amber99_obc";
1178 case amber99sbnmr:
1179 return "amber99_obc";
1180 case amber03:
1181 return "amber03_obc";
1182 case amber10:
1183 return "amber10_obc";
1184 default:
1185 return "amber99_obc";
1186 }
1187 }
1188
getConstraintType(constraintType t)1189 QString OpenMMInputDialog::getConstraintType(constraintType t)
1190 {
1191 switch (t) {
1192 case None:
1193 return "None";
1194 case HBonds:
1195 return "HBonds";
1196 case AllBonds:
1197 return "AllBonds";
1198 case HAngles:
1199 return "HAngles";
1200 default:
1201 return "HBonds";
1202 }
1203 }
1204
getWaterModelType(waterModelType t)1205 QString OpenMMInputDialog::getWaterModelType(waterModelType t)
1206 {
1207 switch (t) {
1208 case spce:
1209 return "spce";
1210 case tip3p:
1211 return "tip3p";
1212 case tip4pew:
1213 return "tip4pew";
1214 case tip5p:
1215 return "tip5p";
1216 case implicit:
1217 return getImplicitSolventType(m_forceFieldType);
1218 default:
1219 return "tip3p";
1220 }
1221 }
1222
getNonBondedType(nonBondedType t)1223 QString OpenMMInputDialog::getNonBondedType(nonBondedType t)
1224 {
1225 switch (t) {
1226 case NoCutoff:
1227 return "NoCutoff";
1228 case CutoffNonPeriodic:
1229 return "CutoffNonPeriodic";
1230 case CutoffPeriodic:
1231 return "CutoffPeriodic";
1232 case Ewald:
1233 return "Ewald";
1234 case PME:
1235 return "PME";
1236 default:
1237 return "PME";
1238 }
1239 }
1240
getIntegratorType(integratorType t)1241 QString OpenMMInputDialog::getIntegratorType(integratorType t)
1242 {
1243 switch (t) {
1244 case Langevin:
1245 return "Langevin";
1246 case Verlet:
1247 return "Verlet";
1248 case Brownian:
1249 return "Brownian";
1250 case VariableVerlet:
1251 return "VariableVerlet";
1252 case VariableLangevin:
1253 return "VariableLangevin";
1254 default:
1255 return "Langevin";
1256 }
1257 }
1258
getBarostatType(barostatType t)1259 QString OpenMMInputDialog::getBarostatType(barostatType t)
1260 {
1261 switch (t) {
1262 case NoBarostat:
1263 return "None";
1264 case MonteCarlo:
1265 return "MonteCarlo";
1266 default:
1267 return "None";
1268 }
1269 }
1270
getRigidWater(int t)1271 QString OpenMMInputDialog::getRigidWater(int t)
1272 {
1273 switch (t) {
1274 case 0:
1275 return "True";
1276 case 1:
1277 return "False";
1278 default:
1279 return "False";
1280 }
1281 }
1282
getVelocityDistRandom(int t)1283 QString OpenMMInputDialog::getVelocityDistRandom(int t)
1284 {
1285 switch (t) {
1286 case 0:
1287 return "True";
1288 case 1:
1289 return "False";
1290 default:
1291 return "True";
1292 }
1293 }
1294
getPlatformType(platformType t)1295 QString OpenMMInputDialog::getPlatformType(platformType t)
1296 {
1297 switch (t) {
1298 case Reference:
1299 return "Reference";
1300 case OpenCL:
1301 return "OpenCL";
1302 case CUDA:
1303 return "CUDA";
1304 case CPU:
1305 return "CPU";
1306 default:
1307 return "CUDA";
1308 }
1309 }
1310
getPrecisionType(precisionType t)1311 QString OpenMMInputDialog::getPrecisionType(precisionType t)
1312 {
1313 switch (t) {
1314 case singlePrecision:
1315 return "single";
1316 case mixedPrecision:
1317 return "mixed";
1318 case doublePrecision:
1319 return "double";
1320 default:
1321 return "mixed";
1322 }
1323 }
1324
getMinimize(int t)1325 QString OpenMMInputDialog::getMinimize(int t)
1326 {
1327 switch (t) {
1328 case 0:
1329 return "True";
1330 case 1:
1331 return "False";
1332 default:
1333 return "True";
1334 }
1335 }
1336
deckDirty(bool dirty)1337 void OpenMMInputDialog::deckDirty(bool dirty)
1338 {
1339 m_dirty = dirty;
1340 // ui.titleLine->setEnabled(!dirty);
1341 // ui.calculationCombo->setEnabled(!dirty);
1342 // ui.theoryCombo->setEnabled(!dirty);
1343 // ui.basisCombo->setEnabled(!dirty);
1344 // ui.multiplicitySpin->setEnabled(!dirty);
1345 // ui.chargeSpin->setEnabled(!dirty);
1346 ui.enableFormButton->setEnabled(dirty);
1347 }
1348
readSettings(QSettings & settings)1349 void OpenMMInputDialog::readSettings(QSettings& settings)
1350 {
1351 m_savePath = settings.value("openmm/savepath").toString();
1352 }
1353
writeSettings(QSettings & settings) const1354 void OpenMMInputDialog::writeSettings(QSettings& settings) const
1355 {
1356 settings.setValue("openmm/savepath", m_savePath);
1357 }
1358
1359 } // namespace QtPlugins
1360 } // namespace Avogadro
1361