diff --git a/extreme_estimator/estimator/abstract_estimator.py b/extreme_estimator/estimator/abstract_estimator.py
index 3cd9220683c5c2c5d6a69ac3fa1d5ca9bd5eeb19..0b938d36253cfd0966cfcd0ac9cdffc77ce0a38f 100644
--- a/extreme_estimator/estimator/abstract_estimator.py
+++ b/extreme_estimator/estimator/abstract_estimator.py
@@ -1,5 +1,6 @@
 import time
 
+from extreme_estimator.extreme_models.result_from_fit import ResultFromFit
 from extreme_estimator.extreme_models.margin_model.margin_function.abstract_margin_function import \
     AbstractMarginFunction
 from extreme_estimator.extreme_models.margin_model.margin_function.linear_margin_function import LinearMarginFunction
@@ -18,7 +19,7 @@ class AbstractEstimator(object):
     def __init__(self, dataset: AbstractDataset):
         self.dataset = dataset  # type: AbstractDataset
         self.additional_information = dict()
-        self._params_fitted = None
+        self._result_from_fit = None  # type: ResultFromFit
         self._margin_function_fitted = None
         self._max_stable_model_fitted = None
 
@@ -34,9 +35,9 @@ class AbstractEstimator(object):
         self.additional_information[self.DURATION] = int((te - ts) * 1000)
 
     @property
-    def params_fitted(self):
+    def fitted_values(self):
         assert self.is_fitted
-        return self._params_fitted
+        return self._result_from_fit.fitted_values
 
     # @property
     # def max_stable_fitted(self) -> AbstractMarginFunction:
@@ -57,7 +58,7 @@ class AbstractEstimator(object):
 
     @property
     def is_fitted(self):
-        return self._params_fitted is not None
+        return self._result_from_fit is not None
 
     @property
     def train_split(self):
diff --git a/extreme_estimator/estimator/full_estimator/abstract_full_estimator.py b/extreme_estimator/estimator/full_estimator/abstract_full_estimator.py
index 70259c5237572b5aab842ad488891882516aff13..16652bcece59d58a8b5b599485c51e53e61e80d5 100644
--- a/extreme_estimator/estimator/full_estimator/abstract_full_estimator.py
+++ b/extreme_estimator/estimator/full_estimator/abstract_full_estimator.py
@@ -55,7 +55,7 @@ class FullEstimatorInASingleStepWithSmoothMargin(AbstractFullEstimator):
 
     def _fit(self):
         # Estimate both the margin and the max-stable structure
