westpa 2022.12__cp313-cp313-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.
- 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-x86_64-linux-gnu.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-x86_64-linux-gnu.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-x86_64-linux-gnu.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-x86_64-linux-gnu.so +0 -0
- westpa/mclib/__init__.py +271 -0
- westpa/mclib/__main__.py +28 -0
- westpa/mclib/_mclib.cpython-313-x86_64-linux-gnu.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-x86_64-linux-gnu.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,127 @@
|
|
|
1
|
+
from westpa.tools import WESTMasterCommand, WESTParallelTool
|
|
2
|
+
from westpa.cli.tools.w_direct import DKinAvg
|
|
3
|
+
from warnings import warn
|
|
4
|
+
|
|
5
|
+
# Just a shim to make sure everything works and is backwards compatible.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class WKinAvg(DKinAvg):
|
|
9
|
+
subcommand = 'trace'
|
|
10
|
+
help_text = 'averages and CIs for path-tracing kinetics analysis'
|
|
11
|
+
default_kinetics_file = 'kintrace.h5'
|
|
12
|
+
default_output_file = 'kinavg.h5'
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class WDirect(WESTMasterCommand, WESTParallelTool):
|
|
16
|
+
prog = 'w_kinavg'
|
|
17
|
+
subcommands = [WKinAvg]
|
|
18
|
+
subparsers_title = 'direct kinetics analysis schemes'
|
|
19
|
+
description = '''\
|
|
20
|
+
Calculate average rates and associated errors from weighted ensemble data. Bin
|
|
21
|
+
assignments (usually "assignments.h5") and kinetics data (usually
|
|
22
|
+
"kintrace.h5" or "kinmat.h5") data files must have been previously generated
|
|
23
|
+
(see "w_assign --help" and "w_kinetics --help" for information on generating
|
|
24
|
+
these files).
|
|
25
|
+
|
|
26
|
+
-----------------------------------------------------------------------------
|
|
27
|
+
Output format
|
|
28
|
+
-----------------------------------------------------------------------------
|
|
29
|
+
|
|
30
|
+
The output file (-o/--output, usually "kinavg.h5") contains the following
|
|
31
|
+
dataset:
|
|
32
|
+
|
|
33
|
+
/avg_rates [state,state]
|
|
34
|
+
(Structured -- see below) State-to-state rates based on entire window of
|
|
35
|
+
iterations selected.
|
|
36
|
+
|
|
37
|
+
For trace mode, the following additional datasets are generated:
|
|
38
|
+
|
|
39
|
+
/avg_total_fluxes [state]
|
|
40
|
+
(Structured -- see below) Total fluxes into each state based on entire
|
|
41
|
+
window of iterations selected.
|
|
42
|
+
|
|
43
|
+
/avg_conditional_fluxes [state,state]
|
|
44
|
+
(Structured -- see below) State-to-state fluxes based on entire window of
|
|
45
|
+
iterations selected.
|
|
46
|
+
|
|
47
|
+
If --evolution-mode is specified, then the following additional dataset is
|
|
48
|
+
available:
|
|
49
|
+
|
|
50
|
+
/rate_evolution [window][state][state]
|
|
51
|
+
(Structured -- see below). State-to-state rates based on windows of
|
|
52
|
+
iterations of varying width. If --evolution-mode=cumulative, then
|
|
53
|
+
these windows all begin at the iteration specified with
|
|
54
|
+
--start-iter and grow in length by --step-iter for each successive
|
|
55
|
+
element. If --evolution-mode=blocked, then these windows are all of
|
|
56
|
+
width --step-iter (excluding the last, which may be shorter), the first
|
|
57
|
+
of which begins at iteration --start-iter.
|
|
58
|
+
|
|
59
|
+
If --evolution-mode is specified in trace mode, the following additional
|
|
60
|
+
datasets are available:
|
|
61
|
+
|
|
62
|
+
/target_flux_evolution [window,state]
|
|
63
|
+
(Structured -- see below). Total flux into a given macro state based on
|
|
64
|
+
windows of iterations of varying width, as in /rate_evolution.
|
|
65
|
+
|
|
66
|
+
/conditional_flux_evolution [window,state,state]
|
|
67
|
+
(Structured -- see below). State-to-state fluxes based on windows of
|
|
68
|
+
varying width, as in /rate_evolution.
|
|
69
|
+
|
|
70
|
+
The structure of these datasets is as follows:
|
|
71
|
+
|
|
72
|
+
iter_start
|
|
73
|
+
(Integer) Iteration at which the averaging window begins (inclusive).
|
|
74
|
+
|
|
75
|
+
iter_stop
|
|
76
|
+
(Integer) Iteration at which the averaging window ends (exclusive).
|
|
77
|
+
|
|
78
|
+
expected
|
|
79
|
+
(Floating-point) Expected (mean) value of the rate as evaluated within
|
|
80
|
+
this window, in units of inverse tau.
|
|
81
|
+
|
|
82
|
+
ci_lbound
|
|
83
|
+
(Floating-point) Lower bound of the confidence interval on the rate
|
|
84
|
+
within this window, in units of inverse tau.
|
|
85
|
+
|
|
86
|
+
ci_ubound
|
|
87
|
+
(Floating-point) Upper bound of the confidence interval on the rate
|
|
88
|
+
within this window, in units of inverse tau.
|
|
89
|
+
|
|
90
|
+
corr_len
|
|
91
|
+
(Integer) Correlation length of the rate within this window, in units
|
|
92
|
+
of tau.
|
|
93
|
+
|
|
94
|
+
Each of these datasets is also stamped with a number of attributes:
|
|
95
|
+
|
|
96
|
+
mcbs_alpha
|
|
97
|
+
(Floating-point) Alpha value of confidence intervals. (For example,
|
|
98
|
+
*alpha=0.05* corresponds to a 95% confidence interval.)
|
|
99
|
+
|
|
100
|
+
mcbs_nsets
|
|
101
|
+
(Integer) Number of bootstrap data sets used in generating confidence
|
|
102
|
+
intervals.
|
|
103
|
+
|
|
104
|
+
mcbs_acalpha
|
|
105
|
+
(Floating-point) Alpha value for determining correlation lengths.
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
-----------------------------------------------------------------------------
|
|
109
|
+
Command-line options
|
|
110
|
+
-----------------------------------------------------------------------------
|
|
111
|
+
'''
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def entry_point():
|
|
115
|
+
warn('{} is being deprecated. Please use w_direct instead.'.format(WDirect.prog))
|
|
116
|
+
import sys
|
|
117
|
+
|
|
118
|
+
try:
|
|
119
|
+
if sys.argv[1] != 'trace':
|
|
120
|
+
sys.argv.insert(1, 'trace')
|
|
121
|
+
except Exception:
|
|
122
|
+
sys.argv.insert(1, 'trace')
|
|
123
|
+
WDirect().main()
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
if __name__ == '__main__':
|
|
127
|
+
entry_point()
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
from westpa.tools import WESTMasterCommand, WESTParallelTool
|
|
2
|
+
from warnings import warn
|
|
3
|
+
|
|
4
|
+
from westpa.cli.tools.w_direct import DKinetics
|
|
5
|
+
|
|
6
|
+
# Just a shim to make sure everything works and is backwards compatible.
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class WKinetics(DKinetics):
|
|
10
|
+
subcommand = 'trace'
|
|
11
|
+
help_text = 'averages and CIs for path-tracing kinetics analysis'
|
|
12
|
+
default_output_file = 'kintrace.h5'
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class WDirect(WESTMasterCommand, WESTParallelTool):
|
|
16
|
+
prog = 'w_kinetics'
|
|
17
|
+
subcommands = [WKinetics]
|
|
18
|
+
subparsers_title = 'calculate state-to-state kinetics by tracing trajectories'
|
|
19
|
+
description = '''\
|
|
20
|
+
Calculate state-to-state rates and transition event durations by tracing
|
|
21
|
+
trajectories.
|
|
22
|
+
|
|
23
|
+
A bin assignment file (usually "assign.h5") including trajectory labeling
|
|
24
|
+
is required (see "w_assign --help" for information on generating this file).
|
|
25
|
+
|
|
26
|
+
The output generated by this program is used as input for the ``w_kinavg``
|
|
27
|
+
tool, which converts the flux data in the output file into average rates
|
|
28
|
+
with confidence intervals. See ``w_kinavg trace --help`` for more
|
|
29
|
+
information.
|
|
30
|
+
|
|
31
|
+
-----------------------------------------------------------------------------
|
|
32
|
+
Output format
|
|
33
|
+
-----------------------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
The output file (-o/--output, by default "kintrace.h5") contains the
|
|
36
|
+
following datasets:
|
|
37
|
+
|
|
38
|
+
``/conditional_fluxes`` [iteration][state][state]
|
|
39
|
+
*(Floating-point)* Macrostate-to-macrostate fluxes. These are **not**
|
|
40
|
+
normalized by the population of the initial macrostate.
|
|
41
|
+
|
|
42
|
+
``/conditional_arrivals`` [iteration][stateA][stateB]
|
|
43
|
+
*(Integer)* Number of trajectories arriving at state *stateB* in a given
|
|
44
|
+
iteration, given that they departed from *stateA*.
|
|
45
|
+
|
|
46
|
+
``/total_fluxes`` [iteration][state]
|
|
47
|
+
*(Floating-point)* Total flux into a given macrostate.
|
|
48
|
+
|
|
49
|
+
``/arrivals`` [iteration][state]
|
|
50
|
+
*(Integer)* Number of trajectories arriving at a given state in a given
|
|
51
|
+
iteration, regardless of where they originated.
|
|
52
|
+
|
|
53
|
+
``/duration_count`` [iteration]
|
|
54
|
+
*(Integer)* The number of event durations recorded in each iteration.
|
|
55
|
+
|
|
56
|
+
``/durations`` [iteration][event duration]
|
|
57
|
+
*(Structured -- see below)* Event durations for transition events ending
|
|
58
|
+
during a given iteration. These are stored as follows:
|
|
59
|
+
|
|
60
|
+
istate
|
|
61
|
+
*(Integer)* Initial state of transition event.
|
|
62
|
+
fstate
|
|
63
|
+
*(Integer)* Final state of transition event.
|
|
64
|
+
duration
|
|
65
|
+
*(Floating-point)* Duration of transition, in units of tau.
|
|
66
|
+
weight
|
|
67
|
+
*(Floating-point)* Weight of trajectory at end of transition, **not**
|
|
68
|
+
normalized by initial state population.
|
|
69
|
+
|
|
70
|
+
Because state-to-state fluxes stored in this file are not normalized by
|
|
71
|
+
initial macrostate population, they cannot be used as rates without further
|
|
72
|
+
processing. The ``w_kinavg`` command is used to perform this normalization
|
|
73
|
+
while taking statistical fluctuation and correlation into account. See
|
|
74
|
+
``w_kinavg trace --help`` for more information. Target fluxes (total flux
|
|
75
|
+
into a given state) require no such normalization.
|
|
76
|
+
|
|
77
|
+
-----------------------------------------------------------------------------
|
|
78
|
+
Command-line options
|
|
79
|
+
-----------------------------------------------------------------------------
|
|
80
|
+
'''
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def entry_point():
|
|
84
|
+
warn('{} is being deprecated. Please use w_direct instead.'.format(WDirect.prog))
|
|
85
|
+
import sys
|
|
86
|
+
|
|
87
|
+
try:
|
|
88
|
+
if sys.argv[1] != 'trace':
|
|
89
|
+
sys.argv.insert(1, 'trace')
|
|
90
|
+
except Exception:
|
|
91
|
+
sys.argv.insert(1, 'trace')
|
|
92
|
+
WDirect().main()
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
if __name__ == '__main__':
|
|
96
|
+
entry_point()
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import numpy as np
|
|
3
|
+
import pickle
|
|
4
|
+
|
|
5
|
+
log = logging.getLogger(__name__)
|
|
6
|
+
from westpa.tools.core import WESTTool
|
|
7
|
+
from westpa.core.data_manager import n_iter_dtype, istate_dtype
|
|
8
|
+
from westpa.tools.progress import ProgressIndicatorComponent
|
|
9
|
+
from westpa.core import h5io
|
|
10
|
+
from westpa.tools.core import WESTMultiTool
|
|
11
|
+
|
|
12
|
+
# from westtools.dtypes import iter_block_ci_dtype as ci_dtype
|
|
13
|
+
import gc
|
|
14
|
+
|
|
15
|
+
# from pympler.tracker import SummaryTracker
|
|
16
|
+
|
|
17
|
+
ci_dtype = np.dtype(
|
|
18
|
+
[
|
|
19
|
+
('iter_start', n_iter_dtype),
|
|
20
|
+
('iter_stop', n_iter_dtype),
|
|
21
|
+
('expected', np.float64),
|
|
22
|
+
('ci_lbound', np.float64),
|
|
23
|
+
('ci_ubound', np.float64),
|
|
24
|
+
('corr_len', n_iter_dtype),
|
|
25
|
+
('variance', np.float64),
|
|
26
|
+
('stderrormean', np.float64),
|
|
27
|
+
]
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# directory locations are stored in a .yaml file with this format:
|
|
31
|
+
# ---
|
|
32
|
+
# PATHS: ['/path/to/simulation/1','/path/to/simulation/2',...,
|
|
33
|
+
# '/path/to/simulation/n']
|
|
34
|
+
|
|
35
|
+
# Straight up stolen from the data manager. In the future, maybe I can just sort it by subbing in the appropriate values.
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def get_bin_mapper(we_h5file, hashval):
|
|
39
|
+
'''Look up the given hash value in the binning table, unpickling and returning the corresponding
|
|
40
|
+
bin mapper if available, or raising KeyError if not.'''
|
|
41
|
+
|
|
42
|
+
# Convert to a hex digest if we need to
|
|
43
|
+
try:
|
|
44
|
+
hashval = hashval.hexdigest()
|
|
45
|
+
except AttributeError:
|
|
46
|
+
pass
|
|
47
|
+
|
|
48
|
+
while True:
|
|
49
|
+
# these will raise KeyError if the group doesn't exist, which also means
|
|
50
|
+
# that bin data is not available, so no special treatment here
|
|
51
|
+
try:
|
|
52
|
+
binning_group = we_h5file['/bin_topologies']
|
|
53
|
+
index = binning_group['index']
|
|
54
|
+
pkl = binning_group['pickles']
|
|
55
|
+
except KeyError:
|
|
56
|
+
raise KeyError('hash {} not found. Could not retrieve binning group'.format(hashval))
|
|
57
|
+
|
|
58
|
+
n_entries = len(index)
|
|
59
|
+
if n_entries == 0:
|
|
60
|
+
raise KeyError('hash {} not found. No entries in index'.format(hashval))
|
|
61
|
+
|
|
62
|
+
chunksize = 1024
|
|
63
|
+
|
|
64
|
+
for istart in range(0, n_entries, chunksize):
|
|
65
|
+
chunk = index[istart : min(istart + chunksize, n_entries)]
|
|
66
|
+
for i in range(len(chunk)):
|
|
67
|
+
if chunk[i]['hash'] == hashval:
|
|
68
|
+
pkldat = bytes(pkl[istart + i, 0 : chunk[i]['pickle_len']].data)
|
|
69
|
+
mapper = pickle.loads(pkldat)
|
|
70
|
+
log.debug('loaded {!r} from {!r}'.format(mapper, binning_group))
|
|
71
|
+
log.debug('hash value {!r}'.format(hashval))
|
|
72
|
+
return mapper
|
|
73
|
+
|
|
74
|
+
raise KeyError('hash {} not found'.format(hashval))
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def create_idtype_array(input_array):
|
|
78
|
+
'''Return a new array with the new istate_dtype while preserving old data.'''
|
|
79
|
+
new_array = np.zeros(input_array.shape, dtype=istate_dtype)
|
|
80
|
+
for j in input_array.dtype.names:
|
|
81
|
+
new_array[j] = input_array[j].copy()
|
|
82
|
+
|
|
83
|
+
# Need to turn 'basis_auxref' to empty bytestrings...
|
|
84
|
+
new_array['basis_auxref'] = b''
|
|
85
|
+
|
|
86
|
+
return new_array
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class WMultiWest(WESTMultiTool):
|
|
90
|
+
prog = 'w_multi_west'
|
|
91
|
+
description = '''\
|
|
92
|
+
Tool designed to combine multiple WESTPA simulations while accounting for
|
|
93
|
+
reweighting.
|
|
94
|
+
-----------------------------------------------------------------------------
|
|
95
|
+
Command-line options
|
|
96
|
+
-----------------------------------------------------------------------------
|
|
97
|
+
'''
|
|
98
|
+
|
|
99
|
+
def __init__(self):
|
|
100
|
+
super(WESTTool, self).__init__()
|
|
101
|
+
self.progress = ProgressIndicatorComponent()
|
|
102
|
+
# We no longer care about a lot of this.
|
|
103
|
+
self.ntrials = 0
|
|
104
|
+
self.nstates = 0
|
|
105
|
+
self.kin_trial = {}
|
|
106
|
+
self.west = {}
|
|
107
|
+
self.niters = 0
|
|
108
|
+
|
|
109
|
+
def add_args(self, parser):
|
|
110
|
+
self.progress.add_args(parser)
|
|
111
|
+
iogroup = parser.add_argument_group('input/output options')
|
|
112
|
+
iogroup.add_argument('-o', '--output-file', default='multi.h5', help='''The name of the output file to store results in.''')
|
|
113
|
+
iogroup.add_argument(
|
|
114
|
+
'-W',
|
|
115
|
+
'--west',
|
|
116
|
+
'--WEST_H5FILE',
|
|
117
|
+
default='west.h5',
|
|
118
|
+
help='''The name of the main .h5 file inside each simulation
|
|
119
|
+
directory''',
|
|
120
|
+
)
|
|
121
|
+
iogroup.add_argument('-a', '--aux', action='append', help='''Names of additional auxiliary datasets to be combined''')
|
|
122
|
+
iogroup.add_argument('-aa', '--auxall', action='store_true', help='''Combine all auxiliary datasets. Default: False''')
|
|
123
|
+
iogroup.add_argument('-nr', '--no-reweight', action='store_true', help='''Do not reweight. Default: False''')
|
|
124
|
+
iogroup.add_argument(
|
|
125
|
+
'-ib', '--ibstates', action='store_true', help='''Attempt to combine ibstates dataset. Default: False'''
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
def open_files(self):
|
|
129
|
+
self.output_file = h5io.WESTPAH5File(self.output_file, 'w', creating_program=True)
|
|
130
|
+
h5io.stamp_creator_data(self.output_file)
|
|
131
|
+
|
|
132
|
+
opened_files = self.generate_file_list([self.west])
|
|
133
|
+
self.westH5 = opened_files[self.west]
|
|
134
|
+
# Just some temp things while I clean everything up...
|
|
135
|
+
# west_files = self.westH5
|
|
136
|
+
# Determine max iteration ...
|
|
137
|
+
|
|
138
|
+
# We can't really use the old method anymore, as we need to calculate rates in the bootstrap.
|
|
139
|
+
# Ergo, we're going to load things like w_kinavg, but that's all.
|
|
140
|
+
# We'll just load them up and store them internally, for the moment.
|
|
141
|
+
|
|
142
|
+
def process_args(self, args):
|
|
143
|
+
self.progress.process_args(args)
|
|
144
|
+
self.output_file = args.output_file
|
|
145
|
+
self.output_file_name = args.output_file
|
|
146
|
+
self.west = args.west
|
|
147
|
+
self.sims = args.sims
|
|
148
|
+
self.aux = args.aux
|
|
149
|
+
self.auxall = args.auxall
|
|
150
|
+
self.reweight = args.no_reweight
|
|
151
|
+
self.ibstates = args.ibstates
|
|
152
|
+
|
|
153
|
+
def total_number_of_walkers(self):
|
|
154
|
+
self.total_walkers = [0] * self.niters
|
|
155
|
+
for key, west in self.westH5.items():
|
|
156
|
+
# Sometimes, we're smaller or larger by one. Hm.
|
|
157
|
+
try:
|
|
158
|
+
self.total_walkers[:] += west['summary'][:-1]['n_particles']
|
|
159
|
+
except ValueError:
|
|
160
|
+
self.total_walkers[:] += west['summary'][:-1]['n_particles'][: len(self.total_walkers)]
|
|
161
|
+
|
|
162
|
+
def go(self):
|
|
163
|
+
pi = self.progress.indicator
|
|
164
|
+
self.istates = True # Assume serendipitously istates is same between runs...
|
|
165
|
+
with pi:
|
|
166
|
+
pi.new_operation('Initializing')
|
|
167
|
+
self.open_files()
|
|
168
|
+
self.total_number_of_walkers()
|
|
169
|
+
if self.auxall is True:
|
|
170
|
+
try:
|
|
171
|
+
self.aux = list(self.westH5[1]['iterations/iter_00000001/auxdata'].keys())
|
|
172
|
+
except KeyError:
|
|
173
|
+
self.aux = None
|
|
174
|
+
log.warning('No auxdata. Proceeding forward without merging auxdata.')
|
|
175
|
+
# Create a giant WEST.h5 file, separating the individual walkers, and renormalizing the weights.
|
|
176
|
+
# It should then be compatible with existing toolsets.
|
|
177
|
+
# Isn't really going to start with auxdata, but we'll add it in.
|
|
178
|
+
|
|
179
|
+
# self.niters = 500
|
|
180
|
+
# Initialize data manager...
|
|
181
|
+
# Just bullshit for the current system.
|
|
182
|
+
# self.niters = self.westH5[1].attrs['west_current_iteration'] - 1
|
|
183
|
+
# print(self.niters, len(self.westH5))
|
|
184
|
+
# self.data_manager = data_manager.WESTDataManager()
|
|
185
|
+
westh5 = []
|
|
186
|
+
self.source_sinks = []
|
|
187
|
+
self.n_sims = {}
|
|
188
|
+
istate_addition = [0]
|
|
189
|
+
for ifile, (key, west) in enumerate(self.westH5.items()):
|
|
190
|
+
d = {'west': west, 'wm': None, 'rt': None, 'remove_next_cycle': [], 'seg_index': None}
|
|
191
|
+
# We're getting the bin mapper, then setting the recycling target...
|
|
192
|
+
binhash = west['iterations/iter_{0:08d}'.format(2)].attrs['binhash']
|
|
193
|
+
bin_mapper = get_bin_mapper(west, bytes(binhash, 'utf-8'))
|
|
194
|
+
try:
|
|
195
|
+
d['rt'] = bin_mapper.assign(west['tstates']['0']['pcoord'][...])[0]
|
|
196
|
+
self.source_sinks.append(bin_mapper.assign(west['tstates']['0']['pcoord'][...])[0])
|
|
197
|
+
except KeyError:
|
|
198
|
+
d['rt'] = None
|
|
199
|
+
self.source_sinks.append(None)
|
|
200
|
+
pass
|
|
201
|
+
# We're going to make a set of source and sink states that we can iterate through, eventually.
|
|
202
|
+
# Keep a count of how many simulations for this particular recycling target we have...
|
|
203
|
+
try:
|
|
204
|
+
self.n_sims[d['rt']] += 1
|
|
205
|
+
except KeyError:
|
|
206
|
+
self.n_sims[d['rt']] = 1
|
|
207
|
+
westh5.append(d)
|
|
208
|
+
if ifile == 0:
|
|
209
|
+
self.niters = west.attrs['west_current_iteration'] - 1
|
|
210
|
+
else:
|
|
211
|
+
self.niters = min(west.attrs['west_current_iteration'] - 1, self.niters)
|
|
212
|
+
|
|
213
|
+
istate_addition.append(istate_addition[-1] + len(west['ibstates/0/istate_index']))
|
|
214
|
+
# Check to see if all the bstates are identical
|
|
215
|
+
if self.ibstates:
|
|
216
|
+
check = [False, False] # Assuming they're false, so not accidentally outputing anything that errors out.
|
|
217
|
+
try:
|
|
218
|
+
check[0] = np.array_equal(bstate_index, west['ibstates/0/bstate_index'][:])
|
|
219
|
+
check[1] = np.array_equal(bstate_pcoord, west['ibstates/0/bstate_pcoord'][:])
|
|
220
|
+
if not np.all(check):
|
|
221
|
+
print(f'File {ifile} used different bstates than the first file. Will skip exporting ibstates dataset.')
|
|
222
|
+
self.ibstates = False
|
|
223
|
+
except NameError:
|
|
224
|
+
bstate_index = west['ibstates/0/bstate_index'][:] # noqa: F841
|
|
225
|
+
bstate_pcoord = west['ibstates/0/bstate_pcoord'][:] # noqa: F841
|
|
226
|
+
|
|
227
|
+
start_point = []
|
|
228
|
+
self.source_sinks = list(set(self.source_sinks))
|
|
229
|
+
# We'll need a global list of walkers to add to and take care of during the next round of simulations, as well as the current one.
|
|
230
|
+
# We'll organize it by source and sink states.
|
|
231
|
+
self.past_iter = {}
|
|
232
|
+
self.futr_iter = {}
|
|
233
|
+
self.past_rm = {}
|
|
234
|
+
self.futr_rm = {}
|
|
235
|
+
for i in self.source_sinks:
|
|
236
|
+
self.past_iter[i] = []
|
|
237
|
+
self.futr_iter[i] = []
|
|
238
|
+
self.past_rm[i] = []
|
|
239
|
+
self.futr_rm[i] = []
|
|
240
|
+
pi.new_operation('Recreating...', self.niters)
|
|
241
|
+
# tracker = SummaryTracker()
|
|
242
|
+
# self.output_file.close()
|
|
243
|
+
|
|
244
|
+
if self.ibstates:
|
|
245
|
+
# Copying the ibstates group from the first file as base
|
|
246
|
+
self.output_file.copy(self.westH5[1]['ibstates'], self.output_file)
|
|
247
|
+
del self.output_file['ibstates/0/istate_pcoord']
|
|
248
|
+
del self.output_file['ibstates/0/istate_index']
|
|
249
|
+
|
|
250
|
+
# Combining the rest of the istate datasets
|
|
251
|
+
for ifile, (key, west) in enumerate(self.westH5.items()):
|
|
252
|
+
if ifile == 0:
|
|
253
|
+
final_istate_index = west['ibstates/0/istate_index']
|
|
254
|
+
final_istate_pcoord = west['ibstates/0/istate_pcoord']
|
|
255
|
+
if final_istate_index.dtype != istate_dtype:
|
|
256
|
+
final_istate_index = create_idtype_array(final_istate_index)
|
|
257
|
+
else:
|
|
258
|
+
addition = west['ibstates/0/istate_index'][:]
|
|
259
|
+
if addition.dtype != istate_dtype:
|
|
260
|
+
addition = create_idtype_array(addition)
|
|
261
|
+
final_istate_index = np.append(final_istate_index, addition)
|
|
262
|
+
final_istate_pcoord = np.append(final_istate_pcoord, west['ibstates/0/istate_pcoord'][:], axis=0)
|
|
263
|
+
|
|
264
|
+
# Saving them into self.output_file
|
|
265
|
+
self.output_file['ibstates/0'].create_dataset('istate_index', data=final_istate_index, dtype=istate_dtype)
|
|
266
|
+
self.output_file['ibstates/0'].create_dataset('istate_pcoord', data=final_istate_pcoord)
|
|
267
|
+
|
|
268
|
+
# Remaking the ibstates index link
|
|
269
|
+
master_index_row = self.output_file['ibstates/index'][0]
|
|
270
|
+
master_index_row['iter_valid'] = 0
|
|
271
|
+
master_index_row['n_bstates'] = len(self.output_file['ibstates/0/bstate_index'])
|
|
272
|
+
master_index_row['group_ref'] = self.output_file['ibstates/0'].ref
|
|
273
|
+
|
|
274
|
+
self.output_file['ibstates/index'][0] = master_index_row
|
|
275
|
+
|
|
276
|
+
for iter in range(self.niters):
|
|
277
|
+
# We have the following datasets in each iteration:
|
|
278
|
+
# ibstates, which can now be combined with --ibstates
|
|
279
|
+
# pcoord
|
|
280
|
+
# seg_index
|
|
281
|
+
# wtgraph
|
|
282
|
+
# wtgraph is going to be a little more complex to handle, but not too bad.
|
|
283
|
+
# aux data specified
|
|
284
|
+
iter += 1
|
|
285
|
+
ifile = 0
|
|
286
|
+
# self.output_file = h5io.WESTPAH5File(self.output_file_name, 'w', creating_program=True)
|
|
287
|
+
# Determine how many simulations to append or remove per west file.
|
|
288
|
+
# self.segments = {}
|
|
289
|
+
# for key,value in self.n_sims.items():
|
|
290
|
+
# self.segments[key] = int(np.floor(len(self.past_iter[key]) / value))
|
|
291
|
+
|
|
292
|
+
# run_once = 0
|
|
293
|
+
# total_current_sims = 0
|
|
294
|
+
# for i in self.source_sinks:
|
|
295
|
+
# total_current_sims += len(self.past_iter[i])
|
|
296
|
+
# total_current_sims += len(self.past_rm[i])
|
|
297
|
+
for ifile, west in enumerate(westh5):
|
|
298
|
+
westdict = west['west']
|
|
299
|
+
seg_index = westdict['iterations/iter_{0:08d}'.format(iter)]['seg_index'][...]
|
|
300
|
+
pcoord = westdict['iterations/iter_{0:08d}'.format(iter)]['pcoord'][...]
|
|
301
|
+
wtgraph = westdict['iterations/iter_{0:08d}'.format(iter)]['wtgraph'][...]
|
|
302
|
+
# new_weight = westdict['iterations/iter_{0:08d}'.format(iter)]['new_weight'][...]
|
|
303
|
+
if self.aux:
|
|
304
|
+
auxdata = {}
|
|
305
|
+
for i in self.aux:
|
|
306
|
+
auxdata[str(i)] = westdict['iterations/iter_{0:08d}'.format(iter)]['auxdata'][str(i)][...]
|
|
307
|
+
if iter == 1 and ifile == 0:
|
|
308
|
+
new_dtype = np.dtype(seg_index.dtype.descr + [('group', '<i8')])
|
|
309
|
+
new_seg_index = np.zeros(seg_index.shape, dtype=new_dtype)
|
|
310
|
+
for dt, val in seg_index.dtype.fields.items():
|
|
311
|
+
new_seg_index[dt] = seg_index[dt]
|
|
312
|
+
new_seg_index['group'] = ifile
|
|
313
|
+
del seg_index
|
|
314
|
+
seg_index = new_seg_index[...]
|
|
315
|
+
del new_seg_index
|
|
316
|
+
if ifile == 0:
|
|
317
|
+
mseg = seg_index
|
|
318
|
+
mpco = pcoord
|
|
319
|
+
mwtg = wtgraph
|
|
320
|
+
if self.aux:
|
|
321
|
+
maux = {}
|
|
322
|
+
for i in self.aux:
|
|
323
|
+
maux[str(i)] = auxdata[str(i)]
|
|
324
|
+
if iter == 1:
|
|
325
|
+
summary = westdict['summary'][...]
|
|
326
|
+
|
|
327
|
+
start_point.append(0)
|
|
328
|
+
if ifile != 0:
|
|
329
|
+
# print(mseg.shape, seg_index.shape, ifile)
|
|
330
|
+
# print(mpco.shape, pcoord.shape, ifile)
|
|
331
|
+
# print(mwtg.shape, wtgraph.shape, ifile)
|
|
332
|
+
if iter != 1:
|
|
333
|
+
addition = prev_start_point[ifile] # noqa: F821
|
|
334
|
+
else:
|
|
335
|
+
addition = mseg.shape[0]
|
|
336
|
+
seg_index['parent_id'][np.where(seg_index['parent_id'] >= 0)] += addition
|
|
337
|
+
seg_index['parent_id'][np.where(seg_index['parent_id'] < 0)] -= istate_addition[ifile]
|
|
338
|
+
seg_index['wtg_offset'] += mwtg.shape[0]
|
|
339
|
+
start_point.append(mseg.shape[0])
|
|
340
|
+
wtgraph += mwtg.shape[0]
|
|
341
|
+
mseg = np.concatenate((mseg, seg_index))
|
|
342
|
+
mpco = np.concatenate((mpco, pcoord))
|
|
343
|
+
mwtg = np.concatenate((mwtg, wtgraph))
|
|
344
|
+
if self.aux:
|
|
345
|
+
for i in self.aux:
|
|
346
|
+
maux[str(i)] = np.concatenate((maux[str(i)], auxdata[str(i)]))
|
|
347
|
+
ifile += 1
|
|
348
|
+
del seg_index, pcoord, wtgraph, westdict
|
|
349
|
+
if self.aux:
|
|
350
|
+
del auxdata
|
|
351
|
+
gc.collect()
|
|
352
|
+
# Make a real copy to use in the next iteration.
|
|
353
|
+
# self.past_iter = self.futr_iter.copy()
|
|
354
|
+
# self.past_rm[i] = self.futr_rm.copy()
|
|
355
|
+
prev_start_point = start_point # noqa: F841
|
|
356
|
+
start_point = []
|
|
357
|
+
# This is... maybe wrong, actually? Or at least, it's not ALL that is required for normalizing things.
|
|
358
|
+
# We need to weight everything by 1/N, then just normalize if that normalization was wrong. Keep the relative weights sane.
|
|
359
|
+
# ... or actually, no, that's fine, nevermind, what's wrong with me? But we'll leave it in for now.
|
|
360
|
+
|
|
361
|
+
# Normalize weight of each iteration, done unless specified not to.
|
|
362
|
+
if not self.reweight:
|
|
363
|
+
mseg['weight'] /= mseg['weight'].sum()
|
|
364
|
+
|
|
365
|
+
summary['n_particles'][iter - 1] = mseg.shape[0]
|
|
366
|
+
summary['norm'][iter - 1] = mseg['weight'].sum()
|
|
367
|
+
summary['min_seg_prob'][iter - 1] = min(mseg['weight'])
|
|
368
|
+
summary['max_seg_prob'][iter - 1] = max(mseg['weight'])
|
|
369
|
+
|
|
370
|
+
curr_iter = self.output_file.create_group('iterations/iter_{0:08d}'.format(iter))
|
|
371
|
+
curr_iter.attrs['n_iter'] = iter
|
|
372
|
+
|
|
373
|
+
# Hard-link ibstates dataset to the main one
|
|
374
|
+
if self.ibstates:
|
|
375
|
+
curr_iter['ibstates'] = self.output_file['ibstates/0']
|
|
376
|
+
|
|
377
|
+
ds_rate_evol = curr_iter.create_dataset('wtgraph', data=mwtg, shuffle=True, compression=9)
|
|
378
|
+
ds_rate_evol = curr_iter.create_dataset('seg_index', data=mseg, shuffle=True, compression=9)
|
|
379
|
+
ds_rate_evol = curr_iter.create_dataset('pcoord', data=mpco, shuffle=True, compression=9)
|
|
380
|
+
if self.aux:
|
|
381
|
+
aux_iter = self.output_file.create_group('iterations/iter_{0:08d}/auxdata'.format(iter))
|
|
382
|
+
for i in self.aux:
|
|
383
|
+
ds_rate_evol = aux_iter.create_dataset(str(i), data=maux[str(i)], shuffle=True, compression=9)
|
|
384
|
+
# We need to be careful about memory, here. We are blowing uppppp.
|
|
385
|
+
# We're STILL blowing up. Criiiiiipes.
|
|
386
|
+
# self.segments = {}
|
|
387
|
+
del mseg, mpco, mwtg, ds_rate_evol, curr_iter # , self.segments
|
|
388
|
+
if self.aux:
|
|
389
|
+
del maux, aux_iter
|
|
390
|
+
gc.collect()
|
|
391
|
+
self.output_file.flush()
|
|
392
|
+
# self.output_file.close()
|
|
393
|
+
# print("How big is our summary?")
|
|
394
|
+
# print(sys.getsizeof(summary))
|
|
395
|
+
# objgraph.show_most_common_types(limit=50)
|
|
396
|
+
# objgraph.show_growth(limit=10)
|
|
397
|
+
# objgraph.show_most_common_types(objects=objgraph.get_leaking_objects())
|
|
398
|
+
pi.progress += 1
|
|
399
|
+
|
|
400
|
+
pi.new_operation('Writing to file...')
|
|
401
|
+
ds_rate_evol = self.output_file.create_dataset('summary', data=summary, shuffle=True, compression=9) # noqa: F841
|
|
402
|
+
self.output_file.attrs['west_current_iteration'] = self.niters
|
|
403
|
+
self.output_file.attrs['west_file_format_version'] = 7
|
|
404
|
+
self.output_file.attrs['west_iter_prec'] = 8
|
|
405
|
+
self.output_file.attrs['westpa_fileformat_version'] = 7
|
|
406
|
+
self.output_file.attrs['westpa_iter_prec'] = 8
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
def entry_point():
|
|
410
|
+
WMultiWest().main()
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
if __name__ == '__main__':
|
|
414
|
+
entry_point()
|