Skip to content

Commit cdbaaae

Browse files
committed
move the definition of TH1::Slice out of the header
1 parent ab53982 commit cdbaaae

File tree

2 files changed

+93
-88
lines changed

2 files changed

+93
-88
lines changed

hist/hist/inc/TH1.h

+2-88
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
#include <string>
4848

4949
#include <variant>
50-
#include <set>
5150

5251
class TF1;
5352
class TH1D;
@@ -120,7 +119,7 @@ namespace ROOT::Internal {
120119
template <typename T>
121120
auto Slice(const T &histo, std::vector<Int_t>& args)
122121
{
123-
histo.Slice(args);
122+
return histo.Slice(args);
124123
}
125124

126125
template <typename T>
@@ -224,92 +223,7 @@ class TH1 : public TNamed, public TAttLine, public TAttFill, public TAttMarker {
224223
TH1(const TH1&) = delete;
225224
TH1& operator=(const TH1&) = delete;
226225

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;
313227

314228
template <typename T>
315229
friend auto ROOT::Internal::Slice(const T &histo, std::vector<Int_t>& args);

hist/hist/src/TH1.cxx

+91
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <fstream>
2323
#include <limits>
2424
#include <iomanip>
25+
#include <unordered_set>
2526

2627
#include "TROOT.h"
2728
#include "TBuffer.h"
@@ -9430,6 +9431,96 @@ TH1* TH1::TransformHisto(TVirtualFFT *fft, TH1* h_output, Option_t *option)
94309431
return hout;
94319432
}
94329433

9434+
////////////////////////////////////////////////////////////////////////////////
9435+
/// TODO docstring
9436+
9437+
TH1* TH1::Slice(std::vector<Int_t>& args) const{
9438+
auto ndim = args.size() / 2;
9439+
if (ndim != static_cast<size_t>(fDimension)) {
9440+
throw std::invalid_argument("Number of dimensions in slice does not match histogram dimension.");
9441+
}
9442+
9443+
std::vector<Int_t> nBins(ndim);
9444+
std::vector<Double_t> binLowEdge(ndim), binUpEdge(ndim);
9445+
std::vector<Int_t> shiftedBins(ndim*2);
9446+
9447+
// Configure all axes
9448+
for (size_t i = 0; i < ndim; ++i) {
9449+
const auto &axis = (i == 0) ? fXaxis : (i == 1) ? fYaxis : fZaxis;
9450+
Int_t binLow = std::max(1, args[i * 2]);
9451+
Int_t binUp = std::min(axis.GetNbins() + 1, args[i * 2 + 1]);
9452+
args[i * 2] = binLow;
9453+
args[i * 2 + 1] = binUp;
9454+
nBins[i] = binUp - binLow;
9455+
binLowEdge[i] = axis.GetBinLowEdge(binLow);
9456+
binUpEdge[i] = axis.GetBinLowEdge(binUp);
9457+
shiftedBins[i * 2] = 1;
9458+
shiftedBins[i * 2 + 1] = nBins[i] + 1;
9459+
}
9460+
9461+
// Create a new histogram of the same type as this
9462+
std::unique_ptr<TH1> hSlice(static_cast<TH1*>(IsA()->GetNew()(nullptr)));
9463+
9464+
if (!hSlice) {
9465+
throw std::runtime_error("Failed to create a new histogram instance.");
9466+
}
9467+
9468+
// Configure name, title and bins
9469+
hSlice->SetNameTitle(Form("%s_slice", GetName()), GetTitle());
9470+
9471+
if (ndim == 1) {
9472+
hSlice->SetBins(nBins[0], binLowEdge[0], binUpEdge[0]);
9473+
} else if (ndim == 2) {
9474+
hSlice->SetBins(nBins[0], binLowEdge[0], binUpEdge[0],
9475+
nBins[1], binLowEdge[1], binUpEdge[1]);
9476+
} else if (ndim == 3) {
9477+
hSlice->SetBins(nBins[0], binLowEdge[0], binUpEdge[0],
9478+
nBins[1], binLowEdge[1], binUpEdge[1],
9479+
nBins[2], binLowEdge[2], binUpEdge[2]);
9480+
}
9481+
9482+
std::vector<Double_t> sliceContents;
9483+
std::unordered_set<Int_t> processedBins;
9484+
Double_t underflowContent = 0.0, overflowContent = 0.0;
9485+
9486+
auto processBinContent = [&](Int_t x, Int_t y, Int_t z) {
9487+
const Int_t globalBin = GetBin(x, y, z);
9488+
if (!processedBins.insert(globalBin).second) return;
9489+
9490+
const auto content = RetrieveBinContent(globalBin);
9491+
const bool isUnderflow = (x < args[0] || (ndim > 1 && y < args[2]) || (ndim > 2 && z < args[4]));
9492+
const bool isOverflow = (x >= args[1] || (ndim > 1 && y >= args[3]) || (ndim > 2 && z >= args[5]));
9493+
9494+
if (isUnderflow) {
9495+
underflowContent += content;
9496+
} else if (isOverflow) {
9497+
overflowContent += content;
9498+
} else {
9499+
sliceContents.push_back(content);
9500+
}
9501+
};
9502+
9503+
for (Int_t x = 0; x <= fXaxis.GetNbins() + 1; ++x) {
9504+
for (Int_t y = 0; y <= (ndim > 1 ? fYaxis.GetNbins() + 1 : 1); ++y) {
9505+
for (Int_t z = 0; z <= (ndim > 2 ? fZaxis.GetNbins() + 1 : 1); ++z) {
9506+
processBinContent(x, y, z);
9507+
}
9508+
}
9509+
}
9510+
9511+
// Set the contents of the slice histogram
9512+
ROOT::Internal::SetSliceContent(*hSlice, sliceContents, shiftedBins);
9513+
9514+
// Set the flow bins
9515+
hSlice->SetBinContent(0, underflowContent);
9516+
auto overflowBin = (ndim == 1) ? hSlice->GetBin(fXaxis.GetNbins() + 1)
9517+
: (ndim == 2) ? hSlice->GetBin(fXaxis.GetNbins() + 1, fYaxis.GetNbins() + 1)
9518+
: hSlice->GetBin(fXaxis.GetNbins() + 1, fYaxis.GetNbins() + 1, fZaxis.GetNbins() + 1);
9519+
hSlice->SetBinContent(overflowBin, overflowContent);
9520+
9521+
return hSlice.release();
9522+
}
9523+
94339524
////////////////////////////////////////////////////////////////////////////////
94349525
/// Print value overload
94359526

0 commit comments

Comments
 (0)