From 1a573227268ebe02326f277a37c1c0790d8660eb Mon Sep 17 00:00:00 2001 From: jacques franc Date: Tue, 16 Sep 2025 15:02:40 +0200 Subject: [PATCH 01/20] wip --- .../geos/pv/plugins/PVFillPartialArrays.py | 37 ++++----- geos-pv/src/geos/pv/utils/details.py | 79 +++++++++++++++++++ 2 files changed, 98 insertions(+), 18 deletions(-) create mode 100644 geos-pv/src/geos/pv/utils/details.py diff --git a/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py b/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py index 218d6bfc0..c98c82a7c 100644 --- a/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py +++ b/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py @@ -30,7 +30,7 @@ update_paths() from geos.mesh.processing.FillPartialArrays import FillPartialArrays - +import geos.pv.utils.details __doc__ = """ Fill partial arrays of input mesh. @@ -47,21 +47,22 @@ """ -@smproxy.filter( name="PVFillPartialArrays", label="Fill Partial Arrays" ) -@smhint.xml( '' ) -@smproperty.input( name="Input", port_index=0 ) -@smdomain.datatype( - dataTypes=[ "vtkMultiBlockDataSet" ], - composite_data_supported=True, -) -class PVFillPartialArrays( VTKPythonAlgorithmBase ): +# @smproxy.filter( name="PVFillPartialArrays", label="Fill Partial Arrays" ) +# @smhint.xml( '' ) +# @smproperty.input( name="Input", port_index=0 ) +# @smdomain.datatype( +# dataTypes=[ "vtkMultiBlockDataSet" ], +# composite_data_supported=True, +# ) +@geos.pv.utils.details.SISOFilter(decorated_name="PVFillPartialArrays", decorated_label="Fill Partial Arrays",decorated_type="vtkMultiBlockDataSet") +class PVFillPartialArrays: def __init__( self: Self, ) -> None: """Fill a partial attribute with constant value per component.""" - super().__init__( nInputPorts=1, - nOutputPorts=1, - inputType="vtkMultiBlockDataSet", - outputType="vtkMultiBlockDataSet" ) + # super().__init__( nInputPorts=1, + # nOutputPorts=1, + # inputType="vtkMultiBlockDataSet", + # outputType="vtkMultiBlockDataSet" ) self.clearDictAttributesValues: bool = True self.dictAttributesValues: dict[ str, Union[ list[ Any ], None ] ] = {} @@ -99,13 +100,13 @@ def _setDictAttributesValues( self: Self, attributeName: str, values: str ) -> N if self.clearDictAttributesValues: self.dictAttributesValues = {} self.clearDictAttributesValues = False - + if attributeName is not None: if values is not None : self.dictAttributesValues[ attributeName ] = list( values.split( "," ) ) else: self.dictAttributesValues[ attributeName ] = None - + self.Modified() def RequestDataObject( @@ -156,13 +157,13 @@ def RequestData( outputMesh.ShallowCopy( inputMesh ) filter: FillPartialArrays = FillPartialArrays( outputMesh, - self.dictAttributesValues, + self.dictAttributesValues, True, ) - + if not filter.logger.hasHandlers(): filter.setLoggerHandler( VTKHandler() ) - + filter.applyFilter() self.clearDictAttributesValues = True diff --git a/geos-pv/src/geos/pv/utils/details.py b/geos-pv/src/geos/pv/utils/details.py new file mode 100644 index 000000000..97fd45f44 --- /dev/null +++ b/geos-pv/src/geos/pv/utils/details.py @@ -0,0 +1,79 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: Copyright 2023-2024 TotalEnergies. +# SPDX-FileContributor: Martin Lemay, Romain Baville +# ruff: noqa: E402 # disable Module level import not at top of file +import sys +from pathlib import Path +from typing import Union, Any +from typing_extensions import Self + +# from functools import wraps +# from dataclasses import dataclass + +from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] + VTKPythonAlgorithmBase, smdomain, smhint, smproperty, smproxy, +) # 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.vtkCommonDataModel import ( + vtkMultiBlockDataSet, ) + +from vtkmodules.vtkCommonCore import ( + vtkInformation, + vtkInformationVector, +) + +# update sys.path to load all GEOS Python Package dependencies +geos_pv_path: Path = Path( __file__ ).parent.parent.parent.parent.parent +sys.path.insert( 0, str( geos_pv_path / "src" ) ) +from geos.pv.utils.config import update_paths + +update_paths() + +__doc__ = """ +Set of decorators that allow: + - quicker generation of MultiBlockDataSet to MultiBlockDataSet filters + - more stable logger strategy + +Usage is: + + @SISO(name='MyFilter',label='This is my filter',dtype='vtkMultiBlockDataSet') + class PVMyFilter: + ... + def __hidden_layer(self): + + +""" + +def SISOFilter(decorated_name, decorated_label, decorated_type): + """ + Decorate single input single output filter + """ + def decorated_class(cls): + @smproxy.filter( name=decorated_name, label=decorated_label ) + @smhint.xml( '' ) + @smproperty.input( name="Input", port_index=0 ) + @smdomain.datatype( + dataTypes=[ decorated_type ], + composite_data_supported=True, + ) + # @dataclass + # class WrappingClass(cls): + class WrappingClass(cls,VTKPythonAlgorithmBase): + + def __init__(self,*ar,**kw): + VTKPythonAlgorithmBase.__init__(self, nInputPorts=1, + nOutputPorts=1, + inputType=decorated_type, + outputType=decorated_type ) + cls.___init__(self,*ar,**kw) + WrappingClass.__name__ = cls.__name__ + WrappingClass.__module__ = cls.__module__ + + return WrappingClass + return decorated_class + + + From 84c0ba865030318340d16150fd61fb433c1d456b Mon Sep 17 00:00:00 2001 From: jacques franc Date: Tue, 30 Sep 2025 18:21:51 +0200 Subject: [PATCH 02/20] PoC --- .../geos/mesh/processing/FillPartialArrays.py | 27 +-------- .../geos/pv/plugins/PVFillPartialArrays.py | 30 +++++----- geos-utils/src/geos/utils/details.py | 55 +++++++++++++++++++ 3 files changed, 73 insertions(+), 39 deletions(-) create mode 100644 geos-utils/src/geos/utils/details.py diff --git a/geos-mesh/src/geos/mesh/processing/FillPartialArrays.py b/geos-mesh/src/geos/mesh/processing/FillPartialArrays.py index 1810bc735..492a77db8 100644 --- a/geos-mesh/src/geos/mesh/processing/FillPartialArrays.py +++ b/geos-mesh/src/geos/mesh/processing/FillPartialArrays.py @@ -9,6 +9,7 @@ from geos.mesh.utils.arrayModifiers import fillPartialAttributes from geos.mesh.utils.arrayHelpers import getAttributePieceInfo +from geos.utils.details import addLogSupport from vtkmodules.vtkCommonDataModel import vtkMultiBlockDataSet __doc__ = """ @@ -51,13 +52,13 @@ loggerTitle: str = "Fill Partial Attribute" +@addLogSupport(loggerTitle= loggerTitle) class FillPartialArrays: def __init__( self: Self, multiBlockDataSet: vtkMultiBlockDataSet, dictAttributesValues: dict[ str, Union[ list[ Any ], None ] ], - speHandler: bool = False, ) -> None: """Fill partial attributes with constant value per component. @@ -75,30 +76,8 @@ def __init__( self.multiBlockDataSet: vtkMultiBlockDataSet = multiBlockDataSet self.dictAttributesValues: dict[ str, Union[ list[ Any ], None ] ] = dictAttributesValues - # Logger. - self.logger: Logger - if not speHandler: - self.logger = getLogger( loggerTitle, True ) - else: - self.logger = logging.getLogger( loggerTitle ) - self.logger.setLevel( logging.INFO ) - def setLoggerHandler( self: Self, handler: logging.Handler ) -> None: - """Set a specific handler for the filter logger. - - In this filter 4 log levels are use, .info, .error, .warning and .critical, be sure to have at least the same 4 levels. - - Args: - handler (logging.Handler): The handler to add. - """ - if not self.logger.hasHandlers(): - self.logger.addHandler( handler ) - else: - self.logger.warning( - "The logger already has an handler, to use yours set the argument 'speHandler' to True during the filter initialization." - ) - - def applyFilter( self: Self ) -> bool: + def applyFilter( self : Self ) -> bool: """Create a constant attribute per region in the mesh. Returns: diff --git a/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py b/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py index c98c82a7c..a8773bbd1 100644 --- a/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py +++ b/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py @@ -30,7 +30,7 @@ update_paths() from geos.mesh.processing.FillPartialArrays import FillPartialArrays -import geos.pv.utils.details +# import geos.pv.utils.details __doc__ = """ Fill partial arrays of input mesh. @@ -47,22 +47,22 @@ """ -# @smproxy.filter( name="PVFillPartialArrays", label="Fill Partial Arrays" ) -# @smhint.xml( '' ) -# @smproperty.input( name="Input", port_index=0 ) -# @smdomain.datatype( -# dataTypes=[ "vtkMultiBlockDataSet" ], -# composite_data_supported=True, -# ) -@geos.pv.utils.details.SISOFilter(decorated_name="PVFillPartialArrays", decorated_label="Fill Partial Arrays",decorated_type="vtkMultiBlockDataSet") -class PVFillPartialArrays: +@smproxy.filter( name="PVFillPartialArrays", label="Fill Partial Arrays" ) +@smhint.xml( '' ) +@smproperty.input( name="Input", port_index=0 ) +@smdomain.datatype( + dataTypes=[ "vtkMultiBlockDataSet" ], + composite_data_supported=True, +) +# @geos.pv.utils.details.SISOFilter(decorated_name="PVFillPartialArrays", decorated_label="Fill Partial Arrays",decorated_type="vtkMultiBlockDataSet") +class PVFillPartialArrays(VTKPythonAlgorithmBase): def __init__( self: Self, ) -> None: """Fill a partial attribute with constant value per component.""" - # super().__init__( nInputPorts=1, - # nOutputPorts=1, - # inputType="vtkMultiBlockDataSet", - # outputType="vtkMultiBlockDataSet" ) + super().__init__( nInputPorts=1, + nOutputPorts=1, + inputType="vtkMultiBlockDataSet", + outputType="vtkMultiBlockDataSet" ) self.clearDictAttributesValues: bool = True self.dictAttributesValues: dict[ str, Union[ list[ Any ], None ] ] = {} @@ -158,7 +158,7 @@ def RequestData( filter: FillPartialArrays = FillPartialArrays( outputMesh, self.dictAttributesValues, - True, + speHandler=True, ) if not filter.logger.hasHandlers(): diff --git a/geos-utils/src/geos/utils/details.py b/geos-utils/src/geos/utils/details.py new file mode 100644 index 000000000..cf6378e80 --- /dev/null +++ b/geos-utils/src/geos/utils/details.py @@ -0,0 +1,55 @@ +import logging +from geos.utils.Logger import Logger, getLogger +from functools import wraps +from typing import Type, TypeVar + + +__doc__ = """ + Decorators + +""" + +def addLogSupport(loggerTitle : str): + T = TypeVar('T') + def decorator(cls:Type[T]) -> Type[T]: + original_init = cls.__init__ + + @wraps(cls) + def new_init(self : T, *args, **kwargs): + + self.logger : Logger + + if kwargs.get('speHandler'): + kwargs.pop('speHandler') + self.logger = logging.getLogger( loggerTitle ) + self.logger.setLevel( logging.INFO ) + else: + self.logger = getLogger( loggerTitle, True) + + original_init(self,*args,*kwargs) + + @property + def logger(self : T)->Logger: + return self.logger + + def setLoggerHandler(self, handler : logging.Handler): + """Set a specific handler for the filter logger. + + In this filter 4 log levels are use, .info, .error, .warning and .critical, be sure to have at least the same 4 levels. + + Args: + handler (logging.Handler): The handler to add. + """ + if not self.logger.hasHandlers(): + self.logger.addHandler( handler ) + else: + self.logger.warning( + "The logger already has an handler, to use yours set the argument 'speHandler' to True during the filter initialization." + ) + + cls.__init__ = new_init + cls.setLoggerHandler = setLoggerHandler + + return cls + + return decorator \ No newline at end of file From f32fe2ec799b18138f61017bcf5a785fb4bdac4b Mon Sep 17 00:00:00 2001 From: jacques franc Date: Thu, 2 Oct 2025 10:24:07 +0200 Subject: [PATCH 03/20] decorator and precommit recipe --- .hooks/pre-commit.example | 20 ++++++++ geos-utils/src/geos/utils/details.py | 71 ++++++++++++++++------------ 2 files changed, 61 insertions(+), 30 deletions(-) create mode 100755 .hooks/pre-commit.example diff --git a/.hooks/pre-commit.example b/.hooks/pre-commit.example new file mode 100755 index 000000000..7c7dc461a --- /dev/null +++ b/.hooks/pre-commit.example @@ -0,0 +1,20 @@ +#!/bin/bash -e + +function run_precommit_checks +{ + python -m mypy --config-file ./.mypy.ini --check-untyped-defs $1 + python -m ruff check --unsafe-fixes --config .ruff.toml $1 + python -m yapf -r -i --style .style.yapf $1 + + return 0 +} + + +source ${ENV_PYTHON_PATH}/bin/activate + +sphinx-build -b html docs/ docs/_build -W +for file in $(git diff --name-only --cached | grep py) +do + run_precommit_checks $file +done + diff --git a/geos-utils/src/geos/utils/details.py b/geos-utils/src/geos/utils/details.py index cf6378e80..88bf7da00 100644 --- a/geos-utils/src/geos/utils/details.py +++ b/geos-utils/src/geos/utils/details.py @@ -1,55 +1,66 @@ import logging from geos.utils.Logger import Logger, getLogger from functools import wraps -from typing import Type, TypeVar - +from typing import Type, TypeVar, Callable, Protocol, Any __doc__ = """ - Decorators + Group of decorators and Protocols that will be used in filters to wrap behaviors without code replication """ -def addLogSupport(loggerTitle : str): - T = TypeVar('T') - def decorator(cls:Type[T]) -> Type[T]: - original_init = cls.__init__ - @wraps(cls) - def new_init(self : T, *args, **kwargs): +class HasLogger( Protocol ): + """Protocol for classes that have logging support.""" + + logger: Logger + + def setLoggerHandler( self, handler: logging.Handler ) -> None: + """Set a specific handler for the filter logger. + + In this filter 4 log levels are use, .info, .error, .warning and .critical, be sure to have at least the same 4 levels. + + Args: + handler (logging.Handler): The handler to add. + """ + pass + - self.logger : Logger +T = TypeVar( 'T', bound='HasLogger' ) - if kwargs.get('speHandler'): - kwargs.pop('speHandler') + +def addLogSupport( loggerTitle: str ) -> Callable[ [ Type[ T ] ], Type[ T ] ]: + """Decorator to add logger support in the class following existing architecture. + + Args: + loggerTitle (str): Title to display in the logger + """ + + def decorator( cls: Type[ T ] ) -> Type[ T ]: + original_init = cls.__init__ + + @wraps( original_init ) + def new_init( self: T, *args: Any, **kwargs: Any ) -> None: + spe_handler = kwargs.pop( 'speHandler', False ) + if spe_handler: self.logger = logging.getLogger( loggerTitle ) self.logger.setLevel( logging.INFO ) else: - self.logger = getLogger( loggerTitle, True) - - original_init(self,*args,*kwargs) - - @property - def logger(self : T)->Logger: - return self.logger - - def setLoggerHandler(self, handler : logging.Handler): - """Set a specific handler for the filter logger. + self.logger = getLogger( loggerTitle, True ) - In this filter 4 log levels are use, .info, .error, .warning and .critical, be sure to have at least the same 4 levels. + original_init( self, *args, **kwargs ) - Args: - handler (logging.Handler): The handler to add. - """ - if not self.logger.hasHandlers(): + def setLoggerHandler( self: T, handler: logging.Handler ) -> None: + # No docstring needed - Protocol defines the contract + if not self.logger.handlers: self.logger.addHandler( handler ) else: self.logger.warning( "The logger already has an handler, to use yours set the argument 'speHandler' to True during the filter initialization." ) - cls.__init__ = new_init - cls.setLoggerHandler = setLoggerHandler + cls.__init__ = new_init # type: ignore[assignment] + cls.setLoggerHandler = setLoggerHandler # type: ignore[assignment] return cls - return decorator \ No newline at end of file + return decorator From 6f6e65269824771b054dd529a2daf7815ac74144 Mon Sep 17 00:00:00 2001 From: jacques franc Date: Thu, 2 Oct 2025 10:55:15 +0200 Subject: [PATCH 04/20] clean up --- .hooks/pre-commit.example | 9 ++- .../geos/pv/plugins/PVFillPartialArrays.py | 25 +++--- geos-pv/src/geos/pv/utils/details.py | 79 ------------------- 3 files changed, 18 insertions(+), 95 deletions(-) delete mode 100644 geos-pv/src/geos/pv/utils/details.py diff --git a/.hooks/pre-commit.example b/.hooks/pre-commit.example index 7c7dc461a..f4f188d77 100755 --- a/.hooks/pre-commit.example +++ b/.hooks/pre-commit.example @@ -2,18 +2,21 @@ function run_precommit_checks { + echo "running mypy" python -m mypy --config-file ./.mypy.ini --check-untyped-defs $1 + echo "running ruff" python -m ruff check --unsafe-fixes --config .ruff.toml $1 + echo "running yapf" python -m yapf -r -i --style .style.yapf $1 return 0 } -source ${ENV_PYTHON_PATH}/bin/activate +source ${ENV_PYTHON}/bin/activate -sphinx-build -b html docs/ docs/_build -W -for file in $(git diff --name-only --cached | grep py) +#sphinx-build -b html docs/ docs/_build -W +for file in $(git diff --name-only --cached | grep -e "modified\|added" | grep py) do run_precommit_checks $file done diff --git a/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py b/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py index a8773bbd1..b6b89272a 100644 --- a/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py +++ b/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py @@ -9,10 +9,10 @@ from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] VTKPythonAlgorithmBase, smdomain, smhint, smproperty, smproxy, -) # source: https://github.com/Kitware/ParaView/blob/master/Wrapping/Python/paraview/util/vtkAlgorithm.py +) # 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 +) # source: https://github.com/Kitware/ParaView/blob/master/Wrapping/Python/paraview/detail/loghandler.py from vtkmodules.vtkCommonDataModel import ( vtkMultiBlockDataSet, ) @@ -30,7 +30,7 @@ update_paths() from geos.mesh.processing.FillPartialArrays import FillPartialArrays -# import geos.pv.utils.details + __doc__ = """ Fill partial arrays of input mesh. @@ -54,8 +54,7 @@ dataTypes=[ "vtkMultiBlockDataSet" ], composite_data_supported=True, ) -# @geos.pv.utils.details.SISOFilter(decorated_name="PVFillPartialArrays", decorated_label="Fill Partial Arrays",decorated_type="vtkMultiBlockDataSet") -class PVFillPartialArrays(VTKPythonAlgorithmBase): +class PVFillPartialArrays( VTKPythonAlgorithmBase ): def __init__( self: Self, ) -> None: """Fill a partial attribute with constant value per component.""" @@ -67,8 +66,7 @@ def __init__( self: Self, ) -> None: self.clearDictAttributesValues: bool = True self.dictAttributesValues: dict[ str, Union[ list[ Any ], None ] ] = {} - - @smproperty.xml(""" + @smproperty.xml( """ None: attributeName | fillingValueComponent1 fillingValueComponent2 ...\n To fill the attribute with the default value, live a blanc. The default value is:\n 0 for uint type, -1 for int type and nan for float type. - + @@ -102,10 +100,10 @@ def _setDictAttributesValues( self: Self, attributeName: str, values: str ) -> N self.clearDictAttributesValues = False if attributeName is not None: - if values is not None : + if values is not None: self.dictAttributesValues[ attributeName ] = list( values.split( "," ) ) else: - self.dictAttributesValues[ attributeName ] = None + self.dictAttributesValues[ attributeName ] = None # type: ignore[unreachable] self.Modified() @@ -156,9 +154,10 @@ def RequestData( outputMesh.ShallowCopy( inputMesh ) - filter: FillPartialArrays = FillPartialArrays( outputMesh, - self.dictAttributesValues, - speHandler=True, + filter: FillPartialArrays = FillPartialArrays( + outputMesh, + self.dictAttributesValues, + speHandler=True, ) if not filter.logger.hasHandlers(): diff --git a/geos-pv/src/geos/pv/utils/details.py b/geos-pv/src/geos/pv/utils/details.py deleted file mode 100644 index 97fd45f44..000000000 --- a/geos-pv/src/geos/pv/utils/details.py +++ /dev/null @@ -1,79 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# SPDX-FileCopyrightText: Copyright 2023-2024 TotalEnergies. -# SPDX-FileContributor: Martin Lemay, Romain Baville -# ruff: noqa: E402 # disable Module level import not at top of file -import sys -from pathlib import Path -from typing import Union, Any -from typing_extensions import Self - -# from functools import wraps -# from dataclasses import dataclass - -from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] - VTKPythonAlgorithmBase, smdomain, smhint, smproperty, smproxy, -) # 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.vtkCommonDataModel import ( - vtkMultiBlockDataSet, ) - -from vtkmodules.vtkCommonCore import ( - vtkInformation, - vtkInformationVector, -) - -# update sys.path to load all GEOS Python Package dependencies -geos_pv_path: Path = Path( __file__ ).parent.parent.parent.parent.parent -sys.path.insert( 0, str( geos_pv_path / "src" ) ) -from geos.pv.utils.config import update_paths - -update_paths() - -__doc__ = """ -Set of decorators that allow: - - quicker generation of MultiBlockDataSet to MultiBlockDataSet filters - - more stable logger strategy - -Usage is: - - @SISO(name='MyFilter',label='This is my filter',dtype='vtkMultiBlockDataSet') - class PVMyFilter: - ... - def __hidden_layer(self): - - -""" - -def SISOFilter(decorated_name, decorated_label, decorated_type): - """ - Decorate single input single output filter - """ - def decorated_class(cls): - @smproxy.filter( name=decorated_name, label=decorated_label ) - @smhint.xml( '' ) - @smproperty.input( name="Input", port_index=0 ) - @smdomain.datatype( - dataTypes=[ decorated_type ], - composite_data_supported=True, - ) - # @dataclass - # class WrappingClass(cls): - class WrappingClass(cls,VTKPythonAlgorithmBase): - - def __init__(self,*ar,**kw): - VTKPythonAlgorithmBase.__init__(self, nInputPorts=1, - nOutputPorts=1, - inputType=decorated_type, - outputType=decorated_type ) - cls.___init__(self,*ar,**kw) - WrappingClass.__name__ = cls.__name__ - WrappingClass.__module__ = cls.__module__ - - return WrappingClass - return decorated_class - - - From 5437cc04940fcd39d6c4122e4b154934e44c3aa7 Mon Sep 17 00:00:00 2001 From: jacques franc Date: Thu, 2 Oct 2025 11:09:36 +0200 Subject: [PATCH 05/20] yapf uncommited --- geos-mesh/src/geos/mesh/processing/FillPartialArrays.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/geos-mesh/src/geos/mesh/processing/FillPartialArrays.py b/geos-mesh/src/geos/mesh/processing/FillPartialArrays.py index 492a77db8..0f048c861 100644 --- a/geos-mesh/src/geos/mesh/processing/FillPartialArrays.py +++ b/geos-mesh/src/geos/mesh/processing/FillPartialArrays.py @@ -52,7 +52,7 @@ loggerTitle: str = "Fill Partial Attribute" -@addLogSupport(loggerTitle= loggerTitle) +@addLogSupport( loggerTitle=loggerTitle ) class FillPartialArrays: def __init__( @@ -76,8 +76,7 @@ def __init__( self.multiBlockDataSet: vtkMultiBlockDataSet = multiBlockDataSet self.dictAttributesValues: dict[ str, Union[ list[ Any ], None ] ] = dictAttributesValues - - def applyFilter( self : Self ) -> bool: + def applyFilter( self: Self ) -> bool: """Create a constant attribute per region in the mesh. Returns: From 0f6c3d4045c2d32bad999200dff81b8f450643bd Mon Sep 17 00:00:00 2001 From: jacques franc Date: Fri, 3 Oct 2025 15:35:24 +0200 Subject: [PATCH 06/20] docs corrections --- geos-mesh/src/geos/mesh/processing/FillPartialArrays.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/geos-mesh/src/geos/mesh/processing/FillPartialArrays.py b/geos-mesh/src/geos/mesh/processing/FillPartialArrays.py index 0f048c861..b70335374 100644 --- a/geos-mesh/src/geos/mesh/processing/FillPartialArrays.py +++ b/geos-mesh/src/geos/mesh/processing/FillPartialArrays.py @@ -70,8 +70,6 @@ def __init__( Args: multiBlockDataSet (vtkMultiBlockDataSet): The mesh where to fill the attribute. dictAttributesValues (dict[str, Any]): The dictionary with the attribute to fill as keys and the list of filling values as items. - speHandler (bool, optional): True to use a specific handler, False to use the internal handler. - Defaults to False. """ self.multiBlockDataSet: vtkMultiBlockDataSet = multiBlockDataSet self.dictAttributesValues: dict[ str, Union[ list[ Any ], None ] ] = dictAttributesValues From a94c1d9a231452d7e0a54563bc0016a3e253d38b Mon Sep 17 00:00:00 2001 From: jacques franc Date: Wed, 15 Oct 2025 13:52:16 +0200 Subject: [PATCH 07/20] from #129 --- geos-utils/src/geos/utils/Logger.py | 82 ++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/geos-utils/src/geos/utils/Logger.py b/geos-utils/src/geos/utils/Logger.py index 9d3fe5c41..1fd832b7f 100644 --- a/geos-utils/src/geos/utils/Logger.py +++ b/geos-utils/src/geos/utils/Logger.py @@ -2,16 +2,96 @@ # SPDX-FileCopyrightText: Copyright 2023-2024 TotalEnergies. # SPDX-FileContributor: Martin Lemay import logging -from typing import Any, Union +from typing import Any, Union, Generator from typing_extensions import Self +import os +import re +import tempfile +from contextlib import contextmanager + __doc__ = """ Logger module manages logging tools. Code was modified from + +It also include adaptor strategy to make vtkLogger behave as a logging's logger. +Indeed, C++ adapted class is based on private Callback assignement which is not compatible +with logging python's logic. + +usage: + #near logger definition + from vtkmodules.vtkCommonCore import vtkLogger + + vtkLogger.SetStderrVerbosity(vtkLogger.VERBOSITY_TRACE) + logger.addFilter(RegexExceptionFilter()) + + ... + + #near VTK calls + with VTKCaptureLog() as captured_log: + vtkcalls.. + captured_log.seek(0) # be kind let's just rewind + captured = captured_log.read().decode() + + logger.error(captured.strip()) + """ +class RegexExceptionFilter( logging.Filter ): + """Class to regexp VTK messages rethrown into logger by VTKCaptureLog.""" + + pattern: str = r"ERR" #pattern captured that will raise a vtkError + + def __init__( self ) -> None: + """Init filter with class based pattern as this is patch to logging logic.""" + super().__init__() + self.regex = re.compile( self.pattern ) + + def filter( self, record: logging.LogRecord ) -> bool: + """Filter VTK Error from stdErr. + + Args: + record(loggging.LogRecord) : record that logger will provide as evaluated + + Raises: + VTKError(geos.utils.Error) if a pattern symbol is caught in the stderr. + """ + message = record.getMessage() + if self.regex.search( message ): + raise TypeError( f"Log message matched forbidden pattern: {message}" ) + return True # Allow other messages to pass + + +@contextmanager +def VTKCaptureLog() -> Generator[ Any, Any, Any ]: + """Hard way of adapting C-like vtkLogger to logging class by throwing in stderr and reading back from it. + + Returns: + Generator: buffering os stderr. + + """ + #equiv to pyvista's + # from pyvista.utilities import VtkErrorCatcher + # with VtkErrorCatcher() as err: + # append_filter.Update() + # print(err) + # original_stderr_fd = sys.stderr.fileno() + original_stderr_fd = 2 + saved_stderr_fd = os.dup( original_stderr_fd ) + + # Create a temporary file to capture stderr + with tempfile.TemporaryFile( mode='w+b' ) as tmp: + os.dup2( tmp.fileno(), original_stderr_fd ) + try: + yield tmp + finally: + # Restore original stderr + os.dup2( saved_stderr_fd, original_stderr_fd ) + os.close( saved_stderr_fd ) + + class CountWarningHandler( logging.Handler ): """Create an handler to count the warnings logged.""" From da14023a56e7d654a3c49bec5fd494dc159a55d7 Mon Sep 17 00:00:00 2001 From: jacques franc Date: Mon, 24 Nov 2025 14:09:09 +0100 Subject: [PATCH 08/20] wip --- .../geos/pv/plugins/PVFillPartialArrays.py | 7 +- geos-utils/src/geos/utils/Logger.py | 96 ++++++++++++++++++- geos-utils/src/geos/utils/details.py | 14 +-- 3 files changed, 104 insertions(+), 13 deletions(-) diff --git a/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py b/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py index 1928aa73f..2bf25b478 100644 --- a/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py +++ b/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py @@ -108,10 +108,11 @@ def ApplyFilter( self, inputMesh: vtkMultiBlockDataSet, outputMesh: vtkMultiBloc speHandler=True, ) - if not filter.logger.hasHandlers(): - filter.setLoggerHandler( VTKHandler() ) + # if not fillPartialArraysFilter.logger.hasHandlers(): + # fillPartialArraysFilter.setLoggerHandler( VTKHandler() ) + - filter.applyFilter() + fillPartialArraysFilter.applyFilter() self.clearDictAttributesValues = True diff --git a/geos-utils/src/geos/utils/Logger.py b/geos-utils/src/geos/utils/Logger.py index 099ce9077..151320be5 100644 --- a/geos-utils/src/geos/utils/Logger.py +++ b/geos-utils/src/geos/utils/Logger.py @@ -10,6 +10,7 @@ import tempfile from contextlib import contextmanager +from vtkmodules.vtkCommonCore import vtkLogger from geos.utils.Errors import VTKError __doc__ = """ @@ -239,6 +240,95 @@ def format( self: Self, record: logging.LogRecord ) -> str: # Fallback for unknown levels or if a level is missing in the map return logging.Formatter().format( record ) +class GEOSFormatter( logging.Formatter ): + + # define color codes + green: str = "\x1b[32;20m" + grey: str = "\x1b[38;20m" + yellow: str = "\x1b[33;20m" + red: str = "\x1b[31;20m" + bold_red: str = "\x1b[31;1m" + reset: str = "\x1b[0m" + + # define prefix of log messages + format_short: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s" + format_long: str = ( "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" ) + format_results: str = "%(name)s - %(levelname)s - %(message)s" + + #: format for each logger output type without colors (e.g., for Paraview) + _formatDict : dict[int, str ] = { + # DEBUG: format_long, + # INFO: format_short, + # WARNING: format_short, + # ERROR: format_short, + # CRITICAL: format_long, + # RESULTS_LEVEL_NUM: format_results, + DEBUG: grey + format_long + reset, + INFO: green + format_short + reset, + WARNING: yellow + format_short + reset, + ERROR: red + format_short + reset, + CRITICAL: bold_red + format_long + reset, + RESULTS_LEVEL_NUM: green + format_results + reset, + } + + def __init__(self, fmt = None, datefmt = None, style = "%", validate = True, *, defaults = None) -> None: + super().__init__(fmt, datefmt, style, validate, defaults=defaults) + + def format(self : Self, record : logging.LogRecord) -> str: + return self._formatDict.get( record.levelname, logging.Formatter() ).format(record) + + +class GEOSHandler(logging.Handler): + + def __init__(self, level = 0): + super().__init__(level) + #default formatter + self.formatter = GEOSFormatter() + + @staticmethod + def get_vtk_level(level : int): + if level >= ERROR: + return vtkLogger.VERBOSITY_ERROR + elif level >= WARNING: + return vtkLogger.VERBOSITY_WARNING + elif level >= INFO: + return vtkLogger.VERBOSITY_INFO + elif level >= DEBUG: + return vtkLogger.VERBOSITY_TRACE + else: + return vtkLogger.VERBOSITY_MAX + + def emit(self, record): + vtkLogger.Log( (lvl:=GEOSHandler.get_vtk_level(record.levelno)), + record.filename, + record.lineno, + (msg:=self.format(record))) + + try: + from vtkmodules.vtkCommonCore import vtkOutputWindow as win + outwin= win.GetInstance() + if outwin: + #see https://www.paraview.org/paraview-docs/v5.13.3/python/_modules/paraview/detail/loghandler.html#VTKHandler + prevMode = outwin.GetDisplayMode() + outwin.DisplayText(f"test test test ---") + outwin.SetDisplayModeToNever() + + if lvl == ERROR: + outwin.DisplayErrorText(self.format(record)) + elif lvl == WARNING: + outwin.DisplayErrorText(self.format(record)) + else: + # lvl == GEOSLogger.VERBOSITY_INFO: + outwin.DisplayText(self.format(record)) + # elif lvl == GEOSLogger.VERBOSITY_DEBUG: + # outwin.DisplayDebugText(fullMsg) + + outwin.SetDisplayMode(prevMode) + + except Exception: + self.handleError(record) + + def getLogger( title: str, use_color: bool = False ) -> Logger: """Return the Logger with pre-defined configuration. @@ -278,9 +368,9 @@ def getLogger( title: str, use_color: bool = False ) -> Logger: if len( logger.handlers ) == 0: logger.setLevel( INFO ) # Set the desired default level for this logger # Create and add the stream handler - ch = logging.StreamHandler() - ch.setFormatter( CustomLoggerFormatter( use_color ) ) # Use your custom formatter - logger.addHandler( ch ) + # ch = logging.StreamHandler() + # ch.setFormatter( CustomLoggerFormatter( use_color ) ) # Use your custom formatter + logger.addHandler( GEOSHandler() ) # Optional: Prevent messages from propagating to the root logger's handlers logger.propagate = False # If you need to ensure a certain level is set every time getLogger is called, diff --git a/geos-utils/src/geos/utils/details.py b/geos-utils/src/geos/utils/details.py index 88bf7da00..900af5db6 100644 --- a/geos-utils/src/geos/utils/details.py +++ b/geos-utils/src/geos/utils/details.py @@ -1,5 +1,5 @@ import logging -from geos.utils.Logger import Logger, getLogger +from geos.utils.Logger import Logger, getLogger, CustomLoggerFormatter, GEOSHandler from functools import wraps from typing import Type, TypeVar, Callable, Protocol, Any @@ -41,18 +41,18 @@ def decorator( cls: Type[ T ] ) -> Type[ T ]: @wraps( original_init ) def new_init( self: T, *args: Any, **kwargs: Any ) -> None: spe_handler = kwargs.pop( 'speHandler', False ) - if spe_handler: - self.logger = logging.getLogger( loggerTitle ) - self.logger.setLevel( logging.INFO ) - else: - self.logger = getLogger( loggerTitle, True ) + # if spe_handler: + # self.logger = logging.getLogger( loggerTitle ) + # self.logger.setLevel( logging.INFO ) + # else: + self.logger = getLogger( loggerTitle, True ) original_init( self, *args, **kwargs ) def setLoggerHandler( self: T, handler: logging.Handler ) -> None: # No docstring needed - Protocol defines the contract if not self.logger.handlers: - self.logger.addHandler( handler ) + self.logger.addHandler( GEOSHandler() ) else: self.logger.warning( "The logger already has an handler, to use yours set the argument 'speHandler' to True during the filter initialization." From 7e41989422077112b8b874f224507dc88b01ce0d Mon Sep 17 00:00:00 2001 From: jacques franc Date: Mon, 24 Nov 2025 18:24:06 +0100 Subject: [PATCH 09/20] Adding logger classes and logic --- .../tests/test_FillPartialArrays.py | 10 +- geos-utils/src/geos/utils/Logger.py | 158 ++++-------------- geos-utils/src/geos/utils/details.py | 21 ++- 3 files changed, 59 insertions(+), 130 deletions(-) diff --git a/geos-processing/tests/test_FillPartialArrays.py b/geos-processing/tests/test_FillPartialArrays.py index e5720d0f5..cc9eafe97 100644 --- a/geos-processing/tests/test_FillPartialArrays.py +++ b/geos-processing/tests/test_FillPartialArrays.py @@ -9,9 +9,11 @@ from typing import Any from vtkmodules.vtkCommonDataModel import vtkMultiBlockDataSet +import sys +sys.path.insert( 0, "/data/pau901/SIM_CS/04_WORKSPACE/USERS/jfranc/geosPythonPackages/geos-processing/src") +sys.path.insert( 0, "/data/pau901/SIM_CS/04_WORKSPACE/USERS/jfranc/geosPythonPackages/geos-utils/src") from geos.processing.generic_processing_tools.FillPartialArrays import FillPartialArrays - @pytest.mark.parametrize( "dictAttributesValues", [ ( { "PORO": None @@ -50,4 +52,10 @@ def test_FillPartialArrays( multiBlockDataSet: vtkMultiBlockDataSet = dataSetTest( "multiblock" ) fillPartialArraysFilter: FillPartialArrays = FillPartialArrays( multiBlockDataSet, dictAttributesValues ) + fillPartialArraysFilter.logger.info("testtesttest") assert fillPartialArraysFilter.applyFilter() + + +if "__main__" == __name__: + + pytest.main(["-v", __file__,"-o", "log_cli=true", "-o" ,"log_cli_level=DEBUG"]) diff --git a/geos-utils/src/geos/utils/Logger.py b/geos-utils/src/geos/utils/Logger.py index 151320be5..09bba1f92 100644 --- a/geos-utils/src/geos/utils/Logger.py +++ b/geos-utils/src/geos/utils/Logger.py @@ -148,98 +148,6 @@ def results( self: logging.Logger, message: str, *args: Any, **kws: Any ) -> Non # types redefinition to import logging.* from this module Logger = logging.Logger # logger type - - -class CustomLoggerFormatter( logging.Formatter ): - """Custom formatter for the logger. - - .. WARNING:: Colors do not work in the output message window of Paraview. - - To use it: - - .. code-block:: python - - logger = logging.getLogger( "Logger name", use_color=False ) - # Ensure handler is added only once, e.g., by checking logger.handlers - if not logger.handlers: - ch = logging.StreamHandler() - ch.setFormatter(CustomLoggerFormatter()) - logger.addHandler(ch) - """ - # define color codes - green: str = "\x1b[32;20m" - grey: str = "\x1b[38;20m" - yellow: str = "\x1b[33;20m" - red: str = "\x1b[31;20m" - bold_red: str = "\x1b[31;1m" - reset: str = "\x1b[0m" - - # define prefix of log messages - format1: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s" - format2: str = ( "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" ) - format_results: str = "%(name)s - %(levelname)s - %(message)s" - - #: format for each logger output type with colors - FORMATS_COLOR: dict[ int, str ] = { - DEBUG: grey + format2 + reset, - INFO: green + format1 + reset, - WARNING: yellow + format1 + reset, - ERROR: red + format1 + reset, - CRITICAL: bold_red + format2 + reset, - RESULTS_LEVEL_NUM: green + format_results + reset, - } - - #: format for each logger output type without colors (e.g., for Paraview) - FORMATS_PLAIN: dict[ int, str ] = { - DEBUG: format2, - INFO: format1, - WARNING: format1, - ERROR: format1, - CRITICAL: format2, - RESULTS_LEVEL_NUM: format_results, - } - - # Pre-compiled formatters for efficiency - _compiled_formatters: dict[ int, logging.Formatter ] = { - level: logging.Formatter( fmt ) - for level, fmt in FORMATS_PLAIN.items() - } - - _compiled_color_formatters: dict[ int, logging.Formatter ] = { - level: logging.Formatter( fmt ) - for level, fmt in FORMATS_COLOR.items() - } - - def __init__( self: Self, use_color: bool = False ) -> None: - """Initialize the log formatter. - - Args: - use_color (bool): If True, use color-coded log formatters. - Defaults to False. - """ - super().__init__() - if use_color: - self.active_formatters = self._compiled_color_formatters - else: - self.active_formatters = self._compiled_formatters - - def format( self: Self, record: logging.LogRecord ) -> str: - """Return the format according to input record. - - Args: - record (logging.LogRecord): record - - Returns: - str: format as a string - """ - # Defaulting to plain formatters as per original logic - log_fmt_obj: Union[ logging.Formatter, None ] = self.active_formatters.get( record.levelno ) - if log_fmt_obj: - return log_fmt_obj.format( record ) - else: - # Fallback for unknown levels or if a level is missing in the map - return logging.Formatter().format( record ) - class GEOSFormatter( logging.Formatter ): # define color codes @@ -256,13 +164,7 @@ class GEOSFormatter( logging.Formatter ): format_results: str = "%(name)s - %(levelname)s - %(message)s" #: format for each logger output type without colors (e.g., for Paraview) - _formatDict : dict[int, str ] = { - # DEBUG: format_long, - # INFO: format_short, - # WARNING: format_short, - # ERROR: format_short, - # CRITICAL: format_long, - # RESULTS_LEVEL_NUM: format_results, + _formatDict : dict[int, str ] = { DEBUG: grey + format_long + reset, INFO: green + format_short + reset, WARNING: yellow + format_short + reset, @@ -275,15 +177,21 @@ def __init__(self, fmt = None, datefmt = None, style = "%", validate = True, *, super().__init__(fmt, datefmt, style, validate, defaults=defaults) def format(self : Self, record : logging.LogRecord) -> str: - return self._formatDict.get( record.levelname, logging.Formatter() ).format(record) + return logging.Formatter( fmt= self._formatDict.get( record.levelno, []) ).format(record) + + @staticmethod + def TrimColor(msg : str) -> str: + return msg[8:-5] -class GEOSHandler(logging.Handler): +class GEOSHandler(logging.StreamHandler): def __init__(self, level = 0): super().__init__(level) #default formatter - self.formatter = GEOSFormatter() + + def setLevel(self, level): + return super().setLevel(level) @staticmethod def get_vtk_level(level : int): @@ -299,30 +207,26 @@ def get_vtk_level(level : int): return vtkLogger.VERBOSITY_MAX def emit(self, record): - vtkLogger.Log( (lvl:=GEOSHandler.get_vtk_level(record.levelno)), - record.filename, - record.lineno, - (msg:=self.format(record))) - try: + msg = self.format(record) + lvl = GEOSHandler.get_vtk_level(record.levelno) + from vtkmodules.vtkCommonCore import vtkOutputWindow as win outwin= win.GetInstance() if outwin: #see https://www.paraview.org/paraview-docs/v5.13.3/python/_modules/paraview/detail/loghandler.html#VTKHandler prevMode = outwin.GetDisplayMode() - outwin.DisplayText(f"test test test ---") outwin.SetDisplayModeToNever() - + + # lvl=GEOSHandler.get_vtk_level(record.levelno) + if lvl == ERROR: - outwin.DisplayErrorText(self.format(record)) + outwin.DisplayErrorText(GEOSFormatter.TrimColor(msg)) elif lvl == WARNING: - outwin.DisplayErrorText(self.format(record)) + outwin.DisplayErrorText(GEOSFormatter.TrimColor(msg)) else: - # lvl == GEOSLogger.VERBOSITY_INFO: - outwin.DisplayText(self.format(record)) - # elif lvl == GEOSLogger.VERBOSITY_DEBUG: - # outwin.DisplayDebugText(fullMsg) - + outwin.DisplayText(GEOSFormatter.TrimColor(msg)) + outwin.SetDisplayMode(prevMode) except Exception: @@ -330,7 +234,7 @@ def emit(self, record): -def getLogger( title: str, use_color: bool = False ) -> Logger: +def getLogger( title: str, use_color=False ) -> Logger: """Return the Logger with pre-defined configuration. This function is now idempotent regarding handler addition. @@ -366,15 +270,27 @@ def getLogger( title: str, use_color: bool = False ) -> Logger: logger = logging.getLogger( title ) # Only configure the logger (add handlers, set level) if it hasn't been configured before. if len( logger.handlers ) == 0: - logger.setLevel( INFO ) # Set the desired default level for this logger + logger.setLevel( DEBUG ) # Set the desired default level for this logger # Create and add the stream handler # ch = logging.StreamHandler() # ch.setFormatter( CustomLoggerFormatter( use_color ) ) # Use your custom formatter - logger.addHandler( GEOSHandler() ) + geos_handler = GEOSHandler() + geos_handler.setFormatter(GEOSFormatter()) + geos_handler.setLevel(logger.getEffectiveLevel()) + logger.addHandler( geos_handler ) + + cli_handle = logging.StreamHandler() + cli_handle.setFormatter(GEOSFormatter()) + cli_handle.setLevel(logger.getEffectiveLevel()) + logger.addHandler(cli_handle) + + file_handle = logging.FileHandler('log.geosPythonPackages') + logger.addHandler(file_handle) # Optional: Prevent messages from propagating to the root logger's handlers - logger.propagate = False + logger.propagate = True + # If you need to ensure a certain level is set every time getLogger is called, # even if handlers were already present, you can set the level outside the 'if' block. # However, typically, setLevel is part of the initial handler configuration. # logger.setLevel(INFO) # Uncomment if you need to enforce level on every call - return logger + return logger \ No newline at end of file diff --git a/geos-utils/src/geos/utils/details.py b/geos-utils/src/geos/utils/details.py index 900af5db6..4d9bbf76b 100644 --- a/geos-utils/src/geos/utils/details.py +++ b/geos-utils/src/geos/utils/details.py @@ -1,5 +1,5 @@ import logging -from geos.utils.Logger import Logger, getLogger, CustomLoggerFormatter, GEOSHandler +from geos.utils.Logger import Logger, getLogger, GEOSHandler from functools import wraps from typing import Type, TypeVar, Callable, Protocol, Any @@ -45,18 +45,23 @@ def new_init( self: T, *args: Any, **kwargs: Any ) -> None: # self.logger = logging.getLogger( loggerTitle ) # self.logger.setLevel( logging.INFO ) # else: - self.logger = getLogger( loggerTitle, True ) + self.logger = getLogger( loggerTitle) + for hdlr in list(filter(lambda x : not isinstance(x,GEOSHandler), self.logger.handlers)): + self.logger.removeHandler(hdlr) + + original_init( self, *args, **kwargs ) def setLoggerHandler( self: T, handler: logging.Handler ) -> None: + pass # No docstring needed - Protocol defines the contract - if not self.logger.handlers: - self.logger.addHandler( GEOSHandler() ) - else: - self.logger.warning( - "The logger already has an handler, to use yours set the argument 'speHandler' to True during the filter initialization." - ) + # if not self.logger.handlers: + # self.logger.addHandler( GEOSHandler() ) + # else: + # self.logger.warning( + # "The logger already has an handler, to use yours set the argument 'speHandler' to True during the filter initialization." + # ) cls.__init__ = new_init # type: ignore[assignment] cls.setLoggerHandler = setLoggerHandler # type: ignore[assignment] From e43f57f23ad1fd8fb3d4520c4ffed50be57d723b Mon Sep 17 00:00:00 2001 From: jacques franc Date: Mon, 24 Nov 2025 18:41:12 +0100 Subject: [PATCH 10/20] wip --- .../generic_processing_tools/FillPartialArrays.py | 7 ++++--- geos-processing/tests/test_FillPartialArrays.py | 11 +++++------ geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py | 10 ++++++++-- geos-utils/src/geos/utils/Logger.py | 9 +-------- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/geos-processing/src/geos/processing/generic_processing_tools/FillPartialArrays.py b/geos-processing/src/geos/processing/generic_processing_tools/FillPartialArrays.py index 6bffbbe10..d53deca3d 100644 --- a/geos-processing/src/geos/processing/generic_processing_tools/FillPartialArrays.py +++ b/geos-processing/src/geos/processing/generic_processing_tools/FillPartialArrays.py @@ -5,11 +5,11 @@ from typing_extensions import Self from typing import Union, Any -from geos.utils.Logger import logging, Logger, getLogger +from geos.utils.Logger import getLogger from geos.mesh.utils.arrayModifiers import fillPartialAttributes from geos.mesh.utils.arrayHelpers import getAttributePieceInfo -from geos.utils.details import addLogSupport +# from geos.utils.details import addLogSupport from vtkmodules.vtkCommonDataModel import vtkMultiBlockDataSet __doc__ = """ @@ -56,7 +56,7 @@ loggerTitle: str = "Fill Partial Attribute" -@addLogSupport( loggerTitle=loggerTitle ) +# @addLogSupport( loggerTitle=loggerTitle ) class FillPartialArrays: def __init__( @@ -77,6 +77,7 @@ def __init__( multiBlockDataSet (vtkMultiBlockDataSet): The mesh where to fill the attribute. dictAttributesValues (dict[str, Any]): The dictionary with the attribute to fill as keys and the list of filling values as items. """ + self.logger = getLogger(loggerTitle) self.multiBlockDataSet: vtkMultiBlockDataSet = multiBlockDataSet self.dictAttributesValues: dict[ str, Union[ list[ Any ], None ] ] = dictAttributesValues diff --git a/geos-processing/tests/test_FillPartialArrays.py b/geos-processing/tests/test_FillPartialArrays.py index cc9eafe97..07d3d95ec 100644 --- a/geos-processing/tests/test_FillPartialArrays.py +++ b/geos-processing/tests/test_FillPartialArrays.py @@ -9,9 +9,9 @@ from typing import Any from vtkmodules.vtkCommonDataModel import vtkMultiBlockDataSet -import sys -sys.path.insert( 0, "/data/pau901/SIM_CS/04_WORKSPACE/USERS/jfranc/geosPythonPackages/geos-processing/src") -sys.path.insert( 0, "/data/pau901/SIM_CS/04_WORKSPACE/USERS/jfranc/geosPythonPackages/geos-utils/src") +# import sys +# sys.path.insert( 0, "/data/pau901/SIM_CS/04_WORKSPACE/USERS/jfranc/geosPythonPackages/geos-processing/src") +# sys.path.insert( 0, "/data/pau901/SIM_CS/04_WORKSPACE/USERS/jfranc/geosPythonPackages/geos-utils/src") from geos.processing.generic_processing_tools.FillPartialArrays import FillPartialArrays @pytest.mark.parametrize( "dictAttributesValues", [ @@ -52,10 +52,9 @@ def test_FillPartialArrays( multiBlockDataSet: vtkMultiBlockDataSet = dataSetTest( "multiblock" ) fillPartialArraysFilter: FillPartialArrays = FillPartialArrays( multiBlockDataSet, dictAttributesValues ) - fillPartialArraysFilter.logger.info("testtesttest") assert fillPartialArraysFilter.applyFilter() -if "__main__" == __name__: +# if "__main__" == __name__: - pytest.main(["-v", __file__,"-o", "log_cli=true", "-o" ,"log_cli_level=DEBUG"]) +# pytest.main(["-v", __file__,"-o", "log_cli=true", "-o" ,"log_cli_level=DEBUG"]) diff --git a/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py b/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py index 2bf25b478..e09401470 100644 --- a/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py +++ b/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py @@ -24,8 +24,9 @@ update_paths() +from geos.utils.Logger import getLogger, GEOSHandler from geos.pv.utils.details import SISOFilter, FilterCategory -from geos.processing.generic_processing_tools.FillPartialArrays import FillPartialArrays +from geos.processing.generic_processing_tools.FillPartialArrays import FillPartialArrays, loggerTitle __doc__ = """ Fill partial arrays of input mesh. @@ -52,7 +53,12 @@ def __init__( self: Self, ) -> None: """Fill a partial attribute with constant value per component.""" self.clearDictAttributesValues: bool = True self.dictAttributesValues: dict[ str, Union[ list[ Any ], None ] ] = {} + #remove noisy loggers to get clean OutputMessage windows + self.logger = getLogger( loggerTitle ) + for hdlr in list(filter(lambda x : not isinstance(x, GEOSHandler), self.logger.handlers)): + self.logger.removeHandler(hdlr) + @smproperty.xml( """ Logger: if len( logger.handlers ) == 0: logger.setLevel( DEBUG ) # Set the desired default level for this logger # Create and add the stream handler - # ch = logging.StreamHandler() - # ch.setFormatter( CustomLoggerFormatter( use_color ) ) # Use your custom formatter geos_handler = GEOSHandler() geos_handler.setFormatter(GEOSFormatter()) geos_handler.setLevel(logger.getEffectiveLevel()) @@ -284,8 +279,6 @@ def getLogger( title: str, use_color=False ) -> Logger: cli_handle.setLevel(logger.getEffectiveLevel()) logger.addHandler(cli_handle) - file_handle = logging.FileHandler('log.geosPythonPackages') - logger.addHandler(file_handle) # Optional: Prevent messages from propagating to the root logger's handlers logger.propagate = True From 2bb1ff278a7b46eada5a3de3686680128c4ffc3f Mon Sep 17 00:00:00 2001 From: jacques franc Date: Tue, 25 Nov 2025 10:28:45 +0100 Subject: [PATCH 11/20] clean up --- .../FillPartialArrays.py | 2 - .../tests/test_FillPartialArrays.py | 8 --- .../geos/pv/plugins/PVFillPartialArrays.py | 19 ++--- geos-utils/src/geos/utils/Logger.py | 49 ++++++++++--- geos-utils/src/geos/utils/details.py | 71 ------------------- 5 files changed, 45 insertions(+), 104 deletions(-) delete mode 100644 geos-utils/src/geos/utils/details.py diff --git a/geos-processing/src/geos/processing/generic_processing_tools/FillPartialArrays.py b/geos-processing/src/geos/processing/generic_processing_tools/FillPartialArrays.py index d53deca3d..39dbd3e90 100644 --- a/geos-processing/src/geos/processing/generic_processing_tools/FillPartialArrays.py +++ b/geos-processing/src/geos/processing/generic_processing_tools/FillPartialArrays.py @@ -55,8 +55,6 @@ loggerTitle: str = "Fill Partial Attribute" - -# @addLogSupport( loggerTitle=loggerTitle ) class FillPartialArrays: def __init__( diff --git a/geos-processing/tests/test_FillPartialArrays.py b/geos-processing/tests/test_FillPartialArrays.py index 07d3d95ec..f437cfcdb 100644 --- a/geos-processing/tests/test_FillPartialArrays.py +++ b/geos-processing/tests/test_FillPartialArrays.py @@ -9,9 +9,6 @@ from typing import Any from vtkmodules.vtkCommonDataModel import vtkMultiBlockDataSet -# import sys -# sys.path.insert( 0, "/data/pau901/SIM_CS/04_WORKSPACE/USERS/jfranc/geosPythonPackages/geos-processing/src") -# sys.path.insert( 0, "/data/pau901/SIM_CS/04_WORKSPACE/USERS/jfranc/geosPythonPackages/geos-utils/src") from geos.processing.generic_processing_tools.FillPartialArrays import FillPartialArrays @pytest.mark.parametrize( "dictAttributesValues", [ @@ -53,8 +50,3 @@ def test_FillPartialArrays( fillPartialArraysFilter: FillPartialArrays = FillPartialArrays( multiBlockDataSet, dictAttributesValues ) assert fillPartialArraysFilter.applyFilter() - - -# if "__main__" == __name__: - -# pytest.main(["-v", __file__,"-o", "log_cli=true", "-o" ,"log_cli_level=DEBUG"]) diff --git a/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py b/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py index e09401470..30abb4b9b 100644 --- a/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py +++ b/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py @@ -10,10 +10,6 @@ from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] VTKPythonAlgorithmBase, smproperty, ) # 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.vtkCommonDataModel import ( vtkMultiBlockDataSet, ) @@ -24,10 +20,10 @@ update_paths() -from geos.utils.Logger import getLogger, GEOSHandler from geos.pv.utils.details import SISOFilter, FilterCategory from geos.processing.generic_processing_tools.FillPartialArrays import FillPartialArrays, loggerTitle +from geos.utils.Logger import addPluginLogSupport __doc__ = """ Fill partial arrays of input mesh. @@ -43,10 +39,10 @@ """ - @SISOFilter( category=FilterCategory.GEOS_UTILS, decoratedLabel="Fill Partial Arrays", decoratedType="vtkMultiBlockDataSet" ) +@addPluginLogSupport( loggerTitle=loggerTitle ) class PVFillPartialArrays( VTKPythonAlgorithmBase ): def __init__( self: Self, ) -> None: @@ -54,9 +50,9 @@ def __init__( self: Self, ) -> None: self.clearDictAttributesValues: bool = True self.dictAttributesValues: dict[ str, Union[ list[ Any ], None ] ] = {} #remove noisy loggers to get clean OutputMessage windows - self.logger = getLogger( loggerTitle ) - for hdlr in list(filter(lambda x : not isinstance(x, GEOSHandler), self.logger.handlers)): - self.logger.removeHandler(hdlr) + # self.logger = getLogger( loggerTitle ) + # for hdlr in list(filter(lambda x : not isinstance(x, GEOSHandler), self.logger.handlers)): + # self.logger.removeHandler(hdlr) @smproperty.xml( """ @@ -111,13 +107,8 @@ def ApplyFilter( self, inputMesh: vtkMultiBlockDataSet, outputMesh: vtkMultiBloc fillPartialArraysFilter: FillPartialArrays = FillPartialArrays( outputMesh, self.dictAttributesValues, - # speHandler=True, ) - # if not fillPartialArraysFilter.logger.hasHandlers(): - # fillPartialArraysFilter.setLoggerHandler( VTKHandler() ) - - fillPartialArraysFilter.applyFilter() self.clearDictAttributesValues = True diff --git a/geos-utils/src/geos/utils/Logger.py b/geos-utils/src/geos/utils/Logger.py index 8f64a3679..2e57dd387 100644 --- a/geos-utils/src/geos/utils/Logger.py +++ b/geos-utils/src/geos/utils/Logger.py @@ -4,6 +4,8 @@ import logging from typing import Any, Generator from typing_extensions import Self +from functools import wraps +from typing import Type, TypeVar, Callable, Any import os import re @@ -42,6 +44,33 @@ """ +## decorators +T = TypeVar('T') + +def addPluginLogSupport( loggerTitle: str ) -> Callable[ [ Type[ T ] ], Type[ T ] ]: + """Decorator to add logger support in the class following existing architecture. + + Args: + loggerTitle (str): Title to display in the logger + """ + + def decorator( cls: Type[ T ] ) -> Type[ T ]: + original_init = cls.__init__ + + @wraps( original_init ) + def new_init( self: T, *args: Any, **kwargs: Any ) -> None: + + self.logger = getLogger( loggerTitle ) + for hdlr in list(filter(lambda x : not isinstance(x,GEOSHandler), self.logger.handlers)): + self.logger.removeHandler(hdlr) + + original_init( self, *args, **kwargs ) + + cls.__init__ = new_init # type: ignore[assignment] + + return cls + + return decorator class RegexExceptionFilter( logging.Filter ): """Class to regexp VTK messages rethrown into logger by VTKCaptureLog. @@ -98,6 +127,8 @@ def VTKCaptureLog() -> Generator[ Any, Any, Any ]: os.close( savedStderrFd ) + +## helpers class CountWarningHandler( logging.Handler ): """Create an handler to count the warnings logged.""" @@ -177,11 +208,11 @@ def __init__(self, fmt = None, datefmt = None, style = "%", validate = True, *, super().__init__(fmt, datefmt, style, validate, defaults=defaults) def format(self : Self, record : logging.LogRecord) -> str: - return logging.Formatter( fmt= self._formatDict.get( record.levelno, []) ).format(record) + return logging.Formatter( fmt= self._formatDict.get( record.levelno, [] ) ).format(record) @staticmethod def TrimColor(msg : str) -> str: - return msg[8:-5] + return msg[8:-4] class GEOSHandler(logging.StreamHandler): @@ -216,21 +247,21 @@ def emit(self, record): #see https://www.paraview.org/paraview-docs/v5.13.3/python/_modules/paraview/detail/loghandler.html#VTKHandler prevMode = outwin.GetDisplayMode() outwin.SetDisplayModeToNever() - - if lvl == ERROR: - outwin.DisplayErrorText(GEOSFormatter.TrimColor(msg)) - elif lvl == WARNING: + + if lvl == vtkLogger.VERBOSITY_ERROR: outwin.DisplayErrorText(GEOSFormatter.TrimColor(msg)) - else: + elif lvl == vtkLogger.VERBOSITY_WARNING: + outwin.DisplayWarningText(GEOSFormatter.TrimColor(msg)) + elif lvl == vtkLogger.VERBOSITY_INFO: outwin.DisplayText(GEOSFormatter.TrimColor(msg)) + elif lvl == vtkLogger.VERBOSITY_TRACE: + outwin.DisplayDebugText(GEOSFormatter.TrimColor(msg)) outwin.SetDisplayMode(prevMode) except Exception: self.handleError(record) - - def getLogger( title: str, use_color=False ) -> Logger: """Return the Logger with pre-defined configuration. diff --git a/geos-utils/src/geos/utils/details.py b/geos-utils/src/geos/utils/details.py deleted file mode 100644 index 4d9bbf76b..000000000 --- a/geos-utils/src/geos/utils/details.py +++ /dev/null @@ -1,71 +0,0 @@ -import logging -from geos.utils.Logger import Logger, getLogger, GEOSHandler -from functools import wraps -from typing import Type, TypeVar, Callable, Protocol, Any - -__doc__ = """ - Group of decorators and Protocols that will be used in filters to wrap behaviors without code replication - -""" - - -class HasLogger( Protocol ): - """Protocol for classes that have logging support.""" - - logger: Logger - - def setLoggerHandler( self, handler: logging.Handler ) -> None: - """Set a specific handler for the filter logger. - - In this filter 4 log levels are use, .info, .error, .warning and .critical, be sure to have at least the same 4 levels. - - Args: - handler (logging.Handler): The handler to add. - """ - pass - - -T = TypeVar( 'T', bound='HasLogger' ) - - -def addLogSupport( loggerTitle: str ) -> Callable[ [ Type[ T ] ], Type[ T ] ]: - """Decorator to add logger support in the class following existing architecture. - - Args: - loggerTitle (str): Title to display in the logger - """ - - def decorator( cls: Type[ T ] ) -> Type[ T ]: - original_init = cls.__init__ - - @wraps( original_init ) - def new_init( self: T, *args: Any, **kwargs: Any ) -> None: - spe_handler = kwargs.pop( 'speHandler', False ) - # if spe_handler: - # self.logger = logging.getLogger( loggerTitle ) - # self.logger.setLevel( logging.INFO ) - # else: - self.logger = getLogger( loggerTitle) - for hdlr in list(filter(lambda x : not isinstance(x,GEOSHandler), self.logger.handlers)): - self.logger.removeHandler(hdlr) - - - - original_init( self, *args, **kwargs ) - - def setLoggerHandler( self: T, handler: logging.Handler ) -> None: - pass - # No docstring needed - Protocol defines the contract - # if not self.logger.handlers: - # self.logger.addHandler( GEOSHandler() ) - # else: - # self.logger.warning( - # "The logger already has an handler, to use yours set the argument 'speHandler' to True during the filter initialization." - # ) - - cls.__init__ = new_init # type: ignore[assignment] - cls.setLoggerHandler = setLoggerHandler # type: ignore[assignment] - - return cls - - return decorator From 7feecdac917f51ba592fcc56a2e0a909d89f512f Mon Sep 17 00:00:00 2001 From: jacques franc Date: Tue, 25 Nov 2025 11:02:39 +0100 Subject: [PATCH 12/20] mypy and friends --- .../geos/pv/plugins/PVFillPartialArrays.py | 3 +- .../src/geos/pv/plugins/PVMohrCirclePlot.py | 2 +- geos-utils/src/geos/utils/Logger.py | 81 +++++++++---------- 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py b/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py index 30abb4b9b..029b8672c 100644 --- a/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py +++ b/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py @@ -24,6 +24,7 @@ from geos.processing.generic_processing_tools.FillPartialArrays import FillPartialArrays, loggerTitle from geos.utils.Logger import addPluginLogSupport + __doc__ = """ Fill partial arrays of input mesh. @@ -39,6 +40,7 @@ """ + @SISOFilter( category=FilterCategory.GEOS_UTILS, decoratedLabel="Fill Partial Arrays", decoratedType="vtkMultiBlockDataSet" ) @@ -54,7 +56,6 @@ def __init__( self: Self, ) -> None: # for hdlr in list(filter(lambda x : not isinstance(x, GEOSHandler), self.logger.handlers)): # self.logger.removeHandler(hdlr) - @smproperty.xml( """ Callable[ [ Type[ T ] ], Type[ T ] ]: """Decorator to add logger support in the class following existing architecture. @@ -60,9 +61,9 @@ def decorator( cls: Type[ T ] ) -> Type[ T ]: @wraps( original_init ) def new_init( self: T, *args: Any, **kwargs: Any ) -> None: - self.logger = getLogger( loggerTitle ) - for hdlr in list(filter(lambda x : not isinstance(x,GEOSHandler), self.logger.handlers)): - self.logger.removeHandler(hdlr) + logger = getLogger( loggerTitle ) + for hdlr in list( filter( lambda x: not isinstance( x, GEOSHandler ), logger.handlers ) ): + logger.removeHandler( hdlr ) original_init( self, *args, **kwargs ) @@ -72,6 +73,7 @@ def new_init( self: T, *args: Any, **kwargs: Any ) -> None: return decorator + class RegexExceptionFilter( logging.Filter ): """Class to regexp VTK messages rethrown into logger by VTKCaptureLog. @@ -127,7 +129,6 @@ def VTKCaptureLog() -> Generator[ Any, Any, Any ]: os.close( savedStderrFd ) - ## helpers class CountWarningHandler( logging.Handler ): """Create an handler to count the warnings logged.""" @@ -179,6 +180,8 @@ def results( self: logging.Logger, message: str, *args: Any, **kws: Any ) -> Non # types redefinition to import logging.* from this module Logger = logging.Logger # logger type + + class GEOSFormatter( logging.Formatter ): # define color codes @@ -195,7 +198,7 @@ class GEOSFormatter( logging.Formatter ): format_results: str = "%(name)s - %(levelname)s - %(message)s" #: format for each logger output type without colors (e.g., for Paraview) - _formatDict : dict[int, str ] = { + _formatDict: dict[ int, str ] = { DEBUG: grey + format_long + reset, INFO: green + format_short + reset, WARNING: yellow + format_short + reset, @@ -204,27 +207,21 @@ class GEOSFormatter( logging.Formatter ): RESULTS_LEVEL_NUM: green + format_results + reset, } - def __init__(self, fmt = None, datefmt = None, style = "%", validate = True, *, defaults = None) -> None: - super().__init__(fmt, datefmt, style, validate, defaults=defaults) - - def format(self : Self, record : logging.LogRecord) -> str: - return logging.Formatter( fmt= self._formatDict.get( record.levelno, [] ) ).format(record) + def format( self: Self, record: logging.LogRecord ) -> str: + """Fomat using the above described format in color and style.""" + return logging.Formatter( fmt=self._formatDict.get( record.levelno ) ).format( record ) @staticmethod - def TrimColor(msg : str) -> str: - return msg[8:-4] + def TrimColor( msg: str ) -> str: + """Helper function to discard bash color tag when throwing to vtk logger logic (C/C++).""" + return msg[ 8:-4 ] -class GEOSHandler(logging.StreamHandler): - - def __init__(self, level = 0): - super().__init__(level) - - def setLevel(self, level): - return super().setLevel(level) +class GEOSHandler( logging.StreamHandler ): @staticmethod - def get_vtk_level(level : int): + def get_vtk_level( level: int ) -> int: + """Translate logging levels to vtk taxonomy.""" if level >= ERROR: return vtkLogger.VERBOSITY_ERROR elif level >= WARNING: @@ -236,33 +233,35 @@ def get_vtk_level(level : int): else: return vtkLogger.VERBOSITY_MAX - def emit(self, record): + def emit( self: Self, record: logging.LogRecord ) -> None: + """Overload of emit to display in the Command Output windows UI.""" try: - msg = self.format(record) - lvl = GEOSHandler.get_vtk_level(record.levelno) + msg = self.format( record ) + lvl = GEOSHandler.get_vtk_level( record.levelno ) from vtkmodules.vtkCommonCore import vtkOutputWindow as win - outwin= win.GetInstance() + outwin = win.GetInstance() if outwin: #see https://www.paraview.org/paraview-docs/v5.13.3/python/_modules/paraview/detail/loghandler.html#VTKHandler prevMode = outwin.GetDisplayMode() outwin.SetDisplayModeToNever() if lvl == vtkLogger.VERBOSITY_ERROR: - outwin.DisplayErrorText(GEOSFormatter.TrimColor(msg)) + outwin.DisplayErrorText( GEOSFormatter.TrimColor( msg ) ) elif lvl == vtkLogger.VERBOSITY_WARNING: - outwin.DisplayWarningText(GEOSFormatter.TrimColor(msg)) + outwin.DisplayWarningText( GEOSFormatter.TrimColor( msg ) ) elif lvl == vtkLogger.VERBOSITY_INFO: - outwin.DisplayText(GEOSFormatter.TrimColor(msg)) + outwin.DisplayText( GEOSFormatter.TrimColor( msg ) ) elif lvl == vtkLogger.VERBOSITY_TRACE: - outwin.DisplayDebugText(GEOSFormatter.TrimColor(msg)) - - outwin.SetDisplayMode(prevMode) + outwin.DisplayDebugText( GEOSFormatter.TrimColor( msg ) ) + + outwin.SetDisplayMode( prevMode ) except Exception: - self.handleError(record) + self.handleError( record ) + -def getLogger( title: str, use_color=False ) -> Logger: +def getLogger( title: str ) -> Logger: """Return the Logger with pre-defined configuration. This function is now idempotent regarding handler addition. @@ -301,14 +300,14 @@ def getLogger( title: str, use_color=False ) -> Logger: logger.setLevel( DEBUG ) # Set the desired default level for this logger # Create and add the stream handler geos_handler = GEOSHandler() - geos_handler.setFormatter(GEOSFormatter()) - geos_handler.setLevel(logger.getEffectiveLevel()) + geos_handler.setFormatter( GEOSFormatter() ) + geos_handler.setLevel( logger.getEffectiveLevel() ) logger.addHandler( geos_handler ) - + cli_handle = logging.StreamHandler() - cli_handle.setFormatter(GEOSFormatter()) - cli_handle.setLevel(logger.getEffectiveLevel()) - logger.addHandler(cli_handle) + cli_handle.setFormatter( GEOSFormatter() ) + cli_handle.setLevel( logger.getEffectiveLevel() ) + logger.addHandler( cli_handle ) # Optional: Prevent messages from propagating to the root logger's handlers logger.propagate = True @@ -317,4 +316,4 @@ def getLogger( title: str, use_color=False ) -> Logger: # even if handlers were already present, you can set the level outside the 'if' block. # However, typically, setLevel is part of the initial handler configuration. # logger.setLevel(INFO) # Uncomment if you need to enforce level on every call - return logger \ No newline at end of file + return logger From ce4d414f8cf425802a6217366c62962160b8906d Mon Sep 17 00:00:00 2001 From: jacques franc Date: Tue, 25 Nov 2025 11:08:41 +0100 Subject: [PATCH 13/20] authorship --- geos-processing/pyproject.toml | 1 + geos-pv/pyproject.toml | 4 +++- geos-utils/pyproject.toml | 4 +++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/geos-processing/pyproject.toml b/geos-processing/pyproject.toml index 3d947f672..226e33fe4 100644 --- a/geos-processing/pyproject.toml +++ b/geos-processing/pyproject.toml @@ -19,6 +19,7 @@ maintainers = [ {name = "Alexandre Benedicto", email = "alexandre.benedicto@external.totalenergies.com" }, {name = "Romain Baville", email = "romain.baville@external.totalenergies.com" }, {name = "Paloma Martinez", email = "paloma.martinez@external.totalenergies.com" }, + {name = "Jacques Franc", email = "jacques.franc@external.totalenergies.com" }, ] license = {text = "Apache-2.0"} classifiers = [ diff --git a/geos-pv/pyproject.toml b/geos-pv/pyproject.toml index 7a79bc45e..a943ee653 100644 --- a/geos-pv/pyproject.toml +++ b/geos-pv/pyproject.toml @@ -9,7 +9,9 @@ description = "geos-pv is a Python package that gathers Paraview plugins and ded authors = [{name = "GEOS Contributors" }] maintainers = [{name = "Alexandre Benedicto", email = "alexandre.benedicto@external.totalenergies.com" }, {name = "Romain Baville", email = "romain.baville@external.totalenergies.com" }, - {name = "Paloma Martinez", email = "paloma.martinez@external.totalenergies.com" }] + {name = "Paloma Martinez", email = "paloma.martinez@external.totalenergies.com" }, + {name = "Jacques Franc", email = "jacques.franc@external.totalenergies.com" }, + ] license = {text = "Apache-2.0"} classifiers = [ "Development Status :: 4 - Beta", diff --git a/geos-utils/pyproject.toml b/geos-utils/pyproject.toml index bc11980d8..947439145 100644 --- a/geos-utils/pyproject.toml +++ b/geos-utils/pyproject.toml @@ -17,7 +17,9 @@ description = "geos-utils is a Python package that gathers utilities common to a authors = [{name = "GEOS Contributors" }] maintainers = [{name = "Alexandre Benedicto", email = "alexandre.benedicto@external.totalenergies.com" }, {name = "Romain Baville", email = "romain.baville@external.totalenergies.com" }, - {name = "Paloma Martinez", email = "paloma.martinez@external.totalenergies.com" }] + {name = "Paloma Martinez", email = "paloma.martinez@external.totalenergies.com" }, + {name = "Jacques Franc", email = "jacques.franc@external.totalenergies.com" }, + ] license = {text = "Apache-2.0"} classifiers = [ "Development Status :: 4 - Beta", From 4e15cae331f54c2a609cb88c95a08a3a6959d6db Mon Sep 17 00:00:00 2001 From: jacques franc Date: Tue, 25 Nov 2025 15:47:22 +0100 Subject: [PATCH 14/20] wip --- .../src/geos/geomechanics/model/MohrCircle.py | 1 + .../src/geos/mesh/utils/arrayModifiers.py | 22 ++++++------ .../AttributeMapping.py | 29 +-------------- .../ClipToMainFrame.py | 10 ++---- .../CreateConstantAttributePerRegion.py | 35 +++---------------- .../MergeBlockEnhanced.py | 22 +----------- .../generic_processing_tools/SplitMesh.py | 1 + .../post_processing/SurfaceGeomechanics.py | 25 ++----------- .../src/geos/pv/plugins/PVAttributeMapping.py | 13 ++++--- .../src/geos/pv/plugins/PVClipToMainFrame.py | 10 +++--- .../PVCreateConstantAttributePerRegion.py | 17 ++++----- .../geos/pv/plugins/PVMergeBlocksEnhanced.py | 11 +++--- .../src/geos/pv/plugins/PVMohrCirclePlot.py | 21 ++++++----- geos-pv/src/geos/pv/plugins/PVSplitMesh.py | 4 ++- .../geos/pv/plugins/PVSurfaceGeomechanics.py | 12 +++---- .../src/geos/pv/utils/paraviewTreatments.py | 7 +--- geos-utils/src/geos/utils/Logger.py | 2 +- 17 files changed, 69 insertions(+), 173 deletions(-) diff --git a/geos-geomechanics/src/geos/geomechanics/model/MohrCircle.py b/geos-geomechanics/src/geos/geomechanics/model/MohrCircle.py index b0916da13..665554fa8 100644 --- a/geos-geomechanics/src/geos/geomechanics/model/MohrCircle.py +++ b/geos-geomechanics/src/geos/geomechanics/model/MohrCircle.py @@ -39,6 +39,7 @@ center: float = mohrCircle.getCircleCenter() """ +loggerTitle : str = "MohrCircle" class MohrCircle: diff --git a/geos-mesh/src/geos/mesh/utils/arrayModifiers.py b/geos-mesh/src/geos/mesh/utils/arrayModifiers.py index 0874c3540..a3ccc032f 100644 --- a/geos-mesh/src/geos/mesh/utils/arrayModifiers.py +++ b/geos-mesh/src/geos/mesh/utils/arrayModifiers.py @@ -87,7 +87,7 @@ def fillPartialAttributes( """ # Check if an external logger is given. if logger is None: - logger = getLogger( "fillPartialAttributes", True ) + logger = getLogger( "fillPartialAttributes") # Check if the input mesh is inherited from vtkMultiBlockDataSet. if not isinstance( multiBlockDataSet, vtkMultiBlockDataSet ): @@ -178,7 +178,7 @@ def fillAllPartialAttributes( """ # Check if an external logger is given. if logger is None: - logger = getLogger( "fillAllPartialAttributes", True ) + logger = getLogger( "fillAllPartialAttributes") logger.warning( "The filling value for the attributes is depending of the type of attribute's data:\n0 for uint data,\n-1 for int data,\nnan for float data." @@ -260,7 +260,7 @@ def createConstantAttribute( """ # Check if an external logger is given. if logger is None: - logger = getLogger( "createConstantAttribute", True ) + logger = getLogger( "createConstantAttribute") # Deals with multiBlocksDataSets. if isinstance( mesh, ( vtkMultiBlockDataSet, vtkCompositeDataSet ) ): @@ -307,7 +307,7 @@ def createConstantAttributeMultiBlock( """ # Check if an external logger is given. if logger is None: - logger = getLogger( "createConstantAttributeMultiBlock", True ) + logger = getLogger( "createConstantAttributeMultiBlock") # Check if the input mesh is inherited from vtkMultiBlockDataSet. if not isinstance( multiBlockDataSet, vtkMultiBlockDataSet ): @@ -376,7 +376,7 @@ def createConstantAttributeDataSet( """ # Check if an external logger is given. if logger is None: - logger = getLogger( "createConstantAttributeDataSet", True ) + logger = getLogger( "createConstantAttributeDataSet") # Check if all the values of listValues have the same type. valueType: type = type( listValues[ 0 ] ) @@ -458,7 +458,7 @@ def createAttribute( """ # Check if an external logger is given. if logger is None: - logger = getLogger( "createAttribute", True ) + logger = getLogger( "createAttribute") # Check if the input mesh is inherited from vtkDataSet. if not isinstance( dataSet, vtkDataSet ): @@ -568,7 +568,7 @@ def copyAttribute( """ # Check if an external logger is given. if logger is None: - logger = getLogger( "copyAttribute", True ) + logger = getLogger( "copyAttribute") # Check if the multiBlockDataSetFrom is inherited from vtkMultiBlockDataSet. if not isinstance( multiBlockDataSetFrom, vtkMultiBlockDataSet ): @@ -650,7 +650,7 @@ def copyAttributeDataSet( """ # Check if an external logger is given. if logger is None: - logger = getLogger( "copyAttributeDataSet", True ) + logger = getLogger( "copyAttributeDataSet") # Check if the dataSetFrom is inherited from vtkDataSet. if not isinstance( dataSetFrom, vtkDataSet ): @@ -724,7 +724,7 @@ def transferAttributeToDataSetWithElementMap( """ # Check if an external logger is given. if logger is None: - logger = getLogger( "transferAttributeToDataSetWithElementMap", True ) + logger = getLogger( "transferAttributeToDataSetWithElementMap") if flatIdDataSetTo not in elementMap: logger.error( f"The map is incomplete, there is no data for the final mesh (flat index { flatIdDataSetTo })." ) @@ -825,8 +825,8 @@ def transferAttributeWithElementMap( bool: True if transfer successfully ended. """ # Check if an external logger is given. - if logger is None: - logger = getLogger( "transferAttributeWithElementMap", True ) + if logger is None:# + logger = getLogger( "transferAttributeWithElementMap") if isinstance( meshTo, vtkDataSet ): return transferAttributeToDataSetWithElementMap( meshFrom, diff --git a/geos-processing/src/geos/processing/generic_processing_tools/AttributeMapping.py b/geos-processing/src/geos/processing/generic_processing_tools/AttributeMapping.py index 9eb7aa6fe..d2ea3e89f 100644 --- a/geos-processing/src/geos/processing/generic_processing_tools/AttributeMapping.py +++ b/geos-processing/src/geos/processing/generic_processing_tools/AttributeMapping.py @@ -41,7 +41,6 @@ attributeNames: set[ str ] # Optional inputs. onPoints: bool # defaults to False - speHandler: bool # defaults to False # Instantiate the filter attributeMappingFilter: AttributeMapping = AttributeMapping( @@ -49,13 +48,8 @@ meshTo, attributeNames, onPoints, - speHandler, ) - # Set the handler of yours (only if speHandler is True). - yourHandler: logging.Handler - attributeMappingFilter.setLoggerHandler( yourHandler ) - # Do calculations. attributeMappingFilter.applyFilter() """ @@ -71,7 +65,6 @@ def __init__( meshTo: Union[ vtkDataSet, vtkMultiBlockDataSet ], attributeNames: set[ str ], onPoints: bool = False, - speHandler: bool = False, ) -> None: """Transfer global attributes from a source mesh to a final mesh. @@ -97,27 +90,7 @@ def __init__( self.ElementMap: dict[ int, npt.NDArray[ np.int64 ] ] = {} # Logger. - self.logger: Logger - if not speHandler: - self.logger = getLogger( loggerTitle, True ) - else: - self.logger = logging.getLogger( loggerTitle ) - self.logger.setLevel( logging.INFO ) - - def setLoggerHandler( self: Self, handler: logging.Handler ) -> None: - """Set a specific handler for the filter logger. - - In this filter 4 log levels are use, .info, .error, .warning and .critical, - be sure to have at least the same 4 levels. - - Args: - handler (logging.Handler): The handler to add. - """ - if not self.logger.hasHandlers(): - self.logger.addHandler( handler ) - else: - self.logger.warning( "The logger already has an handler, to use yours set the argument 'speHandler'" - " to True during the filter initialization." ) + self.logger: Logger = getLogger( loggerTitle) def getElementMap( self: Self ) -> dict[ int, npt.NDArray[ np.int64 ] ]: """Getter of the element mapping dictionary. diff --git a/geos-processing/src/geos/processing/generic_processing_tools/ClipToMainFrame.py b/geos-processing/src/geos/processing/generic_processing_tools/ClipToMainFrame.py index 6b95fbbae..459aa0eec 100644 --- a/geos-processing/src/geos/processing/generic_processing_tools/ClipToMainFrame.py +++ b/geos-processing/src/geos/processing/generic_processing_tools/ClipToMainFrame.py @@ -52,6 +52,7 @@ """ +loggerTitle : str = "ClipToMainFrame" class ClipToMainFrameElement( vtkLandmarkTransform ): @@ -218,7 +219,7 @@ def __getFramePoints( self, vpts: vtkPoints ) -> tuple[ vtkPoints, vtkPoints ]: class ClipToMainFrame( vtkTransformFilter ): """Filter to clip a mesh to the main frame using ClipToMainFrame class.""" - def __init__( self, speHandler: bool = False, **properties: str ) -> None: + def __init__( self, **properties: str ) -> None: """Initialize the ClipToMainFrame Filter with optional speHandler args and forwarding properties to main class. Args: @@ -228,12 +229,7 @@ def __init__( self, speHandler: bool = False, **properties: str ) -> None: """ super().__init__( **properties ) # Logger. - self.logger: Logger - if not speHandler: - self.logger = getLogger( loggerTitle, True ) - else: - self.logger = logging.getLogger( loggerTitle ) - self.logger.setLevel( logging.INFO ) + self.logger: Logger = getLogger( loggerTitle ) def ComputeTransform( self ) -> None: """Update the transformation.""" diff --git a/geos-processing/src/geos/processing/generic_processing_tools/CreateConstantAttributePerRegion.py b/geos-processing/src/geos/processing/generic_processing_tools/CreateConstantAttributePerRegion.py index 85e1fc74b..780e44902 100644 --- a/geos-processing/src/geos/processing/generic_processing_tools/CreateConstantAttributePerRegion.py +++ b/geos-processing/src/geos/processing/generic_processing_tools/CreateConstantAttributePerRegion.py @@ -50,7 +50,6 @@ valueNpType: type nbComponents: int componentNames: tuple[ str, ... ] - speHandler: bool # Instantiate the filter createConstantAttributePerRegionFilter: CreateConstantAttributePerRegion = CreateConstantAttributePerRegion( @@ -61,7 +60,6 @@ valueNpType, nbComponents, componentNames, - speHandler, ) # Set your handler (only if speHandler is True). @@ -86,7 +84,6 @@ def __init__( valueNpType: type = np.float32, nbComponents: int = 1, componentNames: tuple[ str, ...] = (), # noqa: C408 - speHandler: bool = False, ) -> None: """Create an attribute with constant value per region. @@ -123,33 +120,13 @@ def __init__( # Check if the new component have default values (information for the output message). self.useDefaultValue: bool = False - # Warnings counter. - self.counter: CountWarningHandler = CountWarningHandler() - self.counter.setLevel( logging.INFO ) - # Logger. - self.logger: Logger - if not speHandler: - self.logger = getLogger( loggerTitle, True ) - else: - self.logger = logging.getLogger( loggerTitle ) - self.logger.setLevel( logging.INFO ) + self.logger: Logger = getLogger(loggerTitle) # Warnings counter. - def setLoggerHandler( self: Self, handler: logging.Handler ) -> None: - """Set a specific handler for the filter logger. - - In this filter 4 log levels are use, .info, .error, .warning and .critical, - be sure to have at least the same 4 levels. - - Args: - handler (logging.Handler): The handler to add. - """ - if not self.logger.hasHandlers(): - self.logger.addHandler( handler ) - else: - # This warning does not count for the number of warning created during the application of the filter. - self.logger.warning( "The logger already has an handler, to use yours set the argument 'speHandler' to True" - " during the filter initialization." ) + self.counter: CountWarningHandler = CountWarningHandler() + self.counter.setLevel( logging.INFO ) + # Add the handler to count warnings messages. + self.logger.addHandler( self.counter ) def applyFilter( self: Self ) -> bool: """Create a constant attribute per region in the mesh. @@ -159,8 +136,6 @@ def applyFilter( self: Self ) -> bool: """ self.logger.info( f"Apply filter { self.logger.name }." ) - # Add the handler to count warnings messages. - self.logger.addHandler( self.counter ) # Check the validity of the attribute region. if self.onPoints is None: diff --git a/geos-processing/src/geos/processing/generic_processing_tools/MergeBlockEnhanced.py b/geos-processing/src/geos/processing/generic_processing_tools/MergeBlockEnhanced.py index 9bcfa5736..fd97c6ddb 100644 --- a/geos-processing/src/geos/processing/generic_processing_tools/MergeBlockEnhanced.py +++ b/geos-processing/src/geos/processing/generic_processing_tools/MergeBlockEnhanced.py @@ -65,7 +65,6 @@ class MergeBlockEnhanced: def __init__( self: Self, inputMesh: vtkMultiBlockDataSet, - speHandler: bool = False, ) -> None: """Merge a multiblock dataset and keep the partial attributes in the output mesh. @@ -83,26 +82,7 @@ def __init__( self.outputMesh: vtkUnstructuredGrid = vtkUnstructuredGrid() # Logger - self.logger: Logger - if not speHandler: - self.logger = getLogger( loggerTitle, True ) - else: - self.logger = logging.getLogger( loggerTitle ) - self.logger.setLevel( logging.INFO ) - - def setLoggerHandler( self: Self, handler: logging.Handler ) -> None: - """Set a specific handler for the filter logger. - - In this filter 4 log levels are use, .info, .error, .warning and .critical, be sure to have at least the same 4 levels. - - Args: - handler (logging.Handler): The handler to add. - """ - if not self.logger.hasHandlers(): - self.logger.addHandler( handler ) - else: - self.logger.warning( "The logger already has an handler, to use yours set the argument 'speHandler' to True" - " during the filter initialization." ) + self.logger: Logger = getLogger( loggerTitle) def applyFilter( self: Self ) -> None: """Merge the blocks of a multiblock dataset mesh. diff --git a/geos-processing/src/geos/processing/generic_processing_tools/SplitMesh.py b/geos-processing/src/geos/processing/generic_processing_tools/SplitMesh.py index f02ba010f..bc95e1296 100644 --- a/geos-processing/src/geos/processing/generic_processing_tools/SplitMesh.py +++ b/geos-processing/src/geos/processing/generic_processing_tools/SplitMesh.py @@ -60,6 +60,7 @@ output :vtkUnstructuredGrid = splitMeshFilter.GetOutputDataObject( 0 ) """ +loggerTitle: str = "SplitMesh" class SplitMesh( VTKPythonAlgorithmBase ): diff --git a/geos-processing/src/geos/processing/post_processing/SurfaceGeomechanics.py b/geos-processing/src/geos/processing/post_processing/SurfaceGeomechanics.py index 62fcd013a..49b9455a1 100644 --- a/geos-processing/src/geos/processing/post_processing/SurfaceGeomechanics.py +++ b/geos-processing/src/geos/processing/post_processing/SurfaceGeomechanics.py @@ -99,7 +99,7 @@ class SurfaceGeomechanics: - def __init__( self: Self, surfacicMesh: vtkPolyData, speHandler: bool = False ) -> None: + def __init__( self: Self, surfacicMesh: vtkPolyData) -> None: """Vtk filter to compute geomechanical surfacic attributes. Input and Output objects are a vtkPolydata with surfaces @@ -111,14 +111,10 @@ def __init__( self: Self, surfacicMesh: vtkPolyData, speHandler: bool = False ) Defaults to False. """ # Logger - self.logger: Logger - if not speHandler: - self.logger = getLogger( loggerTitle, True ) - else: - self.logger = logging.getLogger( loggerTitle ) - self.logger.setLevel( logging.INFO ) + self.logger: Logger= getLogger( loggerTitle ) # Input surfacic mesh + print(surfacicMesh) if not surfacicMesh.IsA( "vtkPolyData" ): self.logger.error( f"Input surface is expected to be a vtkPolyData, not a {type(surfacicMesh)}." ) self.inputMesh: vtkPolyData = surfacicMesh @@ -141,21 +137,6 @@ def __init__( self: Self, surfacicMesh: vtkPolyData, speHandler: bool = False ) # New created attributes names self.newAttributeNames: set[ str ] = set() - def SetLoggerHandler( self: Self, handler: Logger ) -> None: - """Set a specific handler for the filter logger. - - In this filter 4 log levels are use, .info, .error, .warning and .critical, be sure to have at least the same 4 levels. - - Args: - handler (logging.Handler): The handler to add. - """ - if not self.logger.hasHandlers(): - self.logger.addHandler( handler ) - else: - self.logger.warning( - "The logger already has an handler, to use yours set the argument 'speHandler' to True during the filter initialization." - ) - def SetSurfaceName( self: Self, name: str ) -> None: """Set a name for the input surface. For logging purpose only. diff --git a/geos-pv/src/geos/pv/plugins/PVAttributeMapping.py b/geos-pv/src/geos/pv/plugins/PVAttributeMapping.py index a8dfc28c2..2d1b0c5b5 100644 --- a/geos-pv/src/geos/pv/plugins/PVAttributeMapping.py +++ b/geos-pv/src/geos/pv/plugins/PVAttributeMapping.py @@ -14,13 +14,11 @@ update_paths() -from geos.processing.generic_processing_tools.AttributeMapping import AttributeMapping +from geos.processing.generic_processing_tools.AttributeMapping import AttributeMapping, loggerTitle +from geos.utils.Logger import addPluginLogSupport from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] VTKPythonAlgorithmBase, smdomain, smhint, smproperty, smproxy, ) -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 ( vtkInformation, @@ -69,6 +67,7 @@ dataTypes=[ "vtkDataSet", "vtkMultiBlockDataSet" ], composite_data_supported=True, ) +@addPluginLogSupport(loggerTitle=loggerTitle) class PVAttributeMapping( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: @@ -189,10 +188,10 @@ def RequestData( outData.ShallowCopy( meshTo ) attributeMappingFilter: AttributeMapping = AttributeMapping( meshFrom, outData, set( self.attributeNames ), - self.onPoints, True ) + self.onPoints ) - if not attributeMappingFilter.logger.hasHandlers(): - attributeMappingFilter.setLoggerHandler( VTKHandler() ) + # if not attributeMappingFilter.logger.hasHandlers(): + # attributeMappingFilter.setLoggerHandler( VTKHandler() ) attributeMappingFilter.applyFilter() self.clearAttributeNames = True diff --git a/geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py b/geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py index 1e52b0509..1907be2a8 100644 --- a/geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py +++ b/geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py @@ -23,7 +23,8 @@ update_paths() from geos.pv.utils.details import ( SISOFilter, FilterCategory ) -from geos.processing.generic_processing_tools.ClipToMainFrame import ClipToMainFrame +from geos.processing.generic_processing_tools.ClipToMainFrame import ClipToMainFrame, loggerTitle +from geos.utils.Logger import addPluginLogSupport __doc__ = """ Clip the input mesh to the main frame applying the correct LandmarkTransform @@ -39,13 +40,14 @@ @SISOFilter( category=FilterCategory.GEOS_UTILS, decoratedLabel="Clip to the main frame", decoratedType=[ "vtkMultiBlockDataSet", "vtkDataSet" ] ) +@addPluginLogSupport(loggerTitle=loggerTitle) class PVClipToMainFrame( VTKPythonAlgorithmBase ): def __init__( self ) -> None: """Init motherclass, filter and logger.""" - self._realFilter = ClipToMainFrame( speHandler=True ) - if not self._realFilter.logger.hasHandlers(): - self._realFilter.SetLoggerHandler( VTKHandler() ) + self._realFilter = ClipToMainFrame() + # if not self._realFilter.logger.hasHandlers(): + # self._realFilter.SetLoggerHandler( VTKHandler() ) def ApplyFilter( self, inputMesh: vtkMultiBlockDataSet, outputMesh: vtkMultiBlockDataSet ) -> None: """Is applying CreateConstantAttributePerRegion filter. diff --git a/geos-pv/src/geos/pv/plugins/PVCreateConstantAttributePerRegion.py b/geos-pv/src/geos/pv/plugins/PVCreateConstantAttributePerRegion.py index fb5782e97..f12a5eaee 100644 --- a/geos-pv/src/geos/pv/plugins/PVCreateConstantAttributePerRegion.py +++ b/geos-pv/src/geos/pv/plugins/PVCreateConstantAttributePerRegion.py @@ -12,9 +12,6 @@ from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] VTKPythonAlgorithmBase, smdomain, smproperty, ) # 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 import vtkmodules.util.numpy_support as vnp @@ -24,8 +21,12 @@ # update sys.path to load all GEOS Python Package dependencies geos_pv_path: Path = Path( __file__ ).parent.parent.parent.parent.parent sys.path.insert( 0, str( geos_pv_path / "src" ) ) +from geos.pv.utils.config import update_paths -from geos.processing.generic_processing_tools.CreateConstantAttributePerRegion import CreateConstantAttributePerRegion +update_paths() + +from geos.processing.generic_processing_tools.CreateConstantAttributePerRegion import CreateConstantAttributePerRegion, loggerTitle +from geos.utils.Logger import addPluginLogSupport from geos.pv.utils.details import SISOFilter, FilterCategory @@ -54,6 +55,7 @@ @SISOFilter( category=FilterCategory.GEOS_PROP, decoratedLabel="Create Constant Attribute Per Region", decoratedType=[ "vtkMultiBlockDataSet", "vtkDataSet" ] ) +@addPluginLogSupport(loggerTitle=loggerTitle) class PVCreateConstantAttributePerRegion( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: @@ -70,9 +72,6 @@ def __init__( self: Self ) -> None: self.nbComponents: int = 1 self.componentNames: tuple[ str, ...] = () - # Use the handler of paraview for the log. - self.speHandler: bool = True - # Settings of the attribute with the region indexes: @smproperty.stringvector( name="ChooseRegionAttribute", @@ -288,12 +287,8 @@ def ApplyFilter( self, inputMesh: vtkDataSet, outputMesh: vtkDataSet ) -> None: self.valueNpType, self.nbComponents, self.componentNames, - self.speHandler, ) - if not createConstantAttributePerRegionFilter.logger.hasHandlers(): - createConstantAttributePerRegionFilter.setLoggerHandler( VTKHandler() ) - createConstantAttributePerRegionFilter.applyFilter() self.clearDictRegion = True diff --git a/geos-pv/src/geos/pv/plugins/PVMergeBlocksEnhanced.py b/geos-pv/src/geos/pv/plugins/PVMergeBlocksEnhanced.py index 3ebcd7ebb..ff6dd88a3 100644 --- a/geos-pv/src/geos/pv/plugins/PVMergeBlocksEnhanced.py +++ b/geos-pv/src/geos/pv/plugins/PVMergeBlocksEnhanced.py @@ -10,8 +10,6 @@ from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] VTKPythonAlgorithmBase, smdomain, smhint, smproperty, smproxy, ) -from paraview.detail.loghandler import ( # type: ignore[import-not-found] - VTKHandler, ) from vtkmodules.vtkCommonCore import ( vtkInformation, vtkInformationVector, @@ -29,7 +27,8 @@ update_paths() -from geos.processing.generic_processing_tools.MergeBlockEnhanced import MergeBlockEnhanced +from geos.processing.generic_processing_tools.MergeBlockEnhanced import MergeBlockEnhanced, loggerTitle +from geos.utils.Logger import addPluginLogSupport __doc__ = """ Merge Blocks Keeping Partial Attributes is a Paraview plugin filter that allows to merge blocks from a multiblock dataset while keeping partial attributes. @@ -60,6 +59,7 @@ @smhint.xml( '' ) @smproperty.input( name="Input", port_index=0, label="Input" ) @smdomain.datatype( dataTypes=[ "vtkMultiBlockDataSet" ], composite_data_supported=True ) +@addPluginLogSupport(loggerTitle=loggerTitle) class PVMergeBlocksEnhanced( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: @@ -117,10 +117,7 @@ def RequestData( assert inputMesh is not None, "Input mesh is null." assert outputMesh is not None, "Output pipeline is null." - mergeBlockEnhancedFilter: MergeBlockEnhanced = MergeBlockEnhanced( inputMesh, True ) - - if not mergeBlockEnhancedFilter.logger.hasHandlers(): - mergeBlockEnhancedFilter.setLoggerHandler( VTKHandler() ) + mergeBlockEnhancedFilter: MergeBlockEnhanced = MergeBlockEnhanced( inputMesh ) try: mergeBlockEnhancedFilter.applyFilter() diff --git a/geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py b/geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py index 5b1179546..0604df4a5 100644 --- a/geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py +++ b/geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py @@ -3,7 +3,6 @@ # SPDX-FileContributor: Alexandre Benedicto, Martin Lemay, Paloma Martinez # ruff: noqa: E402 # disable Module level import not at top of file import sys -import logging from pathlib import Path from enum import Enum from typing import Any, Union, cast @@ -15,8 +14,7 @@ from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] VTKPythonAlgorithmBase, smdomain, smhint, smproperty, smproxy, ) -from paraview.detail.loghandler import ( # type: ignore[import-not-found] - VTKHandler, ) + from typing_extensions import Self from vtkmodules.vtkCommonCore import vtkDataArraySelection as vtkDAS @@ -31,13 +29,12 @@ update_paths() -from geos.geomechanics.model.MohrCircle import MohrCircle +from geos.geomechanics.model.MohrCircle import MohrCircle, loggerTitle from geos.utils.enumUnits import Pressure, enumerationDomainUnit from geos.utils.GeosOutputsConstants import ( FAILURE_ENVELOPE, GeosMeshOutputsEnum, ) -from geos.utils.Logger import CustomLoggerFormatter from geos.utils.PhysicalConstants import ( DEFAULT_FRICTION_ANGLE_DEG, DEFAULT_FRICTION_ANGLE_RAD, @@ -61,6 +58,7 @@ optionEnumToXml, ) from geos.pv.utils.mohrCircles.functionsMohrCircle import StressConventionEnum +from geos.utils.Logger import addPluginLogSupport __doc__ = """ PVMohrCirclePlot is a ParaView plugin that allows to compute and plot @@ -112,6 +110,7 @@ dataTypes=[ "vtkUnstructuredGrid" ], composite_data_supported=False, ) +@addPluginLogSupport(loggerTitle=loggerTitle) class PVMohrCirclePlot( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: @@ -187,13 +186,13 @@ def __init__( self: Self ) -> None: self.requestDataStep: int = -1 # Logger - self.logger: logging.Logger = logging.getLogger( "MohrCircle" ) - self.logger.setLevel( logging.INFO ) - if not self.logger.hasHandlers(): - handler = VTKHandler() - handler.setFormatter( CustomLoggerFormatter( False ) ) + # self.logger: logging.Logger = logging.getLogger( "MohrCircle" ) + # self.logger.setLevel( logging.INFO ) + # if not self.logger.hasHandlers(): + # handler = VTKHandler() + # handler.setFormatter( CustomLoggerFormatter( False ) ) - self.logger.addHandler( handler ) + # self.logger.addHandler( handler ) @smproperty.xml( """ None: diff --git a/geos-pv/src/geos/pv/plugins/PVSurfaceGeomechanics.py b/geos-pv/src/geos/pv/plugins/PVSurfaceGeomechanics.py index 3999d620c..6c0b1ca43 100644 --- a/geos-pv/src/geos/pv/plugins/PVSurfaceGeomechanics.py +++ b/geos-pv/src/geos/pv/plugins/PVSurfaceGeomechanics.py @@ -10,8 +10,7 @@ from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] VTKPythonAlgorithmBase, smdomain, smproperty, ) -from paraview.detail.loghandler import ( # type: ignore[import-not-found] - VTKHandler, ) + # update sys.path to load all GEOS Python Package dependencies geos_pv_path: Path = Path( __file__ ).parent.parent.parent.parent.parent @@ -25,7 +24,9 @@ DEFAULT_FRICTION_ANGLE_DEG, DEFAULT_ROCK_COHESION, ) -from geos.processing.post_processing.SurfaceGeomechanics import SurfaceGeomechanics +from geos.processing.post_processing.SurfaceGeomechanics import SurfaceGeomechanics, loggerTitle +from geos.utils.Logger import addPluginLogSupport + from geos.mesh.utils.multiblockHelpers import ( getBlockElementIndexesFlatten, getBlockFromFlatIndex, @@ -62,6 +63,7 @@ @SISOFilter( category=FilterCategory.GEOS_GEOMECHANICS, decoratedLabel="Geos Surface Geomechanics", decoratedType="vtkMultiBlockDataSet" ) +@addPluginLogSupport(loggerTitle=loggerTitle) class PVSurfaceGeomechanics( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: @@ -129,10 +131,8 @@ def ApplyFilter( self: Self, inputMesh: vtkMultiBlockDataSet, outputMesh: vtkMul for blockIndex in surfaceBlockIndexes: surfaceBlock: vtkPolyData = vtkPolyData.SafeDownCast( getBlockFromFlatIndex( outputMesh, blockIndex ) ) - sgFilter: SurfaceGeomechanics = SurfaceGeomechanics( surfaceBlock, True ) + sgFilter: SurfaceGeomechanics = SurfaceGeomechanics( surfaceBlock ) sgFilter.SetSurfaceName( f"blockIndex {blockIndex}" ) - if not sgFilter.logger.hasHandlers(): - sgFilter.SetLoggerHandler( VTKHandler() ) sgFilter.SetRockCohesion( self._getRockCohesion() ) sgFilter.SetFrictionAngle( self._getFrictionAngle() ) diff --git a/geos-pv/src/geos/pv/utils/paraviewTreatments.py b/geos-pv/src/geos/pv/utils/paraviewTreatments.py index 36aad6b1b..f0ee3e68f 100644 --- a/geos-pv/src/geos/pv/utils/paraviewTreatments.py +++ b/geos-pv/src/geos/pv/utils/paraviewTreatments.py @@ -37,7 +37,6 @@ ComponentNameEnum, GeosMeshOutputsEnum, ) -from geos.utils.Logger import ( CustomLoggerFormatter ) from geos.mesh.utils.multiblockModifiers import mergeBlocks # valid sources for Python view configurator @@ -484,12 +483,8 @@ def getVtkOriginalCellIds( mesh: Union[ vtkMultiBlockDataSet, vtkCompositeDataSe list[str]: ids of the cells. """ if logger is None: - logger = logging.getLogger( "getVtkOriginalCellIds" ) + logger = getLogger( "getVtkOriginalCellIds" ) - if not logger.hasHandlers(): - handler = VTKHandler() - handler.setFormatter( CustomLoggerFormatter( False ) ) - logger.addHandler( handler ) # Merge blocks for vtkCompositeDataSet mesh2: vtkUnstructuredGrid = mergeBlocks( mesh, logger=logger ) diff --git a/geos-utils/src/geos/utils/Logger.py b/geos-utils/src/geos/utils/Logger.py index 7085dd0cb..31c7f0fc2 100644 --- a/geos-utils/src/geos/utils/Logger.py +++ b/geos-utils/src/geos/utils/Logger.py @@ -60,12 +60,12 @@ def decorator( cls: Type[ T ] ) -> Type[ T ]: @wraps( original_init ) def new_init( self: T, *args: Any, **kwargs: Any ) -> None: + original_init( self, *args, **kwargs ) logger = getLogger( loggerTitle ) for hdlr in list( filter( lambda x: not isinstance( x, GEOSHandler ), logger.handlers ) ): logger.removeHandler( hdlr ) - original_init( self, *args, **kwargs ) cls.__init__ = new_init # type: ignore[assignment] From c489a57aef4c7d72276bc54245222ef343555a5d Mon Sep 17 00:00:00 2001 From: jacques franc Date: Wed, 26 Nov 2025 09:02:18 +0100 Subject: [PATCH 15/20] first batch --- .../ClipToMainFrame.py | 16 +------- .../generic_processing_tools/SplitMesh.py | 38 ++++--------------- .../pre_processing/CellTypeCounterEnhanced.py | 23 +---------- .../pre_processing/MeshQualityEnhanced.py | 38 +++---------------- .../src/geos/pv/plugins/PVAttributeMapping.py | 2 +- .../pv/plugins/PVCellTypeCounterEnhanced.py | 4 +- .../src/geos/pv/plugins/PVClipToMainFrame.py | 2 +- .../PVCreateConstantAttributePerRegion.py | 2 +- .../geos/pv/plugins/PVFillPartialArrays.py | 2 +- .../geos/pv/plugins/PVMergeBlocksEnhanced.py | 2 +- .../geos/pv/plugins/PVMeshQualityEnhanced.py | 7 +++- geos-pv/src/geos/pv/plugins/PVSplitMesh.py | 5 ++- .../geos/pv/plugins/PVSurfaceGeomechanics.py | 2 +- geos-utils/src/geos/utils/Logger.py | 11 ++++-- 14 files changed, 39 insertions(+), 115 deletions(-) diff --git a/geos-processing/src/geos/processing/generic_processing_tools/ClipToMainFrame.py b/geos-processing/src/geos/processing/generic_processing_tools/ClipToMainFrame.py index 459aa0eec..4b4366b34 100644 --- a/geos-processing/src/geos/processing/generic_processing_tools/ClipToMainFrame.py +++ b/geos-processing/src/geos/processing/generic_processing_tools/ClipToMainFrame.py @@ -250,21 +250,7 @@ def ComputeTransform( self ) -> None: clip.Update() self.SetTransform( clip ) - - def SetLoggerHandler( self, handler: logging.Handler ) -> None: - """Set a specific handler for the filter logger. - - In this filter 4 log levels are use, .info, .error, .warning and .critical, - be sure to have at least the same 4 levels. - - Args: - handler (logging.Handler): The handler to add. - """ - if not self.logger.hasHandlers(): - self.logger.addHandler( handler ) - else: - self.logger.warning( "The logger already has an handler, to use yours set the argument 'speHandler' to True" - " during the filter initialization." ) + self.logger.info( "ClipToMainFrame applied successfully." ) def __locate_reference_point( self, multiBlockDataSet: vtkMultiBlockDataSet ) -> int: """Locate the block to use as reference for the transformation. diff --git a/geos-processing/src/geos/processing/generic_processing_tools/SplitMesh.py b/geos-processing/src/geos/processing/generic_processing_tools/SplitMesh.py index d1e4ae361..4e4d6da49 100644 --- a/geos-processing/src/geos/processing/generic_processing_tools/SplitMesh.py +++ b/geos-processing/src/geos/processing/generic_processing_tools/SplitMesh.py @@ -51,7 +51,7 @@ class SplitMesh(): - def __init__( self, inputMesh: vtkUnstructuredGrid, speHandler: bool = False ) -> None: + def __init__( self, inputMesh: vtkUnstructuredGrid) -> None: """SplitMesh filter splits each cell using edge centers. Args: @@ -65,32 +65,12 @@ def __init__( self, inputMesh: vtkUnstructuredGrid, speHandler: bool = False ) - self.points: vtkPoints self.originalId: vtkIdTypeArray self.cellTypes: list[ int ] - self.speHandler: bool = speHandler - self.handler: None | logging.Handler = None + #subordonate filter + self.cellTypeCounterEnhancedFilter: CellTypeCounterEnhanced = CellTypeCounterEnhanced( + self.inputMesh) # Logger - self.logger: Logger - if not speHandler: - self.logger = getLogger( loggerTitle, True ) - else: - self.logger = logging.getLogger( loggerTitle ) - self.logger.setLevel( logging.INFO ) - self.logger.propagate = False - - def setLoggerHandler( self: Self, handler: logging.Handler ) -> None: - """Set a specific handler for the filter logger. - - In this filter 4 log levels are use, .info, .error, .warning and .critical, be sure to have at least the same 4 levels. - - Args: - handler (logging.Handler): The handler to add. - """ - self.handler = handler - if len( self.logger.handlers ) == 0: - self.logger.addHandler( handler ) - else: - self.logger.warning( "The logger already has an handler, to use yours set the argument 'speHandler' to True" - " during the filter initialization." ) + self.logger: Logger = getLogger( loggerTitle ) def applyFilter( self: Self ) -> bool: """Apply the filter SplitMesh. @@ -185,13 +165,9 @@ def _getCellCounts( self: Self ) -> CellTypeCounts: Returns: CellTypeCounts: cell type counts """ - cellTypeCounterEnhancedFilter: CellTypeCounterEnhanced = CellTypeCounterEnhanced( - self.inputMesh, self.speHandler ) - if self.speHandler and len( cellTypeCounterEnhancedFilter.logger.handlers ) == 0: - cellTypeCounterEnhancedFilter.setLoggerHandler( self.handler ) - if not cellTypeCounterEnhancedFilter.applyFilter(): + if not self.cellTypeCounterEnhancedFilter.applyFilter(): raise - return cellTypeCounterEnhancedFilter.GetCellTypeCountsObject() + return self.cellTypeCounterEnhancedFilter.GetCellTypeCountsObject() def _addMidPoint( self: Self, ptA: int, ptB: int ) -> int: """Add a point at the center of the edge defined by input point ids. diff --git a/geos-processing/src/geos/processing/pre_processing/CellTypeCounterEnhanced.py b/geos-processing/src/geos/processing/pre_processing/CellTypeCounterEnhanced.py index 3aa8953ac..45b1cd77c 100644 --- a/geos-processing/src/geos/processing/pre_processing/CellTypeCounterEnhanced.py +++ b/geos-processing/src/geos/processing/pre_processing/CellTypeCounterEnhanced.py @@ -63,28 +63,7 @@ def __init__( self._counts: CellTypeCounts = CellTypeCounts() # Logger. - self.logger: Logger - if not speHandler: - self.logger = getLogger( loggerTitle, True ) - else: - self.logger = logging.getLogger( loggerTitle ) - self.logger.setLevel( logging.INFO ) - self.logger.propagate = False - - def setLoggerHandler( self: Self, handler: logging.Handler ) -> None: - """Set a specific handler for the filter logger. - - In this filter 4 log levels are use, .info, .error, .warning and .critical, - be sure to have at least the same 4 levels. - - Args: - handler (logging.Handler): The handler to add. - """ - if len( self.logger.handlers ) == 0: - self.logger.addHandler( handler ) - else: - self.logger.warning( "The logger already has an handler, to use yours set the argument 'speHandler'" - " to True during the filter initialization." ) + self.logger: Logger = getLogger( loggerTitle ) def applyFilter( self: Self ) -> bool: """Apply CellTypeCounterEnhanced filter. diff --git a/geos-processing/src/geos/processing/pre_processing/MeshQualityEnhanced.py b/geos-processing/src/geos/processing/pre_processing/MeshQualityEnhanced.py index 6c454c69e..15d34ca6a 100644 --- a/geos-processing/src/geos/processing/pre_processing/MeshQualityEnhanced.py +++ b/geos-processing/src/geos/processing/pre_processing/MeshQualityEnhanced.py @@ -95,7 +95,6 @@ class MeshQualityEnhanced(): def __init__( self: Self, inputMesh: vtkUnstructuredGrid, - speHandler: bool = False, ) -> None: """Enhanced vtkMeshQuality filter. @@ -125,32 +124,11 @@ def __init__( self._allCellTypesExtended: tuple[ int, ...] = getAllCellTypesExtended() self._allCellTypes: tuple[ int, ...] = getAllCellTypes() + #deps + self.cellTypeCounterEnhancedFilter: CellTypeCounterEnhanced = CellTypeCounterEnhanced(self._outputMesh) + # Logger. - self.speHandler: bool = speHandler - self.handler: None | logging.Handler = None - self.logger: Logger - if not speHandler: - self.logger = getLogger( loggerTitle, True ) - else: - self.logger = logging.getLogger( loggerTitle ) - self.logger.setLevel( logging.INFO ) - self.logger.propagate = False - - def setLoggerHandler( self: Self, handler: logging.Handler ) -> None: - """Set a specific handler for the filter logger. - - In this filter 4 log levels are use, .info, .error, .warning and .critical, - be sure to have at least the same 4 levels. - - Args: - handler (logging.Handler): The handler to add. - """ - self.handler = handler - if len( self.logger.handlers ) == 0: - self.logger.addHandler( handler ) - else: - self.logger.warning( "The logger already has an handler, to use yours set the argument 'speHandler'" - " to True during the filter initialization." ) + self.logger: Logger = getLogger( loggerTitle ) def GetQualityMetricSummary( self: Self ) -> QualityMetricSummary: """Get QualityMetricSummary object. @@ -322,14 +300,10 @@ def getOutput( self: Self ) -> vtkUnstructuredGrid: def _computeCellTypeCounts( self: Self ) -> None: """Compute cell type counts.""" - cellTypeCounterEnhancedFilter: CellTypeCounterEnhanced = CellTypeCounterEnhanced( - self._outputMesh, self.speHandler ) - if self.speHandler and len( cellTypeCounterEnhancedFilter.logger.handlers ) == 0: - cellTypeCounterEnhancedFilter.setLoggerHandler( self.handler ) - if not cellTypeCounterEnhancedFilter.applyFilter(): + if not self.cellTypeCounterEnhancedFilter.applyFilter(): raise - counts: CellTypeCounts = cellTypeCounterEnhancedFilter.GetCellTypeCountsObject() + counts: CellTypeCounts = self.cellTypeCounterEnhancedFilter.GetCellTypeCountsObject() if counts is None: raise AttributeError( "CellTypeCounts is undefined" ) diff --git a/geos-pv/src/geos/pv/plugins/PVAttributeMapping.py b/geos-pv/src/geos/pv/plugins/PVAttributeMapping.py index 2d1b0c5b5..89f9207d8 100644 --- a/geos-pv/src/geos/pv/plugins/PVAttributeMapping.py +++ b/geos-pv/src/geos/pv/plugins/PVAttributeMapping.py @@ -67,7 +67,7 @@ dataTypes=[ "vtkDataSet", "vtkMultiBlockDataSet" ], composite_data_supported=True, ) -@addPluginLogSupport(loggerTitle=loggerTitle) +@addPluginLogSupport(loggerTitles=[loggerTitle]) class PVAttributeMapping( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: diff --git a/geos-pv/src/geos/pv/plugins/PVCellTypeCounterEnhanced.py b/geos-pv/src/geos/pv/plugins/PVCellTypeCounterEnhanced.py index ad237bd83..44bef3c46 100644 --- a/geos-pv/src/geos/pv/plugins/PVCellTypeCounterEnhanced.py +++ b/geos-pv/src/geos/pv/plugins/PVCellTypeCounterEnhanced.py @@ -21,8 +21,9 @@ update_paths() -from geos.processing.pre_processing.CellTypeCounterEnhanced import CellTypeCounterEnhanced +from geos.processing.pre_processing.CellTypeCounterEnhanced import CellTypeCounterEnhanced, loggerTitle from geos.mesh.model.CellTypeCounts import CellTypeCounts +from geos.utils.Logger import addPluginLogSupport __doc__ = """ The ``Cell Type Counter Enhanced`` filter computes cell type counts. Counts can be exported into a file easily. @@ -43,6 +44,7 @@ dataTypes=[ "vtkUnstructuredGrid" ], composite_data_supported=True, ) +@addPluginLogSupport(loggerTitles=[loggerTitle]) class PVCellTypeCounterEnhanced( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: diff --git a/geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py b/geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py index 1907be2a8..af03bd66a 100644 --- a/geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py +++ b/geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py @@ -40,7 +40,7 @@ @SISOFilter( category=FilterCategory.GEOS_UTILS, decoratedLabel="Clip to the main frame", decoratedType=[ "vtkMultiBlockDataSet", "vtkDataSet" ] ) -@addPluginLogSupport(loggerTitle=loggerTitle) +@addPluginLogSupport(loggerTitles=[loggerTitle]) class PVClipToMainFrame( VTKPythonAlgorithmBase ): def __init__( self ) -> None: diff --git a/geos-pv/src/geos/pv/plugins/PVCreateConstantAttributePerRegion.py b/geos-pv/src/geos/pv/plugins/PVCreateConstantAttributePerRegion.py index f12a5eaee..d8914558f 100644 --- a/geos-pv/src/geos/pv/plugins/PVCreateConstantAttributePerRegion.py +++ b/geos-pv/src/geos/pv/plugins/PVCreateConstantAttributePerRegion.py @@ -55,7 +55,7 @@ @SISOFilter( category=FilterCategory.GEOS_PROP, decoratedLabel="Create Constant Attribute Per Region", decoratedType=[ "vtkMultiBlockDataSet", "vtkDataSet" ] ) -@addPluginLogSupport(loggerTitle=loggerTitle) +@addPluginLogSupport(loggerTitles=[loggerTitle]) class PVCreateConstantAttributePerRegion( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: diff --git a/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py b/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py index 029b8672c..6bdec9395 100644 --- a/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py +++ b/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py @@ -44,7 +44,7 @@ @SISOFilter( category=FilterCategory.GEOS_UTILS, decoratedLabel="Fill Partial Arrays", decoratedType="vtkMultiBlockDataSet" ) -@addPluginLogSupport( loggerTitle=loggerTitle ) +@addPluginLogSupport( loggerTitles=[loggerTitle] ) class PVFillPartialArrays( VTKPythonAlgorithmBase ): def __init__( self: Self, ) -> None: diff --git a/geos-pv/src/geos/pv/plugins/PVMergeBlocksEnhanced.py b/geos-pv/src/geos/pv/plugins/PVMergeBlocksEnhanced.py index ff6dd88a3..c140662d8 100644 --- a/geos-pv/src/geos/pv/plugins/PVMergeBlocksEnhanced.py +++ b/geos-pv/src/geos/pv/plugins/PVMergeBlocksEnhanced.py @@ -59,7 +59,7 @@ @smhint.xml( '' ) @smproperty.input( name="Input", port_index=0, label="Input" ) @smdomain.datatype( dataTypes=[ "vtkMultiBlockDataSet" ], composite_data_supported=True ) -@addPluginLogSupport(loggerTitle=loggerTitle) +@addPluginLogSupport(loggerTitles=[loggerTitle]) class PVMergeBlocksEnhanced( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: diff --git a/geos-pv/src/geos/pv/plugins/PVMeshQualityEnhanced.py b/geos-pv/src/geos/pv/plugins/PVMeshQualityEnhanced.py index 9384f92fb..3010055dd 100644 --- a/geos-pv/src/geos/pv/plugins/PVMeshQualityEnhanced.py +++ b/geos-pv/src/geos/pv/plugins/PVMeshQualityEnhanced.py @@ -22,7 +22,8 @@ update_paths() from geos.mesh.model.QualityMetricSummary import QualityMetricSummary -from geos.processing.pre_processing.MeshQualityEnhanced import MeshQualityEnhanced +from geos.processing.pre_processing.MeshQualityEnhanced import MeshQualityEnhanced, loggerTitle +from geos.processing.pre_processing.CellTypeCounterEnhanced import loggerTitle as cloggerTitle from geos.mesh.stats.meshQualityMetricHelpers import ( getQualityMetricsOther, getQualityMeasureNameFromIndex, getQualityMeasureIndexFromName, getQuadQualityMeasure, getTriangleQualityMeasure, getCommonPolygonQualityMeasure, @@ -32,6 +33,7 @@ from geos.pv.utils.checkboxFunction import createModifiedCallback # type: ignore[attr-defined] from geos.pv.utils.paraviewTreatments import getArrayChoices from geos.pv.utils.details import ( SISOFilter, FilterCategory ) +from geos.utils.Logger import addPluginLogSupport __doc__ = """ The ``Mesh Quality Enhanced`` filter computes requested mesh quality metrics on meshes. Both surfaces and volumic metrics can be computed with this plugin. @@ -59,6 +61,7 @@ @SISOFilter( category=FilterCategory.GEOS_QC, decoratedLabel="Mesh Quality Enhanced", decoratedType="vtkUnstructuredGrid" ) +@addPluginLogSupport(loggerTitles=[loggerTitle,cloggerTitle]) class PVMeshQualityEnhanced( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: @@ -228,7 +231,7 @@ def ApplyFilter( self, inputMesh: vtkUnstructuredGrid, outputMesh: vtkUnstructur self._getQualityMetricsToUse( self._HexQualityMetric ) ) otherMetrics: set[ int ] = self._getQualityMetricsToUse( self._commonMeshQualityMetric ) - meshQualityEnhancedFilter: MeshQualityEnhanced = MeshQualityEnhanced( inputMesh, True ) + meshQualityEnhancedFilter: MeshQualityEnhanced = MeshQualityEnhanced( inputMesh ) if len( meshQualityEnhancedFilter.logger.handlers ) == 0: meshQualityEnhancedFilter.setLoggerHandler( VTKHandler() ) meshQualityEnhancedFilter.SetCellQualityMetrics( triangleMetrics=triangleMetrics, diff --git a/geos-pv/src/geos/pv/plugins/PVSplitMesh.py b/geos-pv/src/geos/pv/plugins/PVSplitMesh.py index 59f81ca11..9b11220c8 100644 --- a/geos-pv/src/geos/pv/plugins/PVSplitMesh.py +++ b/geos-pv/src/geos/pv/plugins/PVSplitMesh.py @@ -20,6 +20,7 @@ update_paths() from geos.processing.generic_processing_tools.SplitMesh import (SplitMesh, loggerTitle) +from geos.processing.pre_processing.CellTypeCounterEnhanced import loggerTitle as cloggerTitle from geos.pv.utils.details import (SISOFilter, FilterCategory) from geos.utils.Logger import addPluginLogSupport @@ -38,7 +39,7 @@ @SISOFilter( category=FilterCategory.GEOS_UTILS, decoratedLabel="Split Mesh", decoratedType="vtkPointSet" ) -@addPluginLogSupport(loggerTitle=loggerTitle) +@addPluginLogSupport(loggerTitles=[loggerTitle, cloggerTitle]) class PVSplitMesh( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: @@ -52,7 +53,7 @@ def ApplyFilter( self: Self, inputMesh: vtkPointSet, outputMesh: vtkPointSet ) - inputMesh(vtkPointSet): Input mesh. outputMesh: Output mesh. """ - splitMeshFilter: SplitMesh = SplitMesh( inputMesh, True ) + splitMeshFilter: SplitMesh = SplitMesh( inputMesh ) if len( splitMeshFilter.logger.handlers ) == 0: splitMeshFilter.setLoggerHandler( VTKHandler() ) if splitMeshFilter.applyFilter(): diff --git a/geos-pv/src/geos/pv/plugins/PVSurfaceGeomechanics.py b/geos-pv/src/geos/pv/plugins/PVSurfaceGeomechanics.py index 6c0b1ca43..bdc19202d 100644 --- a/geos-pv/src/geos/pv/plugins/PVSurfaceGeomechanics.py +++ b/geos-pv/src/geos/pv/plugins/PVSurfaceGeomechanics.py @@ -63,7 +63,7 @@ @SISOFilter( category=FilterCategory.GEOS_GEOMECHANICS, decoratedLabel="Geos Surface Geomechanics", decoratedType="vtkMultiBlockDataSet" ) -@addPluginLogSupport(loggerTitle=loggerTitle) +@addPluginLogSupport(loggerTitles=[loggerTitle]) class PVSurfaceGeomechanics( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: diff --git a/geos-utils/src/geos/utils/Logger.py b/geos-utils/src/geos/utils/Logger.py index 31c7f0fc2..c24719227 100644 --- a/geos-utils/src/geos/utils/Logger.py +++ b/geos-utils/src/geos/utils/Logger.py @@ -48,7 +48,7 @@ T = TypeVar( 'T' ) -def addPluginLogSupport( loggerTitle: str ) -> Callable[ [ Type[ T ] ], Type[ T ] ]: +def addPluginLogSupport( loggerTitles: list ) -> Callable[ [ Type[ T ] ], Type[ T ] ]: """Decorator to add logger support in the class following existing architecture. Args: @@ -62,9 +62,12 @@ def decorator( cls: Type[ T ] ) -> Type[ T ]: def new_init( self: T, *args: Any, **kwargs: Any ) -> None: original_init( self, *args, **kwargs ) - logger = getLogger( loggerTitle ) - for hdlr in list( filter( lambda x: not isinstance( x, GEOSHandler ), logger.handlers ) ): - logger.removeHandler( hdlr ) + # logger = getLogger( loggerTitle ) + for logger in loggerTitles: + # if not isinstance(logger, logging.PlaceHolder ): + for hdlr in list( filter( lambda x: not isinstance( x, GEOSHandler ), getLogger(logger).handlers ) ): + getLogger(logger).removeHandler( hdlr ) + cls.__init__ = new_init # type: ignore[assignment] From 5477cce3b791bfb26286de92c44a554d18e4b47e Mon Sep 17 00:00:00 2001 From: jacques franc Date: Wed, 26 Nov 2025 11:55:32 +0100 Subject: [PATCH 16/20] fin first pass --- .../generic_processing_tools/ClipToMainFrame.py | 2 +- .../processing/pre_processing/CellTypeCounterEnhanced.py | 1 - .../processing/pre_processing/MeshQualityEnhanced.py | 3 +-- geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py | 9 +++------ geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py | 5 +---- .../src/geos/pv/plugins/PVGeosBlockExtractAndMerge.py | 8 +------- geos-pv/src/geos/pv/plugins/PVMergeBlocksEnhanced.py | 2 +- 7 files changed, 8 insertions(+), 22 deletions(-) diff --git a/geos-processing/src/geos/processing/generic_processing_tools/ClipToMainFrame.py b/geos-processing/src/geos/processing/generic_processing_tools/ClipToMainFrame.py index 4b4366b34..41272716d 100644 --- a/geos-processing/src/geos/processing/generic_processing_tools/ClipToMainFrame.py +++ b/geos-processing/src/geos/processing/generic_processing_tools/ClipToMainFrame.py @@ -250,7 +250,7 @@ def ComputeTransform( self ) -> None: clip.Update() self.SetTransform( clip ) - self.logger.info( "ClipToMainFrame applied successfully." ) + self.logger.info( f"{self.logger.name} applied successfully." ) def __locate_reference_point( self, multiBlockDataSet: vtkMultiBlockDataSet ) -> int: """Locate the block to use as reference for the transformation. diff --git a/geos-processing/src/geos/processing/pre_processing/CellTypeCounterEnhanced.py b/geos-processing/src/geos/processing/pre_processing/CellTypeCounterEnhanced.py index 45b1cd77c..34d28e824 100644 --- a/geos-processing/src/geos/processing/pre_processing/CellTypeCounterEnhanced.py +++ b/geos-processing/src/geos/processing/pre_processing/CellTypeCounterEnhanced.py @@ -49,7 +49,6 @@ class CellTypeCounterEnhanced(): def __init__( self: Self, inputMesh: vtkUnstructuredGrid, - speHandler: bool = False, ) -> None: """CellTypeCounterEnhanced filter computes mesh stats. diff --git a/geos-processing/src/geos/processing/pre_processing/MeshQualityEnhanced.py b/geos-processing/src/geos/processing/pre_processing/MeshQualityEnhanced.py index 15d34ca6a..3a76e0ec0 100644 --- a/geos-processing/src/geos/processing/pre_processing/MeshQualityEnhanced.py +++ b/geos-processing/src/geos/processing/pre_processing/MeshQualityEnhanced.py @@ -100,7 +100,6 @@ def __init__( Args: inputMesh (vtkUnstructuredGrid): Input mesh - speHandler (bool, optional): True to use a specific handler, False to use the internal handler. Defaults to False. """ self.inputMesh: vtkUnstructuredGrid = inputMesh @@ -126,7 +125,7 @@ def __init__( #deps self.cellTypeCounterEnhancedFilter: CellTypeCounterEnhanced = CellTypeCounterEnhanced(self._outputMesh) - + # Logger. self.logger: Logger = getLogger( loggerTitle ) diff --git a/geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py b/geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py index af03bd66a..46c3fbf7f 100644 --- a/geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py +++ b/geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py @@ -8,9 +8,6 @@ from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] VTKPythonAlgorithmBase, ) # 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.vtkCommonDataModel import ( vtkMultiBlockDataSet, ) @@ -24,7 +21,7 @@ from geos.pv.utils.details import ( SISOFilter, FilterCategory ) from geos.processing.generic_processing_tools.ClipToMainFrame import ClipToMainFrame, loggerTitle -from geos.utils.Logger import addPluginLogSupport +from geos.utils.Logger import Logger, addPluginLogSupport __doc__ = """ Clip the input mesh to the main frame applying the correct LandmarkTransform @@ -46,8 +43,8 @@ class PVClipToMainFrame( VTKPythonAlgorithmBase ): def __init__( self ) -> None: """Init motherclass, filter and logger.""" self._realFilter = ClipToMainFrame() - # if not self._realFilter.logger.hasHandlers(): - # self._realFilter.SetLoggerHandler( VTKHandler() ) + self.logger : Logger = getLogger( loggerTitle ) + self.logger.info( f"Applying plugin {self.logger.name}." ) def ApplyFilter( self, inputMesh: vtkMultiBlockDataSet, outputMesh: vtkMultiBlockDataSet ) -> None: """Is applying CreateConstantAttributePerRegion filter. diff --git a/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py b/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py index 6bdec9395..28f5dcc33 100644 --- a/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py +++ b/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py @@ -51,10 +51,7 @@ def __init__( self: Self, ) -> None: """Fill a partial attribute with constant value per component.""" self.clearDictAttributesValues: bool = True self.dictAttributesValues: dict[ str, Union[ list[ Any ], None ] ] = {} - #remove noisy loggers to get clean OutputMessage windows - # self.logger = getLogger( loggerTitle ) - # for hdlr in list(filter(lambda x : not isinstance(x, GEOSHandler), self.logger.handlers)): - # self.logger.removeHandler(hdlr) + @smproperty.xml( """ None: @@ -114,11 +113,6 @@ def __init__( self: Self ) -> None: self.outputCellsT0: vtkMultiBlockDataSet = vtkMultiBlockDataSet() - self.logger = logging.getLogger( loggerTitle ) - self.logger.setLevel( logging.INFO ) - self.logger.addHandler( VTKHandler() ) - self.logger.propagate = False - self.logger.info( f"Apply plugin { self.logger.name }." ) def RequestDataObject( diff --git a/geos-pv/src/geos/pv/plugins/PVMergeBlocksEnhanced.py b/geos-pv/src/geos/pv/plugins/PVMergeBlocksEnhanced.py index c140662d8..bf2dde72b 100644 --- a/geos-pv/src/geos/pv/plugins/PVMergeBlocksEnhanced.py +++ b/geos-pv/src/geos/pv/plugins/PVMergeBlocksEnhanced.py @@ -59,7 +59,7 @@ @smhint.xml( '' ) @smproperty.input( name="Input", port_index=0, label="Input" ) @smdomain.datatype( dataTypes=[ "vtkMultiBlockDataSet" ], composite_data_supported=True ) -@addPluginLogSupport(loggerTitles=[loggerTitle]) +@addPluginLogSupport(loggerTitles=[loggerTitle, f"{loggerTitle}.vtkErrorLogger" ]) class PVMergeBlocksEnhanced( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: From 54864266bf59048ea7cf175fcd50b9aff7241b8c Mon Sep 17 00:00:00 2001 From: jacques franc Date: Wed, 26 Nov 2025 12:09:18 +0100 Subject: [PATCH 17/20] revert changes for complex plugins --- .../pv/plugins/PVGeosBlockExtractAndMerge.py | 8 ++++++- .../src/geos/pv/plugins/PVMohrCirclePlot.py | 23 ++++++++++--------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/geos-pv/src/geos/pv/plugins/PVGeosBlockExtractAndMerge.py b/geos-pv/src/geos/pv/plugins/PVGeosBlockExtractAndMerge.py index 5f622394b..c779c5eb1 100644 --- a/geos-pv/src/geos/pv/plugins/PVGeosBlockExtractAndMerge.py +++ b/geos-pv/src/geos/pv/plugins/PVGeosBlockExtractAndMerge.py @@ -32,6 +32,8 @@ from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] VTKPythonAlgorithmBase, smdomain, smproperty, smproxy ) +from paraview.detail.loghandler import ( # type: ignore[import-not-found] + VTKHandler ) __doc__ = """ PVGeosBlockExtractAndMerge is a Paraview plugin processing the input mesh at the current time in two steps: @@ -85,7 +87,6 @@ """ ) @smproperty.input( name="Input", port_index=0 ) @smdomain.datatype( dataTypes=[ "vtkMultiBlockDataSet" ], composite_data_supported=True ) -@addPluginLogSupport(loggerTitles=[loggerTitle]) class PVGeosBlockExtractAndMerge( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: @@ -113,6 +114,11 @@ def __init__( self: Self ) -> None: self.outputCellsT0: vtkMultiBlockDataSet = vtkMultiBlockDataSet() + self.logger = logging.getLogger( loggerTitle ) + self.logger.setLevel( logging.INFO ) + self.logger.addHandler( VTKHandler() ) + self.logger.propagate = False + self.logger.info( f"Apply plugin { self.logger.name }." ) def RequestDataObject( diff --git a/geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py b/geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py index 0604df4a5..378f4aeb3 100644 --- a/geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py +++ b/geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py @@ -3,6 +3,7 @@ # SPDX-FileContributor: Alexandre Benedicto, Martin Lemay, Paloma Martinez # ruff: noqa: E402 # disable Module level import not at top of file import sys +import logging from pathlib import Path from enum import Enum from typing import Any, Union, cast @@ -14,7 +15,8 @@ from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] VTKPythonAlgorithmBase, smdomain, smhint, smproperty, smproxy, ) - +from paraview.detail.loghandler import ( # type: ignore[import-not-found] + VTKHandler, ) from typing_extensions import Self from vtkmodules.vtkCommonCore import vtkDataArraySelection as vtkDAS @@ -29,12 +31,13 @@ update_paths() -from geos.geomechanics.model.MohrCircle import MohrCircle, loggerTitle +from geos.geomechanics.model.MohrCircle import MohrCircle from geos.utils.enumUnits import Pressure, enumerationDomainUnit from geos.utils.GeosOutputsConstants import ( FAILURE_ENVELOPE, GeosMeshOutputsEnum, ) +from geos.utils.Logger import GEOSFormatter from geos.utils.PhysicalConstants import ( DEFAULT_FRICTION_ANGLE_DEG, DEFAULT_FRICTION_ANGLE_RAD, @@ -58,7 +61,6 @@ optionEnumToXml, ) from geos.pv.utils.mohrCircles.functionsMohrCircle import StressConventionEnum -from geos.utils.Logger import addPluginLogSupport __doc__ = """ PVMohrCirclePlot is a ParaView plugin that allows to compute and plot @@ -110,7 +112,6 @@ dataTypes=[ "vtkUnstructuredGrid" ], composite_data_supported=False, ) -@addPluginLogSupport(loggerTitle=loggerTitle) class PVMohrCirclePlot( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: @@ -186,13 +187,13 @@ def __init__( self: Self ) -> None: self.requestDataStep: int = -1 # Logger - # self.logger: logging.Logger = logging.getLogger( "MohrCircle" ) - # self.logger.setLevel( logging.INFO ) - # if not self.logger.hasHandlers(): - # handler = VTKHandler() - # handler.setFormatter( CustomLoggerFormatter( False ) ) + self.logger: logging.Logger = logging.getLogger( "MohrCircle" ) + self.logger.setLevel( logging.INFO ) + if not self.logger.hasHandlers(): + handler = VTKHandler() + handler.setFormatter( GEOSFormatter() ) - # self.logger.addHandler( handler ) + self.logger.addHandler( handler ) @smproperty.xml( """ Date: Wed, 26 Nov 2025 14:29:13 +0100 Subject: [PATCH 18/20] some fix / mypy and friends --- geos-mesh/src/geos/mesh/utils/genericHelpers.py | 2 +- .../generic_processing_tools/AttributeMapping.py | 3 +-- .../generic_processing_tools/ClipToMainFrame.py | 2 -- .../CreateConstantAttributePerRegion.py | 3 +-- .../generic_processing_tools/FillPartialArrays.py | 3 ++- .../generic_processing_tools/MergeBlockEnhanced.py | 3 +-- .../generic_processing_tools/SplitMesh.py | 7 +++---- .../post_processing/SurfaceGeomechanics.py | 7 +++---- .../pre_processing/CellTypeCounterEnhanced.py | 1 - .../pre_processing/MeshQualityEnhanced.py | 3 +-- geos-processing/tests/test_FillPartialArrays.py | 1 + geos-pv/src/geos/pv/plugins/PVAttributeMapping.py | 2 +- .../geos/pv/plugins/PVCellTypeCounterEnhanced.py | 2 +- geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py | 6 +++--- .../plugins/PVCreateConstantAttributePerRegion.py | 2 +- geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py | 3 +-- .../src/geos/pv/plugins/PVMergeBlocksEnhanced.py | 4 ++-- .../src/geos/pv/plugins/PVMeshQualityEnhanced.py | 2 +- geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py | 2 +- geos-pv/src/geos/pv/plugins/PVSplitMesh.py | 6 +++--- .../src/geos/pv/plugins/PVSurfaceGeomechanics.py | 3 +-- .../geos/pv/pythonViewUtils/Figure2DGenerator.py | 2 +- .../pythonViewUtils/functionsFigure2DGenerator.py | 13 ++++++++----- geos-pv/src/geos/pv/utils/paraviewTreatments.py | 9 +++++++-- 24 files changed, 45 insertions(+), 46 deletions(-) diff --git a/geos-mesh/src/geos/mesh/utils/genericHelpers.py b/geos-mesh/src/geos/mesh/utils/genericHelpers.py index de11a4023..57bf29f45 100644 --- a/geos-mesh/src/geos/mesh/utils/genericHelpers.py +++ b/geos-mesh/src/geos/mesh/utils/genericHelpers.py @@ -641,7 +641,7 @@ def computeSurfaceTextureCoordinates( # Need to compute texture coordinates required for tangent calculation vtkErrorLogger: Logger if logger is None: - vtkErrorLogger = getLogger( "Compute Surface Texture Coordinates vtkError Logger", True ) + vtkErrorLogger = getLogger( "Compute Surface Texture Coordinates vtkError Logger") else: vtkErrorLogger = logging.getLogger( f"{ logger.name } vtkError Logger" ) vtkErrorLogger.setLevel( logging.INFO ) diff --git a/geos-processing/src/geos/processing/generic_processing_tools/AttributeMapping.py b/geos-processing/src/geos/processing/generic_processing_tools/AttributeMapping.py index d2ea3e89f..d075d5dd2 100644 --- a/geos-processing/src/geos/processing/generic_processing_tools/AttributeMapping.py +++ b/geos-processing/src/geos/processing/generic_processing_tools/AttributeMapping.py @@ -4,7 +4,6 @@ # ruff: noqa: E402 # disable Module level import not at top of file import numpy as np import numpy.typing as npt -import logging from typing_extensions import Self, Union from vtkmodules.vtkCommonDataModel import vtkDataSet, vtkMultiBlockDataSet from geos.mesh.utils.arrayModifiers import transferAttributeWithElementMap @@ -90,7 +89,7 @@ def __init__( self.ElementMap: dict[ int, npt.NDArray[ np.int64 ] ] = {} # Logger. - self.logger: Logger = getLogger( loggerTitle) + self.logger: Logger = getLogger( loggerTitle ) def getElementMap( self: Self ) -> dict[ int, npt.NDArray[ np.int64 ] ]: """Getter of the element mapping dictionary. diff --git a/geos-processing/src/geos/processing/generic_processing_tools/ClipToMainFrame.py b/geos-processing/src/geos/processing/generic_processing_tools/ClipToMainFrame.py index 41272716d..2a52e1a80 100644 --- a/geos-processing/src/geos/processing/generic_processing_tools/ClipToMainFrame.py +++ b/geos-processing/src/geos/processing/generic_processing_tools/ClipToMainFrame.py @@ -1,7 +1,6 @@ # SPDX-License-Identifier: Apache 2.0 # SPDX-FileCopyrightText: Copyright 2023-2025 TotalEnergies # SPDX-FileContributor: Jacques Franc -import logging import numpy as np import numpy.typing as npt @@ -52,7 +51,6 @@ """ -loggerTitle : str = "ClipToMainFrame" class ClipToMainFrameElement( vtkLandmarkTransform ): diff --git a/geos-processing/src/geos/processing/generic_processing_tools/CreateConstantAttributePerRegion.py b/geos-processing/src/geos/processing/generic_processing_tools/CreateConstantAttributePerRegion.py index 780e44902..7902ef3d5 100644 --- a/geos-processing/src/geos/processing/generic_processing_tools/CreateConstantAttributePerRegion.py +++ b/geos-processing/src/geos/processing/generic_processing_tools/CreateConstantAttributePerRegion.py @@ -121,7 +121,7 @@ def __init__( self.useDefaultValue: bool = False # Logger. - self.logger: Logger = getLogger(loggerTitle) # Warnings counter. + self.logger: Logger = getLogger( loggerTitle ) # Warnings counter. self.counter: CountWarningHandler = CountWarningHandler() self.counter.setLevel( logging.INFO ) @@ -136,7 +136,6 @@ def applyFilter( self: Self ) -> bool: """ self.logger.info( f"Apply filter { self.logger.name }." ) - # Check the validity of the attribute region. if self.onPoints is None: self.logger.error( f"{ self.regionName } is not in the mesh." ) diff --git a/geos-processing/src/geos/processing/generic_processing_tools/FillPartialArrays.py b/geos-processing/src/geos/processing/generic_processing_tools/FillPartialArrays.py index 39dbd3e90..2fce123c9 100644 --- a/geos-processing/src/geos/processing/generic_processing_tools/FillPartialArrays.py +++ b/geos-processing/src/geos/processing/generic_processing_tools/FillPartialArrays.py @@ -55,6 +55,7 @@ loggerTitle: str = "Fill Partial Attribute" + class FillPartialArrays: def __init__( @@ -75,7 +76,7 @@ def __init__( multiBlockDataSet (vtkMultiBlockDataSet): The mesh where to fill the attribute. dictAttributesValues (dict[str, Any]): The dictionary with the attribute to fill as keys and the list of filling values as items. """ - self.logger = getLogger(loggerTitle) + self.logger = getLogger( loggerTitle ) self.multiBlockDataSet: vtkMultiBlockDataSet = multiBlockDataSet self.dictAttributesValues: dict[ str, Union[ list[ Any ], None ] ] = dictAttributesValues diff --git a/geos-processing/src/geos/processing/generic_processing_tools/MergeBlockEnhanced.py b/geos-processing/src/geos/processing/generic_processing_tools/MergeBlockEnhanced.py index fd97c6ddb..81b89629f 100644 --- a/geos-processing/src/geos/processing/generic_processing_tools/MergeBlockEnhanced.py +++ b/geos-processing/src/geos/processing/generic_processing_tools/MergeBlockEnhanced.py @@ -2,7 +2,6 @@ # SPDX-FileCopyrightText: Copyright 2023-2024 TotalEnergies. # SPDX-FileContributor: Paloma Martinez # ruff: noqa: E402 # disable Module level import not at top of file -import logging from typing_extensions import Self @@ -82,7 +81,7 @@ def __init__( self.outputMesh: vtkUnstructuredGrid = vtkUnstructuredGrid() # Logger - self.logger: Logger = getLogger( loggerTitle) + self.logger: Logger = getLogger( loggerTitle ) def applyFilter( self: Self ) -> None: """Merge the blocks of a multiblock dataset mesh. diff --git a/geos-processing/src/geos/processing/generic_processing_tools/SplitMesh.py b/geos-processing/src/geos/processing/generic_processing_tools/SplitMesh.py index 4e4d6da49..1718ac8ae 100644 --- a/geos-processing/src/geos/processing/generic_processing_tools/SplitMesh.py +++ b/geos-processing/src/geos/processing/generic_processing_tools/SplitMesh.py @@ -1,7 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright 2023-2024 TotalEnergies. # SPDX-FileContributor: Antoine Mazuyer, Martin Lemay -import logging import numpy as np import numpy.typing as npt from typing_extensions import Self @@ -49,9 +48,10 @@ loggerTitle: str = "SplitMesh" + class SplitMesh(): - def __init__( self, inputMesh: vtkUnstructuredGrid) -> None: + def __init__( self, inputMesh: vtkUnstructuredGrid ) -> None: """SplitMesh filter splits each cell using edge centers. Args: @@ -67,8 +67,7 @@ def __init__( self, inputMesh: vtkUnstructuredGrid) -> None: self.cellTypes: list[ int ] #subordonate filter - self.cellTypeCounterEnhancedFilter: CellTypeCounterEnhanced = CellTypeCounterEnhanced( - self.inputMesh) + self.cellTypeCounterEnhancedFilter: CellTypeCounterEnhanced = CellTypeCounterEnhanced( self.inputMesh ) # Logger self.logger: Logger = getLogger( loggerTitle ) diff --git a/geos-processing/src/geos/processing/post_processing/SurfaceGeomechanics.py b/geos-processing/src/geos/processing/post_processing/SurfaceGeomechanics.py index 49b9455a1..f04dd4dd0 100644 --- a/geos-processing/src/geos/processing/post_processing/SurfaceGeomechanics.py +++ b/geos-processing/src/geos/processing/post_processing/SurfaceGeomechanics.py @@ -2,7 +2,6 @@ # SPDX-FileCopyrightText: Copyright 2023-2024 TotalEnergies. # SPDX-FileContributor: Martin Lemay, Paloma Martinez # ruff: noqa: E402 # disable Module level import not at top of file -import logging import numpy as np from typing_extensions import Self, Union @@ -99,7 +98,7 @@ class SurfaceGeomechanics: - def __init__( self: Self, surfacicMesh: vtkPolyData) -> None: + def __init__( self: Self, surfacicMesh: vtkPolyData ) -> None: """Vtk filter to compute geomechanical surfacic attributes. Input and Output objects are a vtkPolydata with surfaces @@ -111,10 +110,10 @@ def __init__( self: Self, surfacicMesh: vtkPolyData) -> None: Defaults to False. """ # Logger - self.logger: Logger= getLogger( loggerTitle ) + self.logger: Logger = getLogger( loggerTitle ) # Input surfacic mesh - print(surfacicMesh) + print( surfacicMesh ) if not surfacicMesh.IsA( "vtkPolyData" ): self.logger.error( f"Input surface is expected to be a vtkPolyData, not a {type(surfacicMesh)}." ) self.inputMesh: vtkPolyData = surfacicMesh diff --git a/geos-processing/src/geos/processing/pre_processing/CellTypeCounterEnhanced.py b/geos-processing/src/geos/processing/pre_processing/CellTypeCounterEnhanced.py index 34d28e824..4a105e39f 100644 --- a/geos-processing/src/geos/processing/pre_processing/CellTypeCounterEnhanced.py +++ b/geos-processing/src/geos/processing/pre_processing/CellTypeCounterEnhanced.py @@ -1,7 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright 2023-2024 TotalEnergies. # SPDX-FileContributor: Antoine Mazuyer, Martin Lemay -import logging from typing_extensions import Self from vtkmodules.vtkCommonCore import vtkIntArray diff --git a/geos-processing/src/geos/processing/pre_processing/MeshQualityEnhanced.py b/geos-processing/src/geos/processing/pre_processing/MeshQualityEnhanced.py index 3a76e0ec0..b2832ccf4 100644 --- a/geos-processing/src/geos/processing/pre_processing/MeshQualityEnhanced.py +++ b/geos-processing/src/geos/processing/pre_processing/MeshQualityEnhanced.py @@ -1,7 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright 2023-2024 TotalEnergies. # SPDX-FileContributor: Antoine Mazuyer, Martin Lemay, Paloma Martinez -import logging import numpy as np import numpy.typing as npt from typing import Optional, cast @@ -124,7 +123,7 @@ def __init__( self._allCellTypes: tuple[ int, ...] = getAllCellTypes() #deps - self.cellTypeCounterEnhancedFilter: CellTypeCounterEnhanced = CellTypeCounterEnhanced(self._outputMesh) + self.cellTypeCounterEnhancedFilter: CellTypeCounterEnhanced = CellTypeCounterEnhanced( self._outputMesh ) # Logger. self.logger: Logger = getLogger( loggerTitle ) diff --git a/geos-processing/tests/test_FillPartialArrays.py b/geos-processing/tests/test_FillPartialArrays.py index f437cfcdb..e5720d0f5 100644 --- a/geos-processing/tests/test_FillPartialArrays.py +++ b/geos-processing/tests/test_FillPartialArrays.py @@ -11,6 +11,7 @@ from geos.processing.generic_processing_tools.FillPartialArrays import FillPartialArrays + @pytest.mark.parametrize( "dictAttributesValues", [ ( { "PORO": None diff --git a/geos-pv/src/geos/pv/plugins/PVAttributeMapping.py b/geos-pv/src/geos/pv/plugins/PVAttributeMapping.py index 89f9207d8..1335f5bd0 100644 --- a/geos-pv/src/geos/pv/plugins/PVAttributeMapping.py +++ b/geos-pv/src/geos/pv/plugins/PVAttributeMapping.py @@ -67,7 +67,7 @@ dataTypes=[ "vtkDataSet", "vtkMultiBlockDataSet" ], composite_data_supported=True, ) -@addPluginLogSupport(loggerTitles=[loggerTitle]) +@addPluginLogSupport( loggerTitles=[ loggerTitle ] ) class PVAttributeMapping( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: diff --git a/geos-pv/src/geos/pv/plugins/PVCellTypeCounterEnhanced.py b/geos-pv/src/geos/pv/plugins/PVCellTypeCounterEnhanced.py index 44bef3c46..16f995044 100644 --- a/geos-pv/src/geos/pv/plugins/PVCellTypeCounterEnhanced.py +++ b/geos-pv/src/geos/pv/plugins/PVCellTypeCounterEnhanced.py @@ -44,7 +44,7 @@ dataTypes=[ "vtkUnstructuredGrid" ], composite_data_supported=True, ) -@addPluginLogSupport(loggerTitles=[loggerTitle]) +@addPluginLogSupport( loggerTitles=[ loggerTitle ] ) class PVCellTypeCounterEnhanced( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: diff --git a/geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py b/geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py index 46c3fbf7f..376c002ac 100644 --- a/geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py +++ b/geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py @@ -20,7 +20,7 @@ update_paths() from geos.pv.utils.details import ( SISOFilter, FilterCategory ) -from geos.processing.generic_processing_tools.ClipToMainFrame import ClipToMainFrame, loggerTitle +from geos.processing.generic_processing_tools.ClipToMainFrame import ClipToMainFrame, loggerTitle, getLogger from geos.utils.Logger import Logger, addPluginLogSupport __doc__ = """ @@ -37,13 +37,13 @@ @SISOFilter( category=FilterCategory.GEOS_UTILS, decoratedLabel="Clip to the main frame", decoratedType=[ "vtkMultiBlockDataSet", "vtkDataSet" ] ) -@addPluginLogSupport(loggerTitles=[loggerTitle]) +@addPluginLogSupport( loggerTitles=[ loggerTitle ] ) class PVClipToMainFrame( VTKPythonAlgorithmBase ): def __init__( self ) -> None: """Init motherclass, filter and logger.""" self._realFilter = ClipToMainFrame() - self.logger : Logger = getLogger( loggerTitle ) + self.logger: Logger = getLogger( loggerTitle ) self.logger.info( f"Applying plugin {self.logger.name}." ) def ApplyFilter( self, inputMesh: vtkMultiBlockDataSet, outputMesh: vtkMultiBlockDataSet ) -> None: diff --git a/geos-pv/src/geos/pv/plugins/PVCreateConstantAttributePerRegion.py b/geos-pv/src/geos/pv/plugins/PVCreateConstantAttributePerRegion.py index d8914558f..e7ca6e63b 100644 --- a/geos-pv/src/geos/pv/plugins/PVCreateConstantAttributePerRegion.py +++ b/geos-pv/src/geos/pv/plugins/PVCreateConstantAttributePerRegion.py @@ -55,7 +55,7 @@ @SISOFilter( category=FilterCategory.GEOS_PROP, decoratedLabel="Create Constant Attribute Per Region", decoratedType=[ "vtkMultiBlockDataSet", "vtkDataSet" ] ) -@addPluginLogSupport(loggerTitles=[loggerTitle]) +@addPluginLogSupport( loggerTitles=[ loggerTitle ] ) class PVCreateConstantAttributePerRegion( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: diff --git a/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py b/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py index 28f5dcc33..4a7971ce6 100644 --- a/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py +++ b/geos-pv/src/geos/pv/plugins/PVFillPartialArrays.py @@ -44,7 +44,7 @@ @SISOFilter( category=FilterCategory.GEOS_UTILS, decoratedLabel="Fill Partial Arrays", decoratedType="vtkMultiBlockDataSet" ) -@addPluginLogSupport( loggerTitles=[loggerTitle] ) +@addPluginLogSupport( loggerTitles=[ loggerTitle ] ) class PVFillPartialArrays( VTKPythonAlgorithmBase ): def __init__( self: Self, ) -> None: @@ -52,7 +52,6 @@ def __init__( self: Self, ) -> None: self.clearDictAttributesValues: bool = True self.dictAttributesValues: dict[ str, Union[ list[ Any ], None ] ] = {} - @smproperty.xml( """ ' ) @smproperty.input( name="Input", port_index=0, label="Input" ) @smdomain.datatype( dataTypes=[ "vtkMultiBlockDataSet" ], composite_data_supported=True ) -@addPluginLogSupport(loggerTitles=[loggerTitle, f"{loggerTitle}.vtkErrorLogger" ]) +@addPluginLogSupport( loggerTitles=[ loggerTitle, f"{loggerTitle}.vtkErrorLogger" ] ) class PVMergeBlocksEnhanced( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: diff --git a/geos-pv/src/geos/pv/plugins/PVMeshQualityEnhanced.py b/geos-pv/src/geos/pv/plugins/PVMeshQualityEnhanced.py index 3010055dd..c12d99bab 100644 --- a/geos-pv/src/geos/pv/plugins/PVMeshQualityEnhanced.py +++ b/geos-pv/src/geos/pv/plugins/PVMeshQualityEnhanced.py @@ -61,7 +61,7 @@ @SISOFilter( category=FilterCategory.GEOS_QC, decoratedLabel="Mesh Quality Enhanced", decoratedType="vtkUnstructuredGrid" ) -@addPluginLogSupport(loggerTitles=[loggerTitle,cloggerTitle]) +@addPluginLogSupport( loggerTitles=[ loggerTitle, cloggerTitle ] ) class PVMeshQualityEnhanced( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: diff --git a/geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py b/geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py index 378f4aeb3..5a9145bcf 100644 --- a/geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py +++ b/geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py @@ -660,7 +660,7 @@ def RequestInformation( if self.requestDataStep < 0: # Get cell ids inData = self.GetInputData( inInfoVec, 0, 0 ) - self.cellIds = pvt.getVtkOriginalCellIds( inData, self.logger) + self.cellIds = pvt.getVtkOriginalCellIds( inData, self.logger ) # Update vtkDAS for circleId in self.cellIds: diff --git a/geos-pv/src/geos/pv/plugins/PVSplitMesh.py b/geos-pv/src/geos/pv/plugins/PVSplitMesh.py index 9b11220c8..112523854 100644 --- a/geos-pv/src/geos/pv/plugins/PVSplitMesh.py +++ b/geos-pv/src/geos/pv/plugins/PVSplitMesh.py @@ -19,9 +19,9 @@ update_paths() -from geos.processing.generic_processing_tools.SplitMesh import (SplitMesh, loggerTitle) +from geos.processing.generic_processing_tools.SplitMesh import ( SplitMesh, loggerTitle ) from geos.processing.pre_processing.CellTypeCounterEnhanced import loggerTitle as cloggerTitle -from geos.pv.utils.details import (SISOFilter, FilterCategory) +from geos.pv.utils.details import ( SISOFilter, FilterCategory ) from geos.utils.Logger import addPluginLogSupport __doc__ = """ @@ -39,7 +39,7 @@ @SISOFilter( category=FilterCategory.GEOS_UTILS, decoratedLabel="Split Mesh", decoratedType="vtkPointSet" ) -@addPluginLogSupport(loggerTitles=[loggerTitle, cloggerTitle]) +@addPluginLogSupport( loggerTitles=[ loggerTitle, cloggerTitle ] ) class PVSplitMesh( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: diff --git a/geos-pv/src/geos/pv/plugins/PVSurfaceGeomechanics.py b/geos-pv/src/geos/pv/plugins/PVSurfaceGeomechanics.py index bdc19202d..c26395fb3 100644 --- a/geos-pv/src/geos/pv/plugins/PVSurfaceGeomechanics.py +++ b/geos-pv/src/geos/pv/plugins/PVSurfaceGeomechanics.py @@ -11,7 +11,6 @@ VTKPythonAlgorithmBase, smdomain, smproperty, ) - # update sys.path to load all GEOS Python Package dependencies geos_pv_path: Path = Path( __file__ ).parent.parent.parent.parent.parent sys.path.insert( 0, str( geos_pv_path / "src" ) ) @@ -63,7 +62,7 @@ @SISOFilter( category=FilterCategory.GEOS_GEOMECHANICS, decoratedLabel="Geos Surface Geomechanics", decoratedType="vtkMultiBlockDataSet" ) -@addPluginLogSupport(loggerTitles=[loggerTitle]) +@addPluginLogSupport( loggerTitles=[ loggerTitle ] ) class PVSurfaceGeomechanics( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: diff --git a/geos-pv/src/geos/pv/pythonViewUtils/Figure2DGenerator.py b/geos-pv/src/geos/pv/pythonViewUtils/Figure2DGenerator.py index 00eceded7..a04a24a99 100755 --- a/geos-pv/src/geos/pv/pythonViewUtils/Figure2DGenerator.py +++ b/geos-pv/src/geos/pv/pythonViewUtils/Figure2DGenerator.py @@ -129,7 +129,7 @@ def changeAxisLimits( self: Self ) -> None: ax.set_ylim( ymin, ymax ) def getFigure( self: Self ) -> figure.Figure: - """access the m_fig attribute. + """Access the m_fig attribute. Returns: figure.Figure: Figure containing all the plots. diff --git a/geos-pv/src/geos/pv/pythonViewUtils/functionsFigure2DGenerator.py b/geos-pv/src/geos/pv/pythonViewUtils/functionsFigure2DGenerator.py index 113953416..c0077180f 100755 --- a/geos-pv/src/geos/pv/pythonViewUtils/functionsFigure2DGenerator.py +++ b/geos-pv/src/geos/pv/pythonViewUtils/functionsFigure2DGenerator.py @@ -615,7 +615,8 @@ def propertiesPerIdentifier( propertyNames: list[ str ] ) -> dict[ str, list[ st Args: propertyNames (list[str]): Property names. - Example + + Example: .. code-block:: python @@ -628,7 +629,8 @@ def propertiesPerIdentifier( propertyNames: list[ str ] ) -> dict[ str, list[ st Returns: dict[str, list[str]]: Property identifiers. - Example + + Example: .. code-block:: python @@ -663,7 +665,8 @@ def associationIdentifiers( propertyNames: list[ str ] ) -> dict[ str, dict[ str Args: propertyNames (list[str]): Property names. - Example + + Example: .. code-block:: python @@ -692,7 +695,8 @@ def associationIdentifiers( propertyNames: list[ str ] ) -> dict[ str, dict[ str Returns: dict[str, dict[str, list[str]]]: Property identifiers. - Example + + Example: .. code-block:: python @@ -1303,7 +1307,6 @@ def findPhasesLabel( label: str ) -> list[ str ]: # if legendLabel.startswith(pattern): # return legendLabel[len(pattern):] # return legendLabel - """ Other 2D tools for simplest figures """ diff --git a/geos-pv/src/geos/pv/utils/paraviewTreatments.py b/geos-pv/src/geos/pv/utils/paraviewTreatments.py index f0ee3e68f..f83aed87a 100644 --- a/geos-pv/src/geos/pv/utils/paraviewTreatments.py +++ b/geos-pv/src/geos/pv/utils/paraviewTreatments.py @@ -8,7 +8,7 @@ import numpy as np import numpy.typing as npt -import pandas as pd # type: ignore[import-untyped] +import pandas as pd # type: ignore[import-untypedGEOSFormatter ] from paraview.simple import ( # type: ignore[import-not-found] FindSource, GetActiveView, GetAnimationScene, GetDisplayProperties, GetSources, servermanager, @@ -37,6 +37,7 @@ ComponentNameEnum, GeosMeshOutputsEnum, ) +from geos.utils.Logger import ( GEOSFormatter ) from geos.mesh.utils.multiblockModifiers import mergeBlocks # valid sources for Python view configurator @@ -483,8 +484,12 @@ def getVtkOriginalCellIds( mesh: Union[ vtkMultiBlockDataSet, vtkCompositeDataSe list[str]: ids of the cells. """ if logger is None: - logger = getLogger( "getVtkOriginalCellIds" ) + logger = logging.getLogger( "getVtkOriginalCellIds" ) + if not logger.hasHandlers(): + handler = VTKHandler() + handler.setFormatter( GEOSFormatter() ) + logger.addHandler( handler ) # Merge blocks for vtkCompositeDataSet mesh2: vtkUnstructuredGrid = mergeBlocks( mesh, logger=logger ) From 39def26caf49bb15b4936df7f450a168d31437c3 Mon Sep 17 00:00:00 2001 From: jacques franc Date: Wed, 26 Nov 2025 15:18:06 +0100 Subject: [PATCH 19/20] some corr --- geos-pv/src/geos/pv/plugins/PVAttributeMapping.py | 3 --- geos-pv/src/geos/pv/plugins/PVCellTypeCounterEnhanced.py | 5 +---- geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py | 3 ++- geos-pv/src/geos/pv/plugins/PVGeomechanicsCalculator.py | 7 ++----- geos-pv/src/geos/pv/plugins/PVGeomechanicsWorkflow.py | 6 +++--- geos-pv/src/geos/pv/plugins/PVGeosBlockExtractAndMerge.py | 5 ++--- geos-pv/src/geos/pv/plugins/PVMeshQualityEnhanced.py | 5 +---- geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py | 7 +++---- geos-pv/src/geos/pv/plugins/PVSplitMesh.py | 4 ---- geos-pv/src/geos/pv/utils/paraviewTreatments.py | 6 ++---- geos-pv/src/geos/pv/utils/workflowFunctions.py | 6 +++--- 11 files changed, 19 insertions(+), 38 deletions(-) diff --git a/geos-pv/src/geos/pv/plugins/PVAttributeMapping.py b/geos-pv/src/geos/pv/plugins/PVAttributeMapping.py index 1335f5bd0..b09642df6 100644 --- a/geos-pv/src/geos/pv/plugins/PVAttributeMapping.py +++ b/geos-pv/src/geos/pv/plugins/PVAttributeMapping.py @@ -190,9 +190,6 @@ def RequestData( attributeMappingFilter: AttributeMapping = AttributeMapping( meshFrom, outData, set( self.attributeNames ), self.onPoints ) - # if not attributeMappingFilter.logger.hasHandlers(): - # attributeMappingFilter.setLoggerHandler( VTKHandler() ) - attributeMappingFilter.applyFilter() self.clearAttributeNames = True diff --git a/geos-pv/src/geos/pv/plugins/PVCellTypeCounterEnhanced.py b/geos-pv/src/geos/pv/plugins/PVCellTypeCounterEnhanced.py index 16f995044..4bb4ecc71 100644 --- a/geos-pv/src/geos/pv/plugins/PVCellTypeCounterEnhanced.py +++ b/geos-pv/src/geos/pv/plugins/PVCellTypeCounterEnhanced.py @@ -9,7 +9,6 @@ from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] VTKPythonAlgorithmBase, smdomain, smhint, smproperty, smproxy ) -from paraview.detail.loghandler import VTKHandler # type: ignore[import-not-found] from vtkmodules.vtkCommonCore import vtkInformation, vtkInformationVector from vtkmodules.vtkCommonDataModel import vtkPointSet, vtkTable @@ -134,9 +133,7 @@ def RequestData( assert inputMesh is not None, "Input server mesh is null." assert outputTable is not None, "Output pipeline is null." - cellTypeCounterEnhancedFilter: CellTypeCounterEnhanced = CellTypeCounterEnhanced( inputMesh, True ) - if len( cellTypeCounterEnhancedFilter.logger.handlers ) == 0: - cellTypeCounterEnhancedFilter.setLoggerHandler( VTKHandler() ) + cellTypeCounterEnhancedFilter: CellTypeCounterEnhanced = CellTypeCounterEnhanced( inputMesh ) if cellTypeCounterEnhancedFilter.applyFilter(): outputTable.ShallowCopy( cellTypeCounterEnhancedFilter.getOutput() ) diff --git a/geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py b/geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py index 376c002ac..43d9201f4 100644 --- a/geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py +++ b/geos-pv/src/geos/pv/plugins/PVClipToMainFrame.py @@ -44,7 +44,6 @@ def __init__( self ) -> None: """Init motherclass, filter and logger.""" self._realFilter = ClipToMainFrame() self.logger: Logger = getLogger( loggerTitle ) - self.logger.info( f"Applying plugin {self.logger.name}." ) def ApplyFilter( self, inputMesh: vtkMultiBlockDataSet, outputMesh: vtkMultiBlockDataSet ) -> None: """Is applying CreateConstantAttributePerRegion filter. @@ -54,6 +53,8 @@ def ApplyFilter( self, inputMesh: vtkMultiBlockDataSet, outputMesh: vtkMultiBloc outputMesh : A mesh transformed. """ # struct + self.logger.info( f"Applying plugin {self.logger.name}." ) + self._realFilter.SetInputData( inputMesh ) self._realFilter.ComputeTransform() self._realFilter.Update() diff --git a/geos-pv/src/geos/pv/plugins/PVGeomechanicsCalculator.py b/geos-pv/src/geos/pv/plugins/PVGeomechanicsCalculator.py index 829eeaa91..21c9a84dd 100644 --- a/geos-pv/src/geos/pv/plugins/PVGeomechanicsCalculator.py +++ b/geos-pv/src/geos/pv/plugins/PVGeomechanicsCalculator.py @@ -11,9 +11,6 @@ from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] VTKPythonAlgorithmBase, smdomain, smproperty ) # 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.vtkCommonDataModel import ( vtkUnstructuredGrid, vtkMultiBlockDataSet ) @@ -248,7 +245,7 @@ def ApplyFilter( ) if not geomechanicsCalculatorFilter.logger.hasHandlers(): - geomechanicsCalculatorFilter.setLoggerHandler( VTKHandler() ) + geomechanicsCalculatorFilter.setLoggerHandler( GEOSHandler() ) geomechanicsCalculatorFilter.physicalConstants.grainBulkModulus = self.grainBulkModulus geomechanicsCalculatorFilter.physicalConstants.specificDensity = self.specificDensity @@ -273,7 +270,7 @@ def ApplyFilter( ) if not geomechanicsCalculatorFilter.logger.hasHandlers(): - geomechanicsCalculatorFilter.setLoggerHandler( VTKHandler() ) + geomechanicsCalculatorFilter.setLoggerHandler( GEOSHandler() ) geomechanicsCalculatorFilter.physicalConstants.grainBulkModulus = self.grainBulkModulus geomechanicsCalculatorFilter.physicalConstants.specificDensity = self.specificDensity diff --git a/geos-pv/src/geos/pv/plugins/PVGeomechanicsWorkflow.py b/geos-pv/src/geos/pv/plugins/PVGeomechanicsWorkflow.py index 992a73020..4617c585d 100644 --- a/geos-pv/src/geos/pv/plugins/PVGeomechanicsWorkflow.py +++ b/geos-pv/src/geos/pv/plugins/PVGeomechanicsWorkflow.py @@ -31,8 +31,8 @@ from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] VTKPythonAlgorithmBase, smdomain, smproperty, smproxy ) -from paraview.detail.loghandler import ( # type: ignore[import-not-found] - VTKHandler ) + +from geos.utils.Logger import GEOSHandler __doc__ = """ PVGeomechanicsWorkflow is a Paraview plugin that executes multiple plugins: @@ -141,7 +141,7 @@ def __init__( self: Self ) -> None: self.logger = logging.getLogger( loggerTitle ) self.logger.setLevel( logging.INFO ) - self.logger.addHandler( VTKHandler() ) + self.logger.addHandler( GEOSHandler() ) self.logger.info( f"Apply plugin { self.logger.name }." ) diff --git a/geos-pv/src/geos/pv/plugins/PVGeosBlockExtractAndMerge.py b/geos-pv/src/geos/pv/plugins/PVGeosBlockExtractAndMerge.py index c779c5eb1..7b054cb4c 100644 --- a/geos-pv/src/geos/pv/plugins/PVGeosBlockExtractAndMerge.py +++ b/geos-pv/src/geos/pv/plugins/PVGeosBlockExtractAndMerge.py @@ -32,8 +32,7 @@ from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] VTKPythonAlgorithmBase, smdomain, smproperty, smproxy ) -from paraview.detail.loghandler import ( # type: ignore[import-not-found] - VTKHandler ) +from geos.utils.Logger import GEOSHandler __doc__ = """ PVGeosBlockExtractAndMerge is a Paraview plugin processing the input mesh at the current time in two steps: @@ -116,7 +115,7 @@ def __init__( self: Self ) -> None: self.logger = logging.getLogger( loggerTitle ) self.logger.setLevel( logging.INFO ) - self.logger.addHandler( VTKHandler() ) + self.logger.addHandler( GEOSHandler() ) self.logger.propagate = False self.logger.info( f"Apply plugin { self.logger.name }." ) diff --git a/geos-pv/src/geos/pv/plugins/PVMeshQualityEnhanced.py b/geos-pv/src/geos/pv/plugins/PVMeshQualityEnhanced.py index c12d99bab..87a037258 100644 --- a/geos-pv/src/geos/pv/plugins/PVMeshQualityEnhanced.py +++ b/geos-pv/src/geos/pv/plugins/PVMeshQualityEnhanced.py @@ -8,7 +8,6 @@ from typing_extensions import Self, Optional from paraview.util.vtkAlgorithm import VTKPythonAlgorithmBase, smdomain, smproperty # type: ignore[import-not-found] -from paraview.detail.loghandler import VTKHandler # type: ignore[import-not-found] # source: https://github.com/Kitware/ParaView/blob/master/Wrapping/Python/paraview/detail/loghandler.py from vtkmodules.vtkCommonCore import vtkDataArraySelection @@ -33,7 +32,7 @@ from geos.pv.utils.checkboxFunction import createModifiedCallback # type: ignore[attr-defined] from geos.pv.utils.paraviewTreatments import getArrayChoices from geos.pv.utils.details import ( SISOFilter, FilterCategory ) -from geos.utils.Logger import addPluginLogSupport +from geos.utils.Logger import addPluginLogSupport, GEOSHandler __doc__ = """ The ``Mesh Quality Enhanced`` filter computes requested mesh quality metrics on meshes. Both surfaces and volumic metrics can be computed with this plugin. @@ -232,8 +231,6 @@ def ApplyFilter( self, inputMesh: vtkUnstructuredGrid, outputMesh: vtkUnstructur otherMetrics: set[ int ] = self._getQualityMetricsToUse( self._commonMeshQualityMetric ) meshQualityEnhancedFilter: MeshQualityEnhanced = MeshQualityEnhanced( inputMesh ) - if len( meshQualityEnhancedFilter.logger.handlers ) == 0: - meshQualityEnhancedFilter.setLoggerHandler( VTKHandler() ) meshQualityEnhancedFilter.SetCellQualityMetrics( triangleMetrics=triangleMetrics, quadMetrics=quadMetrics, tetraMetrics=tetraMetrics, diff --git a/geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py b/geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py index 5a9145bcf..5a8de1577 100644 --- a/geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py +++ b/geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py @@ -15,8 +15,7 @@ from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] VTKPythonAlgorithmBase, smdomain, smhint, smproperty, smproxy, ) -from paraview.detail.loghandler import ( # type: ignore[import-not-found] - VTKHandler, ) + from typing_extensions import Self from vtkmodules.vtkCommonCore import vtkDataArraySelection as vtkDAS @@ -37,7 +36,6 @@ FAILURE_ENVELOPE, GeosMeshOutputsEnum, ) -from geos.utils.Logger import GEOSFormatter from geos.utils.PhysicalConstants import ( DEFAULT_FRICTION_ANGLE_DEG, DEFAULT_FRICTION_ANGLE_RAD, @@ -61,6 +59,7 @@ optionEnumToXml, ) from geos.pv.utils.mohrCircles.functionsMohrCircle import StressConventionEnum +from geos.utils.Logger import ( GEOSHandler, GEOSFormatter ) __doc__ = """ PVMohrCirclePlot is a ParaView plugin that allows to compute and plot @@ -190,7 +189,7 @@ def __init__( self: Self ) -> None: self.logger: logging.Logger = logging.getLogger( "MohrCircle" ) self.logger.setLevel( logging.INFO ) if not self.logger.hasHandlers(): - handler = VTKHandler() + handler = GEOSHandler() handler.setFormatter( GEOSFormatter() ) self.logger.addHandler( handler ) diff --git a/geos-pv/src/geos/pv/plugins/PVSplitMesh.py b/geos-pv/src/geos/pv/plugins/PVSplitMesh.py index 112523854..f097b165c 100644 --- a/geos-pv/src/geos/pv/plugins/PVSplitMesh.py +++ b/geos-pv/src/geos/pv/plugins/PVSplitMesh.py @@ -7,8 +7,6 @@ from typing_extensions import Self from paraview.util.vtkAlgorithm import VTKPythonAlgorithmBase # type: ignore[import-not-found] -from paraview.detail.loghandler import VTKHandler # type: ignore[import-not-found] -# source: https://github.com/Kitware/ParaView/blob/master/Wrapping/Python/paraview/detail/loghandler.py from vtkmodules.vtkCommonDataModel import vtkPointSet @@ -54,8 +52,6 @@ def ApplyFilter( self: Self, inputMesh: vtkPointSet, outputMesh: vtkPointSet ) - outputMesh: Output mesh. """ splitMeshFilter: SplitMesh = SplitMesh( inputMesh ) - if len( splitMeshFilter.logger.handlers ) == 0: - splitMeshFilter.setLoggerHandler( VTKHandler() ) if splitMeshFilter.applyFilter(): outputMesh.ShallowCopy( splitMeshFilter.getOutput() ) diff --git a/geos-pv/src/geos/pv/utils/paraviewTreatments.py b/geos-pv/src/geos/pv/utils/paraviewTreatments.py index f83aed87a..72a17d9aa 100644 --- a/geos-pv/src/geos/pv/utils/paraviewTreatments.py +++ b/geos-pv/src/geos/pv/utils/paraviewTreatments.py @@ -13,8 +13,6 @@ from paraview.simple import ( # type: ignore[import-not-found] FindSource, GetActiveView, GetAnimationScene, GetDisplayProperties, GetSources, servermanager, ) -from paraview.detail.loghandler import ( # type: ignore[import-not-found] - VTKHandler, ) import vtkmodules.util.numpy_support as vnp from vtkmodules.vtkCommonCore import ( vtkDataArray, @@ -37,7 +35,7 @@ ComponentNameEnum, GeosMeshOutputsEnum, ) -from geos.utils.Logger import ( GEOSFormatter ) +from geos.utils.Logger import ( GEOSFormatter, GEOSHandler ) from geos.mesh.utils.multiblockModifiers import mergeBlocks # valid sources for Python view configurator @@ -487,7 +485,7 @@ def getVtkOriginalCellIds( mesh: Union[ vtkMultiBlockDataSet, vtkCompositeDataSe logger = logging.getLogger( "getVtkOriginalCellIds" ) if not logger.hasHandlers(): - handler = VTKHandler() + handler = GEOSHandler() handler.setFormatter( GEOSFormatter() ) logger.addHandler( handler ) diff --git a/geos-pv/src/geos/pv/utils/workflowFunctions.py b/geos-pv/src/geos/pv/utils/workflowFunctions.py index 28602fce0..23804d566 100644 --- a/geos-pv/src/geos/pv/utils/workflowFunctions.py +++ b/geos-pv/src/geos/pv/utils/workflowFunctions.py @@ -8,7 +8,7 @@ from vtkmodules.vtkCommonDataModel import vtkMultiBlockDataSet -from paraview.detail.loghandler import ( VTKHandler ) # type: ignore[import-not-found] +from geos.utils.Logger import GEOSHandler def doExtractAndMerge( @@ -35,7 +35,7 @@ def doExtractAndMerge( extractWell=extractWell, speHandler=True ) if not blockExtractor.logger.hasHandlers(): - blockExtractor.setLoggerHandler( VTKHandler() ) + blockExtractor.setLoggerHandler( GEOSHandler() ) blockExtractor.applyFilter() # recover output objects from GeosBlockExtractor filter and merge internal blocks @@ -76,7 +76,7 @@ def mergeBlocksFilter( loggerName = f"GEOS Block Merge for the domain { domainToMerge }." mergeBlockFilter: GeosBlockMerge = GeosBlockMerge( mesh, convertSurfaces, True, loggerName ) if not mergeBlockFilter.logger.hasHandlers(): - mergeBlockFilter.setLoggerHandler( VTKHandler() ) + mergeBlockFilter.setLoggerHandler( GEOSHandler() ) mergeBlockFilter.applyFilter() mergedBlocks: vtkMultiBlockDataSet = vtkMultiBlockDataSet() mergedBlocks.ShallowCopy( mergeBlockFilter.getOutput() ) From 0c9939407ab6d016af975872d652ba42cb347bbe Mon Sep 17 00:00:00 2001 From: jacques franc Date: Wed, 26 Nov 2025 16:10:06 +0100 Subject: [PATCH 20/20] some more --- .../post_processing/GeomechanicsCalculator.py | 22 +++++-------------- .../pv/plugins/PVGeomechanicsCalculator.py | 19 ++++++++-------- .../src/geos/pv/plugins/PVMohrCirclePlot.py | 15 ++++--------- geos-utils/src/geos/utils/Logger.py | 2 -- 4 files changed, 18 insertions(+), 40 deletions(-) diff --git a/geos-processing/src/geos/processing/post_processing/GeomechanicsCalculator.py b/geos-processing/src/geos/processing/post_processing/GeomechanicsCalculator.py index 053404699..270864f39 100644 --- a/geos-processing/src/geos/processing/post_processing/GeomechanicsCalculator.py +++ b/geos-processing/src/geos/processing/post_processing/GeomechanicsCalculator.py @@ -84,15 +84,9 @@ # Define filter inputs mesh: vtkUnstructuredGrid computeAdvancedProperties: bool # optional, defaults to False - speHandler: bool # optional, defaults to False - loggerName: str # Defaults to "Geomechanics Calculator" # Instantiate the filter - geomechanicsCalculatorFilter: GeomechanicsCalculator = GeomechanicsCalculator( mesh, computeAdvancedProperties, speHandler ) - - # Use your own handler (if speHandler is True) - yourHandler: logging.Handler - geomechanicsCalculatorFilter.setLoggerHandler( yourHandler ) + geomechanicsCalculatorFilter: GeomechanicsCalculator = GeomechanicsCalculator( mesh, computeAdvancedProperties ) # Change the physical constants if needed ## For the basic properties @@ -167,6 +161,9 @@ ADVANCED_PROPERTIES: tuple[ AttributeEnum, ...] = ( CRITICAL_TOTAL_STRESS_RATIO, TOTAL_STRESS_RATIO_THRESHOLD, CRITICAL_PORE_PRESSURE, CRITICAL_PORE_PRESSURE_THRESHOLD ) + + +loggerTitle: str = "Geomechanics Calculator" class GeomechanicsCalculator: @@ -684,8 +681,6 @@ def __init__( self: Self, mesh: vtkUnstructuredGrid, computeAdvancedProperties: bool = False, - loggerName: str = "Geomechanics Calculator", - speHandler: bool = False, ) -> None: """VTK Filter to perform geomechanics properties computation. @@ -695,8 +690,6 @@ def __init__( Defaults to False. loggerName (str, optional): Name of the filter logger. Defaults to "Geomechanics Calculator". - speHandler (bool, optional): True to use a specific handler, False to use the internal handler. - Defaults to False. """ self.output: vtkUnstructuredGrid = mesh.NewInstance() self.output.DeepCopy( mesh ) @@ -711,12 +704,7 @@ def __init__( self._attributesToCreate: list[ AttributeEnum ] = [] # Logger. - self.logger: Logger - if not speHandler: - self.logger = getLogger( loggerName, True ) - else: - self.logger = logging.getLogger( loggerName ) - self.logger.setLevel( logging.INFO ) + self.logger: Logger = getLogger( loggerTitle ) def applyFilter( self: Self ) -> None: """Compute the geomechanics properties and create attributes on the mesh.""" diff --git a/geos-pv/src/geos/pv/plugins/PVGeomechanicsCalculator.py b/geos-pv/src/geos/pv/plugins/PVGeomechanicsCalculator.py index 21c9a84dd..cae518611 100644 --- a/geos-pv/src/geos/pv/plugins/PVGeomechanicsCalculator.py +++ b/geos-pv/src/geos/pv/plugins/PVGeomechanicsCalculator.py @@ -28,8 +28,9 @@ WATER_DENSITY, ) from geos.mesh.utils.multiblockHelpers import ( getBlockElementIndexesFlatten, getBlockNameFromIndex ) -from geos.processing.post_processing.GeomechanicsCalculator import GeomechanicsCalculator +from geos.processing.post_processing.GeomechanicsCalculator import GeomechanicsCalculator, loggerTitle from geos.pv.utils.details import ( SISOFilter, FilterCategory ) +from geos.utils.Logger import addPluginLogSupport __doc__ = """ PVGeomechanicsCalculator is a paraview plugin that allows to compute additional geomechanics properties from existing ones in the mesh. @@ -78,6 +79,7 @@ @SISOFilter( category=FilterCategory.GEOS_GEOMECHANICS, decoratedLabel="GEOS Geomechanics Calculator", decoratedType=[ "vtkUnstructuredGrid", "vtkMultiBlockDataSet" ] ) +@addPluginLogSupport( loggerTitles=[ loggerTitle ] ) class PVGeomechanicsCalculator( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: @@ -241,11 +243,10 @@ def ApplyFilter( geomechanicsCalculatorFilter = GeomechanicsCalculator( outputMesh, self.computeAdvancedProperties, - speHandler=True, ) - if not geomechanicsCalculatorFilter.logger.hasHandlers(): - geomechanicsCalculatorFilter.setLoggerHandler( GEOSHandler() ) + # if not geomechanicsCalculatorFilter.logger.hasHandlers(): + # geomechanicsCalculatorFilter.setLoggerHandler( GEOSHandler() ) geomechanicsCalculatorFilter.physicalConstants.grainBulkModulus = self.grainBulkModulus geomechanicsCalculatorFilter.physicalConstants.specificDensity = self.specificDensity @@ -259,18 +260,16 @@ def ApplyFilter( for blockIndex in volumeBlockIndexes: volumeBlock: vtkUnstructuredGrid = vtkUnstructuredGrid.SafeDownCast( outputMesh.GetDataSet( blockIndex ) ) - volumeBlockName: str = getBlockNameFromIndex( outputMesh, blockIndex ) - filterName: str = f"Geomechanics Calculator for the block { volumeBlockName }" + # volumeBlockName: str = getBlockNameFromIndex( outputMesh, blockIndex ) + # filterName: str = f"Geomechanics Calculator for the block { volumeBlockName }" geomechanicsCalculatorFilter = GeomechanicsCalculator( volumeBlock, self.computeAdvancedProperties, - filterName, - True, ) - if not geomechanicsCalculatorFilter.logger.hasHandlers(): - geomechanicsCalculatorFilter.setLoggerHandler( GEOSHandler() ) + # if not geomechanicsCalculatorFilter.logger.hasHandlers(): + # geomechanicsCalculatorFilter.setLoggerHandler( GEOSHandler() ) geomechanicsCalculatorFilter.physicalConstants.grainBulkModulus = self.grainBulkModulus geomechanicsCalculatorFilter.physicalConstants.specificDensity = self.specificDensity diff --git a/geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py b/geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py index 5a8de1577..791f01802 100644 --- a/geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py +++ b/geos-pv/src/geos/pv/plugins/PVMohrCirclePlot.py @@ -30,7 +30,7 @@ update_paths() -from geos.geomechanics.model.MohrCircle import MohrCircle +from geos.geomechanics.model.MohrCircle import MohrCircle, loggerTitle from geos.utils.enumUnits import Pressure, enumerationDomainUnit from geos.utils.GeosOutputsConstants import ( FAILURE_ENVELOPE, @@ -59,7 +59,7 @@ optionEnumToXml, ) from geos.pv.utils.mohrCircles.functionsMohrCircle import StressConventionEnum -from geos.utils.Logger import ( GEOSHandler, GEOSFormatter ) +from geos.utils.Logger import ( addPluginLogSupport, getLogger ) __doc__ = """ PVMohrCirclePlot is a ParaView plugin that allows to compute and plot @@ -111,6 +111,7 @@ dataTypes=[ "vtkUnstructuredGrid" ], composite_data_supported=False, ) +@addPluginLogSupport( loggerTitles=[ loggerTitle ] ) class PVMohrCirclePlot( VTKPythonAlgorithmBase ): def __init__( self: Self ) -> None: @@ -184,15 +185,7 @@ def __init__( self: Self ) -> None: # Request data processing step - incremented each time RequestUpdateExtent is called self.requestDataStep: int = -1 - - # Logger - self.logger: logging.Logger = logging.getLogger( "MohrCircle" ) - self.logger.setLevel( logging.INFO ) - if not self.logger.hasHandlers(): - handler = GEOSHandler() - handler.setFormatter( GEOSFormatter() ) - - self.logger.addHandler( handler ) + self.logger: Logger = getLogger( loggerTitle ) @smproperty.xml( """ Type[ T ]: def new_init( self: T, *args: Any, **kwargs: Any ) -> None: original_init( self, *args, **kwargs ) - # logger = getLogger( loggerTitle ) for logger in loggerTitles: - # if not isinstance(logger, logging.PlaceHolder ): for hdlr in list( filter( lambda x: not isinstance( x, GEOSHandler ), getLogger(logger).handlers ) ): getLogger(logger).removeHandler( hdlr )