westpa 2022.12__cp313-cp313-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of westpa might be problematic. Click here for more details.

Files changed (149) 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 +68 -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 +376 -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 +491 -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-313-darwin.so +0 -0
  42. westpa/core/binning/assign.py +455 -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 +506 -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-313-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 +719 -0
  61. westpa/core/reweight/__init__.py +14 -0
  62. westpa/core/reweight/_reweight.cpython-313-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 +835 -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 +910 -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/_fasthist.cpython-313-darwin.so +0 -0
  75. westpa/mclib/__init__.py +271 -0
  76. westpa/mclib/__main__.py +28 -0
  77. westpa/mclib/_mclib.cpython-313-darwin.so +0 -0
  78. westpa/oldtools/__init__.py +4 -0
  79. westpa/oldtools/aframe/__init__.py +35 -0
  80. westpa/oldtools/aframe/atool.py +75 -0
  81. westpa/oldtools/aframe/base_mixin.py +26 -0
  82. westpa/oldtools/aframe/binning.py +178 -0
  83. westpa/oldtools/aframe/data_reader.py +560 -0
  84. westpa/oldtools/aframe/iter_range.py +200 -0
  85. westpa/oldtools/aframe/kinetics.py +117 -0
  86. westpa/oldtools/aframe/mcbs.py +153 -0
  87. westpa/oldtools/aframe/output.py +39 -0
  88. westpa/oldtools/aframe/plotting.py +90 -0
  89. westpa/oldtools/aframe/trajwalker.py +126 -0
  90. westpa/oldtools/aframe/transitions.py +469 -0
  91. westpa/oldtools/cmds/__init__.py +0 -0
  92. westpa/oldtools/cmds/w_ttimes.py +361 -0
  93. westpa/oldtools/files.py +34 -0
  94. westpa/oldtools/miscfn.py +23 -0
  95. westpa/oldtools/stats/__init__.py +4 -0
  96. westpa/oldtools/stats/accumulator.py +35 -0
  97. westpa/oldtools/stats/edfs.py +129 -0
  98. westpa/oldtools/stats/mcbs.py +96 -0
  99. westpa/tools/__init__.py +33 -0
  100. westpa/tools/binning.py +472 -0
  101. westpa/tools/core.py +340 -0
  102. westpa/tools/data_reader.py +159 -0
  103. westpa/tools/dtypes.py +31 -0
  104. westpa/tools/iter_range.py +198 -0
  105. westpa/tools/kinetics_tool.py +340 -0
  106. westpa/tools/plot.py +283 -0
  107. westpa/tools/progress.py +17 -0
  108. westpa/tools/selected_segs.py +154 -0
  109. westpa/tools/wipi.py +751 -0
  110. westpa/trajtree/__init__.py +4 -0
  111. westpa/trajtree/_trajtree.cpython-313-darwin.so +0 -0
  112. westpa/trajtree/trajtree.py +117 -0
  113. westpa/westext/__init__.py +0 -0
  114. westpa/westext/adaptvoronoi/__init__.py +3 -0
  115. westpa/westext/adaptvoronoi/adaptVor_driver.py +214 -0
  116. westpa/westext/hamsm_restarting/__init__.py +3 -0
  117. westpa/westext/hamsm_restarting/example_overrides.py +35 -0
  118. westpa/westext/hamsm_restarting/restart_driver.py +1165 -0
  119. westpa/westext/stringmethod/__init__.py +11 -0
  120. westpa/westext/stringmethod/fourier_fitting.py +69 -0
  121. westpa/westext/stringmethod/string_driver.py +253 -0
  122. westpa/westext/stringmethod/string_method.py +306 -0
  123. westpa/westext/weed/BinCluster.py +180 -0
  124. westpa/westext/weed/ProbAdjustEquil.py +100 -0
  125. westpa/westext/weed/UncertMath.py +247 -0
  126. westpa/westext/weed/__init__.py +10 -0
  127. westpa/westext/weed/weed_driver.py +192 -0
  128. westpa/westext/wess/ProbAdjust.py +101 -0
  129. westpa/westext/wess/__init__.py +6 -0
  130. westpa/westext/wess/wess_driver.py +217 -0
  131. westpa/work_managers/__init__.py +57 -0
  132. westpa/work_managers/core.py +396 -0
  133. westpa/work_managers/environment.py +134 -0
  134. westpa/work_managers/mpi.py +318 -0
  135. westpa/work_managers/processes.py +187 -0
  136. westpa/work_managers/serial.py +28 -0
  137. westpa/work_managers/threads.py +79 -0
  138. westpa/work_managers/zeromq/__init__.py +20 -0
  139. westpa/work_managers/zeromq/core.py +641 -0
  140. westpa/work_managers/zeromq/node.py +131 -0
  141. westpa/work_managers/zeromq/work_manager.py +526 -0
  142. westpa/work_managers/zeromq/worker.py +320 -0
  143. westpa-2022.12.dist-info/AUTHORS +22 -0
  144. westpa-2022.12.dist-info/LICENSE +21 -0
  145. westpa-2022.12.dist-info/METADATA +193 -0
  146. westpa-2022.12.dist-info/RECORD +149 -0
  147. westpa-2022.12.dist-info/WHEEL +6 -0
  148. westpa-2022.12.dist-info/entry_points.txt +29 -0
  149. westpa-2022.12.dist-info/top_level.txt +1 -0
