diff --git a/src/bayesvalidrox/bayes_inference/bayes_inference.py b/src/bayesvalidrox/bayes_inference/bayes_inference.py
index c8073ba76ebeb3249646e17b7f395f8a2472e2f6..3246f405815383cdc26e2502f2e4e6e92292f404 100644
--- a/src/bayesvalidrox/bayes_inference/bayes_inference.py
+++ b/src/bayesvalidrox/bayes_inference/bayes_inference.py
@@ -331,7 +331,7 @@ class BayesInference:
             for itr_idx, data in tqdm(
                     enumerate(self.perturbed_data),
                     total=self.n_bootstrap_itrs,
-                    desc="Boostraping the BME calculations", ascii=True
+                    desc="Bootstrapping the BME calculations", ascii=True
                     ):
 
                 # ---------------- Likelihood calculation ----------------
@@ -352,6 +352,16 @@ class BayesInference:
                     output_names[i]: data[j:k] for i, (j, k) in
                     enumerate(indices)
                     }
+                #print(output_names)
+                #print(indices)
+                #print(numbers)
+                #print(nobs)
+                #print(self.measured_data)
+                #for i, (j, k) in enumerate(indices):
+                #    print(i,j,k)
+                #print(data)
+                #print(data_dict)
+                #stop
 
                 # Unknown sigma2
                 if opt_sigma == 'C' or hasattr(self, 'sigma2s'):
@@ -370,7 +380,7 @@ class BayesInference:
                 # BME (log)
                 log_BME[itr_idx] = np.log(
                     np.nanmean(np.exp(logLikelihoods[:, itr_idx],
-                                      dtype=np.float128))
+                                      dtype=np.longdouble))#float128))
                     )
 
                 # BME correction when using Emulator
@@ -1042,9 +1052,9 @@ class BayesInference:
         # Take the first column of Likelihoods (Observation data without noise)
         if self.just_analysis or self.bayes_loocv:
             index = self.n_tot_measurement-1
-            likelihoods = np.exp(self.log_likes[:, index], dtype=np.float128)
+            likelihoods = np.exp(self.log_likes[:, index], dtype=np.longdouble)#np.float128)
         else:
-            likelihoods = np.exp(self.log_likes[:, 0], dtype=np.float128)
+            likelihoods = np.exp(self.log_likes[:, 0], dtype=np.longdouble)#np.float128)
 
         n_samples = len(likelihoods)
         norm_ikelihoods = likelihoods / np.max(likelihoods)
diff --git a/src/bayesvalidrox/bayes_inference/mcmc.py b/src/bayesvalidrox/bayes_inference/mcmc.py
index 6b9ca94823fb7064baa2f0588d0f97fb4c9d1d44..cc632c2de57140ab0ba4bd4c81a49316406dacd1 100755
--- a/src/bayesvalidrox/bayes_inference/mcmc.py
+++ b/src/bayesvalidrox/bayes_inference/mcmc.py
@@ -251,7 +251,7 @@ class MCMC:
 
                 # output current autocorrelation estimate
                 if self.verbose:
-                    print(f"Mean autocorr time estimate: {np.nanmean(tau):.3f}")
+                    print(f"Mean autocorr. time estimate: {np.nanmean(tau):.3f}")
                     list_gr = np.round(self.gelman_rubin(sampler.chain), 3)
                     print("Gelman-Rubin Test*: ", list_gr)
 
@@ -282,15 +282,15 @@ class MCMC:
         # Print summary
         print('\n')
         print('-'*15 + 'Posterior diagnostics' + '-'*15)
-        print(f"mean auto-correlation time: {np.nanmean(tau):.3f}")
-        print(f"thin: {thin}")
-        print(f"burn-in: {burnin}")
-        print(f"flat chain shape: {finalsamples.shape}")
-        print(f"Mean acceptance fraction: {acc_fr:.3f}")
-        print("Gelman-Rubin Test*: ", list_gr)
+        print(f"Mean auto-correlation time: {np.nanmean(tau):.3f}")
+        print(f"Thin: {thin}")
+        print(f"Burn-in: {burnin}")
+        print(f"Flat chain shape: {finalsamples.shape}")
+        print(f"Mean acceptance fraction*: {acc_fr:.3f}")
+        print("Gelman-Rubin Test**: ", list_gr)
 
         print("\n* This value must lay between 0.234 and 0.5.")
