23#include "TCollection.h"
73template <
class TemplateArray>
81 LOGF(warning,
"StepTHn: Requesting more than 250M bins (%lld). This will need extensive memory.",
mNBins);
83 mPrototype =
new THnSparseT<TemplateArray>(Form(
"%s_sparse",
name), title, nAxes, nBins, xmin, xmax);
86template <
class TemplateArray>
88 Int_t* nBins, std::vector<Double_t> binEdges[],
const char** axisTitles) :
StepTHn(
name, title, nSteps, nAxes)
95 LOGF(warning,
"StepTHn: Requesting more than 250M bins (%lld). This will need extensive memory.",
mNBins);
97 mPrototype =
new THnSparseT<TemplateArray>(Form(
"%s_sparse",
name), title, nAxes, nBins);
100 if (nBins[
i] + 1 == binEdges[
i].
size()) {
102 }
else if (binEdges[
i].
size() == 2) {
103 mPrototype->GetAxis(
i)->Set(nBins[
i], binEdges[
i][0], binEdges[
i][1]);
105 LOGF(fatal,
"Invalid binning information for axis %d with %d bins and %d entries for bin edges",
i, nBins[
i], binEdges[
i].
size());
107 LOGF(
debug,
"Histogram %s Axis %d created with %d bins and %d edges",
name,
i, nBins[
i], binEdges[
i].
size());
128 mValues(new TArray*[
c.mNSteps]),
129 mSumw2(new TArray*[
c.mNSteps]),
132 mNbinsCache(nullptr),
228template <
class TemplateArray>
238 if (list->IsEmpty()) {
242 TIterator* iter = list->MakeIterator();
246 while ((obj = iter->Next())) {
249 if (
entry ==
nullptr) {
253 for (Int_t
i = 0;
i < mNSteps;
i++) {
256 mValues[
i] = createArray();
259 auto source =
dynamic_cast<TemplateArray*
>(
entry->mValues[
i])->GetArray();
260 auto target =
dynamic_cast<TemplateArray*
>(mValues[
i])->GetArray();
261 for (Long64_t l = 0; l < mNBins; l++) {
268 mSumw2[
i] = createArray();
271 auto source =
dynamic_cast<TemplateArray*
>(
entry->mSumw2[
i])->GetArray();
272 auto target =
dynamic_cast<TemplateArray*
>(mSumw2[
i])->GetArray();
273 for (Long64_t l = 0; l < mNBins; l++) {
294 bin += binIdx[
i] - 1;
305 LOGF(fatal,
"Histogram request for step %d which is empty.", step);
322 TArray* sourceSumw2 =
source;
324 sourceSumw2 =
mSumw2[step];
328 mTarget[step] = THnSparse::CreateSparse(Form(
"%s_%d", GetName(), step), Form(
"%s_%d", GetTitle(), step),
mPrototype);
330 mTarget[step] = THn::CreateHn(Form(
"%s_%d", GetName(), step), Form(
"%s_%d", GetTitle(), step),
mPrototype);
338 Int_t* binIdx =
new Int_t[
mNVars];
339 Int_t* nBins =
new Int_t[
mNVars];
342 nBins[
j] =
target->GetAxis(
j)->GetNbins();
358 target->SetBinError(binIdx, TMath::Sqrt(sourceSumw2->GetAt(globalBin)));
366 if (binIdx[
j] > nBins[
j]) {
372 if (binIdx[0] > nBins[0]) {
389 LOGF(fatal,
"Selected step for filling is not in range of StepTHn.");
393 if (nParams ==
mNVars + 1) {
395 }
else if (nParams !=
mNVars) {
396 LOGF(fatal,
"Fill called with invalid number of parameters (%d vs %d)",
mNVars, nParams);
415 if (lut.edges && lut.xmax > lut.xmin) {
417 Double_t slotWidth = (lut.xmax - lut.xmin) /
kLookupSize;
418 lut.invSlotWidth = 1.0 / slotWidth;
420 Double_t
x = lut.xmin + (s + 0.5) * slotWidth;
426 lut.invSlotWidth = lut.xmax > lut.xmin ? lut.nBins / (lut.xmax - lut.xmin) : 0;
450 Double_t
x = positionAndWeight[
i];
459 tmpBin = 1 +
static_cast<Int_t
>(std::floor(rawBin));
460 if (tmpBin >= 1 && tmpBin <= lut.nBins) {
464 Double_t binWidth = (lut.xmax - lut.xmin) / lut.nBins;
465 Double_t upperEdge = lut.xmin + tmpBin * binWidth;
466 if (
x >= upperEdge && tmpBin < lut.nBins) {
472 }
else if (tmpBin > lut.nBins) {
473 tmpBin = lut.nBins + 1;
477 Int_t slot =
static_cast<Int_t
>((
x - lut.xmin) * lut.invSlotWidth);
479 tmpBin = (slot < 0) ? 0 : lut.nBins + 1;
481 tmpBin = lut.table[slot];
484 while (tmpBin > 1 &&
x < lut.edges[tmpBin - 1]) {
488 while (tmpBin < lut.nBins && x >= lut.edges[tmpBin]) {
templateClassImp(StepTHnT)
Long64_t Merge(TCollection *list) override
Double_t * mLastVars
cache Nbins per axis
Int_t * mLastBins
caching of last used bins (in many loops some vars are the same for a while)
void Fill(int iStep, const Ts &... valuesAndWeight)
TAxis ** mAxisCache
target histogram
Long64_t getGlobalBinIndex(const Int_t *binIdx)
StepTHn & operator=(const StepTHn &corr)
virtual TArray * createArray(const TArray *src=nullptr) const =0
Int_t * mNbinsCache
cache axis pointers (about 50% of the time in Fill is spent in GetAxis otherwise)
virtual void updateBin(int iStep, Long64_t bin, double weight)=0
void createTarget(Int_t step, Bool_t sparse)
THnSparse * mPrototype
per-axis lookup tables
void Copy(TObject &c) const override
static constexpr Int_t kLookupSize
caching of last used bins (in many loops some vars are the same for a while)
GLuint const GLchar * name
GLuint GLuint GLfloat weight
GLsizei GLsizei GLchar * source
GLsizei const GLfloat * value