@@ -0,0 +1,780 @@
1
+ import logging
2
+ import warnings
3
+
4
+ import numpy as np
5
+
6
+ from westpa.tools import WESTMasterCommand, WESTParallelTool
7
+
8
+ from westpa.tools.kinetics_tool import WESTKineticsBase, AverageCommands, generate_future
9
+ from westpa.core import h5io
10
+
11
+
12
+ from westpa.mclib import mcbs_ci_correl
13
+
14
+ from westpa.core.reweight import reweight_for_c, FluxMatrix
15
+
16
+
17
+ warnings.filterwarnings('ignore', category=DeprecationWarning)
18
+ warnings.filterwarnings('ignore', category=RuntimeWarning)
19
+ warnings.filterwarnings('ignore', category=FutureWarning)
20
+
21
+ log = logging.getLogger('w_reweight')
22
+
23
+
24
+ def _2D_eval_block(
25
+ iblock, start, stop, nstates, data_input, name, mcbs_alpha, mcbs_nsets, mcbs_acalpha, do_correl, mcbs_enable, estimator_kwargs
26
+ ):
27
+ # As our reweighting estimator is a weird function, we can't use the general mclib block.
28
+ results = []
29
+ for istate in range(nstates):
30
+ for jstate in range(nstates):
31
+ if istate == jstate:
32
+ continue
33
+ estimator_kwargs.update(dict(istate=istate, jstate=jstate, nstates=nstates))
34
+
35
+ dataset = {'indices': np.array(list(range(start - 1, stop - 1)), dtype=np.uint16)}
36
+
37
+ ci_res = mcbs_ci_correl(
38
+ dataset,
39
+ estimator=reweight_for_c,
40
+ alpha=mcbs_alpha,
41
+ n_sets=mcbs_nsets,
42
+ autocorrel_alpha=mcbs_acalpha,
43
+ subsample=(lambda x: x[0]),
44
+ do_correl=do_correl,
45
+ mcbs_enable=mcbs_enable,
46
+ estimator_kwargs=estimator_kwargs,
47
+ )
48
+ results.append((name, iblock, istate, jstate, (start, stop) + ci_res))
49
+
50
+ return results
51
+
52
+
53
+ def _1D_eval_block(
54
+ iblock, start, stop, nstates, data_input, name, mcbs_alpha, mcbs_nsets, mcbs_acalpha, do_correl, mcbs_enable, estimator_kwargs
55
+ ):
56
+ # As our reweighting estimator is a weird function, we can't use the general mclib block.
57
+ results = []
58
+ for istate in range(nstates):
59
+ # A little hack to make our estimator play nice, as jstate must be there.
60
+ # For 1D datasets (state probabilities, etc), the argument isn't used in our estimator,
61
+ # and so any variable which has the proper type is fine.
62
+ estimator_kwargs.update(dict(istate=istate, jstate=istate, nstates=nstates))
63
+
64
+ dataset = {'indices': np.array(list(range(start - 1, stop - 1)), dtype=np.uint16)}
65
+
66
+ ci_res = mcbs_ci_correl(
67
+ dataset,
68
+ estimator=reweight_for_c,
69
+ alpha=mcbs_alpha,
70
+ n_sets=mcbs_nsets,
71
+ autocorrel_alpha=mcbs_acalpha,
72
+ subsample=(lambda x: x[0]),
73
+ do_correl=do_correl,
74
+ mcbs_enable=mcbs_enable,
75
+ estimator_kwargs=estimator_kwargs,
76
+ )
77
+ results.append((name, iblock, istate, (start, stop) + ci_res))
78
+
79
+ return results
80
+
81
+
82
+ def _pop_eval_block(
83
+ iblock,
84
+ start,
85
+ stop,
86
+ nstates,
87
+ data_input,
88
+ name,
89
+ mcbs_alpha,
90
+ mcbs_nsets,
91
+ mcbs_acalpha,
92
+ do_correl,
93
+ mcbs_enable,
94
+ estimator_kwargs,
95
+ **kwargs
96
+ ):
97
+ # As our reweighting estimator is a weird function, we can't use the general mclib block.
98
+ # A little hack to make our estimator play nice, as jstate must be there.
99
+ # For 1D datasets (state probabilities, etc), the argument isn't used in our estimator,
100
+ # and so any variable which has the proper type is fine.
101
+ estimator_kwargs.update(dict(istate=0, jstate=0, nstates=nstates))
102
+
103
+ estimator_kwargs.update({'indices': np.array(list(range(start - 1, stop - 1)), dtype=np.uint16), 'stride': 1})
104
+ # cpdef reweight_for_c(rows, cols, obs, flux, insert, indices, nstates, nbins, state_labels, state_map, nfbins, istate, jstate, stride, bin_last_state_map, bin_state_map, return_obs, obs_threshold=1):
105
+ # ['nbins', 'rows', 'state_map', 'nfbins', 'bin_state_map', 'cols', 'jstate', 'flux', 'istate', 'return_obs', 'bin_last_state_map', 'insert', 'nstates', 'indices', 'state_labels', 'obs']
106
+ # cpdef reweight_for_c(stride, obs_threshold=1):
107
+
108
+ ci_res = reweight_for_c(**estimator_kwargs)[...].reshape(-1, nstates).sum(axis=1)
109
+
110
+ return ci_res
111
+
112
+
113
+ class RWMatrix(WESTKineticsBase, FluxMatrix):
114
+ subcommand = 'init'
115
+ default_kinetics_file = 'reweight.h5'
116
+ default_output_file = 'reweight.h5'
117
+ help_text = 'create a color-labeled transition matrix from a WESTPA simulation'
118
+ description = '''\
119
+ Generate a colored transition matrix from a WE assignment file. The subsequent
120
+ analysis requires that the assignments are calculated using only the initial and
121
+ final time points of each trajectory segment. This may require downsampling the
122
+ h5file generated by a WE simulation. In the future w_assign may be enhanced to optionally
123
+ generate the necessary assignment file from a h5file with intermediate time points.
124
+ Additionally, this analysis is currently only valid on simulations performed under
125
+ either equilibrium or steady-state conditions without recycling target states.
126
+
127
+ -----------------------------------------------------------------------------
128
+ Output format
129
+ -----------------------------------------------------------------------------
130
+
131
+ The output file (-o/--output, by default "reweight.h5") contains the
132
+ following datasets:
133
+
134
+ ``/bin_populations`` [window, bin]
135
+ The reweighted populations of each bin based on windows. Bins contain
136
+ one color each, so to recover the original un-colored spatial bins,
137
+ one must sum over all states.
138
+
139
+ ``/iterations`` [iteration]
140
+ *(Structured -- see below)* Sparse matrix data from each
141
+ iteration. They are reconstructed and averaged within the
142
+ w_reweight {kinetics/probs} routines so that observables may
143
+ be calculated. Each group contains 4 vectors of data:
144
+
145
+ flux
146
+ *(Floating-point)* The weight of a series of flux events
147
+ cols
148
+ *(Integer)* The bin from which a flux event began.
149
+ cols
150
+ *(Integer)* The bin into which the walker fluxed.
151
+ obs
152
+ *(Integer)* How many flux events were observed during this
153
+ iteration.
154
+
155
+ -----------------------------------------------------------------------------
156
+ Command-line options
157
+ -----------------------------------------------------------------------------
158
+ '''
159
+
160
+ def __init__(self, parent):
161
+ super().__init__(parent)
162
+ self.parent = parent
163
+ self.assignments_file = None
164
+
165
+ def add_args(self, parser):
166
+ cogroup = parser.add_argument_group('calculation options')
167
+ cogroup.add_argument(
168
+ '-s',
169
+ '--sampling-frequency',
170
+ dest='sampling_frequency',
171
+ choices=['timepoint', 'iteration'],
172
+ default='timepoint',
173
+ help='''Observe for transition events with a lag
174
+ time corresponding to either each weighted ensemble
175
+ iteration (``iteration``) or each sub-iteration
176
+ timepoint (``timepoint``) (default: %(default)s).
177
+ For each pair of bins, store the sum of fluxes
178
+ in a given iteration (['flux']). Similarly,
179
+ for each bin, store the sum of weights in the bin
180
+ over all observation points for a given iteration
181
+ (['bin_populations']).''',
182
+ )
183
+
184
+ def process_args(self, args):
185
+ self.output_file = h5io.WESTPAH5File(args.output, 'w', creating_program=True)
186
+ self.assignments_file = h5io.WESTPAH5File(args.assignments, 'r')
187
+ # Force a build of the transition matrix at the iteration level.
188
+ self.sampling_frequency = 'iteration' if self.assignments_file.attrs['subsampled'] is True else args.sampling_frequency
189
+
190
+ def go(self):
191
+ # This function exists in FluxMatrix, and is not currently portable.
192
+ # That is, it assumes all properties are properly initialized (self.assignments_file, etc)
193
+ # TO DO : make it portable.
194
+ pi = self.progress.indicator
195
+ with pi:
196
+ self.w_postanalysis_matrix()
197
+
198
+
199
+ class RWReweight(AverageCommands):
200
+ help_text = 'Parent class for all reweighting routines, as they all use the same estimator code.'
201
+
202
+ def __init__(self, parent):
203
+ super().__init__(parent)
204
+ self.parent = parent
205
+ self.assignments_file = None
206
+
207
+ def add_args(self, parser):
208
+ cogroup = parser.add_argument_group('calculation options')
209
+ cogroup.add_argument(
210
+ '--obs-threshold',
211
+ type=int,
212
+ default=1,
213
+ help='''The minimum number of observed transitions between two states i and j necessary to include
214
+ fluxes in the reweighting estimate''',
215
+ )
216
+
217
+ def process_args(self, args):
218
+ self.obs_threshold = args.obs_threshold
219
+
220
+ def accumulate_statistics(self, start_iter, stop_iter):
221
+ '''
222
+ This function pulls previously generated flux matrix data into memory.
223
+ The data is assumed to exist within an HDF5 file that is available
224
+ as a property.
225
+ The data is kept as a single dimensional numpy array to use with the
226
+ cython estimator.
227
+ '''
228
+ # This is designed to pull in the flux data...
229
+ rows = []
230
+ cols = []
231
+ obs = []
232
+ flux = []
233
+ insert = [0] * (start_iter)
234
+
235
+ # Actually, I'm not sure we need to start this at start_iter...
236
+ # ... as it's keyed to the iteration, we need to make sure that the index
237
+ # matches with the iteration (particularly for 'insert').
238
+ # It's just easier to load all the data, although we could just start insert as a list of length
239
+ # start_iter.
240
+ for iiter in range(start_iter, stop_iter):
241
+ iter_grp = self.kinetics_file['iterations']['iter_{:08d}'.format(iiter)]
242
+
243
+ rows.append(iter_grp['rows'][...])
244
+ cols.append(iter_grp['cols'][...])
245
+ obs.append(iter_grp['obs'][...])
246
+ flux.append(iter_grp['flux'][...])
247
+ # 'insert' is the insertion point for each iteration; that is,
248
+ # at what point do we look into the list for iteration X?
249
+ insert.append(iter_grp['rows'][...].shape[0] + insert[-1])
250
+ self.rows = np.concatenate(rows)
251
+ self.cols = np.concatenate(cols)
252
+ self.obs = np.concatenate(obs)
253
+ self.flux = np.concatenate(flux)
254
+ assert insert[-1] == len(self.rows)
255
+ self.insert = np.array(insert, dtype=np.intc)
256
+
257
+ def generate_reweight_data(self):
258
+ '''
259
+ This function ensures all the appropriate files are loaded, sets
260
+ appropriate attributes necessary for all calling functions/children,
261
+ and then calls the function to load in the flux matrix data.
262
+ '''
263
+
264
+ self.open_files()
265
+ self.open_assignments()
266
+
267
+ self.nfbins = self.kinetics_file.attrs['nrows']
268
+ self.npts = self.kinetics_file.attrs['npts']
269
+ self.state_map = self.assignments_file['state_map'][...]
270
+ self.state_labels = self.assignments_file['state_labels'][...]
271
+
272
+ # Copying this over to make it more convenient...
273
+ self.output_file.replace_dataset('state_labels', data=self.assignments_file['state_labels'][...])
274
+ # ... as we'll need it for ploterr.
275
+
276
+ assert self.nstates == len(self.state_labels)
277
+ assert self.nfbins == self.nbins * self.nstates
278
+
279
+ start_iter, stop_iter, _ = self.iter_range.iter_start, self.iter_range.iter_stop, self.iter_range.iter_step
280
+
281
+ # This function call loads up all the flux matrix data and stores it in memory.
282
+ # We just give our cython estimator all the information it needs beforehand, as
283
+ # the nature of the bootstrap means we can't know what iterations we'll actually need before
284
+ # the routine is called.
285
+
286
+ self.accumulate_statistics(start_iter, stop_iter)
287
+
288
+
289
+ class RWRate(RWReweight):
290
+ subcommand = 'kinetics'
291
+ help_text = 'Generates rate and flux values from a WESTPA simulation via reweighting.'
292
+ default_kinetics_file = 'reweight.h5'
293
+ default_output_file = 'reweight.h5'
294
+ description = '''\
295
+ Calculate average rates from weighted ensemble data using the postanalysis
296
+ reweighting scheme. Bin assignments (usually "assign.h5") and pre-calculated
297
+ iteration flux matrices (usually "reweight.h5") data files must have been
298
+ previously generated using w_reweight matrix (see "w_assign --help" and
299
+ "w_reweight init --help" for information on generating these files).
300
+
301
+ -----------------------------------------------------------------------------
302
+ Output format
303
+ -----------------------------------------------------------------------------
304
+ The output file (-o/--output, usually "kinrw.h5") contains the following
305
+ dataset:
306
+
307
+ /avg_rates [state,state]
308
+ (Structured -- see below) State-to-state rates based on entire window of
309
+ iterations selected.
310
+
311
+ /avg_total_fluxes [state]
312
+ (Structured -- see below) Total fluxes into each state based on entire
313
+ window of iterations selected.
314
+
315
+ /avg_conditional_fluxes [state,state]
316
+ (Structured -- see below) State-to-state fluxes based on entire window of
317
+ iterations selected.
318
+
319
+ If --evolution-mode is specified, then the following additional datasets are
320
+ available:
321
+
322
+ /rate_evolution [window][state][state]
323
+ (Structured -- see below). State-to-state rates based on windows of
324
+ iterations of varying width. If --evolution-mode=cumulative, then
325
+ these windows all begin at the iteration specified with
326
+ --start-iter and grow in length by --step-iter for each successive
327
+ element. If --evolution-mode=blocked, then these windows are all of
328
+ width --step-iter (excluding the last, which may be shorter), the first
329
+ of which begins at iteration --start-iter.
330
+
331
+ /target_flux_evolution [window,state]
332
+ (Structured -- see below). Total flux into a given macro state based on
333
+ windows of iterations of varying width, as in /rate_evolution.
334
+
335
+ /conditional_flux_evolution [window,state,state]
336
+ (Structured -- see below). State-to-state fluxes based on windows of
337
+ varying width, as in /rate_evolution.
338
+
339
+ The structure of these datasets is as follows:
340
+
341
+ iter_start
342
+ (Integer) Iteration at which the averaging window begins (inclusive).
343
+
344
+ iter_stop
345
+ (Integer) Iteration at which the averaging window ends (exclusive).
346
+
347
+ expected
348
+ (Floating-point) Expected (mean) value of the observable as evaluated within
349
+ this window, in units of inverse tau.
350
+
351
+ ci_lbound
352
+ (Floating-point) Lower bound of the confidence interval of the observable
353
+ within this window, in units of inverse tau.
354
+
355
+ ci_ubound
356
+ (Floating-point) Upper bound of the confidence interval of the observable
357
+ within this window, in units of inverse tau.
358
+
359
+ stderr
360
+ (Floating-point) The standard error of the mean of the observable
361
+ within this window, in units of inverse tau.
362
+
363
+ corr_len
364
+ (Integer) Correlation length of the observable within this window, in units
365
+ of tau.
366
+
367
+ Each of these datasets is also stamped with a number of attributes:
368
+
369
+ mcbs_alpha
370
+ (Floating-point) Alpha value of confidence intervals. (For example,
371
+ *alpha=0.05* corresponds to a 95% confidence interval.)
372
+
373
+ mcbs_nsets
374
+ (Integer) Number of bootstrap data sets used in generating confidence
375
+ intervals.
376
+
377
+ mcbs_acalpha
378
+ (Floating-point) Alpha value for determining correlation lengths.
379
+
380
+
381
+ -----------------------------------------------------------------------------
382
+ Command-line options
383
+ -----------------------------------------------------------------------------
384
+ '''
385
+
386
+ def __init__(self, parent):
387
+ super().__init__(parent)
388
+ self.parent = parent
389
+ self.assignments_file = None
390
+
391
+ def w_postanalysis_reweight(self):
392
+ '''
393
+ This function ensures the data is ready to send in to the estimator and
394
+ the bootstrapping routine, then does so. Much of this is simply setting
395
+ up appropriate args and kwargs, then passing them in to the
396
+ 'run_calculation' function, which sets up future objects to send to the
397
+ work manager. The results are returned, and then written to the
398
+ appropriate HDF5 dataset.
399
+ This function is specific for the rates and fluxes from the reweighting
400
+ method.
401
+ '''
402
+ self.generate_reweight_data()
403
+ pi = self.progress.indicator
404
+
405
+ # start_iter, stop_iter, step_iter = self.iter_range.iter_start, self.iter_range.iter_stop, self.iter_range.iter_step
406
+ # start_pts = list(range(start_iter, stop_iter, step_iter))
407
+ start_iter = self.iter_range.iter_start
408
+ stop_iter = self.iter_range.iter_stop
409
+
410
+ indices = np.array(list(range(start_iter - 1, stop_iter - 1)), dtype=np.uint16)
411
+ submit_kwargs = dict(
412
+ pi=pi, nstates=self.nstates, start_iter=self.start_iter, stop_iter=self.stop_iter, step_iter=self.step_iter
413
+ )
414
+
415
+ # Due to the way our estimator is written, we're using the same dataset every time. We're just returning different values.
416
+ submit_kwargs['dataset'] = {'indices': indices}
417
+ submit_kwargs['estimator_kwargs'] = {}
418
+ submit_kwargs['estimator_kwargs'].update(
419
+ dict(
420
+ rows=self.rows,
421
+ cols=self.cols,
422
+ obs=self.obs,
423
+ flux=self.flux,
424
+ insert=self.insert,
425
+ bin_last_state_map=np.tile(np.arange(self.nstates, dtype=int), self.nbins),
426
+ bin_state_map=np.repeat(self.state_map[:-1], self.nstates),
427
+ nfbins=self.nfbins,
428
+ state_labels=self.state_labels,
429
+ return_obs='R', # Set to a default, here, but we explicitly set it later.
430
+ state_map=self.state_map,
431
+ nbins=self.nbins,
432
+ )
433
+ )
434
+
435
+ # Calculate averages for the simulation, then report, if necessary.
436
+
437
+ # The dataset options are what we pass on to the estimator...
438
+ submit_kwargs['estimator_kwargs']['return_obs'] = 'R'
439
+ avg_rates = self.run_calculation(eval_block=_2D_eval_block, name='Average Rates', dim=2, do_averages=True, **submit_kwargs)
440
+ avg_rates['expected'] *= self.npts - 1
441
+ avg_rates['ci_ubound'] *= self.npts - 1
442
+ avg_rates['ci_lbound'] *= self.npts - 1
443
+ self.output_file.replace_dataset('avg_rates', data=avg_rates[1])
444
+
445
+ submit_kwargs['estimator_kwargs']['return_obs'] = 'F'
446
+ avg_conditional_fluxes = self.run_calculation(
447
+ eval_block=_2D_eval_block, name='Average Flux', dim=2, do_averages=True, **submit_kwargs
448
+ )
449
+ avg_conditional_fluxes['expected'] *= self.npts - 1
450
+ avg_conditional_fluxes['ci_ubound'] *= self.npts - 1
451
+ avg_conditional_fluxes['ci_lbound'] *= self.npts - 1
452
+ self.output_file.replace_dataset('avg_conditional_fluxes', data=avg_conditional_fluxes[1])
453
+
454
+ # Now, print them!
455
+
456
+ # We've returned an average, but it still exists in a timeslice format. So we need to return the 'last' value.
457
+ if self.display_averages:
458
+ self.print_averages(avg_conditional_fluxes[1], '\nfluxes from state to state:', dim=2)
459
+ self.print_averages(avg_rates[1], '\nrates from state to state:', dim=2)
460
+
461
+ # Do a bootstrap evolution.
462
+
463
+ submit_kwargs['estimator_kwargs']['return_obs'] = 'R'
464
+ rate_evol = self.run_calculation(eval_block=_2D_eval_block, name='Rate Evolution', dim=2, **submit_kwargs)
465
+ rate_evol['expected'] *= self.npts - 1
466
+ rate_evol['ci_ubound'] *= self.npts - 1
467
+ rate_evol['ci_lbound'] *= self.npts - 1
468
+ self.output_file.replace_dataset('rate_evolution', data=rate_evol, shuffle=True, compression=9)
469
+
470
+ submit_kwargs['estimator_kwargs']['return_obs'] = 'F'
471
+ flux_evol = self.run_calculation(eval_block=_2D_eval_block, name='Conditional Flux Evolution', dim=2, **submit_kwargs)
472
+ flux_evol['expected'] *= self.npts - 1
473
+ flux_evol['ci_ubound'] *= self.npts - 1
474
+ flux_evol['ci_lbound'] *= self.npts - 1
475
+ self.output_file.replace_dataset('conditional_flux_evolution', data=rate_evol, shuffle=True, compression=9)
476
+
477
+ def go(self):
478
+ pi = self.progress.indicator
479
+ with pi:
480
+ self.w_postanalysis_reweight()
481
+
482
+
483
+ class RWStateProbs(RWReweight):
484
+ subcommand = 'probs'
485
+ help_text = 'Calculates color and state probabilities via reweighting.'
486
+ default_kinetics_file = 'reweight.h5'
487
+ description = '''\
488
+ Calculate average populations from weighted ensemble data using the postanalysis
489
+ reweighting scheme. Bin assignments (usually "assign.h5") and pre-calculated
490
+ iteration flux matrices (usually "reweight.h5") data files must have been
491
+ previously generated using w_reweight matrix (see "w_assign --help" and
492
+ "w_reweight init --help" for information on generating these files).
493
+
494
+ -----------------------------------------------------------------------------
495
+ Output format
496
+ -----------------------------------------------------------------------------
497
+
498
+ The output file (-o/--output, usually "direct.h5") contains the following
499
+ dataset:
500
+
501
+ /avg_state_probs [state]
502
+ (Structured -- see below) Population of each state across entire
503
+ range specified.
504
+
505
+ /avg_color_probs [state]
506
+ (Structured -- see below) Population of each ensemble across entire
507
+ range specified.
508
+
509
+ If --evolution-mode is specified, then the following additional datasets are
510
+ available:
511
+
512
+ /state_pop_evolution [window][state]
513
+ (Structured -- see below). State populations based on windows of
514
+ iterations of varying width. If --evolution-mode=cumulative, then
515
+ these windows all begin at the iteration specified with
516
+ --start-iter and grow in length by --step-iter for each successive
517
+ element. If --evolution-mode=blocked, then these windows are all of
518
+ width --step-iter (excluding the last, which may be shorter), the first
519
+ of which begins at iteration --start-iter.
520
+
521
+ /color_prob_evolution [window][state]
522
+ (Structured -- see below). Ensemble populations based on windows of
523
+ iterations of varying width. If --evolution-mode=cumulative, then
524
+ these windows all begin at the iteration specified with
525
+ --start-iter and grow in length by --step-iter for each successive
526
+ element. If --evolution-mode=blocked, then these windows are all of
527
+ width --step-iter (excluding the last, which may be shorter), the first
528
+ of which begins at iteration --start-iter.
529
+
530
+ The structure of these datasets is as follows:
531
+
532
+ iter_start
533
+ (Integer) Iteration at which the averaging window begins (inclusive).
534
+
535
+ iter_stop
536
+ (Integer) Iteration at which the averaging window ends (exclusive).
537
+
538
+ expected
539
+ (Floating-point) Expected (mean) value of the observable as evaluated within
540
+ this window, in units of inverse tau.
541
+
542
+ ci_lbound
543
+ (Floating-point) Lower bound of the confidence interval of the observable
544
+ within this window, in units of inverse tau.
545
+
546
+ ci_ubound
547
+ (Floating-point) Upper bound of the confidence interval of the observable
548
+ within this window, in units of inverse tau.
549
+
550
+ stderr
551
+ (Floating-point) The standard error of the mean of the observable
552
+ within this window, in units of inverse tau.
553
+
554
+ corr_len
555
+ (Integer) Correlation length of the observable within this window, in units
556
+ of tau.
557
+
558
+
559
+ Each of these datasets is also stamped with a number of attributes:
560
+
561
+ mcbs_alpha
562
+ (Floating-point) Alpha value of confidence intervals. (For example,
563
+ *alpha=0.05* corresponds to a 95% confidence interval.)
564
+
565
+ mcbs_nsets
566
+ (Integer) Number of bootstrap data sets used in generating confidence
567
+ intervals.
568
+
569
+ mcbs_acalpha
570
+ (Floating-point) Alpha value for determining correlation lengths.
571
+
572
+
573
+ -----------------------------------------------------------------------------
574
+ Command-line options
575
+ -----------------------------------------------------------------------------
576
+ '''
577
+
578
+ def w_postanalysis_stateprobs(self):
579
+ '''
580
+ This function ensures the data is ready to send in to the estimator and
581
+ the bootstrapping routine, then does so. Much of this is simply setting
582
+ up appropriate args and kwargs, then passing them in to the
583
+ 'run_calculation' function, which sets up future objects to send to the
584
+ work manager. The results are returned, and then written to the
585
+ appropriate HDF5 dataset.
586
+ This function is specific for the color (steady-state) and macrostate
587
+ probabilities from the reweighting method.
588
+ '''
589
+ self.generate_reweight_data()
590
+ pi = self.progress.indicator
591
+
592
+ start_iter, stop_iter, step_iter = self.iter_range.iter_start, self.iter_range.iter_stop, self.iter_range.iter_step
593
+ start_pts = list(range(start_iter, stop_iter, step_iter))
594
+ indices = np.array(list(range(start_iter - 1, stop_iter - 1, step_iter)), dtype=np.uint16)
595
+ submit_kwargs = dict(
596
+ pi=pi, nstates=self.nstates, start_iter=self.start_iter, stop_iter=self.stop_iter, step_iter=self.step_iter
597
+ )
598
+
599
+ # Due to the way our estimator is written, we're using the same dataset every time. We're just returning different values.
600
+ submit_kwargs['dataset'] = {'indices': indices}
601
+ submit_kwargs['estimator_kwargs'] = {}
602
+ submit_kwargs['estimator_kwargs'].update(
603
+ dict(
604
+ rows=self.rows,
605
+ cols=self.cols,
606
+ obs=self.obs,
607
+ flux=self.flux,
608
+ insert=self.insert,
609
+ bin_last_state_map=np.tile(np.arange(self.nstates, dtype=int), self.nbins),
610
+ bin_state_map=np.repeat(self.state_map[:-1], self.nstates),
611
+ nfbins=self.nfbins,
612
+ state_labels=self.state_labels,
613
+ return_obs='C', # Set to a default, but we explicitly set it later.
614
+ state_map=self.state_map,
615
+ nbins=self.nbins,
616
+ )
617
+ )
618
+
619
+ # Calculate averages for the simulation, then report, if necessary.
620
+
621
+ # The dataset options are what we pass on to the estimator...
622
+ submit_kwargs['estimator_kwargs']['return_obs'] = 'C'
623
+ avg_color_probs = self.run_calculation(
624
+ eval_block=_1D_eval_block, name='Average Color (Ensemble) Probability', dim=1, do_averages=True, **submit_kwargs
625
+ )
626
+ self.output_file.replace_dataset('avg_color_probs', data=avg_color_probs[1])
627
+
628
+ submit_kwargs['estimator_kwargs']['return_obs'] = 'S'
629
+ avg_state_probs = self.run_calculation(
630
+ eval_block=_1D_eval_block, name='Average State Probability', dim=1, do_averages=True, **submit_kwargs
631
+ )
632
+ self.output_file.replace_dataset('avg_state_probs', data=avg_state_probs[1])
633
+
634
+ # Now, print them!
635
+
636
+ # We've returned an average, but it still exists in a timeslice format. So we need to return the 'last' value.
637
+ if self.display_averages:
638
+ self.print_averages(avg_color_probs[1], '\naverage color probabilities:', dim=1)
639
+ self.print_averages(avg_state_probs[1], '\naverage state probabilities:', dim=1)
640
+
641
+ # Do a bootstrap evolution.
642
+
643
+ submit_kwargs['estimator_kwargs']['return_obs'] = 'C'
644
+ color_evol = self.run_calculation(
645
+ eval_block=_1D_eval_block, name='Color (Ensemble) Probability Evolution', dim=1, **submit_kwargs
646
+ )
647
+ self.output_file.replace_dataset('color_prob_evolution', data=color_evol, shuffle=True, compression=9)
648
+
649
+ submit_kwargs['estimator_kwargs']['return_obs'] = 'S'
650
+ state_evol = self.run_calculation(eval_block=_1D_eval_block, name='State Probability Evolution', dim=1, **submit_kwargs)
651
+ self.output_file.replace_dataset('state_pop_evolution', data=state_evol, shuffle=True, compression=9)
652
+
653
+ # Little different, here. Do a non-bootstrap evolution.
654
+ # Just use the work manager and the estimator without the bootstrap code, which is problematic for a dataset like this.
655
+ # We'll be adding this in later.
656
+ if False:
657
+ submit_kwargs['estimator_kwargs']['return_obs'] = 'P'
658
+ submit_kwargs['pi'] = None
659
+ futures = []
660
+ bin_pops = []
661
+ for iblock, start in enumerate(start_pts):
662
+ stop = min(start + step_iter, stop_iter)
663
+ # TODO: below line references uninitialized variable `do_averages`. Removed for now to satisfy
664
+ # flake8 since code never runs because of `if False`. Needs to be dealt with if this changes
665
+ # if self.evolution_mode == 'cumulative' or do_averages is True:
666
+ if self.evolution_mode == 'cumulative':
667
+ windowsize = int(self.evol_window_frac * (stop - start_iter))
668
+ block_start = max(start_iter, stop - windowsize)
669
+ else: # self.evolution_mode == 'blocked'
670
+ block_start = start
671
+ future_kwargs = dict(
672
+ iblock=iblock,
673
+ start=block_start,
674
+ stop=stop,
675
+ # nstates=self.nstates,
676
+ mcbs_alpha=self.mcbs_alpha,
677
+ mcbs_nsets=self.mcbs_nsets,
678
+ mcbs_acalpha=self.mcbs_acalpha,
679
+ do_correl=self.do_correl,
680
+ name='Bin Population Evolution',
681
+ mcbs_enable=self.mcbs_enable,
682
+ data_input={},
683
+ **submit_kwargs
684
+ )
685
+ # print(future_kwargs)
686
+ futures.append(generate_future(self.work_manager, 'Bin Pop Evolution', _pop_eval_block, future_kwargs))
687
+ # bin_evol = self.run_calculation(eval_block=_pop_eval_block, name='Bin Population Evolution', dim=1, **submit_kwargs)
688
+ # bin_evol = bin_evol.reshape(-1, 2)
689
+ for future in self.work_manager.as_completed(futures):
690
+ # pi.progress += iblock / step_iter
691
+ bin_pops.append(future.get_result(discard=True))
692
+ hist = self.output_file.replace_dataset('histograms', data=bin_pops, shuffle=True, compression=9)
693
+ hist.attrs['iter_start'] = start_iter
694
+ hist.attrs['iter_stop'] = stop_iter
695
+ import ast
696
+
697
+ binbounds = []
698
+ midpoints = []
699
+ for i in self.assignments_file['bin_labels']:
700
+ binbounds.append(ast.literal_eval(i)[0][0])
701
+ # This is probably crap, so...
702
+ binbounds.append(ast.literal_eval(self.assignments_file['bin_labels'][-1])[0][1])
703
+ # binbounds.append(binbounds[-1]+1)
704
+ for i in range(1, len(binbounds)):
705
+ midpoints.append(((binbounds[i] - binbounds[i - 1]) / 2) + binbounds[i - 1])
706
+ self.output_file.replace_dataset('binbounds_0', data=binbounds, shuffle=True, compression=9)
707
+ self.output_file.replace_dataset('midpoints_0', data=midpoints, shuffle=True, compression=9)
708
+ self.output_file.replace_dataset('n_iter', data=list(range(start_iter, stop_iter)), shuffle=True, compression=9)
709
+
710
+ def go(self):
711
+ pi = self.progress.indicator
712
+ with pi:
713
+ self.w_postanalysis_stateprobs()
714
+
715
+
716
+ class RWAll(RWMatrix, RWStateProbs, RWRate):
717
+ subcommand = 'all'
718
+ help_text = 'Runs the full suite, including the generation of the flux matrices.'
719
+ default_kinetics_file = 'reweight.h5'
720
+ default_output_file = 'reweight.h5'
721
+ description = '''\
722
+ A convenience function to run init/kinetics/probs. Bin assignments,
723
+ including macrostate definitions, are required. (See
724
+ "w_assign --help" for more information).
725
+
726
+ For more information on the individual subcommands this subs in for, run
727
+ w_reweight {init/kinetics/probs} --help.
728
+
729
+ -----------------------------------------------------------------------------
730
+ Command-line options
731
+ -----------------------------------------------------------------------------
732
+ '''
733
+
734
+ def go(self):
735
+ pi = self.progress.indicator
736
+ with pi:
737
+ self.w_postanalysis_matrix()
738
+ self.w_postanalysis_reweight()
739
+ self.w_postanalysis_stateprobs()
740
+
741
+
742
+ # Just a convenience class to average the observables.
743
+ class RWAverage(RWStateProbs, RWRate):
744
+ subcommand = 'average'
745
+ help_text = 'Averages and returns fluxes, rates, and color/state populations.'
746
+ default_kinetics_file = 'reweight.h5'
747
+ default_output_file = 'reweight.h5'
748
+ description = '''\
749
+ A convenience function to run kinetics/probs. Bin assignments,
750
+ including macrostate definitions, are required. (See
751
+ "w_assign --help" for more information).
752
+
753
+ For more information on the individual subcommands this subs in for, run
754
+ w_reweight {kinetics/probs} --help.
755
+
756
+ -----------------------------------------------------------------------------
757
+ Command-line options
758
+ -----------------------------------------------------------------------------
759
+ '''
760
+
761
+ def go(self):
762
+ pi = self.progress.indicator
763
+ with pi:
764
+ self.w_postanalysis_reweight()
765
+ self.w_postanalysis_stateprobs()
766
+
767
+
768
+ class WReweight(WESTMasterCommand, WESTParallelTool):
769
+ prog = 'w_reweight'
770
+ subcommands = [RWMatrix, RWAverage, RWRate, RWStateProbs, RWAll]
771
+ subparsers_title = 'reweighting kinetics analysis scheme'
772
+
773
+
774
+ def entry_point():
775
+ warnings.warn('{} is being deprecated. Please use WESS, WEED or the haMSM plugin instead.'.format(WReweight.prog))
776
+ WReweight().main()
777
+
778
+
779
+ if __name__ == '__main__':
780
+ entry_point()