Source code for schrodinger.application.desmond.packages.msys.vdw

import math


[docs]def count_overrides(nb): ''' return the number of pairwise nonbonded interactions which are affected by the overrides in the given term table. ''' # count the number of atoms for each nonbonded param nparams = nb.params.nparams pcount = [0] * nparams for t in nb.terms: pcount[t.param.id] += 1 cnt = sum(pcount[pi.id] * pcount[pj.id] for pi, pj in nb.overrides()) return cnt
[docs]def duplicate_overrides(nb, pdict): # duplicate the overridden parameters and reassign while disambiguating nb.params.addProp('override', int) override_base = max(p['override'] for p in nb.params.params) + 1 for p, atoms in pdict.items(): p_ = p.duplicate() p['override'] = p.id + override_base p_['override'] = p_.id + override_base for a in atoms: nb.term(a.id).param = p_ # for the parameters that we duplicated, if there was already an # override involving that type, duplicate it with the new type. for (pi, pj), op in nb.overrides().items(): if pi == p: pi = p_ if pj == p: pj = p_ nb.setOverride(pi, pj, op)
[docs]def add_override(nb, **params): p = nb.override_params.addParam() for k, v in params.items(): nb.override_params.addProp(k, type(v)) p[k] = v return p
[docs]def apply_override(nb, sel1, sel2, p): t1 = set(nb.term(a.id).param for a in sel1) t2 = set(nb.term(a.id).param for a in sel2) for pi in t1: for pj in t2: nb.setOverride(pi, pj, p)
[docs]def Override(mol, sel1, sel2, **params): ''' override the nonbonded interaction for selections sel1 and sel2 with the given keyword parameters. ''' # add properties nb = mol.table('nonbonded') pdict = dict() for a in sel1 + sel2: p = nb.term(a.id).param pdict.setdefault(p, []).append(a) duplicate_overrides(nb, pdict) p = add_override(nb, **params) apply_override(nb, sel1, sel2, p)
[docs]def combine_arithmetic_geometric(pi, pj): sigma = 0.5 * (pi['sigma'] + pj['sigma']) epsilon = math.sqrt(pi['epsilon'] * pj['epsilon']) return sigma, epsilon
[docs]def combine_geometric(pi, pj): sigma = math.sqrt(pi['sigma'] * pj['sigma']) epsilon = math.sqrt(pi['epsilon'] * pj['epsilon']) return sigma, epsilon
[docs]def Scale(mol, sel1, sel2, scale_sigma, scale_epsilon): ''' scale the sigma and epsilon interaction for selections s1 and s2 with the given keyword parameters. ''' rule = mol.nonbonded_info.vdw_rule.lower() if rule == 'arithmetic/geometric': combine = combine_arithmetic_geometric elif rule == 'geometric': combine = combine_geometric else: raise ValueError("Don't understand vdw_rule '%s'" % rule) # partition selections by type, and call Override for each pair nb = mol.table('nonbonded') pdict1 = dict() pdict2 = dict() for a in sel1: p = nb.term(a.id).param pdict1.setdefault(p, []).append(a) for a in sel2: p = nb.term(a.id).param pdict2.setdefault(p, []).append(a) duplicate_overrides(nb, pdict1) duplicate_overrides(nb, pdict2) for p1, s1 in pdict1.items(): for p2, s2 in pdict2.items(): sigma, epsilon = combine(p1, p2) p = add_override(nb, sigma=scale_sigma * sigma, epsilon=scale_epsilon * epsilon) apply_override(nb, s1, s2, p)