Skip to content

Commit b5ce4f4

Browse files
refactor: Add a logger for all the vtk filter of geos-processing and all the plugin of geos-pv (#178)
1 parent 7982467 commit b5ce4f4

32 files changed

+477
-551
lines changed

geos-mesh/src/geos/mesh/utils/multiblockModifiers.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
vtkUnstructuredGrid, vtkDataSet )
99
from packaging.version import Version
1010
from vtkmodules.vtkCommonCore import vtkLogger
11+
from geos.utils.Errors import VTKError
1112

1213
# TODO: remove this condition when all codes are adapted for VTK newest version.
1314
import vtk
@@ -50,20 +51,21 @@ def mergeBlocks(
5051
.. Warning:: This function will not work properly if there are duplicated cell IDs in the different blocks of the input mesh.
5152
5253
"""
54+
vtkErrorLogger: Logger
5355
if logger is None:
54-
logger = getLogger( "mergeBlocks" )
55-
# Creation of a child logger to deal with VTKErrors without polluting parent logger
56-
mbLogger: Logger = getLogger( f"{logger.name}.vtkErrorLogger" )
57-
58-
mbLogger.propagate = False
56+
vtkErrorLogger = getLogger( "Merge blocks", True )
57+
else:
58+
vtkErrorLogger = logging.getLogger( f"{ logger.name } vtkError Logger" )
59+
vtkErrorLogger.setLevel( logging.INFO )
60+
vtkErrorLogger.addHandler( logger.handlers[ 0 ] )
61+
vtkErrorLogger.propagate = False
5962

6063
vtkLogger.SetStderrVerbosity( vtkLogger.VERBOSITY_ERROR )
61-
mbLogger.addFilter( RegexExceptionFilter() ) # will raise VTKError if captured VTK Error
62-
mbLogger.setLevel( logging.DEBUG )
64+
vtkErrorLogger.addFilter( RegexExceptionFilter() ) # will raise VTKError if captured VTK Error
6365

6466
# Fill the partial attributes with default values to keep them during the merge.
6567
if keepPartialAttributes and not fillAllPartialAttributes( inputMesh, logger ):
66-
logger.warning( "Failed to fill partial attributes. Merging without keeping partial attributes." )
68+
raise ValueError( "Failed to fill partial attributes. Merging without keeping partial attributes." )
6769

6870
outputMesh: vtkUnstructuredGrid
6971

@@ -76,9 +78,10 @@ def mergeBlocks(
7678

7779
else:
7880
if inputMesh.IsA( "vtkDataSet" ):
79-
logger.warning( "Input mesh is already a single block." )
81+
vtkErrorLogger.warning( "Input mesh is already a single block." )
8082
outputMesh = vtkUnstructuredGrid.SafeDownCast( inputMesh )
8183
else:
84+
8285
with VTKCaptureLog() as captured_log:
8386

8487
af: vtkAppendDataSets = vtkAppendDataSets()
@@ -95,8 +98,14 @@ def mergeBlocks(
9598
captured_log.seek( 0 )
9699
captured = captured_log.read().decode()
97100

98-
mbLogger.debug( captured.strip() )
101+
if captured != "":
102+
vtkErrorLogger.error( captured.strip() )
103+
# raise VTKError( captured.strip() )
104+
# pass
99105

100106
outputMesh = af.GetOutputDataObject( 0 )
101107

108+
if outputMesh is None:
109+
raise VTKError( "Something went wrong in VTK" )
110+
102111
return outputMesh

geos-mesh/tests/test_multiblockModifiers.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99
from vtkmodules.vtkCommonDataModel import vtkMultiBlockDataSet, vtkUnstructuredGrid
1010
from geos.mesh.utils import multiblockModifiers
1111

12+
from unittest import TestCase
13+
from geos.utils.Errors import VTKError
14+
15+
import vtk
16+
from packaging.version import Version
17+
1218

1319
@pytest.mark.parametrize( "keepPartialAttributes, nbPointAttributes, nbCellAttributes, nbFieldAttributes", [
1420
( False, 0, 16, 1 ),
@@ -35,3 +41,14 @@ def test_mergeBlocks(
3541

3642
assert dataset.GetFieldData().GetNumberOfArrays(
3743
) == nbFieldAttributes, f"Expected {nbFieldAttributes} field attributes after the merge, not {dataset.GetFieldData().GetNumberOfArrays()}."
44+
45+
46+
class RaiseMergeBlocks( TestCase ):
47+
"""Test failure on empty multiBlockDataSet."""
48+
49+
def test_TypeError( self ) -> None:
50+
"""Test raise of TypeError."""
51+
multiBlockDataset = vtkMultiBlockDataSet() # should fail on empty data
52+
if Version( vtk.__version__ ) < Version( "9.5" ):
53+
with pytest.raises( VTKError ):
54+
multiblockModifiers.mergeBlocks( multiBlockDataset, True )

geos-processing/src/geos/processing/generic_processing_tools/AttributeMapping.py

Lines changed: 51 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ def __init__(
103103
else:
104104
self.logger = logging.getLogger( loggerTitle )
105105
self.logger.setLevel( logging.INFO )
106+
self.logger.propagate = False
106107

107108
def setLoggerHandler( self: Self, handler: logging.Handler ) -> None:
108109
"""Set a specific handler for the filter logger.
@@ -113,7 +114,7 @@ def setLoggerHandler( self: Self, handler: logging.Handler ) -> None:
113114
Args:
114115
handler (logging.Handler): The handler to add.
115116
"""
116-
if not self.logger.hasHandlers():
117+
if len( self.logger.handlers ) == 0:
117118
self.logger.addHandler( handler )
118119
else:
119120
self.logger.warning( "The logger already has an handler, to use yours set the argument 'speHandler'"
@@ -139,58 +140,58 @@ def applyFilter( self: Self ) -> bool:
139140
"""
140141
self.logger.info( f"Apply filter { self.logger.name }." )
141142

142-
if len( self.attributeNames ) == 0:
143-
self.logger.warning( f"Please enter at least one { self.piece } attribute to transfer." )
144-
self.logger.warning( f"The filter { self.logger.name } has not been used." )
145-
return False
146-
147-
attributesInMeshFrom: set[ str ] = getAttributeSet( self.meshFrom, self.onPoints )
148-
wrongAttributeNames: set[ str ] = self.attributeNames.difference( attributesInMeshFrom )
149-
if len( wrongAttributeNames ) > 0:
150-
self.logger.error(
151-
f"The { self.piece } attributes { wrongAttributeNames } are not present in the source mesh." )
152-
self.logger.error( f"The filter { self.logger.name } failed." )
153-
return False
154-
155-
attributesInMeshTo: set[ str ] = getAttributeSet( self.meshTo, self.onPoints )
156-
attributesAlreadyInMeshTo: set[ str ] = self.attributeNames.intersection( attributesInMeshTo )
157-
if len( attributesAlreadyInMeshTo ) > 0:
158-
self.logger.error(
159-
f"The { self.piece } attributes { attributesAlreadyInMeshTo } are already present in the final mesh." )
160-
self.logger.error( f"The filter { self.logger.name } failed." )
161-
return False
143+
try:
144+
if len( self.attributeNames ) == 0:
145+
raise ValueError( f"Please enter at least one { self.piece } attribute to transfer." )
146+
147+
attributesInMeshFrom: set[ str ] = getAttributeSet( self.meshFrom, self.onPoints )
148+
wrongAttributeNames: set[ str ] = self.attributeNames.difference( attributesInMeshFrom )
149+
if len( wrongAttributeNames ) > 0:
150+
raise AttributeError(
151+
f"The { self.piece } attributes { wrongAttributeNames } are not present in the source mesh." )
152+
153+
attributesInMeshTo: set[ str ] = getAttributeSet( self.meshTo, self.onPoints )
154+
attributesAlreadyInMeshTo: set[ str ] = self.attributeNames.intersection( attributesInMeshTo )
155+
if len( attributesAlreadyInMeshTo ) > 0:
156+
raise AttributeError(
157+
f"The { self.piece } attributes { attributesAlreadyInMeshTo } are already present in the final mesh."
158+
)
159+
160+
if isinstance( self.meshFrom, vtkMultiBlockDataSet ):
161+
partialAttributes: list[ str ] = []
162+
for attributeName in self.attributeNames:
163+
if not isAttributeGlobal( self.meshFrom, attributeName, self.onPoints ):
164+
partialAttributes.append( attributeName )
165+
166+
if len( partialAttributes ) > 0:
167+
raise AttributeError(
168+
f"All { self.piece } attributes to transfer must be global, { partialAttributes } are partials."
169+
)
170+
171+
self.ElementMap = computeElementMapping( self.meshFrom, self.meshTo, self.onPoints )
172+
sharedElement: bool = False
173+
for key in self.ElementMap:
174+
if np.any( self.ElementMap[ key ] > -1 ):
175+
sharedElement = True
176+
177+
if not sharedElement:
178+
raise ValueError( f"The two meshes do not have any shared { self.piece }." )
162179

163-
if isinstance( self.meshFrom, vtkMultiBlockDataSet ):
164-
partialAttributes: list[ str ] = []
165180
for attributeName in self.attributeNames:
166-
if not isAttributeGlobal( self.meshFrom, attributeName, self.onPoints ):
167-
partialAttributes.append( attributeName )
168-
169-
if len( partialAttributes ) > 0:
170-
self.logger.error(
171-
f"All { self.piece } attributes to transfer must be global, { partialAttributes } are partials." )
172-
self.logger.error( f"The filter { self.logger.name } failed." )
173-
174-
self.ElementMap = computeElementMapping( self.meshFrom, self.meshTo, self.onPoints )
175-
sharedElement: bool = False
176-
for key in self.ElementMap:
177-
if np.any( self.ElementMap[ key ] > -1 ):
178-
sharedElement = True
179-
180-
if not sharedElement:
181-
self.logger.warning( f"The two meshes do not have any shared { self.piece }." )
182-
self.logger.warning( f"The filter { self.logger.name } has not been used." )
181+
# TODO:: Modify arrayModifiers function to raise error.
182+
if not transferAttributeWithElementMap( self.meshFrom, self.meshTo, self.ElementMap, attributeName,
183+
self.onPoints, self.logger ):
184+
raise
185+
186+
# Log the output message.
187+
self._logOutputMessage()
188+
except ( TypeError, ValueError, AttributeError ) as e:
189+
self.logger.error( f"The filter { self.logger.name } failed.\n{ e }" )
190+
return False
191+
except Exception as e:
192+
mess: str = f"The filter { self.logger.name } failed.\n{ e }"
193+
self.logger.critical( mess, exc_info=True )
183194
return False
184-
185-
for attributeName in self.attributeNames:
186-
if not transferAttributeWithElementMap( self.meshFrom, self.meshTo, self.ElementMap, attributeName,
187-
self.onPoints, self.logger ):
188-
self.logger.error( f"The attribute { attributeName } has not been mapped." )
189-
self.logger.error( f"The filter { self.logger.name } failed." )
190-
return False
191-
192-
# Log the output message.
193-
self._logOutputMessage()
194195

195196
return True
196197

geos-processing/src/geos/processing/generic_processing_tools/ClipToMainFrame.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ def __init__( self, speHandler: bool = False, **properties: str ) -> None:
234234
else:
235235
self.logger = logging.getLogger( loggerTitle )
236236
self.logger.setLevel( logging.INFO )
237+
self.logger.propagate = False
237238

238239
def ComputeTransform( self ) -> None:
239240
"""Update the transformation."""
@@ -264,7 +265,7 @@ def SetLoggerHandler( self, handler: logging.Handler ) -> None:
264265
Args:
265266
handler (logging.Handler): The handler to add.
266267
"""
267-
if not self.logger.hasHandlers():
268+
if len( self.logger.handlers ) == 0:
268269
self.logger.addHandler( handler )
269270
else:
270271
self.logger.warning( "The logger already has an handler, to use yours set the argument 'speHandler' to True"

0 commit comments

Comments
 (0)