-        print("* These values must be smaller than 1.1.")
+        print("** These values must be smaller than 1.1.")
         print('-'*50)
 
         print(f"\n>>>> Bayesian inference with MCMC for {self.BayesOpts.name} "
@@ -777,7 +777,7 @@ class MCMC:
             )
         if ~np.isfinite(tmp['logml']):
             warnings.warn(
-                "logml could not be estimated within maxiter, rerunning with "
+                "Logml could not be estimated within maxiter, rerunning with "
                 "adjusted starting value. Estimate might be more variable than"
                 " usual.")
             # use geometric mean as starting value
diff --git a/src/bayesvalidrox/post_processing/post_processing.py b/src/bayesvalidrox/post_processing/post_processing.py
index 4db354bbd541affdc50a8dce37eb293188091f73..e1795a74ce7a7b7a7c9519b30b53e1ea11d4eab8 100644
--- a/src/bayesvalidrox/post_processing/post_processing.py
+++ b/src/bayesvalidrox/post_processing/post_processing.py
@@ -237,8 +237,8 @@ class PostProcessing:
         elif samples is not None:
             self.n_samples = samples.shape[0]
         else:
-            raise Exception("Please provide either samples or pass number of "
-                            "samples!")
+            raise Exception("Please provide either samples or pass the number"
+                            " of samples!")
 
         # Generate random samples if necessary
         Samples = self._get_sample() if samples is None else samples
@@ -922,7 +922,7 @@ class PostProcessing:
             ax = plt.gca()
             _, p = stats.shapiro(residuals)
             if p < 0.01:
-                annText = "The residuals seem to come from Gaussian process."
+                annText = "The residuals seem to come from a Gaussian Process."
             else:
                 annText = "The normality assumption may not hold."
             at = AnchoredText(annText, prop=dict(size=30), frameon=True,
diff --git a/src/bayesvalidrox/pylink/pylink.py b/src/bayesvalidrox/pylink/pylink.py
index 7af4a14b8f8acb62c21862d5df4a527dc7fe57b9..84695119a2631ab5d37e7c5c2d78b0d5a25b5e09 100644
--- a/src/bayesvalidrox/pylink/pylink.py
+++ b/src/bayesvalidrox/pylink/pylink.py
@@ -170,9 +170,9 @@ class PyLinkForwardModel(object):
                 obs = self.observations
             else:
                 raise Exception("Please provide the observation data as a "
-                                "dictionary via observations attribute or pass"
-                                " the csv-file path to MeasurementFile "
-                                "attribute")
+                                "dictionary via the observations attribute or "
+                                "pass the csv-file path to the MeasurementFile"
+                                " attribute")
         elif case.lower() == 'valid':
             if isinstance(self.observations_valid, dict) and \
               bool(self.observations_valid):
@@ -184,9 +184,9 @@ class PyLinkForwardModel(object):
                 obs = self.observations_valid
             else:
                 raise Exception("Please provide the observation data as a "
-                                "dictionary via Observations attribute or pass"
-                                " the csv-file path to MeasurementFile "
-                                "attribute")
+                                "dictionary via the observations attribute or "
+                                "pass the csv-file path to the MeasurementFile"
+                                " attribute")
 
         # Compute the number of observation
         n_obs = obs[self.Output.names].notnull().sum().values.sum()
@@ -316,9 +316,8 @@ class PyLinkForwardModel(object):
                 Process = os.system(f'./../{command}')
                 if Process != 0:
                     print('\nMessage 1:')
