westpa 2022.10__cp312-cp312-manylinux_2_17_x86_64.manylinux2014_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.

Files changed (150) hide show
  1. westpa/__init__.py +14 -0
  2. westpa/_version.py +21 -0
  3. westpa/analysis/__init__.py +5 -0
  4. westpa/analysis/core.py +746 -0
  5. westpa/analysis/statistics.py +27 -0
  6. westpa/analysis/trajectories.py +360 -0
  7. westpa/cli/__init__.py +0 -0
  8. westpa/cli/core/__init__.py +0 -0
  9. westpa/cli/core/w_fork.py +152 -0
  10. westpa/cli/core/w_init.py +230 -0
  11. westpa/cli/core/w_run.py +77 -0
  12. westpa/cli/core/w_states.py +212 -0
  13. westpa/cli/core/w_succ.py +99 -0
  14. westpa/cli/core/w_truncate.py +59 -0
  15. westpa/cli/tools/__init__.py +0 -0
  16. westpa/cli/tools/ploterr.py +506 -0
  17. westpa/cli/tools/plothist.py +706 -0
  18. westpa/cli/tools/w_assign.py +596 -0
  19. westpa/cli/tools/w_bins.py +166 -0
  20. westpa/cli/tools/w_crawl.py +119 -0
  21. westpa/cli/tools/w_direct.py +547 -0
  22. westpa/cli/tools/w_dumpsegs.py +94 -0
  23. westpa/cli/tools/w_eddist.py +506 -0
  24. westpa/cli/tools/w_fluxanl.py +378 -0
  25. westpa/cli/tools/w_ipa.py +833 -0
  26. westpa/cli/tools/w_kinavg.py +127 -0
  27. westpa/cli/tools/w_kinetics.py +96 -0
  28. westpa/cli/tools/w_multi_west.py +414 -0
  29. westpa/cli/tools/w_ntop.py +213 -0
  30. westpa/cli/tools/w_pdist.py +515 -0
  31. westpa/cli/tools/w_postanalysis_matrix.py +82 -0
  32. westpa/cli/tools/w_postanalysis_reweight.py +53 -0
  33. westpa/cli/tools/w_red.py +486 -0
  34. westpa/cli/tools/w_reweight.py +780 -0
  35. westpa/cli/tools/w_select.py +226 -0
  36. westpa/cli/tools/w_stateprobs.py +111 -0
  37. westpa/cli/tools/w_trace.py +599 -0
  38. westpa/core/__init__.py +0 -0
  39. westpa/core/_rc.py +673 -0
  40. westpa/core/binning/__init__.py +55 -0
  41. westpa/core/binning/_assign.cpython-312-x86_64-linux-gnu.so +0 -0
  42. westpa/core/binning/assign.py +449 -0
  43. westpa/core/binning/binless.py +96 -0
  44. westpa/core/binning/binless_driver.py +54 -0
  45. westpa/core/binning/binless_manager.py +190 -0
  46. westpa/core/binning/bins.py +47 -0
  47. westpa/core/binning/mab.py +427 -0
  48. westpa/core/binning/mab_driver.py +54 -0
  49. westpa/core/binning/mab_manager.py +198 -0
  50. westpa/core/data_manager.py +1694 -0
  51. westpa/core/extloader.py +74 -0
  52. westpa/core/h5io.py +995 -0
  53. westpa/core/kinetics/__init__.py +24 -0
  54. westpa/core/kinetics/_kinetics.cpython-312-x86_64-linux-gnu.so +0 -0
  55. westpa/core/kinetics/events.py +147 -0
  56. westpa/core/kinetics/matrates.py +156 -0
  57. westpa/core/kinetics/rate_averaging.py +266 -0
  58. westpa/core/progress.py +218 -0
  59. westpa/core/propagators/__init__.py +54 -0
  60. westpa/core/propagators/executable.py +715 -0
  61. westpa/core/reweight/__init__.py +14 -0
  62. westpa/core/reweight/_reweight.cpython-312-x86_64-linux-gnu.so +0 -0
  63. westpa/core/reweight/matrix.py +126 -0
  64. westpa/core/segment.py +119 -0
  65. westpa/core/sim_manager.py +830 -0
  66. westpa/core/states.py +359 -0
  67. westpa/core/systems.py +93 -0
  68. westpa/core/textio.py +74 -0
  69. westpa/core/trajectory.py +330 -0
  70. westpa/core/we_driver.py +908 -0
  71. westpa/core/wm_ops.py +43 -0
  72. westpa/core/yamlcfg.py +391 -0
  73. westpa/fasthist/__init__.py +34 -0
  74. westpa/fasthist/__main__.py +110 -0
  75. westpa/fasthist/_fasthist.cpython-312-x86_64-linux-gnu.so +0 -0
  76. westpa/mclib/__init__.py +264 -0
  77. westpa/mclib/__main__.py +28 -0
  78. westpa/mclib/_mclib.cpython-312-x86_64-linux-gnu.so +0 -0
  79. westpa/oldtools/__init__.py +4 -0
  80. westpa/oldtools/aframe/__init__.py +35 -0
  81. westpa/oldtools/aframe/atool.py +75 -0
  82. westpa/oldtools/aframe/base_mixin.py +26 -0
  83. westpa/oldtools/aframe/binning.py +178 -0
  84. westpa/oldtools/aframe/data_reader.py +560 -0
  85. westpa/oldtools/aframe/iter_range.py +200 -0
  86. westpa/oldtools/aframe/kinetics.py +117 -0
  87. westpa/oldtools/aframe/mcbs.py +146 -0
  88. westpa/oldtools/aframe/output.py +39 -0
  89. westpa/oldtools/aframe/plotting.py +90 -0
  90. westpa/oldtools/aframe/trajwalker.py +126 -0
  91. westpa/oldtools/aframe/transitions.py +469 -0
  92. westpa/oldtools/cmds/__init__.py +0 -0
  93. westpa/oldtools/cmds/w_ttimes.py +358 -0
  94. westpa/oldtools/files.py +34 -0
  95. westpa/oldtools/miscfn.py +23 -0
  96. westpa/oldtools/stats/__init__.py +4 -0
  97. westpa/oldtools/stats/accumulator.py +35 -0
  98. westpa/oldtools/stats/edfs.py +129 -0
  99. westpa/oldtools/stats/mcbs.py +89 -0
  100. westpa/tools/__init__.py +33 -0
  101. westpa/tools/binning.py +472 -0
  102. westpa/tools/core.py +340 -0
  103. westpa/tools/data_reader.py +159 -0
  104. westpa/tools/dtypes.py +31 -0
  105. westpa/tools/iter_range.py +198 -0
  106. westpa/tools/kinetics_tool.py +340 -0
  107. westpa/tools/plot.py +283 -0
  108. westpa/tools/progress.py +17 -0
  109. westpa/tools/selected_segs.py +154 -0
  110. westpa/tools/wipi.py +751 -0
  111. westpa/trajtree/__init__.py +4 -0
  112. westpa/trajtree/_trajtree.cpython-312-x86_64-linux-gnu.so +0 -0
  113. westpa/trajtree/trajtree.py +117 -0
  114. westpa/westext/__init__.py +0 -0
  115. westpa/westext/adaptvoronoi/__init__.py +3 -0
  116. westpa/westext/adaptvoronoi/adaptVor_driver.py +214 -0
  117. westpa/westext/hamsm_restarting/__init__.py +3 -0
  118. westpa/westext/hamsm_restarting/example_overrides.py +35 -0
  119. westpa/westext/hamsm_restarting/restart_driver.py +1165 -0
  120. westpa/westext/stringmethod/__init__.py +11 -0
  121. westpa/westext/stringmethod/fourier_fitting.py +69 -0
  122. westpa/westext/stringmethod/string_driver.py +253 -0
  123. westpa/westext/stringmethod/string_method.py +306 -0
  124. westpa/westext/weed/BinCluster.py +180 -0
  125. westpa/westext/weed/ProbAdjustEquil.py +100 -0
  126. westpa/westext/weed/UncertMath.py +247 -0
  127. westpa/westext/weed/__init__.py +10 -0
  128. westpa/westext/weed/weed_driver.py +182 -0
  129. westpa/westext/wess/ProbAdjust.py +101 -0
  130. westpa/westext/wess/__init__.py +6 -0
  131. westpa/westext/wess/wess_driver.py +207 -0
  132. westpa/work_managers/__init__.py +57 -0
  133. westpa/work_managers/core.py +396 -0
  134. westpa/work_managers/environment.py +134 -0
  135. westpa/work_managers/mpi.py +318 -0
  136. westpa/work_managers/processes.py +187 -0
  137. westpa/work_managers/serial.py +28 -0
  138. westpa/work_managers/threads.py +79 -0
  139. westpa/work_managers/zeromq/__init__.py +20 -0
  140. westpa/work_managers/zeromq/core.py +641 -0
  141. westpa/work_managers/zeromq/node.py +131 -0
  142. westpa/work_managers/zeromq/work_manager.py +526 -0
  143. westpa/work_managers/zeromq/worker.py +320 -0
  144. westpa-2022.10.dist-info/AUTHORS +22 -0
  145. westpa-2022.10.dist-info/LICENSE +21 -0
  146. westpa-2022.10.dist-info/METADATA +183 -0
  147. westpa-2022.10.dist-info/RECORD +150 -0
  148. westpa-2022.10.dist-info/WHEEL +6 -0
  149. westpa-2022.10.dist-info/entry_points.txt +29 -0
  150. 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()