westpa 2022.13__cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.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.
- westpa/__init__.py +14 -0
- westpa/_version.py +21 -0
- westpa/analysis/__init__.py +5 -0
- westpa/analysis/core.py +749 -0
- westpa/analysis/statistics.py +27 -0
- westpa/analysis/trajectories.py +369 -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 +597 -0
- westpa/cli/tools/w_bins.py +166 -0
- westpa/cli/tools/w_crawl.py +119 -0
- westpa/cli/tools/w_direct.py +557 -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 +832 -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_timings.py +113 -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.c +36018 -0
- westpa/core/binning/_assign.cpython-312-aarch64-linux-gnu.so +0 -0
- westpa/core/binning/_assign.pyx +370 -0
- westpa/core/binning/assign.py +454 -0
- westpa/core/binning/binless.py +96 -0
- westpa/core/binning/binless_driver.py +54 -0
- westpa/core/binning/binless_manager.py +189 -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 +197 -0
- westpa/core/data_manager.py +1761 -0
- westpa/core/extloader.py +74 -0
- westpa/core/h5io.py +1079 -0
- westpa/core/kinetics/__init__.py +24 -0
- westpa/core/kinetics/_kinetics.c +45174 -0
- westpa/core/kinetics/_kinetics.cpython-312-aarch64-linux-gnu.so +0 -0
- westpa/core/kinetics/_kinetics.pyx +815 -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 +592 -0
- westpa/core/propagators/loaders.py +196 -0
- westpa/core/reweight/__init__.py +14 -0
- westpa/core/reweight/_reweight.c +36899 -0
- westpa/core/reweight/_reweight.cpython-312-aarch64-linux-gnu.so +0 -0
- westpa/core/reweight/_reweight.pyx +439 -0
- westpa/core/reweight/matrix.py +126 -0
- westpa/core/segment.py +119 -0
- westpa/core/sim_manager.py +839 -0
- westpa/core/states.py +359 -0
- westpa/core/systems.py +93 -0
- westpa/core/textio.py +74 -0
- westpa/core/trajectory.py +603 -0
- westpa/core/we_driver.py +910 -0
- westpa/core/wm_ops.py +43 -0
- westpa/core/yamlcfg.py +298 -0
- westpa/fasthist/__init__.py +34 -0
- westpa/fasthist/_fasthist.c +38755 -0
- westpa/fasthist/_fasthist.cpython-312-aarch64-linux-gnu.so +0 -0
- westpa/fasthist/_fasthist.pyx +222 -0
- westpa/mclib/__init__.py +271 -0
- westpa/mclib/__main__.py +28 -0
- westpa/mclib/_mclib.c +34610 -0
- westpa/mclib/_mclib.cpython-312-aarch64-linux-gnu.so +0 -0
- westpa/mclib/_mclib.pyx +226 -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 +88 -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 +343 -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.c +17829 -0
- westpa/trajtree/_trajtree.cpython-312-aarch64-linux-gnu.so +0 -0
- westpa/trajtree/_trajtree.pyx +130 -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 +201 -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 +635 -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.13.dist-info/METADATA +179 -0
- westpa-2022.13.dist-info/RECORD +162 -0
- westpa-2022.13.dist-info/WHEEL +7 -0
- westpa-2022.13.dist-info/entry_points.txt +30 -0
- westpa-2022.13.dist-info/licenses/LICENSE +21 -0
- westpa-2022.13.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
import h5py
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
from westpa.tools import WESTMasterCommand, WESTSubcommand, ProgressIndicatorComponent, Plotter
|
|
9
|
+
from westpa.core import h5io
|
|
10
|
+
|
|
11
|
+
if os.environ.get('DISPLAY') is not None:
|
|
12
|
+
from matplotlib import pyplot
|
|
13
|
+
|
|
14
|
+
log = logging.getLogger('ploterrs')
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class CommonPloterrs(WESTSubcommand):
|
|
18
|
+
def __init__(self, parent):
|
|
19
|
+
super().__init__(parent)
|
|
20
|
+
|
|
21
|
+
self.progress = ProgressIndicatorComponent()
|
|
22
|
+
|
|
23
|
+
self.xscale = None
|
|
24
|
+
self.yscale = None
|
|
25
|
+
self.xrange = None
|
|
26
|
+
self.yrange = None
|
|
27
|
+
self.xlabel = None
|
|
28
|
+
self.ylabel = None
|
|
29
|
+
self.title = None
|
|
30
|
+
|
|
31
|
+
self.plot_options_group = None
|
|
32
|
+
|
|
33
|
+
def add_args(self, parser):
|
|
34
|
+
self.progress.add_args(parser)
|
|
35
|
+
|
|
36
|
+
pogroup = self.plot_options_group = parser.add_argument_group('plot options')
|
|
37
|
+
pogroup.add_argument(
|
|
38
|
+
'--xscale',
|
|
39
|
+
choices=['linear', 'log', 'symlog'],
|
|
40
|
+
default='linear',
|
|
41
|
+
help='''Use "linear", "log", or "symlog" scaling for the x axis.
|
|
42
|
+
(Default: %(default)s).''',
|
|
43
|
+
)
|
|
44
|
+
pogroup.add_argument(
|
|
45
|
+
'--yscale',
|
|
46
|
+
choices=['linear', 'log', 'symlog'],
|
|
47
|
+
default='linear',
|
|
48
|
+
help='''Use "linear", "log", or "symlog" scaling for the y axis.
|
|
49
|
+
(Default: %(default)s).''',
|
|
50
|
+
)
|
|
51
|
+
pogroup.add_argument(
|
|
52
|
+
'--xrange',
|
|
53
|
+
help='''Restrict X range to XRANGE, which must be formatted as "xmin,xmax".
|
|
54
|
+
(Default: determined by input data.)''',
|
|
55
|
+
)
|
|
56
|
+
pogroup.add_argument(
|
|
57
|
+
'--yrange',
|
|
58
|
+
help='''Restrict Y range to YRANGE, which must be formatted as "ymin,ymax".
|
|
59
|
+
(Default: determined by input data.)''',
|
|
60
|
+
)
|
|
61
|
+
pogroup.add_argument('--xlabel', help='''Use XLABEL for the x-axis label. (Default: varies.)''')
|
|
62
|
+
pogroup.add_argument('--ylabel', help='''Use YLABEL for the y-axis label. (Default: varies.)''')
|
|
63
|
+
pogroup.add_argument('--title', help='''Use TITLE for the plot title. (Default: varies.)''')
|
|
64
|
+
pogroup.add_argument('--terminal', '-t', dest='plotting', action='store_true', help='''Plot output in terminal.''')
|
|
65
|
+
|
|
66
|
+
def process_args(self, args):
|
|
67
|
+
self.progress.process_args(args)
|
|
68
|
+
|
|
69
|
+
if args.xrange:
|
|
70
|
+
self.xrange = self.parse_range(args.xrange)
|
|
71
|
+
|
|
72
|
+
if args.yrange:
|
|
73
|
+
self.yrange = self.parse_range(args.yrange)
|
|
74
|
+
|
|
75
|
+
self.xscale = args.xscale
|
|
76
|
+
self.yscale = args.yscale
|
|
77
|
+
self.xlabel = args.xlabel or 'Iteration'
|
|
78
|
+
self.ylabel = args.ylabel
|
|
79
|
+
self.title = args.title
|
|
80
|
+
if args.plotting or os.environ.get('DISPLAY') is None:
|
|
81
|
+
self.interface = 'text'
|
|
82
|
+
else:
|
|
83
|
+
self.interface = 'matplotlib'
|
|
84
|
+
|
|
85
|
+
def parse_range(self, rangespec):
|
|
86
|
+
try:
|
|
87
|
+
(lbt, ubt) = rangespec.split(',')
|
|
88
|
+
return float(lbt), float(ubt)
|
|
89
|
+
except (ValueError, TypeError) as e:
|
|
90
|
+
raise ValueError('invalid range specification {!r}: {!s}'.format(rangespec, e))
|
|
91
|
+
|
|
92
|
+
def do_plot(self, data, output_filename, title=None, x_range=None, y_range=None, x_label=None, y_label=None):
|
|
93
|
+
if not output_filename:
|
|
94
|
+
return
|
|
95
|
+
|
|
96
|
+
title = title or self.title
|
|
97
|
+
x_range = x_range or self.xrange
|
|
98
|
+
y_range = y_range or self.yrange
|
|
99
|
+
x_label = x_label or self.xlabel
|
|
100
|
+
y_label = y_label or self.ylabel
|
|
101
|
+
|
|
102
|
+
iters = data['iter_stop'] - 1
|
|
103
|
+
|
|
104
|
+
pyplot.figure()
|
|
105
|
+
pyplot.plot(iters, data['expected'], color='black')
|
|
106
|
+
pyplot.plot(iters, data['ci_lbound'], color='gray')
|
|
107
|
+
pyplot.plot(iters, data['ci_ubound'], color='gray')
|
|
108
|
+
|
|
109
|
+
pyplot.gca().set_xscale(self.xscale)
|
|
110
|
+
pyplot.gca().set_yscale(self.yscale)
|
|
111
|
+
|
|
112
|
+
if title:
|
|
113
|
+
pyplot.title(title)
|
|
114
|
+
|
|
115
|
+
if x_range is not None:
|
|
116
|
+
pyplot.xlim(x_range)
|
|
117
|
+
|
|
118
|
+
if y_range is not None:
|
|
119
|
+
pyplot.ylim(y_range)
|
|
120
|
+
|
|
121
|
+
if x_label:
|
|
122
|
+
pyplot.xlabel(x_label)
|
|
123
|
+
|
|
124
|
+
if y_label:
|
|
125
|
+
pyplot.ylabel(y_label)
|
|
126
|
+
|
|
127
|
+
pyplot.savefig(output_filename)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class GenericIntervalSubcommand(CommonPloterrs):
|
|
131
|
+
description = '''\
|
|
132
|
+
Plots generic expectation/CI data. A path to the HDF5 file and the dataset
|
|
133
|
+
within it must be provided. This path takes the form **FILENAME/PATH[SLICE]**.
|
|
134
|
+
If the dataset is not a vector (one dimensional) then a slice must be provided.
|
|
135
|
+
For example, to access the state 0 to state 1 rate evolution calculated by
|
|
136
|
+
``w_kinavg``, one would use ``kinavg.h5/rate_evolution[:,0,1]``.
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
-----------------------------------------------------------------------------
|
|
140
|
+
Command-line arguments
|
|
141
|
+
-----------------------------------------------------------------------------
|
|
142
|
+
'''
|
|
143
|
+
subcommand = 'generic'
|
|
144
|
+
help_text = 'arbitrary HDF5 file and dataset'
|
|
145
|
+
|
|
146
|
+
def __init__(self, parent):
|
|
147
|
+
super().__init__(parent)
|
|
148
|
+
self.h5file = None
|
|
149
|
+
self.h5dset = None
|
|
150
|
+
self.dset_slice = None
|
|
151
|
+
self.output_filename = None
|
|
152
|
+
|
|
153
|
+
def add_args(self, parser):
|
|
154
|
+
iogroup = parser.add_argument_group('input/output options')
|
|
155
|
+
iogroup.add_argument(
|
|
156
|
+
'-o',
|
|
157
|
+
'--output',
|
|
158
|
+
default='errbars.pdf',
|
|
159
|
+
help='''Write plot to OUTPUT (default: %(default)s), whose format will
|
|
160
|
+
be determined by filename extension.''',
|
|
161
|
+
)
|
|
162
|
+
iogroup.add_argument(
|
|
163
|
+
'dsspec',
|
|
164
|
+
help='''Use data located at DSSPEC, which must be formatted as
|
|
165
|
+
FILENAME/PATH[SLICE]. FILENAME is the HDF5 file to read, PATH is the
|
|
166
|
+
HDF5 path to the dataset, and SLICE, if provided, must be the Numpy-style
|
|
167
|
+
slice (including brackets) which selects a vector of data of the
|
|
168
|
+
appropriate type.''',
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
def process_args(self, args):
|
|
172
|
+
self.output_filename = args.output
|
|
173
|
+
(pathname, slicestr) = re.search(r'([^[]+)(\[[^\]]+\])?$', args.dsspec).groups()
|
|
174
|
+
if slicestr:
|
|
175
|
+
sl = eval('np.index_exp' + slicestr)
|
|
176
|
+
else:
|
|
177
|
+
sl = np.index_exp[...]
|
|
178
|
+
self.h5file, self.h5dset = h5io.resolve_filepath(pathname, mode='r')
|
|
179
|
+
self.dset_slice = sl
|
|
180
|
+
|
|
181
|
+
def load_and_validate_data(self):
|
|
182
|
+
reqd_fields = set(['iter_start', 'iter_stop', 'expected', 'ci_lbound', 'ci_ubound'])
|
|
183
|
+
|
|
184
|
+
self.progress.indicator.new_operation('loading data')
|
|
185
|
+
data = self.h5dset[self.dset_slice]
|
|
186
|
+
|
|
187
|
+
if data.ndim != 1:
|
|
188
|
+
raise TypeError('dataset to be plotted must be 1-dimensional')
|
|
189
|
+
try:
|
|
190
|
+
fieldnames = set(data.dtype.fields.keys())
|
|
191
|
+
except AttributeError:
|
|
192
|
+
raise TypeError('dataset has inappropriate type')
|
|
193
|
+
else:
|
|
194
|
+
if len(fieldnames & reqd_fields) < len(reqd_fields):
|
|
195
|
+
raise TypeError('dataset does not contain correct fields')
|
|
196
|
+
|
|
197
|
+
return data
|
|
198
|
+
|
|
199
|
+
def go(self):
|
|
200
|
+
with self.progress.indicator:
|
|
201
|
+
data = self.load_and_validate_data()
|
|
202
|
+
self.progress.indicator.new_operation('plotting')
|
|
203
|
+
self.do_plot(data, self.output_filename)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
class DirectKinetics(CommonPloterrs):
|
|
207
|
+
subcommand = 'd.kinetics'
|
|
208
|
+
help_text = 'output of w_direct kinetics'
|
|
209
|
+
input_filename = 'direct.h5'
|
|
210
|
+
flux_output_filename = 'flux_evolution_d_{state_label}.pdf'
|
|
211
|
+
rate_output_filename = 'rate_evolution_d_{istate_label}_{fstate_label}.pdf'
|
|
212
|
+
description = '''\
|
|
213
|
+
Plot evolution of state-to-state rates and total flux into states as generated
|
|
214
|
+
by ``w_{direct/reweight} kinetics`` (when used with the ``--evolution-mode``
|
|
215
|
+
option). Plots are generated for all rates/fluxes calculated. Output filenames
|
|
216
|
+
require (and plot titles and axis labels support) substitution based on which
|
|
217
|
+
flux/rate is being plotted:
|
|
218
|
+
|
|
219
|
+
istate_label, fstate_label
|
|
220
|
+
*(String, for rates)* Names of the initial and final states, as originally
|
|
221
|
+
given to ``w_assign``.
|
|
222
|
+
|
|
223
|
+
istate_index, fstate_index
|
|
224
|
+
*(Integer, for rates)* Indices of initial and final states.
|
|
225
|
+
|
|
226
|
+
state_label
|
|
227
|
+
*(String, for fluxes)* Name of state
|
|
228
|
+
|
|
229
|
+
state_index
|
|
230
|
+
*(Integer, for fluxes)* Index of state
|
|
231
|
+
'''
|
|
232
|
+
|
|
233
|
+
def __init__(self, parent):
|
|
234
|
+
super().__init__(parent)
|
|
235
|
+
self.kinavg_file = None
|
|
236
|
+
|
|
237
|
+
self.dset_slice = None
|
|
238
|
+
self.rate_output_pattern = None
|
|
239
|
+
self.flux_output_pattern = None
|
|
240
|
+
|
|
241
|
+
self.state_labels = None
|
|
242
|
+
|
|
243
|
+
def add_args(self, parser):
|
|
244
|
+
iogroup = parser.add_argument_group('input/output')
|
|
245
|
+
iogroup.add_argument(
|
|
246
|
+
'-i', '--input', default=self.input_filename, help='''Read kinetics results from INPUT (default: %(default)s).'''
|
|
247
|
+
)
|
|
248
|
+
iogroup.add_argument(
|
|
249
|
+
'--rate-output',
|
|
250
|
+
default=self.rate_output_filename,
|
|
251
|
+
help='''Filename pattern for rate evolution output. See above for valid
|
|
252
|
+
field names. (Default: %(default)r).''',
|
|
253
|
+
)
|
|
254
|
+
iogroup.add_argument(
|
|
255
|
+
'--flux-output',
|
|
256
|
+
default=self.flux_output_filename,
|
|
257
|
+
help='''Filename pattern for flux evolution output. See above for valid
|
|
258
|
+
field names. (Default: %(default)r).''',
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
def process_args(self, args):
|
|
262
|
+
self.kinavg_file = h5py.File(args.input, 'r')
|
|
263
|
+
|
|
264
|
+
self.state_labels = list(self.kinavg_file['state_labels'][...])
|
|
265
|
+
|
|
266
|
+
self.rate_output_pattern = args.rate_output
|
|
267
|
+
self.flux_output_pattern = args.flux_output
|
|
268
|
+
|
|
269
|
+
def plot_flux(self, istate):
|
|
270
|
+
label = self.state_labels[istate]
|
|
271
|
+
data = self.kinavg_file['target_flux_evolution'][:, istate]
|
|
272
|
+
|
|
273
|
+
if (data['iter_start'] == 0).all():
|
|
274
|
+
# No data
|
|
275
|
+
return
|
|
276
|
+
|
|
277
|
+
subdict = dict(state_label=label, state_index=istate)
|
|
278
|
+
|
|
279
|
+
output_filename = self.flux_output_pattern.format(**subdict) if self.flux_output_pattern else None
|
|
280
|
+
|
|
281
|
+
title = self.title if self.title is not None else 'Flux into state "{state_label}"'
|
|
282
|
+
title = title.format(**subdict)
|
|
283
|
+
|
|
284
|
+
x_label = self.xlabel.format(**subdict) if self.xlabel else None
|
|
285
|
+
|
|
286
|
+
y_label = self.ylabel if self.ylabel is not None else r'Flux $(\tau^{{-1}})$'
|
|
287
|
+
y_label = y_label.format(**subdict)
|
|
288
|
+
|
|
289
|
+
self.do_plot(data, output_filename, title, x_label=x_label, y_label=y_label)
|
|
290
|
+
|
|
291
|
+
def plot_rate(self, istate, jstate):
|
|
292
|
+
ilabel = self.state_labels[istate]
|
|
293
|
+
jlabel = self.state_labels[jstate]
|
|
294
|
+
data = self.kinavg_file['rate_evolution'][:, istate, jstate]
|
|
295
|
+
|
|
296
|
+
if (data['iter_start'] == 0).all():
|
|
297
|
+
# No data
|
|
298
|
+
return
|
|
299
|
+
|
|
300
|
+
subdict = dict(istate_label=ilabel, istate_index=istate, fstate_label=jlabel, fstate_index=jstate)
|
|
301
|
+
|
|
302
|
+
output_filename = self.rate_output_pattern.format(**subdict) if self.rate_output_pattern else None
|
|
303
|
+
|
|
304
|
+
title = self.title if self.title is not None else 'Rate from state "{istate_label}" to state "{fstate_label}"'
|
|
305
|
+
title = title.format(**subdict)
|
|
306
|
+
|
|
307
|
+
x_label = self.xlabel.format(**subdict) if self.xlabel else None
|
|
308
|
+
|
|
309
|
+
y_label = self.ylabel if self.ylabel is not None else r'Rate $(\tau^{{-1}})$'
|
|
310
|
+
y_label = y_label.format(**subdict)
|
|
311
|
+
|
|
312
|
+
self.do_plot(data, output_filename, title, x_label=x_label, y_label=y_label)
|
|
313
|
+
|
|
314
|
+
def go(self):
|
|
315
|
+
pi = self.progress.indicator
|
|
316
|
+
nstates = len(self.state_labels)
|
|
317
|
+
if self.interface == 'matplotlib':
|
|
318
|
+
with pi:
|
|
319
|
+
# if --evolution-mode wasn't specified, neither of these exist:
|
|
320
|
+
if 'target_flux_evolution' in self.kinavg_file:
|
|
321
|
+
pi.new_operation('plotting fluxes', nstates)
|
|
322
|
+
for istate in range(nstates):
|
|
323
|
+
self.plot_flux(istate)
|
|
324
|
+
pi.progress += 1
|
|
325
|
+
|
|
326
|
+
# if --evolution-mode wasn't specified, we won't get this either
|
|
327
|
+
if 'rate_evolution' in self.kinavg_file:
|
|
328
|
+
pi.new_operation('plotting rates', nstates * nstates)
|
|
329
|
+
for istate in range(nstates):
|
|
330
|
+
for jstate in range(nstates):
|
|
331
|
+
self.plot_rate(istate, jstate)
|
|
332
|
+
pi.progress += 1
|
|
333
|
+
else:
|
|
334
|
+
print('rate evolution not available')
|
|
335
|
+
else:
|
|
336
|
+
plotter = Plotter(self.kinavg_file, 'rate_evolution', iteration=-1, interface='text')
|
|
337
|
+
for istate in range(nstates):
|
|
338
|
+
for jstate in range(nstates):
|
|
339
|
+
if istate != jstate:
|
|
340
|
+
plotter.plot(istate, jstate)
|
|
341
|
+
plotter = Plotter(self.kinavg_file, 'conditional_flux_evolution', iteration=-1, interface='text')
|
|
342
|
+
for istate in range(nstates):
|
|
343
|
+
for jstate in range(nstates):
|
|
344
|
+
if istate != jstate:
|
|
345
|
+
plotter.plot(istate, jstate)
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
class DirectStateprobs(CommonPloterrs):
|
|
349
|
+
subcommand = 'd.probs'
|
|
350
|
+
help_text = 'output of w_direct probs'
|
|
351
|
+
input_filename = 'direct.h5'
|
|
352
|
+
pop_output_filename = 'pop_evolution_d_{state_label}.pdf'
|
|
353
|
+
color_output_filename = 'color_evolution_d_{state_label}.pdf'
|
|
354
|
+
description = '''\
|
|
355
|
+
Plot evolution of macrostate populations and associated uncertainties. Plots
|
|
356
|
+
are generated for all states calculated. Output filenames require (and plot
|
|
357
|
+
titles and axis labels support) substitution based on which state is being
|
|
358
|
+
plotted:
|
|
359
|
+
|
|
360
|
+
state_label
|
|
361
|
+
*(String, for fluxes)* Name of state
|
|
362
|
+
|
|
363
|
+
state_index
|
|
364
|
+
*(Integer, for fluxes)* Index of state
|
|
365
|
+
'''
|
|
366
|
+
|
|
367
|
+
def __init__(self, parent):
|
|
368
|
+
super().__init__(parent)
|
|
369
|
+
self.stateprobs_file = None
|
|
370
|
+
|
|
371
|
+
self.dset_slice = None
|
|
372
|
+
self.rate_output_pattern = None
|
|
373
|
+
self.flux_output_pattern = None
|
|
374
|
+
|
|
375
|
+
self.state_labels = None
|
|
376
|
+
|
|
377
|
+
def add_args(self, parser):
|
|
378
|
+
iogroup = parser.add_argument_group('input/output')
|
|
379
|
+
iogroup.add_argument(
|
|
380
|
+
'-i', '--input', default=self.input_filename, help='''Read w_kinavg results from INPUT (default: %(default)s).'''
|
|
381
|
+
)
|
|
382
|
+
iogroup.add_argument(
|
|
383
|
+
'--population-output',
|
|
384
|
+
default=self.pop_output_filename,
|
|
385
|
+
help='''Filename pattern for population evolution output. See above for valid
|
|
386
|
+
field names. (Default: %(default)r).''',
|
|
387
|
+
)
|
|
388
|
+
iogroup.add_argument(
|
|
389
|
+
'--color-output',
|
|
390
|
+
default=self.color_output_filename,
|
|
391
|
+
help='''Filename pattern for ensemble evolution output. See above for valid
|
|
392
|
+
field names. (Default: %(default)r).''',
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
def process_args(self, args):
|
|
396
|
+
self.stateprobs_file = h5py.File(args.input, 'r')
|
|
397
|
+
|
|
398
|
+
self.state_labels = list(self.stateprobs_file['state_labels'][...])
|
|
399
|
+
self.pop_output_pattern = args.population_output
|
|
400
|
+
self.color_output_pattern = args.color_output
|
|
401
|
+
|
|
402
|
+
def plot_pop(self, istate):
|
|
403
|
+
label = self.state_labels[istate]
|
|
404
|
+
data = self.stateprobs_file['state_pop_evolution'][:, istate]
|
|
405
|
+
|
|
406
|
+
if (data['iter_start'] == 0).all():
|
|
407
|
+
# No data
|
|
408
|
+
return
|
|
409
|
+
|
|
410
|
+
subdict = dict(state_label=label, state_index=istate)
|
|
411
|
+
|
|
412
|
+
output_filename = self.pop_output_pattern.format(**subdict) if self.pop_output_pattern else None
|
|
413
|
+
|
|
414
|
+
title = self.title if self.title is not None else 'Population in state "{state_label}"'
|
|
415
|
+
title = title.format(**subdict)
|
|
416
|
+
|
|
417
|
+
x_label = self.xlabel.format(**subdict) if self.xlabel else None
|
|
418
|
+
y_label = self.ylabel if self.ylabel is not None else r'Population'
|
|
419
|
+
y_label = y_label.format(**subdict)
|
|
420
|
+
|
|
421
|
+
self.do_plot(data, output_filename, title, x_label=x_label, y_label=y_label)
|
|
422
|
+
|
|
423
|
+
def plot_color(self, istate):
|
|
424
|
+
label = self.state_labels[istate]
|
|
425
|
+
data = self.stateprobs_file['color_prob_evolution'][:, istate]
|
|
426
|
+
|
|
427
|
+
if (data['iter_start'] == 0).all():
|
|
428
|
+
# No data
|
|
429
|
+
return
|
|
430
|
+
|
|
431
|
+
subdict = dict(state_label=label, state_index=istate)
|
|
432
|
+
|
|
433
|
+
output_filename = self.color_output_pattern.format(**subdict) if self.color_output_pattern else None
|
|
434
|
+
|
|
435
|
+
title = self.title if self.title is not None else 'Population in ensemble "{state_label}"'
|
|
436
|
+
title = title.format(**subdict)
|
|
437
|
+
|
|
438
|
+
x_label = self.xlabel.format(**subdict) if self.xlabel else None
|
|
439
|
+
y_label = self.ylabel if self.ylabel is not None else r'Population'
|
|
440
|
+
y_label = y_label.format(**subdict)
|
|
441
|
+
|
|
442
|
+
self.do_plot(data, output_filename, title, x_label=x_label, y_label=y_label)
|
|
443
|
+
|
|
444
|
+
def go(self):
|
|
445
|
+
pi = self.progress.indicator
|
|
446
|
+
nstates = len(self.state_labels)
|
|
447
|
+
if self.interface == 'matplotlib':
|
|
448
|
+
with pi:
|
|
449
|
+
if 'state_pop_evolution' in self.stateprobs_file:
|
|
450
|
+
pi.new_operation('plotting populations', nstates)
|
|
451
|
+
for istate in range(nstates):
|
|
452
|
+
self.plot_pop(istate)
|
|
453
|
+
pi.progress += 1
|
|
454
|
+
|
|
455
|
+
if 'color_prob_evolution' in self.stateprobs_file:
|
|
456
|
+
pi.new_operation('plotting ensemble populations', nstates)
|
|
457
|
+
for istate in range(nstates):
|
|
458
|
+
self.plot_color(istate)
|
|
459
|
+
pi.progress += 1
|
|
460
|
+
else:
|
|
461
|
+
print('population evolution not available')
|
|
462
|
+
else:
|
|
463
|
+
plotter = Plotter(self.stateprobs_file, 'state_pop_evolution', iteration=-1, interface='text')
|
|
464
|
+
for istate in range(nstates):
|
|
465
|
+
plotter.plot(istate)
|
|
466
|
+
plotter = Plotter(self.stateprobs_file, 'color_prob_evolution', iteration=-1, interface='text')
|
|
467
|
+
for istate in range(nstates):
|
|
468
|
+
plotter.plot(istate)
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
class ReweightStateprobs(DirectStateprobs):
|
|
472
|
+
subcommand = 'rw.probs'
|
|
473
|
+
help_text = 'output of w_reweight probs'
|
|
474
|
+
input_filename = 'reweight.h5'
|
|
475
|
+
pop_output_filename = 'pop_evolution_rw_{state_label}.pdf'
|
|
476
|
+
color_output_filename = 'color_evolution_rw_{state_label}.pdf'
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
class ReweightKinetics(DirectKinetics):
|
|
480
|
+
subcommand = 'rw.kinetics'
|
|
481
|
+
help_text = 'output of w_reweight kinetics'
|
|
482
|
+
input_filename = 'reweight.h5'
|
|
483
|
+
flux_output_filename = 'flux_evolution_rw_{state_label}.pdf'
|
|
484
|
+
rate_output_filename = 'rate_evolution_rw_{istate_label}_{fstate_label}.pdf'
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
class PloterrsTool(WESTMasterCommand):
|
|
488
|
+
prog = 'ploterrs'
|
|
489
|
+
subcommands = [DirectKinetics, DirectStateprobs, ReweightStateprobs, ReweightKinetics, GenericIntervalSubcommand]
|
|
490
|
+
subparsers_title = 'supported input formats'
|
|
491
|
+
description = '''\
|
|
492
|
+
Plots error ranges for weighted ensemble datasets.
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
-----------------------------------------------------------------------------
|
|
496
|
+
Command-line options
|
|
497
|
+
-----------------------------------------------------------------------------
|
|
498
|
+
'''
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
def entry_point():
|
|
502
|
+
PloterrsTool().main()
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
if __name__ == '__main__':
|
|
506
|
+
entry_point()
|