|
47 | 47 | #include <string>
|
48 | 48 |
|
49 | 49 | #include <variant>
|
50 |
| -#include <set> |
51 | 50 |
|
52 | 51 | class TF1;
|
53 | 52 | class TH1D;
|
@@ -120,7 +119,7 @@ namespace ROOT::Internal {
|
120 | 119 | template <typename T>
|
121 | 120 | auto Slice(const T &histo, std::vector<Int_t>& args)
|
122 | 121 | {
|
123 |
| - histo.Slice(args); |
| 122 | + return histo.Slice(args); |
124 | 123 | }
|
125 | 124 |
|
126 | 125 | template <typename T>
|
@@ -224,92 +223,7 @@ class TH1 : public TNamed, public TAttLine, public TAttFill, public TAttMarker {
|
224 | 223 | TH1(const TH1&) = delete;
|
225 | 224 | TH1& operator=(const TH1&) = delete;
|
226 | 225 |
|
227 |
| - TH1* Slice(std::vector<Int_t>& args) const{ |
228 |
| - auto ndim = args.size() / 2; |
229 |
| - if (ndim != static_cast<size_t>(fDimension)) { |
230 |
| - throw std::invalid_argument("Number of dimensions in slice does not match histogram dimension."); |
231 |
| - } |
232 |
| - |
233 |
| - std::vector<Int_t> nBins(ndim); |
234 |
| - std::vector<Double_t> binLowEdge(ndim), binUpEdge(ndim); |
235 |
| - std::vector<Int_t> shiftedBins(ndim*2); |
236 |
| - |
237 |
| - // Configure all axes |
238 |
| - for (size_t i = 0; i < ndim; ++i) { |
239 |
| - const auto &axis = (i == 0) ? fXaxis : (i == 1) ? fYaxis : fZaxis; |
240 |
| - Int_t binLow = std::max(1, args[i * 2]); |
241 |
| - Int_t binUp = std::min(axis.GetNbins() + 1, args[i * 2 + 1]); |
242 |
| - args[i * 2] = binLow; |
243 |
| - args[i * 2 + 1] = binUp; |
244 |
| - nBins[i] = binUp - binLow; |
245 |
| - binLowEdge[i] = axis.GetBinLowEdge(binLow); |
246 |
| - binUpEdge[i] = axis.GetBinLowEdge(binUp); |
247 |
| - shiftedBins[i * 2] = 1; |
248 |
| - shiftedBins[i * 2 + 1] = nBins[i] + 1; |
249 |
| - } |
250 |
| - |
251 |
| - // Create a new histogram of the same type as this |
252 |
| - std::unique_ptr<TH1> hSlice(static_cast<TH1*>(IsA()->GetNew()(nullptr))); |
253 |
| - |
254 |
| - if (!hSlice) { |
255 |
| - throw std::runtime_error("Failed to create a new histogram instance."); |
256 |
| - } |
257 |
| - |
258 |
| - // Configure name, title and bins |
259 |
| - hSlice->SetNameTitle(Form("%s_slice", GetName()), GetTitle()); |
260 |
| - |
261 |
| - if (ndim == 1) { |
262 |
| - hSlice->SetBins(nBins[0], binLowEdge[0], binUpEdge[0]); |
263 |
| - } else if (ndim == 2) { |
264 |
| - hSlice->SetBins(nBins[0], binLowEdge[0], binUpEdge[0], |
265 |
| - nBins[1], binLowEdge[1], binUpEdge[1]); |
266 |
| - } else if (ndim == 3) { |
267 |
| - hSlice->SetBins(nBins[0], binLowEdge[0], binUpEdge[0], |
268 |
| - nBins[1], binLowEdge[1], binUpEdge[1], |
269 |
| - nBins[2], binLowEdge[2], binUpEdge[2]); |
270 |
| - } |
271 |
| - |
272 |
| - std::vector<Double_t> sliceContents; |
273 |
| - std::unordered_set<Int_t> processedBins; |
274 |
| - Double_t underflowContent = 0.0, overflowContent = 0.0; |
275 |
| - |
276 |
| - auto processBinContent = [&](Int_t x, Int_t y, Int_t z) { |
277 |
| - const Int_t globalBin = GetBin(x, y, z); |
278 |
| - if (!processedBins.insert(globalBin).second) return; |
279 |
| - |
280 |
| - const auto content = RetrieveBinContent(globalBin); |
281 |
| - const bool isUnderflow = (x < args[0] || (ndim > 1 && y < args[2]) || (ndim > 2 && z < args[4])); |
282 |
| - const bool isOverflow = (x >= args[1] || (ndim > 1 && y >= args[3]) || (ndim > 2 && z >= args[5])); |
283 |
| - |
284 |
| - if (isUnderflow) { |
285 |
| - underflowContent += content; |
286 |
| - } else if (isOverflow) { |
287 |
| - overflowContent += content; |
288 |
| - } else { |
289 |
| - sliceContents.push_back(content); |
290 |
| - } |
291 |
| - }; |
292 |
| - |
293 |
| - for (Int_t x = 0; x <= fXaxis.GetNbins() + 1; ++x) { |
294 |
| - for (Int_t y = 0; y <= (ndim > 1 ? fYaxis.GetNbins() + 1 : 1); ++y) { |
295 |
| - for (Int_t z = 0; z <= (ndim > 2 ? fZaxis.GetNbins() + 1 : 1); ++z) { |
296 |
| - processBinContent(x, y, z); |
297 |
| - } |
298 |
| - } |
299 |
| - } |
300 |
| - |
301 |
| - // Set the contents of the slice histogram |
302 |
| - ROOT::Internal::SetSliceContent(*hSlice, sliceContents, shiftedBins); |
303 |
| - |
304 |
| - // Set the flow bins |
305 |
| - hSlice->SetBinContent(0, underflowContent); |
306 |
| - auto overflowBin = (ndim == 1) ? hSlice->GetBin(fXaxis.GetNbins() + 1) |
307 |
| - : (ndim == 2) ? hSlice->GetBin(fXaxis.GetNbins() + 1, fYaxis.GetNbins() + 1) |
308 |
| - : hSlice->GetBin(fXaxis.GetNbins() + 1, fYaxis.GetNbins() + 1, fZaxis.GetNbins() + 1); |
309 |
| - hSlice->SetBinContent(overflowBin, overflowContent); |
310 |
| - |
311 |
| - return hSlice.release(); |
312 |
| - } |
| 226 | + TH1* Slice(std::vector<Int_t>& args) const; |
313 | 227 |
|
314 | 228 | template <typename T>
|
315 | 229 | friend auto ROOT::Internal::Slice(const T &histo, std::vector<Int_t>& args);
|
|
0 commit comments