Source code for harmless.io.base
from harmless import diagnostics
__all__ = ["BaseDump"]
[docs]
class BaseDump:
"""Abstract base class for GRMHD fluid dump readers.
Implements lazy evaluation: derived quantities are computed on first
access and cached in ``self.cache``. Primitives and derived quantities
are accessed uniformly via ``dump['key']``.
Subclasses must populate the standard primitives (``rho``, ``u``,
``u1``–``u3``, ``B1``–``B3``) as instance attributes in ``__init__``.
A :class:`harmless.grid.Grid` must be attached via :meth:`set_grid`
before requesting any metric-dependent quantity (``ucon``, ``bcon``,
``bsq``, stress-energy tensors, flux profiles, etc.).
Example::
dump = KHARMADump("torus.out0.00000.h5")
G = Grid(...)
dump.set_grid(G)
bsq = dump['bsq'] # computed and cached
beta = dump['beta'] # reuses cached bsq -- free
pg = dump['pg'] # no grid needed
"""
[docs]
def set_grid(self, G):
"""Attach a :class:`harmless.grid.Grid` to the dump.
Required before requesting any metric-dependent quantity.
Clears the cache so stale values are not returned if the grid changes.
:param G: Grid object
:type G: :class:`harmless.grid.Grid`
"""
self.G = G
self.cache = {}
def __getitem__(self, key):
"""Retrieve a primitive or derived quantity by string key.
Resolution order:
1. **Cache** – return immediately if already computed.
2. **Diagnostic dict** – compute via
:data:`harmless.diagnostics.diagnostic_dict`, cache, and return.
3. **Primitive attribute** – return ``getattr(self, key)`` as a fallback
for raw primitives set by the reader (``rho``, ``u``, ``B1``, etc.).
:param key: Variable name (e.g. ``'rho'``, ``'pg'``, ``'ucon'``)
:type key: str
:return: The requested array
:raises KeyError: If the key is not a primitive attribute or a known
diagnostic key.
"""
if not hasattr(self, "cache"):
self.cache = {}
if key in self.cache:
return self.cache[key]
if key in diagnostics.diagnostic_dict:
self.cache[key] = diagnostics.diagnostic_dict[key](self)
return self.cache[key]
if hasattr(self, key):
return getattr(self, key)
raise KeyError(
f"'{key}' is not a primitive attribute or a known diagnostic key."
)
[docs]
def get_derived(self, var, G=None, components=None):
"""Compute or retrieve a derived quantity, using the cache.
Wraps :meth:`__getitem__` with optional grid attachment and
component selection for tensor quantities.
:param var: Variable key (e.g. ``'pg'``, ``'ucon'``, ``'Tmixed'``)
:type var: str
:param G: Grid object; stored on the dump if provided
:type G: :class:`harmless.grid.Grid`, optional
:param components: Tensor component ``(mu, nu)`` to extract, or
``None`` for the full array
:type components: tuple, optional
:return: Computed quantity (full array or a single component)
:raises KeyError: If var is not a recognised diagnostic key
"""
if G is not None:
self.G = G
if not hasattr(self, "cache"):
self.cache = {}
result = self[var]
if components is not None:
mu, nu = components
return result[..., mu, nu]
return result