ndmspc  v1.2.0-0.1.rc3
NBinningPoint.cxx
1 #include <vector>
2 #include <TAxis.h>
3 #include "NBinningDef.h"
4 #include "NLogger.h"
5 #include "NStorageTree.h"
6 #include "NUtils.h"
7 #include "NBinning.h"
8 
9 #include "NBinningPoint.h"
10 
12 ClassImp(Ndmspc::NBinningPoint);
14 
15 namespace Ndmspc {
16 NBinningPoint::NBinningPoint(NBinning * b) : TObject(), fBinning(b)
17 {
18 
19  if (fBinning == nullptr) {
20  // NLogError("NBinningPoint: Binning is nullptr");
21  return;
22  }
23  if (fBinning->GetAxes().empty()) {
24  NLogError("NBinningPoint: Binning has no axes");
25  return;
26  }
27  if (fBinning->GetContent() == nullptr) {
28  NLogError("NBinningPoint: Binning content is nullptr");
29  return;
30  }
31 
32  fContentNDimensions = fBinning->GetContent()->GetNdimensions();
33  fNDimensions = fBinning->GetAxes().size();
35  fStorageCoords = new Int_t[fNDimensions];
36  fMins = new Double_t[fNDimensions];
37  fMaxs = new Double_t[fNDimensions];
38  fBaseBinMin = new Int_t[fNDimensions];
39  fBaseBinMax = new Int_t[fNDimensions];
40  fLabels.resize(fNDimensions);
41 
42  Reset();
43 }
45 {
46  delete[] fContentCoords;
47  delete[] fStorageCoords;
48  delete[] fMins;
49  delete[] fMaxs;
50  delete[] fBaseBinMin;
51  delete[] fBaseBinMax;
52  fLabels.clear();
53 }
54 
56 {
60 
61  NLogTrace("NBinningPoint::Reset: Resetting point ...");
62 
63  if (fContentNDimensions <= 0 || fNDimensions <= 0 || fContentCoords == nullptr) {
64  NLogError("NBinningPoint::Reset: Invalid dimensions or coordinates");
65  return;
66  }
67  for (Int_t i = 0; i < fContentNDimensions; ++i) {
68  fContentCoords[i] = -1;
69  }
70  for (Int_t i = 0; i < fNDimensions; ++i) {
71  fStorageCoords[i] = -1;
72  fMins[i] = -1;
73  fMaxs[i] = -1;
74  fBaseBinMin[i] = -1;
75  fBaseBinMax[i] = -1;
76  fLabels[i] = "";
77  }
78  fEntryNumber = -1;
79 }
80 
81 void NBinningPoint::Print(Option_t * option) const
82 {
85  if (fContentNDimensions <= 0 || fNDimensions <= 0 || fContentCoords == nullptr) {
86  NLogError("NBinningPoint::Print: Invalid dimensions or coordinates");
87  return;
88  }
89  TString opt = option;
90  opt.ToUpper();
91 
92  NLogInfo("NBinningPoint: %s",
94  NLogInfo(" Storage coordinates: %s",
96  NLogInfo(" Entry number: %lld", fEntryNumber);
97  NLogInfo(" Title: '%s'", GetString().c_str());
98  if (opt.Contains("C")) {
99  NLogInfo(" Config: %s", fCfg.dump().c_str());
100  }
101 
102  if (opt.Contains("A")) {
103  for (int i = 0; i < fNDimensions; ++i) {
104  NLogInfo(" Axis %d: min=%.3f max=%.3f label='%s'", i, fMins[i], fMaxs[i], fLabels[i].c_str());
105  }
106  }
107 }
108 
109 bool NBinningPoint::RecalculateStorageCoords(Long64_t entry, bool useBinningDefCheck)
110 {
114 
115  if (fBinning == nullptr || fBinning->GetContent() == nullptr) {
116  NLogError("NBinningPoint::RecalculateStorageCoords: Binning or content is nullptr");
117  return false;
118  }
119 
120  fEntryNumber = entry;
121  std::vector<int> contentVec = NUtils::ArrayToVector(fContentCoords, fContentNDimensions);
122  std::vector<std::vector<int>> axisRanges = fBinning->GetAxisRanges(contentVec);
123  // for (size_t i = 0; i < axisRanges.size(); i++) {
124  // NLogDebug("Axis %zu: %s", i, NUtils::GetCoordsString(axisRanges[i], -1).c_str());
125  // }
126  NBinningDef * binDef = fBinning->GetDefinition();
127  if (binDef == nullptr) {
128  NLogError("NBinningPoint::RecalculateStorageCoords: Binning definition is nullptr");
129  return false;
130  }
131  std::vector<Long64_t> ids = binDef->GetIds();
132 
133  // useBinningDefCheck = false;
134  if (useBinningDefCheck) {
135  if (fTreeStorage == nullptr) {
136  NLogError("NBinningPoint::RecalculateStorageCoords: Storage tree is nullptr !!! Skipping check ...");
137  }
138  else {
139  if (std::find(ids.begin(), ids.end(), fEntryNumber) == ids.end() && fEntryNumber >= 0 &&
140  fEntryNumber < fTreeStorage->GetEntries()) {
141  NLogError("NBinningPoint::RecalculateStorageCoords: Entry %lld not found in binning definition '%s' !!!",
143 
144  // loop over all available definitions and print their ids
145  NLogError("Available binning definitions for entry=%lld :", fEntryNumber);
146  std::string firstDefName;
147  for (const auto & kv : fBinning->GetDefinitions()) {
148  NBinningDef * def = kv.second;
149  if (def == nullptr) continue;
150  std::vector<Long64_t> defIds = def->GetIds();
151  if (std::find(defIds.begin(), defIds.end(), fEntryNumber) != defIds.end()) {
152  if (firstDefName.empty()) firstDefName = kv.first;
153  NLogError(" Definition '%s' size=%zu ", kv.first.c_str(), defIds.size());
154  }
155  }
156 
157  NLogError(
158  "One can set definition via 'NBinning::SetCurrentDefinitionName(\"%s\")' before calling 'GetEntry(%lld)'",
159  firstDefName.c_str(), fEntryNumber);
160  Reset();
161  return false;
162  }
163  }
164  }
165 
166  // binDef->Print();
167  for (Int_t i = 0; i < fNDimensions; ++i) {
168  TAxis * axis = fBinning->GetAxes()[i];
169  TAxis * axisStorage = (TAxis *)binDef->GetAxes()->At(i);
170  fBaseBinMin[i] = axisRanges[i][1];
171  fBaseBinMax[i] = axisRanges[i][2];
172  fMins[i] = axis->GetBinLowEdge(axisRanges[i][1]);
173  fMaxs[i] = axis->GetBinUpEdge(axisRanges[i][2]);
174  // FIXME: Check if GetBinLabel works when min and max are not the same
175  fLabels[i] = axis->GetBinLabel(axisRanges[i][1]);
176  fStorageCoords[i] = axisStorage->FindBin((fMins[i] + fMaxs[i]) / 2.0);
177  }
178 
179  if (fParameters) fParameters->GetHisto()->Reset();
180 
181  return true;
182 }
183 
184 std::map<int, std::vector<int>> NBinningPoint::GetBaseAxisRanges() const
185 {
189  std::map<int, std::vector<int>> axisRanges;
190  for (Int_t i = 0; i < fNDimensions; ++i) {
191  axisRanges[i] = {fBaseBinMin[i], fBaseBinMax[i]};
192  }
193  return axisRanges;
194 }
195 
196 std::string NBinningPoint::GetString(const std::string & prefix, bool all) const
197 {
198 
202 
203  std::string title = !prefix.empty() ? prefix + " " : "";
204  for (int i = 0; i < fNDimensions; i++) {
205  TAxis * a = fBinning->GetAxes()[i];
206  if (a == nullptr) {
207  NLogError("NBinningPoint::GetTitle: Axis %d is nullptr !!!", i);
208  continue;
209  }
210 
211  // check type of axis
212  if (fBinning->GetAxisType(i) == AxisType::kVariable || all) {
213  if (a->IsAlphanumeric()) {
214  title += TString::Format("%s[%s] ", a->GetName(), a->GetBinLabel(fBaseBinMin[i])).Data();
215  }
216  else {
217  title += TString::Format("%s[%.3f,%.3f] ", a->GetName(), fMins[i], fMaxs[i]).Data();
218  }
219  }
220  }
221  if (title.back() == ' ') {
222  title.pop_back(); // remove last space
223  }
224  return title;
225 }
226 Long64_t NBinningPoint::Fill(bool ignoreFilledCheck)
227 {
231  if (fBinning == nullptr || fBinning->GetContent() == nullptr) {
232  NLogError("NBinningPoint::Fill: Binning or content is nullptr");
233  return -1;
234  }
235 
236  // TODO: Find more efficient way to verify if bin exists
237  Long64_t bin = fBinning->GetContent()->GetBin(fContentCoords, kFALSE);
238  if (bin >= 0 && ignoreFilledCheck == false) {
239  fBinning->GetDefinition()->GetContent()->SetBinContent(fStorageCoords, bin);
240  fBinning->GetDefinition()->GetIds().push_back(bin);
241  // NLogError("NBinningPoint::Fill: Bin for content already exists for coordinates: %s",
242  // NUtils::GetCoordsString(NUtils::ArrayToVector(fContentCoords, fContentNDimensions)).c_str());
243  return -bin;
244  }
245  bin = fBinning->GetContent()->GetBin(fContentCoords, kTRUE);
246  fBinning->GetContent()->SetBinContent(fContentCoords, 1);
247 
248  return bin;
249 }
250 
251 bool NBinningPoint::SetPointContentFromLinearIndex(Long64_t linBin, bool checkBinningDef)
252 {
256  if (fBinning == nullptr || fBinning->GetContent() == nullptr) {
257  NLogError("NBinningPoint::SetPointContentFromLinearIndex: Binning or content is nullptr");
258  return false;
259  }
260 
261  if (linBin < 0 || linBin >= fBinning->GetContent()->GetNbins()) {
262  NLogError("NBinningPoint::SetPointContentFromLinearIndex: Invalid linear bin index: %lld", linBin);
263  return false;
264  }
265 
266  fBinning->GetContent()->GetBinContent(linBin, fContentCoords);
267  return RecalculateStorageCoords(linBin, checkBinningDef);
268 }
269 
270 Double_t NBinningPoint::GetBinMin(std::string axis) const
271 {
275 
276  // check if axis exists in fBinning->GetAxes()
277  for (int i = 0; i < fNDimensions; i++) {
278  TAxis * a = fBinning->GetAxes()[i];
279  if (a == nullptr) {
280  NLogError("NBinningPoint::GetMin: Axis %d is nullptr !!!", i);
281  continue;
282  }
283  if (axis.compare(a->GetName()) == 0) {
284  return fMins[i];
285  }
286  }
287 
288  NLogError("NBinningPoint::GetMin: Axis '%s' not found !!!", axis.c_str());
289  return -1;
290 }
291 
292 Double_t NBinningPoint::GetBinMax(std::string axis) const
293 {
297 
298  // check if axis exists in fBinning->GetAxes()
299  for (int i = 0; i < fNDimensions; i++) {
300  TAxis * a = fBinning->GetAxes()[i];
301  if (a == nullptr) {
302  NLogError("NBinningPoint::GetMax: Axis %d is nullptr !!!", i);
303  continue;
304  }
305  if (axis.compare(a->GetName()) == 0) {
306  return fMaxs[i];
307  }
308  }
309 
310  NLogError("NBinningPoint::GetMax: Axis '%s' not found !!!", axis.c_str());
311  return -1;
312 }
313 
314 Double_t NBinningPoint::GetBinCenter(std::string axis) const
315 {
319 
320  // check if axis exists in fBinning->GetAxes()
321  for (int i = 0; i < fNDimensions; i++) {
322  TAxis * a = fBinning->GetAxes()[i];
323  if (a == nullptr) {
324  NLogError("NBinningPoint::GetCenter: Axis %d is nullptr !!!", i);
325  continue;
326  }
327  if (axis.compare(a->GetName()) == 0) {
328  return (fMins[i] + fMaxs[i]) / 2.0;
329  }
330  }
331 
332  NLogError("NBinningPoint::GetCenter: Axis '%s' not found !!!", axis.c_str());
333  return -1;
334 }
335 
336 std::string NBinningPoint::GetBinLabel(std::string axis) const
337 {
341 
342  // check if axis exists in fBinning->GetAxes()
343  for (int i = 0; i < fNDimensions; i++) {
344  TAxis * a = fBinning->GetAxes()[i];
345  if (a == nullptr) {
346  NLogError("NBinningPoint::GetLabel: Axis %d is nullptr !!!", i);
347  continue;
348  }
349  if (axis.compare(a->GetName()) == 0) {
350  return fLabels[i];
351  }
352  }
353 
354  NLogError("NBinningPoint::GetLabel: Axis '%s' not found !!!", axis.c_str());
355  return "";
356 }
357 
358 int NBinningPoint::GetBin(std::string axis) const
359 {
363 
364  // check if axis exists in fBinning->GetAxes()
365  for (int i = 0; i < fNDimensions; i++) {
366  TAxis * a = fBinning->GetAxes()[i];
367  if (a == nullptr) {
368  NLogError("NBinningPoint::GetBin: Axis %d is nullptr !!!", i);
369  continue;
370  }
371  if (axis.compare(a->GetName()) == 0) {
372  return fStorageCoords[i];
373  }
374  }
375 
376  NLogError("NBinningPoint::GetLabel: Axis '%s' not found !!!", axis.c_str());
377  return -1;
378 }
379 
380 TObject * NBinningPoint::GetTempObject(const std::string & name) const
381 {
382  auto it = fTempObjects.find(name);
383  if (it != fTempObjects.end()) {
384  return it->second;
385  }
386  return nullptr;
387 }
388 
389 } // namespace Ndmspc
Defines binning mapping and content for NDMSPC histograms.
Definition: NBinningDef.h:26
THnSparse * GetContent() const
Get the template content histogram.
Definition: NBinningDef.h:118
TObjArray * GetAxes() const
Get list of axes from content histogram.
Definition: NBinningDef.h:112
std::vector< Long64_t > GetIds() const
Get list of bin IDs.
Definition: NBinningDef.h:93
Represents a single point in multi-dimensional binning.
Definition: NBinningPoint.h:21
NBinningPoint(NBinning *b=nullptr)
Constructor.
Double_t GetBinMax(std::string axis) const
Get the maximum value for a specific axis.
Long64_t Fill(bool ignoreFilledCheck=false)
Fill the binning point content.
Int_t fNDimensions
Number of dimensions.
std::map< int, std::vector< int > > GetBaseAxisRanges() const
Get base axis ranges for the point.
std::string GetString(const std::string &prefix="", bool all=false) const
Returns a string representation of the binning point.
std::string GetBinLabel(std::string axis) const
Get the label for a specific axis.
bool RecalculateStorageCoords(Long64_t entry=-1, bool useBinningDefCheck=false)
Recalculate storage coordinates for the point.
virtual ~NBinningPoint()
Destructor.
Int_t * fContentCoords
Coordinates of the point.
std::vector< std::string > fLabels
Labels for each axis.
Double_t GetBinCenter(std::string axis) const
Returns the center value of the bin along the specified axis.
NBinning * fBinning
Binning object.
NParameters * fParameters
Parameter axis (if any)
Int_t * fBaseBinMin
Base bin minimum (for variable binning)
virtual void Print(Option_t *option="") const
Print binning point information.
Double_t * fMaxs
Maximum values for each axis.
bool SetPointContentFromLinearIndex(Long64_t linBin, bool checkBinningDef=false)
Set point content from linear index.
Int_t fContentNDimensions
Number of dimensions in content histogram.
Double_t * fMins
Minimum values for each axis.
TObject * GetTempObject(const std::string &name) const
Retrieve a temporary object by name.
NStorageTree * fTreeStorage
Storage tree object.
Int_t GetBin(std::string axis) const
Returns the bin index for the specified axis.
std::map< std::string, TObject * > fTempObjects
! Outputs map
Long64_t fEntryNumber
Entry in the storage tree.
Int_t * fBaseBinMax
Base bin maximum (for variable binning)
json fCfg
Configuration object.
virtual void Reset()
Reset the binning point to initial state.
Int_t * fStorageCoords
Storage coordinates of the point.
Double_t GetBinMin(std::string axis) const
Get the minimum value for a specific axis.
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.
Definition: NBinning.cxx:1024
std::string GetCurrentDefinitionName() const
Get current definition name.
Definition: NBinning.h:276
std::vector< std::vector< int > > GetAxisRanges(std::vector< int > c) const
Get axis ranges for given coordinates.
Definition: NBinning.cxx:721
AxisType GetAxisType(size_t i) const
Get axis type for a specific axis.
Definition: NBinning.cxx:909
std::vector< TAxis * > GetAxes() const
Get vector of axis pointers.
Definition: NBinning.h:223
std::map< std::string, NBinningDef * > GetDefinitions() const
Get all binning definitions.
Definition: NBinning.h:264
THnSparse * GetContent() const
Get the content histogram.
Definition: NBinning.h:217
TH1D * GetHisto() const
Returns the associated histogram.
Definition: NParameters.h:84
static std::string GetCoordsString(const std::vector< int > &coords, int index=-1, int width=0)
Get string representation of coordinates.
Definition: NUtils.cxx:1588
static std::vector< int > ArrayToVector(Int_t *v1, int size)
Convert array to vector.
Definition: NUtils.cxx:1551