@@ -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