-                    print(f'\tIf value of \'{Process}\' is a non-zero value, '
-                          'then compilation problems \n' % Process)
-
+                    print(f'\tIf the value of \'{Process}\' is a non-zero value'
+                          ', then compilation problems occur \n' % Process)          
         os.chdir("..")
 
         # Read the output
@@ -438,6 +437,12 @@ class PyLinkForwardModel(object):
         # Initilization
         n_c_points = len(c_points)
         all_outputs = {}
+        
+        # TODO: if umbridge, just run, no parallel from here
+        # If the link type is UM-Bridge, then no parallel needs to be started from here
+        if self.link_type.lower() == 'umbridge':
+            # For now just do same as usual
+            self.link_type = 'function'
 
         # Extract the function
         if self.link_type.lower() == 'function':
@@ -499,7 +504,7 @@ class PyLinkForwardModel(object):
         if len(NaN_idx) != 0:
             print('\n')
             print('*'*20)
-            print("\nThe following parametersets have been removed:\n",
+            print("\nThe following parameter sets have been removed:\n",
                   c_points[NaN_idx])
             print("\n")
             print('*'*20)
@@ -656,6 +661,6 @@ class PyLinkForwardModel(object):
                 shutil.rmtree(path)
 
             print("\n")
-            print(f'{dir_name}.zip file has been created successfully!\n')
+            print(f'{dir_name}.zip has been created successfully!\n')
 
         return
diff --git a/src/bayesvalidrox/surrogate_models/bayes_linear.py b/src/bayesvalidrox/surrogate_models/bayes_linear.py
index a7d6b5929a83fc89d15d7ab8f369187d0542923c..767e6fff73df0d524dcf94e620b0a67ae0742d83 100644
--- a/src/bayesvalidrox/surrogate_models/bayes_linear.py
+++ b/src/bayesvalidrox/surrogate_models/bayes_linear.py
@@ -138,7 +138,7 @@ class EBLinearRegression(BayesianLinearRegression):
                  normalize=True, perfect_fit_tol = 1e-6, alpha = 1, copy_X = True, verbose = False):
         super(EBLinearRegression,self).__init__(n_iter, tol, fit_intercept, copy_X, verbose)
         if optimizer not in ['em','fp']:
-            raise ValueError('Optimizer can be either "em" of "fp" ')
+            raise ValueError('Optimizer can be either "em" or "fp" ')
         self.optimizer     =  optimizer 
         self.alpha         =  alpha 
         self.perfect_fit   =  False
diff --git a/src/bayesvalidrox/surrogate_models/meta_model_engine.py b/src/bayesvalidrox/surrogate_models/meta_model_engine.py
index 2df2dee5390ae4e6dc7eb88343c2469dbd88aad6..c2e9ec409a7d17ceb697c694d9845ede185a0d0c 100644
--- a/src/bayesvalidrox/surrogate_models/meta_model_engine.py
+++ b/src/bayesvalidrox/surrogate_models/meta_model_engine.py
@@ -1067,7 +1067,7 @@ class MetaModelEngine():
                                             maxfun=max_func_itr)
 
         if verbose:
