"""
@author: A. Falco
Logging module,
inspired from TauREX 3 (https://github.com/ucl-exoplanets/TauREx3_public/tree/master/taurex/log).
"""
import logging
from pytmosph3r.util.memory import MemoryUtils
from pytmosph3r.util.pkg_dir import pkg_dir
from pytmosph3r.util.util import get_attributes, get_methods
__all__ = ['Logger', 'root_logger']
root_logger = logging.getLogger('pytmosph3r')
root_logger.propagate = False
"""Root logger for pytmosph3r"""
rh = logging.StreamHandler()
formatter = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
rh.setFormatter(formatter)
rh.setLevel(logging.DEBUG)
root_logger.handlers = []
root_logger.addHandler(rh)
root_logger.setLevel(logging.INFO)
[docs]
class Logger(MemoryUtils):
"""
Standard logging using logger library
Parameters
-----------
name : str
Name used for logging
"""
verbose = 0
def __init__(self, name=None):
name = name if name is not None else self.__class__.__name__
self._log_name = f'pytmosph3r.{name}'
self._logger = logging.getLogger(f'pytmosph3r.{name}')
self.filename = None
[docs]
def info(self, message, *args, **kwargs):
""" See :class:`logging.Logger` """
self._logger.info(message, *args, **kwargs)
[docs]
def warning(self, message, *args, **kwargs):
""" See :class:`logging.Logger` """
self._logger.warning(message, *args, **kwargs)
[docs]
def debug(self, message, *args, **kwargs):
""" See :class:`logging.Logger` """
self._logger.debug(message, *args, **kwargs)
[docs]
def error(self, message, *args, **kwargs):
""" See :class:`logging.Logger` """
self._logger.error(message, *args, **kwargs)
[docs]
def critical(self, message, *args, **kwargs):
""" See :class:`logging.Logger` """
self._logger.critical(message, *args, **kwargs)
[docs]
def isEnabledFor(self, level):
return self._logger.isEnabledFor(level)
[docs]
def search_path(self, filename):
"""Search for filename in current folder, then in :attr:`~pytmosph3r.relative_dir`, and finally in the `examples/` folder of the `pytmosph3r` code. It then set the attribute :attr:`filename` to its path.
"""
self.filename = None
if filename:
import os
self.filename = filename
if not os.path.isfile(filename):
import pytmosph3r as p3
self.filename = os.path.realpath(os.path.join(pkg_dir.relative_dir, filename))
if os.path.exists(self.filename):
self.warning(f"File ./{filename} doesn't exist. Using {self.filename}")
else:
relative_filename = self.filename
self.filename = os.path.realpath(os.path.join(pkg_dir.root_dir, "examples", filename))
if os.path.exists(self.filename):
self.warning(
f"File ./{filename} and {relative_filename} don't exist. Using {self.filename}")
else:
raise IOError(f"Couldn't find file {filename}")
return self.filename
[docs]
def summary(self):
"""Prints all attributes and values of object. WARNING: could be verbose."""
return get_attributes(self)
def __repr__(self) -> str:
if not ("inputs" in get_methods(self) or "outputs" in get_methods(self)):
return super().__repr__()
msg = " " + self.__class__.__name__ + "()\n"
if "inputs" in get_methods(self):
msg += f"- Inputs: {self.inputs()}\n"
if "outputs" in get_methods(self):
msg += f"- Outputs: {self.outputs()}\n"
msg += f"- Methods: {get_methods(self)}\n"
return msg