Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set default logger to stdout and add output directory setting option for file loggers #139

Merged
merged 8 commits into from
Dec 30, 2024
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## latest

- Set default logger to stdout and add output directory setting option for file loggers https://github.com/precice/micro-manager/pull/139
- Remove the `adaptivity_data` data structure and handle all adaptivity data internally https://github.com/precice/micro-manager/pull/137
- Improve logging by wrapping Python logger in a class https://github.com/precice/micro-manager/pull/133
- Refactor large parts of solve and adaptivity to group datasets and simplify handling https://github.com/precice/micro-manager/pull/135
Expand Down
15 changes: 12 additions & 3 deletions micro_manager/adaptivity/adaptivity.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from math import exp
from typing import Callable
from warnings import warn
import subprocess
from micro_manager.tools.logging_wrapper import Logger

import numpy as np
Expand Down Expand Up @@ -37,9 +38,17 @@ def __init__(self, configurator, rank) -> None:
configurator.get_adaptivity_similarity_measure()
)

self._metrics_logger = Logger(
"Adaptivity", "adaptivity-metrics.csv", rank, csv_logger=True
)
output_dir = configurator.get_output_dir()

if output_dir is not None:
subprocess.run(["mkdir", "-p", output_dir]) # Create output directory
self._metrics_logger = Logger(
__name__, output_dir + "/adaptivity-metrics.csv", rank, csv_logger=True
)
else:
self._metrics_logger = Logger(
__name__, "adaptivity-metrics.csv", rank=rank, csv_logger=True
)

