Source code for schrodinger.application.jaguar.macro_pka_validation

"""
Macro-pKa keywords input validation and specialized Exceptions
"""
# Contributors: Mark A. Watson

import schrodinger.application.jaguar.workflow_validation as wv
import schrodinger.application.jaguar.macro_pka_constants as constants

from schrodinger.application.jaguar.utils import get_total_charge
from schrodinger.application.jaguar.exceptions import JaguarRuntimeError

PROT_CHARGES = [1, 0]
DEPROT_CHARGES = [0, -1]


[docs]def check_conflicts(kwd, all_keywords): """ Raise Exception if keyword value is inconsistent with the other keywords. This is done in an adhoc case-by-case way. :type kwd: WorkflowKeyword :param kwd: reference Macro-pKa keyword :type all_keywords: dict of WorkflowKeyword instances indexed by name :param all_keywords: all the other Macro-pKa keywords set :raise WorkflowKeywordConflictError if conflicting values found. :return: True otherwise """ # Add any known conflicts here... allowed_charges = [PROT_CHARGES, DEPROT_CHARGES] conflicting_keys = ['protonate', 'deprotonate'] for ikey, key in enumerate(conflicting_keys): if kwd.name == key and kwd.value: other_key = conflicting_keys[ikey - 1] val = False if all_keywords[other_key].value != val: raise wv.WorkflowKeywordConflictError(kwd.name, other_key, val) other_key = 'relative_charges' val = allowed_charges[ikey] if all_keywords[other_key].value != all_keywords[other_key].default: raise wv.WorkflowKeywordConflictError(kwd.name, other_key, val) # General test for mutually exclusive options... non_default = (1 if all_keywords[key].value != all_keywords[key].default else 0 for key in constants.MUTUALLY_EXCLUSIVE_1) if sum(non_default) > 1: msg = "The following keywords are mutually exclusive;" msg += f" please adjust input file:\n{constants.MUTUALLY_EXCLUSIVE_1}" raise wv.WorkflowKeywordConflictError(msg=msg) # Process any known aliases... _process_aliases(kwd, all_keywords) return True
def _process_aliases(kwd, all_keywords): """ Handle alias keywords which map to the same input attribute. :type kwd: WorkflowKeyword :param kwd: reference Macro-pKa keyword :type all_keywords: dict of WorkflowKeyword instances indexed by name :param all_keywords: all the other Macro-pKa keywords set """ # Add any known aliases here... if kwd.name == 'protonate': if kwd.value == True: all_keywords['relative_charges'].value = PROT_CHARGES elif kwd.name == 'deprotonate': if kwd.value == True: all_keywords['relative_charges'].value = DEPROT_CHARGES
[docs]def validate_structures(spec): """ Perform a check to ensure that charge/multiplicity are consistent. :type spec: MacroKaInput :param spec: Macro-pKa input instance :raise: WorkflowConservationError if any test fails. """ st = spec.getInputMolecule() if st is None: raise JaguarRuntimeError("No input molecule specified!") charge = get_total_charge(st) # There is no way to set multiplicity by the user; the backend assume 1 mult = 1 _validate_charges(st, charge, mult)
def _validate_charges(st, charge, mult): """ Validate a structure. :type st: `structure.Structure` :param st: structure instance :type charge: int :param charge: structure total charge :type mult: int :param mult: specified multiplicity :raise: WorkflowConservationError if the specification is invalid. """ wv.estate_is_physical(st, charge, mult) wv.charge_is_consistent(st, charge)