Beispiel #1
0
    def __init__(self,
                 name,
                 cv_store_cache=False,
                 cv_time_reversible=False,
                 cv_requires_lists=False,
                 cv_wrap_numpy_array=False,
                 cv_scalarize_numpy_singletons=False):
        if (type(name) is not str
                and type(name) is not unicode) or len(name) == 0:
            raise ValueError('name must be a non-empty string')

        StorableNamedObject.__init__(self)

        self.name = name

        self.store_cache = cv_store_cache
        self.time_reversible = cv_time_reversible
        self.requires_lists = cv_requires_lists
        self.wrap_numpy_array = cv_wrap_numpy_array
        self.scalarize_numpy_singletons = cv_scalarize_numpy_singletons

        self._single_dict = cd.ExpandSingle()
        self._cache_dict = cd.ReversibleCacheChainDict(
            WeakLRUCache(1000, weak_type='key'), reversible=cv_time_reversible)

        self._func_dict = cd.Function(self._eval, self.requires_lists,
                                      self.scalarize_numpy_singletons)

        post = self._func_dict + self._cache_dict + self._single_dict

        if cv_wrap_numpy_array:
            post = post + cd.MergeNumpy()

        super(CollectiveVariable, self).__init__(post=post)
    def __init__(self, name, volume):
        """
        Parameters
        ----------
        name : string
            name of the collective variable
        volume : openpathsampling.Volume
            the Volume instance to be treated as a (storable) CV

        """

        super(InVolumeCV, self).__init__(
            name,
            cv_time_reversible=True
        )
        self.volume = volume

        self._eval_dict = cd.Function(
            self._eval,
            requires_lists=False
        )

        self._post = self._post > self._eval_dict
    def __init__(
            self,
            name,
            cv_callable,
            cv_time_reversible=False,
            cv_requires_lists=False,
            cv_wrap_numpy_array=False,
            cv_scalarize_numpy_singletons=False,
            **kwargs
    ):
        """
        Parameters
        ----------
        name
        cv_callable : callable (function or class with __call__)
            The callable to be used
        cv_time_reversible
        cv_requires_lists : If `True` the internal function  always a list of
            elements instead of single values. It also means that if you call
            the CV with a list of snapshots a list of snapshot objects will be
            passed. If `False` a list of Snapshots like a trajectory will
            be passed snapshot by snapshot.
        cv_wrap_numpy_array : bool, default: False
            if `True` the returned array will be wrapped with a
            `numpy.array()` which will convert a list of numpy arrays into a
            single large numpy.array. This is useful for post-processing of
            larger data since numpy arrays are easier to manipulate.
        cv_scalarize_numpy_singletons : bool, default: True
            If `True` then arrays of length 1 will be treated as array with one
            dimension less. e.g. [[1], [2], [3]] will be turned into [1, 2, 3].
            This is often useful, when you use en external function to get only
            a single value.
        kwargs : **kwargs
            a dictionary with named arguments which should be used
            with `c`. Either for class creation or for calling the function

        Notes
        -----
        This function is abstract and need _eval to be implemented to work.
        Problem is that there are two types of callable functions:
        1. direct functions: these can be called and give the wanted value
           `c(snapshot, \**kwargs)` would be the typical call
        2. a generating function: a function the creates the callable object
           `c(**kwargs)(snapshot)` is the typical call. This is usually used
           for classes. Create the instance and then use it.

        This function is very powerful, but need some explanation if you want
        the function to be stored alongside all other information in your
        storage. The problem is that a python function relies (usually) on
        an underlying global namespace that can be accessed. This is especially
        important when using an iPython notebook. The problem is, that the
        function that stored your used-defined function has no knowledge
        about this underlying namespace and its variables. All it can save is
        names of variables from your namespace to be used. This means you can
        store arbitrary functions, but these will only work, if you call the
        reconstructed ones from the same context (scope). This is a powerful
        feature because a function might do something different in another
        context, but in our case we cannot store these additional information.

        What we can do, is analyse your function and determine which variables
        (if at all these are) and inform you, if you might run into trouble.
        To avoid problems you should try to:

        1. import necessary modules inside of your function
        2. create constants inside your function
        3. if variables from the global scope are used these need to be stored
           with the function and this can only be done if they are passed as
           arguments to the function and added as kwargs to the FunctionCV

        >>> import openpathsampling.engines as peng
        >>> def func(snapshot, indices):
        >>>     import mdtraj as md
        >>>     return md.compute_dihedrals(
        >>>         peng.Trajectory([snapshot]).to_mdtraj(), indices=indices)

        >>> cv = FunctionCV('my_cv', func, indices=[[4, 6, 8, 10]])

        The function will also check if non-standard modules are imported,
        which are now `numpy`, `math`, `msmbuilder`, `pandas` and `mdtraj`
        """

        super(CallableCV, self).__init__(
            name,
            cv_time_reversible=cv_time_reversible
        )
        self.cv_requires_lists = cv_requires_lists
        self.cv_wrap_numpy_array = cv_wrap_numpy_array
        self.cv_scalarize_numpy_singletons = cv_scalarize_numpy_singletons

        self.cv_callable = cv_callable

        if kwargs is None:
            kwargs = dict()
        self.kwargs = kwargs

        self._eval_dict = cd.Function(
            self._eval,
            self.cv_requires_lists,
            self.cv_scalarize_numpy_singletons
        )

        post = self._post > self._eval_dict

        if cv_wrap_numpy_array:
            # noinspection PyTypeChecker
            post = cd.MergeNumpy() > post

        self._post = post