-        self._params_fitted = self.max_stable_model.fitmaxstab(
+        self._result_from_fit = self.max_stable_model.fitmaxstab(
             maxima_gev=self.dataset.maxima_gev(split=self.train_split),
             df_coordinates=self.dataset.df_coordinates(split=self.train_split),
             fit_marge=True,
@@ -63,7 +63,7 @@ class FullEstimatorInASingleStepWithSmoothMargin(AbstractFullEstimator):
             margin_start_dict=self.linear_margin_function_to_fit.coef_dict
         )
         # Create the fitted margin function
-        self.extract_fitted_models_from_fitted_params(self.linear_margin_function_to_fit, self._params_fitted)
+        self.extract_fitted_models_from_fitted_params(self.linear_margin_function_to_fit, self.fitted_values)
 
 
 class PointwiseAndThenUnitaryMsp(AbstractFullEstimator):
diff --git a/extreme_estimator/estimator/margin_estimator/abstract_margin_estimator.py b/extreme_estimator/estimator/margin_estimator/abstract_margin_estimator.py
index d79fcec2e475ab3af8f594fb242ceb366a32fa3b..f9b369e7085604aa4479e6a8569d7f3a826db8fe 100644
--- a/extreme_estimator/estimator/margin_estimator/abstract_margin_estimator.py
+++ b/extreme_estimator/estimator/margin_estimator/abstract_margin_estimator.py
@@ -37,8 +37,8 @@ class SmoothMarginEstimator(AbstractMarginEstimator):
         maxima_gev = self.dataset.maxima_gev(split=self.train_split)
         df_coordinates_spatial = self.dataset.coordinates.df_spatial_coordinates(self.train_split)
         df_coordinates_temporal = self.dataset.coordinates.df_temporal_coordinates(self.train_split)
-        self._params_fitted = self.margin_model.fitmargin_from_maxima_gev(maxima_gev=maxima_gev,
-                                                                          df_coordinates_spatial=df_coordinates_spatial,
-                                                                          df_coordinates_temporal=df_coordinates_temporal)
-        self.extract_fitted_models_from_fitted_params(self.margin_model.margin_function_start_fit, self._params_fitted)
+        self._result_from_fit = self.margin_model.fitmargin_from_maxima_gev(maxima_gev=maxima_gev,
+                                                                            df_coordinates_spatial=df_coordinates_spatial,
+                                                                            df_coordinates_temporal=df_coordinates_temporal)
+        self.extract_fitted_models_from_fitted_params(self.margin_model.margin_function_start_fit, self.fitted_values)
         assert isinstance(self.margin_function_fitted, AbstractMarginFunction)
diff --git a/extreme_estimator/estimator/max_stable_estimator/abstract_max_stable_estimator.py b/extreme_estimator/estimator/max_stable_estimator/abstract_max_stable_estimator.py
index 9fe8d2e8cf4d7ca1bb468bbf945aaf919c5ecc8a..9016613e718e26c6a25939c815cb674067f7398b 100644
--- a/extreme_estimator/estimator/max_stable_estimator/abstract_max_stable_estimator.py
+++ b/extreme_estimator/estimator/max_stable_estimator/abstract_max_stable_estimator.py
@@ -18,9 +18,10 @@ class MaxStableEstimator(AbstractMaxStableEstimator):
 
     def _fit(self):
         assert self.dataset.maxima_frech(split=self.train_split) is not None
-        self.max_stable_params_fitted = self.max_stable_model.fitmaxstab(
+        self._result_from_fit = self.max_stable_model.fitmaxstab(
             maxima_frech=self.dataset.maxima_frech(split=self.train_split),
             df_coordinates=self.dataset.df_coordinates(split=self.train_split))
+        self.max_stable_params_fitted = self.fitted_values
 
     def _error(self, true_max_stable_params: dict):
         absolute_errors = {param_name: np.abs(param_true_value - self.max_stable_params_fitted[param_name])
diff --git a/extreme_estimator/extreme_models/margin_model/smooth_margin_model.py b/extreme_estimator/extreme_models/margin_model/smooth_margin_model.py
index 5622ad5f3ce0c44192c0564d5e0d7d3ab5c32834..0fa0e34b4d756cf378ba73143c724ee6efc79b7e 100644
--- a/extreme_estimator/extreme_models/margin_model/smooth_margin_model.py
+++ b/extreme_estimator/extreme_models/margin_model/smooth_margin_model.py
@@ -1,12 +1,11 @@
-from typing import Dict
-
 import numpy as np
 import pandas as pd
 
+from extreme_estimator.extreme_models.result_from_fit import ResultFromFit
 from extreme_estimator.extreme_models.margin_model.abstract_margin_model import AbstractMarginModel
 from extreme_estimator.extreme_models.margin_model.margin_function.linear_margin_function import LinearMarginFunction
 from extreme_estimator.extreme_models.margin_model.param_function.linear_coef import LinearCoef
-from extreme_estimator.extreme_models.utils import safe_run_r_estimator, r, retrieve_fitted_values, get_coord, \
+from extreme_estimator.extreme_models.utils import safe_run_r_estimator, r, get_coord, \
     get_margin_formula
 from extreme_estimator.margin_fits.gev.gev_params import GevParams
 
@@ -59,7 +58,7 @@ class LinearMarginModel(AbstractMarginModel):
         return cls(coordinates, params_sample=params, params_start_fit=params)
 
     def fitmargin_from_maxima_gev(self, maxima_gev: np.ndarray, df_coordinates_spatial: pd.DataFrame,
-                                  df_coordinates_temporal: pd.DataFrame) -> Dict[str, float]:
+                                  df_coordinates_temporal: pd.DataFrame) -> ResultFromFit:
         # The reshaping on the line below is only valid if we have a single observation per spatio-temporal point
         if maxima_gev.shape[1] == 1:
             maxima_gev = maxima_gev.reshape([len(df_coordinates_temporal), len(df_coordinates_spatial)])
@@ -75,9 +74,8 @@ class LinearMarginModel(AbstractMarginModel):
         coef_dict = self.margin_function_start_fit.coef_dict
         fit_params['start'] = r.list(**coef_dict)
 
-        res = safe_run_r_estimator(function=r.fitspatgev, use_start=self.use_start_value, data=data,
-                                   covariables=covariables, **fit_params)
-        return retrieve_fitted_values(res)
+        return safe_run_r_estimator(function=r.fitspatgev, use_start=self.use_start_value, data=data,
+                                    covariables=covariables, **fit_params)
 
 
 class ConstantMarginModel(LinearMarginModel):
diff --git a/extreme_estimator/extreme_models/max_stable_model/abstract_max_stable_model.py b/extreme_estimator/extreme_models/max_stable_model/abstract_max_stable_model.py
index 78ae219a174b9cd846fbc218196066789af4723d..231a46a85ed11f0fef1c8cf0d0bf86b0f2d35ed4 100644
--- a/extreme_estimator/extreme_models/max_stable_model/abstract_max_stable_model.py
+++ b/extreme_estimator/extreme_models/max_stable_model/abstract_max_stable_model.py
@@ -2,10 +2,10 @@ from enum import Enum
 
 import numpy as np
 import pandas as pd
-import rpy2.robjects as robjects
 
 from extreme_estimator.extreme_models.abstract_model import AbstractModel
-from extreme_estimator.extreme_models.utils import r, safe_run_r_estimator, retrieve_fitted_values, get_coord, \
+from extreme_estimator.extreme_models.result_from_fit import ResultFromFit
+from extreme_estimator.extreme_models.utils import r, safe_run_r_estimator, get_coord, \
     get_margin_formula
 from spatio_temporal_dataset.coordinates.abstract_coordinates import AbstractCoordinates
 
@@ -21,8 +21,7 @@ class AbstractMaxStableModel(AbstractModel):
         return {'cov.mod': self.cov_mod}
 
     def fitmaxstab(self, df_coordinates: pd.DataFrame, maxima_frech: np.ndarray = None, maxima_gev: np.ndarray = None,
-                   fit_marge=False,
-                   fit_marge_form_dict=None, margin_start_dict=None) -> dict:
+                   fit_marge=False, fit_marge_form_dict=None, margin_start_dict=None) -> ResultFromFit:
         assert isinstance(df_coordinates, pd.DataFrame)
         if fit_marge:
             assert fit_marge_form_dict is not None
@@ -63,8 +62,7 @@ class AbstractMaxStableModel(AbstractModel):
         fit_params['fit.marge'] = fit_marge
 
         # Run the fitmaxstab in R
-        res = safe_run_r_estimator(function=r.fitmaxstab, use_start=self.use_start_value, data=data, coord=coord, **fit_params)
-        return retrieve_fitted_values(res)
+        return safe_run_r_estimator(function=r.fitmaxstab, use_start=self.use_start_value, data=data, coord=coord, **fit_params)
 
     def rmaxstab(self, nb_obs: int, coordinates_values: np.ndarray) -> np.ndarray:
         """
diff --git a/extreme_estimator/extreme_models/result_from_fit.py b/extreme_estimator/extreme_models/result_from_fit.py
new file mode 100644
index 0000000000000000000000000000000000000000..b8a8d7d18378e5af351dd3f683886b3939c89451
--- /dev/null
+++ b/extreme_estimator/extreme_models/result_from_fit.py
@@ -0,0 +1,31 @@
+from typing import Dict
+
+from rpy2 import robjects
+
+
+class ResultFromFit(object):
+    """
+    Handler from any result with the result of a fit functions from the package Spatial Extreme
+    """
+    FITTED_VALUES_NAME = 'fitted.values'
+    CONVERGENCE_NAME = 'convergence'
+
+    def __init__(self, result_from_fit: robjects.ListVector) -> None:
+        if hasattr(result_from_fit, 'names'):
+            self.name_to_value = {name: result_from_fit.rx2(name) for name in result_from_fit.names}
+        else:
+            self.name_to_value = {}
+
+    @property
+    def names(self):
+        return self.name_to_value.keys()
+
+    @property
+    def convergence(self):
+        convergence_value = self.name_to_value[self.CONVERGENCE_NAME]
+        return convergence_value
+
+    @property
+    def fitted_values(self) -> Dict[str, float]:
+        fitted_values = self.name_to_value[self.FITTED_VALUES_NAME]
+        return {key: fitted_values.rx2(key)[0] for key in fitted_values.names}
diff --git a/extreme_estimator/extreme_models/utils.py b/extreme_estimator/extreme_models/utils.py
index d404a9940a10f474171a1f4954255e66a716725d..057dfdfb6663d2973800c3717088ccf556f7d965 100644
--- a/extreme_estimator/extreme_models/utils.py
+++ b/extreme_estimator/extreme_models/utils.py
@@ -16,6 +16,8 @@ from rpy2.rinterface._rinterface import RRuntimeError
 from rpy2.robjects import numpy2ri
 from rpy2.robjects import pandas2ri
 
+from extreme_estimator.extreme_models.result_from_fit import ResultFromFit
+
 r = ro.R()
 numpy2ri.activate()
 pandas2ri.activate()
@@ -41,7 +43,7 @@ class WarningMaximumAbsoluteValueTooHigh(Warning):
     pass
 
 
-def safe_run_r_estimator(function, data, use_start=False, threshold_max_abs_value=100, **parameters):
+def safe_run_r_estimator(function, data, use_start=False, threshold_max_abs_value=100, **parameters) -> ResultFromFit:
     # Raise warning if the maximum absolute value is above a threshold
     assert isinstance(data, np.ndarray)
     maximum_absolute_value = np.max(np.abs(data))
@@ -54,6 +56,7 @@ def safe_run_r_estimator(function, data, use_start=False, threshold_max_abs_valu
     # First run without using start value
     # Then if it crashes, use start value
     run_successful = False
+    res = None
     while not run_successful:
         current_parameter = parameters.copy()
         if not use_start and 'start' in current_parameter:
@@ -70,15 +73,7 @@ def safe_run_r_estimator(function, data, use_start=False, threshold_max_abs_valu
             if isinstance(e, RRuntimeWarning):
                 print(e.__repr__())
                 print('WARNING')
-    return res
-
-
-def retrieve_fitted_values(res: robjects.ListVector) -> Dict[str, float]:
-    # todo: maybe if the convergence was not successful I could try other starting point several times
-    # Retrieve the resulting fitted values
-    fitted_values = res.rx2('fitted.values')
-    fitted_values = {key: fitted_values.rx2(key)[0] for key in fitted_values.names}
-    return fitted_values
+    return ResultFromFit(res)
 
 
 def get_coord(df_coordinates: pd.DataFrame):
diff --git a/test/test_unitary/test_fitmaxstab/test_fitmaxstab_with_margin.py b/test/test_unitary/test_fitmaxstab/test_fitmaxstab_with_margin.py
index 4246cb2785aed58bb110fcc817e26836c4db8a81..a4e29995136747183cfb9ac6a30b2d8be7e3c9b0 100644
--- a/test/test_unitary/test_fitmaxstab/test_fitmaxstab_with_margin.py
+++ b/test/test_unitary/test_fitmaxstab/test_fitmaxstab_with_margin.py
@@ -31,7 +31,7 @@ class TestMaxStableFitWithConstantMargin(TestUnitaryAbstract):
         full_estimator = FullEstimatorInASingleStepWithSmoothMargin(dataset, margin_model,
                                                                     max_stable_model)
         full_estimator.fit()
-        return full_estimator.params_fitted
+        return full_estimator.fitted_values
 
     def test_max_stable_fit_with_constant_margin(self):
         self.compare()
@@ -59,7 +59,7 @@ class TestMaxStableFitWithLinearMargin(TestUnitaryAbstract):
         full_estimator = FullEstimatorInASingleStepWithSmoothMargin(dataset, margin_model,
                                                                     max_stable_model)
         full_estimator.fit()
-        return full_estimator.params_fitted
+        return full_estimator.fitted_values
 
     def test_max_stable_fit_with_linear_margin(self):
         self.compare()