Commit 25b08e79 authored by Gaetano Scandariato's avatar Gaetano Scandariato
Browse files

refactor of group 7 (logging and error handling): repository-wide unification...

refactor of group 7 (logging and error handling): repository-wide unification into a single canonical logger module (`PyAETNA.logger`).

- Removed all legacy logging utility files and delegation shims (`reporting/logger.py` and `sampling/engine/utils/logging_utils.py`)

- Updated all modules across `PyAETNA` to import `_log` and `set_log_file` directly from `PyAETNA.logger`.

- Redundant "INFO:" severity tags were eliminated across the entire codebase while maintaining "WARNING:" and "ERROR:" tags. `run.py` was also migrated: its local `_log` closure (which always prepended the `INFO:` tag) was removed and replaced with the canonical `PyAETNA.logger._log`; the log file is now configured once via `set_log_file(logFilePath)` so all downstream modules (sampler, reporter, physics) automatically share the same destination.

- `planet_phys.py` was fixed to no longer import the now-deleted `_get_logger` from `PyAETNA.reporting`, replacing that pattern with a direct import from `PyAETNA.logger`.

- The `_EIV_TRIGGERED` flag was moved to `PyAETNA.logger` as a module-level attribute, removing the last import of `PyAETNA.reporting.logger`.

- Updated and verified the test suite with `/dati/pyenvs/pyaetnaEnv/bin/python` (198 passed, 0 failures), confirming full regression-free functionality before permanently deleting the deprecated logging files.
parent 01559a39
Loading
Loading
Loading
Loading
Loading

PyAETNA/logger.py

0 → 100644
+70 −0
Changes for PyAETNA/logger.py: 70 added lines, 0 removed lines.
Original line number Diff line number Diff line
# -*- coding: utf-8 -*-
"""
Canonical repository-wide logging module for PyAETNA.

Provides a unified logger `_log` supporting both implicit module-level log file
destinations (configured via `set_log_file`) and explicit model/file target parameters.
"""
import time as ttt

_LOG_FILE = None
_EIV_TRIGGERED = False


def set_log_file(path):
    """Set the module-wide default log file path.

    All subsequent calls to `_log` without an explicit target will write to `path`.
    Pass `None` to log to stdout by default.
    """
    global _LOG_FILE
    _LOG_FILE = path


def get_log_file():
    """Return the current default log file path."""
    return _LOG_FILE


def _log(target_or_msg, msg=None, level=None):
    """Write a timestamped message to a log file or stdout.

    Signatures supported:
        _log("Message", level="WARNING")         # Default target (_LOG_FILE or stdout)
        _log(plModel, "Message")                 # Explicit model or path target
        _log(log_file_path, "Message")           # Explicit string path target

    Args:
        target_or_msg: Target object (with `.logFile` attribute), path (str), or message string.
        msg (str, optional): Message string if target_or_msg is a target object/path.
        level (str, optional): Severity level (e.g. 'WARNING', 'ERROR'). Standard 'INFO' level
            is omitted from the output string as messages are informative by nature.
    """
    if msg is not None:
        target = target_or_msg
        message = msg
    else:
        target = None
        message = target_or_msg

    # Extract path from target object if present, otherwise use target path or module default
    log_file = target.logFile if hasattr(target, 'logFile') else (target or _LOG_FILE)

    # Omit 'INFO' tag from output line; include non-INFO severity levels (WARNING, ERROR, etc.)
    level_tag = f" {level.upper()}:" if level and level.upper() != 'INFO' else ""
    timestamp = ttt.strftime("%Y-%m-%d %H:%M:%S", ttt.gmtime())
    formatted = f"{timestamp}{level_tag} {message}"

    if not log_file:
        print(formatted)
        return

    try:
        with open(log_file, 'a') as f:
            f.write(formatted + '\n')
    except OSError as e:
        print(f"{formatted} (warning: failed to write to log file {log_file!r}: {e})")


# Default log file is stdout (None)
set_log_file(None)
+2 −2
Changes for PyAETNA/planet_phys.py: 2 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -2170,13 +2170,13 @@ def generate_physics_report(pickle_path, output_pdf, physics_config, log_file=No
        Path to the main log file (shared with sampler and reports steps).
    """
    from .reporting import (
        load_numpyro_results, _get_logger, set_log_file,
        load_numpyro_results,
        find_map_parameters, compute_mcmc_diagnostics,
    )
    from .logger import _log, set_log_file

    if log_file is not None:
        set_log_file(log_file)
    _log = _get_logger(log_file)

    _log("")
    _log("=" * 90)
+1 −7
Changes for PyAETNA/reporting/__init__.py: 1 added line, 7 removed lines.
Original line number Diff line number Diff line
# -*- coding: utf-8 -*-
# NOTE: `_log`/`_LOG_FILE` are intentionally NOT re-exported here. Both are
# rebound at runtime by `set_log_file()`, so importing them by value (e.g.
# `from PyAETNA.reporting import _log`) would silently capture a stale
# reference. Use `from PyAETNA.reporting import logger` and call
# `logger._log(...)`, or call `_get_logger(...)` for a fresh instance.
from .logger import set_log_file, _get_logger
from PyAETNA.logger import set_log_file, _log
from .map_search import (
    find_map_parameters,
    _evaluate_chain_endpoints,
+1 −3
Changes for PyAETNA/reporting/corner_plot.py: 1 added line, 3 removed lines.
Original line number Diff line number Diff line
@@ -8,9 +8,7 @@ from scipy.stats import truncnorm, norm, uniform, lognorm, gaussian_kde
from matplotlib.gridspec import GridSpec
from matplotlib.lines import Line2D

from . import logger
def _log(msg, level='INFO'):
    logger._log(msg, level=level)
from PyAETNA.logger import _log

def _rename_params_with_instrument_names(param_names, plModel=None):
    """
+1 −3
Changes for PyAETNA/reporting/diagnostics.py: 1 added line, 3 removed lines.
Original line number Diff line number Diff line
@@ -2,9 +2,7 @@
import numpy as np
from numpyro.diagnostics import effective_sample_size, split_gelman_rubin

from . import logger
def _log(msg, level='INFO'):
    logger._log(msg, level=level)
from PyAETNA.logger import _log

def compute_goodness_of_fit(residuals, dy, n_params, map_loglike=None):
    """
Loading