-            print(f"global minimum: xmin = {Res_Global.x}, "
+            print(f"Global minimum: xmin = {Res_Global.x}, "
                   f"f(xmin) = {Res_Global.fun:.6f}, nfev = {Res_Global.nfev}")
 
         return (Run_No, Res_Global.x)
@@ -1237,7 +1237,7 @@ class MetaModelEngine():
 
             elapsed_time = time.time() - start_time
             print("\n")
-            print(f"elapsed_time: {round(elapsed_time,2)} sec.")
+            print(f"Elapsed_time: {round(elapsed_time,2)} sec.")
             print('-'*20)
 
         elif explore_method == 'LOOCV':
diff --git a/src/bayesvalidrox/surrogate_models/reg_fast_ard.py b/src/bayesvalidrox/surrogate_models/reg_fast_ard.py
index 44073da8e78642ba3b3914f6ce55a2d01986b1f1..e6883a3edd6d247c219b8be328f5206b75780fbb 100755
--- a/src/bayesvalidrox/surrogate_models/reg_fast_ard.py
+++ b/src/bayesvalidrox/surrogate_models/reg_fast_ard.py
@@ -286,9 +286,9 @@ class RegressionFastARD(LinearModel, RegressorMixin):
             # raise warning in case cholesky fails
             if warning_flag == 1:
                 warnings.warn(("Cholesky decomposition failed! Algorithm uses "
-                               "pinvh, which is significantly slower, if you "
+                               "pinvh, which is significantly slower. If you "
                                "use RVR it is advised to change parameters of "
-                               "kernel"))
+                               "the kernel!"))
 
             # compute quality & sparsity parameters
             s, q, S, Q = self._sparsity_quality(XX, XXd, XY, XYa, Aa, Ri,
@@ -319,7 +319,7 @@ class RegressionFastARD(LinearModel, RegressorMixin):
 
             if converged or i == self.n_iter - 1:
                 if converged and self.verbose:
-                    print('Algorithm converged !')
+                    print('Algorithm converged!')
                 break
 
         # after last update of alpha & beta update parameters
diff --git a/src/bayesvalidrox/surrogate_models/reg_fast_laplace.py b/src/bayesvalidrox/surrogate_models/reg_fast_laplace.py
index bdff324ede818a42d226e9aa55aaf01666ca8fc8..84faa6026e18f9013ed04b1bb08e2740671d3af3 100644
--- a/src/bayesvalidrox/surrogate_models/reg_fast_laplace.py
+++ b/src/bayesvalidrox/surrogate_models/reg_fast_laplace.py
@@ -307,7 +307,7 @@ class RegressionFastLaplace():
                 # recomputation
                 # zero if regressor has not been chosen yet
                 if not ind_global_to_local[ind_L_max]:
-                    raise Exception('cannot recompute index{0} -- not yet\
+                    raise Exception('Cannot recompute index{0} -- not yet\
                                     part of the model!'.format(ind_L_max))
                 Sigma = np.atleast_2d(Sigma)
                 mu = np.atleast_2d(mu)
diff --git a/src/bayesvalidrox/surrogate_models/sequential_design.py b/src/bayesvalidrox/surrogate_models/sequential_design.py
index fc81dcd4529ca0708dfba47385aef4415992eb3e..1e0935deed32ad5c398a82879d65723b22f03080 100644
--- a/src/bayesvalidrox/surrogate_models/sequential_design.py
+++ b/src/bayesvalidrox/surrogate_models/sequential_design.py
@@ -1099,7 +1099,7 @@ class SeqDesign():
                                             maxfun=max_func_itr)
 
         if verbose:
-            print(f"global minimum: xmin = {Res_Global.x}, "
+            print(f"Global minimum: xmin = {Res_Global.x}, "
                   f"f(xmin) = {Res_Global.fun:.6f}, nfev = {Res_Global.nfev}")
 
         return (Run_No, Res_Global.x)
@@ -1269,7 +1269,7 @@ class SeqDesign():
 
             elapsed_time = time.time() - start_time
             print("\n")
-            print(f"elapsed_time: {round(elapsed_time,2)} sec.")
+            print(f"Elapsed_time: {round(elapsed_time,2)} sec.")
             print('-'*20)
 
         elif explore_method == 'LOOCV':
diff --git a/src/bayesvalidrox/surrogate_models/surrogate_models.py b/src/bayesvalidrox/surrogate_models/surrogate_models.py
index c51ea8c6679aaeec685da069154e8f460c7c4450..96cb1d8c54a40911951b70b76b09ad15a4d6908a 100644
--- a/src/bayesvalidrox/surrogate_models/surrogate_models.py
+++ b/src/bayesvalidrox/surrogate_models/surrogate_models.py
@@ -136,7 +136,7 @@ class MetaModel():
 
         if self.ExpDesign.method == 'sequential':
             raise Exception(
-                "Please use MetaModelEngine class for the sequential design!"
+                "Please use the MetaModelEngine class for sequential design!"
                 )
 
         elif self.ExpDesign.method == 'normal':
@@ -238,7 +238,7 @@ class MetaModel():
         if verbose and self.n_bootstrap_itrs > 1:
             enum_obj = tqdm(range(self.n_bootstrap_itrs),
                             total=self.n_bootstrap_itrs,
-                            desc="Boostraping the metamodel",
+                            desc="Bootstrapping the metamodel",
                             ascii=True)
         else:
             enum_obj = range(self.n_bootstrap_itrs)
@@ -516,7 +516,7 @@ class MetaModel():
                 self.ModelOutputDict = ExpDesign.Y
             else:
                 raise Exception('Please provide either a dictionary or a hdf5'
-                                'file to ExpDesign.hdf5_file argument.')
+                                'file as the ExpDesign.hdf5_file argument.')
 
         return ED_X_tr, self.ModelOutputDict
 
@@ -882,9 +882,9 @@ class MetaModel():
             print(' '*10 + ' Summary of results ')
             print('='*50)
 
-            print("scores:\n", scores)
-            print("Best score's degree:", self.deg_array[best_deg-1])
-            print("NO. of terms:", len(basis_indices))
+            print("Scores:\n", scores)
+            print("Degree of best score:", self.deg_array[best_deg-1])
+            print("No. of terms:", len(basis_indices))
             print("Sparsity index:", round(len(basis_indices)/P, 3))
             print("Best Indices:\n", basis_indices)
 
@@ -980,7 +980,7 @@ class MetaModel():
         # only the trace is, to save memory)
         PsiM = np.dot(psi_sparse, M)
 
-        h = np.sum(np.multiply(PsiM, psi_sparse), axis=1, dtype=np.float128)
+        h = np.sum(np.multiply(PsiM, psi_sparse), axis=1, dtype=np.longdouble)#float128)
 
         # ------ Calculate Error Loocv for each measurement point ----
         # Residuals
diff --git a/src/test_umbridge.py b/src/test_umbridge.py
new file mode 100644
index 0000000000000000000000000000000000000000..8e7c32cf4c868445d641ee834ca850c1b279f4da
--- /dev/null
+++ b/src/test_umbridge.py
@@ -0,0 +1,114 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Mon Dec 11 14:03:23 2023
+
+Example and test for using umbridge with bayesvalidrox.
+Example model is the tsunami model by 
+docker run -it -p 4242:4242 -v ~/tsunami_output:/output linusseelinger/model-exahype-tsunami
+
+@author: rkohlhaas
+"""
+
+import joblib
+import numpy as np 
+import umbridge
+
+import bayesvalidrox as bv
+
+
+if __name__ == '__main__':
+    
+    # This model has 2 inputs and four outputs
+    n_prior_sample = 1000
+    priors = bv.Input()
+    priors.add_marginals()
+    priors.Marginals[0].name = 'x'
+    priors.Marginals[0].input_data = np.random.uniform(50,150,n_prior_sample)  
+    priors.add_marginals()
+    priors.Marginals[1].name = 'y'
+    priors.Marginals[1].input_data = np.random.uniform(50,150,n_prior_sample)
+    
+    # Define the model
+    model = bv.PyLinkForwardModel()
+    #model.link_type = 'Function'
+    model.link_type = 'umbridge'
+    model.py_file = 'tsunami_model'
+    model.name = 'tsunami_model'
+    model.Output.names = ['T1', 'T2', 'H1', 'H2']
+    #model.observations = data_dict1_times
+    
+    # Create the surrogate
+    surrogate_opts1 = bv.MetaModel(priors, model)
+    
+    # Select your metamodel method
+    surrogate_opts1.meta_model_type = 'aPCE'
+    surrogate_opts1.pce_reg_method = 'FastARD'
+    surrogate_opts1.pce_deg = np.arange(1, 5)
+    surrogate_opts1.pce_q_norm = 0.4#1.0
+
+    # Select your metamodel method         
+    surrogate_opts1.add_ExpDesign()
+    surrogate_opts1.ExpDesign.method = 'normal'
+    surrogate_opts1.ExpDesign.n_init_samples = 20
+    surrogate_opts1.ExpDesign.sampling_method = 'latin-hypercube'
+    surrogate1 = surrogate_opts1.create_metamodel()
+    print('Surrogate completed')
+    print('')
+
+    # Save surrogate
+    with open('tsunami.pk1', 'wb') as output:
+        joblib.dump(surrogate1, output, 2)
+    
+    # Post processing
+    L2_PostPCE = bv.PostProcessing(surrogate1)
+    L2_PostPCE.plot_moments(plot_type='line')
+    # Plot to check validation visually.
+    L2_PostPCE.valid_metamodel(n_samples=1)
+    # Compute and print RMSE error
+    L2_PostPCE.check_accuracy(n_samples=300)
+    total_sobol = L2_PostPCE.sobol_indices()
+    
+    # Test BayesInference
+    import copy
+    from tsunami_model import tsunami_model
+    true_data = tsunami_model(np.array([[90.0,60.0]]))
+    model.observations = true_data
+    true_data_nox = copy.deepcopy(true_data)
+    true_data_nox.pop('x_values')
+    
+    # Test surrogate output shape
+    mean, std = surrogate1.eval_metamodel(np.array([[90.0,60.0]]))
+    
+    # Set uncertainty
+    import pandas as pd
+    obsData = pd.DataFrame(true_data_nox, columns=model.Output.names)
+    DiscrepancyOpts = bv.Discrepancy('')
+    DiscrepancyOpts.type = 'Gaussian'
+    DiscrepancyOpts.parameters = (obsData*0.15)**2
+    
+    # Parameter estimation / single model validation via TOM
+    BayesOpts = bv.BayesInference(surrogate1)
+    BayesOpts.emulator= True
+    BayesOpts.plot_post_pred = True
+    #BayesOpts.inference_method = 'rejection'
+    BayesOpts.Discrepancy = DiscrepancyOpts
+    BayesOpts.bootstrap = True
+    BayesOpts.n_bootstrap_itrs = 10
+    BayesOpts.bootstrap_noise = 0.05
+    BayesOpts.out_dir = ''
+    
+    # Set the MCMC parameters
+    import emcee
+    BayesOpts.inference_method = "MCMC"
+    BayesOpts.mcmc_params = {
+        'n_steps': 1e3,
+        'n_walkers': 30,
+        'moves': emcee.moves.KDEMove(),
+        'multiprocessing': False,
+        'verbose': False
+        }
+     
+    Bayes = BayesOpts.create_inference()
+    # Pkl the inference results
+    with open(f'Bayes_{model.name}.pkl', 'wb') as output:
+        joblib.dump(Bayes, output, 2)
\ No newline at end of file
diff --git a/src/tsunami.pk1 b/src/tsunami.pk1
new file mode 100644
index 0000000000000000000000000000000000000000..3f5e6991ba13f525c9e5d63d9e044796c36de9e0
Binary files /dev/null and b/src/tsunami.pk1 differ
diff --git a/src/tsunami_model.py b/src/tsunami_model.py
new file mode 100644
index 0000000000000000000000000000000000000000..6e9b0e50bed2ea2d0e01eb9125ff6c2d8cb12a0d
--- /dev/null
+++ b/src/tsunami_model.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+"""
+Runs the umbridge command for the tsunami model
+
+@author: Rebecca Kohlhaas
+"""
+import umbridge
+import numpy as np
+
+def tsunami_model(params):
+    model = umbridge.HTTPModel('http://localhost:4242', 'forward')
+    out = np.array(model(np.ndarray.tolist(params)))
+    
+    return {'T1': out[:,0], 'T2': out[:,1], 'H1': out[:,2], 'H2': out[:,3], 'x_values': [0]}
+    
+    
\ No newline at end of file