self._metrics_logger.log_info_one_rank(
"Time Window,Avg Active Sims,Avg Inactive Sims,Max Active,Max Inactive"
Expand Down
20 changes: 20 additions & 0 deletions micro_manager/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ def __init__(self, config_file_name):
self._postprocessing_file_name = None
self._initialize_once = False

self._output_dir = None

def set_logger(self, logger):
"""
Set the logger for the Config class.
Expand Down Expand Up @@ -91,6 +93,13 @@ def _read_json(self, config_file_name):
.replace(".py", "")
)

try:
self._output_dir = self._data["output_dir"]
except BaseException:
self._logger.log_info_one_rank(
"No output directory provided. Output (including logging) will be saved in the current working directory."
)

try:
self._write_data_names = self._data["coupling_params"]["write_data_names"]
assert isinstance(
Expand Down Expand Up @@ -640,3 +649,14 @@ def create_single_sim_object(self):
True if initialization is done only once, False otherwise.
"""
return self._initialize_once

def get_output_dir(self):
"""
Get the name of the output directory.

Returns
-------
output_dir : string
Name of the output folder.
"""
return self._output_dir
4 changes: 1 addition & 3 deletions micro_manager/micro_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ def __init__(self, config_file: str) -> None:
"""
super().__init__(config_file)

self._logger = Logger(
"MicroManagerCoupling", "micro-manager-coupling.log", self._rank
)
self._logger = Logger(__name__, None, self._rank)

self._config.set_logger(self._logger)
self._config.read_json_micro_manager()
Expand Down
18 changes: 13 additions & 5 deletions micro_manager/tools/logging_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
Provides a logging wrapper for the Micro Manager classes.
"""
import logging
import sys


class Logger:
"""
Provides a logging wrapper for the Micro Manager classes.
"""

def __init__(self, name, log_file, rank=0, level=logging.INFO, csv_logger=False):
def __init__(
self, name, log_file=None, rank=0, level=logging.INFO, csv_logger=False
):
"""
Set up a logger.

Expand All @@ -19,7 +22,7 @@ def __init__(self, name, log_file, rank=0, level=logging.INFO, csv_logger=False)
name : string
Name of the logger.
log_file : string
Name of the log file.
Name of the log file (default is None).
rank : int, optional
Rank of the logger (default is 0).
level : int, optional
Expand All @@ -30,16 +33,21 @@ def __init__(self, name, log_file, rank=0, level=logging.INFO, csv_logger=False)

self._rank = rank

handler = logging.FileHandler(log_file)
if log_file is None:
handler = logging.StreamHandler(sys.stdout)
else:
handler = logging.FileHandler(log_file)

handler.setLevel(level)

if csv_logger:
formatter = logging.Formatter("%(message)s")
else:
formatter = logging.Formatter(
"["
"("
+ str(self._rank)
+ "] %(asctime)s - %(name)s - %(levelname)s - %(message)s"
+ ") %(asctime)s - %(name)s - %(levelname)s - %(message)s",
datefmt="%m/%d/%Y %I:%M:%S %p",
)

handler.setFormatter(formatter)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"micro_file_name": "micro_dummy",
"output_dir": "adaptivity_output",
"coupling_params": {
"precice_config_file_name": "precice-config.xml",
"macro_mesh_name": "macro-cube-mesh",
Expand Down
5 changes: 5 additions & 0 deletions tests/unit/test_adaptivity_parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ def test_update_inactive_sims_global_adaptivity(self):

configurator = MagicMock()
configurator.get_adaptivity_similarity_measure = MagicMock(return_value="L1")
configurator.get_output_dir = MagicMock(return_value="output_dir")

adaptivity_controller = GlobalAdaptivityCalculator(
configurator, 5, global_ids, rank=self._rank, comm=self._comm
)
Expand Down Expand Up @@ -108,6 +110,7 @@ def test_update_all_active_sims_global_adaptivity(self):
configurator.get_adaptivity_refining_const = MagicMock(return_value=0.05)
configurator.get_adaptivity_coarsening_const = MagicMock(return_value=0.2)
configurator.get_adaptivity_similarity_measure = MagicMock(return_value="L2rel")
configurator.get_output_dir = MagicMock(return_value="output_dir")

adaptivity_controller = GlobalAdaptivityCalculator(
configurator, 5, global_ids, rank=self._rank, comm=self._comm
Expand Down Expand Up @@ -175,6 +178,8 @@ def test_communicate_micro_output(self):

configurator = MagicMock()
configurator.get_adaptivity_similarity_measure = MagicMock(return_value="L1")
configurator.get_output_dir = MagicMock(return_value="output_dir")

adaptivity_controller = GlobalAdaptivityCalculator(
configurator, 5, global_ids, rank=self._rank, comm=self._comm
)
Expand Down
8 changes: 8 additions & 0 deletions tests/unit/test_adaptivity_serial.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ def test_get_similarity_dists(self):
"""
configurator = MagicMock()
configurator.get_adaptivity_similarity_measure = MagicMock(return_value="L1")
configurator.get_output_dir = MagicMock(return_value="output_dir")

adaptivity_controller = AdaptivityCalculator(configurator, 0)
adaptivity_controller._hist_param = 0.5
adaptivity_controller._adaptivity_data_names = [
Expand Down Expand Up @@ -102,6 +104,8 @@ def test_update_active_sims(self):
"""
configurator = MagicMock()
configurator.get_adaptivity_similarity_measure = MagicMock(return_value="L1")
configurator.get_output_dir = MagicMock(return_value="output_dir")

adaptivity_controller = AdaptivityCalculator(configurator, 0)
adaptivity_controller._refine_const = self._refine_const
adaptivity_controller._coarse_const = self._coarse_const
Expand Down Expand Up @@ -208,6 +212,8 @@ def test_associate_active_to_inactive(self):
"""
configurator = MagicMock()
configurator.get_adaptivity_similarity_measure = MagicMock(return_value="L1")
configurator.get_output_dir = MagicMock(return_value="output_dir")

adaptivity_controller = AdaptivityCalculator(configurator, 0)
adaptivity_controller._refine_const = self._refine_const
adaptivity_controller._coarse_const = self._coarse_const
Expand Down Expand Up @@ -235,6 +241,8 @@ def test_update_inactive_sims_local_adaptivity(self):
"""
configurator = MagicMock()
configurator.get_adaptivity_similarity_measure = MagicMock(return_value="L1")
configurator.get_output_dir = MagicMock(return_value="output_dir")

adaptivity_controller = LocalAdaptivityCalculator(
configurator, 0, MagicMock(), 5
)
Expand Down
Loading