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
westpa/tools/core.py ADDED
@@ -0,0 +1,340 @@
1
+ '''Core classes for creating WESTPA command-line tools'''
2
+
3
+ import argparse
4
+ import logging
5
+ import sys
6
+ import os
7
+
8
+ import westpa
9
+ from westpa import work_managers
10
+ from westpa.core import h5io
11
+
12
+
13
+ log = logging.getLogger(__name__)
14
+
15
+
16
+ class WESTToolComponent:
17
+ '''Base class for WEST command line tools and components used in constructing tools'''
18
+
19
+ def __init__(self):
20
+ self.config_required = False
21
+ self.include_args = {}
22
+ self.arg_defaults = {}
23
+ self.parser = None
24
+ self.args = None
25
+
26
+ def include_arg(self, argname):
27
+ self.include_args[argname] = True
28
+
29
+ def exclude_arg(self, argname):
30
+ self.include_args[argname] = False
31
+
32
+ def set_arg_default(self, argname, value):
33
+ self.arg_defaults[argname] = value
34
+
35
+ def add_args(self, parser):
36
+ '''Add arguments specific to this component to the given argparse parser.'''
37
+ pass
38
+
39
+ def process_args(self, args):
40
+ '''Take argparse-processed arguments associated with this component and deal
41
+ with them appropriately (setting instance variables, etc)'''
42
+ pass
43
+
44
+ def add_all_args(self, parser):
45
+ '''Add arguments for all components from which this class derives to the given parser,
46
+ starting with the class highest up the inheritance chain (most distant ancestor).'''
47
+ self.parser = parser
48
+ for cls in reversed(self.__class__.__mro__):
49
+ try:
50
+ fn = cls.__dict__['add_args']
51
+ except KeyError:
52
+ pass
53
+ else:
54
+ fn(self, parser)
55
+
56
+ def process_all_args(self, args):
57
+ self.args = args
58
+ '''Process arguments for all components from which this class derives,
59
+ starting with the class highest up the inheritance chain (most distant ancestor).'''
60
+ for cls in reversed(self.__class__.__mro__):
61
+ try:
62
+ fn = cls.__dict__['process_args']
63
+ except KeyError:
64
+ pass
65
+ else:
66
+ fn(self, args)
67
+
68
+
69
+ class WESTTool(WESTToolComponent):
70
+ '''Base class for WEST command line tools'''
71
+
72
+ prog = None
73
+ usage = None
74
+ description = None
75
+ epilog = None
76
+
77
+ def __init__(self):
78
+ super().__init__()
79
+
80
+ def add_args(self, parser):
81
+ '''Add arguments specific to this tool to the given argparse parser.'''
82
+ westpa.rc.add_args(parser)
83
+
84
+ def process_args(self, args):
85
+ '''Take argparse-processed arguments associated with this tool and deal
86
+ with them appropriately (setting instance variables, etc)'''
87
+ westpa.rc.process_args(args, config_required=self.config_required)
88
+
89
+ def make_parser(self, prog=None, usage=None, description=None, epilog=None, args=None):
90
+ prog = prog or self.prog
91
+ usage = usage or self.usage
92
+ description = description or self.description
93
+ epilog = epilog or self.epilog
94
+ parser = argparse.ArgumentParser(
95
+ prog=prog,
96
+ usage=usage,
97
+ description=description,
98
+ epilog=epilog,
99
+ formatter_class=argparse.RawDescriptionHelpFormatter,
100
+ conflict_handler='resolve',
101
+ )
102
+ self.add_all_args(parser)
103
+ return parser
104
+
105
+ def make_parser_and_process(self, prog=None, usage=None, description=None, epilog=None, args=None):
106
+ '''A convenience function to create a parser, call add_all_args(), and then call process_all_args().
107
+ The argument namespace is returned.'''
108
+ parser = self.make_parser(prog, usage, description, epilog, args)
109
+ args = parser.parse_args(args)
110
+ self.process_all_args(args)
111
+ return args
112
+
113
+ def go(self):
114
+ '''Perform the analysis associated with this tool.'''
115
+ raise NotImplementedError
116
+
117
+ def main(self):
118
+ '''A convenience function to make a parser, parse and process arguments, then call self.go()'''
119
+ self.make_parser_and_process()
120
+ self.go()
121
+
122
+
123
+ class WESTParallelTool(WESTTool):
124
+ '''Base class for command-line tools parallelized with wwmgr. This automatically adds and processes
125
+ wwmgr command-line arguments and creates a work manager at self.work_manager.'''
126
+
127
+ def __init__(self, wm_env=None):
128
+ super().__init__()
129
+ self.work_manager = None
130
+ self.wm_env = wm_env or work_managers.environment.default_env
131
+ self.max_queue_len = None
132
+
133
+ def make_parser_and_process(self, prog=None, usage=None, description=None, epilog=None, args=None):
134
+ '''A convenience function to create a parser, call add_all_args(), and then call process_all_args().
135
+ The argument namespace is returned.'''
136
+ parser = self.make_parser(prog, usage, description, epilog, args)
137
+ self.wm_env.add_wm_args(parser)
138
+
139
+ args = parser.parse_args(args)
140
+ self.wm_env.process_wm_args(args)
141
+
142
+ # Instantiate work manager
143
+ self.work_manager = self.wm_env.make_work_manager()
144
+
145
+ # Process args
146
+ self.process_all_args(args)
147
+ return args
148
+
149
+ def add_args(self, parser):
150
+ pgroup = parser.add_argument_group('parallelization options')
151
+ pgroup.add_argument(
152
+ '--max-queue-length',
153
+ type=int,
154
+ help='''Maximum number of tasks that can be queued. Useful to limit RAM use
155
+ for tasks that have very large requests/response. Default: no limit.''',
156
+ )
157
+
158
+ def process_args(self, args):
159
+ self.max_queue_len = args.max_queue_length
160
+ log.debug('max queue length: {!r}'.format(self.max_queue_len))
161
+
162
+ def go(self):
163
+ '''Perform the analysis associated with this tool.'''
164
+ raise NotImplementedError
165
+
166
+ def main(self):
167
+ '''A convenience function to make a parser, parse and process arguments, then run self.go() in the master process.'''
168
+ self.make_parser_and_process()
169
+ with self.work_manager:
170
+ if self.work_manager.is_master:
171
+ self.go()
172
+ else:
173
+ self.work_manager.run()
174
+
175
+
176
+ class WESTMultiTool(WESTParallelTool):
177
+ '''Base class for command-line tools which work with multiple simulations. Automatically parses for
178
+ and gives commands to load multiple files.'''
179
+
180
+ def __init__(self, wm_env=None):
181
+ super(WESTTool, self).__init__()
182
+ self.ntrials = 0
183
+ self.master = None
184
+
185
+ def make_parser_and_process(self, prog=None, usage=None, description=None, epilog=None, args=None):
186
+ '''A convenience function to create a parser, call add_all_args(), and then call process_all_args().
187
+ The argument namespace is returned.'''
188
+ parser = self.make_parser(prog, usage, description, epilog, args)
189
+ args = parser.parse_args(args)
190
+
191
+ # Process args
192
+ self.process_all_args(args)
193
+ return args
194
+
195
+ def parse_from_yaml(self, yamlfilepath):
196
+ '''Parse options from YAML input file. Command line arguments take
197
+ precedence over options specified in the YAML hierarchy.
198
+ TODO: add description on how YAML files should be constructed.
199
+ '''
200
+ import yaml
201
+
202
+ with open(yamlfilepath, 'r') as yamlfile:
203
+ self.yamlargdict = yaml.load(yamlfile, Loader=yaml.Loader)
204
+ # add in options here for intelligent processing of files
205
+
206
+ def add_args(self, parser):
207
+ mgroup = parser.add_argument_group('multiple simulation options')
208
+ mgroup.add_argument(
209
+ '-m',
210
+ '--master',
211
+ default=os.getcwd(),
212
+ help='''Master path of simulations; this is where all the small sims
213
+ are stored.''',
214
+ )
215
+ mgroup.add_argument('-n', '--sims', default=0, help='''The number of simulation directories. Assumes leading zeros.''')
216
+
217
+ class NoSimulationsException(Exception):
218
+ pass
219
+
220
+ def generate_file_list(self, key_list):
221
+ '''A convenience function which takes in a list of keys that are filenames, and returns a dictionary
222
+ which contains all the individual files loaded inside of a dictionary keyed to the filename.'''
223
+ return_dict = {}
224
+ if self.ntrials == 0:
225
+ raise self.NoSimulationsException('You must specify the number of simulations.')
226
+
227
+ for key in key_list:
228
+ return_dict[key] = {}
229
+ for i in range(1, self.ntrials + 1):
230
+ # Need to not make this hard coded, but who cares for now.
231
+ for key in key_list:
232
+ return_dict[key][i] = h5io.WESTPAH5File(os.path.join(self.master, str(i).zfill(2), key), 'r')
233
+ return return_dict
234
+
235
+ def process_args(self, args):
236
+ self.master = args.master
237
+ self.ntrials = int(args.sims)
238
+ log.debug('Simulations loaded from: {!r}'.format(self.master))
239
+ log.debug('Number of simulations: {!r}'.format(self.ntrials))
240
+
241
+ def go(self):
242
+ '''Perform the analysis associated with this tool.'''
243
+ raise NotImplementedError
244
+
245
+ def main(self):
246
+ '''A convenience function to make a parser, parse and process arguments, then run self.go() in the master process.'''
247
+ self.make_parser_and_process()
248
+ self.go()
249
+
250
+
251
+ class WESTSubcommand(WESTToolComponent):
252
+ '''Base class for command-line tool subcommands. A little sugar for making this
253
+ more uniform.'''
254
+
255
+ subcommand = None
256
+ help_text = None
257
+ description = None
258
+
259
+ def __init__(self, parent):
260
+ self.parent = parent
261
+ self.subparser = None
262
+
263
+ def add_to_subparsers(self, subparsers):
264
+ subparser = subparsers.add_parser(
265
+ self.subcommand,
266
+ help=self.help_text,
267
+ description=self.description,
268
+ formatter_class=argparse.RawDescriptionHelpFormatter,
269
+ )
270
+ self.add_all_args(subparser)
271
+ subparser.set_defaults(west_subcommand=self)
272
+ self.subparser = subparser
273
+
274
+ def go(self):
275
+ raise NotImplementedError
276
+
277
+ @property
278
+ def work_manager(self):
279
+ '''The work manager for this tool. Raises AttributeError if this is not a parallel
280
+ tool.'''
281
+ return self.parent.work_manager
282
+
283
+
284
+ class _WESTSubcommandHelp(WESTSubcommand):
285
+ subcommand = 'help'
286
+ help_text = 'print help for this command or individual subcommands'
287
+
288
+ def add_args(self, parser):
289
+ parser.add_argument('command', nargs='?', choices=[subcommand.subcommand for subcommand in self.parent.subcommands])
290
+
291
+ def process_args(self, args):
292
+ self.command = args.command
293
+
294
+ def go(self):
295
+ if self.command is None:
296
+ # Get parent help
297
+ self.parent.parser.print_help(sys.stdout)
298
+ else:
299
+ self.parent._subcommand_instances[self.command].subparser.print_help(sys.stdout)
300
+ sys.exit(0)
301
+
302
+
303
+ class WESTMasterCommand(WESTTool):
304
+ '''Base class for command-line tools that employ subcommands'''
305
+
306
+ subparsers_title = None
307
+ subcommands = None
308
+
309
+ include_help_command = True
310
+
311
+ def __init__(self):
312
+ super().__init__()
313
+ self._subcommand = None
314
+ self._subcommand_instances = {subcommand_class.subcommand: subcommand_class(self) for subcommand_class in self.subcommands}
315
+
316
+ # Sanity checks
317
+ if __debug__:
318
+ for scclass in self.subcommands:
319
+ assert scclass.subcommand, 'subcommand {!r} does not define a "subcommand" class variable'.format(scclass)
320
+
321
+ def add_args(self, parser):
322
+ subparsers = parser.add_subparsers(title=self.subparsers_title)
323
+ if self.include_help_command:
324
+ _WESTSubcommandHelp(self).add_to_subparsers(subparsers)
325
+ for instance in self._subcommand_instances.values():
326
+ instance.add_to_subparsers(subparsers)
327
+
328
+ def process_args(self, args):
329
+ try:
330
+ self._subcommand = args.west_subcommand
331
+ except AttributeError:
332
+ # No subcommand given; display help
333
+ print('Error: a command is required. See below.', file=sys.stderr)
334
+ self.parser.print_help(sys.stderr)
335
+ sys.exit(2)
336
+ else:
337
+ self._subcommand.process_all_args(args)
338
+
339
+ def go(self):
340
+ self._subcommand.go()
@@ -0,0 +1,159 @@
1
+ import numpy as np
2
+ from numpy import index_exp
3
+
4
+ from .core import WESTToolComponent
5
+
6
+ import westpa
7
+ from westpa.core.extloader import get_object
8
+ from westpa.core.h5io import FnDSSpec, MultiDSSpec, SingleSegmentDSSpec, SingleIterDSSpec
9
+
10
+
11
+ def _get_parent_ids(n_iter, iter_group):
12
+ seg_index = iter_group['seg_index']
13
+ try:
14
+ return seg_index['parent_id'][:]
15
+ except ValueError:
16
+ # field not found
17
+ offsets = seg_index['parents_offset'][:]
18
+ all_parents = iter_group['parents'][...]
19
+ return np.require(all_parents.take(offsets), dtype=np.int64)
20
+ else:
21
+ return seg_index['parent_id']
22
+
23
+
24
+ class WESTDataReader(WESTToolComponent):
25
+ '''Tool for reading data from WEST-related HDF5 files. Coordinates finding
26
+ the main HDF5 file from west.cfg or command line arguments, caching of certain
27
+ kinds of data (eventually), and retrieving auxiliary data sets from various
28
+ places.'''
29
+
30
+ def __init__(self):
31
+ super().__init__()
32
+ self.data_manager = westpa.rc.get_data_manager()
33
+ self.we_h5filename = None
34
+
35
+ self._weight_dsspec = None
36
+ self._parent_id_dsspec = None
37
+
38
+ def add_args(self, parser):
39
+ group = parser.add_argument_group('WEST input data options')
40
+ group.add_argument(
41
+ '-W',
42
+ '--west-data',
43
+ dest='we_h5filename',
44
+ metavar='WEST_H5FILE',
45
+ help='''Take WEST data from WEST_H5FILE (default: read from the HDF5 file specified in west.cfg).''',
46
+ )
47
+
48
+ def process_args(self, args):
49
+ if args.we_h5filename:
50
+ self.data_manager.we_h5filename = self.we_h5filename = args.we_h5filename
51
+ else:
52
+ self.we_h5filename = self.data_manager.we_h5filename
53
+
54
+ def open(self, mode='r'):
55
+ self.data_manager.open_backing(mode)
56
+
57
+ def close(self):
58
+ self.data_manager.close_backing()
59
+
60
+ def __getattr__(self, key):
61
+ return getattr(self.data_manager, key)
62
+
63
+ @property
64
+ def weight_dsspec(self):
65
+ if self._weight_dsspec is None:
66
+ assert self.we_h5filename is not None
67
+ self._weight_dsspec = SingleIterDSSpec(self.we_h5filename, 'seg_index', slice=index_exp['weight'])
68
+ return self._weight_dsspec
69
+
70
+ @property
71
+ def parent_id_dsspec(self):
72
+ if self._parent_id_dsspec is None:
73
+ assert self.we_h5filename is not None
74
+ # self._parent_id_dsspec = SingleIterDSSpec(self.we_h5filename, 'seg_index', slice=index_exp['parent_id'])
75
+ self._parent_id_dsspec = FnDSSpec(self.we_h5filename, _get_parent_ids)
76
+ return self._parent_id_dsspec
77
+
78
+ def __enter__(self):
79
+ self.open('r')
80
+ return self
81
+
82
+ def __exit__(self, exc_type, exc_val, exc_traceback):
83
+ self.close()
84
+ return False
85
+
86
+
87
+ class WESTDSSynthesizer(WESTToolComponent):
88
+ '''Tool for synthesizing a dataset for analysis from other datasets. This
89
+ may be done using a custom function, or a list of "data set specifications".
90
+ It is anticipated that if several source datasets are required, then a tool
91
+ will have multiple instances of this class.'''
92
+
93
+ group_name = 'input dataset options'
94
+
95
+ def __init__(self, default_dsname=None, h5filename=None):
96
+ super().__init__()
97
+
98
+ self.h5filename = h5filename
99
+ self.default_dsname = default_dsname
100
+
101
+ self.dsspec = None
102
+
103
+ def add_args(self, parser):
104
+ igroup = parser.add_argument_group(self.group_name).add_mutually_exclusive_group(required=not bool(self.default_dsname))
105
+
106
+ igroup.add_argument(
107
+ '--construct-dataset',
108
+ help='''Use the given function (as in module.function) to extract source data.
109
+ This function will be called once per iteration as function(n_iter, iter_group)
110
+ to construct data for one iteration. Data returned must be indexable as
111
+ [seg_id][timepoint][dimension]''',
112
+ )
113
+
114
+ igroup.add_argument('--dsspecs', nargs='+', metavar='DSSPEC', help='''Construct source data from one or more DSSPECs.''')
115
+
116
+ def process_args(self, args):
117
+ if args.construct_dataset:
118
+ self.dsspec = FnDSSpec(self.h5filename, get_object(args.construct_dataset, path=['.']))
119
+ elif args.dsspecs:
120
+ self.dsspec = MultiDSSpec([SingleSegmentDSSpec.from_string(dsspec, self.h5filename) for dsspec in args.dsspecs])
121
+ else:
122
+ # we can only get here if a default dataset name was specified
123
+ assert self.default_dsname
124
+ self.dsspec = SingleSegmentDSSpec(self.h5filename, self.default_dsname)
125
+
126
+
127
+ class WESTWDSSynthesizer(WESTToolComponent):
128
+ group_name = 'weight dataset options'
129
+
130
+ def __init__(self, default_dsname=None, h5filename=None):
131
+ super(WESTWDSSynthesizer, self).__init__()
132
+
133
+ self.h5filename = h5filename
134
+ self.default_dsname = default_dsname
135
+
136
+ self.dsspec = None
137
+
138
+ def add_args(self, parser):
139
+ wgroup = parser.add_argument_group(self.group_name).add_mutually_exclusive_group(required=not bool(self.default_dsname))
140
+
141
+ wgroup.add_argument(
142
+ '--construct-wdataset',
143
+ help='''Use the given function (as in module.function) to extract source data.
144
+ This function will be called once per iteration as function(n_iter, iter_group)
145
+ to construct data for one iteration. Data returned must be indexable as
146
+ [seg_id]''',
147
+ )
148
+ wgroup.add_argument('--wdsspecs', nargs='+', metavar='WDSSPEC', help='''Construct weight data from one or more DSSPECs.''')
149
+
150
+ def process_args(self, args):
151
+ if args.construct_wdataset:
152
+ self.dsspec = FnDSSpec(self.h5filename, get_object(args.construct_wdataset, path=['.']))
153
+ elif args.dsspecs:
154
+ self.dsspec = MultiDSSpec([SingleSegmentDSSpec.from_string(dsspec, self.h5filename) for dsspec in args.dsspecs])
155
+ else:
156
+ # we can only get here if a default dataset name was specified
157
+ assert self.default_dsname
158
+ # we gotta slice by weight for weights if we want to get the default to work
159
+ self.dsspec = SingleIterDSSpec(self.h5filename, self.default_dsname, slice=np.index_exp['weight'])
westpa/tools/dtypes.py ADDED
@@ -0,0 +1,31 @@
1
+ '''Numpy/HDF5 data types shared among several WESTPA tools'''
2
+
3
+ import numpy as np
4
+
5
+ # Pick up a few data types from the WEST core if possible
6
+ try:
7
+ from westpa.core.data_manager import n_iter_dtype, seg_id_dtype, weight_dtype
8
+ except ImportError:
9
+ n_iter_dtype = np.uint32
10
+ seg_id_dtype = np.int64
11
+ weight_dtype = np.float64
12
+
13
+ # A quantity averaged over iterations
14
+ iter_block_ci_dtype = np.dtype(
15
+ [
16
+ ('iter_start', n_iter_dtype),
17
+ ('iter_stop', n_iter_dtype),
18
+ ('expected', np.float64),
19
+ ('ci_lbound', np.float64),
20
+ ('ci_ubound', np.float64),
21
+ ('sterr', np.float64),
22
+ ('corr_len', n_iter_dtype),
23
+ ]
24
+ )
25
+
26
+ # A quantity to store event duration distribution stuff.
27
+ # Comes from the old w_kinetics.
28
+
29
+ ed_list_dtype = np.dtype(
30
+ [('istate', np.uint16), ('fstate', np.uint16), ('duration', np.float64), ('weight', np.float64), ('seg_id', seg_id_dtype)]
31
+ )