Implement BaseObserver
Description
Observers are meant as means to provide and/or compute more complex observables, including e.g., the calculation of short
and long range order parameters, the extraction of site occupancy factors, or the storage of configurations to obtain a trajectory.
The BaseObserver
class shall provide the basic functionality that is shared by all observers.
Firstly, observers must be attached to an ensemble (handled by the BaseEnsemble
class).
mc = CanonicalEnsemble(atoms, calculator=ce, temperature=500.0)
# attach a trajectory/configuration to store snapshots
obs = SnapShooter(interval=100)
mc.attach_observer(obs, tag='snapshooter')
# attach SRO calculator
obs = ShortRangeOrderCalculator(mode='Warren-Cowley', interval=10)
mc.attach_observer(obs, tag='sro')
The observers are then to be called to compute observables based on the current configuration.
In #158 (closed) a snippet illustrates how BaseEnsemble
would add such data to a DataContainer
object:
dc = DataContainer(...)
if self.mcstep % self.minimum_interval == 0:
for obs in self.observers:
if self.mcstep % obs.interval == 0:
dc.append(self.mcstep, obs.tag, obs.get_observable(...))
The BaseEnsemble
class must include basic properties such as e.g., interval
, tag
, type
(of the returned data).
It must furthermore declare/define elementary functions for retrieval of the computed properties. Examples
- a short range order (SRO) observer is going to return a list of variables that represent the SROs for different neighbor shells
- the
SnapShooter
can return a list ofint
s that reflect the occupation of sites by different species
It is also important that observers can be called after the fact
Sub-tasks
- implement class
- write unit test
Demonstration
- all tests pass
- docstrings complete