Repository: DARMA-tasking/LB-analysis-framework

Issue:
Different runtime errors occurring depending on whether vtk package is installed or not
## Steps to repeat
Identical as those of #509 

## Observed errors
### If `vtk` package is **not** installed via `pip`
```
(lbaf39) [pppebay@aneto]~/Documents/Git/LB-analysis-framework/src/lbaf/Applications$ pip uninstall vtk
Found existing installation: vtk 9.1.0
Uninstalling vtk-9.1.0:
  Would remove:
    /Users/pppebay/miniconda3/envs/lbaf39/lib/python3.9/site-packages/vtk-9.1.0.dist-info/*
    /Users/pppebay/miniconda3/envs/lbaf39/lib/python3.9/site-packages/vtk.py
    /Users/pppebay/miniconda3/envs/lbaf39/lib/python3.9/site-packages/vtkmodules/*
Proceed (Y/n)?  
  Successfully uninstalled vtk-9.1.0
(lbaf39) [pppebay@aneto]~/Documents/Git/LB-analysis-framework/src/lbaf/Applications$ python LBAF_app.py -c ../../../config/test-vt-tv.yaml
Traceback (most recent call last):
  File "/Users/pppebay/Documents/Git/LB-analysis-framework/src/lbaf/Applications/LBAF_app.py", line 19, in <module>
    import lbaf.IO.lbsStatistics as lbstats
  File "/Users/pppebay/Documents/Git/LB-analysis-framework/src/lbaf/__init__.py", line 21, in <module>
    from lbaf.Applications.MoveCountsViewer import MoveCountsViewer
  File "/Users/pppebay/Documents/Git/LB-analysis-framework/src/lbaf/Applications/MoveCountsViewer.py", line 5, in <module>
    import vtk
ModuleNotFoundError: No module named 'vtk'
```

### If `vtk` package installed via `pip`
Prior to de-installing it a runtime error occurred, but following uninstallation and re-installation, the following **warning** is issued:
```
[LBAF_app] Executing with Python 3.9.19
objc[51824]: Class vtkCocoaTimer is implemented in both /Users/pppebay/Documents/Build/VTK-9.3.0@Release/lib/libvtkRenderingUI-9.3.9.3.dylib (0x102fa8200) and /Users/pppebay/miniconda3/envs/lbaf39/lib/python3.9/site-packages/vtkmodules/.dylibs/libvtkRenderingUI-9.3.dylib (0x1203c43e0). One of the two will be used. Which one is undefined.
objc[51824]: Class vtkCocoaFullScreenWindow is implemented in both /Users/pppebay/Documents/Build/VTK-9.3.0@Release/lib/libvtkRenderingOpenGL2-9.3.9.3.dylib (0x103fe4ba0) and /Users/pppebay/miniconda3/envs/lbaf39/lib/python3.9/site-packages/vtkmodules/.dylibs/libvtkRenderingOpenGL2-9.3.dylib (0x153e16068). One of the two will be used. Which one is undefined.
objc[51824]: Class vtkCocoaServer is implemented in both /Users/pppebay/Documents/Build/VTK-9.3.0@Release/lib/libvtkRenderingOpenGL2-9.3.9.3.dylib (0x103fe4bc8) and /Users/pppebay/miniconda3/envs/lbaf39/lib/python3.9/site-packages/vtkmodules/.dylibs/libvtkRenderingOpenGL2-9.3.dylib (0x153e16090). One of the two will be used. Which one is undefined.
objc[51824]: Class vtkCocoaGLView is implemented in both /Users/pppebay/Documents/Build/VTK-9.3.0@Release/lib/libvtkRenderingOpenGL2-9.3.9.3.dylib (0x103fe4c18) and /Users/pppebay/miniconda3/envs/lbaf39/lib/python3.9/site-packages/vtkmodules/.dylibs/libvtkRenderingOpenGL2-9.3.dylib (0x153e160e0). One of the two will be used. Which one is undefined.
objc[51825]: Class vtkCocoaTimer is implemented in both /Users/pppebay/Documents/Build/VTK-9.3.0@Release/lib/libvtkRenderingUI-9.3.9.3.dylib (0x10390c200) and /Users/pppebay/miniconda3/envs/lbaf39/lib/python3.9/site-packages/vtkmodules/.dylibs/libvtkRenderingUI-9.3.dylib (0x111fdc3e0). One of the two will be used. Which one is undefined.
objc[51825]: Class vtkCocoaFullScreenWindow is implemented in both /Users/pppebay/Documents/Build/VTK-9.3.0@Release/lib/libvtkRenderingOpenGL2-9.3.9.3.dylib (0x104948ba0) and /Users/pppebay/miniconda3/envs/lbaf39/lib/python3.9/site-packages/vtkmodules/.dylibs/libvtkRenderingOpenGL2-9.3.dylib (0x166092068). One of the two will be used. Which one is undefined.
objc[51825]: Class vtkCocoaServer is implemented in both /Users/pppebay/Documents/Build/VTK-9.3.0@Release/lib/libvtkRenderingOpenGL2-9.3.9.3.dylib (0x104948bc8) and /Users/pppebay/miniconda3/envs/lbaf39/lib/python3.9/site-packages/vtkmodules/.dylibs/libvtkRenderingOpenGL2-9.3.dylib (0x166092090). One of the two will be used. Which one is undefined.
objc[51825]: Class vtkCocoaGLView is implemented in both /Users/pppebay/Documents/Build/VTK-9.3.0@Release/lib/libvtkRenderingOpenGL2-9.3.9.3.dylib (0x104948c18) and /Users/pppebay/miniconda3/envs/lbaf39/lib/python3.9/site-packages/vtkmodules/.dylibs/libvtkRenderingOpenGL2-9.3.dylib (0x1660920e0). One of the two will be used. Which one is undefined.
```
but code runs to completion.

