westpa 2022.10__cp312-cp312-macosx_11_0_arm64.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 +59 -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 +378 -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 +486 -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-312-darwin.so +0 -0
- westpa/core/binning/assign.py +449 -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 +427 -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-312-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 +715 -0
- westpa/core/reweight/__init__.py +14 -0
- westpa/core/reweight/_reweight.cpython-312-darwin.so +0 -0
- westpa/core/reweight/matrix.py +126 -0
- westpa/core/segment.py +119 -0
- westpa/core/sim_manager.py +830 -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 +908 -0
- westpa/core/wm_ops.py +43 -0
- westpa/core/yamlcfg.py +391 -0
- westpa/fasthist/__init__.py +34 -0
- westpa/fasthist/__main__.py +110 -0
- westpa/fasthist/_fasthist.cpython-312-darwin.so +0 -0
- westpa/mclib/__init__.py +264 -0
- westpa/mclib/__main__.py +28 -0
- westpa/mclib/_mclib.cpython-312-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 +146 -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 +358 -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 +89 -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-312-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 +182 -0
- westpa/westext/wess/ProbAdjust.py +101 -0
- westpa/westext/wess/__init__.py +6 -0
- westpa/westext/wess/wess_driver.py +207 -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.10.dist-info/AUTHORS +22 -0
- westpa-2022.10.dist-info/LICENSE +21 -0
- westpa-2022.10.dist-info/METADATA +183 -0
- westpa-2022.10.dist-info/RECORD +150 -0
- westpa-2022.10.dist-info/WHEEL +5 -0
- westpa-2022.10.dist-info/entry_points.txt +29 -0
- westpa-2022.10.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def time_average(observable, iterations):
|
|
5
|
+
"""Compute the time average of an observable.
|
|
6
|
+
|
|
7
|
+
Parameters
|
|
8
|
+
----------
|
|
9
|
+
observable : Callable[[Walker], ArrayLike]
|
|
10
|
+
Function that takes a walker as input and returns a number or
|
|
11
|
+
a fixed-size array of numbers.
|
|
12
|
+
iterations : Sequence[Iteration]
|
|
13
|
+
Sequence of iterations over which to compute the average.
|
|
14
|
+
|
|
15
|
+
Returns
|
|
16
|
+
-------
|
|
17
|
+
ArrayLike
|
|
18
|
+
The time average of `observable` over `iterations`.
|
|
19
|
+
|
|
20
|
+
"""
|
|
21
|
+
for iteration in iterations:
|
|
22
|
+
values = [observable(walker) for walker in iteration]
|
|
23
|
+
try:
|
|
24
|
+
value += np.dot(iteration.weights, values)
|
|
25
|
+
except NameError:
|
|
26
|
+
value = np.dot(iteration.weights, values)
|
|
27
|
+
return value / len(iterations)
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
import concurrent.futures as cf
|
|
2
|
+
import functools
|
|
3
|
+
import inspect
|
|
4
|
+
import operator
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
import mdtraj
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
10
|
+
from tqdm import tqdm
|
|
11
|
+
from typing import Callable
|
|
12
|
+
from westpa.analysis.core import Walker, Trace
|
|
13
|
+
from westpa.core.states import InitialState
|
|
14
|
+
from westpa.core.h5io import WESTIterationFile
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Trajectory:
|
|
18
|
+
"""A callable that returns the trajectory of a walker or trace.
|
|
19
|
+
|
|
20
|
+
Parameters
|
|
21
|
+
----------
|
|
22
|
+
fget : callable
|
|
23
|
+
Function for retrieving a single trajectory segment. Must take a
|
|
24
|
+
:class:`Walker` instance as its first argument and accept a boolean
|
|
25
|
+
keyword argument `include_initpoint`. The function should return a
|
|
26
|
+
sequence (e.g., a list or ndarray) representing the trajectory of
|
|
27
|
+
the walker. If `include_initpoint` is True, the trajectory segment
|
|
28
|
+
should include its initial point. Otherwise, the trajectory segment
|
|
29
|
+
should exclude its initial point.
|
|
30
|
+
fconcat : callable, optional
|
|
31
|
+
Function for concatenating trajectory segments. Must take a sequence
|
|
32
|
+
of trajectory segments as input and return their concatenation. The
|
|
33
|
+
default concatenation function is :func:`concatenate`.
|
|
34
|
+
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(self, fget=None, *, fconcat=None):
|
|
38
|
+
if fget is None:
|
|
39
|
+
return functools.partial(self.__init__, fconcat=fconcat)
|
|
40
|
+
|
|
41
|
+
if 'include_initpoint' not in inspect.signature(fget).parameters:
|
|
42
|
+
raise ValueError("'fget' must accept a parameter 'include_initpoint'")
|
|
43
|
+
|
|
44
|
+
self._fget = fget
|
|
45
|
+
self.fconcat = fconcat
|
|
46
|
+
|
|
47
|
+
self._segment_collector = SegmentCollector(self)
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def segment_collector(self):
|
|
51
|
+
"""SegmentCollector: Segment retrieval manager."""
|
|
52
|
+
return self._segment_collector
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def fget(self):
|
|
56
|
+
"""callable: Function for getting trajectory segments."""
|
|
57
|
+
return self._fget
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def fconcat(self):
|
|
61
|
+
"""callable: Function for concatenating trajectory segments."""
|
|
62
|
+
return self._fconcat
|
|
63
|
+
|
|
64
|
+
@fconcat.setter
|
|
65
|
+
def fconcat(self, value):
|
|
66
|
+
if value is None:
|
|
67
|
+
value = concatenate
|
|
68
|
+
elif not isinstance(value, Callable):
|
|
69
|
+
raise TypeError("'fconcat' must be a callable object")
|
|
70
|
+
self._fconcat = value
|
|
71
|
+
|
|
72
|
+
def __call__(self, obj, include_initpoint=True, **kwargs):
|
|
73
|
+
if isinstance(obj, Walker):
|
|
74
|
+
value = self.fget(obj, include_initpoint=include_initpoint, **kwargs)
|
|
75
|
+
self._validate_segment(value)
|
|
76
|
+
return value
|
|
77
|
+
if isinstance(obj, Trace):
|
|
78
|
+
initpoint_mask = np.full(len(obj), False)
|
|
79
|
+
initpoint_mask[0] = include_initpoint
|
|
80
|
+
segments = self.segment_collector.get_segments(obj, initpoint_mask, **kwargs)
|
|
81
|
+
return self.fconcat(segments)
|
|
82
|
+
raise TypeError('argument must be a Walker or Trace instance')
|
|
83
|
+
|
|
84
|
+
def _validate_segment(self, value):
|
|
85
|
+
if not hasattr(value, '__getitem__'):
|
|
86
|
+
msg = f"{type(value).__name__!r} object can't be concatenated"
|
|
87
|
+
raise TypeError(msg)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class SegmentCollector:
|
|
91
|
+
"""An object that manages the retrieval of trajectory segments.
|
|
92
|
+
|
|
93
|
+
Parameters
|
|
94
|
+
----------
|
|
95
|
+
trajectory : Trajectory
|
|
96
|
+
The trajectory to which the segment collector is attached.
|
|
97
|
+
use_threads : bool, default False
|
|
98
|
+
Whether to use a pool of threads to retrieve trajectory segments
|
|
99
|
+
asynchronously. Setting this parameter to True may be may be
|
|
100
|
+
useful when segment retrieval is an I/O bound task.
|
|
101
|
+
max_workers : int, optional
|
|
102
|
+
Maximum number of threads to use. The default value is specified in the
|
|
103
|
+
`ThreadPoolExecutor <https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor>`_
|
|
104
|
+
documentation.
|
|
105
|
+
show_progress : bool, default False
|
|
106
|
+
Whether to show a progress bar when retrieving multiple segments.
|
|
107
|
+
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
def __init__(self, trajectory, use_threads=False, max_workers=None, show_progress=False):
|
|
111
|
+
self.trajectory = trajectory
|
|
112
|
+
self.use_threads = use_threads
|
|
113
|
+
self.max_workers = max_workers
|
|
114
|
+
self.show_progress = show_progress
|
|
115
|
+
|
|
116
|
+
@property
|
|
117
|
+
def trajectory(self):
|
|
118
|
+
return self._trajectory
|
|
119
|
+
|
|
120
|
+
@trajectory.setter
|
|
121
|
+
def trajectory(self, value):
|
|
122
|
+
if not isinstance(value, Trajectory):
|
|
123
|
+
msg = f'trajectory must be an instance of {Trajectory}'
|
|
124
|
+
raise TypeError(msg)
|
|
125
|
+
self._trajectory = value
|
|
126
|
+
|
|
127
|
+
@property
|
|
128
|
+
def use_threads(self):
|
|
129
|
+
return self._use_threads
|
|
130
|
+
|
|
131
|
+
@use_threads.setter
|
|
132
|
+
def use_threads(self, value):
|
|
133
|
+
if not isinstance(value, bool):
|
|
134
|
+
raise TypeError('use_threads must be True or False')
|
|
135
|
+
self._use_threads = value
|
|
136
|
+
|
|
137
|
+
@property
|
|
138
|
+
def max_workers(self):
|
|
139
|
+
return self._max_workers
|
|
140
|
+
|
|
141
|
+
@max_workers.setter
|
|
142
|
+
def max_workers(self, value):
|
|
143
|
+
if value is None:
|
|
144
|
+
self._max_workers = None
|
|
145
|
+
return
|
|
146
|
+
if value <= 0:
|
|
147
|
+
raise ValueError('max_workers must be greater than 0')
|
|
148
|
+
self._max_workers = value
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def show_progress(self):
|
|
152
|
+
return self._show_progress
|
|
153
|
+
|
|
154
|
+
@show_progress.setter
|
|
155
|
+
def show_progress(self, value):
|
|
156
|
+
if not isinstance(value, bool):
|
|
157
|
+
raise ValueError('show_progress must be True or False')
|
|
158
|
+
self._show_progress = value
|
|
159
|
+
|
|
160
|
+
def get_segments(self, walkers, initpoint_mask=None, **kwargs):
|
|
161
|
+
"""Retrieve the trajectories of multiple walkers.
|
|
162
|
+
|
|
163
|
+
Parameters
|
|
164
|
+
----------
|
|
165
|
+
walkers : sequence of Walker
|
|
166
|
+
The walkers for which to retrieve trajectories.
|
|
167
|
+
initpoint_mask : sequence of bool, optional
|
|
168
|
+
A Boolean mask indicating whether each trajectory segment should
|
|
169
|
+
include (True) or exclude (False) its initial point. Default is
|
|
170
|
+
all True.
|
|
171
|
+
|
|
172
|
+
Returns
|
|
173
|
+
-------
|
|
174
|
+
list of sequences
|
|
175
|
+
The trajectory of each walker.
|
|
176
|
+
|
|
177
|
+
"""
|
|
178
|
+
if initpoint_mask is None:
|
|
179
|
+
initpoint_mask = np.full(len(walkers), True)
|
|
180
|
+
else:
|
|
181
|
+
initpoint_mask = np.asarray(initpoint_mask, dtype=bool)
|
|
182
|
+
|
|
183
|
+
get_segment = functools.partial(self.trajectory, **kwargs)
|
|
184
|
+
|
|
185
|
+
tqdm_kwargs = dict(
|
|
186
|
+
desc='Retrieving segments',
|
|
187
|
+
disable=(not self.show_progress),
|
|
188
|
+
position=0,
|
|
189
|
+
total=len(walkers),
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
if self.use_threads:
|
|
193
|
+
with cf.ThreadPoolExecutor(self.max_workers) as executor:
|
|
194
|
+
future_to_key = {
|
|
195
|
+
executor.submit(get_segment, walker, include_initpoint=i): key
|
|
196
|
+
for key, (walker, i) in enumerate(zip(walkers, initpoint_mask))
|
|
197
|
+
}
|
|
198
|
+
futures = list(tqdm(cf.as_completed(future_to_key), **tqdm_kwargs))
|
|
199
|
+
futures.sort(key=future_to_key.get)
|
|
200
|
+
segments = (future.result() for future in futures)
|
|
201
|
+
else:
|
|
202
|
+
it = (get_segment(walker, include_initpoint=i) for walker, i in zip(walkers, initpoint_mask))
|
|
203
|
+
segments = tqdm(it, **tqdm_kwargs)
|
|
204
|
+
|
|
205
|
+
return list(segments)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class BasicMDTrajectory(Trajectory):
|
|
209
|
+
"""Trajectory reader for MD trajectories stored as in the
|
|
210
|
+
`Basic Tutorial <https://github.com/westpa/westpa_tutorials/tree/main/basic_nacl>`_.
|
|
211
|
+
|
|
212
|
+
Parameters
|
|
213
|
+
----------
|
|
214
|
+
top : str or mdtraj.Topology, default 'bstate.pdb'
|
|
215
|
+
traj_ext : str, default '.dcd'
|
|
216
|
+
state_ext : str, default '.xml'
|
|
217
|
+
sim_root : str, default '.'
|
|
218
|
+
|
|
219
|
+
"""
|
|
220
|
+
|
|
221
|
+
def __init__(self, top='bstate.pdb', traj_ext='.dcd', state_ext='.xml', sim_root='.'):
|
|
222
|
+
self.top = top
|
|
223
|
+
self.traj_ext = traj_ext
|
|
224
|
+
self.state_ext = state_ext
|
|
225
|
+
self.sim_root = sim_root
|
|
226
|
+
|
|
227
|
+
def fget(walker, include_initpoint=True, atom_indices=None, sim_root=None):
|
|
228
|
+
sim_root = sim_root or self.sim_root
|
|
229
|
+
|
|
230
|
+
if isinstance(self.top, str):
|
|
231
|
+
top = os.path.join(sim_root, 'common_files', self.top)
|
|
232
|
+
else:
|
|
233
|
+
top = self.top
|
|
234
|
+
|
|
235
|
+
path = os.path.join(
|
|
236
|
+
sim_root,
|
|
237
|
+
'traj_segs',
|
|
238
|
+
format(walker.iteration.number, '06d'),
|
|
239
|
+
format(walker.index, '06d'),
|
|
240
|
+
'seg' + self.traj_ext,
|
|
241
|
+
)
|
|
242
|
+
if top is not None:
|
|
243
|
+
traj = mdtraj.load(path, top=top)
|
|
244
|
+
else:
|
|
245
|
+
traj = mdtraj.load(path)
|
|
246
|
+
|
|
247
|
+
if include_initpoint:
|
|
248
|
+
parent = walker.parent
|
|
249
|
+
|
|
250
|
+
if isinstance(parent, InitialState):
|
|
251
|
+
if parent.istate_type == InitialState.ISTATE_TYPE_BASIS:
|
|
252
|
+
path = os.path.join(
|
|
253
|
+
sim_root,
|
|
254
|
+
'bstates',
|
|
255
|
+
parent.basis_state.auxref,
|
|
256
|
+
)
|
|
257
|
+
else:
|
|
258
|
+
path = os.path.join(
|
|
259
|
+
sim_root,
|
|
260
|
+
'istates',
|
|
261
|
+
str(parent.iter_created),
|
|
262
|
+
str(parent.state_id) + self.state_ext,
|
|
263
|
+
)
|
|
264
|
+
else:
|
|
265
|
+
path = os.path.join(
|
|
266
|
+
sim_root,
|
|
267
|
+
'traj_segs',
|
|
268
|
+
format(walker.iteration.number - 1, '06d'),
|
|
269
|
+
format(parent.index, '06d'),
|
|
270
|
+
'seg' + self.state_ext,
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
frame = mdtraj.load(path, top=traj.top)
|
|
274
|
+
traj = frame.join(traj, check_topology=False)
|
|
275
|
+
|
|
276
|
+
if atom_indices is not None:
|
|
277
|
+
traj.atom_slice(atom_indices, inplace=True)
|
|
278
|
+
|
|
279
|
+
return traj
|
|
280
|
+
|
|
281
|
+
super().__init__(fget)
|
|
282
|
+
|
|
283
|
+
self.segment_collector.use_threads = True
|
|
284
|
+
self.segment_collector.show_progress = True
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
class HDF5MDTrajectory(Trajectory):
|
|
288
|
+
"""Trajectory reader for MD trajectories stored by the HDF5 framework."""
|
|
289
|
+
|
|
290
|
+
def __init__(self):
|
|
291
|
+
def fget(walker, include_initpoint=True, atom_indices=None):
|
|
292
|
+
iteration = walker.iteration
|
|
293
|
+
|
|
294
|
+
try:
|
|
295
|
+
link = iteration.h5group['trajectories']
|
|
296
|
+
except KeyError:
|
|
297
|
+
msg = 'the HDF5 framework does not appear to have been used to store trajectories for this run'
|
|
298
|
+
raise ValueError(msg)
|
|
299
|
+
|
|
300
|
+
with WESTIterationFile(link.file.filename) as traj_file:
|
|
301
|
+
traj = traj_file.read_as_traj(
|
|
302
|
+
iteration=iteration.number,
|
|
303
|
+
segment=walker.index,
|
|
304
|
+
atom_indices=atom_indices,
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
if include_initpoint:
|
|
308
|
+
parent = walker.parent
|
|
309
|
+
|
|
310
|
+
if isinstance(parent, InitialState):
|
|
311
|
+
if parent.istate_type == InitialState.ISTATE_TYPE_BASIS:
|
|
312
|
+
link = walker.run.h5file.get_iter_group(0)['trajectories']
|
|
313
|
+
with WESTIterationFile(link.file.filename) as traj_file:
|
|
314
|
+
frame = traj_file.read_as_traj(
|
|
315
|
+
iteration=0,
|
|
316
|
+
segment=parent.basis_state_id,
|
|
317
|
+
atom_indices=atom_indices,
|
|
318
|
+
)
|
|
319
|
+
elif parent.istate_type == InitialState.ISTATE_TYPE_GENERATED:
|
|
320
|
+
link = walker.run.h5file.get_iter_group(0)['trajectories']
|
|
321
|
+
istate_iter = -int(parent.iter_created) # the conversion to int is because iter_created is uint
|
|
322
|
+
with WESTIterationFile(link.file.filename) as traj_file:
|
|
323
|
+
frame = traj_file.read_as_traj(
|
|
324
|
+
iteration=istate_iter,
|
|
325
|
+
segment=parent.state_id,
|
|
326
|
+
atom_indices=atom_indices,
|
|
327
|
+
)
|
|
328
|
+
else:
|
|
329
|
+
raise ValueError('unsupported initial state type: %d' % parent.istate_type)
|
|
330
|
+
else:
|
|
331
|
+
frame = fget(parent, include_initpoint=False, atom_indices=atom_indices)[-1]
|
|
332
|
+
traj = frame.join(traj, check_topology=False)
|
|
333
|
+
|
|
334
|
+
return traj
|
|
335
|
+
|
|
336
|
+
super().__init__(fget)
|
|
337
|
+
|
|
338
|
+
self.segment_collector.use_threads = False
|
|
339
|
+
self.segment_collector.show_progress = True
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
def concatenate(segments):
|
|
343
|
+
"""Return the concatenation of a sequence of trajectory segments.
|
|
344
|
+
|
|
345
|
+
Parameters
|
|
346
|
+
----------
|
|
347
|
+
segments : sequence of sequences
|
|
348
|
+
A sequence of trajectory segments.
|
|
349
|
+
|
|
350
|
+
Returns
|
|
351
|
+
-------
|
|
352
|
+
sequence
|
|
353
|
+
The concatenation of `segments`.
|
|
354
|
+
|
|
355
|
+
"""
|
|
356
|
+
if isinstance(segments[0], np.ndarray):
|
|
357
|
+
return np.concatenate(segments)
|
|
358
|
+
if isinstance(segments[0], mdtraj.Trajectory):
|
|
359
|
+
return segments[0].join(segments[1:], check_topology=False)
|
|
360
|
+
return functools.reduce(operator.concat, segments)
|
westpa/cli/__init__.py
ADDED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import logging
|
|
3
|
+
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
import westpa
|
|
7
|
+
from westpa.core.segment import Segment
|
|
8
|
+
from westpa.core.states import InitialState
|
|
9
|
+
from westpa.core.data_manager import n_iter_dtype, seg_id_dtype
|
|
10
|
+
|
|
11
|
+
log = logging.getLogger('w_fork')
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def entry_point():
|
|
15
|
+
parser = argparse.ArgumentParser(
|
|
16
|
+
'w_fork',
|
|
17
|
+
description='''\
|
|
18
|
+
Prepare a new weighted ensemble simulation from an existing one at a particular
|
|
19
|
+
point. A new HDF5 file is generated. In the case of executable propagation,
|
|
20
|
+
it is the user's responsibility to prepare the new simulation directory
|
|
21
|
+
appropriately, particularly making the old simulation's restart data from the
|
|
22
|
+
appropriate iteration available as the new simulations initial state data; a
|
|
23
|
+
mapping of old simulation segment to new simulation initial states is
|
|
24
|
+
created, both in the new HDF5 file and as a flat text file, to aid in this.
|
|
25
|
+
Target states and basis states for the new simulation are taken from those
|
|
26
|
+
in the original simulation.
|
|
27
|
+
''',
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
westpa.rc.add_args(parser)
|
|
31
|
+
parser.add_argument(
|
|
32
|
+
'-i',
|
|
33
|
+
'--input',
|
|
34
|
+
dest='input_h5file',
|
|
35
|
+
help='''Create simulation from the given INPUT_H5FILE (default: read from
|
|
36
|
+
configuration file.''',
|
|
37
|
+
)
|
|
38
|
+
parser.add_argument(
|
|
39
|
+
'-I',
|
|
40
|
+
'--iteration',
|
|
41
|
+
dest='n_iter',
|
|
42
|
+
type=int,
|
|
43
|
+
help='''Take initial distribution for new simulation from iteration N_ITER
|
|
44
|
+
(default: last complete iteration).''',
|
|
45
|
+
)
|
|
46
|
+
parser.add_argument(
|
|
47
|
+
'-o',
|
|
48
|
+
'--output',
|
|
49
|
+
dest='output_h5file',
|
|
50
|
+
default='forked.h5',
|
|
51
|
+
help='''Save new simulation HDF5 file as OUTPUT (default: %(default)s).''',
|
|
52
|
+
)
|
|
53
|
+
parser.add_argument(
|
|
54
|
+
'--istate-map',
|
|
55
|
+
default='istate_map.txt',
|
|
56
|
+
help='''Write text file describing mapping of existing segments to new initial
|
|
57
|
+
states in ISTATE_MAP (default: %(default)s).''',
|
|
58
|
+
)
|
|
59
|
+
parser.add_argument('--no-headers', action='store_true', help='''Do not write header to ISTATE_MAP''')
|
|
60
|
+
args = parser.parse_args()
|
|
61
|
+
westpa.rc.process_args(args)
|
|
62
|
+
|
|
63
|
+
# Open old HDF5 file
|
|
64
|
+
dm_old = westpa.rc.new_data_manager()
|
|
65
|
+
if args.input_h5file:
|
|
66
|
+
dm_old.we_h5filename = args.input_h5file
|
|
67
|
+
dm_old.open_backing(mode='r')
|
|
68
|
+
|
|
69
|
+
# Get iteration if necessary
|
|
70
|
+
n_iter = args.n_iter or dm_old.current_iteration - 1
|
|
71
|
+
|
|
72
|
+
# Create and open new HDF5 file
|
|
73
|
+
dm_new = westpa.rc.new_data_manager()
|
|
74
|
+
dm_new.we_h5filename = args.output_h5file
|
|
75
|
+
dm_new.prepare_backing()
|
|
76
|
+
dm_new.open_backing()
|
|
77
|
+
|
|
78
|
+
# Copy target states
|
|
79
|
+
target_states = dm_old.get_target_states(n_iter)
|
|
80
|
+
dm_new.save_target_states(target_states, n_iter)
|
|
81
|
+
|
|
82
|
+
# Copy basis states
|
|
83
|
+
basis_states = dm_old.get_basis_states(n_iter)
|
|
84
|
+
dm_new.create_ibstate_group(basis_states, n_iter=1)
|
|
85
|
+
|
|
86
|
+
# Transform old segments into initial states and new segments
|
|
87
|
+
# We produce one initial state and one corresponding
|
|
88
|
+
# new segment for each old segment. Further adjustment
|
|
89
|
+
# can be accomplished by using w_binning.
|
|
90
|
+
old_iter_group = dm_old.get_iter_group(n_iter)
|
|
91
|
+
old_index = old_iter_group['seg_index'][...]
|
|
92
|
+
old_pcoord_ds = old_iter_group['pcoord']
|
|
93
|
+
n_segments = old_pcoord_ds.shape[0]
|
|
94
|
+
pcoord_len = old_pcoord_ds.shape[1]
|
|
95
|
+
pcoord_ndim = old_pcoord_ds.shape[2]
|
|
96
|
+
old_final_pcoords = old_pcoord_ds[:, pcoord_len - 1, :]
|
|
97
|
+
|
|
98
|
+
istates = dm_new.create_initial_states(n_segments, n_iter=1)
|
|
99
|
+
segments = []
|
|
100
|
+
state_map_dtype = np.dtype([('old_n_iter', n_iter_dtype), ('old_seg_id', seg_id_dtype), ('new_istate_id', seg_id_dtype)])
|
|
101
|
+
state_map = np.empty((n_segments,), dtype=state_map_dtype)
|
|
102
|
+
state_map['old_n_iter'] = n_iter
|
|
103
|
+
|
|
104
|
+
for iseg, (index_row, pcoord) in enumerate(zip(old_index, old_final_pcoords)):
|
|
105
|
+
istate = istates[iseg]
|
|
106
|
+
istate.iter_created = 0
|
|
107
|
+
istate.iter_used = 1
|
|
108
|
+
istate.istate_type = InitialState.ISTATE_TYPE_RESTART
|
|
109
|
+
istate.istate_status = InitialState.ISTATE_STATUS_PREPARED
|
|
110
|
+
istate.pcoord = pcoord
|
|
111
|
+
|
|
112
|
+
segment = Segment(
|
|
113
|
+
n_iter=1,
|
|
114
|
+
seg_id=iseg,
|
|
115
|
+
weight=index_row['weight'],
|
|
116
|
+
parent_id=-(istate.state_id + 1),
|
|
117
|
+
wtg_parent_ids=[-(istate.state_id + 1)],
|
|
118
|
+
status=Segment.SEG_STATUS_PREPARED,
|
|
119
|
+
)
|
|
120
|
+
segment.pcoord = np.zeros((pcoord_len, pcoord_ndim), dtype=pcoord.dtype)
|
|
121
|
+
segment.pcoord[0] = pcoord
|
|
122
|
+
segments.append(segment)
|
|
123
|
+
state_map[iseg]['old_seg_id'] = iseg
|
|
124
|
+
state_map[iseg]['new_istate_id'] = istate.state_id
|
|
125
|
+
|
|
126
|
+
dm_new.update_initial_states(istates, n_iter=0)
|
|
127
|
+
dm_new.prepare_iteration(n_iter=1, segments=segments)
|
|
128
|
+
|
|
129
|
+
# Update current iteration and close both files
|
|
130
|
+
dm_new.current_iteration = 1
|
|
131
|
+
dm_new.close_backing()
|
|
132
|
+
dm_old.close_backing()
|
|
133
|
+
|
|
134
|
+
# Write state map
|
|
135
|
+
istate_map_file = open(args.istate_map, 'wt')
|
|
136
|
+
if not args.no_headers:
|
|
137
|
+
istate_map_file.write('# mapping from previous segment IDs to new initial states\n')
|
|
138
|
+
istate_map_file.write('# generated by w_fork\n')
|
|
139
|
+
istate_map_file.write('# column 0: old simulation n_iter\n')
|
|
140
|
+
istate_map_file.write('# column 1: old simulation seg_id\n')
|
|
141
|
+
istate_map_file.write('# column 2: new simulation initial state ID\n')
|
|
142
|
+
|
|
143
|
+
for row in state_map:
|
|
144
|
+
istate_map_file.write(
|
|
145
|
+
'{old_n_iter:20d} {old_seg_id:20d} {new_istate_id:20d}\n'.format(
|
|
146
|
+
old_n_iter=int(row['old_n_iter']), old_seg_id=int(row['old_seg_id']), new_istate_id=int(row['new_istate_id'])
|
|
147
|
+
)
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
if __name__ == '__main__':
|
|
152
|
+
entry_point()
|