Source code for engines.snapshot

"""

@author: JD Chodera
@author: JH Prinz
"""

import abc

from openpathsampling.netcdfplus import StorableObject
from . import features as feats


# =============================================================================
# ABSTRACT SNAPSHOT (IMPLEMENTS ONLY REVERSED SNAPSHOTS)
# =============================================================================

[docs]class BaseSnapshot(StorableObject): """ Simulation snapshot. Contains references to a configuration and momentum """ __metaclass__ = abc.ABCMeta def __init__(self, topology=None): """ Attributes ---------- topology : openpathsamping.Topology, default: None The corresponding topology used with this Snapshot. Can also be None and means no topology is specified. """ super(BaseSnapshot, self).__init__() self._reversed = None self.topology = topology # def __eq__(self, other): # if self is other: # return True # # if isinstance(other, BaseSnapshot): # return self.__uuid__ == other.__uuid__ # # return NotImplemented # # def __ne__(self, other): # return not self == other # def __hash__(self): # return self.__uuid__ & 1152921504606846975 @property def reversed(self): """ Get the reversed copy. Returns ------- :class:`openpathsampling.snapshots.AbstractSnapshot` the reversed partner of the current snapshot Snapshots exist in pairs and this returns the reversed counter part. The actual implementation takes care the the reversed version have reversed momenta, etc. Usually these will not be stored separately but flipped when requested. """ if self._reversed is None: self._reversed = self.create_reversed() return self._reversed
[docs] def __neg__(self): """ Access the reversed snapshot using `-` Returns ------- :class:`BaseSnapshot` the reversed copy """ return self.reversed
# ========================================================================== # Utility functions # ==========================================================================
[docs] def copy(self): """ Returns a shallow copy of the instance itself. The contained configuration and momenta are not copied. Returns ------- :class:`openpathsampling.BaseSnapshot` the shallow copy Notes ----- Shallow here means that content will not be copied but only referenced. Hence if you store the shallow copy it will be stored under a different idx, but the content (e.g. Configuration object) will not. """ this = self.__class__.__new__(self.__class__) BaseSnapshot.__init__(this, topology=self.topology) return this
def copy_with_replacement(self, **kwargs): cp = self.copy() # this will copy all, but it is simple for key, value in kwargs.items(): if hasattr(cp, key): setattr(cp, key, value) else: raise TypeError("copy_with_replacement() got an " "unexpected keyword argument '%s'" % key) return cp def create_reversed(self): this = self.copy() this._reversed = self return this
[docs]def SnapshotFactory( name, features, description=None, use_lazy_reversed=False, base_class=None): """ Helper to create a new Snapshot class Parameters ---------- name : str name of the Snapshot class features : list of :obj:`openpathsampling.features` the features used to build the snapshot description : str the string to be used as basis for the docstring of the new class it will be merged with the docs for the features use_lazy_reversed : bool still in there for legacy reasons. It will make the .reversed attribute into a descriptor than can treat LoaderProxy objects. This feature is not relly used anymore and can in the best case only save little memory with slowing down construction, etc. Using `False` is faster base_class : :obj:`openpathsampling.BaseSnapshot` The base class the Snapshot is derived from. Default is the `BaseSnapshot` class. Returns ------- :class:`openpathsampling.Snapshot` the created `Snapshot` class """ if base_class is None: base_class = BaseSnapshot if type(base_class) is not tuple: base_class = (base_class,) cls = type(name, base_class, {}) if description is not None: cls.__doc__ = description cls = feats.attach_features( features, use_lazy_reversed=use_lazy_reversed)(cls) return cls
class SnapshotDescriptor(frozenset, StorableObject): def __init__(self, contents): StorableObject.__init__(self) frozenset.__init__(contents) self._dimensions = dict(self) self._cls = self._dimensions['class'] del self._dimensions['class'] @property def snapshot_class(self): return self._cls @property def dimensions(self): return self._dimensions @classmethod def from_dict(cls, dct): return cls(dct.items()) def to_dict(self): return dict(self) @staticmethod def construct(snapshot_class, snapshot_dimensions): d = {'class': snapshot_class} if set(snapshot_class.__features__.dimensions) > \ set(snapshot_dimensions.keys()): raise RuntimeError( ('Snapshot of type %s needs %s as dimensions, ' 'you only provided %s') % ( snapshot_class.__class__.__name__, str(set(snapshot_class.__features__['dimensions'])), str(set(snapshot_dimensions.keys())) ) ) d.update(snapshot_dimensions) return SnapshotDescriptor(d.items())