Source code for schrodinger.application.desmond.ana
"""
Desmond analyses
Copyright Schrodinger, LLC. All rights reserved.
"""
from bisect import bisect
from bisect import bisect_left
from schrodinger.application.desmond.packages import analysis
from schrodinger.application.desmond.packages import topo
from schrodinger.application.desmond.packages import traj
QUANTITY_CLASS_MAP = {
"angle": analysis.Angle,
"dihedral": analysis.Torsion,
"distance": analysis.Distance,
}
[docs]def calc_time_series(requests, model_fname, traj_fname):
"""
:type requests: `list` of requests where each request is a `list` of
quantity name, arguments, and (optional) time selection.
Examples::
[['dihedral', 1, 2, 3, 4],
['dihedral', 1, 2, 3, 4, {'begin':0, 'end':24.001}],]
:return: `list` of analysis results
"""
if not requests:
return []
models = list(topo.read_cms(model_fname))
tr = traj.read_traj(traj_fname)
sim_times = [fr.time for fr in tr]
analyzers, times = [], []
for req in requests:
has_opt = isinstance(req[-1], dict)
args = models + (req[1:-1] if has_opt else req[1:])
times.append(req[-1] if has_opt else None)
analyzers.append(QUANTITY_CLASS_MAP[req[0]](*args))
results = analysis.analyze(tr, *analyzers)
# FIXME: this is to undo the special treatment of analysis.analyze() when
# there is only one analyzer
if len(analyzers) == 1:
results = [results]
answer = []
for res, time_sel in zip(results, times):
if time_sel:
left = bisect_left(sim_times, time_sel['begin'])
right = bisect(sim_times, time_sel['end'])
answer.append(list(zip(sim_times[left:right], res[left:right])))
else:
answer.append(list(zip(sim_times, res)))
return answer
[docs]def calc_prob_profile(data, bin_width, min, max, is_periodic=False):
"""
FIXME: To be added.
"""
num_bin = int(float(max - min) / bin_width)
bin = [0] * num_bin
range = max - min
for e in data:
while (e > max):
e -= range
while (e < min):
e += range
i_bin = int((e - min) / bin_width + 0.5)
if (i_bin >= num_bin):
i_bin = i_bin - num_bin if (is_periodic) else num_bin - 1
elif (i_bin < 0):
i_bin = i_bin + num_bin if (is_periodic) else 0
bin[i_bin] += 1
result = []
num_data = len(data)
for i, e in enumerate(bin):
result.append((i * bin_width + min, float(e) / num_data))
return result