From 8d666a3fec6c4af0b0a846f232c4ce3138f3e0f5 Mon Sep 17 00:00:00 2001
From: Jack Christopher Hutchinson Rolph <jack.rolph@desy.de>
Date: Wed, 11 Jan 2023 20:05:37 +0100
Subject: [PATCH] Update PeakOTron.py

---
 PeakOTron.py | 139 +++++++++++++++++++--------------------------------
 1 file changed, 52 insertions(+), 87 deletions(-)

diff --git a/PeakOTron.py b/PeakOTron.py
index d6f33b8..53a2f36 100644
--- a/PeakOTron.py
+++ b/PeakOTron.py
@@ -64,6 +64,7 @@ class PeakOTron:
             "bin_centres":None,
             "counts_bg":None,
             "counts_bgsub":None,
+            "truncate_nsigma0_do_min":None,
             "bw":None,
             "peaks":{
                 "peak_position":None,
@@ -102,7 +103,7 @@ class PeakOTron:
         self._verbose=verbose
         self._n_call_minuit = n_call_minuit
         self._n_iterations_minuit = n_iterations_minuit
-        
+       
         
         self._max_n_peaks = None
         self._max_n_peaks_dcr = 6
@@ -350,107 +351,68 @@ class PeakOTron:
     ##
     ## Calculates the Chi2 of the resultant fit relative to the original density estimate.
     ########################################################################################################
-
-    
-    
-#     def __CalcChi2(self, x, y, y_hat, y_err):
-#         chi2 = np.nansum(((y_hat - y)/y_err)**2)
-#         ndof = len(x) - 10
-#         return chi2, ndof
-    
-    
-    
-#     def GetChi2(self, prefit=False):
-        
-#         if(self._m_DRM is None):
-#             raise Exception ("Fit has not yet been performed. Please first perform a fit.")
-#         else:
-
-#             x_all = self._hist_data["bin_numbers"]
-#             y_all = self._hist_data["counts"]
-#             y_err_all = self._hist_data["counts_error"]
-            
-#             if(self._fit_kwargs["truncate_nsigma0_do"] is not None):
-#                 lim_nsigma0 = self._prefit_values_bin["Q_0"] - self._fit_kwargs["truncate_nsigma0_do"]*self._prefit_values_bin["sigma_0"]
-#                 cond_sel_nsigma0 = (self._hist_data["bin_numbers"]>lim_nsigma0)
-
-#             else:
-#                 cond_sel_nsigma0 = np.full(len(self._hist_data["bin_numbers"]), True).astype(bool)
-
-#             x = x_all[cond_sel_nsigma0]
-#             y = y_all[cond_sel_nsigma0]
-#             y_err = y_err_all[cond_sel_nsigma0]
-
-#             y_hat = self.GetModel(x, prefit=prefit, bin_units=True)
-#             y_hat_err = np.sqrt(y_hat)
-            
-                 
-#             plt.figure()
-#             plt.plot(x, (y-y_hat)/y_err)
-#             plt.show()
-        
-#             chi2, ndof = self.__CalcChi2(x, y, y_hat, y_err)
-
-#             return chi2, ndof
-    
+   
     
 
     
-    def GetChi2(self, pars=None, prefit=False, full=False, n_sigma_lims=[None, None]):
+    def GetChi2(self, pars=None, prefit=False,  n_sigma_lims=[None, None]):
 
      
-        x_all = self._hist_data["bin_numbers"]
-        y_all = self._hist_data["counts"]
-        y_err_all = self._hist_data["counts_error"]
+        _x_all = self._hist_data["bin_numbers"]
+        _y_all = self._hist_data["counts"]
+        _y_err_all = self._hist_data["counts_error"]
         
-        Q_0_prefit = self._prefit_values_bin["Q_0"]
-        sigma_0_prefit = self._prefit_values_bin["sigma_0"]
+        _Q_0_prefit = self._prefit_values_bin["Q_0"]
+        _sigma_0_prefit = self._prefit_values_bin["sigma_0"]
+
+
 
         if(pars is None):
-            y_hat_all = self.GetModel(x_all, prefit=prefit, bin_units=True)
+            _y_hat_all = self.GetModel(_x_all, prefit=prefit, bin_units=True)
         else:
-            y_hat_all = DRM(x_all, **pars)
+            _y_hat_all = DRM(_x_all, **pars)
             
         
-        conds = []
-        
-        
-        cond_count = (y_all>1) & (y_hat_all>1)
+        cond_count = (_y_all>1) 
 
-        conds.append(cond_count)
-#         print("Check nsigma = {:3.3f} for chi2".format(self._fit_kwargs["truncate_nsigma0_do"]))
-        
+      
         if(n_sigma_lims[0] is None):
-            if(self._fit_kwargs["truncate_nsigma0_do"] is not None and not full):
-                n_sigma_lims[0] = self._fit_kwargs["truncate_nsigma0_do"]
-
+            if(self._hist_data["truncate_nsigma0_do_min"] is not None):
+                _lim_nsigma0_low = _Q_0_prefit -self._hist_data["truncate_nsigma0_do_min"]*_sigma_0_prefit
+            else:
+                _lim_nsigma0_low = -np.inf
+        else:
+            _lim_nsigma0_low = _Q_0_prefit - n_sigma_lims[0]*_sigma_0_prefit
+    
+        if(n_sigma_lims[1] is None):
+            _lim_nsigma0_hi = np.inf
+        else:
+            _lim_nsigma0_hi = _Q_0_prefit + n_sigma_lims[1]*_sigma_0_prefit
       
-        if(n_sigma_lims[0] is not None and not full):
-            lim_nsigma0_low = Q_0_prefit - n_sigma_lims[0]*sigma_0_prefit
-            cond_nsigma0_low = (x_all > lim_nsigma0_low)
-            conds.append(cond_nsigma0_low)
-
-        if(n_sigma_lims[1] is not None and not full):
-            lim_nsigma0_hi = Q_0_prefit + n_sigma_lims[1]*sigma_0_prefit
-            cond_nsigma0_hi = (x_all < lim_nsigma0_hi)
-            conds.append(cond_nsigma0_hi)
+       
+        
+        cond_nsigma0_low = (_x_all > _lim_nsigma0_low)
+        cond_nsigma0_hi = (_x_all < _lim_nsigma0_hi)
               
-        conds = np.vstack(conds).all(axis=0)
+        conds = cond_count & cond_nsigma0_low & cond_nsigma0_hi
         
+
         
-        x = x_all[conds]
-        y = y_all[conds]
-        y_err = y_err_all[conds]
-        y_hat = y_hat_all[conds]
-        y_hat_err =  np.sqrt(y_hat_all[conds])
+        _x = _x_all[conds]
+        _y = _y_all[conds]
+        _y_err = _y_err_all[conds]
+        _y_hat = _y_hat_all[conds]
+        _y_hat_err =  np.sqrt(_y_hat_all[conds])
         
+    
 
         
                     
-        chi2 = np.nansum(((y_hat - y)/y_hat_err)**2)
-        ndof = len(x)-10
-
+        chi2 = np.sum(((_y_hat - _y)/_y_hat_err)**2)
+        ndof = len(_x)-10
         
+       
+
         return chi2, ndof
     
 
@@ -1076,8 +1038,8 @@ class PeakOTron:
         sigma_0_prefit = self._prefit_values_bin["sigma_0"]
         
         
-        if(self._fit_kwargs["truncate_nsigma0_do"] is not None):
-            lim_nsigma0 =  Q_0_prefit - self._fit_kwargs["truncate_nsigma0_do"]*sigma_0_prefit
+        if(self._hist_data["truncate_nsigma0_do_min"] is not None):
+            lim_nsigma0 =  Q_0_prefit - self._hist_data["truncate_nsigma0_do_min"]*sigma_0_prefit
             cond_sel_nsigma0 = (self._hist_data["bin_numbers"]>lim_nsigma0)
           
         else:
@@ -1089,10 +1051,11 @@ class PeakOTron:
         
         y_hat = self.GetModel(x, prefit=prefit, bin_units=plot_in_bins)*bw
         y_hat_err = np.sqrt(y_hat)
-        
-        
+       
         chi2, ndf = self.GetChi2(prefit=prefit)
             
+
+
         if(xlabel is None):
             if(plot_in_bins):
                 xlabel="Bin"
@@ -1680,14 +1643,14 @@ class PeakOTron:
 
 
                         if(self._fit_kwargs["truncate_nsigma0_chi2scanlim"] is not None):
-                            if(red_chi2_full<self._fit_kwargs["truncate_nsigma0_chi2scanlim"]):
+                            if(red_chi2_range<self._fit_kwargs["truncate_nsigma0_chi2scanlim"]):
                                 if(self._verbose):
                                     print("Fit chi2/NDF less than limit. (Fit: {:3.3f} < Limit {:3.3f}. Scan complete".format(red_chi2, 
                                                                                                                    self._fit_kwargs["truncate_nsigma0_chi2scanlim"]))
 
                                 self._m_DRM = deepcopy(m_DRM)
                                 self._time_fit = np.sum(time_fits)
-                                self._fit_kwargs["truncate_nsigma0_do"] = _nsigma0low
+                                self._hist_data["truncate_nsigma0_do_min"] = _nsigma0low
                                 
 
                                 break
@@ -1715,8 +1678,10 @@ class PeakOTron:
 
                         self._m_DRM = deepcopy(m_DRMs[fit_i_best])
                         self._time_fit = np.sum(time_fits)
-                        self._fit_kwargs["truncate_nsigma0_do"] = nsigma_0_scan_range[fit_i_best]
 
+                        #print(self._hist_data["truncate_nsigma0_do_min"] )
+                        self._hist_data["truncate_nsigma0_do_min"] = nsigma_0_scan_range[fit_i_best]
+                        #print(self._hist_data["truncate_nsigma0_do_min"] )
             else:
                   
                 f_DRM = BinnedLH(DRM, 
-- 
GitLab