Source code for general_python.common

"""Shared utilities for IO, plotting, logging, and runtime helpers.

The ``common`` package contains cross-cutting infrastructure used by all major
subpackages, including directory management, plotting, HDF5 helpers, timers,
and low-level binary utilities.

Input/output contracts
----------------------
Utilities are intentionally lightweight: they accept standard Python objects or
NumPy-compatible arrays and return plain Python or NumPy outputs where possible.
Plotting helpers expect Matplotlib-compatible inputs.

Determinism and stability
-------------------------
Most helpers are deterministic for fixed inputs. Logging or timing output may
vary with runtime scheduling. Binary helper functions operate on integer bit
patterns and are deterministic by construction.

Submodules are loaded lazily on first access to reduce import overhead.
"""

import  importlib
from    typing import TYPE_CHECKING

# For static type checking (IDE support) without runtime import
if TYPE_CHECKING:
    from .directories           import Directories
    from .plot                  import (
                                    Plotter, PlotterSave, MatrixPrinter,
                                    colorsCycle, colorsCycleBright, colorsCycleDark, colorsList,
                                    linestylesCycle, linestylesCycleExtended, linestylesList,
                                    markersCycle, markersList
                                )
    from .datah                 import DataHandler
    from .binary                import (
                                    ctz64, popcount64,
                                    mask_from_indices, indices_from_mask,
                                    complement_mask, complement_indices
                                )
    from .hdf5man               import HDF5Manager
    from .lazy_entry            import (
                                    LazyDataEntry, LazyHDF5Entry,
                                    LazyNpzEntry, LazyPickleEntry, LazyJsonEntry
                                )
    from .plotters.data_loader  import load_results, filter_results, ResultSet, PlotData
    from .flog                  import Logger, get_global_logger
    from .memory                import log_memory_status, check_memory_for_operation
    from .timer                 import Timer

[docs] def dtype_to_name(dtype): """ Normalize dtype-like objects to the canonical QES dtype name. """ if isinstance(dtype, str): return dtype try: import numpy as np dtype_obj = np.dtype(dtype) except Exception: dtype_obj = dtype try: from QES.Algebra.backends import get_dtype_map dtype_name = get_dtype_map().get(dtype) if dtype_name is None: dtype_name = get_dtype_map().get(dtype_obj) if dtype_name is not None: return dtype_name except Exception: pass try: import numpy as np return np.dtype(dtype).name except Exception: return str(dtype)
# Lazy loading registry _LAZY_IMPORTS = { # directories 'Directories' : ('.directories', 'Directories'), # plot 'Plotter' : ('.plot', 'Plotter'), 'PlotterSave' : ('.plot', 'PlotterSave'), 'MatrixPrinter' : ('.plot', 'MatrixPrinter'), 'colorsCycle' : ('.plot', 'colorsCycle'), 'colorsCycleBright' : ('.plot', 'colorsCycleBright'), 'colorsCycleDark' : ('.plot', 'colorsCycleDark'), 'colorsList' : ('.plot', 'colorsList'), 'linestylesCycle' : ('.plot', 'linestylesCycle'), 'linestylesCycleExtended' : ('.plot', 'linestylesCycleExtended'), 'linestylesList' : ('.plot', 'linestylesList'), 'markersCycle' : ('.plot', 'markersCycle'), 'markersList' : ('.plot', 'markersList'), # datah 'DataHandler' : ('.datah', 'DataHandler'), # binary - Numba-safe bit operations 'ctz64' : ('.binary', 'ctz64'), 'popcount64' : ('.binary', 'popcount64'), 'mask_from_indices' : ('.binary', 'mask_from_indices'), 'indices_from_mask' : ('.binary', 'indices_from_mask'), 'complement_mask' : ('.binary', 'complement_mask'), 'complement_indices' : ('.binary', 'complement_indices'), # alias # hdf5 'HDF5Manager' : ('.hdf5man', 'HDF5Manager'), # lazy entries 'LazyDataEntry' : ('.lazy_entry', 'LazyDataEntry'), 'LazyHDF5Entry' : ('.lazy_entry', 'LazyHDF5Entry'), 'LazyNpzEntry' : ('.lazy_entry', 'LazyNpzEntry'), 'LazyPickleEntry' : ('.lazy_entry', 'LazyPickleEntry'), 'LazyJsonEntry' : ('.lazy_entry', 'LazyJsonEntry'), # data loaders 'load_results' : ('.plotters.data_loader', 'load_results'), 'filter_results' : ('.plotters.data_loader', 'filter_results'), 'ResultSet' : ('.plotters.data_loader', 'ResultSet'), 'PlotData' : ('.plotters.data_loader', 'PlotData'), # logging 'Logger' : ('.flog', 'Logger'), 'get_global_logger' : ('.flog', 'get_global_logger'), # memory 'log_memory_status' : ('.memory', 'log_memory_status'), 'check_memory_for_operation': ('.memory', 'check_memory_for_operation'), # timer 'Timer' : ('.timer', 'Timer'), } # Cache for loaded modules _LOADED = {} def __getattr__(name: str): """Lazy import handler - loads modules only when accessed.""" if name in _LAZY_IMPORTS: if name not in _LOADED: module_path, attr_name = _LAZY_IMPORTS[name] module = importlib.import_module(module_path, package=__name__) _LOADED[name] = getattr(module, attr_name) return _LOADED[name] raise AttributeError(f"module {__name__!r} has no attribute {name!r}") def __dir__(): """List available attributes for autocompletion.""" return list(_LAZY_IMPORTS.keys()) + ['dtype_to_name', 'get_module_description', 'list_available_modules'] ####################################################################################################
[docs] def get_module_description(module_name): """ Get the description of a specific module in the common package. Parameters: - module_name (str): The name of the module. Returns: - str: The description of the module. """ descriptions = { "binary" : "Handles binary data operations.", "directories" : "Provides the Directories class for managing directory structures.", "plot" : "Provides visualization utilities (Plotter, PlotterSave, MatrixPrinter).", "datah" : "Handles various data operations and transformations.", "hdf5man" : "Manages reading and writing HDF5 files.", "lazy_entry" : "Lazy data-entry wrappers for HDF5/NPZ/Pickle/JSON files.", "plotters" : "Plot-related data loaders and plotting utilities.", "flog" : "Provides logging functionalities for structured output.", "memory" : "Memory monitoring and management utilities.", "timer" : "Context manager and utilities for performance timing." } return descriptions.get(module_name, "Module not found.")
[docs] def list_available_modules(): """ List all available modules in the common package. Returns: - list: A list of available module names. """ return ["binary", "directories", "plot", "datah", "hdf5man", "lazy_entry", "plotters", "flog", "memory", "timer"]
# Expose all lazy-loadable names for `from common import *` __all__ = list(_LAZY_IMPORTS.keys()) + ['dtype_to_name', 'get_module_description', 'list_available_modules'] #################################################################################################### #! EOF ####################################################################################################