Source code for schrodinger.application.jaguar.solvation_input
"""
Functions and classes for defining the input to a Solvation workflow.
"""
# Contributors: Mark A. Watson, Leif D. Jacobson, Daniel S. Levine
import copy
import os
from schrodinger.application.jaguar import solvation_keywords
from schrodinger.application.jaguar import solvation_validation as sv
from schrodinger.application.jaguar.workflow_input import WorkflowInput
from schrodinger.structure import StructureReader
[docs]class SolvationInput(WorkflowInput):
"""
A class to completely specify a Solvation calculation.
Example usage::
input = SolvationInput()
# Set user-defined values
input.setValue('integerKW', 3)
input.setValue('floatKW', '7.0')
input.setValue('stringKW', 'foo')
# Print all keyword/value pairs.
for keyword in input:
print "keyword '%s' has value %s" % (keyword, input[keyword])
# Handling the case of trying to set an unsupported keyword
try:
input['mykeyword'] = 'value'
except WorkflowKeywordException as e:
print e.allowed_keywords
"""
# List of keys for all possible input files associated with a given
# Solvation workflow
input_file_keys = [solvation_keywords.INPUT_MOLECULE]
workflow_name = 'Solvation'
[docs] def __init__(self,
inputfile=None,
keywords=None,
jaguar_keywords=None,
jobname=None,
add_solvation_jaguar_defaults=False):
"""
Create a SolvationInput instance.
If a keyword is specified in both 'inputfile' and 'keywords',
then the values in 'keywords' will be set preferrentially.
This also applies to 'jaguar_keywords'.
:type inputfile: str
:param inputfile: Path to a Solvation input file
:type keywords: dict
:param keywords: Solvation keyword/value pairs
:type jaguar_keywords: dict
:param jaguar_keywords: Jaguar &gen section keyword/value pairs
:type jobname: string
:param jobname: Name of job, if it is not None it will be set to
the basename of the input file name.
:type add_solvation_jaguar_defaults: boolean
:param add_solvation_jaguar_defaults: if True add some custom Jaguar defaults
"""
self._add_solvation_jaguar_defaults = add_solvation_jaguar_defaults
super().__init__(inputfile=inputfile,
keywords=keywords,
jaguar_keywords=jaguar_keywords,
jobname=jobname)
if inputfile or keywords or jaguar_keywords:
self.validate()
[docs] def generate_keywords(self):
"""
Initialize dictionary of all possible Solvation keywords
"""
if not solvation_keywords.SOLVATION_KEYWORDS:
solvation_keywords.generate_all_keywords()
return copy.deepcopy(solvation_keywords.SOLVATION_KEYWORDS)
[docs] def setJaguarValues(self, keywords):
"""
Set multiple Jaguar &gen section keywords.
:type keywords: dict of string/anytype pairs
:param keywords: Jaguar &gen section keyword/value pairs
"""
super().setJaguarValues(keywords)
input_jaguar_keywords = list(keywords)
if self._add_solvation_jaguar_defaults:
self._addSolvationJaguarDefaults(input_jaguar_keywords)
def _addSolvationJaguarDefaults(self, keywords_list):
"""
Add a few defaults for Jaguar that are specific to Solvation.
:type keywords_list: list
:param keywords_list: List of jaguar keywords that have already been
set. No specialized non-defaults will be set for any of these
keywords.
"""
# set some extra defaults unless the user has specified otherwise
if 'isymm' not in keywords_list:
self._jaguarinput.setValue('isymm', 0)
if 'maxit' not in keywords_list:
self._jaguarinput.setValue('maxit', 200)
if 'nogas' not in keywords_list:
self._jaguarinput.setValue('nogas', 2)
is_single_diffuse = self._jaguarinput.getValue('basis').count('+') == 1
if is_single_diffuse and 'iusediffuse' not in keywords_list:
self._jaguarinput.setValue('iusediffuse', 1)
[docs] def getInputMolecule(self):
"""
Return list of input molecules.
If no file(s) found, return None.
:rtype: list of Structures (or None)
:return: reactant Structures
"""
fh = self.getValue(solvation_keywords.INPUT_MOLECULE)
# if file doesn't exist use a basename
# this is a fallback for when running
# remotely under jobcontrol and the path is bad
fname_basename = fh if os.path.exists(fh) else os.path.basename(fh)
# filter out files that can't be found
if os.path.exists(fname_basename):
inputs = list(StructureReader(fname_basename))
else:
inputs = None
return inputs
[docs] def validate(self):
"""
Perform a self-consistency check of all currently set keywords.
:raise WorkflowKeywordConflictError if conflicting values found
:raise WorkflowConservationError if matter not conserved
"""
for k, kwd in self._keywords.items():
# The keys to self._keywords are keyword names so should be kept
# in sync else confusion could arise.
if k != kwd.name:
msg = "SolvationInput class is corrupted: %s != %s" % (k,
kwd.name)
raise RuntimeError(msg)
# Do internal SolvationKeyword validation
kwd.validate()
# Do some ad hoc self-consistency checks for conflicting keywords
sv.check_conflicts(kwd, self._keywords)
# validate structures
sv.validate_structures(self)
structs = self.getInputMolecule()
self.validate_jaguar_keywords(structs)
[docs] def read(self, inputfile):
"""
Read an existing Solvation input file.
Any keywords specified in the input file will override
existing values in this SolvationInput instance.
Jaguar &gen section keywords are defined like::
&JaguarKeywords
key=val
key=val
...
&
Constraints can be defined with::
&Constraints
st_title atom_index1 atom_index2... value
&
:type inputfile: str
:param inputfile: Path to a Solvation input file
"""
super().read(inputfile)
if self._add_solvation_jaguar_defaults:
jaguar_keys = self.getJaguarNonDefault().keys()
self._addSolvationJaguarDefaults(jaguar_keys)