HistCache.cxx
Go to the documentation of this file.
2 
4 
5 #include "TH2.h"
6 
7 #include <iostream>
8 
9 namespace ana
10 {
11  std::multimap<int, std::unique_ptr<TH1D>> HistCache::fgMap;
12  std::multimap<int, std::unique_ptr<TH1F>> HistCache::fgMapF;
13  std::multimap<std::pair<int, int>, std::unique_ptr<TH2D>> HistCache::fgMap2D;
14  std::multimap<std::pair<int, int>, std::unique_ptr<TH2F>> HistCache::fgMap2F;
15 
16  int HistCache::fgOut = 0;
17  int HistCache::fgIn = 0;
18 
19  long HistCache::fgEstMemUsage = 0;
20 
21  //---------------------------------------------------------------------
23  {
24  ++fgOut;
25 
26  // Look in the cache
27  auto it = fgMap.find(bins.ID());
28  if(it != fgMap.end()){
29  TH1D* ret = it->second.release();
30  fgMap.erase(it);
31  ret->Reset();
32  ret->SetTitle(title.c_str());
33 
34  fgEstMemUsage -= 16*bins.NBins();
35 
36  assert(bins.NBins() == ret->GetNbinsX());
37 
38  return ret;
39  }
40 
41  // If not, create a new one directly
42  return MakeTH1D(UniqueName().c_str(), title.c_str(), bins);
43  }
44 
45  //---------------------------------------------------------------------
47  {
48  ++fgOut;
49 
50  // Look in the cache
51  auto it = fgMapF.find(bins.ID());
52  if(it != fgMapF.end()){
53  TH1F* ret = it->second.release();
54  fgMapF.erase(it);
55  ret->Reset();
56  ret->SetTitle(title.c_str());
57 
58  fgEstMemUsage -= 8*bins.NBins();
59 
60  assert(bins.NBins() == ret->GetNbinsX());
61 
62  return ret;
63  }
64 
65  // If not, create a new one directly
66  return MakeTH1F(UniqueName().c_str(), title.c_str(), bins);
67  }
68 
69  //---------------------------------------------------------------------
70  TH1D* HistCache::New(const std::string& title, const TAxis* bins)
71  {
72  return New(title, Binning::FromTAxis(bins));
73  }
74 
75  //---------------------------------------------------------------------
76  TH1F* HistCache::NewF(const std::string& title, const TAxis* bins)
77  {
78  return NewF(title, Binning::FromTAxis(bins));
79  }
80 
81  //---------------------------------------------------------------------
83  {
84  ++fgOut;
85  std::pair<int, int> IDs (xbins.ID(), ybins.ID());
86  auto it = fgMap2D.find(IDs);
87  if(it != fgMap2D.end()){
88  TH2D* ret = it->second.release();
89  fgMap2D.erase(it);
90  ret->Reset();
91  ret->SetTitle(title.c_str());
92  fgEstMemUsage -= 16*xbins.NBins()*ybins.NBins();
93 
94  assert(xbins.NBins() == ret->GetNbinsX());
95  assert(ybins.NBins() == ret->GetNbinsY());
96 
97  return ret;
98  }
99 
100  return MakeTH2D(UniqueName().c_str(), title.c_str(), xbins, ybins);
101  }
102 
103  //---------------------------------------------------------------------
105  {
106  ++fgOut;
107  std::pair<int, int> IDs (xbins.ID(), ybins.ID());
108  auto it = fgMap2F.find(IDs);
109  if(it != fgMap2F.end()){
110  TH2F* ret = it->second.release();
111  fgMap2F.erase(it);
112  ret->Reset();
113  ret->SetTitle(title.c_str());
114  fgEstMemUsage -= 8*xbins.NBins()*ybins.NBins();
115 
116  assert(xbins.NBins() == ret->GetNbinsX());
117  assert(ybins.NBins() == ret->GetNbinsY());
118 
119  return ret;
120  }
121 
122  return MakeTH2F(UniqueName().c_str(), title.c_str(), xbins, ybins);
123  }
124 
125  //---------------------------------------------------------------------
126  TH2D* HistCache::NewTH2D(const std::string& title, const TAxis* xbins, const TAxis* ybins)
127  {
128  return NewTH2D(title, Binning::FromTAxis(xbins), Binning::FromTAxis(ybins));
129  }
130 
131  //---------------------------------------------------------------------
132  TH2F* HistCache::NewTH2F(const std::string& title, const TAxis* xbins, const TAxis* ybins)
133  {
134  return NewTH2F(title, Binning::FromTAxis(xbins), Binning::FromTAxis(ybins));
135  }
136 
137  //---------------------------------------------------------------------
138  TH1D* HistCache::Copy(const TH1D* h)
139  {
140  TH1D* ret = New(h->GetTitle(), h->GetXaxis());
141  *ret = *h;
142  ret->SetDirectory(0);
143  return ret;
144  }
145 
146  //---------------------------------------------------------------------
147  TH1D* HistCache::Copy(const TH1D* h, const Binning& bins)
148  {
149  assert(bins.NBins() == h->GetNbinsX());
150 
151  TH1D* ret = New(h->GetTitle(), bins);
152  *ret = *h;
153  ret->SetDirectory(0);
154  return ret;
155  }
156 
157  //---------------------------------------------------------------------
158  TH1F* HistCache::Copy(const TH1F* h)
159  {
160  TH1F* ret = NewF(h->GetTitle(), h->GetXaxis());
161  *ret = *h;
162  ret->SetDirectory(0);
163  return ret;
164  }
165 
166  //---------------------------------------------------------------------
167  TH1F* HistCache::Copy(const TH1F* h, const Binning& bins)
168  {
169  assert(bins.NBins() == h->GetNbinsX());
170 
171  TH1F* ret = NewF(h->GetTitle(), bins);
172  *ret = *h;
173  ret->SetDirectory(0);
174  return ret;
175  }
176 
177  //---------------------------------------------------------------------
178  TH2D* HistCache::Copy(const TH2D* h)
179  {
180  TH2D* ret = NewTH2D(h->GetTitle(), h->GetXaxis(), h->GetYaxis());
181  *ret = *h;
182  ret->SetDirectory(0);
183  return ret;
184  }
185 
186  //---------------------------------------------------------------------
187  TH2D* HistCache::Copy(const TH2D* h, const Binning& binsX, const Binning& binsY)
188  {
189  assert(binsX.NBins() == h->GetNbinsX());
190  assert(binsY.NBins() == h->GetNbinsY());
191 
192  TH2D* ret = NewTH2D(h->GetTitle(), binsX, binsY);
193  *ret = *h;
194  ret->SetDirectory(0);
195  return ret;
196  }
197 
198  //---------------------------------------------------------------------
199  TH2F* HistCache::Copy(const TH2F* h)
200  {
201  TH2F* ret = NewTH2F(h->GetTitle(), h->GetXaxis(), h->GetYaxis());
202  *ret = *h;
203  ret->SetDirectory(0);
204  return ret;
205  }
206 
207  //---------------------------------------------------------------------
208  TH2F* HistCache::Copy(const TH2F* h, const Binning& binsX, const Binning& binsY)
209  {
210  assert(binsX.NBins() == h->GetNbinsX());
211  assert(binsY.NBins() == h->GetNbinsY());
212 
213  TH2F* ret = NewTH2F(h->GetTitle(), binsX, binsY);
214  *ret = *h;
215  ret->SetDirectory(0);
216  return ret;
217  }
218 
219  //---------------------------------------------------------------------
220  void HistCache::Delete(TH1D*& h)
221  {
222  if(!h) return;
223 
224  assert(!h->GetDirectory());
225 
226  HistCache::Delete(h, Binning::FromTAxis(h->GetXaxis()));
227  }
228 
229  //---------------------------------------------------------------------
230  void HistCache::Delete(TH1D*& h, const Binning& bins)
231  {
232  if(!h) return;
233 
234  assert(!h->GetDirectory());
235 
236  assert(h->GetNbinsX() == bins.NBins());
237 
238  ++fgIn;
239 
240  fgMap.emplace(bins.ID(), std::unique_ptr<TH1D>(h));
241 
242  fgEstMemUsage += 16*h->GetNbinsX();
243  CheckMemoryUse();
244 
245  h = 0;
246  }
247 
248  //---------------------------------------------------------------------
249  void HistCache::Delete(TH1F*& h)
250  {
251  if(!h) return;
252 
253  assert(!h->GetDirectory());
254 
255  HistCache::Delete(h, Binning::FromTAxis(h->GetXaxis()));
256  }
257 
258  //---------------------------------------------------------------------
259  void HistCache::Delete(TH1F*& h, const Binning& bins)
260  {
261  if(!h) return;
262 
263  assert(!h->GetDirectory());
264 
265  assert(bins.NBins() == h->GetNbinsX());
266 
267  ++fgIn;
268 
269  fgMapF.emplace(bins.ID(), std::unique_ptr<TH1F>(h));
270 
271  fgEstMemUsage += 8*h->GetNbinsX();
272  CheckMemoryUse();
273 
274  h = 0;
275  }
276 
277  //---------------------------------------------------------------------
278  void HistCache::Delete(TH2D*& h)
279  {
280  if(!h) return;
281 
282  assert(!h->GetDirectory());
283 
285  Binning::FromTAxis(h->GetXaxis()),
286  Binning::FromTAxis(h->GetYaxis()));
287  }
288 
289  //---------------------------------------------------------------------
290  void HistCache::Delete(TH2D*& h, const Binning& binsX, const Binning& binsY)
291  {
292  if(!h) return;
293 
294  assert(!h->GetDirectory());
295 
296  assert(binsX.NBins() == h->GetNbinsX());
297  assert(binsY.NBins() == h->GetNbinsY());
298 
299  ++fgIn;
300 
301  fgMap2D.emplace(std::make_pair(binsX.ID(), binsY.ID()),
302  std::unique_ptr<TH2D>(h));
303 
304  fgEstMemUsage += 16*h->GetNbinsX()*h->GetNbinsY();
305  CheckMemoryUse();
306 
307  h = 0;
308  }
309 
310  //---------------------------------------------------------------------
311  void HistCache::Delete(TH2F*& h)
312  {
313  if(!h) return;
314 
315  assert(!h->GetDirectory());
316 
318  Binning::FromTAxis(h->GetXaxis()),
319  Binning::FromTAxis(h->GetYaxis()));
320  }
321 
322  //---------------------------------------------------------------------
323  void HistCache::Delete(TH2F*& h, const Binning& binsX, const Binning& binsY)
324  {
325  if(!h) return;
326 
327  assert(!h->GetDirectory());
328 
329  assert(binsX.NBins() == h->GetNbinsX());
330  assert(binsY.NBins() == h->GetNbinsY());
331 
332  ++fgIn;
333 
334  fgMap2F.emplace(std::make_pair(binsX.ID(), binsY.ID()),
335  std::unique_ptr<TH2F>(h));
336 
337  fgEstMemUsage += 8*h->GetNbinsX()*h->GetNbinsY();
338  CheckMemoryUse();
339 
340  h = 0;
341  }
342 
343  //---------------------------------------------------------------------
345  {
346  if(fgEstMemUsage > 500l*1024*1024){
347  std::cerr << "Warning! HistCache memory usage exceeds 500MB. "
348  << "That probably means histograms are being returned "
349  << "to the cache that weren't originally handed out by it. "
350  << std::endl;
351  PrintStats();
352  std::cerr << "Now clearing cache. This could take a long time..."
353  << std::endl;
354  ClearCache();
355  std::cerr << "Done clearing cache" << std::endl;
356  }
357  }
358 
359  //---------------------------------------------------------------------
361  {
362  fgMap.clear();
363  fgMapF.clear();
364  fgMap2D.clear();
365  fgMap2F.clear();
366  fgEstMemUsage = 0;
367  fgOut = 0;
368  fgIn = 0;
369  }
370 
371  //---------------------------------------------------------------------
373  {
374  // Count number of unique keys
375  std::set<int> keys;
376  for(auto& it: fgMap) keys.insert(it.first);
377  for(auto& it: fgMapF) keys.insert(it.first);
378  std::set<std::pair<int, int>> keys2;
379  for(auto& it: fgMap2D) keys2.insert(it.first);
380  for(auto& it: fgMap2F) keys2.insert(it.first);
381 
382  std::cout << "Gave out " << fgOut << " histograms, got back "
383  << fgIn << " of them (" << fgOut-fgIn << " lost), in "
384  << keys.size()+keys2.size() << " different shapes." << std::endl
385  << "Holding " << fgMap.size()+fgMap2D.size()
386  << " histograms for an estimated memory usage of "
387  << fgEstMemUsage << " bytes." << std::endl;
388  }
389 
390  //---------------------------------------------------------------------
392  {
393  for(auto& it: fgMap) it.second.release();
394  for(auto& it: fgMapF) it.second.release();
395  for(auto& it: fgMap2D) it.second.release();
396  for(auto& it: fgMap2F) it.second.release();
397 
398  ClearCache();
399  }
400 }
TH2D * MakeTH2D(const char *name, const char *title, const Binning &binsx, const Binning &binsy)
Definition: Utilities.cxx:345
keys
Reco plots.
Definition: caf_analysis.py:46
static std::multimap< std::pair< int, int >, std::unique_ptr< TH2D > > fgMap2D
Definition: HistCache.h:69
Represent the binning of a Spectrum&#39;s x-axis.
Definition: Binning.h:16
Cuts and Vars for the 2020 FD DiF Study.
Definition: CutFlow_header.h:5
set< int >::iterator it
static TH1D * Copy(const TH1D *h)
Definition: HistCache.cxx:138
static Binning FromTAxis(const TAxis *ax)
Definition: Binning.cxx:122
OStream cerr
Definition: OStream.cxx:7
static long fgEstMemUsage
Definition: HistCache.h:74
std::pair< Spectrum *, CheatDecomp * > make_pair(SpectrumLoaderBase &loader_data, SpectrumLoaderBase &loader_mc, HistAxis *axis, Cut *cut, const SystShifts &shift, const Var &wei)
Definition: DataMCLoad.C:335
static TH2F * NewTH2F(const std::string &title, const Binning &xbins, const Binning &ybins)
Definition: HistCache.cxx:104
static std::multimap< int, std::unique_ptr< TH1F > > fgMapF
Definition: HistCache.h:68
static void LeakAll()
for debugging shutdown crashes
Definition: HistCache.cxx:391
static TH2D * NewTH2D(const std::string &title, const Binning &xbins, const Binning &ybins)
Definition: HistCache.cxx:82
static std::multimap< std::pair< int, int >, std::unique_ptr< TH2F > > fgMap2F
Definition: HistCache.h:70
static void Delete(TH1D *&h)
Definition: HistCache.cxx:220
static int fgOut
Definition: HistCache.h:72
static TH1F * NewF(const std::string &title, const Binning &bins)
Definition: HistCache.cxx:46
OStream cout
Definition: OStream.cxx:6
TH1D * MakeTH1D(const char *name, const char *title, const Binning &bins)
Definition: Utilities.cxx:333
const Binning bins
Definition: NumuCC_CPiBin.h:8
TH2F * MakeTH2F(const char *name, const char *title, const Binning &binsx, const Binning &binsy)
Definition: Utilities.cxx:353
const Binning ybins
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
static int fgIn
Definition: HistCache.h:72
static void PrintStats()
Definition: HistCache.cxx:372
const int xbins
Definition: MakePlots.C:82
int NBins() const
Definition: Binning.h:25
static void CheckMemoryUse()
Definition: HistCache.cxx:344
assert(nhit_max >=nhit_nbins)
static TH1D * New(const std::string &title, const Binning &bins)
Definition: HistCache.cxx:22
static std::multimap< int, std::unique_ptr< TH1D > > fgMap
Definition: HistCache.h:67
int ID() const
Definition: Binning.h:40
static void ClearCache()
Definition: HistCache.cxx:360
std::string UniqueName()
Return a different string each time, for creating histograms.
Definition: Utilities.cxx:30
TH1F * MakeTH1F(const char *name, const char *title, const Binning &bins)
Definition: Utilities.cxx:339