From f23a5c98f76dbfcd97040a39fa4b0ffffab59ad8 Mon Sep 17 00:00:00 2001
From: kohlhaasrebecca <rebecca.kohlhaas@outlook.com>
Date: Wed, 9 Oct 2024 12:17:21 +0200
Subject: [PATCH] [tests] Add some PCE PostProcessing tests

---
 .../post_processing/post_processing.py        |  27 ++++-
 tests/test_PostProcessing.py                  | 104 +++++++++++++++++-
 2 files changed, 125 insertions(+), 6 deletions(-)

diff --git a/src/bayesvalidrox/post_processing/post_processing.py b/src/bayesvalidrox/post_processing/post_processing.py
index c32abd626..e68e5120e 100644
--- a/src/bayesvalidrox/post_processing/post_processing.py
+++ b/src/bayesvalidrox/post_processing/post_processing.py
@@ -552,9 +552,9 @@ class PostProcessing:
         # This function currently only supports PCE/aPCE
         PCEModel = self.engine.MetaModel
         if not hasattr(PCEModel, 'meta_model_type'):
-            raise AttributeError('Sobol indices currently only support PCE-type models!')
+            raise AttributeError('Sobol indices only support PCE-type models!')
         if PCEModel.meta_model_type.lower() not in ['pce', 'apce']:
-            raise AttributeError('Sobol indices currently only support PCE-type models!')
+            raise AttributeError('Sobol indices only support PCE-type models!')
             
         # Extract the necessary variables
         basis_dict = PCEModel._basis_dict
@@ -949,10 +949,14 @@ class PostProcessing:
 
     # -------------------------------------------------------------------------
     def eval_pce_model_3d(self):
+        # This function currently only supports PCE/aPCE
+        PCEModel = self.engine.MetaModel
+        if not hasattr(PCEModel, 'meta_model_type'):
+            raise AttributeError('This evaluation only support PCE-type models!')
+        if PCEModel.meta_model_type.lower() not in ['pce', 'apce']:
+            raise AttributeError('This evaluation only support PCE-type models!')
 
         self.n_samples = 1000
-
-        PCEModel = self.engine.MetaModel
         n_samples = self.n_samples
 
         # Create 3D-Grid
@@ -1094,7 +1098,13 @@ class PostProcessing:
         None.
 
         """
-        PCEModel = self.MetaModel
+        # This function currently only supports PCE/aPCE
+        PCEModel = self.engine.MetaModel
+        if not hasattr(PCEModel, 'meta_model_type'):
+            raise AttributeError('This evaluation only support PCE-type models!')
+        if PCEModel.meta_model_type.lower() not in ['pce', 'apce']:
+            raise AttributeError('This evaluation only support PCE-type models!')
+
 
         # get the samples
         x_val = self.samples
@@ -1170,6 +1180,13 @@ class PostProcessing:
         None.
 
         """
+        # This function currently only supports PCE/aPCE
+        PCEModel = self.engine.MetaModel
+        if not hasattr(PCEModel, 'meta_model_type'):
+            raise AttributeError('This evaluation only support PCE-type models!')
+        if PCEModel.meta_model_type.lower() not in ['pce', 'apce']:
+            raise AttributeError('This evaluation only support PCE-type models!')
+
         newpath = f'Outputs_PostProcessing_{self.name}/'
         if not os.path.exists(newpath):
             os.makedirs(newpath)
diff --git a/tests/test_PostProcessing.py b/tests/test_PostProcessing.py
index 7e686b2c9..79cb666f7 100644
--- a/tests/test_PostProcessing.py
+++ b/tests/test_PostProcessing.py
@@ -41,6 +41,8 @@ def basic_engine():
     mod = PL()
     expdes = ExpDesigns(inp)
     engine = Engine(mm, mod, expdes)
+    engine.out_names = ['Z']
+    engine.emulator = True
     return engine
 
 @pytest.fixture
@@ -53,11 +55,14 @@ def pce_engine():
     expdes.init_param_space(max_deg=1)
     expdes.X = np.array([[0], [1], [0.5]])
     expdes.Y = {'Z': [[0.4], [0.5], [0.45]]}
+    expdes.x_values = [0]
 
     mm = PCE(inp)
     mm.fit(expdes.X, expdes.Y)
     mod = PL()
     engine = Engine(mm, mod, expdes)
