Skip to content

Commit 18685de

Browse files
maxgallianigamova
authored andcommitted
Add non-uniform binning support for fastVerticalInterpHistPdf2 codegen implementation
1 parent fec3e76 commit 18685de

File tree

1 file changed

+60
-23
lines changed

1 file changed

+60
-23
lines changed

src/CombineCodegenImpl.cxx

Lines changed: 60 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,27 @@ void RooFit::Experimental::codegenImpl(FastVerticalInterpHistPdf2& arg, CodegenC
7878
nominalVec[i] = cacheNominal.GetBinContent(i);
7979
}
8080

81-
// The bin index part
82-
// We also have to assert that x is uniformely binned!
83-
if (!dynamic_cast<RooUniformBinning const*>(&xVar.getBinning())) {
84-
throw std::runtime_error("We only support uniform binning!");
81+
// The bin index part - handle both uniform and non-uniform binning
82+
const RooAbsBinning& binning = xVar.getBinning();
83+
std::string binIdx;
84+
85+
if (dynamic_cast<RooUniformBinning const*>(&binning)) {
86+
// UNIFORM BINNING - fast path using arithmetic
87+
double xLow = xVar.getMin();
88+
double xHigh = xVar.getMax();
89+
binIdx = ctx.buildCall("RooFit::Detail::MathFuncs::uniformBinNumber", xLow, xHigh, xVar, numBins, 1.);
90+
} else {
91+
// NON-UNIFORM BINNING - use binary search
92+
// Extract bin edges from binning object
93+
std::vector<double> binEdges(numBins + 1);
94+
for (int i = 0; i < numBins; ++i) {
95+
binEdges[i] = binning.binLow(i);
96+
}
97+
binEdges[numBins] = binning.binHigh(numBins - 1);
98+
99+
// Pass vector to ctx
100+
binIdx = ctx.buildCall("RooFit::Detail::MathFuncs::rawBinNumber", xVar, binEdges, numBins + 1);
85101
}
86-
double xLow = xVar.getMin();
87-
double xHigh = xVar.getMax();
88-
std::string binIdx = ctx.buildCall("RooFit::Detail::MathFuncs::uniformBinNumber", xLow, xHigh, xVar, numBins, 1.);
89102

90103
std::string arrName = ctx.getTmpVarName();
91104

@@ -119,13 +132,9 @@ void RooFit::Experimental::codegenImpl(FastVerticalInterpHistPdf2D2& arg, Codege
119132
RooRealVar const& xVar = arg.x();
120133
RooRealVar const& yVar = arg.y();
121134

122-
// We also have to assert that x and y are uniformely binned!
123-
if (!dynamic_cast<RooUniformBinning const*>(&xVar.getBinning())) {
124-
throw std::runtime_error("We only support uniform binning!");
125-
}
126-
if (!dynamic_cast<RooUniformBinning const*>(&yVar.getBinning())) {
127-
throw std::runtime_error("We only support uniform binning!");
128-
}
135+
// Handle both uniform and non-uniform binning for X and Y
136+
const RooAbsBinning& binningX = xVar.getBinning();
137+
const RooAbsBinning& binningY = yVar.getBinning();
129138

130139
auto const& cacheNominal = arg.cacheNominal();
131140

@@ -159,15 +168,43 @@ void RooFit::Experimental::codegenImpl(FastVerticalInterpHistPdf2D2& arg, Codege
159168
nominalVec[i] = cacheNominal.GetBinContent(i);
160169
}
161170

162-
// The bin index part
163-
double xLow = xVar.getMin();
164-
double xHigh = xVar.getMax();
165-
std::string binIdxX =
166-
ctx.buildCall("RooFit::Detail::MathFuncs::uniformBinNumber", xLow, xHigh, arg.x(), numBinsX, 1.);
167-
double yLow = yVar.getMin();
168-
double yHigh = yVar.getMax();
169-
std::string binIdxY =
170-
ctx.buildCall("RooFit::Detail::MathFuncs::uniformBinNumber", yLow, yHigh, arg.y(), numBinsY, 1.);
171+
// The bin index part - handle both uniform and non-uniform binning for X
172+
std::string binIdxX;
173+
if (dynamic_cast<RooUniformBinning const*>(&binningX)) {
174+
// UNIFORM BINNING for X - fast path
175+
double xLow = xVar.getMin();
176+
double xHigh = xVar.getMax();
177+
binIdxX = ctx.buildCall("RooFit::Detail::MathFuncs::uniformBinNumber", xLow, xHigh, arg.x(), numBinsX, 1.);
178+
} else {
179+
// NON-UNIFORM BINNING for X - use binary search
180+
std::vector<double> binEdgesX(numBinsX + 1);
181+
for (int i = 0; i < numBinsX; ++i) {
182+
binEdgesX[i] = binningX.binLow(i);
183+
}
184+
binEdgesX[numBinsX] = binningX.binHigh(numBinsX - 1);
185+
186+
// Pass vector to ctx
187+
binIdxX = ctx.buildCall("RooFit::Detail::MathFuncs::rawBinNumber", arg.x(), binEdgesX, numBinsX + 1);
188+
}
189+
190+
// Handle both uniform and non-uniform binning for Y
191+
std::string binIdxY;
192+
if (dynamic_cast<RooUniformBinning const*>(&binningY)) {
193+
// UNIFORM BINNING for Y - fast path
194+
double yLow = yVar.getMin();
195+
double yHigh = yVar.getMax();
196+
binIdxY = ctx.buildCall("RooFit::Detail::MathFuncs::uniformBinNumber", yLow, yHigh, arg.y(), numBinsY, 1.);
197+
} else {
198+
// NON-UNIFORM BINNING for Y - use binary search
199+
std::vector<double> binEdgesY(numBinsY + 1);
200+
for (int i = 0; i < numBinsY; ++i) {
201+
binEdgesY[i] = binningY.binLow(i);
202+
}
203+
binEdgesY[numBinsY] = binningY.binHigh(numBinsY - 1);
204+
205+
// Pass vector to ctx
206+
binIdxY = ctx.buildCall("RooFit::Detail::MathFuncs::rawBinNumber", arg.y(), binEdgesY, numBinsY + 1);
207+
}
171208

172209
std::stringstream binIdx;
173210
binIdx << "(" << binIdxY << " + " << yVar.numBins() << " * " << binIdxX << ")";

0 commit comments

Comments
 (0)