Skip to content

Commit

Permalink
Add _Compute base class
Browse files Browse the repository at this point in the history
  • Loading branch information
AlainKadar committed Nov 3, 2023
1 parent 9536986 commit 6bdab6b
Showing 1 changed file with 71 additions and 0 deletions.
71 changes: 71 additions & 0 deletions StructuralGT/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,77 @@
import time
import gsd.hoomd
import warnings
from functools import wraps

class _Compute:
r"""Parent class for all compute classes in StructuralGT. Modelled after
the :class:`_Compute` class used in **freud** :cite:`Ramasubramani2020`.
The primary purpose of this class is to prevent access of uncomputed
values. This is accomplished by maintaining a boolean flag to track whether
the compute method in a class has been called and decorating class
properties that rely on compute having been called.
To use this class, one would write, for example,
.. code-block:: python
class Electronic(_Compute):
def compute(...)
...
@_Compute._computed_property
def effectice_resistance(self):
return ...
Attributes:
_called_compute (bool):
Flag representing whether the compute method has been called.
"""

def __init__(self):
self._called_compute = False

def __getattribute__(self, attr):
"""Compute methods set a flag to indicate that quantities have been
computed. Compute must be called before plotting."""
attribute = object.__getattribute__(self, attr)
if attr == 'compute':
# Set the attribute *after* computing. This enables
# self._called_compute to be used in the compute method itself.
compute = attribute

@wraps(compute)
def compute_wrapper(*args, **kwargs):
return_value = compute(*args, **kwargs)
self._called_compute = True
return return_value
return compute_wrapper
elif attr == 'plot':
if not self._called_compute:
raise AttributeError(
"The compute method must be called before calling plot.")
return attribute

@staticmethod
def _computed_property(prop):
r"""Decorator that makes a class method to be a property with limited access.
Args:
prop (callable): The property function.
Returns:
Decorator decorating appropriate property method.
"""

@property
@wraps(prop)
def wrapper(self, *args, **kwargs):
if not self._called_compute:
raise AttributeError(
"Property not computed. Call compute first.")
return prop(self, *args, **kwargs)
return wrapper

def _abs_path(network, name):
if name[0] == "/":
Expand Down

0 comments on commit 6bdab6b

Please sign in to comment.