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
|
Binary file
|
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
|
|
2
|
+
# A cythoned version of the original function of the stats_process function,
|
|
3
|
+
# based on _kinetics.pyx
|
|
4
|
+
|
|
5
|
+
from __future__ import print_function,division
|
|
6
|
+
import cython
|
|
7
|
+
import numpy as np
|
|
8
|
+
import h5py
|
|
9
|
+
from scipy.sparse import csgraph
|
|
10
|
+
import warnings
|
|
11
|
+
from collections import Counter
|
|
12
|
+
cimport numpy as np
|
|
13
|
+
cimport scipy.linalg
|
|
14
|
+
cimport scipy.linalg.cython_lapack as cl
|
|
15
|
+
import scipy.linalg
|
|
16
|
+
from libc.math cimport isnan
|
|
17
|
+
|
|
18
|
+
ctypedef np.uint16_t index_t
|
|
19
|
+
ctypedef np.float64_t weight_t
|
|
20
|
+
ctypedef np.uint8_t bool_t
|
|
21
|
+
ctypedef np.int64_t trans_t
|
|
22
|
+
ctypedef np.uintp_t uint_t # 32 bits on 32-bit systems, 64 bits on 64-bit systems
|
|
23
|
+
ctypedef unsigned short Ushort
|
|
24
|
+
ctypedef double complex Cdouble
|
|
25
|
+
|
|
26
|
+
weight_dtype = np.float64
|
|
27
|
+
index_dtype = np.uint16
|
|
28
|
+
bool_dtype = np.bool_
|
|
29
|
+
intc_dtype = np.intc
|
|
30
|
+
|
|
31
|
+
@cython.boundscheck(False)
|
|
32
|
+
@cython.wraparound(False)
|
|
33
|
+
cpdef stats_process(np.ndarray[index_t, ndim=2] bin_assignments,
|
|
34
|
+
np.ndarray[weight_t, ndim=1] weights,
|
|
35
|
+
np.ndarray[weight_t, ndim=2] fluxes,
|
|
36
|
+
np.ndarray[weight_t, ndim=1] populations,
|
|
37
|
+
np.ndarray[trans_t, ndim=2] trans,
|
|
38
|
+
np.ndarray[index_t, ndim=2] mask,
|
|
39
|
+
str interval='timepoint' ):
|
|
40
|
+
cdef:
|
|
41
|
+
Py_ssize_t i,k
|
|
42
|
+
index_t ibin,fbin,nsegs,npts
|
|
43
|
+
nsegs = bin_assignments.shape[0]
|
|
44
|
+
npts = bin_assignments.shape[1]
|
|
45
|
+
|
|
46
|
+
if interval == 'timepoint':
|
|
47
|
+
for i in xrange(0,npts - 1):
|
|
48
|
+
for k in xrange(nsegs):
|
|
49
|
+
ibin = bin_assignments[k,i]
|
|
50
|
+
fbin = bin_assignments[k, i + 1]
|
|
51
|
+
|
|
52
|
+
if mask[k, 0] == 1:
|
|
53
|
+
continue
|
|
54
|
+
|
|
55
|
+
w = weights[k]
|
|
56
|
+
|
|
57
|
+
fluxes[ibin, fbin] += w
|
|
58
|
+
trans[ibin, fbin] += 1
|
|
59
|
+
populations[ibin] += w
|
|
60
|
+
return
|
|
61
|
+
|
|
62
|
+
if interval == 'iteration':
|
|
63
|
+
for k in xrange(nsegs):
|
|
64
|
+
# Should this be 0?
|
|
65
|
+
# .... this should super be 0. What?
|
|
66
|
+
ibin = bin_assignments[k,0]
|
|
67
|
+
fbin = bin_assignments[k, npts - 1]
|
|
68
|
+
|
|
69
|
+
if mask[k, 0] == 1:
|
|
70
|
+
continue
|
|
71
|
+
|
|
72
|
+
w = weights[k]
|
|
73
|
+
|
|
74
|
+
fluxes[ibin, fbin] += w
|
|
75
|
+
trans[ibin, fbin] += 1
|
|
76
|
+
populations[ibin] += w
|
|
77
|
+
return
|
|
78
|
+
|
|
79
|
+
@cython.boundscheck(False)
|
|
80
|
+
@cython.wraparound(False)
|
|
81
|
+
@cython.cdivision(True)
|
|
82
|
+
cpdef int normalize(weight_t[:,:] m, Py_ssize_t nfbins) nogil:
|
|
83
|
+
|
|
84
|
+
cdef:
|
|
85
|
+
weight_t row_sum
|
|
86
|
+
Py_ssize_t x, y
|
|
87
|
+
|
|
88
|
+
for y in range(nfbins):
|
|
89
|
+
row_sum = 0
|
|
90
|
+
for x in range(nfbins):
|
|
91
|
+
row_sum += m[y,x]
|
|
92
|
+
if row_sum != 0:
|
|
93
|
+
for x in range(nfbins):
|
|
94
|
+
m[y,x] /= row_sum
|
|
95
|
+
return 0
|
|
96
|
+
|
|
97
|
+
@cython.boundscheck(False)
|
|
98
|
+
@cython.wraparound(False)
|
|
99
|
+
@cython.cdivision(True)
|
|
100
|
+
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):
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# Instead of pulling in start and stop, we'll pull in a list of indices.
|
|
105
|
+
# This way, it should support the bootstrap.
|
|
106
|
+
cdef:
|
|
107
|
+
int[:] _rows, _cols, _obs, _ins, _nrows, _ncols, _nobs, _visited
|
|
108
|
+
long[:] _bin_last_state_map
|
|
109
|
+
weight_t[:] _flux, _total_pop, _rw_bin_probs, _nflux, _rw_color_probs, _rw_state_probs
|
|
110
|
+
double[:] _eigvals, _eigvalsi
|
|
111
|
+
int n_trans, _nstates, lind, _nfbins, _stride, _obs_threshold, nnz, nlind, i, j, _istate, _jstate
|
|
112
|
+
Ushort[:] _indices, _bin_state_map
|
|
113
|
+
weight_t _return_value
|
|
114
|
+
|
|
115
|
+
Ushort[:] _new_indices
|
|
116
|
+
|
|
117
|
+
weight_t[:,:] _total_fluxes, _transition_matrix, _rw_state_flux, _strong_transition_matrix
|
|
118
|
+
double[:,:] _WORK, _eigvecs
|
|
119
|
+
int[:,:] _total_obs, _graph
|
|
120
|
+
#bint _return_flux, _return_states, _return_color
|
|
121
|
+
str _return_obs
|
|
122
|
+
#double[:] eigvals, eigvalsi
|
|
123
|
+
#double[:,:] eigvecs, WORK
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
# CREATE NUMPY ARRAYS
|
|
128
|
+
# This is a temporary measure that fixes some segfaults, which implies I'm probably off by
|
|
129
|
+
# a little bit. Memory heavy, but whatever.
|
|
130
|
+
# It breaks depending on things, so I need to root that out. Clearly, nnz is larger than that.
|
|
131
|
+
_flux = flux
|
|
132
|
+
nnz = len(flux)
|
|
133
|
+
lind = indices.shape[0]
|
|
134
|
+
nlind = indices.shape[0]*stride
|
|
135
|
+
total_fluxes = np.zeros((nfbins, nfbins), weight_dtype)
|
|
136
|
+
total_obs = np.zeros((nfbins, nfbins), intc_dtype)
|
|
137
|
+
transition_matrix = np.zeros((nfbins, nfbins), weight_dtype)
|
|
138
|
+
strong_transition_matrix = np.zeros((nfbins, nfbins), weight_dtype)
|
|
139
|
+
visited = np.zeros((nfbins), intc_dtype)
|
|
140
|
+
graph = np.zeros((nfbins, nfbins+1), dtype=intc_dtype)
|
|
141
|
+
rw_bin_probs = np.zeros(nfbins, weight_dtype)
|
|
142
|
+
new_indices = np.zeros(((nlind)), dtype=indices.dtype)
|
|
143
|
+
rw_state_flux = np.zeros((nstates, nstates), np.float64)
|
|
144
|
+
state_flux = np.zeros((nstates, nstates), weight_dtype)
|
|
145
|
+
eigvals = np.zeros((nfbins), np.float64)
|
|
146
|
+
eigvalsi = np.zeros((nfbins), np.float64)
|
|
147
|
+
eigvecs = np.zeros((nfbins, nfbins), np.float64)
|
|
148
|
+
WORK = np.zeros((nfbins*4, nfbins*4), np.float64)
|
|
149
|
+
rw_color_probs = np.zeros((nstates), weight_dtype)
|
|
150
|
+
rw_state_probs = np.zeros((nbins), weight_dtype)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
# CREATE MEMORYVIEWS
|
|
154
|
+
# These are for what we sent in...
|
|
155
|
+
_rows = rows
|
|
156
|
+
_cols = cols
|
|
157
|
+
_obs = obs
|
|
158
|
+
_flux = flux
|
|
159
|
+
_ins = insert
|
|
160
|
+
_nstates = nstates
|
|
161
|
+
# ... these are for functions we'll be using.
|
|
162
|
+
_total_fluxes = total_fluxes
|
|
163
|
+
_total_obs = total_obs
|
|
164
|
+
_transition_matrix = transition_matrix
|
|
165
|
+
_strong_transition_matrix = strong_transition_matrix
|
|
166
|
+
_nfbins = nfbins
|
|
167
|
+
_stride = stride
|
|
168
|
+
_obs_threshold = obs_threshold
|
|
169
|
+
_indices = indices
|
|
170
|
+
_new_indices = new_indices
|
|
171
|
+
_rw_state_flux = rw_state_flux
|
|
172
|
+
_rw_bin_probs = rw_bin_probs
|
|
173
|
+
_eigvals = eigvals
|
|
174
|
+
_eigvalsi = eigvalsi
|
|
175
|
+
_eigvals = eigvals
|
|
176
|
+
_eigvecs = eigvecs
|
|
177
|
+
_WORK = WORK
|
|
178
|
+
_graph = graph
|
|
179
|
+
_visited = visited
|
|
180
|
+
_rw_color_probs = rw_color_probs
|
|
181
|
+
_rw_state_probs = rw_state_probs
|
|
182
|
+
_bin_last_state_map = bin_last_state_map
|
|
183
|
+
_bin_state_map = bin_state_map
|
|
184
|
+
_istate = istate
|
|
185
|
+
_jstate = jstate
|
|
186
|
+
_return_obs = return_obs
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
#NOGIL
|
|
190
|
+
# Reconstruct dataset. We're just passing the same thing back and forth between functions.
|
|
191
|
+
with nogil:
|
|
192
|
+
for i in range(_nfbins):
|
|
193
|
+
for j in range(1, _nfbins+1):
|
|
194
|
+
_graph[i, j] = _nfbins
|
|
195
|
+
regenerate_subsampled_indices(_indices, _new_indices, lind, _stride)
|
|
196
|
+
accumulate_fluxes(_rows, _cols, _obs, _flux, _ins, _new_indices, nnz, _transition_matrix, nlind)
|
|
197
|
+
accumulate_obs(_rows, _cols, _obs, _flux, _ins, _new_indices, nnz, _total_obs, nlind)
|
|
198
|
+
|
|
199
|
+
remove_under_obs(_transition_matrix, _total_obs, _obs_threshold, _nfbins)
|
|
200
|
+
normalize(_transition_matrix, _nfbins)
|
|
201
|
+
steadystate_solve(_transition_matrix, _strong_transition_matrix, _rw_bin_probs, _nfbins, _eigvals, _eigvalsi, _eigvecs, _WORK, _graph, _visited)
|
|
202
|
+
|
|
203
|
+
for i in range(_nfbins):
|
|
204
|
+
_rw_color_probs[_bin_last_state_map[i]] += _rw_bin_probs[i]
|
|
205
|
+
_rw_state_probs[_bin_state_map[i]] += _rw_bin_probs[i]
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
calc_state_flux(_transition_matrix, _rw_bin_probs, _bin_last_state_map, _bin_state_map, _nstates, _rw_state_flux, _nfbins)
|
|
209
|
+
|
|
210
|
+
# This allows us to use the same function for all three types.
|
|
211
|
+
# Return conditional fluxes.
|
|
212
|
+
if _return_obs == b'F':
|
|
213
|
+
_return_value = _rw_state_flux[_istate,_jstate]
|
|
214
|
+
if isnan(_return_value) is True:
|
|
215
|
+
return 0.0
|
|
216
|
+
else:
|
|
217
|
+
return _return_value
|
|
218
|
+
# Return state probabilities.
|
|
219
|
+
elif _return_obs == b'S':
|
|
220
|
+
_return_value = _rw_state_probs[_istate]
|
|
221
|
+
if isnan(_return_value) is True:
|
|
222
|
+
return 0.0
|
|
223
|
+
else:
|
|
224
|
+
return _return_value
|
|
225
|
+
# Return color (ensemble) probabilities
|
|
226
|
+
elif _return_obs == b'C':
|
|
227
|
+
_return_value = _rw_color_probs[_istate]
|
|
228
|
+
if isnan(_return_value) is True:
|
|
229
|
+
return 0.0
|
|
230
|
+
else:
|
|
231
|
+
return _return_value
|
|
232
|
+
# Return the rates.
|
|
233
|
+
elif _return_obs == b'R':
|
|
234
|
+
if _rw_color_probs[_istate] != 0.0:
|
|
235
|
+
_return_value = (_rw_state_flux[_istate,_jstate] / (_rw_color_probs[_istate] / (_rw_color_probs[_istate] + _rw_color_probs[_jstate])))
|
|
236
|
+
if isnan(_return_value) is True:
|
|
237
|
+
return 0.0
|
|
238
|
+
else:
|
|
239
|
+
return _return_value
|
|
240
|
+
else:
|
|
241
|
+
# We have no ensemble probability, and as such, cannot have a flux.
|
|
242
|
+
return 0.0
|
|
243
|
+
# Return the populations.
|
|
244
|
+
elif _return_obs == b'P':
|
|
245
|
+
return rw_bin_probs
|
|
246
|
+
|
|
247
|
+
@cython.boundscheck(False)
|
|
248
|
+
@cython.wraparound(False)
|
|
249
|
+
@cython.cdivision(True)
|
|
250
|
+
cpdef int regenerate_subsampled_indices(Ushort[:] iin, Ushort[:] iout, int ilen, int stride) nogil:
|
|
251
|
+
|
|
252
|
+
cdef:
|
|
253
|
+
int i, si
|
|
254
|
+
|
|
255
|
+
# go over the range of all indices within iin
|
|
256
|
+
for i in range(ilen):
|
|
257
|
+
# Run over the length of the stride.
|
|
258
|
+
for si in range(stride):
|
|
259
|
+
iout[(i*stride)+si] = iin[i] + si
|
|
260
|
+
|
|
261
|
+
return 0
|
|
262
|
+
|
|
263
|
+
@cython.boundscheck(False)
|
|
264
|
+
@cython.wraparound(False)
|
|
265
|
+
@cython.cdivision(True)
|
|
266
|
+
cpdef int accumulate_fluxes(int[:] hrows, int[:] hcols, int[:] hobs, weight_t[:] hflux, int[:] hins, Ushort[:] iterations, Py_ssize_t nnz, weight_t[:,:] total_fluxes, int itermax) nogil:
|
|
267
|
+
|
|
268
|
+
cdef:
|
|
269
|
+
index_t curriter, elem, iiter, ipop
|
|
270
|
+
long ilem
|
|
271
|
+
|
|
272
|
+
curriter = 0
|
|
273
|
+
|
|
274
|
+
for iter in range(itermax):
|
|
275
|
+
iiter = iterations[iter]
|
|
276
|
+
for ilem in range(hins[iiter], hins[iiter+1]):
|
|
277
|
+
# Not sure if this is necessary, here...
|
|
278
|
+
if ilem < nnz and iiter+1 < itermax:
|
|
279
|
+
total_fluxes[hrows[ilem], hcols[ilem]] += hflux[ilem]
|
|
280
|
+
|
|
281
|
+
return 0
|
|
282
|
+
|
|
283
|
+
@cython.boundscheck(False)
|
|
284
|
+
@cython.wraparound(False)
|
|
285
|
+
@cython.cdivision(True)
|
|
286
|
+
cpdef int accumulate_obs(int[:] hrows, int[:] hcols, int[:] hobs, weight_t[:] hflux, int[:] hins, Ushort[:] iterations, Py_ssize_t nnz, int[:,:] total_obs, int itermax) nogil:
|
|
287
|
+
|
|
288
|
+
cdef:
|
|
289
|
+
index_t curriter, elem, iiter, ipop
|
|
290
|
+
long ilem
|
|
291
|
+
|
|
292
|
+
curriter = 0
|
|
293
|
+
|
|
294
|
+
for iter in range(itermax):
|
|
295
|
+
iiter = iterations[iter]
|
|
296
|
+
for ilem in range(hins[iiter], hins[iiter+1]):
|
|
297
|
+
if ilem < nnz and iiter+1 < itermax:
|
|
298
|
+
total_obs[hrows[ilem], hcols[ilem]] += hobs[ilem]
|
|
299
|
+
|
|
300
|
+
return 0
|
|
301
|
+
|
|
302
|
+
@cython.boundscheck(False)
|
|
303
|
+
@cython.wraparound(False)
|
|
304
|
+
@cython.cdivision(True)
|
|
305
|
+
cpdef int remove_under_obs(weight_t[:,:] flux, int[:,:] obs, int threshold, int nbins) nogil:
|
|
306
|
+
|
|
307
|
+
cdef:
|
|
308
|
+
int x, y
|
|
309
|
+
|
|
310
|
+
for x in range(nbins):
|
|
311
|
+
for y in range(nbins):
|
|
312
|
+
if obs[x,y] < threshold:
|
|
313
|
+
flux[x,y] = 0
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
@cython.boundscheck(False)
|
|
317
|
+
@cython.wraparound(False)
|
|
318
|
+
@cython.cdivision(True)
|
|
319
|
+
cpdef int calc_state_flux(weight_t[:, :] trans_matrix, weight_t[:] bin_probs, long[:] bin_last_state_map, Ushort[:] bin_state_map, int nstates, weight_t[:,:] state_flux, int K_shape) nogil:
|
|
320
|
+
|
|
321
|
+
cdef:
|
|
322
|
+
int i, j, ii, jj
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
for i in range(K_shape):
|
|
326
|
+
for j in range(K_shape):
|
|
327
|
+
|
|
328
|
+
ii = bin_last_state_map[i]
|
|
329
|
+
jj = bin_state_map[j]
|
|
330
|
+
|
|
331
|
+
if jj != nstates:
|
|
332
|
+
state_flux[ii, jj] += (trans_matrix[i, j] * bin_probs[i])
|
|
333
|
+
|
|
334
|
+
return 0
|
|
335
|
+
|
|
336
|
+
@cython.boundscheck(False)
|
|
337
|
+
@cython.wraparound(False)
|
|
338
|
+
@cython.cdivision(True)
|
|
339
|
+
cpdef int steadystate_solve(weight_t[:,:] K, weight_t[:,:] K_mod, weight_t[:] bin_prob, int K_shape, double[:] eigvals, double[:] eigvalsi, double[:,:] eigvecs, double[:,:] WORK, int[:,:] graph, int[:] visited) nogil:
|
|
340
|
+
|
|
341
|
+
cdef:
|
|
342
|
+
int[:] components
|
|
343
|
+
int[:,:] _graph
|
|
344
|
+
double max, eigsum
|
|
345
|
+
int n_components, components_assignments, largest_component, maxi, x, y, n, INFO, LWORK, i, j
|
|
346
|
+
|
|
347
|
+
# POINTERS
|
|
348
|
+
|
|
349
|
+
int *_INFO, *_K_shape, *_LWORK
|
|
350
|
+
double *_K_mod, *_eigvals, *_eigvecs, *_WORK, *_eigvalsi
|
|
351
|
+
_K_shape = &K_shape
|
|
352
|
+
_INFO = &INFO
|
|
353
|
+
_LWORK = &LWORK
|
|
354
|
+
INFO = 0
|
|
355
|
+
LWORK = K_shape * 4
|
|
356
|
+
_K_mod = &K_mod[0,0]
|
|
357
|
+
_eigvals = &eigvals[0]
|
|
358
|
+
_eigvecs = &eigvecs[0,0]
|
|
359
|
+
_eigvalsi = &eigvalsi[0]
|
|
360
|
+
_WORK = &WORK[0,0]
|
|
361
|
+
_graph = graph
|
|
362
|
+
|
|
363
|
+
for i in range(K_shape):
|
|
364
|
+
if visited[i] == 0:
|
|
365
|
+
visited[i] = 1
|
|
366
|
+
return_strong_component(K, K_shape, _graph, i, i, visited)
|
|
367
|
+
n = 0
|
|
368
|
+
for i in range(K_shape):
|
|
369
|
+
if graph[i, 0] >= graph[n, 0]:
|
|
370
|
+
n = i
|
|
371
|
+
# I suspect this may be giving us issues?
|
|
372
|
+
#components = _graph[n, :K_shape+1]
|
|
373
|
+
|
|
374
|
+
maxi = 0
|
|
375
|
+
eigsum = 0.0
|
|
376
|
+
# This all works!
|
|
377
|
+
for x in range(K_shape):
|
|
378
|
+
#i = components[x+1]
|
|
379
|
+
i = graph[n, x+1]
|
|
380
|
+
for y in range(K_shape):
|
|
381
|
+
#j = components[y+1]
|
|
382
|
+
j = graph[n, y+1]
|
|
383
|
+
if i != K_shape and j != K_shape:
|
|
384
|
+
K_mod[i, j] = K[i, j]
|
|
385
|
+
normalize(K_mod, K_shape)
|
|
386
|
+
cl.dgeev('N', 'V', _K_shape, _K_mod, _K_shape, _eigvals, _eigvalsi, _eigvecs, _K_shape, _eigvecs, _K_shape, _WORK, _LWORK, _INFO)
|
|
387
|
+
for x in range(K_shape):
|
|
388
|
+
if x == 0:
|
|
389
|
+
max = eigvals[0]
|
|
390
|
+
maxi = x
|
|
391
|
+
else:
|
|
392
|
+
if max < eigvals[x]:
|
|
393
|
+
max = eigvals[x]
|
|
394
|
+
maxi = x
|
|
395
|
+
# We need to go over the whole range and pick out non K_shape elements.
|
|
396
|
+
# This probably no longer needs to be done, now...
|
|
397
|
+
for i in range(K_shape):
|
|
398
|
+
#x = components[i+1]
|
|
399
|
+
x = graph[n, i+1]
|
|
400
|
+
if x != K_shape:
|
|
401
|
+
#eigsum += eigvecs[maxi, components[i+1]]
|
|
402
|
+
eigsum += eigvecs[maxi, x]
|
|
403
|
+
for i in range(K_shape):
|
|
404
|
+
#x = components[i+1]
|
|
405
|
+
x = graph[n, i+1]
|
|
406
|
+
if x != K_shape:
|
|
407
|
+
#bin_prob[components[i+1]] = eigvecs[maxi, components[i+1]]
|
|
408
|
+
#bin_prob[components[i+1]] /= eigsum
|
|
409
|
+
bin_prob[x] = eigvecs[maxi, x]
|
|
410
|
+
bin_prob[x] /= eigsum
|
|
411
|
+
|
|
412
|
+
return 0
|
|
413
|
+
|
|
414
|
+
@cython.boundscheck(False)
|
|
415
|
+
@cython.wraparound(False)
|
|
416
|
+
@cython.cdivision(True)
|
|
417
|
+
cpdef int return_strong_component(weight_t[:,:] K, int K_shape, int[:, :] graph, int i, int z, int[:] visited) nogil:
|
|
418
|
+
|
|
419
|
+
cdef:
|
|
420
|
+
int j, y
|
|
421
|
+
|
|
422
|
+
if graph[z, 0] == 0:
|
|
423
|
+
graph[z, 0] += 1
|
|
424
|
+
graph[z, 1] = i
|
|
425
|
+
for j in xrange(K_shape):
|
|
426
|
+
if i != j:
|
|
427
|
+
if K[i, j] > 0.0:
|
|
428
|
+
# Strongly connected!
|
|
429
|
+
if visited[j] == 0:
|
|
430
|
+
graph[z, 0] += 1
|
|
431
|
+
y = graph[z, 0]
|
|
432
|
+
graph[z, y] = j
|
|
433
|
+
# We only want to call it when we haven't visited it before.
|
|
434
|
+
# We don't want to call, THEN modify and check. Otherwise, we could be doing many calls.
|
|
435
|
+
visited[j] = 1
|
|
436
|
+
return_strong_component(K, K_shape, graph, j, z, visited)
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
return 0
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import scipy.sparse as sp
|
|
5
|
+
|
|
6
|
+
from westpa.core.data_manager import weight_dtype
|
|
7
|
+
from westpa.core import h5io
|
|
8
|
+
|
|
9
|
+
# From postanalysis matrix
|
|
10
|
+
from westpa.core.binning import index_dtype
|
|
11
|
+
from westpa.core.reweight import stats_process
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
warnings.filterwarnings('ignore', category=DeprecationWarning)
|
|
15
|
+
warnings.filterwarnings('ignore', category=RuntimeWarning)
|
|
16
|
+
warnings.filterwarnings('ignore', category=FutureWarning)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def calc_stats(bin_assignments, weights, fluxes, populations, trans, mask, sampling_frequency):
|
|
20
|
+
fluxes.fill(0.0)
|
|
21
|
+
populations.fill(0.0)
|
|
22
|
+
trans.fill(0)
|
|
23
|
+
|
|
24
|
+
stats_process(bin_assignments, weights, fluxes, populations, trans, mask, interval=sampling_frequency)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class FluxMatrix:
|
|
28
|
+
def w_postanalysis_matrix(self):
|
|
29
|
+
pi = self.progress.indicator
|
|
30
|
+
pi.new_operation('Initializing')
|
|
31
|
+
|
|
32
|
+
self.data_reader.open('r')
|
|
33
|
+
nbins = self.assignments_file.attrs['nbins']
|
|
34
|
+
|
|
35
|
+
state_labels = self.assignments_file['state_labels'][...]
|
|
36
|
+
# state_map = self.assignments_file['state_map'][...]
|
|
37
|
+
nstates = len(state_labels)
|
|
38
|
+
|
|
39
|
+
start_iter, stop_iter = self.iter_range.iter_start, self.iter_range.iter_stop # h5io.get_iter_range(self.assignments_file)
|
|
40
|
+
iter_count = stop_iter - start_iter
|
|
41
|
+
|
|
42
|
+
nfbins = nbins * nstates
|
|
43
|
+
|
|
44
|
+
flux_shape = (iter_count, nfbins, nfbins)
|
|
45
|
+
pop_shape = (iter_count, nfbins)
|
|
46
|
+
|
|
47
|
+
h5io.stamp_iter_range(self.output_file, start_iter, stop_iter)
|
|
48
|
+
|
|
49
|
+
bin_populations_ds = self.output_file.create_dataset('bin_populations', shape=pop_shape, dtype=weight_dtype)
|
|
50
|
+
h5io.stamp_iter_range(bin_populations_ds, start_iter, stop_iter)
|
|
51
|
+
h5io.label_axes(bin_populations_ds, ['iteration', 'bin'])
|
|
52
|
+
|
|
53
|
+
flux_grp = self.output_file.create_group('iterations')
|
|
54
|
+
self.output_file.attrs['nrows'] = nfbins
|
|
55
|
+
self.output_file.attrs['ncols'] = nfbins
|
|
56
|
+
|
|
57
|
+
fluxes = np.empty(flux_shape[1:], weight_dtype)
|
|
58
|
+
populations = np.empty(pop_shape[1:], weight_dtype)
|
|
59
|
+
trans = np.empty(flux_shape[1:], np.int64)
|
|
60
|
+
|
|
61
|
+
# Check to make sure this isn't a data set with target states
|
|
62
|
+
# tstates = self.data_reader.data_manager.get_target_states(0)
|
|
63
|
+
# if len(tstates) > 0:
|
|
64
|
+
# raise ValueError('Postanalysis reweighting analysis does not support WE simulation run under recycling conditions')
|
|
65
|
+
|
|
66
|
+
pi.new_operation('Calculating flux matrices', iter_count)
|
|
67
|
+
# Calculate instantaneous statistics
|
|
68
|
+
for iiter, n_iter in enumerate(range(start_iter, stop_iter)):
|
|
69
|
+
# Get data from the main HDF5 file
|
|
70
|
+
iter_group = self.data_reader.get_iter_group(n_iter)
|
|
71
|
+
seg_index = iter_group['seg_index']
|
|
72
|
+
nsegs, npts = iter_group['pcoord'].shape[0:2]
|
|
73
|
+
weights = seg_index['weight']
|
|
74
|
+
|
|
75
|
+
# Get bin and traj. ensemble assignments from the previously-generated assignments file
|
|
76
|
+
assignment_iiter = h5io.get_iteration_entry(self.assignments_file, n_iter)
|
|
77
|
+
bin_assignments = np.require(
|
|
78
|
+
self.assignments_file['assignments'][assignment_iiter + np.s_[:nsegs, :npts]], dtype=index_dtype
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
mask_unknown = np.zeros_like(bin_assignments, dtype=np.uint16)
|
|
82
|
+
|
|
83
|
+
macrostate_iiter = h5io.get_iteration_entry(self.assignments_file, n_iter)
|
|
84
|
+
macrostate_assignments = np.require(
|
|
85
|
+
self.assignments_file['trajlabels'][macrostate_iiter + np.s_[:nsegs, :npts]], dtype=index_dtype
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
# Transform bin_assignments to take macrostate membership into account
|
|
89
|
+
bin_assignments = nstates * bin_assignments + macrostate_assignments
|
|
90
|
+
|
|
91
|
+
mask_indx = np.where(macrostate_assignments == nstates)
|
|
92
|
+
mask_unknown[mask_indx] = 1
|
|
93
|
+
|
|
94
|
+
# Calculate bin-to-bin fluxes, bin populations and number of obs transitions
|
|
95
|
+
calc_stats(bin_assignments, weights, fluxes, populations, trans, mask_unknown, self.sampling_frequency)
|
|
96
|
+
|
|
97
|
+
# Store bin-based kinetics data
|
|
98
|
+
bin_populations_ds[iiter] = populations
|
|
99
|
+
|
|
100
|
+
# Setup sparse data structures for flux and obs
|
|
101
|
+
fluxes_sp = sp.coo_matrix(fluxes)
|
|
102
|
+
trans_sp = sp.coo_matrix(trans)
|
|
103
|
+
|
|
104
|
+
assert fluxes_sp.nnz == trans_sp.nnz
|
|
105
|
+
|
|
106
|
+
flux_iter_grp = flux_grp.create_group('iter_{:08d}'.format(n_iter))
|
|
107
|
+
flux_iter_grp.create_dataset('flux', data=fluxes_sp.data, dtype=weight_dtype)
|
|
108
|
+
flux_iter_grp.create_dataset('obs', data=trans_sp.data, dtype=np.int32)
|
|
109
|
+
flux_iter_grp.create_dataset('rows', data=fluxes_sp.row, dtype=np.int32)
|
|
110
|
+
flux_iter_grp.create_dataset('cols', data=fluxes_sp.col, dtype=np.int32)
|
|
111
|
+
flux_iter_grp.attrs['nrows'] = nfbins
|
|
112
|
+
flux_iter_grp.attrs['ncols'] = nfbins
|
|
113
|
+
|
|
114
|
+
# Do a little manual clean-up to prevent memory explosion
|
|
115
|
+
del iter_group, weights, bin_assignments
|
|
116
|
+
del macrostate_assignments
|
|
117
|
+
|
|
118
|
+
pi.progress += 1
|
|
119
|
+
|
|
120
|
+
# Check and save the number of intermediate time points; this will be used to normalize the
|
|
121
|
+
# flux and kinetics to tau in w_postanalysis_reweight.
|
|
122
|
+
if self.assignments_file.attrs['subsampled'] is True or self.sampling_frequency == 'iteration':
|
|
123
|
+
self.output_file.attrs['npts'] = 2
|
|
124
|
+
else:
|
|
125
|
+
# self.output_file.attrs['npts'] = npts if self.sampling_frequency == 'timepoint' else 2
|
|
126
|
+
self.output_file.attrs['npts'] = npts
|
westpa/core/segment.py
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import math
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Segment:
|
|
7
|
+
'''A class wrapping segment data that must be passed through the work manager or data manager.
|
|
8
|
+
Most fields are self-explanatory. One item worth noting is that a negative parent ID means that
|
|
9
|
+
the segment starts from the initial state with ID -(segment.parent_id+1)
|
|
10
|
+
'''
|
|
11
|
+
|
|
12
|
+
SEG_STATUS_UNSET = 0
|
|
13
|
+
SEG_STATUS_PREPARED = 1
|
|
14
|
+
SEG_STATUS_COMPLETE = 2
|
|
15
|
+
SEG_STATUS_FAILED = 3
|
|
16
|
+
|
|
17
|
+
SEG_INITPOINT_UNSET = 0
|
|
18
|
+
SEG_INITPOINT_CONTINUES = 1
|
|
19
|
+
SEG_INITPOINT_NEWTRAJ = 2
|
|
20
|
+
|
|
21
|
+
SEG_ENDPOINT_UNSET = 0
|
|
22
|
+
SEG_ENDPOINT_CONTINUES = 1
|
|
23
|
+
SEG_ENDPOINT_MERGED = 2
|
|
24
|
+
SEG_ENDPOINT_RECYCLED = 3
|
|
25
|
+
|
|
26
|
+
statuses = {}
|
|
27
|
+
initpoint_types = {}
|
|
28
|
+
endpoint_types = {}
|
|
29
|
+
|
|
30
|
+
status_names = {}
|
|
31
|
+
initpoint_type_names = {}
|
|
32
|
+
endpoint_type_names = {}
|
|
33
|
+
|
|
34
|
+
# convenience functions for binning
|
|
35
|
+
@staticmethod
|
|
36
|
+
def initial_pcoord(segment):
|
|
37
|
+
'Return the initial progress coordinate point of this segment.'
|
|
38
|
+
return segment.pcoord[0]
|
|
39
|
+
|
|
40
|
+
@staticmethod
|
|
41
|
+
def final_pcoord(segment):
|
|
42
|
+
'Return the final progress coordinate point of this segment.'
|
|
43
|
+
return segment.pcoord[-1]
|
|
44
|
+
|
|
45
|
+
def __init__(
|
|
46
|
+
self,
|
|
47
|
+
n_iter=None,
|
|
48
|
+
seg_id=None,
|
|
49
|
+
weight=None,
|
|
50
|
+
endpoint_type=None,
|
|
51
|
+
parent_id=None,
|
|
52
|
+
wtg_parent_ids=None,
|
|
53
|
+
pcoord=None,
|
|
54
|
+
status=None,
|
|
55
|
+
walltime=None,
|
|
56
|
+
cputime=None,
|
|
57
|
+
data=None,
|
|
58
|
+
):
|
|
59
|
+
# NaNs appear sometimes if a WEST program is terminated unexpectedly; replace with zero
|
|
60
|
+
walltime = 0.0 if walltime is None or math.isnan(walltime) else walltime
|
|
61
|
+
cputime = 0.0 if cputime is None or math.isnan(cputime) else cputime
|
|
62
|
+
|
|
63
|
+
# the int() and float() calls are required so that new-style string formatting doesn't barf
|
|
64
|
+
# assuming that the respective fields are actually strings, probably after implicitly
|
|
65
|
+
# calling __str__() on them. Not sure if this is a numpy, h5py, or python problem
|
|
66
|
+
self.n_iter = int(n_iter) if n_iter is not None else None
|
|
67
|
+
self.seg_id = int(seg_id) if seg_id is not None else None
|
|
68
|
+
self.status = int(status) if status is not None else None
|
|
69
|
+
self.parent_id = int(parent_id) if parent_id is not None else None
|
|
70
|
+
self.endpoint_type = int(endpoint_type) if endpoint_type else self.SEG_ENDPOINT_UNSET
|
|
71
|
+
|
|
72
|
+
self.weight = float(weight) if weight is not None else None
|
|
73
|
+
self.wtg_parent_ids = set(wtg_parent_ids or ())
|
|
74
|
+
|
|
75
|
+
self.pcoord = np.asarray(pcoord) if pcoord is not None else None
|
|
76
|
+
self.walltime = walltime
|
|
77
|
+
self.cputime = cputime
|
|
78
|
+
self.data = data if data else {}
|
|
79
|
+
|
|
80
|
+
def __repr__(self):
|
|
81
|
+
return '<%s(%s) n_iter=%r seg_id=%r weight=%r parent_id=%r wtg_parent_ids=%r pcoord[0]=%r pcoord[-1]=%r>' % (
|
|
82
|
+
self.__class__.__name__,
|
|
83
|
+
hex(id(self)),
|
|
84
|
+
self.n_iter,
|
|
85
|
+
self.seg_id,
|
|
86
|
+
self.weight,
|
|
87
|
+
self.parent_id,
|
|
88
|
+
tuple(self.wtg_parent_ids or ()),
|
|
89
|
+
self.pcoord[0] if self.pcoord is not None else None,
|
|
90
|
+
self.pcoord[-1] if self.pcoord is not None else None,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
@property
|
|
94
|
+
def initpoint_type(self):
|
|
95
|
+
if self.parent_id < 0:
|
|
96
|
+
return Segment.SEG_INITPOINT_NEWTRAJ
|
|
97
|
+
else:
|
|
98
|
+
return Segment.SEG_INITPOINT_CONTINUES
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def initial_state_id(self):
|
|
102
|
+
if self.parent_id < 0:
|
|
103
|
+
return -(self.parent_id + 1)
|
|
104
|
+
else:
|
|
105
|
+
return None
|
|
106
|
+
|
|
107
|
+
status_text = property((lambda s: s.status_names[s.status]))
|
|
108
|
+
endpoint_type_text = property((lambda s: s.endpoint_type_names[s.endpoint_type]))
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
Segment.statuses.update({_attr: getattr(Segment, _attr) for _attr in dir(Segment) if _attr.startswith('SEG_STATUS_')})
|
|
112
|
+
Segment.initpoint_types.update({_attr: getattr(Segment, _attr) for _attr in dir(Segment) if _attr.startswith('SEG_INITPOINT_')})
|
|
113
|
+
Segment.endpoint_types.update({_attr: getattr(Segment, _attr) for _attr in dir(Segment) if _attr.startswith('SEG_ENDPOINT_')})
|
|
114
|
+
|
|
115
|
+
Segment.status_names.update({getattr(Segment, _attr): _attr for _attr in dir(Segment) if _attr.startswith('SEG_STATUS_')})
|
|
116
|
+
Segment.initpoint_type_names.update(
|
|
117
|
+
{getattr(Segment, _attr): _attr for _attr in dir(Segment) if _attr.startswith('SEG_INITPOINT_')}
|
|
118
|
+
)
|
|
119
|
+
Segment.endpoint_type_names.update({getattr(Segment, _attr): _attr for _attr in dir(Segment) if _attr.startswith('SEG_ENDPOINT_')})
|