ndmspc v1.2.0-0.1.rc7
Loading...
Searching...
No Matches
NBinning.cxx
1#include <string>
2#include <vector>
3#include "TAxis.h"
4#include <TAttAxis.h>
5#include <TObjArray.h>
6#include "NBinningDef.h"
7#include "NBinningPoint.h"
8#include "NDimensionalExecutor.h"
9#include "NUtils.h"
10#include "NLogger.h"
11
12#include "NBinning.h"
13
15ClassImp(Ndmspc::NBinning);
17
18namespace Ndmspc {
19NBinning::NBinning() : TObject()
20{
24}
25NBinning::NBinning(std::vector<TAxis *> axes) : TObject(), fAxes(axes)
26{
30
31 Initialize();
32}
33NBinning::NBinning(TObjArray * axes) : TObject()
34{
38
39 if (axes == nullptr) {
40 NLogError("NBinning(TObjArray * axes) : axes is nullptr");
41 return;
42 }
43
44 for (int i = 0; i < axes->GetEntriesFast(); i++) {
45 TAxis * axis = dynamic_cast<TAxis *>(axes->At(i));
46 if (axis) {
47 fAxes.push_back((TAxis *)axis->Clone());
48 }
49 else {
50 NLogError("NBinning: Axis %d is not a TAxis", i);
51 }
52 }
53
54 Initialize();
55}
57{
61
62 // Cleanup fDefinitions
63 for (auto & def : fDefinitions) {
64 delete def.second;
65 }
66 fDefinitions.clear();
67
68 // Cleanup fAxes
69 for (auto & axis : fAxes) {
70 if (axis) {
71 delete axis; // Delete the axis if it was created by this class
72 }
73 }
74
75 delete fMap;
76 delete fContent;
77}
79{
83 fMap->Reset();
84 fContent->Reset();
85 if (fPoint != nullptr) {
86 fPoint->Reset();
87 }
88}
89
91{
95
96 if (fAxes.size() == 0) {
97 NLogError("No axes provided");
98 return;
99 }
100
101 int dim = fAxes.size();
102 // Calculate maximyn=m of nbins
103 int nbinsMax = 0;
104 int nContentDims = 0;
105 Binning binningType;
106 for (int i = 0; i < dim; i++) {
107 int nbins = fAxes[i]->GetNbins();
108 if (nbins > nbinsMax) {
109 nbinsMax = nbins;
110 }
111 // NLogDebug("Axis %d: %s nbins=%d", i, fAxes[i]->GetName(), nbins);
112 // if (nbins == 1 || axes[i]->IsAlphanumeric()) {
113 TString axisname(fAxes[i]->GetName());
114 bool isUser = axisname.Contains("/U");
115 if (isUser) {
116 axisname.ReplaceAll("/U", "");
117 fAxes[i]->SetName(axisname.Data());
118 }
119
120 if (isUser) {
121 binningType = Binning::kUser;
122 nContentDims++;
123 }
124 else if (fAxes[i]->IsAlphanumeric()) {
125 // TODO: Optimized beiing for alphanumeric axis (maybe no need to fix)
126 // binningType = Binning::kSingle;
127 // nContentDims++;
128 binningType = Binning::kMultiple;
129 nContentDims += 3;
130 }
131 else {
132 binningType = Binning::kMultiple;
133 nContentDims += 3;
134 }
135 fBinningTypes.push_back(binningType);
136 fAxisTypes.push_back(AxisType::kFixed);
137 }
138 int dimBinning = 4;
139 Int_t * nbinsBinning = new Int_t[dimBinning];
140 Double_t * xminBinning = new Double_t[dimBinning];
141 Double_t * xmaxBinning = new Double_t[dimBinning];
142 // set first item nbinsBinning to dim min to zero and max to dim
143
144 nbinsBinning[0] = dim;
145 xminBinning[0] = 0;
146 xmaxBinning[0] = dim;
147 for (int i = 1; i < dimBinning; i++) {
148 nbinsBinning[i] = nbinsMax;
149 xminBinning[i] = 0;
150 xmaxBinning[i] = nbinsMax;
151 }
152
153 if (fMap) {
154 delete fMap;
155 }
156 fMap = new THnSparseI("ngntBinningMap", "NGnTree binning map", dimBinning, nbinsBinning, xminBinning, xmaxBinning);
157 if (fMap == nullptr) {
158 NLogError("Cannot create binnings !!!");
159 return;
160 }
161 fMap->GetAxis(0)->SetNameTitle("dim", "dimension");
162 fMap->GetAxis(1)->SetNameTitle("rebin", "rebins");
163 fMap->GetAxis(2)->SetNameTitle("start", "rebins start");
164 fMap->GetAxis(3)->SetNameTitle("bin", "bin id");
165
166 for (int i = 0; i < dim; i++) {
167 fMap->GetAxis(0)->SetBinLabel(i + 1, fAxes[i]->GetName());
168 }
169
170 int dimBinningContent = nContentDims;
171 Int_t * nbinsBinningContent = new Int_t[dimBinningContent];
172 Double_t * xminBinningContent = new Double_t[dimBinningContent];
173 Double_t * xmaxBinningContent = new Double_t[dimBinningContent];
174 int iContentDim = 0;
175 for (int i = 0; i < dim; i++) {
177 // NLogDebug("Binning %d: %d", i, axes[idim]->GetNbins());
178 nbinsBinningContent[iContentDim] = fAxes[i]->GetNbins();
179 xminBinningContent[iContentDim] = 0;
180 xmaxBinningContent[iContentDim] = fAxes[i]->GetNbins();
181 iContentDim++;
182 NLogTrace("[S] Binning %d: %d", i, fAxes[i]->GetNbins());
183 }
184 else if (fBinningTypes[i] == Binning::kMultiple) {
185 for (int j = 0; j < 3; j++) {
186 nbinsBinningContent[iContentDim + j] = fAxes[i]->GetNbins();
187 xminBinningContent[iContentDim + j] = 0;
188 xmaxBinningContent[iContentDim + j] = fAxes[i]->GetNbins();
189 }
190 iContentDim += 3;
191 NLogTrace("[M] Binning %d: %d", i, fAxes[i]->GetNbins());
192 }
193 else if (fBinningTypes[i] == Binning::kUser) {
194 // NLogDebug("Binning %d: %d", i, axes[idim]->GetNbins());
195 nbinsBinningContent[iContentDim] = fAxes[i]->GetNbins();
196 xminBinningContent[iContentDim] = 0;
197 xmaxBinningContent[iContentDim] = fAxes[i]->GetNbins();
198 iContentDim++;
199 NLogTrace("[U] Binning %d: %d", i, fAxes[i]->GetNbins());
200 }
201 else {
202 NLogError("Invalid binning type %d", fBinningTypes[i]);
203 return;
204 }
205 }
206 fContent = new THnSparseI("ngntBinningContent", "NGnTree binning content", dimBinningContent, nbinsBinningContent,
207 xminBinningContent, xmaxBinningContent);
208
209 int iContentAxis = 0;
210 std::vector<std::string> types = {"rebin", "start", "bin"};
211 for (int i = 0; i < dim; i++) {
212 std::string name = fAxes[i]->GetName();
213 std::string title = fAxes[i]->GetName();
214 // NLogTrace("Binning %d: %d %d", i, axes[i]->GetNbins(), fBinningTypes[i]);
216 fContent->GetAxis(iContentAxis)->SetNameTitle(name.c_str(), title.c_str());
217 iContentAxis++;
218 }
219 else if (fBinningTypes[i] == Binning::kMultiple) {
220 for (int j = 0; j < 3; j++) {
221 int imod = j % 3;
222 std::string n = name + "_" + types[imod];
223 std::string t = title + " (" + types[imod] + ")";
224 fContent->GetAxis(iContentAxis)->SetNameTitle(n.c_str(), t.c_str());
225 iContentAxis++;
226 }
227 // NLogDebug("Binning %d: %d", i, axes[idim]->GetNbins());
228 }
229 else if (fBinningTypes[i] == Binning::kUser) {
230 fContent->GetAxis(iContentAxis)->SetNameTitle(name.c_str(), title.c_str());
231 iContentAxis++;
232 }
233 }
234 for (int i = 0; i < fContent->GetNdimensions(); i++) {
235 NLogTrace("Axis[fContent] %d: %s nbins=%d", i, fContent->GetAxis(i)->GetName(), fContent->GetAxis(i)->GetNbins());
236 }
237
238 fPoint = new NBinningPoint(this);
239
240 delete[] nbinsBinning;
241 delete[] xminBinning;
242 delete[] xmaxBinning;
243}
244
245void NBinning::Print(Option_t * option) const
246{
250
251 if (fMap == nullptr) {
252 NLogError("THnSparse fMap is null");
253 return;
254 }
255
256 TString opt(option);
257 opt.ToLower();
258
259 NLogInfo("NBinning base axes:");
260 for (size_t i = 0; i < fAxes.size(); i++) {
261 NLogInfo(" Axis %d: name='%s' title='%s' nbins=%d min=%.3f max=%.3f", i, fAxes[i]->GetName(), fAxes[i]->GetTitle(),
262 fAxes[i]->GetNbins(), fAxes[i]->GetXmin(), fAxes[i]->GetXmax());
263 }
264
265 if (opt.Contains("A")) {
266 NLogInfo("NBinning map name='%s' title='%s'", fMap->GetName(), fMap->GetTitle());
267 NLogInfo(" dimensions: %d", fMap->GetNdimensions());
268 // loop over all axes and print name title
269 for (int i = 0; i < fMap->GetNdimensions(); i++) {
270 NLogInfo(" [%d] name='%s' title='%s' nbins=%d min=%.3f max=%.3f", i, fMap->GetAxis(i)->GetName(),
271 fMap->GetAxis(i)->GetTitle(), fMap->GetAxis(i)->GetNbins(), fMap->GetAxis(i)->GetXmin(),
272 fMap->GetAxis(i)->GetXmax());
273 }
274 NLogInfo(" filled bins = %lld", fMap->GetNbins());
275 NLogInfo("NBinning content name='%s' title='%s'", fContent->GetName(), fContent->GetTitle());
276 NLogInfo(" dimensions: %d", fContent->GetNdimensions());
277 // loop over all axes and print name title
278 for (int i = 0; i < fContent->GetNdimensions(); i++) {
279 NLogInfo(" [%d] name='%s' title='%s' nbins=%d min=%.3f max=%.3f", i, fContent->GetAxis(i)->GetName(),
280 fContent->GetAxis(i)->GetTitle(), fContent->GetAxis(i)->GetNbins(), fContent->GetAxis(i)->GetXmin(),
281 fContent->GetAxis(i)->GetXmax());
282 }
283 }
284 NLogInfo("NBinning content:");
285 NLogInfo(" filled bins = %lld", fContent->GetNbins());
286 // print list of definitions names from fDefinitions
287 NLogInfo("NBinning definitions:");
288 for (const auto & kv : fDefinitions) {
289 if (kv.first == fCurrentDefinitionName) {
290 NLogInfo(" '%s' (current)", kv.first.c_str());
291 }
292 else {
293 NLogInfo(" '%s'", kv.first.c_str());
294 }
295 }
296
297 if (option && opt.Contains("all")) {
298 NLogInfo("NBinning content:");
299 PrintContent(option);
300 }
301
302 // // loop over definition and print
303 // for (const auto & kv : fDefinition) {
304 // NLogInfo("Binning '%s':", kv.first.c_str());
305 // for (const auto & v : kv.second) {
306 // NLogInfo(" %s", NUtils::GetCoordsString(v, -1).c_str());
307 // }
308 // }
309
310 // fMap->Print(option);
311
312 // // Using executor print all bins
313 // NDimensionalExecutor executor(fMap, true);
314 // // NDimensionalExecutor executor(fMap, false);
315 // auto binning_task = [this, &all_bins](const std::vector<int> & coords) {
316 // fMap->Print();
317 // NUtils::PrintPointSafe(coords, -1);
318 // };
319 //
320 // executor.Execute(binning_task);
321
322 // size_t num_threads_to_use = 0;
323 // // set num_threads_to_use to the number of available threads
324 // if (num_threads_to_use < 1) num_threads_to_use = std::thread::hardware_concurrency();
325 // NLogInfo("Using %zu threads ...", num_threads_to_use);
326 // std::vector<NThreadData> thread_data_vector(num_threads_to_use);
327 // for (size_t i = 0; i < thread_data_vector.size(); ++i) {
328 // thread_data_vector[i].SetAssignedIndex(i);
329 // }
330 //
331 // // 2. Define the lambda (type in signature updated)
332 // auto parallel_task = [](const std::vector<int> & coords, NThreadData & thread_obj) {
333 // NUtils::PrintPointSafe(coords, thread_obj.GetAssignedIndex());
334 // thread_obj.Process(coords);
335 // // thread_obj.Print();
336 // };
337 //
338 // // 3. Call ExecuteParallel (template argument updated)
339 // executor.ExecuteParallel<NThreadData>(parallel_task, thread_data_vector);
340}
341void NBinning::PrintContent(Option_t * option) const
342{
346
347 std::map<std::string, std::vector<int>> binningMap;
348
349 TString opt(option);
350 // loop over all selected bins via ROOT iterarot for THnSparse
351 THnSparse * cSparse = fContent;
352 Int_t * bins = new Int_t[cSparse->GetNdimensions()];
353 Long64_t linBin = 0;
354 std::unique_ptr<ROOT::Internal::THnBaseBinIter> iter{cSparse->CreateIter(true /*use axis range*/)};
355 while ((linBin = iter->Next()) >= 0) {
356 Double_t v = cSparse->GetBinContent(linBin, bins);
357 Long64_t idx = cSparse->GetBin(bins, false);
358 std::string binCoords = NUtils::GetCoordsString(NUtils::ArrayToVector(bins, cSparse->GetNdimensions()), -1);
359 NLogTrace("Bin %lld: %f %s idx=%lld content=%f", linBin, v, binCoords.c_str(), idx, v);
360
361 size_t iAxis = 0;
362 bool isValid = false;
363 // for (int i = 0; i < cSparse->GetNdimensions(); i += 3) {
364 int index = 0;
365 for (iAxis = 0; iAxis < fAxes.size(); iAxis++) {
366 int min;
367 int max;
368 // Print type of binning
369 // NLogTrace("Axis %d: %s [%s]", iAxis, fAxes[iAxis]->GetName(),
370 // fBinningTypes[iAxis] == Binning::kSingle ? "S" : "M");
371 if (fBinningTypes[iAxis] == Binning::kSingle) {
372 isValid = NUtils::GetAxisRangeInBase(fAxes[iAxis], 1, 1, bins[index], min, max);
373 binCoords += TString::Format(" | (S%c) %s %d %d %d [%d,%d] [%d,%d]", GetAxisTypeChar(iAxis),
374 fAxes[iAxis]->GetName(), 1, 1, bins[index], min, max, 1, fAxes[iAxis]->GetNbins())
375 .Data();
376 binningMap[fAxes[iAxis]->GetName()] = {1, 1, bins[index]};
377 index++;
378 }
379 else if (fBinningTypes[iAxis] == Binning::kMultiple) {
380 isValid = NUtils::GetAxisRangeInBase(fAxes[iAxis], bins[index], bins[index + 1], bins[index + 2], min, max);
381 binCoords +=
382 TString::Format(" | (M%c) %s %d %d %d [%d,%d] [%d,%d]", GetAxisTypeChar(iAxis), fAxes[iAxis]->GetName(),
383 bins[index], bins[index + 1], bins[index + 2], min, max, 1, fAxes[iAxis]->GetNbins())
384 .Data();
385 binningMap[fAxes[iAxis]->GetName()] = {bins[index], bins[index + 1], bins[index + 2]};
386 index += 3;
387 }
388 else if (fBinningTypes[iAxis] == Binning::kUser) {
389 isValid = NUtils::GetAxisRangeInBase(fAxes[iAxis], fAxes[iAxis]->GetNbins(), 1, 1, min, max);
390 binCoords += TString::Format(" | (U) %s %d %d %d [%d,%d] [%d,%d]", fAxes[iAxis]->GetName(),
391 fAxes[iAxis]->GetNbins(), 1, 1, min, max, 1, fAxes[iAxis]->GetNbins())
392 .Data();
393 // binningMap[fAxes[iAxis]->GetName()] = {1, 1, bins[index]};
394 binningMap[fAxes[iAxis]->GetName()] = {fAxes[iAxis]->GetNbins(), 1, 1};
395 index++;
396 }
397 else {
398 NLogError("[NBinning::PrintContent] Unknown binning type [%d]", fBinningTypes[iAxis]);
399 continue;
400 }
401 if (!isValid) {
402 NLogError("Cannot get axis range for axis %d", iAxis);
403 continue;
404 }
405 }
406 if (!isValid) {
407 // NLogError("Cannot get axis range for axis %d", iAxis);
408 NLogError("Bin %lld: %s [not valid for axis=%s]", linBin, binCoords.c_str(), fAxes[iAxis]->GetName());
409 continue;
410 }
411 NLogDebug("Bin %lld: %s", linBin, binCoords.c_str());
412 }
413 delete[] bins;
414}
415
417{
421 Long64_t nBinsFilled = 0;
422
423 // fContent->Reset();
424
425 std::vector<int> mins(fMap->GetAxis(0)->GetNbins(), 1);
426 std::vector<int> maxs(fMap->GetAxis(0)->GetNbins(), 0);
427 std::vector<std::vector<std::vector<int>>> content(fMap->GetAxis(0)->GetNbins());
428
429 // loop over all selected bins via ROOT iterarot for THnSparse
430 THnSparse * cSparse = fMap;
431 Int_t * p = new Int_t[cSparse->GetNdimensions()];
432 Long64_t linBin = 0;
433 std::unique_ptr<ROOT::Internal::THnBaseBinIter> iter{cSparse->CreateIter(true /*use axis range*/)};
434 // Print number of filled bins
435 // NLogInfo("Filled bins = %lld", cSparse->GetNbins());
436 while ((linBin = iter->Next()) >= 0) {
437 Double_t v = cSparse->GetBinContent(linBin, p);
438 // continue;
439 int idx = p[0] - 1;
440 NLogTrace("NBinning::FillAll: Bin %lld: %d %d %d %d type=%d content=%f", linBin, p[0], p[1], p[2], p[3],
441 fBinningTypes[idx], v);
442 if (fBinningTypes[idx] == Binning::kSingle) {
443
444 content[idx].push_back({p[0], p[3]});
445 }
446 else if (fBinningTypes[idx] == Binning::kMultiple) {
447 // NLogDebug("Binning %d: %d", i, axes[idim]->GetNbins());
448 content[idx].push_back({p[0], p[1], p[2], p[3]});
449 }
450 else if (fBinningTypes[idx] == Binning::kUser) {
451 // TODO: Fix nbins for user binning (it should ok now)
452 content[idx].push_back({p[0], 1});
453 }
454 else {
455 NLogError("NBinning::FillAll: Unknown binning type %d", fBinningTypes[idx]);
456 continue;
457 }
458 maxs[idx] = maxs[idx] + 1;
459 }
460 delete[] p;
461
462 Long64_t nTotalBins = 1;
463 // loop over content vector and set axis types
464 for (size_t i = 0; i < content.size(); i++) {
465 if (content[i].size() == 0) {
466 NLogWarning("NBinning::FillAll: No content for binning %zu", i);
467 continue;
468 }
469
470 if (content[i].size() > 0) {
471 TAxis * axis = fAxes[i];
473 NLogTrace("NBinning::FillAll: Axis id=%d name=%s bins=%zu", i, axis->GetName(), content[i].size());
474 // check if i is persent in variable axes of def
475 bool found = false;
476 for (size_t j = 0; j < def->GetVariableAxes().size(); j++) {
477 if (def->GetVariableAxes()[j] == static_cast<int>(i)) {
478 NLogTrace("NBinning::FillAll: Axis id=%d name=%s already in variable axes of def", i, axis->GetName());
479 found = true;
480 break;
481 }
482 }
483 NLogTrace("NBinning::FillAll: Axis id=%d name=%s set to variable found=%d", i, axis->GetName(), found);
484 if (!found) def->AddVariableAxis(i);
485 }
486 nTotalBins *= content[i].size();
487 }
488
489 def->Print();
490 NLogDebug("NBinning::FillAll: Filling total of %lld bins ...", nTotalBins);
491
492 auto start_par = std::chrono::high_resolution_clock::now();
493 // Loop over all binning combinations
494 NDimensionalExecutor executor(mins, maxs);
495 auto binning_task = [&content, &nBinsFilled, &nTotalBins, start_par, def, this](const std::vector<int> & coords) {
496 std::vector<int> pointContentVector;
497 NLogTrace("Binning task: %s", NUtils::GetCoordsString(coords, -1).c_str());
498 for (size_t i = 0; i < coords.size(); i++) {
499 NLogTrace(" Binning %zu: coord=%d content size=%zu", i, coords[i], content[i].size());
500 if (content[i][coords[i] - 1].size() == 2) {
501 pointContentVector.push_back(content[i][coords[i] - 1][1]);
502 }
503 else {
504 pointContentVector.push_back(content[i][coords[i] - 1][1]);
505 pointContentVector.push_back(content[i][coords[i] - 1][2]);
506 pointContentVector.push_back(content[i][coords[i] - 1][3]);
507 }
508 }
509
510 // NUtils::PrintPointSafe(pointContentVector, -1);
511 Int_t nContentDims = fContent->GetNdimensions();
512 NLogTrace("NBinning::FillAll: pointContentVector dims=%zu nContentDims=%d", pointContentVector.size(),
513 nContentDims);
514
515 auto pointContent = std::make_unique<Int_t[]>(nContentDims);
516
517 // Int_t pointContent[nContentDims];
518 NUtils::VectorToArray(pointContentVector, pointContent.get());
519 Long64_t pointContentBin = fContent->GetBin(pointContent.get());
520
521 // ids.push_back(pointContentBin);
522 if (def) {
523 NBinningPoint point(this);
524 fContent->GetBinContent(pointContentBin, point.GetCoords());
526 Long64_t linBin = def->GetContent()->GetBin(point.GetStorageCoords());
527 def->GetContent()->SetBinContent(linBin, pointContentBin);
528 def->GetIds().push_back(pointContentBin);
529 }
530
531 NLogTrace("NBinning::FillAll: Setting content bin %lld", pointContentBin);
532
533 fContent->SetBinContent(pointContentBin, 1);
534 nBinsFilled++;
535 // NLogDebug("NBinning::FillAll: Filled bin %lld: %s", nBinsFilled,
536 // NUtils::GetCoordsString(pointContentVector, -1).c_str());
537 NLogTrace("NBinning::FillAll: Filled bin %lld: %lld", nBinsFilled, nTotalBins);
538 int refreshRate = nTotalBins / 100;
539 if (refreshRate == 0) refreshRate = nTotalBins;
540 if (nBinsFilled % (refreshRate) == 0 && nBinsFilled != nTotalBins)
541 Ndmspc::NUtils::ProgressBar(nBinsFilled, nTotalBins, start_par, "I ");
542 // NLogDebug("NBinning::FillAll: [%3.2f%%] nBinsFilled=%lld", (double)nBinsFilled / nTotalBins * 100,
543 // nBinsFilled);
544 };
545 executor.Execute(binning_task);
546
547 Ndmspc::NUtils::ProgressBar(nTotalBins, nTotalBins, start_par, "I ");
548
549 auto end_par = std::chrono::high_resolution_clock::now();
550 std::chrono::duration<double, std::milli> par_duration = end_par - start_par;
551
552 NLogInfo("NBinning::FillAll: Filled %lld bins in %s s", nTotalBins,
553 NUtils::FormatTime(par_duration.count() / 1000).c_str());
554
555 fMap->Reset();
556
557 return nBinsFilled;
558}
559
560bool NBinning::AddBinning(size_t id, std::vector<int> binning, size_t n)
561{
565
566 if (fAxes.size() == 0) {
567 NLogError("AddBinning: No axes defined !!!");
568 return false;
569 }
570
571 if (id <= 0 || id > fAxes.size()) {
572 NLogError("AddBinning: Invalid binning id %d", id);
573 return false;
574 }
575
576 binning.insert(binning.begin(), id);
577 Int_t * point = new Int_t[fMap->GetNdimensions()];
578 NUtils::VectorToArray(binning, point);
579 if (binning.size() == 2) {
580 point[3] = point[1];
581 point[2] = 1;
582 point[1] = 1;
583 }
584 for (size_t i = 0; i < n; i++) {
585 NLogTrace("Adding binning %d: %d %d %d %d", i, point[0], point[1], point[2], point[3]);
586 fMap->SetBinContent(point, 1);
587 point[3] += 1;
588 }
589 delete[] point;
590
591 return true;
592}
593bool NBinning::AddBinningVariable(size_t id, std::vector<int> mins)
594{
598 if (id <= 0 || id > fAxes.size()) {
599 NLogError("AddBinningVariable: Invalid binning id %d", id);
600 return false;
601 }
602
603 // lopp over all mins and set binning
604 for (size_t i = 1; i < mins.size(); i++) {
605
606 if (mins[i] < 1 || mins[i] > fAxes[id - 1]->GetNbins() + 1) {
607 // NLogWarning("AddBinningVariable: Invalid binning value mins=%d", mins[i]);
608 return true;
609 }
610 // if (mins[i] == fAxes[id - 1]->GetNbins() || i == mins.size() - 1) mins[i]++;
611 int rebin = mins[i] - mins[i - 1];
612 if (rebin < 1) {
613 NLogError("AddBinningVariable: Invalid binning value rebin=%d", rebin);
614 return false;
615 }
616
617 int rebin_start = mins[i - 1] % rebin;
618 int bin = mins[i] / rebin;
619
620 // int rebin_start = ((mins[i - 1]) % rebin) + 1;
621 // int bin = (mins[i] / rebin);
622 if (rebin == 1) {
623 rebin_start = 1;
624 bin = mins[i - 1];
625 }
626 // rebin_start + 1 is just that it looks better in the output
627 // NLogDebug("Adding partial binning %d: %d %d %d %d [%d,%d]", i - 1, id, rebin, rebin_start + 1, bin,
628 // mins[i - 1], mins[i]);
629 AddBinning(id, {rebin, rebin_start, bin}, 1);
630 }
631
632 return true;
633}
634bool NBinning::AddBinningViaBinWidths(size_t id, std::vector<std::vector<int>> widths)
635{
639 // NLogTrace("Adding binning via bin widths for id=%d", id);
640 std::vector<int> mins;
641 // Print vector of widths
642 mins.push_back(1);
643 for (auto & w : widths) {
644 TAxis * axis = fAxes[id - 1];
645 int width = w[0];
646 int nWidths = w.size() > 1 ? w[1] : axis->GetNbins() / width;
647
648 // NLogDebug(" width=%d nWidths=%d last min=%d", width, nWidths, mins[mins.size() - 1]);
649 for (int iWidth = 0; iWidth < nWidths; iWidth++) {
650 if (mins[mins.size() - 1] > axis->GetNbins()) {
651 // NLogWarning("NBinning::AddBinningViaBinWidths: Exceeding axis nbins %d", axis->GetNbins());
652 break;
653 }
654 mins.push_back(mins[mins.size() - 1] + width);
655 // NLogDebug(" width=%d nWidths=%d iWidth=%d -> min=%d", width, nWidths, iWidth, mins[mins.size() - 1]);
656 }
657 }
658
659 NLogTrace("NBinning::AddBinningViaBinWidths: Adding binning via bin widths: %s",
660 NUtils::GetCoordsString(mins, -1).c_str());
661
662 return AddBinningVariable(id, mins);
663}
664
665std::vector<std::vector<int>> NBinning::GetCoordsRange(std::vector<int> c) const
666{
667 std::vector<std::vector<int>> coordsRange;
668 std::vector<int> ids;
669 std::vector<int> mins;
670 std::vector<int> maxs;
671 // int iAxis = 0;
672 bool isValid;
673 int index = 0;
674 for (size_t iAxis = 0; iAxis < fAxes.size(); iAxis++) {
675 // for (int i = 0; i < fContent->GetNdimensions(); i += 3) {
676 int min;
677 int max;
678 if (fBinningTypes[iAxis] == Binning::kSingle) {
679 isValid = NUtils::GetAxisRangeInBase(fAxes[iAxis], 1, 1, c[index], min, max);
680 index++;
681 }
682 else if (fBinningTypes[iAxis] == Binning::kMultiple) {
683 isValid = NUtils::GetAxisRangeInBase(fAxes[iAxis], c[index], c[index + 1], c[index + 2], min, max);
684 index += 3;
685 }
686 else if (fBinningTypes[iAxis] == Binning::kUser) {
687 // isValid = NUtils::GetAxisRangeInBase(fAxes[iAxis], 1, 1, c[index], min, max);
688 isValid = NUtils::GetAxisRangeInBase(fAxes[iAxis], fAxes[iAxis]->GetNbins(), 1, 1, min, max);
689 index++;
690 }
691 else {
692 NLogError("NBinning::GetCoordsRange: Unknown binning type %d", fBinningTypes[iAxis]);
693 continue;
694 }
695 if (!isValid) {
696 // NLogError("Cannot get axis range for axis %d", iAxis);
697 return {};
698 }
699 // print min max
700 NLogDebug("Axis %d: %s [%d,%d]", iAxis, fAxes[iAxis]->GetName(), min, max);
701 ids.push_back(iAxis); // +1 because id starts from 1
702 mins.push_back(min);
703 maxs.push_back(max);
704 }
705
706 coordsRange.push_back(ids);
707 coordsRange.push_back(mins);
708 coordsRange.push_back(maxs);
709 return coordsRange;
710}
711
713{
714 if (i >= fBinningTypes.size()) {
715 NLogError("Invalid binning type %d", i);
716 // return Binning::kSingle;
717 return Binning::kUndefined;
718 }
719 return fBinningTypes[i];
720}
721std::vector<std::vector<int>> NBinning::GetAxisRanges(std::vector<int> c) const
722{
726 std::vector<std::vector<int>> axisRanges;
727
728 bool isValid;
729 int index = 0;
730 for (size_t iAxis = 0; iAxis < fAxes.size(); iAxis++) {
731 // for (int i = 0; i < fContent->GetNdimensions(); i += 3) {
732 int min;
733 int max;
734 if (fBinningTypes[iAxis] == Binning::kSingle) {
735 isValid = NUtils::GetAxisRangeInBase(fAxes[iAxis], 1, 1, c[index], min, max);
736 index++;
737 }
738 else if (fBinningTypes[iAxis] == Binning::kMultiple) {
739 isValid = NUtils::GetAxisRangeInBase(fAxes[iAxis], c[index], c[index + 1], c[index + 2], min, max);
740 index += 3;
741 }
742 else if (fBinningTypes[iAxis] == Binning::kUser) {
743 isValid = NUtils::GetAxisRangeInBase(fAxes[iAxis], fAxes[iAxis]->GetNbins(), 1, 1, min, max);
744 index++;
745 }
746 else {
747 NLogError("[NBinning::GetAxisRanges] Unknown binning type [%d]", fBinningTypes[iAxis]);
748 continue;
749 }
750 if (!isValid) {
751 // NLogError("Cannot get axis range for axis %d", iAxis);
752 return {};
753 }
754 // print min max
755 NLogTrace("Axis %d: %s [%d,%d]", iAxis, fAxes[iAxis]->GetName(), min, max);
756 axisRanges.push_back({(int)iAxis, min, max});
757 }
758
759 return axisRanges;
760}
761std::vector<int> NBinning::GetAxisBinning(size_t axisId, const std::vector<int> & c) const
762{
766 std::vector<int> binning;
767
768 int index = 0;
769 for (size_t iAxis = 0; iAxis < fAxes.size(); iAxis++) {
770 // for (int i = 0; i < fContent->GetNdimensions(); i += 3) {
771 // int min;
772 // int max;
773 if (fBinningTypes[iAxis] == Binning::kSingle) {
774 if (iAxis == axisId) {
775 binning.push_back(1);
776 binning.push_back(1);
777 binning.push_back(c[index]);
778 break;
779 }
780 index++;
781 }
782 else if (fBinningTypes[iAxis] == Binning::kMultiple) {
783 if (iAxis == axisId) {
784 binning.push_back(c[index]);
785 binning.push_back(c[index + 1]);
786 binning.push_back(c[index + 2]);
787 break;
788 }
789 index += 3;
790 }
791 else if (fBinningTypes[iAxis] == Binning::kUser) {
792 if (iAxis == axisId) {
793 binning.push_back(c[index]);
794 binning.push_back(1);
795 binning.push_back(1);
796 break;
797 }
798 index++;
799 }
800 else {
801 NLogError("[NBinning::GetAxisBinning] Unknown binning type [%d]", fBinningTypes[iAxis]);
802 continue;
803 }
804 }
805
806 return binning;
807}
808
809bool NBinning::GetAxisRange(size_t axisId, double & min, double & max, std::vector<int> c) const
810{
814 int minBin = 0;
815 int maxBin = 0;
816 Bool_t isValid = GetAxisRangeInBase(axisId, minBin, maxBin, c);
817
818 min = fAxes[axisId]->GetBinLowEdge(minBin);
819 max = fAxes[axisId]->GetBinUpEdge(maxBin);
820 return isValid;
821}
822
823bool NBinning::GetAxisRangeInBase(size_t axisId, int & min, int & max, std::vector<int> c) const
824{
828 if (axisId >= fAxes.size()) {
829 NLogError("Invalid axis id %d", axisId);
830 return false;
831 }
832
833 // Generate c if not provided
834
835 int minBin = 0;
836 int maxBin = 0;
837 Bool_t isValid = false;
838 if (fBinningTypes[axisId] == Binning::kSingle) {
839 isValid = NUtils::GetAxisRangeInBase(fAxes[axisId], 1, 1, c[0], minBin, maxBin);
840 }
841 else if (fBinningTypes[axisId] == Binning::kMultiple) {
842 isValid = NUtils::GetAxisRangeInBase(fAxes[axisId], c[0], c[1], c[2], minBin, maxBin);
843 }
844
845 min = minBin;
846 max = maxBin;
847 return isValid;
848}
849
851{
855
856 // TODO: Verify memery leak and its posible consequence for user
857
858 TObjArray * axesArray = new TObjArray();
859
860 // loop over all axes and create TObjArray
861 for (size_t i = 0; i < fAxes.size(); i++) {
862 TAxis * axis = (TAxis *)fAxes[i];
863 TAxis * axisNew = (TAxis *)axis->Clone();
864
865 std::string name = axis->GetName();
866 NLogTrace("NBinning::GetListOfAxes(): Binning '%s': %d", name.c_str(), axis->GetNbins());
867
868 auto bins = std::make_unique<double[]>(axis->GetNbins() + 1);
869 // double bins[axis->GetNbins() + 1];
870 int count = 0;
871 int iBin = 1; // start from bin 1
872 bins[count++] = axis->GetBinLowEdge(1);
873
874 NBinningDef * def = GetDefinition();
875 std::map<std::string, std::vector<std::vector<int>>> definition = def->GetDefinition();
876 for (auto & v : definition.at(name)) {
877 NLogTrace(" %s", NUtils::GetCoordsString(v, -1).c_str());
878
879 int n = v.size() > 1 ? v[1] : axis->GetNbins() / v[0];
880 for (int i = 0; i < n; i++) {
881 iBin += v[0];
882 bins[count++] = axis->GetBinLowEdge(iBin);
883 }
884 }
885 // loop over bins and print
886 for (int i = 0; i < count; i++) {
887 NLogTrace(" %s: %d %f", axis->GetName(), i + 1, bins[i]);
888 }
889 axisNew->Set(count - 1, bins.get());
890 axesArray->Add(axisNew);
891 }
892
893 return axesArray;
894}
895
896bool NBinning::SetAxisType(size_t axisId, AxisType at)
897{
901 if (axisId >= fAxes.size()) {
902 NLogError("Invalid axis id %d", axisId);
903 return false;
904 }
905 fAxisTypes[axisId] = at;
906 return true;
907}
908
910{
914 if (i >= fAxisTypes.size()) {
915 NLogError("Invalid axis type %d", i);
916 return AxisType::kUndefined; // Undefined
917 }
918 return fAxisTypes[i];
919}
920char NBinning::GetAxisTypeChar(size_t i) const
921{
922 if (i >= fAxisTypes.size()) {
923 NLogError("Invalid axis type %d", i);
924 return 'X'; // Undefined
925 }
926 switch (fAxisTypes[i]) {
927 case AxisType::kFixed: return 'F';
928 case AxisType::kVariable: return 'V';
930 default: return 'X';
931 }
932}
933
934std::vector<int> NBinning::GetAxisIndexes(AxisType type) const
935{
939 std::vector<int> ids;
940 for (size_t i = 0; i < fAxes.size(); i++) {
941 if (fAxisTypes[i] == type) {
942 NLogTrace("Axis %d: %s type=%d", i, fAxes[i]->GetName(), fAxisTypes[i]);
943 ids.push_back(i);
944 }
945 else {
946 NLogTrace("Axis %d: %s type=%d [not selected]", i, fAxes[i]->GetName(), fAxisTypes[i]);
947 }
948 }
949 return ids;
950}
951
952std::vector<TAxis *> NBinning::GetAxesByType(AxisType type) const
953{
957 std::vector<TAxis *> axes;
958 for (size_t i = 0; i < fAxes.size(); i++) {
959 if (fAxisTypes[i] == type) {
960 NLogTrace("Axis %d: %s type=%d", i, fAxes[i]->GetName(), fAxisTypes[i]);
961 axes.push_back(fAxes[i]);
962 }
963 else {
964 NLogTrace("Axis %d: %s type=%d [not selected]", i, fAxes[i]->GetName(), fAxisTypes[i]);
965 }
966 }
967 return axes;
968}
969
970std::vector<int> NBinning::GetAxisIndexesByNames(std::vector<std::string> names) const
971{
975 std::vector<int> ids;
976 for (auto & name : names) {
977 for (size_t i = 0; i < fAxes.size(); i++) {
978 if (fAxes[i]->GetName() == name) {
979 NLogTrace("Axis %d: %s type=%d", i, fAxes[i]->GetName(), fAxisTypes[i]);
980 ids.push_back(i);
981 break; // break inner loop if found
982 }
983 }
984 }
985 return ids;
986}
987
988std::vector<std::string> NBinning::GetAxisNamesByType(AxisType type) const
989{
993 std::vector<std::string> names;
994 for (size_t i = 0; i < fAxes.size(); i++) {
995 if (fAxisTypes[i] == type) {
996 NLogTrace("Axis %d: %s type=%d", i, fAxes[i]->GetName(), fAxisTypes[i]);
997 names.push_back(fAxes[i]->GetName());
998 continue;
999 }
1000 else {
1001 NLogTrace("Axis %d: %s type=%d [not selected]", i, fAxes[i]->GetName(), fAxisTypes[i]);
1002 }
1003 }
1004 return names;
1005}
1006std::vector<std::string> NBinning::GetAxisNamesByIndexes(std::vector<int> ids) const
1007{
1011 std::vector<std::string> names;
1012 for (auto & id : ids) {
1013 // FIXME: change to size_t
1014 if (id < 0 || id >= (int)fAxes.size()) {
1015 NLogError("Invalid axis id %d", id);
1016 continue;
1017 }
1018 NLogTrace("Axis %d: %s type=%d", id, fAxes[id]->GetName(), fAxisTypes[id]);
1019 names.push_back(fAxes[id]->GetName());
1020 }
1021 return names;
1022}
1023
1024NBinningDef * NBinning::GetDefinition(const std::string & name)
1025{
1026
1030
1031 if (name.empty()) {
1032 if (fCurrentDefinitionName.empty()) {
1033 return nullptr;
1034 }
1035 // check if current definition exists
1037 NLogError("NBinning::GetDefinition: Current definition '%s' not found", fCurrentDefinitionName.c_str());
1038 return nullptr;
1039 }
1040 NLogTrace("NBinning::GetDefinition: Using current definition '%s'", fCurrentDefinitionName.c_str());
1042 }
1043
1044 if (fDefinitions.find(name) == fDefinitions.end()) {
1045 NLogError("NBinning::GetDefinition: Definition '%s' not found", name.c_str());
1046 return nullptr;
1047 }
1048 NLogTrace("NBinning::GetDefinition: Using definition '%s'", name.c_str());
1050 return fDefinitions.at(name);
1051}
1052
1053void NBinning::AddBinningDefinition(std::string name, std::map<std::string, std::vector<std::vector<int>>> binning,
1054 bool forceDefault)
1055{
1059 if (fDefinitions.find(name) != fDefinitions.end()) {
1060 NLogError("Binning definition '%s' already exists", name.c_str());
1061 return;
1062 }
1063
1064 NLogInfo("NBinning::AddBinningDefinition: Adding binning definition '%s'", name.c_str());
1065 NBinningDef * def = new NBinningDef(name, binning, this);
1066 fDefinitionNames.push_back(name);
1067 fDefinitions[name] = def;
1069 fMap->Reset();
1070 // loop over binning axes
1071 for (size_t i = 0; i < fAxes.size(); i++) {
1072 TAxis * axis = fAxes[i];
1073 std::string axisName = axis->GetName();
1074 // NLogDebug("Axis %zu: name='%s' title='%s' nbins=%d min=%.3f max=%.3f", i, axisName.c_str(),
1075 // axis->GetTitle(), axis->GetNbins(), axis->GetXmin(), axis->GetXmax());
1076
1077 // TODO: Handle case when user wants to rebin alphanumeric axis. Now we are failing
1078 if (!binning[axisName].empty()) {
1079
1080 // TODO: Handle case when user wants to rebin alphanumeric axis. Now we are failing
1081 if (axis->IsAlphanumeric() && (binning[axisName].size() != 1 || binning[axisName][0][0] != 1)) {
1082 NLogError("NBinning::AddBinningDefinition: Axis '%s' is alphanumeric and is binning provided in definition "
1083 "'%s'. Exiting ...",
1084 axisName.c_str(), name.c_str());
1085 exit(1);
1086 }
1087
1088
1089 AddBinningViaBinWidths(i + 1, binning[axisName]);
1091 // GetDefinition()[axisName] = binning[axisName];
1092 // def->SetAxisDefinition(axisName, binning[axisName]);
1093 }
1094 else {
1095
1096 // TODO: Handle case when user wants to rebin alphanumeric axis. Now we are failing
1097 if (axis->IsAlphanumeric()) {
1098 NLogError("NBinning::AddBinningDefinition: Axis '%s' is alphanumeric and no binning provided in definition "
1099 "'%s'. Exiting ...",
1100 axisName.c_str(), name.c_str());
1101 exit(1);
1102 }
1103
1104 AddBinning(i + 1, {axis->GetNbins(), 1, 1}, 1);
1105 // GetDefinition()[axisName] = {{axis->GetNbins()}};
1106 // def->SetAxisDefinition(axisName, {{axis->GetNbins()}});
1107 }
1108 }
1109
1110 // Long64_t nStart = fContent->GetNbins();
1111 // def->SetStartId(nStart);
1112 // std::vector<Long64_t> entries;
1113 Long64_t nFilled = FillAll(def);
1114 // def->Print();
1115 NLogTrace("NBinning::AddBinningDefinition: Filled %lld bins for definition '%s'", nFilled,
1116 NUtils::GetCoordsString(def->GetIds(), -1).c_str());
1117 // def->SetNEntries(nFilled);
1118
1119 if (forceDefault || fCurrentDefinitionName.empty()) {
1121 NLogTrace("Set default binning definition '%s'", fCurrentDefinitionName.c_str());
1122 }
1123 else {
1124 NLogTrace("Added binning definition '%s' [not default]", name.c_str());
1125 }
1126}
1127
1129{
1133
1134 if (fPoint == nullptr) {
1135 fPoint = new NBinningPoint(this);
1136 }
1137 return fPoint;
1138}
1139
1140NBinningPoint * NBinning::GetPoint(size_t id, std::string binning)
1141{
1145
1146 // TODO: Optimize speed here
1147
1148 NBinningDef * def = GetDefinition(binning);
1149 if (def == nullptr) {
1150 NLogError("NBinning::FillPoint: Definition '%s' not found", binning.c_str());
1151 return nullptr;
1152 }
1153
1154 if (fPoint == nullptr) {
1155 fPoint = new NBinningPoint(this);
1156 }
1157
1158 Long64_t linBin = def->GetId(id);
1159 if (linBin < 0) {
1160 NLogError("NBinning::GetPoint: Invalid linear bin %lld for id=%d in definition '%s'", linBin, id, binning.c_str());
1161 return nullptr;
1162 }
1163 if (linBin >= fContent->GetNbins()) {
1164 NLogError("NBinning::GetPoint: Linear bin %lld out of range [0,%lld) for id=%d in definition '%s'", linBin,
1165 fContent->GetNbins(), id, binning.c_str());
1166 return nullptr;
1167 }
1168 fContent->GetBinContent(linBin, fPoint->GetCoords());
1169 fPoint->RecalculateStorageCoords(linBin);
1170
1171 return fPoint;
1172}
1173
1174bool NBinning::SetCfg(const json & cfg)
1175{
1179 GetPoint()->SetCfg(cfg);
1180
1181 return true;
1182}
1183
1184void NBinning::SetCurrentDefinitionName(const std::string & name)
1185{
1190
1191 if (name.empty()) {
1192 if (!fDefinitionNames.empty()) {
1194 NLogInfo("Binning definition name='' set to first available definition '%s'", fCurrentDefinitionName.c_str());
1195 return;
1196 }
1197 else {
1198 NLogError("Binning definition name='' and no definitions are available !!! Ignorred ...");
1199 return;
1200 }
1201 }
1202
1203 if (fDefinitions.find(name) == fDefinitions.end()) {
1204 NLogError("Binning definition '%s' not found", name.c_str());
1205 return;
1206 }
1207
1208 // check if name is already current
1209 if (fCurrentDefinitionName.compare(name) == 0) {
1210 NLogTrace("Binning definition '%s' is already current", name.c_str());
1211 return;
1212 }
1213
1214 // Set current definition name
1216
1217 // Reset Point
1218 if (fPoint == nullptr) {
1219 fPoint = new NBinningPoint(this);
1220 }
1221 fPoint->Reset();
1222}
1223
1224} // namespace Ndmspc
Defines binning mapping and content for NDMSPC histograms.
Definition NBinningDef.h:26
std::vector< int > GetVariableAxes() const
Get list of variable axes indices.
Definition NBinningDef.h:71
std::vector< Long64_t > GetIds() const
Get list of bin IDs.
Definition NBinningDef.h:93
THnSparse * GetContent() const
Get the template content histogram.
std::map< std::string, std::vector< std::vector< int > > > GetDefinition() const
Get the binning mapping definition.
Definition NBinningDef.h:52
virtual void Print(Option_t *option="") const
Print binning definition information.
void AddVariableAxis(size_t axis)
Add a variable axis index.
Definition NBinningDef.h:77
Long64_t GetId(size_t index) const
Get bin ID at specified index.
Represents a single point in multi-dimensional binning.
bool RecalculateStorageCoords(Long64_t entry=-1, bool useBinningDefCheck=false)
Recalculate storage coordinates for the point.
void SetCfg(json cfg)
Set configuration JSON object.
Int_t * GetCoords() const
Get pointer to content coordinates array.
Int_t * GetStorageCoords() const
Get pointer to storage coordinates array.
NBinning object for managing multi-dimensional binning and axis definitions.
Definition NBinning.h:45
NBinningDef * GetDefinition(const std::string &name="")
Get binning definition by name.
std::vector< std::string > GetAxisNamesByType(AxisType type) const
Get axis names by type.
Definition NBinning.cxx:988
std::vector< int > GetAxisIndexes(AxisType type) const
Get indexes of axes by type.
Definition NBinning.cxx:934
std::vector< std::string > GetAxisNamesByIndexes(std::vector< int > axisIds) const
Get axis names by indexes.
std::vector< AxisType > fAxisTypes
Axis types.
Definition NBinning.h:325
std::vector< TAxis * > fAxes
List of axes.
Definition NBinning.h:323
NBinningPoint * GetPoint()
Get the current binning point.
std::vector< int > GetAxisIndexesByNames(std::vector< std::string > axisNames) const
Get axis indexes by axis names.
Definition NBinning.cxx:970
bool GetAxisRange(size_t axisId, double &min, double &max, std::vector< int > c) const
Get axis range for a specific axis and coordinates.
Definition NBinning.cxx:809
std::vector< std::vector< int > > GetAxisRanges(std::vector< int > c) const
Get axis ranges for given coordinates.
Definition NBinning.cxx:721
void AddBinningDefinition(std::string name, std::map< std::string, std::vector< std::vector< int > > > binning, bool forceDefault=false)
Add a binning definition.
TObjArray * GenerateListOfAxes()
Generate a list of axes as TObjArray.
Definition NBinning.cxx:850
bool AddBinningVariable(size_t id, std::vector< int > mins)
Add variable binning for a specific axis.
Definition NBinning.cxx:593
NBinning()
Default constructor.
Definition NBinning.cxx:19
virtual void Print(Option_t *option="") const
Print binning information.
Definition NBinning.cxx:245
AxisType GetAxisType(size_t i) const
Get axis type for a specific axis.
Definition NBinning.cxx:909
void Initialize()
Initialize the binning object.
Definition NBinning.cxx:90
bool SetCfg(const json &cfg)
Set configuration from JSON.
std::vector< std::string > fDefinitionNames
Binning definition names.
Definition NBinning.h:328
THnSparse * fContent
Content histogram.
Definition NBinning.h:322
std::string fCurrentDefinitionName
Current definition name.
Definition NBinning.h:326
std::map< std::string, NBinningDef * > fDefinitions
Binning definitions.
Definition NBinning.h:327
Binning GetBinningType(size_t i) const
Get binning type for a specific axis.
Definition NBinning.cxx:712
void PrintContent(Option_t *option="") const
Print binning content.
Definition NBinning.cxx:341
bool GetAxisRangeInBase(size_t axisId, int &min, int &max, std::vector< int > c) const
Get axis range in base for a specific axis and coordinates.
Definition NBinning.cxx:823
std::vector< int > GetAxisBinning(size_t axisId, const std::vector< int > &c) const
Get binning for a specific axis and coordinates.
Definition NBinning.cxx:761
virtual ~NBinning()
Destructor.
Definition NBinning.cxx:56
NBinningPoint * fPoint
! Binning point object
Definition NBinning.h:329
char GetAxisTypeChar(size_t i) const
Get axis type as character for a specific axis.
Definition NBinning.cxx:920
void Reset()
Reset the binning object to initial state.
Definition NBinning.cxx:78
std::vector< std::vector< int > > GetCoordsRange(std::vector< int > c) const
Get coordinate ranges for given coordinates.
Definition NBinning.cxx:665
bool SetAxisType(size_t id, AxisType type)
Set axis type for a specific axis.
Definition NBinning.cxx:896
std::vector< TAxis * > GetAxesByType(AxisType type) const
Get axes by type.
Definition NBinning.cxx:952
void SetCurrentDefinitionName(const std::string &name)
Set current definition name.
THnSparse * fMap
Mapping histogram.
Definition NBinning.h:321
std::vector< Binning > fBinningTypes
Binning types.
Definition NBinning.h:324
bool AddBinning(size_t id, std::vector< int > binning, size_t n=1)
Add binning for a specific axis.
Definition NBinning.cxx:560
bool AddBinningViaBinWidths(size_t id, std::vector< std::vector< int > > widths)
Add binning via bin widths for a specific axis.
Definition NBinning.cxx:634
Long64_t FillAll(NBinningDef *def=nullptr)
Fill all bins according to definition.
Definition NBinning.cxx:416
Executes a function over all points in an N-dimensional space, optionally in parallel.
void Execute(const std::function< void(const std::vector< int > &coords)> &func)
Execute a function over all coordinates in the N-dimensional space.
static std::string FormatTime(long long seconds)
Format time in seconds to human-readable string.
Definition NUtils.cxx:1664
static bool GetAxisRangeInBase(TAxis *a, int rebin, int rebin_start, int bin, int &min, int &max)
Get axis range in base for rebinned axis.
Definition NUtils.cxx:1342
static void ProgressBar(int current, int total, std::string prefix="", std::string suffix="", int barWidth=50)
Display progress bar.
Definition NUtils.cxx:1677
static std::string GetCoordsString(const std::vector< int > &coords, int index=-1, int width=0)
Get string representation of coordinates.
Definition NUtils.cxx:1592
static void VectorToArray(std::vector< int > v1, Int_t *v2)
Convert vector to array.
Definition NUtils.cxx:1568
static std::vector< int > ArrayToVector(Int_t *v1, int size)
Convert array to vector.
Definition NUtils.cxx:1555
Global callback function for libwebsockets client events.
AxisType
Types of axis supported.
Definition NBinning.h:30
@ kUndefined
Undefined axis type.
Definition NBinning.h:33
@ kFixed
fixed axis type
Definition NBinning.h:31
@ kVariable
variable axis type
Definition NBinning.h:32
Binning
Types of binning supported.
Definition NBinning.h:19
@ kUser
No rebin possible, but axis range is as single bin (User must set bin as needed)
Definition NBinning.h:22
@ kUndefined
Undefined binning type.
Definition NBinning.h:23
@ kMultiple
Rebin is possible.
Definition NBinning.h:21
@ kSingle
No rebin possible.
Definition NBinning.h:20