diff --git a/doc/source/index.rst b/doc/source/index.rst index 94fd76232138995504434cc6119211b2db12250e..0f246c0a483993f5a4250e51615e3bb3abdc4935 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -6,11 +6,18 @@ Welcome to PyCGTOOL's documentation! ==================================== -Contents: +.. toctree:: + :hidden: + + self + tutorial + Module Documentation <modules> + .. toctree:: :maxdepth: 2 + Features -------- PyCGTOOL provides a means to quickly and easily generate coarse-grained molecular dynamics models within the MARTINI framework from all-atom or united-atom simulation trajectories. diff --git a/doc/source/pycgtool.rst b/doc/source/pycgtool.rst index 3375064902240b17376bd9a0fa90bfffe6cd2e98..a61ef054c4e1ad21403f73b6d45e595c141a3207 100644 --- a/doc/source/pycgtool.rst +++ b/doc/source/pycgtool.rst @@ -18,6 +18,7 @@ Submodules pycgtool.frame pycgtool.interface pycgtool.mapping + pycgtool.pycgtool pycgtool.util pycgtool.warnings diff --git a/pycgtool/bondset.py b/pycgtool/bondset.py index 873d5bd7e854c557125963b3c46c4bb1d6da87c0..84494674c5c295b1b9e4f4acbd17aa998b55dd7d 100644 --- a/pycgtool/bondset.py +++ b/pycgtool/bondset.py @@ -8,8 +8,9 @@ import itertools import numpy as np import math +import random -from .util import stat_moments, sliding, dist_with_pbc +from .util import stat_moments, sliding, dist_with_pbc, transpose_and_sample from .util import extend_graph_chain, cross, backup_file from .parsers.cfg import CFG @@ -365,36 +366,23 @@ class BondSet: :param target_number: Approx number of sample measurements to output. If None, all samples will be output """ - def transpose(bond_list): - """ - Transpose a list of bonds containing values and slice to provide target number of rows. - """ - if not bond_list: - return [] - - lenmin = min([len(bond.values) for bond in bond_list]) - rows = zip(*(bond.values for bond in bond_list)) - if target_number is not None: - skip = 1 + max(0, lenmin // target_number) - rows = itertools.islice(rows, 0, None, skip) - return rows for mol in self._molecules: if mol == "SOL": continue with open("{0}_length.dat".format(mol), "w") as f: bonds = self.get_bond_lengths(mol, with_constr=True) - for row in transpose(bonds): + for row in transpose_and_sample((bond.values for bond in bonds), n=target_number): print((len(row) * "{:12.5f}").format(*row), file=f) with open("{0}_angle.dat".format(mol), "w") as f: bonds = self.get_bond_angles(mol) - for row in transpose(bonds): + for row in transpose_and_sample((bond.values for bond in bonds), n=target_number): print((len(row) * "{:12.5f}").format(*row), file=f) with open("{0}_dihedral.dat".format(mol), "w") as f: bonds = self.get_bond_dihedrals(mol) - for row in transpose(bonds): + for row in transpose_and_sample((bond.values for bond in bonds), n=target_number): print((len(row) * "{:12.5f}").format(*row), file=f) def __len__(self): diff --git a/pycgtool/util.py b/pycgtool/util.py index 356942e8213e3e765457db93446ff41aea40fe61..62920591a6c26879ef061d91f2dfac955831ef47 100644 --- a/pycgtool/util.py +++ b/pycgtool/util.py @@ -4,6 +4,7 @@ This module contains some general purpose utility functions used in PyCGTOOL. import os import itertools +import random import numpy as np np.seterr(all="raise") @@ -138,6 +139,21 @@ def stat_moments(vals, ignore_nan=True): return np.zeros(2) +def transpose_and_sample(sequence, n=None): + """ + Transpose a sequence of lists and sample to provide target number of rows. + + :param sequence: 2d sequence object to transpose + :param n: Number of samples to take + """ + rows = list(zip(*sequence)) + + if n is not None and len(rows) > n: + rows = random.sample(rows, n) + + return rows + + def dir_up(name, n=1): """ Return the directory path n levels above a specified file/directory. diff --git a/test/test_util.py b/test/test_util.py index 23e8d2b5cf28a68c40a92aca3fd123751fc675e5..815403743c48edfd2c9139a89ec3df3db3b2479b 100644 --- a/test/test_util.py +++ b/test/test_util.py @@ -4,7 +4,7 @@ import os import numpy as np import numpy.testing -from pycgtool.util import tuple_equivalent, extend_graph_chain, stat_moments +from pycgtool.util import tuple_equivalent, extend_graph_chain, stat_moments, transpose_and_sample from pycgtool.util import dir_up, backup_file, sliding, r_squared, dist_with_pbc @@ -90,6 +90,19 @@ class UtilTest(unittest.TestCase): fit = [i for i in range(1, 6)] self.assertEqual(0.5, r_squared(ref, fit)) + def test_transpose_and_sample_no_sample(self): + l = [(1, 2), (3, 4), (5, 6)] + l_t = [(1, 3, 5), (2, 4, 6)] + self.assertEqual(l_t, transpose_and_sample(l, None)) + + def test_transpose_and_sample(self): + l = [(1, 2), (3, 4), (5, 6)] + l_t = [(1, 3, 5), (2, 4, 6)] + + l_t_test = transpose_and_sample(l, n=1) + self.assertEqual(1, len(l_t_test)) + self.assertIn(l_t_test[0], l_t) + if __name__ == '__main__': unittest.main()