ATLAS Offline Software
HistVal1D.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include <vector>
6 #include <utility>
7 
8 //____________________________________________________________________
9 template <class TH_1D, class THLW_1D>
10 HistVal1D<TH_1D,THLW_1D>::HistVal1D( bool trigger_conversion_all,
11  const std::string& name,
12  const std::string& title,
13  int nbins,
14  const double& xmin,
15  const double& xmax )
16  : HistValBase()
17 {
18  m_h1 = new TH_1D(name.c_str(),title.c_str(),nbins,xmin,xmax);
19  m_h2 = THLW_1D::create(name.c_str(),title.c_str(),nbins,xmin,xmax);
20  HistVal1D::compareMetaData();
21 
22  if (trigger_conversion_all)
23  triggerConversionToROOTHist();
24 }
25 
26 //____________________________________________________________________
27 template <class TH_1D, class THLW_1D>
28 template <class TFloat>
29 HistVal1D<TH_1D,THLW_1D>::HistVal1D( bool trigger_conversion_all,
30  const std::string& name,
31  const std::string& title,
32  int nbins,
33  const TFloat* xbins )
34 {
35  m_h1 = new TH_1D(name.c_str(),title.c_str(),nbins,xbins);
36  m_h2 = THLW_1D::create(name.c_str(),title.c_str(),nbins,xbins);
37  compareMetaData();
38  if (trigger_conversion_all)
39  triggerConversionToROOTHist();
40 }
41 
42 //____________________________________________________________________
43 template <class TH_1D, class THLW_1D>
44 HistVal1D<TH_1D,THLW_1D>::~HistVal1D()
45 {
46  compareAll();
47  delete m_h1;
48  LWHist::safeDelete(m_h2);
49 }
50 
51 //____________________________________________________________________
52 template <class TH_1D, class THLW_1D>
53 unsigned HistVal1D<TH_1D,THLW_1D>::getXAxis_NBins() const
54 {
55  return std::as_const(*m_h1).GetXaxis()->GetNbins();
56 }
57 
58 //____________________________________________________________________
59 template <class TH_1D, class THLW_1D>
60 unsigned HistVal1D<TH_1D,THLW_1D>::getYAxis_NBins() const
61 {
62  return std::as_const(*m_h1).GetYaxis()->GetNbins();
63 }
64 
65 //____________________________________________________________________
66 template <class TH_1D, class THLW_1D>
67 void HistVal1D<TH_1D,THLW_1D>::setXAxis_BinLabel(unsigned bin, const char* label)
68 {
69  m_h1->GetXaxis()->SetBinLabel(bin,label);
70  m_h2->GetXaxis()->SetBinLabel(bin,label);
71  this->titleOrNameWasChanged();
72 }
73 
74 //____________________________________________________________________
75 template <class TH_1D, class THLW_1D>
76 void HistVal1D<TH_1D,THLW_1D>::setYAxis_BinLabel(unsigned bin, const char* label)
77 {
78  m_h1->GetYaxis()->SetBinLabel(bin,label);
79  m_h2->GetYaxis()->SetBinLabel(bin,label);
80  this->titleOrNameWasChanged();
81 }
82 
83 //____________________________________________________________________
84 template <class TH_1D, class THLW_1D>
85 void HistVal1D<TH_1D,THLW_1D>::setXAxis_LabelSize(float s)
86 {
87  m_h1->GetXaxis()->SetLabelSize(s);
88  m_h2->GetXaxis()->SetLabelSize(s);
89  this->titleOrNameWasChanged();
90 }
91 
92 //____________________________________________________________________
93 template <class TH_1D, class THLW_1D>
94 void HistVal1D<TH_1D,THLW_1D>::setYAxis_LabelSize(float s)
95 {
96  m_h1->GetYaxis()->SetLabelSize(s);
97  m_h2->GetYaxis()->SetLabelSize(s);
98  this->titleOrNameWasChanged();
99 }
100 
101 //____________________________________________________________________
102 template <class TH_1D, class THLW_1D>
103 void HistVal1D<TH_1D,THLW_1D>::setXAxis_Title(const std::string&t)
104 {
105  m_h1->GetXaxis()->SetTitle(t.c_str());
106  m_h2->GetXaxis()->SetTitle(t.c_str());
107  this->titleOrNameWasChanged();
108 }
109 
110 //____________________________________________________________________
111 template <class TH_1D, class THLW_1D>
112 void HistVal1D<TH_1D,THLW_1D>::setYAxis_Title(const std::string&t)
113 {
114  m_h1->GetYaxis()->SetTitle(t.c_str());
115  m_h2->GetYaxis()->SetTitle(t.c_str());
116  this->titleOrNameWasChanged();
117 }
118 //____________________________________________________________________
119 template <class TH_1D, class THLW_1D>
120 void HistVal1D<TH_1D,THLW_1D>::setZAxis_Title(const std::string&t)
121 {
122  m_h1->GetZaxis()->SetTitle(t.c_str());
123  m_h2->GetZaxis()->SetTitle(t.c_str());
124  this->titleOrNameWasChanged();
125 }
126 
127 //____________________________________________________________________
128 template <class TH_1D, class THLW_1D>
129 void HistVal1D<TH_1D,THLW_1D>::SetMarkerColor( short c)
130 {
131  m_h1->SetMarkerColor(c);
132  m_h2->SetMarkerColor(c);
133  this->titleOrNameWasChanged();
134 }
135 
136 //____________________________________________________________________
137 template <class TH_1D, class THLW_1D>
138 void HistVal1D<TH_1D,THLW_1D>::SetMarkerStyle( short s )
139 {
140  m_h1->SetMarkerStyle(s);
141  m_h2->SetMarkerStyle(s);
142  assert(m_h1->GetMarkerStyle()==s);
143  assert(m_h2->GetMarkerStyle()==s);
144  this->titleOrNameWasChanged();
145 }
146 
147 //____________________________________________________________________
148 template <class TH_1D, class THLW_1D>
149 void HistVal1D<TH_1D,THLW_1D>::SetMarkerSize( float sz)
150 {
151  m_h1->SetMarkerSize(sz);
152  m_h2->SetMarkerSize(sz);
153  this->titleOrNameWasChanged();
154 }
155 
156 //____________________________________________________________________
157 template <class TH_1D, class THLW_1D>
158 void HistVal1D<TH_1D,THLW_1D>::setMinimum( const double& m )
159 {
160  m_h1->SetMinimum(m);
161  m_h2->SetMinimum(m);
162  this->titleOrNameWasChanged();
163 }
164 
165 //____________________________________________________________________
166 template <class TH_1D, class THLW_1D>
167 void HistVal1D<TH_1D,THLW_1D>::setMaximum( const double& m )
168 {
169  m_h1->SetMaximum(m);
170  m_h2->SetMaximum(m);
171  this->titleOrNameWasChanged();
172 }
173 
174 //____________________________________________________________________
175 template <class TH_1D, class THLW_1D>
176 void HistVal1D<TH_1D,THLW_1D>::setName(const std::string& name)
177 {
178  m_h1->SetName(convertedRootName(name).c_str());
179  m_h2->SetName(name.c_str());
180  this->titleOrNameWasChanged();
181 }
182 
183 //____________________________________________________________________
184 template <class TH_1D, class THLW_1D>
185 void HistVal1D<TH_1D,THLW_1D>::setTitle(const std::string& title)
186 {
187  m_h1->SetTitle(title.c_str());
188  m_h2->SetTitle(title.c_str());
189  this->titleOrNameWasChanged();
190 }
191 
192 //____________________________________________________________________
193 template <class TH_1D, class THLW_1D>
194 void HistVal1D<TH_1D,THLW_1D>::setNameTitle(const std::string& name,
195  const std::string& title)
196 {
197  m_h1->SetNameTitle(convertedRootName(name).c_str(),title.c_str());
198  m_h2->SetNameTitle(name.c_str(),title.c_str());
199  this->titleOrNameWasChanged();
200 }
201 
202 //____________________________________________________________________
203 template <class TH_1D, class THLW_1D>
204 void HistVal1D<TH_1D,THLW_1D>::fill(const double& x)
205 {
206  if (int(m_h2->GetXaxis()->FindBin(x))!=m_h1->GetXaxis()->FindBin(x)) {
207  //repeat test at x+epsilon to not get false positives since
208  //LWHists use float* internally rather than double*:
209  HistValFunctions::test("[TH1-level] GetXaxis()->FindBin()",m_h1->GetXaxis()->FindBin(x+1.0e-5),int(m_h2->GetXaxis()->FindBin(x+1.0e-5)));
210  }
211  m_h1->Fill(x);
212  m_h2->Fill(x);
213  this->binContentsChanged();
214 }
215 
216 //____________________________________________________________________
217 template <class TH_1D, class THLW_1D>
218 void HistVal1D<TH_1D,THLW_1D>::fill(const double& x, const double& w)
219 {
220  m_h1->Fill(x,w);
221  m_h2->Fill(x,w);
222  this->binContentsChanged();
223 }
224 
225 //____________________________________________________________________
226 template <class TH_1D, class THLW_1D>
227 void HistVal1D<TH_1D,THLW_1D>::setBinContent(unsigned bin, const double& content)
228 {
229  //FIXME: I can't figure out why I can't have the next ifdef uncommented!!!
230 // #ifndef LW_STRICT_ROOT_BEHAVIOUR
231  if (bin>getXAxis_NBins())//problems in root even in overflow bin
232  return;
233 // #else
234 // if (bin>getXAxis_NBins()+1)//problems in root even in overflow bin
235 // return;
236 // #endif
237  m_h1->SetBinContent(bin,content);
238  m_h2->SetBinContent(bin,content);
239  this->binContentsChanged();
240 }
241 
242 //____________________________________________________________________
243 template <class TH_1D, class THLW_1D>
244 void HistVal1D<TH_1D,THLW_1D>::setBinError(unsigned bin, const double& error)
245 {
246 #ifndef LW_STRICT_ROOT_BEHAVIOUR
247  if (bin>getXAxis_NBins()+1)
248  return;
249 #endif
250  m_h1->SetBinError(bin,error);
251  m_h2->SetBinError(bin,error);
252  this->binContentsChanged();
253 }
254 
255 //____________________________________________________________________
256 template <class TH_1D, class THLW_1D>
257 void HistVal1D<TH_1D,THLW_1D>::setBinContentAndError(unsigned bin, const double& content,const double& error)
258 {
259 #ifndef LW_STRICT_ROOT_BEHAVIOUR
260  if (bin>getXAxis_NBins()+1)
261  return;
262 #endif
263  if (bin>getXAxis_NBins()) {
264  //only fill errors (to align with if-statements above)... not great:
265  m_h1->SetBinError(bin,error);
266  m_h2->SetBinError(bin,error);
267  } else {
268  m_h1->SetBinContent(bin,content);
269  m_h1->SetBinError(bin,error);
270  m_h2->SetBinContentAndError(bin,content,error);
271  }
272  this->binContentsChanged();
273 }
274 
275 //____________________________________________________________________
276 template <class TH_1D, class THLW_1D>
277 void HistVal1D<TH_1D,THLW_1D>::compareBinContents() const
278 {
279  HistValFunctions::compareBinContents_1D(m_h1,m_h2);
280  //Also check the getbincontentanderror:
281  const int n = m_h1->GetNbinsX();
282  double cont2, err2;
283  for (int i=0;i<=n+1;++i) {
284  m_h2->GetBinContentAndError(i,cont2,err2);
285  if (!HistValFunctions::compatible(m_h1->GetBinContent(i),cont2)) {
286  std::ostringstream s;
287  s << "["<<typeid(TH_1D).name()<<" vs. "<<typeid(THLW_1D).name()<<"] Bin content from GetBinContentAndError [ibin="<<i<<", nbins="<<n<<", ninternalbins="<<n+2<<"]";
288  HistValFunctions::test(s.str(),m_h1->GetBinContent(i),cont2);
289  }
290  if (!HistValFunctions::compatible(m_h1->GetBinError(i),err2)) {
291  std::ostringstream s;
292  s << "["<<typeid(TH_1D).name()<<" vs. "<<typeid(THLW_1D).name()<<"] Bin error from GetBinContentAndError [ibin="<<i<<", nbins="<<n<<", ninternalbins="<<n+2<<"]";
293  HistValFunctions::test(s.str(),m_h1->GetBinError(i),err2);
294  }
295  }
296 
297 }
298 
299 //____________________________________________________________________
300 template <class TH_1D, class THLW_1D>
301 void HistVal1D<TH_1D,THLW_1D>::compareMetaData()
302 {
303  HistValFunctions::compareMetaData(m_h1, m_h2);
304 }
305 
306 //____________________________________________________________________
307 template <class TH_1D, class THLW_1D>
308 void HistVal1D<TH_1D,THLW_1D>::compareTH1s()
309 {
310  assert(m_h1->GetMarkerStyle()==m_h2->GetMarkerStyle());
311  std::string name1(m_h1->GetName());
312  TH1 * th1_gen(0);
313  if (!converted()) {
314  m_h1->SetName((name1+"tmp").c_str());
315  LWHistControls::setCleanupOnGetROOT(false);
316  m_h2->SetName("tmpname");
317  th1_gen = m_h2->getROOTHist();
318  LWHistControls::setCleanupOnGetROOT(true);
319  } else {
320  th1_gen = m_h2->getROOTHist();
321  }
322  if (!th1_gen)
323  HistValFunctions::testfailed("getROOTHist(..) returns null!");
324 
325  if (!converted())
326  HistValFunctions::test("[TH1-level] GetName()",std::string("tmpname"),th1_gen->GetName());
327  else
328  HistValFunctions::test("[TH1-level] GetName()",&(m_h1->GetName()[11]),th1_gen->GetName());//"stripping off "::trigger::"
329 
330  //Test various meta data including type and other state data:
331  HistValFunctions::test("[TH1-level] GetTitle()",m_h1->GetTitle(), th1_gen->GetTitle());
332  HistValFunctions::test("[TH1-level] ClassName()",m_h1->ClassName(), th1_gen->ClassName());
333 
334  //Should test axes also:
335  HistValFunctions::test("[TH1-level] GetXTitle()",m_h1->GetXaxis()->GetTitle(), th1_gen->GetXaxis()->GetTitle());
336  HistValFunctions::test("[TH1-level] GetYTitle()",m_h1->GetYaxis()->GetTitle(), th1_gen->GetYaxis()->GetTitle());
337  HistValFunctions::test("[TH1-level] GetZTitle()",m_h1->GetZaxis()->GetTitle(), th1_gen->GetZaxis()->GetTitle());
338 
339  HistValFunctions::compareBinContents_1D(m_h1,th1_gen);
340  HistValFunctions::compareFields(m_h1,th1_gen);
341 
342  // -> And all other supported state data...
343  HistValFunctions::test("[TH1-level] GetRMS()",m_h1->GetRMS(), th1_gen->GetRMS());
344  HistValFunctions::test("[TH1-level] GetMean()",m_h1->GetMean(), th1_gen->GetMean());
345  HistValFunctions::test("[TH1-level] GetMeanError()",m_h1->GetMeanError(), th1_gen->GetMeanError());
346  //HistValFunctions::test("[TH1-level] ComputeIntegral()",m_h1->ComputeIntegral(), th1_gen->ComputeIntegral());
347  HistValFunctions::test("[TH1-level] Integral()",m_h1->Integral(), th1_gen->Integral());
348 
349  //TODO: Compare more axes values (like min and max, nbins etc.)!!
350  const TArrayD * h1_xbins = m_h1->GetXaxis()->GetXbins();
351  const TArrayD * gen_xbins = th1_gen->GetXaxis()->GetXbins();
352  if ((h1_xbins!=0)!=(gen_xbins!=0))
353  HistValFunctions::testfailed("2D hist has inconsistent presence of xbins");
354  if (h1_xbins&&gen_xbins)
355  HistValFunctions::test("[TH1-level] GetXaxis()->GetXbins()->GetSize()",h1_xbins->GetSize(), gen_xbins->GetSize());
356 
357  HistValFunctions::compareBinContents_1D(m_h1, m_h2);
358  HistValFunctions::compareBinContents_1D(th1_gen, m_h2);
359  HistValFunctions::compareBinContents_1D(th1_gen, m_h1);
360  HistValFunctions::compareMetaData(static_cast<TH_1D*>(th1_gen), m_h2,true/*ignore name*/);
361  HistValFunctions::compareMetaData(m_h1, m_h2,true/*ignore name*/);
362 
363 
364  if (!converted()) {
365  LWHistVal::clearKeptROOTHist(m_h2);//deletes th1_gen
366  m_h1->SetName(name1.c_str());
367  m_h2->SetName(name1.c_str());
368  }
369 
370 }
371 
372 //____________________________________________________________________
373 template <class TH_1D, class THLW_1D>
374 void HistVal1D<TH_1D,THLW_1D>::compareFastLoop()
375 {
376  const unsigned nbins = m_h2->GetNbinsX();
377  std::vector<std::pair<unsigned,std::pair<double,double> > > active_bins_direct, active_bins_fastloop;
378  unsigned ibin;
379  double c,e;
380  for (ibin=0;ibin<=nbins+1;++ibin) {
381  c = m_h1->GetBinContent(ibin);
382  e = m_h1->GetBinError(ibin);
383  if (c!=0||e!=0)
384  active_bins_direct.push_back(std::pair<unsigned,std::pair<double,double> >(ibin,std::make_pair(c,e)));
385  }
386  m_h2->resetActiveBinLoop();
387  while(m_h2->getNextActiveBin(ibin, c, e))
388  active_bins_fastloop.push_back(std::pair<unsigned,std::pair<double,double> >(ibin,std::make_pair(c,e)));
389  if (!HistValFunctions::compatible(active_bins_direct,active_bins_fastloop)) {
390  std::cout<<"--> Correct bins: "<< HistValFunctions::toString(active_bins_direct)<<std::endl;;
391  std::cout<<"--> Fastloop bins: "<< HistValFunctions::toString(active_bins_fastloop)<<std::endl;;
392  HistValFunctions::testfailed("Fast-looping did not return correct active bins");
393  }
394 }