5050#include < Rtypes.h>
5151#include < RtypesCore.h>
5252
53+ #include < algorithm>
5354#include < array>
5455#include < cmath>
5556#include < cstdio>
@@ -199,13 +200,12 @@ void HFInvMassFitter::doFit()
199200 if (mTypeOfBkgPdf == NoBkg) { // MC
200201 mass->setRange (" signal" , mMass - 3 . * mSigmaSgn , mMass + 3 . * mSigmaSgn );
201202 } else {
203+ mass->setRange (" SBL" , mMinMass , mMass - mNSigmaForSidebands * mSigmaSgn );
202204 if (mTypeOfSgnPdf == GausSec) { // Second Peak fit range
203- mass->setRange (" SBL" , mMinMass , mMass - mNSigmaForSidebands * mSigmaSgn );
204205 mass->setRange (" SBR" , mMass + mNSigmaForSidebands * mSigmaSgn , mSecMass - mNSigmaForSidebands * mSecSigma );
205206 mass->setRange (" SEC" , mSecMass + mNSigmaForSidebands * mSecSigma , mMaxMass );
206207 mass->setRange (" signal" , mSecMass - mNSigmaForSgn * mSecSigma , mSecMass + mNSigmaForSgn * mSecSigma );
207208 } else { // Single Peak fit range
208- mass->setRange (" SBL" , mMinMass , mMass - mNSigmaForSidebands * mSigmaSgn );
209209 mass->setRange (" SBR" , mMass + mNSigmaForSidebands * mSigmaSgn , mMaxMass );
210210 mass->setRange (" signal" , mMass - mNSigmaForSgn * mSigmaSgn , mMass + mNSigmaForSgn * mSigmaSgn );
211211 }
@@ -215,12 +215,17 @@ void HFInvMassFitter::doFit()
215215 mInvMassFrame = mass->frame (Title (Form (" %s" , mHistoInvMass ->GetTitle ()))); // define the frame to plot
216216 dataHistogram.plotOn (mInvMassFrame , Name (" data_c" )); // plot data histogram on the frame
217217
218+ TH1 * histoInvMassSB = dynamic_cast <TH1 *>(mHistoInvMass ->Clone ());
219+ cutRangesFromHisto (histoInvMassSB, {" SBL" , " SBR" });
220+ histoInvMassSB->SaveAs (" histoInvMassSB.root" );
221+ RooDataHist sbHistogram (" sbHistogram" , " sb" , *mass, Import (*histoInvMassSB));
222+
218223 RooAbsPdf* bkgPdf = createBackgroundFitFunction (mWorkspace ); // Create background pdf
219224 RooAbsPdf* sgnPdf = createSignalFitFunction (mWorkspace ); // Create signal pdf
220225
226+ const double integralHisto = integrateHistoInvMassOverWorkspaceRanges ({" full" });
221227 // fit MC or Data
222228 if (mTypeOfBkgPdf == NoBkg) { // MC
223- const double integralHisto = integrateHistoInvMassOverWorkspaceRanges ({" full" });
224229 const ParameterRanges rooNSgnParamRanges{0.5 * integralHisto, 1.5 * integralHisto, integralHisto};
225230 mRooNSgn = new RooRealVar (" mRooNSig" , " number of signal" , randomizeInitialParameter (rooNSgnParamRanges), rooNSgnParamRanges.lower , rooNSgnParamRanges.upper ); // signal yield
226231 mTotalPdf = new RooAddPdf (" mMCFunc" , " MC fit function" , RooArgList (*sgnPdf), RooArgList (*mRooNSgn )); // create total pdf
@@ -248,13 +253,9 @@ void HFInvMassFitter::doFit()
248253 if (mTypeOfSgnPdf == GausSec) { // two peak fit
249254 sbRanges.append (" ,SEC" );
250255 }
251- if (strcmp (mFitOption .c_str (), " Chi2" ) == 0 ) {
252- mBkgPdf ->chi2FitTo (dataHistogram, Range (sbRanges.c_str ()), Save ());
253- } else {
254- mBkgPdf ->fitTo (dataHistogram, Range (sbRanges.c_str ()), Save ());
255- }
256-
256+ mBkgPdf ->chi2FitTo (sbHistogram, DataError (RooAbsData::SumW2), Save ());
257257 std::cout << " mRooNBkg->getVal() = " << mRooNBkg ->getVal () << " \n " ;
258+
258259 // define the frame to evaluate background sidebands chi2 (bg pdf needs to be plotted within sideband ranges)
259260 RooPlot* frameTemporary = mass->frame (Title (Form (" %s_temp" , mHistoInvMass ->GetTitle ())));
260261 dataHistogram.plotOn (frameTemporary, Name (" data_for_bkgchi2" ));
@@ -263,7 +264,7 @@ void HFInvMassFitter::doFit()
263264 delete frameTemporary;
264265 if (mDrawBgPrefit ) {
265266 RooAbsPdf* bkgPdfPrefit = dynamic_cast <RooAbsPdf*>(mBkgPdf ->Clone ());
266- bkgPdfPrefit->plotOn (mInvMassFrame , Range (" full" ), Name (" Bkg_c_prefit" ), LineColor (kGray ));
267+ bkgPdfPrefit->plotOn (mInvMassFrame , Range (" full" ), Normalization ( mRooNBkg -> getVal (), RooAbsReal::NumEvent), Name (" Bkg_c_prefit" ), LineColor (kGray ));
267268 delete bkgPdfPrefit;
268269 }
269270
@@ -275,7 +276,7 @@ void HFInvMassFitter::doFit()
275276 calculateBackground (mBkgYield , mBkgYieldErr ); // BG's absolute integral in "bkg" range
276277
277278 std::cout << " estimatedSignal = " << estimatedSignal << " \n " ;
278- const ParameterRanges rooNSgnParamRanges{0.5 * estimatedSignal, 1.5 * estimatedSignal, estimatedSignal};
279+ const ParameterRanges rooNSgnParamRanges{0.1 * estimatedSignal, 20 * estimatedSignal, estimatedSignal};
279280 mRooNSgn = new RooRealVar (" mNSgn" , " number of signal" , randomizeInitialParameter (rooNSgnParamRanges), rooNSgnParamRanges.lower , rooNSgnParamRanges.upper ); // estimated signal yield
280281 if (mFixedRawYield > 0 ) {
281282 mRooNSgn ->setVal (mFixedRawYield ); // fixed signal yield
@@ -1192,3 +1193,28 @@ double HFInvMassFitter::integrateHistoInvMassOverWorkspaceRanges(const std::vect
11921193
11931194 return sumEntries / sumLengths * fullLength;
11941195}
1196+
1197+ void HFInvMassFitter::cutRangesFromHisto (TH1 * histo, const std::vector<std::string>& ranges) const
1198+ {
1199+ auto * mass = mWorkspace ->var (" mass" );
1200+
1201+ for (int iBin = 1 , nBins = histo->GetNbinsX (); iBin <= nBins; ++iBin) {
1202+ const double binLow = histo->GetBinLowEdge (iBin);
1203+ const double binHigh = binLow + histo->GetBinWidth (iBin);
1204+
1205+ bool overlapsAnyRange = false ;
1206+ for (const auto & range : ranges) {
1207+ const double rangeMin = mass->getMin (range.c_str ());
1208+ const double rangeMax = mass->getMax (range.c_str ());
1209+ if (std::max (binLow, rangeMin) <= std::min (binHigh, rangeMax)) {
1210+ overlapsAnyRange = true ;
1211+ break ;
1212+ }
1213+ }
1214+
1215+ if (!overlapsAnyRange) {
1216+ histo->SetBinContent (iBin, 0 .);
1217+ histo->SetBinError (iBin, 1 .e9 );
1218+ }
1219+ }
1220+ }
0 commit comments