@@ -657,12 +657,38 @@ void FitPVResiduals(TString namesandlabels,
657657 timer .Continue ();
658658 }
659659
660+ // Lambda function to determine the effective number of entries
661+ auto getEffectiveEntries = [](TH1 * hist ) -> double {
662+ if (!hist ) {
663+ std ::cerr << "Invalid histogram pointer!" << std ::endl ;
664+ return 0. ;
665+ }
666+
667+ double entries = hist -> GetEntries () / hist -> GetNbinsX ();
668+
669+ // Check if the histogram was hadded (entries != 1 indicates potential hadding)
670+ if (entries != 1 ) {
671+ // If the sum of weights is not equal to effective entries, it suggests that the histogram was weighted
672+ if (hist -> GetSumOfWeights () != hist -> GetEffectiveEntries ()) {
673+ entries = 1. ; // Assuming overall sum of weights is 1 (lumi-weighted histograms)
674+ }
675+ }
676+
677+ if (isDebugMode ) {
678+ std ::cout << "name:" << hist -> GetName () << " bins:" << hist -> GetNbinsX () << " sumW:" << hist -> GetSumOfWeights ()
679+ << " effective entries:" << hist -> GetEffectiveEntries () << " returned entries:" << entries << std ::endl ;
680+ }
681+
682+ return entries ;
683+ };
684+
660685 for (Int_t i = 0 ; i < nFiles_ ; i ++ ) {
661686 fins [i ]-> cd ("PVValidation/EventFeatures/" );
662687
663688 if (gDirectory -> GetListOfKeys ()-> Contains ("etaMax" )) {
664689 gDirectory -> GetObject ("etaMax" , theEtaHistos [i ]);
665- theEtaMax_ [i ] = theEtaHistos [i ]-> GetBinContent (1 ) / theEtaHistos [i ]-> GetEntries ();
690+ double entries = getEffectiveEntries (theEtaHistos [i ]);
691+ theEtaMax_ [i ] = theEtaHistos [i ]-> GetBinContent (1 ) / entries ;
666692 std ::cout << "File n. " << i << " has theEtaMax[" << i << "] = " << theEtaMax_ [i ] << std ::endl ;
667693 } else {
668694 theEtaMax_ [i ] = 2.5 ;
@@ -671,7 +697,8 @@ void FitPVResiduals(TString namesandlabels,
671697
672698 if (gDirectory -> GetListOfKeys ()-> Contains ("nbins" )) {
673699 gDirectory -> GetObject ("nbins" , thebinsHistos [i ]);
674- theNBINS [i ] = thebinsHistos [i ]-> GetBinContent (1 ) / thebinsHistos [i ]-> GetEntries ();
700+ double entries = getEffectiveEntries (thebinsHistos [i ]);
701+ theNBINS [i ] = thebinsHistos [i ]-> GetBinContent (1 ) / entries ;
675702 std ::cout << "File n. " << i << " has theNBINS[" << i << "] = " << theNBINS [i ] << std ::endl ;
676703 } else {
677704 theNBINS [i ] = 48. ;
@@ -680,7 +707,8 @@ void FitPVResiduals(TString namesandlabels,
680707
681708 if (gDirectory -> GetListOfKeys ()-> Contains ("nladders" )) {
682709 gDirectory -> GetObject ("nladders" , theLaddersHistos [i ]);
683- theLadders [i ] = theLaddersHistos [i ]-> GetBinContent (1 ) / theLaddersHistos [i ]-> GetEntries ();
710+ double entries = getEffectiveEntries (theLaddersHistos [i ]);
711+ theLadders [i ] = theLaddersHistos [i ]-> GetBinContent (1 ) / entries ;
684712 std ::cout << "File n. " << i << " has theNLadders[" << i << "] = " << theLadders [i ] << std ::endl ;
685713 } else {
686714 theLadders [i ] = -1. ;
@@ -689,7 +717,8 @@ void FitPVResiduals(TString namesandlabels,
689717
690718 if (gDirectory -> GetListOfKeys ()-> Contains ("nModZ" )) {
691719 gDirectory -> GetObject ("nModZ" , theModZHistos [i ]);
692- theModZ [i ] = theModZHistos [i ]-> GetBinContent (1 ) / theModZHistos [i ]-> GetEntries ();
720+ double entries = getEffectiveEntries (theModZHistos [i ]);
721+ theModZ [i ] = theModZHistos [i ]-> GetBinContent (1 ) / entries ;
693722 std ::cout << "File n. " << i << " has theNModZ[" << i << "] = " << theModZ [i ] << std ::endl ;
694723 } else {
695724 theModZ [i ] = -1. ;
@@ -698,10 +727,10 @@ void FitPVResiduals(TString namesandlabels,
698727
699728 if (gDirectory -> GetListOfKeys ()-> Contains ("pTinfo" )) {
700729 gDirectory -> GetObject ("pTinfo" , thePtInfoHistos [i ]);
701- thePTBINS [ i ] = thePtInfoHistos [ i ] -> GetBinContent ( 1 ) * 3. / thePtInfoHistos [i ]-> GetEntries ( );
702- ;
703- thePtMin [i ] = thePtInfoHistos [i ]-> GetBinContent (2 ) * 3. / thePtInfoHistos [ i ] -> GetEntries () ;
704- thePtMax [i ] = thePtInfoHistos [i ]-> GetBinContent (3 ) * 3. / thePtInfoHistos [ i ] -> GetEntries () ;
730+ double entries = getEffectiveEntries ( thePtInfoHistos [i ]);
731+ thePTBINS [ i ] = thePtInfoHistos [ i ] -> GetBinContent ( 1 ) / entries ;
732+ thePtMin [i ] = thePtInfoHistos [i ]-> GetBinContent (2 ) / entries ;
733+ thePtMax [i ] = thePtInfoHistos [i ]-> GetBinContent (3 ) / entries ;
705734 std ::cout << "File n. " << i << " has thePTBINS[" << i << "] = " << thePTBINS [i ] << " pT min: " << thePtMin [i ]
706735 << " pT max: " << thePtMax [i ] << std ::endl ;
707736 } else {
@@ -727,7 +756,7 @@ void FitPVResiduals(TString namesandlabels,
727756 gDirectory -> GetObject ("h_probeRefitVSigXY" , dxySigRefit [i ]);
728757 gDirectory -> GetObject ("h_probeRefitVSigZ" , dzSigRefit [i ]);
729758
730- for (Int_t j = 0 ; j < theNBINS [i ]; j ++ ) {
759+ for (Int_t j = 0 ; j < Int_t ( theNBINS [i ]) ; j ++ ) {
731760 if (stdres ) {
732761 // DCA absolute residuals
733762
@@ -757,7 +786,7 @@ void FitPVResiduals(TString namesandlabels,
757786 // double differential residuals
758787
759788 if (do2DMaps ) {
760- for (Int_t k = 0 ; k < theNBINS [i ]; k ++ ) {
789+ for (Int_t k = 0 ; k < Int_t ( theNBINS [i ]) ; k ++ ) {
761790 // absolute residuals
762791 fins [i ]-> cd ("PVValidation/Abs_DoubleDiffResiduals/" );
763792 gDirectory -> GetObject (Form ("histo_dxy_eta_plot%i_phi_plot%i" , j , k ), dxyMapResiduals [i ][j ][k ]);
@@ -792,7 +821,7 @@ void FitPVResiduals(TString namesandlabels,
792821
793822 // double differential residuals
794823 if (do2DMaps ) {
795- for (Int_t k = 0 ; k < theNBINS [i ]; k ++ ) {
824+ for (Int_t k = 0 ; k < Int_t ( theNBINS [i ]) ; k ++ ) {
796825 // absolute residuals
797826 fins [i ]-> cd ("PVValidation/Abs_DoubleDiffResiduals" );
798827 gDirectory -> GetObject (Form ("PVValidation/Abs_DoubleDiffResiduals/histo_dxy_eta_plot%i_phi_plot%i" , j , k ),
@@ -815,7 +844,7 @@ void FitPVResiduals(TString namesandlabels,
815844
816845 // residuals vs pT
817846
818- for (Int_t l = 0 ; l < thePTBINS [i ] - 1 ; l ++ ) {
847+ for (Int_t l = 0 ; l < Int_t ( thePTBINS [i ] - 1 ) ; l ++ ) {
819848 dxyPtResiduals [i ][l ] = (TH1F * )fins [i ]-> Get (Form ("PVValidation/Abs_Transv_pT_Residuals/histo_dxy_pT_plot%i" , l ));
820849 dzPtResiduals [i ][l ] = (TH1F * )fins [i ]-> Get (Form ("PVValidation/Abs_Long_pT_Residuals/histo_dz_pT_plot%i" , l ));
821850
@@ -3054,11 +3083,26 @@ std::pair<params::measurement, params::measurement> fitResiduals(TH1 *hist, bool
30543083 sigma = func .GetParameter (2 );
30553084
30563085 if (!singleTime ) {
3057- // second fit: three sigma of first fit around mean of first fit
3086+ // Check if histogram is weighted
3087+ double sumWeights = hist -> GetSumOfWeights ();
3088+ double effectiveEntries = hist -> GetEffectiveEntries ();
3089+ bool isWeighted = !(sumWeights == effectiveEntries );
3090+
3091+ if (isWeighted && isDebugMode ) {
3092+ std ::cout << "A weighted input histogram has been provided, will use least squares fit instead of likelihood!"
3093+ << " Sum of weights: " << sumWeights << " effective entries: " << hist -> GetEffectiveEntries ()
3094+ << std ::endl ;
3095+ }
3096+ // If histogram is weighted, exclude the "L" option (Likelihood fit)
3097+ std ::string fitOptions = isWeighted ? "Q0R" : "Q0LR" ;
3098+
3099+ // second fit: two sigma of first fit around mean of first fit
30583100 func .SetRange (std ::max (mean - 2 * sigma , minHist ), std ::min (mean + 2 * sigma , maxHist ));
3101+
3102+ // Perform fit with the appropriate options
30593103 // I: integral gives more correct results if binning is too wide
30603104 // L: Likelihood can treat empty bins correctly (if hist not weighted...)
3061- if (0 == hist -> Fit (& func , "Q0LR" )) {
3105+ if (0 == hist -> Fit (& func , fitOptions . c_str () )) {
30623106 if (hist -> GetFunction (func .GetName ())) { // Take care that it is later on drawn:
30633107 hist -> GetFunction (func .GetName ())-> ResetBit (TF1 ::kNotDraw );
30643108 }
0 commit comments