+    engine.out_names = ['Z']
+    engine.emulator = True
     return engine
 
 #%% Test PostProcessing init
@@ -72,16 +77,113 @@ def test_postprocessing(basic_engine) -> None:
     
 #%% plot_moments
 
+def test_plot_moments_pce(pce_engine) -> None:
+    """
+    Plot moments for PCE metamodel
+    """
+    engine = pce_engine
+    post = PostProcessing(engine)
+    mean, stdev = post.plot_moments()
+    # Check the mean dict
+    assert list(mean.keys()) == ['Z']
+    assert mean['Z'].shape == (1,)
+    assert mean['Z'][0] == pytest.approx(0.4, abs=0.01)
+    # Check the stdev dict
+    assert list(stdev.keys()) == ['Z']
+    assert stdev['Z'].shape == (1,)
+    assert stdev['Z'][0] == pytest.approx(0.1, abs=0.01)
+    
+def test_plot_moments_pcebar(pce_engine) -> None:
+    """
+    Plot moments for PCE metamodel with bar-plot
+    """
+    engine = pce_engine
+    post = PostProcessing(engine)
+    mean, stdev = post.plot_moments(plot_type='bar')
+    # Check the mean dict
+    assert list(mean.keys()) == ['Z']
+    assert mean['Z'].shape == (1,)
+    assert mean['Z'][0] == pytest.approx(0.4, abs=0.01)
+    # Check the stdev dict
+    assert list(stdev.keys()) == ['Z']
+    assert stdev['Z'].shape == (1,)
+    assert stdev['Z'][0] == pytest.approx(0.1, abs=0.01)
+    
+
 #%% valid_metamodel
 
 #%% check_accuracy
 
+def test_check_accuracy_pce(pce_engine) -> None:
+    """
+    Check accuracy for PCE metamodel 
+    """
+    engine = pce_engine
+    post = PostProcessing(engine)
+    post.check_accuracy(samples = engine.ExpDesign.X, outputs = engine.ExpDesign.Y)
+
+
 #%% plot_seq_design
 #%% sobol_indices
+
+def test_sobol_indices_nopce(basic_engine) -> None:
+    """
+    Calculate sobol indices for non-PCE metamodel
+    """
+    engine = basic_engine
+    post = PostProcessing(engine)
+    with pytest.raises(AttributeError) as excinfo:
+        post.sobol_indices()
+    assert str(excinfo.value) == 'Sobol indices only support PCE-type models!'
+    
+def test_sobol_indices_pce(pce_engine) -> None:
+    """
+    Calculate sobol indices for PCE metamodel
+    """
+    engine = pce_engine
+    post = PostProcessing(engine)
+    sobol = post.sobol_indices()
+    assert list(sobol.keys()) == ['Z']
+    assert sobol['Z'].shape == (1,1)
+    assert sobol['Z'][0,0] == 1
+
 #%% check_reg_quality
 #%% eval_pce_model_3d
+
+def test_eval_pce_model_3d_nopce(basic_engine) -> None:
+    """
+    3d eval of non-PCE metamodel
+    """
+    engine = basic_engine
+    post = PostProcessing(engine)
+    with pytest.raises(AttributeError) as excinfo:
+        post.eval_pce_model_3d()
+    assert str(excinfo.value) == 'This evaluation only support PCE-type models!'
+    
+
 #%% _get_sample
 #%% _eval_model
-#%% plot_validation
+#%% _plot_validation
+
+def test_plot_validation_nopce(basic_engine) -> None:
+    """
+    Plot validation of non-PCE metamodel
+    """
+    engine = basic_engine
+    post = PostProcessing(engine)
+    with pytest.raises(AttributeError) as excinfo:
+        post._plot_validation()
+    assert str(excinfo.value) == 'This evaluation only support PCE-type models!'
+    
 #%% _plot_validation_multi
+    
+def test_plot_validation_multi_nopce(basic_engine) -> None:
+    """
+    Plot multi-validation of non-PCE metamodel
+    """
+    engine = basic_engine
+    post = PostProcessing(engine)
+    with pytest.raises(AttributeError) as excinfo:
+        post._plot_validation_multi()
+    assert str(excinfo.value) == 'This evaluation only support PCE-type models!'
     
\ No newline at end of file
-- 
GitLab