From 2b7e527c50e34f97455e49a598b6fdc46eb78c58 Mon Sep 17 00:00:00 2001
From: Hugo Karas <hkaras@ethz.ch>
Date: Mon, 16 Sep 2024 12:56:06 +0100
Subject: [PATCH] General improvemements

---
 deerlab/classes.py   |  2 +-
 deerlab/fit.py       |  4 ++--
 deerlab/fitresult.py | 31 +++++++++++++++++--------------
 3 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/deerlab/classes.py b/deerlab/classes.py
index d41e4482..49a6ec46 100644
--- a/deerlab/classes.py
+++ b/deerlab/classes.py
@@ -583,7 +583,7 @@ def propagate(self,model,lb=None,ub=None,samples=None):
                 # Get the parameter uncertainty distribution
                 values,pdf = self.pardist(n)
                 # Random sampling form the uncertainty distribution
-                sampled_parameters[n] =  [np.random.choice(values, p=pdf/sum(pdf)) for _ in range(Nsamples)]
+                sampled_parameters[n] = np.random.choice(values, p=pdf/sum(pdf),size=Nsamples)
             # Convert to matrix
             sampled_parameters = np.atleast_2d(sampled_parameters)
 
diff --git a/deerlab/fit.py b/deerlab/fit.py
index 0c516c15..a1b5e8bc 100644
--- a/deerlab/fit.py
+++ b/deerlab/fit.py
@@ -543,8 +543,8 @@ def _scale(x):
                     FitResult_param_[f'{key}_scale'] = _scale(FitResult_param_[key]) # Normalization factor
                     FitResult_param_[key] = param.normalization(FitResult_param_[key]) # Normalized value
 
-                    FitResult_paramuq_[f'{key}_scaleUncert'] = FitResult_paramuq_[f'{key}Uncert'].propagate(_scale,samples=bootstrap)
-                    FitResult_paramuq_[f'{key}Uncert'] = FitResult_paramuq_[f'{key}Uncert'].propagate(lambda x: x/FitResult_param_[f'{key}_scale'], lb=param.lb, ub=param.ub,samples=bootstrap) # Normalization of the uncertainty
+                    FitResult_paramuq_[f'{key}_scaleUncert'] = FitResult_paramuq_[f'{key}Uncert'].propagate(_scale,samples=bootstrap+1)
+                    FitResult_paramuq_[f'{key}Uncert'] = FitResult_paramuq_[f'{key}Uncert'].propagate(lambda x: x/FitResult_param_[f'{key}_scale'], lb=param.lb, ub=param.ub,samples=bootstrap+1) # Normalization of the uncertainty
     if len(noiselvl)==1: 
         noiselvl = noiselvl[0]
     
diff --git a/deerlab/fitresult.py b/deerlab/fitresult.py
index 6980c626..c1a552b0 100644
--- a/deerlab/fitresult.py
+++ b/deerlab/fitresult.py
@@ -97,20 +97,21 @@ def _extarct_params_from_model(self, model):
         if not hasattr(self,'param'):
             raise ValueError('The fit object does not contain any fitted parameters.')
 
-        # # Enforce model normalization
-        # normfactor_keys = []
-        # for key in modelparam:
-        #     param = getattr(model,key)
-        #     if np.all(param.linear):
-        #         if param.normalization is not None:
-        #             normfactor_key = f'{key}_scale'
-        #             normfactor_keys.append(normfactor_key)
-        #             try:
-        #                 model.addnonlinear(normfactor_key,lb=-np.inf,ub=np.inf,par0=1,description=f'Normalization factor of {key}')
-        #                 getattr(model,normfactor_key).freeze(1)
-        #             except KeyError:
-        #                 pass
-                    
+        # Enforce model normalization
+        normfactor_keys = []
+        for key in modelparam:
+            param = getattr(model,key)
+            if np.all(param.linear):
+                if param.normalization is not None:
+                    normfactor_key = f'{key}_scale'
+                    normfactor_keys.append(normfactor_key)
+                    try:
+                        model.addnonlinear(normfactor_key,lb=-np.inf,ub=np.inf,par0=1,description=f'Normalization factor of {key}')
+                        getattr(model,normfactor_key).freeze(1)
+                    except KeyError:
+                        pass
+        modelparam += normfactor_keys
+        
 
         # # Get some basic information on the parameter vector
         # modelparam = model._parameter_list(order='vector')
@@ -187,6 +188,7 @@ def evaluate(self, model, *constants):
             Model response at the fitted parameter values. 
         """
         try:
+            model = model.copy()
             modelparam = model._parameter_list('vector')
             modelparam, fitparams, fitparam_idx = self._extarct_params_from_model(model)
         except AttributeError:
@@ -234,6 +236,7 @@ def propagate(self, model, *constants, lb=None, ub=None,samples=None):
         responseUncert : :ref:`UQResult`
             Uncertainty quantification of the model's response.
         """
+        model = model.copy()
 
         try:
             modelparam = model._parameter_list('vector')