Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion openpathsampling/experimental/simstore/storable_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,8 @@ class StorableFunction(StorableNamedObject):
(None) stores source for anything created in ``__main__`` that is
not a lambda expression.
"""
def __init__(self, func, func_config=None, store_source=None, **kwargs):
def __init__(self, func, func_config=None, store_source=None,
period_min=None, period_max=None,**kwargs):
super(StorableFunction, self).__init__()
self.func = func
self.source = None
Expand All @@ -270,8 +271,28 @@ def __init__(self, func, func_config=None, store_source=None, **kwargs):
self.local_cache = None # set correctly by self.mode setter
self._disk_cache = True
self._handlers = set([])
self._check_period(period_min, period_max)
self.period_min = period_min
self.period_max = period_max
self.mode = 'analysis'

@staticmethod
def _check_period(period_min, period_max):
is_not_periodic = period_min is None and period_max is None
is_periodic = period_min is not None and period_max is not None
is_error = not (is_periodic or is_not_periodic)
if is_error:
raise ValueError("Periodic functions must have upper and "
"lower bounds. This function has period_min "
+ str(period_min) + " and period_max "
+ str(period_max) + ".")
return is_periodic

@property
def is_periodic(self):
return self._check_period(self.period_min, self.period_max)


def add_handler(self, storage, override=False):
self._handlers.add(storage)

Expand Down
20 changes: 19 additions & 1 deletion openpathsampling/experimental/simstore/test_storable_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
except ImportError:
import mock

from collections import defaultdict
from collections import defaultdict, Counter
import itertools

import numpy as np
Expand Down Expand Up @@ -223,6 +223,24 @@ def get_expected(uuid):

self.func = StorableFunction(get_expected)

@pytest.mark.parametrize('min_max', [(None, None), (None, 10), (0, 10)])
def test_check_periodic(self, min_max):
period_min, period_max = min_max
n_nones = Counter(min_max)[None]
expected = {2: False, 0: True, 1: 'error'}[n_nones]
check_period = StorableFunction._check_period
if expected == 'error':
with pytest.raises(ValueError, match='period'):
check_period(period_min, period_max)
else:
assert check_period(period_min, period_max) == expected

def test_is_periodic(self):
assert not self.func.is_periodic
func = StorableFunction(lambda s: s.xyz[0][0], period_min=0.0,
period_max=1.0)
assert func.is_periodic

def test_gets_source(self):
pytest.skip()
pass
Expand Down
12 changes: 9 additions & 3 deletions openpathsampling/experimental/storage/collective_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,19 @@ def __call__(self, values):
return paths.Trajectory(values).to_mdtraj(topology=top)

class MDTrajFunctionCV(CoordinateFunctionCV):
def __init__(self, func, topology, func_config=None,
**kwargs):
def __init__(self, func, topology, func_config=None, period_min=None,
period_max=None, **kwargs):
if func_config is None:
func_config = StorableFunctionConfig([
MDTrajProcessor(topology), wrap_numpy, scalarize_singletons,
])
super(MDTrajFunctionCV, self).__init__(func, func_config, **kwargs)
super(MDTrajFunctionCV, self).__init__(
func,
func_config=func_config,
period_min=period_min,
period_max=period_max,
**kwargs
)
self.topology = topology
self.mdtraj_topology = topology.mdtraj

Expand Down