From 6f64b0bcb1e6b9226fb1cebc9a29db9964117ddb Mon Sep 17 00:00:00 2001 From: Romain Baville Date: Tue, 3 Mar 2026 17:56:29 +0100 Subject: [PATCH] Update logger managment --- .../pv/plugins/qc/PVPythonViewConfigurator.py | 61 ++++++++++++++++--- .../pv/pythonViewUtils/Figure2DGenerator.py | 26 +++----- .../functionsFigure2DGenerator.py | 9 ++- .../geos/pv/pythonViewUtils/mainPythonView.py | 14 +---- 4 files changed, 68 insertions(+), 42 deletions(-) diff --git a/geos-pv/src/geos/pv/plugins/qc/PVPythonViewConfigurator.py b/geos-pv/src/geos/pv/plugins/qc/PVPythonViewConfigurator.py index d9ca58266..8e875aa52 100755 --- a/geos-pv/src/geos/pv/plugins/qc/PVPythonViewConfigurator.py +++ b/geos-pv/src/geos/pv/plugins/qc/PVPythonViewConfigurator.py @@ -3,6 +3,7 @@ # SPDX-FileContributor: Alexandre Benedicto, Martin Lemay # ruff: noqa: E402 # disable Module level import not at top of file import sys +import logging from pathlib import Path from typing import Any, Union, cast @@ -17,6 +18,7 @@ update_paths() from geos.mesh.utils.multiblockModifiers import mergeBlocks +from geos.utils.Logger import ( CountVerbosityHandler, getLoggerHandlerType ) import geos.pv.utils.paraviewTreatments as pvt from geos.pv.utils.checkboxFunction import createModifiedCallback # type: ignore[attr-defined] from geos.pv.utils.DisplayOrganizationParaview import DisplayOrganizationParaview @@ -28,6 +30,11 @@ GetActiveSource, GetActiveView, Render, Show, servermanager ) from paraview.util.vtkAlgorithm import VTKPythonAlgorithmBase, smdomain, smproperty # type: ignore[import-not-found] # source: https://github.com/Kitware/ParaView/blob/master/Wrapping/Python/paraview/util/vtkAlgorithm.py +from paraview.detail.loghandler import ( # type: ignore[import-not-found] + VTKHandler, +) # source: https://github.com/Kitware/ParaView/blob/master/Wrapping/Python/paraview/detail/loghandler.py + + from vtkmodules.vtkCommonCore import vtkDataArraySelection, vtkInformation from vtkmodules.vtkCommonDataModel import vtkDataObject, vtkMultiBlockDataSet @@ -50,6 +57,9 @@ """ +loggerTitle: str = "Python View Configurator" +HANDLER: VTKHandler = VTKHandler() + @SISOFilter( category=FilterCategory.QC, decoratedLabel="Python View Configurator", @@ -61,7 +71,6 @@ def __init__( self: Self ) -> None: Input is a vtkDataObject. """ - # super().__init__( nInputPorts=1, nOutputPorts=1 ) # Python view layout and object. self.m_layoutName: str = "" self.m_pythonView: Any @@ -139,6 +148,23 @@ def __init__( self: Self ) -> None: "curvesAspect": {}, } + self.logger = logging.getLogger( loggerTitle ) + self.logger.setLevel( logging.INFO ) + self.logger.addHandler( HANDLER ) + self.logger.propagate = False + + counter: CountVerbosityHandler = CountVerbosityHandler() + self.counter: CountVerbosityHandler + self.nbWarnings: int = 0 + try: + self.counter = getLoggerHandlerType( type( counter ), self.logger ) + self.counter.resetWarningCount() + except ValueError: + self.counter = counter + self.counter.setLevel( logging.INFO ) + + self.logger.addHandler( self.counter ) + def getUserChoices( self: Self ) -> dict[ str, Any ]: """Access the m_userChoices attribute. @@ -808,12 +834,29 @@ def ApplyFilter( self, inputMesh: vtkDataObject, outputMesh: vtkDataObject ) -> outputMesh : A dummy mesh transformed. """ - assert self.m_pythonView is not None, "No Python View was found." - viewSize = GetActiveView().ViewSize - self.m_userChoices[ "ratio" ] = viewSize[ 0 ] / viewSize[ 1 ] - self.defineInputNames() - self.defineUserChoicesCurves() - self.defineCurvesAspect() - self.m_pythonView.Script = self.buildPythonViewScript() - Render() + self.logger.info( f"Apply the plugin { self.logger.name }." ) + try: + if self.m_pythonView is None: + raise ValueError( "No Python View was found." ) + + viewSize = GetActiveView().ViewSize + self.m_userChoices[ "ratio" ] = viewSize[ 0 ] / viewSize[ 1 ] + self.defineInputNames() + self.defineUserChoicesCurves() + self.defineCurvesAspect() + self.m_pythonView.Script = self.buildPythonViewScript() + Render() + + result: str = f"The plugin { self.logger.name } succeeded" + if self.counter.warningCount > 0: + self.logger.warning( f"{ result } but { self.counter.warningCount } warnings have been logged." ) + else: + self.logger.info( f"{ result }." ) + except Exception as e: + self.logger.error( f"The plugin failed due to:\n{ e }" ) + return + + self.nbWarnings = self.counter.warningCount + self.counter.resetWarningCount() + return diff --git a/geos-pv/src/geos/pv/pythonViewUtils/Figure2DGenerator.py b/geos-pv/src/geos/pv/pythonViewUtils/Figure2DGenerator.py index 00eceded7..f3d41fb48 100755 --- a/geos-pv/src/geos/pv/pythonViewUtils/Figure2DGenerator.py +++ b/geos-pv/src/geos/pv/pythonViewUtils/Figure2DGenerator.py @@ -1,7 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright 2023-2024 TotalEnergies. # SPDX-FileContributor: Alexandre Benedicto -from logging import Logger from typing import Any import pandas as pd # type: ignore[import-untyped] @@ -16,7 +15,7 @@ class Figure2DGenerator: - def __init__( self: Self, dataframe: pd.DataFrame, userChoices: dict[ str, list[ str ] ], logger: Logger ) -> None: + def __init__( self: Self, dataframe: pd.DataFrame, userChoices: dict[ str, list[ str ] ] ) -> None: """Utility to create cross plots using Python View. We want to plot f(X) = Y where in this class, @@ -25,7 +24,6 @@ def __init__( self: Self, dataframe: pd.DataFrame, userChoices: dict[ str, list[ Args: dataframe (pd.DataFrame): Data to plot. userChoices (dict[str, list[str]]): User choices. - logger (Logger): Logger to use. """ self.m_dataframe: pd.DataFrame = dataframe self.m_userChoices: dict[ str, Any ] = userChoices @@ -33,21 +31,13 @@ def __init__( self: Self, dataframe: pd.DataFrame, userChoices: dict[ str, list[ self.m_axes: list[ axes._axes.Axes ] = [] self.m_lines: list[ lines.Line2D ] = [] self.m_labels: list[ str ] = [] - self.m_logger: Logger = logger - - try: - # Apply minus 1 multiplication on certain columns. - self.initMinus1Multiplication() - # Defines m_fig, m_axes, m_lines and m_labels. - self.plotInitialFigure() - # Then to edit and customize the figure. - self.enhanceFigure() - self.m_logger.info( "Data were successfully plotted." ) - - except Exception as e: - mess: str = "Plot creation failed due to:" - self.m_logger.critical( mess ) - self.m_logger.critical( e, exc_info=True ) + + # Apply minus 1 multiplication on certain columns. + self.initMinus1Multiplication() + # Defines m_fig, m_axes, m_lines and m_labels. + self.plotInitialFigure() + # Then to edit and customize the figure. + self.enhanceFigure() def initMinus1Multiplication( self: Self ) -> None: """Multiply by -1 certain columns of the input dataframe.""" diff --git a/geos-pv/src/geos/pv/pythonViewUtils/functionsFigure2DGenerator.py b/geos-pv/src/geos/pv/pythonViewUtils/functionsFigure2DGenerator.py index 113953416..167d6d884 100755 --- a/geos-pv/src/geos/pv/pythonViewUtils/functionsFigure2DGenerator.py +++ b/geos-pv/src/geos/pv/pythonViewUtils/functionsFigure2DGenerator.py @@ -292,7 +292,8 @@ def setupAllAxes( first_ax.ticklabel_format( style="sci", axis="x", scilimits=( 0, 0 ), useMathText=True ) for i in range( 1, len( associatedProperties.keys() ) ): second_ax = first_ax.twinx() - assert isinstance( second_ax, axes.Axes ) + if not isinstance( second_ax, axes.Axes ): + raise TypeError( "The second ax has not the right type.") all_ax.append( second_ax ) all_ax[ i ].spines[ "right" ].set_position( ( "axes", 1 + 0.07 * ( i - 1 ) ) ) all_ax[ i ].tick_params( axis="y", which="both", left=False, right=True ) @@ -304,7 +305,8 @@ def setupAllAxes( first_ax.ticklabel_format( style="sci", axis="y", scilimits=( 0, 0 ), useMathText=True ) for i in range( 1, len( associatedProperties.keys() ) ): second_ax = first_ax.twiny() - assert isinstance( second_ax, axes.Axes ) + if not isinstance( second_ax, axes.Axes ): + raise TypeError( "The second ax has not the right type.") all_ax.append( second_ax ) all_ax[ i ].spines[ "bottom" ].set_position( ( "axes", -0.08 * i ) ) all_ax[ i ].xaxis.set_label_position( "bottom" ) @@ -383,7 +385,8 @@ def getExtremaAllAxes( axes: list[ axes.Axes ], ) -> tuple[ tuple[ float, float Returns: tuple[tuple[float, float], tuple[float, float]]: ((xMin, xMax), (yMin, yMax)) """ - assert len( axes ) > 0 + if len( axes ) <= 0: + raise ValueError( "The list of axes can not be empty.") xMin, xMax, yMin, yMax = getAxeLimits( axes[ 0 ] ) if len( axes ) > 1: for i in range( 1, len( axes ) ): diff --git a/geos-pv/src/geos/pv/pythonViewUtils/mainPythonView.py b/geos-pv/src/geos/pv/pythonViewUtils/mainPythonView.py index bc7e78189..1909a0ede 100755 --- a/geos-pv/src/geos/pv/pythonViewUtils/mainPythonView.py +++ b/geos-pv/src/geos/pv/pythonViewUtils/mainPythonView.py @@ -3,16 +3,6 @@ # SPDX-FileContributor: Alexandre Benedicto # type: ignore # ruff: noqa -from logging import Logger, getLogger, INFO -from paraview.detail.loghandler import ( # type: ignore[import-not-found] - VTKHandler, -) # source: https://github.com/Kitware/ParaView/blob/master/Wrapping/Python/paraview/detail/loghandler.py - -logger: Logger = getLogger( "Python View Configurator" ) -logger.setLevel( INFO ) -vtkHandler: VTKHandler = VTKHandler() -logger.addHandler( vtkHandler ) - try: import matplotlib.pyplot as plt from paraview import python_view @@ -30,7 +20,7 @@ variableName # noqa: F821 ) dataframe = pvt.mergeDataframes( dataframes, variableName ) # noqa: F821 - obj_figure = Figure2DGenerator( dataframe, userChoices, logger ) # noqa: F821 + obj_figure = Figure2DGenerator( dataframe, userChoices ) # noqa: F821 fig = obj_figure.getFigure() def setup_data( view ) -> None: # noqa @@ -42,4 +32,4 @@ def render( view, width: int, height: int ): # noqa return imageToReturn except Exception as e: - logger.critical( e, exc_info=True ) + raise ChildProcessError( f"Error during the plot:\n{ e }" ) from e