diff --git a/.gitignore b/.gitignore index 005142f11..3aeb9b4db 100644 --- a/.gitignore +++ b/.gitignore @@ -72,6 +72,9 @@ ipython_config.py dmypy.json +# idea env +.idea/ + # vim [._]*.s[a-v][a-z] [._]*.sw[a-p] diff --git a/src/westpa/core/_rc.py b/src/westpa/core/_rc.py index 50abbc30a..07efed852 100644 --- a/src/westpa/core/_rc.py +++ b/src/westpa/core/_rc.py @@ -16,7 +16,7 @@ from westpa.core.binning.assign import BinMapper from westpa.core.binning import RectilinearBinMapper, RecursiveBinMapper, MABBinMapper, BinlessMapper from .yamlcfg import YAMLConfig -from .yamlcfg import YAMLSystem +from .systems import WESTSystem from . import extloader from ..work_managers import SerialWorkManager @@ -548,7 +548,7 @@ def system_from_yaml(self, system_dict): the parsed settings from the config file. """ - yamlSystem = YAMLSystem() + yamlSystem = WESTSystem() print("System building only off of the configuration file") # Now for the building of the system from YAML we need to use # require for these settings since they are musts. diff --git a/src/westpa/core/binning/_assign.pyx b/src/westpa/core/binning/_assign.pyx index 75a976c05..efcb71e23 100644 --- a/src/westpa/core/binning/_assign.pyx +++ b/src/westpa/core/binning/_assign.pyx @@ -71,7 +71,6 @@ cpdef rectilinear_assign(coord_t[:,:] coords, # backwards iteration needs signed values, so that the final != -1 works for idim in range(ndim-1,-1,-1): - found = 0 cval = coords[icoord,idim] boundlen = boundlens[idim] bvec = boundvecs[idim] diff --git a/src/westpa/core/propagators/executable.py b/src/westpa/core/propagators/executable.py index 6c8045f77..7dfee8336 100644 --- a/src/westpa/core/propagators/executable.py +++ b/src/westpa/core/propagators/executable.py @@ -52,7 +52,7 @@ def pcoord_loader(fieldname, pcoord_return_filename, destobj, single_point): pcoord.shape = expected_shape if pcoord.shape != expected_shape: raise ValueError( - 'progress coordinate data has incorrect shape {!r} [expected {!r}] Check pcoord.err or seg_logs for more information.'.format( + 'progress coordinate data has incorrect shape {!r} [expected {!r}] Check the get_pcoord stderr or seg_logs for more information.'.format( pcoord.shape, expected_shape ) ) diff --git a/src/westpa/core/reweight/_reweight.pyx b/src/westpa/core/reweight/_reweight.pyx index d5a10b890..8378f8024 100644 --- a/src/westpa/core/reweight/_reweight.pyx +++ b/src/westpa/core/reweight/_reweight.pyx @@ -4,40 +4,38 @@ from __future__ import print_function,division import cython -import numpy import numpy as np import h5py from scipy.sparse import csgraph import warnings from collections import Counter -cimport numpy cimport numpy as np cimport scipy.linalg cimport scipy.linalg.cython_lapack as cl import scipy.linalg from libc.math cimport isnan -ctypedef numpy.uint16_t index_t -ctypedef numpy.float64_t weight_t -ctypedef numpy.uint8_t bool_t -ctypedef numpy.int64_t trans_t -ctypedef numpy.uint_t uint_t # 32 bits on 32-bit systems, 64 bits on 64-bit systems +ctypedef np.uint16_t index_t +ctypedef np.float64_t weight_t +ctypedef np.uint8_t bool_t +ctypedef np.int64_t trans_t +ctypedef np.uint_t uint_t # 32 bits on 32-bit systems, 64 bits on 64-bit systems ctypedef unsigned short Ushort ctypedef double complex Cdouble -weight_dtype = numpy.float64 -index_dtype = numpy.uint16 -bool_dtype = numpy.bool_ -intc_dtype = numpy.intc +weight_dtype = np.float64 +index_dtype = np.uint16 +bool_dtype = np.bool_ +intc_dtype = np.intc @cython.boundscheck(False) @cython.wraparound(False) -cpdef stats_process(numpy.ndarray[index_t, ndim=2] bin_assignments, - numpy.ndarray[weight_t, ndim=1] weights, - numpy.ndarray[weight_t, ndim=2] fluxes, - numpy.ndarray[weight_t, ndim=1] populations, - numpy.ndarray[trans_t, ndim=2] trans, - numpy.ndarray[index_t, ndim=2] mask, +cpdef stats_process(np.ndarray[index_t, ndim=2] bin_assignments, + np.ndarray[weight_t, ndim=1] weights, + np.ndarray[weight_t, ndim=2] fluxes, + np.ndarray[weight_t, ndim=1] populations, + np.ndarray[trans_t, ndim=2] trans, + np.ndarray[index_t, ndim=2] mask, str interval='timepoint' ): cdef: Py_ssize_t i,k diff --git a/src/westpa/core/sim_manager.py b/src/westpa/core/sim_manager.py index f45a17c7e..d005aa89e 100644 --- a/src/westpa/core/sim_manager.py +++ b/src/westpa/core/sim_manager.py @@ -303,7 +303,7 @@ def initialize_simulation(self, basis_states, target_states, start_states, segs_ # Process start states # Unlike the above, does not create an ibstate group. - # TODO: Should it? I don't think so, if needed it can be traced back through basis_auxref + # Should it? I don't think so, if needed it can be traced back through basis_auxref # Here, we are trying to assign a state_id to the start state to be initialized, without actually # saving it to the ibstates records in any of the h5 files. It might actually be a problem diff --git a/src/westpa/core/we_driver.py b/src/westpa/core/we_driver.py index 93d432362..4acfa2eb1 100644 --- a/src/westpa/core/we_driver.py +++ b/src/westpa/core/we_driver.py @@ -279,7 +279,6 @@ def new_iteration(self, initial_states=None, target_states=None, new_weights=Non self.initial_binning = self.bin_mapper.construct_bins() self.final_binning = self.bin_mapper.construct_bins() - self.next_iter_binning = None flux_matrix = self.flux_matrix = np.zeros((nbins, nbins), dtype=np.float64) transition_matrix = self.transition_matrix = np.zeros((nbins, nbins), np.uint) @@ -530,7 +529,7 @@ def _split_by_weight(self, bin, target_count, ideal_weight): to_split = segments[weights > self.weight_split_threshold * ideal_weight] for segment in to_split: - m = int(math.ceil(segment.weight / ideal_weight)) + m = math.ceil(segment.weight / ideal_weight) bin.remove(segment) new_segments_list = self._split_walker(segment, m, bin) bin.update(new_segments_list) @@ -623,7 +622,7 @@ def _split_by_threshold(self, bin, subgroup): to_split = segments[weights > self.largest_allowed_weight] for segment in to_split: - m = int(math.ceil(segment.weight / self.largest_allowed_weight)) + m = math.ceil(segment.weight / self.largest_allowed_weight) bin.remove(segment) subgroup.remove(segment) new_segments_list = self._split_walker(segment, m, bin) diff --git a/src/westpa/core/yamlcfg.py b/src/westpa/core/yamlcfg.py index 812c9f183..6efa9b057 100644 --- a/src/westpa/core/yamlcfg.py +++ b/src/westpa/core/yamlcfg.py @@ -4,9 +4,7 @@ import os import warnings - import yaml -import numpy as np try: from yaml import CLoader as YLoader @@ -15,10 +13,6 @@ from yaml import Loader as YLoader from . import extloader -from .binning import NopMapper - -# Only needed for temporary class -import westpa NotProvided = object() @@ -302,90 +296,3 @@ def get_choice(self, key, choices, default=NotProvided, value_transform=None): ), ) return value - - -# Temporary class here -class YAMLSystem: - '''A description of the system being simulated, including the dimensionality and - data type of the progress coordinate, the number of progress coordinate entries - expected from each segment, and binning. To construct a simulation, the user must - subclass WESTSystem and set several instance variables. - - At a minimum, the user must subclass ``WESTSystem`` and override - :method:`initialize` to set the data type and dimensionality of progress - coordinate data and define a bin mapper. - - :ivar pcoord_ndim: The number of dimensions in the progress coordinate. - Defaults to 1 (i.e. a one-dimensional progress - coordinate). - :ivar pcoord_dtype: The data type of the progress coordinate, which must be - callable (e.g. ``np.float32`` and ``long`` will work, - but ``' 0.5'.format(alpha)) dlen = len(dataset) - lbi = int(math.floor(n_sets*alpha/2.0)) - ubi = int(math.ceil(n_sets*(1-alpha/2.0))) + lbi = math.floor(n_sets*alpha/2.0) + ubi = math.ceil(n_sets*(1-alpha/2.0)) synth_sets = numpy.empty((n_sets,)+dataset.shape, dtype=dataset.dtype) synth_acf_elems = numpy.empty((n_sets,), numpy.float64) diff --git a/src/westpa/oldtools/aframe/mcbs.py b/src/westpa/oldtools/aframe/mcbs.py index f42a855ab..24f3f7261 100644 --- a/src/westpa/oldtools/aframe/mcbs.py +++ b/src/westpa/oldtools/aframe/mcbs.py @@ -50,7 +50,7 @@ def process_args(self, args, upcall=True): self.mcbs_alpha = 1 - args.mcbs_confidence self.mcbs_nsets = args.mcbs_size if args.mcbs_nsets else min(1000, calc_mcbs_nsets(self.mcbs_alpha)) self.mcbs_display_confidence = '{:.{cp}f}'.format( - 100 * args.mcbs_confidence, cp=-int(math.floor(math.log10(self.mcbs_alpha))) - 2 + 100 * args.mcbs_confidence, cp=-math.floor(math.log10(self.mcbs_alpha)) - 2 ) westpa.rc.pstatus( 'Using bootstrap of {:d} sets to calculate {:s}% confidence interval (alpha={:g}).'.format( @@ -85,7 +85,7 @@ def calc_mcbs_nsets(alpha): def calc_ci_bound_indices(n_sets, alpha): - return (int(math.floor(n_sets * alpha / 2)), int(math.ceil(n_sets * (1 - alpha / 2)))) + return (math.floor(n_sets * alpha / 2), math.ceil(n_sets * (1 - alpha / 2))) def bootstrap_ci_ll(estimator, data, alpha, n_sets, storage, sort, eargs=(), ekwargs={}, fhat=None): @@ -105,8 +105,8 @@ def bootstrap_ci_ll(estimator, data, alpha, n_sets, storage, sort, eargs=(), ekw storage[iset] = estimator(data[indices], *eargs, **ekwargs) synth_sorted = sort(storage) - lbi = int(math.floor(n_sets * alpha / 2)) - ubi = int(math.ceil(n_sets * (1 - alpha / 2))) + lbi = math.floor(n_sets * alpha / 2) + ubi = math.ceil(n_sets * (1 - alpha / 2)) lb = synth_sorted[lbi] ub = synth_sorted[ubi] diff --git a/src/westpa/oldtools/stats/mcbs.py b/src/westpa/oldtools/stats/mcbs.py index 02878a21d..cc7264725 100644 --- a/src/westpa/oldtools/stats/mcbs.py +++ b/src/westpa/oldtools/stats/mcbs.py @@ -74,8 +74,8 @@ def bootstrap_ci(estimator, data, alpha, n_sets=None, args=(), kwargs={}, sort=n f_synth[i] = estimator(data[indices], *args, **kwargs) f_synth_sorted = sort(f_synth) - lbi = int(math.floor(n_sets * alpha / 2)) - ubi = int(math.ceil(n_sets * (1 - alpha / 2))) + lbi = math.floor(n_sets * alpha / 2) + ubi = math.ceil(n_sets * (1 - alpha / 2)) lb = f_synth_sorted[lbi] ub = f_synth_sorted[ubi] diff --git a/src/westpa/tools/binning.py b/src/westpa/tools/binning.py index 668d18ef6..867a87446 100644 --- a/src/westpa/tools/binning.py +++ b/src/westpa/tools/binning.py @@ -144,7 +144,7 @@ def write_bin_info(mapper, assignments, weights, n_target_states, outfile=sys.st min_seg_weight = weights.min() max_seg_weight = weights.max() - ndec = int(math.ceil(-math.log10(1 / n_active))) + ndec = math.ceil(-math.log10(1 / n_active)) outfile.write('{:d} segments\n'.format(len(weights))) outfile.write( diff --git a/tests/fixtures/odld/odld_system.py b/tests/fixtures/odld/odld_system.py deleted file mode 100644 index 8b519eb69..000000000 --- a/tests/fixtures/odld/odld_system.py +++ /dev/null @@ -1,130 +0,0 @@ -import numpy as np -from numpy.random import normal as random_normal - -from westpa.core.binning import RectilinearBinMapper -from westpa.core.propagators import WESTPropagator -from westpa.core.systems import WESTSystem -from westpa.core.binning.mab import MABBinMapper -from westpa.core.binning.binless import BinlessMapper - -PI = np.pi - -pcoord_len = 21 -pcoord_dtype = np.float32 - - -class ODLDPropagator(WESTPropagator): - def __init__(self, rc=None): - super().__init__(rc) - - self.coord_len = pcoord_len - self.coord_dtype = pcoord_dtype - self.coord_ndim = 1 - - self.initial_pcoord = np.array([8.0], dtype=self.coord_dtype) - - self.sigma = 0.001 ** (0.5) - - self.A = 2 - self.B = 10 - self.C = 0.5 - self.x0 = 1 - - # Implement a reflecting boundary at this x value - # (or None, for no reflection) - self.reflect_at = 10.0 - - def get_pcoord(self, state): - '''Get the progress coordinate of the given basis or initial state.''' - state.pcoord = self.initial_pcoord.copy() - - def gen_istate(self, basis_state, initial_state): - initial_state.pcoord = self.initial_pcoord.copy() - initial_state.istate_status = initial_state.ISTATE_STATUS_PREPARED - return initial_state - - def propagate(self, segments): - A, B, C, x0 = self.A, self.B, self.C, self.x0 - - n_segs = len(segments) - - coords = np.empty((n_segs, self.coord_len, self.coord_ndim), dtype=self.coord_dtype) - - for iseg, segment in enumerate(segments): - coords[iseg, 0] = segment.pcoord[0] - - twopi_by_A = 2 * PI / A - half_B = B / 2 - sigma = self.sigma - gradfactor = self.sigma * self.sigma / 2 - coord_len = self.coord_len - reflect_at = self.reflect_at - all_displacements = np.zeros((n_segs, self.coord_len, self.coord_ndim), dtype=self.coord_dtype) - for istep in range(1, coord_len): - x = coords[:, istep - 1, 0] - - xarg = twopi_by_A * (x - x0) - - eCx = np.exp(C * x) - eCx_less_one = eCx - 1.0 - - all_displacements[:, istep, 0] = displacements = random_normal(scale=sigma, size=(n_segs,)) - grad = half_B / (eCx_less_one * eCx_less_one) * (twopi_by_A * eCx_less_one * np.sin(xarg) + C * eCx * np.cos(xarg)) - - newx = x - gradfactor * grad + displacements - if reflect_at is not None: - # Anything that has moved beyond reflect_at must move back that much - - # boolean array of what to reflect - to_reflect = newx > reflect_at - - # how far the things to reflect are beyond our boundary - reflect_by = newx[to_reflect] - reflect_at - - # subtract twice how far they exceed the boundary by - # puts them the same distance from the boundary, on the other side - newx[to_reflect] -= 2 * reflect_by - coords[:, istep, 0] = newx - - for iseg, segment in enumerate(segments): - segment.pcoord[...] = coords[iseg, :] - segment.data['displacement'] = all_displacements[iseg] - segment.status = segment.SEG_STATUS_COMPLETE - - return segments - - -class ODLDSystem(WESTSystem): - def initialize(self): - self.pcoord_ndim = 1 - self.pcoord_dtype = pcoord_dtype - self.pcoord_len = pcoord_len - - # self.bin_mapper = RectilinearBinMapper([[0,1.3] + list(np.arange(1.4, 10.1, 0.1)) + [float('inf')]]) - self.bin_mapper = RectilinearBinMapper([list(np.arange(0.0, 10.12, 0.1))]) - self.bin_target_counts = np.empty((self.bin_mapper.nbins,), np.int_) - self.bin_target_counts[...] = 10 - - -class MABODLDSystem(WESTSystem): - def initialize(self): - self.pcoord_ndim = 1 - self.pcoord_dtype = pcoord_dtype - self.pcoord_len = pcoord_len - - # self.bin_mapper = RectilinearBinMapper([[0,1.3] + list(np.arange(1.4, 10.1, 0.1)) + [float('inf')]]) - self.bin_mapper = MABBinMapper([10]) - self.bin_target_counts = np.empty((self.bin_mapper.nbins,), np.int_) - self.bin_target_counts[...] = 10 - - -class BinlessODLDSystem(WESTSystem): - def initialize(self): - self.pcoord_ndim = 1 - self.pcoord_dtype = pcoord_dtype - self.pcoord_len = pcoord_len - - # self.bin_mapper = RectilinearBinMapper([[0,1.3] + list(np.arange(1.4, 10.1, 0.1)) + [float('inf')]]) - self.bin_mapper = BinlessMapper(ngroups=10, ndims=1, group_function='westpa.core.we_driver._group_walkers_identity') - self.bin_target_counts = np.empty((self.bin_mapper.nbins,), np.int_) - self.bin_target_counts[...] = 10 diff --git a/tests/refs/odld_system.py b/tests/refs/odld_system.py index 3698fc6fb..991690624 100755 --- a/tests/refs/odld_system.py +++ b/tests/refs/odld_system.py @@ -1,7 +1,9 @@ import numpy as np from numpy.random import RandomState -from westpa.core.binning import RectilinearBinMapper +# from numpy.random import normal as random_normal + +from westpa.core.binning import RectilinearBinMapper, BinlessMapper, MABBinMapper from westpa.core.propagators import WESTPropagator from westpa.core.systems import WESTSystem @@ -107,3 +109,27 @@ def initialize(self): self.bin_mapper = RectilinearBinMapper([list(np.arange(0.0, 10.12, 0.1))]) self.bin_target_counts = np.empty((self.bin_mapper.nbins,), np.int_) self.bin_target_counts[...] = 10 + + +class MABODLDSystem(WESTSystem): + def initialize(self): + self.pcoord_ndim = 1 + self.pcoord_dtype = pcoord_dtype + self.pcoord_len = pcoord_len + + # self.bin_mapper = RectilinearBinMapper([[0,1.3] + list(np.arange(1.4, 10.1, 0.1)) + [float('inf')]]) + self.bin_mapper = MABBinMapper([10]) + self.bin_target_counts = np.empty((self.bin_mapper.nbins,), np.int_) + self.bin_target_counts[...] = 10 + + +class BinlessODLDSystem(WESTSystem): + def initialize(self): + self.pcoord_ndim = 1 + self.pcoord_dtype = pcoord_dtype + self.pcoord_len = pcoord_len + + # self.bin_mapper = RectilinearBinMapper([[0,1.3] + list(np.arange(1.4, 10.1, 0.1)) + [float('inf')]]) + self.bin_mapper = BinlessMapper(ngroups=10, ndims=1, group_function='westpa.core.we_driver._group_walkers_identity') + self.bin_target_counts = np.empty((self.bin_mapper.nbins,), np.int_) + self.bin_target_counts[...] = 10 diff --git a/tests/fixtures/odld/west.cfg b/tests/refs/west.cfg similarity index 100% rename from tests/fixtures/odld/west.cfg rename to tests/refs/west.cfg diff --git a/tests/fixtures/odld/west_binless.cfg b/tests/refs/west_binless.cfg similarity index 100% rename from tests/fixtures/odld/west_binless.cfg rename to tests/refs/west_binless.cfg diff --git a/tests/fixtures/odld/west_mab.cfg b/tests/refs/west_mab.cfg similarity index 100% rename from tests/fixtures/odld/west_mab.cfg rename to tests/refs/west_mab.cfg diff --git a/tests/test_data_manager.py b/tests/test_data_manager.py index bdaa7a95b..f12652ef9 100755 --- a/tests/test_data_manager.py +++ b/tests/test_data_manager.py @@ -17,9 +17,9 @@ def setUp(self): here = os.path.dirname(__file__) # Set SIM_ROOT to fixtures folder with west.cfg for odld simulation - os.environ['WEST_SIM_ROOT'] = os.path.join(here, 'fixtures', 'odld') + os.environ['WEST_SIM_ROOT'] = os.path.join(here, 'refs') - config_file_name = os.path.join(here, 'fixtures', 'odld', 'west.cfg') + config_file_name = os.path.join(here, 'refs', 'west.cfg') args = parser.parse_args(['-r={}'.format(config_file_name), "--verbose"]) westpa.rc.process_args(args) diff --git a/tests/test_sim_manager.py b/tests/test_sim_manager.py index aca2899cc..67c1c9b4a 100755 --- a/tests/test_sim_manager.py +++ b/tests/test_sim_manager.py @@ -24,9 +24,9 @@ def setUp(self): westpa.rc.add_args(parser) here = os.path.dirname(__file__) - os.environ['WEST_SIM_ROOT'] = os.path.join(here, 'fixtures', 'odld') + os.environ['WEST_SIM_ROOT'] = os.path.join(here, 'refs') - config_file_name = os.path.join(here, 'fixtures', 'odld', 'west.cfg') + config_file_name = os.path.join(here, 'refs', 'west.cfg') args = parser.parse_args(['-r={}'.format(config_file_name)]) westpa.rc.process_args(args) self.sim_manager = westpa.rc.get_sim_manager() @@ -200,9 +200,8 @@ def setUp(self): westpa.rc.add_args(parser) here = os.path.dirname(__file__) - os.environ['WEST_SIM_ROOT'] = os.path.join(here, 'fixtures', 'odld') - config_file_name = os.path.join(here, 'fixtures', 'odld', 'west_mab.cfg') + config_file_name = os.path.join(here, 'refs', 'west_mab.cfg') args = parser.parse_args(['-r={}'.format(config_file_name)]) westpa.rc.process_args(args) self.sim_manager = westpa.rc.get_sim_manager() @@ -245,9 +244,8 @@ def setUp(self): westpa.rc.add_args(parser) here = os.path.dirname(__file__) - os.environ['WEST_SIM_ROOT'] = os.path.join(here, 'fixtures', 'odld') - config_file_name = os.path.join(here, 'fixtures', 'odld', 'west_binless.cfg') + config_file_name = os.path.join(here, 'refs', 'west_binless.cfg') args = parser.parse_args(['-r={}'.format(config_file_name)]) westpa.rc.process_args(args) self.sim_manager = westpa.rc.get_sim_manager() diff --git a/tests/test_yamlfe.py b/tests/test_yamlfe.py index c6eae389d..81d178ece 100644 --- a/tests/test_yamlfe.py +++ b/tests/test_yamlfe.py @@ -2,10 +2,11 @@ import westpa import westpa.core.yamlcfg as ycf +from westpa.core.systems import WESTSystem from westpa.core.binning import RectilinearBinMapper -class TESTSystem(ycf.YAMLSystem): +class TESTSystem(WESTSystem): def initialize(self): self.pcoord_ndim = 1 self.pcoord_dtype = np.float32