Skip to content

Commit 3fa72a0

Browse files
committed
BUG: Fix general issues and multi-threading issues
1 parent 8f54f43 commit 3fa72a0

1 file changed

Lines changed: 30 additions & 15 deletions

File tree

src/mimrec/src/MARMFitter.cxx

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
#include "Math/WrappedMultiTF1.h"
4545
#include "Fit/BinData.h"
4646
#include "Fit/UnBinData.h"
47-
#include "HFitInterface.h"
4847
#include "Fit/Fitter.h"
4948
#include "TLatex.h"
5049
#include "TStyle.h"
@@ -72,7 +71,7 @@ MARMFitter::MARMFitter()
7271
ROOT::Math::MinimizerOptions::SetDefaultMaxFunctionCalls(250000);
7372

7473
std::random_device RD; // <-- should use MEGAlib global
75-
std::mt19937 m_MersenneTwister(RD());
74+
m_MersenneTwister.seed(RD());
7675

7776
m_NumberOfBins = 101;
7877
m_MaxARMValue = 180;
@@ -818,18 +817,31 @@ bool MARMFitter::PerformFit(unsigned int FitID, vector<double>& ARMValues)
818817
ROOT::Fit::UnBinData UnbinnedData(CleanedData.size(), CleanedData.data(), Range);
819818
Fitter.LikelihoodFit(UnbinnedData, true);
820819
} else {
821-
//cout<<"Binned fit"<<endl;
822820
DataOptions.fIntegral = true;
823-
DataOptions.fUseRange =true;
824-
ROOT::Fit::BinData BinnedData(DataOptions, Range);
825-
// Easiest option to fill the binned data set is via a histogram:
826-
TH1D* D = new TH1D("", "", m_NumberOfBins, -m_MaxARMValue, m_MaxARMValue);
827-
for (auto& V: CleanedData) D->Fill(V);
828-
for (int b = 1; b <= D->GetNbinsX(); ++b) D->SetBinError(b, sqrt(D->GetBinContent(b)));
829-
ROOT::Fit::FillData(BinnedData, D);
830-
delete D;
821+
DataOptions.fUseRange = true;
822+
823+
// Bin the data directly into a counts vector — one entry per bin over [-m_MaxARMValue, m_MaxARMValue]
824+
double BinWidth = 2.0 * m_MaxARMValue / m_NumberOfBins;
825+
vector<double> BinCounts(m_NumberOfBins, 0.0);
826+
for (auto& V: CleanedData) {
827+
int Bin = static_cast<int>((V + m_MaxARMValue) / BinWidth);
828+
if (Bin >= 0 && Bin < static_cast<int>(m_NumberOfBins)) {
829+
BinCounts[Bin]++;
830+
}
831+
}
832+
833+
// Fill BinData directly: bin center, bin content, half-bin-width (required by fIntegral), Poisson error.
834+
// Empty bins are skipped, consistent with the default DataOptions.fUseEmpty = false.
835+
// kCoordError is required to store both x (bin half-width) and y (Poisson) errors,
836+
// which ROOT needs to integrate the fit function over each bin (fIntegral = true).
837+
ROOT::Fit::BinData BinnedData(DataOptions, Range, m_NumberOfBins, 1, ROOT::Fit::BinData::kCoordError);
838+
for (unsigned int b = 0; b < m_NumberOfBins; ++b) {
839+
if (BinCounts[b] == 0) continue;
840+
double BinCenter = -m_MaxARMValue + (b + 0.5) * BinWidth;
841+
BinnedData.Add(BinCenter, BinCounts[b], 0.5 * BinWidth, sqrt(BinCounts[b]));
842+
}
843+
831844
Fitter.LikelihoodFit(BinnedData, true);
832-
//Fitter.LeastSquareFit(BinnedData);
833845
}
834846

835847
// Retrieve results
@@ -936,11 +948,13 @@ vector<double> MARMFitter::BootstrapARMValues()
936948
{
937949
std::uniform_int_distribution<> Distributor(0, m_OriginalARMValues.size() - 1);
938950

939-
// Bootstrapping: sample with replacement
951+
// Bootstrapping: sample with replacement.
952+
// m_MersenneTwister is shared across threads, so all draws must be made under the mutex.
940953
vector<double> ARMValues;
941954
ARMValues.reserve(m_OriginalARMValues.size());
942955
for (size_t i = 0; i < m_OriginalARMValues.size(); ++i) {
943-
int D = Distributor(m_MersenneTwister);
956+
int D;
957+
{ std::unique_lock<std::mutex> Lock(m_Mutex); D = Distributor(m_MersenneTwister); }
944958
ARMValues.push_back(m_OriginalARMValues[D]);
945959
}
946960

@@ -1162,6 +1176,7 @@ bool MARMFitter::Fit(unsigned int NumberOfFits)
11621176
double MaxX = Hist->GetBinCenter(Hist->GetMaximumBin());
11631177
m_GuessMaximumLow = MaxX - 0.5*Hist->GetRMS();
11641178
m_GuessMaximumHigh = MaxX + 0.5*Hist->GetRMS();
1179+
delete Hist;
11651180

11661181

11671182
// Right size the result storage
@@ -1298,7 +1313,7 @@ double MARMFitter::Get95p5PercentContainmentUsingAllData() const
12981313
//! Return the 99.7% containment for all events
12991314
double MARMFitter::Get99p7PercentContainmentUsingAllData() const
13001315
{
1301-
return m_FitSuccessful ? m_Containment3SigmaUsingAllData : g_UnsignedIntNotDefined;
1316+
return m_FitSuccessful ? m_Containment3SigmaUsingAllData : g_DoubleNotDefined;
13021317
}
13031318

13041319

0 commit comments

Comments
 (0)