westpa 2022.12__cp313-cp313-macosx_10_13_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of westpa might be problematic. Click here for more details.
- westpa/__init__.py +14 -0
- westpa/_version.py +21 -0
- westpa/analysis/__init__.py +5 -0
- westpa/analysis/core.py +746 -0
- westpa/analysis/statistics.py +27 -0
- westpa/analysis/trajectories.py +360 -0
- westpa/cli/__init__.py +0 -0
- westpa/cli/core/__init__.py +0 -0
- westpa/cli/core/w_fork.py +152 -0
- westpa/cli/core/w_init.py +230 -0
- westpa/cli/core/w_run.py +77 -0
- westpa/cli/core/w_states.py +212 -0
- westpa/cli/core/w_succ.py +99 -0
- westpa/cli/core/w_truncate.py +68 -0
- westpa/cli/tools/__init__.py +0 -0
- westpa/cli/tools/ploterr.py +506 -0
- westpa/cli/tools/plothist.py +706 -0
- westpa/cli/tools/w_assign.py +596 -0
- westpa/cli/tools/w_bins.py +166 -0
- westpa/cli/tools/w_crawl.py +119 -0
- westpa/cli/tools/w_direct.py +547 -0
- westpa/cli/tools/w_dumpsegs.py +94 -0
- westpa/cli/tools/w_eddist.py +506 -0
- westpa/cli/tools/w_fluxanl.py +376 -0
- westpa/cli/tools/w_ipa.py +833 -0
- westpa/cli/tools/w_kinavg.py +127 -0
- westpa/cli/tools/w_kinetics.py +96 -0
- westpa/cli/tools/w_multi_west.py +414 -0
- westpa/cli/tools/w_ntop.py +213 -0
- westpa/cli/tools/w_pdist.py +515 -0
- westpa/cli/tools/w_postanalysis_matrix.py +82 -0
- westpa/cli/tools/w_postanalysis_reweight.py +53 -0
- westpa/cli/tools/w_red.py +491 -0
- westpa/cli/tools/w_reweight.py +780 -0
- westpa/cli/tools/w_select.py +226 -0
- westpa/cli/tools/w_stateprobs.py +111 -0
- westpa/cli/tools/w_trace.py +599 -0
- westpa/core/__init__.py +0 -0
- westpa/core/_rc.py +673 -0
- westpa/core/binning/__init__.py +55 -0
- westpa/core/binning/_assign.cpython-313-darwin.so +0 -0
- westpa/core/binning/assign.py +455 -0
- westpa/core/binning/binless.py +96 -0
- westpa/core/binning/binless_driver.py +54 -0
- westpa/core/binning/binless_manager.py +190 -0
- westpa/core/binning/bins.py +47 -0
- westpa/core/binning/mab.py +506 -0
- westpa/core/binning/mab_driver.py +54 -0
- westpa/core/binning/mab_manager.py +198 -0
- westpa/core/data_manager.py +1694 -0
- westpa/core/extloader.py +74 -0
- westpa/core/h5io.py +995 -0
- westpa/core/kinetics/__init__.py +24 -0
- westpa/core/kinetics/_kinetics.cpython-313-darwin.so +0 -0
- westpa/core/kinetics/events.py +147 -0
- westpa/core/kinetics/matrates.py +156 -0
- westpa/core/kinetics/rate_averaging.py +266 -0
- westpa/core/progress.py +218 -0
- westpa/core/propagators/__init__.py +54 -0
- westpa/core/propagators/executable.py +719 -0
- westpa/core/reweight/__init__.py +14 -0
- westpa/core/reweight/_reweight.cpython-313-darwin.so +0 -0
- westpa/core/reweight/matrix.py +126 -0
- westpa/core/segment.py +119 -0
- westpa/core/sim_manager.py +835 -0
- westpa/core/states.py +359 -0
- westpa/core/systems.py +93 -0
- westpa/core/textio.py +74 -0
- westpa/core/trajectory.py +330 -0
- westpa/core/we_driver.py +910 -0
- westpa/core/wm_ops.py +43 -0
- westpa/core/yamlcfg.py +391 -0
- westpa/fasthist/__init__.py +34 -0
- westpa/fasthist/_fasthist.cpython-313-darwin.so +0 -0
- westpa/mclib/__init__.py +271 -0
- westpa/mclib/__main__.py +28 -0
- westpa/mclib/_mclib.cpython-313-darwin.so +0 -0
- westpa/oldtools/__init__.py +4 -0
- westpa/oldtools/aframe/__init__.py +35 -0
- westpa/oldtools/aframe/atool.py +75 -0
- westpa/oldtools/aframe/base_mixin.py +26 -0
- westpa/oldtools/aframe/binning.py +178 -0
- westpa/oldtools/aframe/data_reader.py +560 -0
- westpa/oldtools/aframe/iter_range.py +200 -0
- westpa/oldtools/aframe/kinetics.py +117 -0
- westpa/oldtools/aframe/mcbs.py +153 -0
- westpa/oldtools/aframe/output.py +39 -0
- westpa/oldtools/aframe/plotting.py +90 -0
- westpa/oldtools/aframe/trajwalker.py +126 -0
- westpa/oldtools/aframe/transitions.py +469 -0
- westpa/oldtools/cmds/__init__.py +0 -0
- westpa/oldtools/cmds/w_ttimes.py +361 -0
- westpa/oldtools/files.py +34 -0
- westpa/oldtools/miscfn.py +23 -0
- westpa/oldtools/stats/__init__.py +4 -0
- westpa/oldtools/stats/accumulator.py +35 -0
- westpa/oldtools/stats/edfs.py +129 -0
- westpa/oldtools/stats/mcbs.py +96 -0
- westpa/tools/__init__.py +33 -0
- westpa/tools/binning.py +472 -0
- westpa/tools/core.py +340 -0
- westpa/tools/data_reader.py +159 -0
- westpa/tools/dtypes.py +31 -0
- westpa/tools/iter_range.py +198 -0
- westpa/tools/kinetics_tool.py +340 -0
- westpa/tools/plot.py +283 -0
- westpa/tools/progress.py +17 -0
- westpa/tools/selected_segs.py +154 -0
- westpa/tools/wipi.py +751 -0
- westpa/trajtree/__init__.py +4 -0
- westpa/trajtree/_trajtree.cpython-313-darwin.so +0 -0
- westpa/trajtree/trajtree.py +117 -0
- westpa/westext/__init__.py +0 -0
- westpa/westext/adaptvoronoi/__init__.py +3 -0
- westpa/westext/adaptvoronoi/adaptVor_driver.py +214 -0
- westpa/westext/hamsm_restarting/__init__.py +3 -0
- westpa/westext/hamsm_restarting/example_overrides.py +35 -0
- westpa/westext/hamsm_restarting/restart_driver.py +1165 -0
- westpa/westext/stringmethod/__init__.py +11 -0
- westpa/westext/stringmethod/fourier_fitting.py +69 -0
- westpa/westext/stringmethod/string_driver.py +253 -0
- westpa/westext/stringmethod/string_method.py +306 -0
- westpa/westext/weed/BinCluster.py +180 -0
- westpa/westext/weed/ProbAdjustEquil.py +100 -0
- westpa/westext/weed/UncertMath.py +247 -0
- westpa/westext/weed/__init__.py +10 -0
- westpa/westext/weed/weed_driver.py +192 -0
- westpa/westext/wess/ProbAdjust.py +101 -0
- westpa/westext/wess/__init__.py +6 -0
- westpa/westext/wess/wess_driver.py +217 -0
- westpa/work_managers/__init__.py +57 -0
- westpa/work_managers/core.py +396 -0
- westpa/work_managers/environment.py +134 -0
- westpa/work_managers/mpi.py +318 -0
- westpa/work_managers/processes.py +187 -0
- westpa/work_managers/serial.py +28 -0
- westpa/work_managers/threads.py +79 -0
- westpa/work_managers/zeromq/__init__.py +20 -0
- westpa/work_managers/zeromq/core.py +641 -0
- westpa/work_managers/zeromq/node.py +131 -0
- westpa/work_managers/zeromq/work_manager.py +526 -0
- westpa/work_managers/zeromq/worker.py +320 -0
- westpa-2022.12.dist-info/AUTHORS +22 -0
- westpa-2022.12.dist-info/LICENSE +21 -0
- westpa-2022.12.dist-info/METADATA +193 -0
- westpa-2022.12.dist-info/RECORD +149 -0
- westpa-2022.12.dist-info/WHEEL +6 -0
- westpa-2022.12.dist-info/entry_points.txt +29 -0
- westpa-2022.12.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
from h5py import File as H5File
|
|
2
|
+
import numpy as np
|
|
3
|
+
from westpa import rc
|
|
4
|
+
from westpa.tools import WESTParallelTool
|
|
5
|
+
|
|
6
|
+
try:
|
|
7
|
+
from numpy import trapezoid
|
|
8
|
+
except ImportError:
|
|
9
|
+
from numpy import trapz as trapezoid
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class DurationCorrector(object):
|
|
13
|
+
@staticmethod
|
|
14
|
+
def from_kinetics_file(directh5, istate, fstate, dtau, n_iters=None):
|
|
15
|
+
iter_slice = slice(n_iters)
|
|
16
|
+
|
|
17
|
+
if isinstance(directh5, H5File):
|
|
18
|
+
dataset = directh5['durations'][iter_slice]
|
|
19
|
+
else:
|
|
20
|
+
with H5File(directh5, 'r') as directh5:
|
|
21
|
+
dataset = directh5['durations'][iter_slice]
|
|
22
|
+
|
|
23
|
+
torf = np.logical_and(dataset['istate'] == istate, dataset['fstate'] == fstate)
|
|
24
|
+
torf = np.logical_and(torf, dataset['weight'] > 0)
|
|
25
|
+
|
|
26
|
+
durations = dataset['duration']
|
|
27
|
+
weights = dataset['weight']
|
|
28
|
+
|
|
29
|
+
weights[~torf] = 0.0 # mask off irrelevant flux
|
|
30
|
+
|
|
31
|
+
return DurationCorrector(durations, weights, dtau)
|
|
32
|
+
|
|
33
|
+
def __init__(self, durations, weights, dtau, maxduration=None):
|
|
34
|
+
self.weights = np.array(weights)
|
|
35
|
+
self.durations = np.array(durations)
|
|
36
|
+
self.dtau = dtau
|
|
37
|
+
self._f_tilde = None
|
|
38
|
+
self._f_int1 = None
|
|
39
|
+
|
|
40
|
+
if maxduration is None:
|
|
41
|
+
self.maxduration = self.durations.shape[0]
|
|
42
|
+
else:
|
|
43
|
+
self.maxduration = maxduration
|
|
44
|
+
|
|
45
|
+
if dtau is None:
|
|
46
|
+
all_durations = []
|
|
47
|
+
all_durations.extend(durations)
|
|
48
|
+
all_durations.extend(np.arange(maxduration))
|
|
49
|
+
uniq_durations = np.unique(all_durations) # unique sorts automatically
|
|
50
|
+
self.dtau = np.min(np.diff(uniq_durations))
|
|
51
|
+
|
|
52
|
+
self._build_map()
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def event_duration_histogram(self):
|
|
56
|
+
return self._f_tilde
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def cumulative_event_duration_histogram(self):
|
|
60
|
+
return self._f_int1
|
|
61
|
+
|
|
62
|
+
def _build_map(self):
|
|
63
|
+
weights = self.weights
|
|
64
|
+
durations = self.durations
|
|
65
|
+
maxduration = self.maxduration
|
|
66
|
+
dtau = self.dtau
|
|
67
|
+
|
|
68
|
+
taugrid = np.arange(0, maxduration, dtau, dtype=float)
|
|
69
|
+
f_map = np.zeros(weights.shape, dtype=int) - 1
|
|
70
|
+
for i, tau in enumerate(taugrid):
|
|
71
|
+
matches = np.logical_and(durations >= tau, durations < tau + dtau)
|
|
72
|
+
f_map[matches] = i
|
|
73
|
+
|
|
74
|
+
self.taugrid = taugrid
|
|
75
|
+
self.f_map = f_map
|
|
76
|
+
|
|
77
|
+
def correction(self, iters, freqs=None):
|
|
78
|
+
r"""
|
|
79
|
+
Return the correction factor
|
|
80
|
+
|
|
81
|
+
__ __ -1
|
|
82
|
+
| t=theta tau=t |
|
|
83
|
+
| |\ |\ |
|
|
84
|
+
| | | ~ |
|
|
85
|
+
| | | f(tau) dtau dt | * maxduration
|
|
86
|
+
| \| \| |
|
|
87
|
+
| t=0 tau=0 |
|
|
88
|
+
|_ _|
|
|
89
|
+
|
|
90
|
+
where
|
|
91
|
+
~` ^
|
|
92
|
+
f(tau) is proportional to f(tau)/(theta-tau), and is normalized to
|
|
93
|
+
^
|
|
94
|
+
integrate to 1, and f(tau) is sum of the weights of walkers with
|
|
95
|
+
duration time tau.
|
|
96
|
+
|
|
97
|
+
---------
|
|
98
|
+
Arguments
|
|
99
|
+
---------
|
|
100
|
+
maxduration: the maximum duration time that could have been observed in
|
|
101
|
+
the simulation, which is usually equal to the length of the
|
|
102
|
+
simulation. This should be in units of tau.
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
if iters is None:
|
|
106
|
+
iters = np.arange(len(self.weights))
|
|
107
|
+
|
|
108
|
+
if freqs is None:
|
|
109
|
+
freqs = np.ones(len(iters), dtype=float)
|
|
110
|
+
|
|
111
|
+
maxduration = np.max(iters) + 1
|
|
112
|
+
|
|
113
|
+
f_map = self.f_map[iters]
|
|
114
|
+
weights = self.weights[iters]
|
|
115
|
+
taugrid = self.taugrid # [self.taugrid < maxduration]
|
|
116
|
+
|
|
117
|
+
weights *= freqs[:, None]
|
|
118
|
+
|
|
119
|
+
dtau = self.dtau
|
|
120
|
+
|
|
121
|
+
f_tilde = np.zeros(len(taugrid), dtype=float)
|
|
122
|
+
for i, tau in enumerate(taugrid):
|
|
123
|
+
if tau < maxduration:
|
|
124
|
+
f_tilde[i] = weights[f_map == i].sum() / (maxduration - tau + 1)
|
|
125
|
+
|
|
126
|
+
if f_tilde.sum() != 0:
|
|
127
|
+
f_tilde /= f_tilde.sum() * dtau
|
|
128
|
+
|
|
129
|
+
self._f_tilde = f_tilde
|
|
130
|
+
# now integrate f_tilde twice
|
|
131
|
+
# integral1[t/dtau] gives the integral of f_tilde(tau) dtau from 0 to t
|
|
132
|
+
self._f_int1 = integral1 = np.zeros(f_tilde.shape)
|
|
133
|
+
|
|
134
|
+
for i, tau in enumerate(taugrid):
|
|
135
|
+
if i > 0 and tau < maxduration:
|
|
136
|
+
integral1[i] = trapezoid(f_tilde[: i + 1], taugrid[: i + 1])
|
|
137
|
+
|
|
138
|
+
integral2 = trapezoid(integral1, taugrid)
|
|
139
|
+
|
|
140
|
+
if integral2 == 0:
|
|
141
|
+
return 0.0
|
|
142
|
+
return maxduration / integral2
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def get_raw_rates(directh5, istate, fstate, n_iters=None):
|
|
146
|
+
rate_evol = directh5['rate_evolution'][slice(n_iters), istate, fstate]
|
|
147
|
+
avg = rate_evol['expected']
|
|
148
|
+
|
|
149
|
+
return avg
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def calc_avg_rate(directh5_path, istate, fstate, **kwargs):
|
|
153
|
+
"""
|
|
154
|
+
Return the raw or RED-corrected rate constant with the confidence interval.
|
|
155
|
+
|
|
156
|
+
---------
|
|
157
|
+
Arguments
|
|
158
|
+
---------
|
|
159
|
+
dt: timestep (ps)
|
|
160
|
+
nstiter: duration of each iteration (number of steps)
|
|
161
|
+
ntpr: report inteval (number of steps)
|
|
162
|
+
|
|
163
|
+
"""
|
|
164
|
+
|
|
165
|
+
n_iters = kwargs.pop("n_iters", None)
|
|
166
|
+
|
|
167
|
+
ntpr = kwargs.pop("report_interval", 20)
|
|
168
|
+
nstiter = kwargs.pop("n_steps_iter", 1000)
|
|
169
|
+
callback = kwargs.pop("callback", None)
|
|
170
|
+
|
|
171
|
+
red = kwargs.pop("red", False)
|
|
172
|
+
|
|
173
|
+
if len(kwargs) > 0:
|
|
174
|
+
raise ValueError("unparsed kwargs")
|
|
175
|
+
|
|
176
|
+
dtau = float(ntpr) / nstiter
|
|
177
|
+
dc = None
|
|
178
|
+
|
|
179
|
+
with H5File(directh5_path, 'r') as directh5:
|
|
180
|
+
if n_iters is None:
|
|
181
|
+
n_iters = directh5['rate_evolution'].shape[0]
|
|
182
|
+
|
|
183
|
+
rate_evol = directh5['rate_evolution'][n_iters - 1, istate, fstate]
|
|
184
|
+
rate = rate_evol['expected']
|
|
185
|
+
|
|
186
|
+
if red:
|
|
187
|
+
dc = DurationCorrector.from_kinetics_file(directh5, istate, fstate, dtau, n_iters)
|
|
188
|
+
|
|
189
|
+
if callback is not None:
|
|
190
|
+
kw = {"correction": dc}
|
|
191
|
+
callback(**kw)
|
|
192
|
+
|
|
193
|
+
iters = np.arange(n_iters)
|
|
194
|
+
|
|
195
|
+
correction = dc.correction(iters) if dc else 1.0
|
|
196
|
+
|
|
197
|
+
rate *= correction
|
|
198
|
+
|
|
199
|
+
return rate
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def calc_rates(directh5_path, istate, fstate, **kwargs):
|
|
203
|
+
"""
|
|
204
|
+
Return the raw and RED-corrected rate constants vs. iterations.
|
|
205
|
+
This code is faster than calling calc_rate() iteratively
|
|
206
|
+
|
|
207
|
+
---------
|
|
208
|
+
Arguments
|
|
209
|
+
---------
|
|
210
|
+
dt: timestep (ps)
|
|
211
|
+
nstiter: duration of each iteration (number of steps)
|
|
212
|
+
ntpr: report inteval (number of steps)
|
|
213
|
+
|
|
214
|
+
"""
|
|
215
|
+
|
|
216
|
+
n_iters = kwargs.pop("n_iters", None)
|
|
217
|
+
|
|
218
|
+
ntpr = kwargs.pop("report_interval", 20)
|
|
219
|
+
nstiter = kwargs.pop("n_steps_iter", 1000)
|
|
220
|
+
callback = kwargs.pop("callback", None)
|
|
221
|
+
|
|
222
|
+
red = kwargs.pop("red", False)
|
|
223
|
+
|
|
224
|
+
if len(kwargs) > 0:
|
|
225
|
+
raise ValueError("unparsed kwargs")
|
|
226
|
+
|
|
227
|
+
dtau = float(ntpr) / nstiter
|
|
228
|
+
dc = None
|
|
229
|
+
|
|
230
|
+
with H5File(directh5_path, 'r') as directh5:
|
|
231
|
+
rate_evol, cilb, ciub = get_raw_rates(directh5, istate, fstate, n_iters)
|
|
232
|
+
if n_iters is None:
|
|
233
|
+
n_iters = len(rate_evol)
|
|
234
|
+
if red:
|
|
235
|
+
dc = DurationCorrector.from_kinetics_file(directh5, istate, fstate, dtau, n_iters)
|
|
236
|
+
|
|
237
|
+
if callback is not None:
|
|
238
|
+
kw = {"correction": dc}
|
|
239
|
+
callback(**kw)
|
|
240
|
+
|
|
241
|
+
raw_rates = np.zeros(n_iters)
|
|
242
|
+
|
|
243
|
+
rates = np.zeros(n_iters)
|
|
244
|
+
|
|
245
|
+
for i in range(n_iters):
|
|
246
|
+
i_iter = i + 1
|
|
247
|
+
print("\riter %d/%d (%3.0f%%)" % (i_iter, n_iters, i_iter * 100.0 / n_iters), end="")
|
|
248
|
+
|
|
249
|
+
r = rate_evol[i]
|
|
250
|
+
|
|
251
|
+
iters = np.arange(i_iter)
|
|
252
|
+
|
|
253
|
+
correction = dc.correction(iters) if dc else 1.0
|
|
254
|
+
|
|
255
|
+
raw_rates[i] = r
|
|
256
|
+
rates[i] = raw_rates[i] * correction
|
|
257
|
+
|
|
258
|
+
print("\n")
|
|
259
|
+
|
|
260
|
+
return rates
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
class RateCalculator:
|
|
264
|
+
def __init__(self, directh5, istate, fstate, assignh5=None, **kwargs):
|
|
265
|
+
n_iters = kwargs.pop("n_iters", None)
|
|
266
|
+
ntpr = kwargs.pop("report_interval", 20)
|
|
267
|
+
nstiter = kwargs.pop("n_steps_iter", 1000)
|
|
268
|
+
|
|
269
|
+
if len(kwargs) > 0:
|
|
270
|
+
for k in kwargs:
|
|
271
|
+
print(k)
|
|
272
|
+
raise ValueError("unparsed kwargs")
|
|
273
|
+
|
|
274
|
+
dtau = float(ntpr) / nstiter
|
|
275
|
+
|
|
276
|
+
with H5File(directh5, 'r') as f:
|
|
277
|
+
state_labels = {}
|
|
278
|
+
for i, raw_label in enumerate(f['state_labels']):
|
|
279
|
+
label = raw_label.decode() if isinstance(raw_label, bytes) else raw_label
|
|
280
|
+
state_labels[label] = i
|
|
281
|
+
if istate not in state_labels:
|
|
282
|
+
raise ValueError(f"istate not found: {istate}, available options are {list(state_labels.keys())}")
|
|
283
|
+
if fstate not in state_labels:
|
|
284
|
+
raise ValueError(f"istate not found: {fstate}, available options are {list(state_labels.keys())}")
|
|
285
|
+
istate = state_labels[istate]
|
|
286
|
+
fstate = state_labels[fstate]
|
|
287
|
+
cond_fluxes = f['conditional_fluxes'][slice(n_iters), istate, fstate]
|
|
288
|
+
|
|
289
|
+
if assignh5 is not None:
|
|
290
|
+
with H5File(assignh5, 'r') as f:
|
|
291
|
+
pops = f['labeled_populations'][slice(n_iters)]
|
|
292
|
+
pops = pops.sum(axis=2)
|
|
293
|
+
else:
|
|
294
|
+
pops = None
|
|
295
|
+
|
|
296
|
+
self._dc = None
|
|
297
|
+
self._pops = pops
|
|
298
|
+
self._cond_fluxes = cond_fluxes
|
|
299
|
+
self._dtau = dtau
|
|
300
|
+
self._directh5 = directh5
|
|
301
|
+
self._assignh5 = assignh5
|
|
302
|
+
self._istate = istate
|
|
303
|
+
self._fstate = fstate
|
|
304
|
+
|
|
305
|
+
@property
|
|
306
|
+
def conditional_fluxes(self):
|
|
307
|
+
return self._cond_fluxes
|
|
308
|
+
|
|
309
|
+
@property
|
|
310
|
+
def populations(self):
|
|
311
|
+
return self._pops
|
|
312
|
+
|
|
313
|
+
@property
|
|
314
|
+
def tau(self):
|
|
315
|
+
return self._tau
|
|
316
|
+
|
|
317
|
+
@property
|
|
318
|
+
def dtau(self):
|
|
319
|
+
return self._dtau
|
|
320
|
+
|
|
321
|
+
@property
|
|
322
|
+
def istate(self):
|
|
323
|
+
return self._istate
|
|
324
|
+
|
|
325
|
+
@property
|
|
326
|
+
def fstate(self):
|
|
327
|
+
return self._fstate
|
|
328
|
+
|
|
329
|
+
@property
|
|
330
|
+
def n_iters(self):
|
|
331
|
+
return len(self.conditional_fluxes)
|
|
332
|
+
|
|
333
|
+
def _get_corrector(self):
|
|
334
|
+
if self._dc is None:
|
|
335
|
+
with H5File(self._directh5, 'r') as f:
|
|
336
|
+
self._dc = DurationCorrector.from_kinetics_file(f, self.istate, self.fstate, self.dtau, self.n_iters)
|
|
337
|
+
|
|
338
|
+
return self._dc
|
|
339
|
+
|
|
340
|
+
def calc_rate(self, i_iter=None, red=False, **kwargs):
|
|
341
|
+
if i_iter is None:
|
|
342
|
+
i_iter = self.n_iters
|
|
343
|
+
|
|
344
|
+
dc = self._get_corrector() if red else None
|
|
345
|
+
found = False
|
|
346
|
+
with H5File(self._directh5, 'r') as f:
|
|
347
|
+
for i in range(f['rate_evolution'].shape[0]):
|
|
348
|
+
rate_evol = f['rate_evolution'][i, self.istate, self.fstate]
|
|
349
|
+
start = rate_evol['iter_start']
|
|
350
|
+
stop = rate_evol['iter_stop']
|
|
351
|
+
|
|
352
|
+
if i_iter >= start and i_iter < stop:
|
|
353
|
+
rate = rate_evol['expected']
|
|
354
|
+
found = True
|
|
355
|
+
break
|
|
356
|
+
|
|
357
|
+
if not found:
|
|
358
|
+
self.log.error("Can't find rate evolution data for iteration %d!" % i_iter)
|
|
359
|
+
|
|
360
|
+
if dc:
|
|
361
|
+
iters = np.arange(i_iter)
|
|
362
|
+
correction = dc.correction(iters)
|
|
363
|
+
rate *= correction
|
|
364
|
+
|
|
365
|
+
return rate
|
|
366
|
+
|
|
367
|
+
def calc_rates(self, n_iters=None, **kwargs):
|
|
368
|
+
if n_iters is None:
|
|
369
|
+
n_iters = self.n_iters
|
|
370
|
+
|
|
371
|
+
rates = np.zeros(n_iters)
|
|
372
|
+
|
|
373
|
+
for i in range(n_iters):
|
|
374
|
+
i_iter = i + 1
|
|
375
|
+
print("\riter %d/%d (%3.0f%%)" % (i_iter, n_iters, i_iter * 100.0 / n_iters), end="")
|
|
376
|
+
|
|
377
|
+
r = self.calc_rate(i_iter, **kwargs)
|
|
378
|
+
|
|
379
|
+
rates[i] = r
|
|
380
|
+
|
|
381
|
+
print("\n")
|
|
382
|
+
|
|
383
|
+
return rates
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
class WRed(WESTParallelTool):
|
|
387
|
+
prog = 'w_red'
|
|
388
|
+
description = '''\
|
|
389
|
+
Apply the RED scheme to estimate steady-state WE fluxes from
|
|
390
|
+
shorter trajectories.
|
|
391
|
+
|
|
392
|
+
-----------------------------------------------------------------------------
|
|
393
|
+
Source data
|
|
394
|
+
-----------------------------------------------------------------------------
|
|
395
|
+
|
|
396
|
+
Source data is provided as a w_ipa "scheme" which is typically defined
|
|
397
|
+
in the west.cfg file. For instance, if a user wishes to estimate RED
|
|
398
|
+
fluxes for a scheme named "DEFAULT" that argument would be provided
|
|
399
|
+
to w_red and WRed would estimate RED fluxes based off of the data
|
|
400
|
+
contained in the assign.h5 and direct.h5 files in ANALYSIS/DEFAULT.
|
|
401
|
+
|
|
402
|
+
'''
|
|
403
|
+
|
|
404
|
+
def __init__(self):
|
|
405
|
+
super().__init__()
|
|
406
|
+
|
|
407
|
+
def go(self):
|
|
408
|
+
try:
|
|
409
|
+
rc.config['west']['analysis']['red']
|
|
410
|
+
except Exception:
|
|
411
|
+
raise ValueError('No RED parameters are specified in west.cfg.')
|
|
412
|
+
try:
|
|
413
|
+
rc.config['west']['analysis']['red']['scheme']
|
|
414
|
+
except Exception:
|
|
415
|
+
raise ValueError('No scheme specified for RED calculation in west.cfg.')
|
|
416
|
+
try:
|
|
417
|
+
rc.config['west']['analysis']['red']['istate_label']
|
|
418
|
+
except Exception:
|
|
419
|
+
raise ValueError('No intial state label specified for RED calculation in west.cfg.')
|
|
420
|
+
try:
|
|
421
|
+
rc.config['west']['analysis']['red']['fstate_label']
|
|
422
|
+
except Exception:
|
|
423
|
+
raise ValueError('No final state label specified for RED calculation in west.cfg.')
|
|
424
|
+
try:
|
|
425
|
+
rc.config['west']['analysis']['red']['nstiter']
|
|
426
|
+
except Exception:
|
|
427
|
+
raise ValueError('Time step not specified in west.cfg.')
|
|
428
|
+
try:
|
|
429
|
+
rc.config['west']['analysis']['red']['nstrep']
|
|
430
|
+
except Exception:
|
|
431
|
+
raise ValueError('Time step not specified in west.cfg.')
|
|
432
|
+
|
|
433
|
+
if rc.config['west']['analysis']['kinetics']['evolution'] == "cumulative":
|
|
434
|
+
pass
|
|
435
|
+
else:
|
|
436
|
+
print("Only RED estimates with cumulative averaging are supported at this time.")
|
|
437
|
+
exit()
|
|
438
|
+
|
|
439
|
+
config = rc.config
|
|
440
|
+
adir = config.get(['west', 'analysis', 'directory'])
|
|
441
|
+
name = config.get(['west', 'analysis', 'red', 'scheme'])
|
|
442
|
+
istate = config.get(['west', 'analysis', 'red', 'istate_label'])
|
|
443
|
+
fstate = config.get(['west', 'analysis', 'red', 'fstate_label'])
|
|
444
|
+
n_steps_per_iter = config.get(['west', 'analysis', 'red', 'nstiter'])
|
|
445
|
+
n_steps_per_report = config.get(['west', 'analysis', 'red', 'nstrep'])
|
|
446
|
+
|
|
447
|
+
directh5path = '%s/%s/direct.h5' % (adir, name)
|
|
448
|
+
assignh5path = '%s/%s/assign.h5' % (adir, name)
|
|
449
|
+
|
|
450
|
+
print('\nConfig successfully read from west.cfg:')
|
|
451
|
+
print('--------------------------------------')
|
|
452
|
+
print('scheme: %s' % name)
|
|
453
|
+
print('states: %s -> %s' % (istate, fstate))
|
|
454
|
+
print('nstiter: %s' % n_steps_per_iter)
|
|
455
|
+
print('nstrep: %s' % n_steps_per_report)
|
|
456
|
+
print('--------------------------------------')
|
|
457
|
+
print('\nEstimating RED fluxes...')
|
|
458
|
+
rater = RateCalculator(
|
|
459
|
+
directh5path,
|
|
460
|
+
istate,
|
|
461
|
+
fstate,
|
|
462
|
+
n_steps_iter=n_steps_per_iter,
|
|
463
|
+
report_interval=n_steps_per_report,
|
|
464
|
+
assignh5=assignh5path,
|
|
465
|
+
)
|
|
466
|
+
|
|
467
|
+
rates = rater.calc_rates(red=True, callback=None)
|
|
468
|
+
|
|
469
|
+
with H5File(directh5path, "r+") as dest_file:
|
|
470
|
+
try:
|
|
471
|
+
dest_file.create_dataset('red_flux_evolution', data=rates)
|
|
472
|
+
print('saved RED fluxes to red_flux_evolution in ANALYSIS/%s/direct.h5' % name)
|
|
473
|
+
except Exception:
|
|
474
|
+
warning = input('Dataset already exists! Overwrite? (y/n)')
|
|
475
|
+
if warning == "y":
|
|
476
|
+
dest_file['red_flux_evolution'][...] = rates
|
|
477
|
+
print('saved RED fluxes to red_flux_evolution in ANALYSIS/%s/direct.h5' % name)
|
|
478
|
+
elif warning == "n":
|
|
479
|
+
np.save('ANALYSIS/%s/red.npy' % name, rates)
|
|
480
|
+
print('saved RED fluxes to red_flux_evolution.npy in ANALYSIS/%s' % name)
|
|
481
|
+
else:
|
|
482
|
+
print('red rates not saved. Exiting...')
|
|
483
|
+
exit
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
def entry_point():
|
|
487
|
+
WRed().main()
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
if __name__ == '__main__':
|
|
491
|
+
entry_point()
|