It remains concerning to have this warning, e**specially considering the fact that before uninstall/reinstall** it resulted in a segfault as follows:
```
zsh: segmentation fault  python LBAF_app.py -c ../../../config/test-vt-tv.yaml
```
```


Discussion:

Patch:
diff --git a/src/lbaf/Applications/LBAF_app.py b/src/lbaf/Applications/LBAF_app.py
index 9c00900..167b2ad 100644
--- a/src/lbaf/Applications/LBAF_app.py
+++ b/src/lbaf/Applications/LBAF_app.py
@@ -121,7 +121,7 @@ class InternalParameters:
 
             # Ensure that vttv module was found
             if not using_vttv:
-                self.__logger.warning("Visualization enabled but vttv not found. No visualization will be generated.")
+                raise ModuleNotFoundError("Visualization enabled but vt-tv module not found.")
 
             # Retrieve mandatory visualization parameters
             try:
diff --git a/src/lbaf/Applications/MoveCountsViewer.py b/src/lbaf/Applications/MoveCountsViewer.py
index 52cc368..cb23723 100644
--- a/src/lbaf/Applications/MoveCountsViewer.py
+++ b/src/lbaf/Applications/MoveCountsViewer.py
@@ -2,7 +2,11 @@ import os
 import sys
 import csv
 import importlib
-import vtk
+try:
+    import vtk
+    using_vtk = True
+except ModuleNotFoundError:
+    using_vtk = False
 
 # pylint:disable=C0413:wrong-import-position
 # Use lbaf module from source if lbaf package is not installed
@@ -333,6 +337,10 @@ class MoveCountsViewer:
             writer.Write()
 
     def run(self):
+        # Raise error if vtk is not installed
+        if not using_vtk:
+            raise ModuleNotFoundError("Could not find vtk module, which is required for the MoveCountsViewer.")
+
         """Run the MoveCountViewer logic."""
         # Parse command line arguments
         self.__parse_args()


Test patch:
diff --git a/tests/unit/IO/test_lbs_visualizer_deprecation.py b/tests/unit/IO/test_lbs_visualizer_deprecation.py
index 563bece..002e2a6 100644
--- a/tests/unit/IO/test_lbs_visualizer_deprecation.py
+++ b/tests/unit/IO/test_lbs_visualizer_deprecation.py
@@ -22,7 +22,7 @@ class TestVizDeprecation(unittest.TestCase):
         config_file = os.path.join(os.path.dirname(os.path.dirname(__file__)), "config", "conf_wrong_visualization.yml")
         pipes = subprocess.Popen(["python", "src/lbaf", "-c", config_file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
         std_err = pipes.communicate()[1].decode("utf-8")
-        assert "Visualization enabled but vttv not found. No visualization will be generated." in std_err
+        assert "Visualization enabled but vt-tv module not found." in std_err
 
 if __name__ == "__main__":
     unittest.main()