westpa 2022.10__cp312-cp312-macosx_10_9_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-darwin.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-darwin.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-darwin.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-darwin.so +0 -0
  76. westpa/mclib/__init__.py +264 -0
  77. westpa/mclib/__main__.py +28 -0
  78. westpa/mclib/_mclib.cpython-312-darwin.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-darwin.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 +5 -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,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()