import sys
import warnings
from collections import OrderedDict
from schrodinger.infra import mm
from schrodinger.Qt import QtGui
from .. import ui
from .. import utils as gui_utils
from ..utils import JaguarSettingWarning
from .base_tab import BaseTab
[docs]class ScfTab(BaseTab):
"""
This is the basic SCF tab that is used for majority of tasks.
"""
NAME = "SCF"
UI_MODULES = (ui.scf_tab_ui,)
HELP_TOPIC = "JAGUAR_TOPIC_SCF_FOLDER"
INCLUDE_USE_CONSISTENT_ORBITALS_CB = False
FULLY_ANALYTIC_ACCURACY = "FULLY_ANALYTIC_ACCURACY"
ACCURACY_LEVELS = OrderedDict(((
"Quick",
mm.MMJAG_IACC_QUICK,
), ("Accurate", mm.MMJAG_IACC_ACCURATE), ("Ultrafine", mm.MMJAG_IACC_HIGH),
("Fully analytic", FULLY_ANALYTIC_ACCURACY)))
INITIAL_GUESS_OPTS = OrderedDict(
(("Atomic overlap", mm.MMJAG_IGUESS_OVER), ("Atomic density",
mm.MMJAG_IGUESS_DENS),
("Core Hamiltonian", mm.MMJAG_IGUESS_ONEE), ("Ligand field theory",
mm.MMJAG_IGUESS_TMIG2),
("Ligand field theory with d-d repulsion", mm.MMJAG_IGUESS_TMIG3)))
THERMAL_SMEARING_OPTS = OrderedDict(
(("None", mm.MMJAG_IFDTHERM_OFF), ("FON", mm.MMJAG_IFDTHERM_FON),
("pFON", mm.MMJAG_IFDTHERM_PFON)))
CONVERGENCE_SCHEME_OPTS = OrderedDict(
(("DIIS", mm.MMJAG_ICONV_DIIS), ("OCBSE", mm.MMJAG_ICONV_OCBSE),
("GVB - DIIS", mm.MMJAG_ICONV_GVBDIIS)))
LOCALIZATION_METHODS = OrderedDict(
(("None", mm.MMJAG_LOCPOSTV_OFF), ("Pipek-Mezey",
mm.MMJAG_LOCPOSTV_ATOM),
("Boys", mm.MMJAG_LOCPOSTV_BOYS), ("Pipek-Mezey (alt)",
mm.MMJAG_LOCPOSTV_BASIS)))
[docs] def setup(self):
"""
Common setup for all SCF tabs.
"""
self.ui.thermal_smearing_combo.currentIndexChanged.connect(
self.thermalSmearingChanged)
self.ui.energy_change_le.setValidator(
QtGui.QDoubleValidator(1.e-12, 1.0, 5, self))
self.ui.rms_density_matrix_change_le.setValidator(
QtGui.QDoubleValidator(1.e-12, 1.0, 5, self))
self.ui.scf_level_shift_le.setValidator(
QtGui.QDoubleValidator(0.0, 10000.0, 5, self))
self.ui.initial_temp_le.setValidator(
QtGui.QDoubleValidator(0.0, sys.float_info.max, 5, self))
self.ui.accuracy_combo.addItemsFromDict(self.ACCURACY_LEVELS)
self.ui.initial_guess_combo.addItemsFromDict(self.INITIAL_GUESS_OPTS)
self.ui.thermal_smearing_combo.addItemsFromDict(
self.THERMAL_SMEARING_OPTS)
self.ui.convergence_scheme_combo.addItemsFromDict(
self.CONVERGENCE_SCHEME_OPTS)
self.ui.final_localization_combo.addItemsFromDict(
self.LOCALIZATION_METHODS)
self.ui.consistent_orbitals_cb.setVisible(
self.INCLUDE_USE_CONSISTENT_ORBITALS_CB)
[docs] def thermalSmearingChanged(self, index):
"""
This function is used to enable or disable initial temperature
widgets depending on thermal smearing method.
:param index: thermal smearing combo box index (0 is 'None')
:type index: int
"""
enabled = True
if index == 0:
enabled = False
self.ui.initial_temp_lbl.setEnabled(enabled)
self.ui.initial_temp_le.setEnabled(enabled)
self.ui.initial_temp_unit_lbl.setEnabled(enabled)
[docs] def getMmJagKeywords(self):
keywords = {}
keywords.update(self.getAccuracyAndInitialGuessKeywords())
keywords.update(self.getConvergenceCriteriaKeywords())
keywords.update(self.getConvergenceMethodsKeywords())
keywords.update(self.getOrbitalsKeywords())
return keywords
[docs] def getAccuracyAndInitialGuessKeywords(self):
"""
Get the accuracy and initial guess keywords
:return: A dictionary of keywords
:rtype: dict
"""
keywords = {}
accuracy = self.ui.accuracy_combo.currentData()
if accuracy == self.FULLY_ANALYTIC_ACCURACY:
keywords[mm.MMJAG_IKEY_NOPS] = mm.MMJAG_NOPS_ON
keywords[mm.MMJAG_IKEY_IACC] = None
else:
keywords[mm.MMJAG_IKEY_NOPS] = mm.MMJAG_NOPS_OFF
keywords[mm.MMJAG_IKEY_IACC] = accuracy
initial_guess = self.ui.initial_guess_combo.currentData()
keywords[mm.MMJAG_IKEY_IGUESS] = initial_guess
return keywords
[docs] def getConvergenceCriteriaKeywords(self):
"""
Get keywords from the Convergence criteria frame
:return: A dictionary of keywords
:rtype: dict
"""
keywords = {}
keywords[mm.MMJAG_IKEY_MAXIT] = \
self.ui.maximum_iterations_sb.value()
econv = gui_utils.validate_le_float_input(
self.ui.energy_change_le, "Invalid input for energy change field.")
keywords[mm.MMJAG_RKEY_ECONV] = econv
dconv = gui_utils.validate_le_float_input(
self.ui.rms_density_matrix_change_le,
"Invalid input for RMS density matrix change field.")
keywords[mm.MMJAG_RKEY_DCONV] = dconv
return keywords
[docs] def getConvergenceMethodsKeywords(self):
"""
Get keywords from the Convergence methods frame
:return: A dictionary of keywords
:rtype: dict
"""
keywords = {}
vshift = gui_utils.validate_le_float_input(
self.ui.scf_level_shift_le,
"Invalid input for SCF level shift field.")
keywords[mm.MMJAG_RKEY_VSHIFT] = vshift
thermal_smearing = self.ui.thermal_smearing_combo.currentData()
keywords[mm.MMJAG_IKEY_IFDTHERM] = thermal_smearing
fdtemp = gui_utils.validate_le_float_input(
self.ui.initial_temp_le,
"Invalid input for initial temperature field.")
keywords[mm.MMJAG_RKEY_FDTEMP] = fdtemp
convergence = self.ui.convergence_scheme_combo.currentData()
keywords[mm.MMJAG_IKEY_ICONV] = convergence
if self.ui.force_convergence_cb.isChecked():
keywords[mm.MMJAG_IKEY_IACSCF] = mm.MMJAG_IACSCF_YES
else:
keywords[mm.MMJAG_IKEY_IACSCF] = mm.MMJAG_IACSCF_NO
return keywords
[docs] def getOrbitalsKeywords(self):
"""
Get keywords from the Orbitals frame
:return: A dictionary of keywords
:rtype: dict
"""
keywords = {}
if self.ui.fixed_symmetry_cb.isChecked():
keywords[mm.MMJAG_IKEY_IPOPSYM] = mm.MMJAG_IPOPSYM_ON
else:
keywords[mm.MMJAG_IKEY_IPOPSYM] = mm.MMJAG_IPOPSYM_OFF
localization = self.ui.final_localization_combo.currentData()
keywords[mm.MMJAG_IKEY_LOCPOSTV] = localization
return keywords
[docs] def loadSettings(self, jag_input):
self.loadAccuracyAndInitialGuessSettings(jag_input)
self.loadConvergenceCriteriaSettings(jag_input)
self.loadConvergenceMethodsSettings(jag_input)
self.loadOrbitalsSettings(jag_input)
[docs] def loadAccuracyAndInitialGuessSettings(self, jag_input):
"""
Load the accuracy and initial guess settings.
:param jag_input: The Jaguar settings to load
:type jag_input: `schrodinger.application.jaguar.input.JaguarInput`
"""
if jag_input[mm.MMJAG_IKEY_NOPS] != mm.MMJAG_NOPS_OFF:
self.ui.accuracy_combo.setCurrentData(self.FULLY_ANALYTIC_ACCURACY)
if jag_input.isNonDefault(mm.MMJAG_IKEY_IACC):
msg = (
'Cannot set both %s and %s. Accuracy will be set to '
'"Fully analytic" because %s = 1. %s = %i will be '
'ignored.' %
(mm.MMJAG_IKEY_NOPS, mm.MMJAG_IKEY_IACC, mm.MMJAG_IKEY_NOPS,
mm.MMJAG_IKEY_IACC, jag_input[mm.MMJAG_IKEY_IACC]))
warnings.warn(JaguarSettingWarning(msg))
else:
self.ui.accuracy_combo.setCurrentMmJagData(jag_input,
mm.MMJAG_IKEY_IACC,
"accuracy")
self.ui.initial_guess_combo.setCurrentMmJagData(jag_input,
mm.MMJAG_IKEY_IGUESS,
"initial guess")
[docs] def loadConvergenceCriteriaSettings(self, jag_input):
"""
Load settings into the Convergence criteria frame
:param jag_input: The Jaguar settings to load
:type jag_input: `schrodinger.application.jaguar.input.JaguarInput`
"""
maxit = jag_input[mm.MMJAG_IKEY_MAXIT]
self.ui.maximum_iterations_sb.setValue(maxit)
econv = jag_input[mm.MMJAG_RKEY_ECONV]
self.ui.energy_change_le.setText(str(econv))
dconv = jag_input[mm.MMJAG_RKEY_DCONV]
self.ui.rms_density_matrix_change_le.setText(str(dconv))
[docs] def loadConvergenceMethodsSettings(self, jag_input):
"""
Load settings into the Convergence methods frame
:param jag_input: The Jaguar settings to load
:type jag_input: `schrodinger.application.jaguar.input.JaguarInput`
"""
vshift = jag_input[mm.MMJAG_RKEY_VSHIFT]
self.ui.scf_level_shift_le.setText(str(vshift))
index = jag_input[mm.MMJAG_IKEY_IFDTHERM]
self.ui.thermal_smearing_combo.setCurrentIndex(index)
fdtemp = jag_input[mm.MMJAG_RKEY_FDTEMP]
self.ui.initial_temp_le.setText(str(fdtemp))
self.ui.convergence_scheme_combo.setCurrentMmJagData(
jag_input, mm.MMJAG_IKEY_ICONV, "convergence scheme")
force_convergence = jag_input[mm.MMJAG_IKEY_IACSCF]
if force_convergence in (mm.MMJAG_IACSCF_NO, mm.MMJAG_IACSCF_YES):
force_convergence_bool = force_convergence == mm.MMJAG_IACSCF_YES
self.ui.force_convergence_cb.setChecked(force_convergence_bool)
else:
# There are constants for force convergence values of 2, 3, and 4,
# that aren't included in the GUI (mm.MMJAG_IACSCF_OPT2,
# mm.MMJAG_IACSCF_OPT3, and mm.MMJAG_IACSCF_OPT4), so we explicitly
# disallow them rather that treating the variable as a typical
# Boolean.
msg = ("Force convergence value of %s=%i not recognized." %
(mm.MMJAG_IKEY_IACSCF, force_convergence))
warnings.warn(JaguarSettingWarning(msg))
[docs] def loadOrbitalsSettings(self, jag_input):
"""
Load settings into the Orbitals frame
:param jag_input: The Jaguar settings to load
:type jag_input: `schrodinger.application.jaguar.input.JaguarInput`
"""
fixed_symm = jag_input[mm.MMJAG_IKEY_IPOPSYM] != mm.MMJAG_IPOPSYM_OFF
self.ui.fixed_symmetry_cb.setChecked(fixed_symm)
self.ui.final_localization_combo.setCurrentMmJagData(
jag_input, mm.MMJAG_IKEY_LOCPOSTV, "localization")
[docs]class ScfTabConsistentOrbitals(ScfTab):
"""
This tab is used for SPE and Optimizations tasks and includes the "Use
consistent orbital sets when all input structures are isomers" check box
"""
INCLUDE_USE_CONSISTENT_ORBITALS_CB = True
[docs] def isUseConsistentOrbitalsChecked(self):
return self.ui.consistent_orbitals_cb.isChecked()
[docs] def reset(self):
self.ui.consistent_orbitals_cb.setChecked(True)
[docs]class ScfTabIGO(ScfTab):
"""
This tab is used for 'Initial Guess Only' task.
"""
[docs] def setup(self):
super(ScfTabIGO, self).setup()
self.ui.accuracy_lbl.setDisabled(True)
self.ui.accuracy_combo.setDisabled(True)
self.ui.criteria_gb.setDisabled(True)
self.ui.methods_gb.setDisabled(True)
self.ui.fixed_symmetry_cb.setDisabled(True)
[docs] def getMmJagKeywords(self):
keywords = {}
initial_guess = self.ui.initial_guess_combo.currentData()
keywords[mm.MMJAG_IKEY_IGUESS] = initial_guess
localization = self.ui.final_localization_combo.currentData()
keywords[mm.MMJAG_IKEY_LOCPOSTV] = localization
return keywords
[docs] def loadSettings(self, jag_input):
self._checkSettings(jag_input)
self.ui.initial_guess_combo.setCurrentMmJagData(jag_input,
mm.MMJAG_IKEY_IGUESS,
"initial guess")
self.ui.final_localization_combo.setCurrentMmJagData(
jag_input, mm.MMJAG_IKEY_LOCPOSTV, "localization")
def _checkSettings(self, jag_input):
#Make sure the user didn't specify any non-IGO keywords
NON_ALLOWED_KEYS = (mm.MMJAG_IKEY_IACC, mm.MMJAG_IKEY_NOPS,
mm.MMJAG_IKEY_MAXIT, mm.MMJAG_RKEY_ECONV,
mm.MMJAG_RKEY_VSHIFT, mm.MMJAG_IKEY_IFDTHERM,
mm.MMJAG_RKEY_FDTEMP, mm.MMJAG_IKEY_ICONV,
mm.MMJAG_IKEY_IACSCF, mm.MMJAG_IKEY_IPOPSYM)
bad_keys = [
key for key in NON_ALLOWED_KEYS if jag_input.isNonDefault(key)
]
if bad_keys:
plural_s = "s" if len(bad_keys) > 1 else ""
msg = ("The following SCF keyword%s are not available for this "
"task: %s" % (plural_s, ", ".join(bad_keys)))
warnings.warn(JaguarSettingWarning(msg))