1 /**************************************************************************
2 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 * Container class for histogram objects. Currenly can handle
22 * Histograms can be stored in groups. For this the parent group is
23 * included inside the histogram name, i.e. /base/inheriting/histogram.
24 * In case just the histogram name is given, it is assumed that the
25 * histogram is stored at the top level.
27 * Author: Markus Fasel
37 #include <THnSparse.h>
38 #include <THashList.h>
39 #include <TObjArray.h>
40 #include <TObjString.h>
45 #include "AliEMCalHistoContainer.h"
47 ClassImp(EMCalTriggerPtAnalysis::AliEMCalHistoContainer)
49 namespace EMCalTriggerPtAnalysis {
51 //______________________________________________________________________________
52 AliEMCalHistoContainer::AliEMCalHistoContainer():
58 * Default constructor, only initialising pointers with 0
62 //______________________________________________________________________________
63 AliEMCalHistoContainer::AliEMCalHistoContainer(const char *name):
64 TNamed(name, Form("Histogram container %s", name)),
69 * Main constructor, creating also a list for the histograms
71 * @param name: Name of the object (list named accordingly)
73 fHistos = new THashList();
74 fHistos->SetName(Form("histos%s", name));
78 //______________________________________________________________________________
79 AliEMCalHistoContainer::~AliEMCalHistoContainer(){
81 * Destructor, deletes the list of histograms if it is the owner
83 if(fHistos && fIsOwner) delete fHistos;
86 //______________________________________________________________________________
87 void AliEMCalHistoContainer::CreateHistoGroup(const char *groupname, const char *parent) throw(HistoContainerContentException) {
89 * Create a new group of histograms within a parent group. Groups are represented as list. The default parent is
90 * always the top list. List name structure accouding to unix paths (i.e. top list /, hirarchies separated by /).
92 * @param groupname: Name of the new group
93 * @param parent (@default "/"): Name of the parent group
94 * @throw HistoContainerContentException
96 THashList *parentgroup = FindGroup(parent);
97 if(!parentgroup) throw HistoContainerContentException(NULL, parent, HistoContainerContentException::kGroupException);
98 THashList *childgroup = new THashList();
99 childgroup->SetName(groupname);
100 parentgroup->Add(childgroup);
103 //______________________________________________________________________________
104 void AliEMCalHistoContainer::CreateTH1(const char *name, const char *title, int nbins, double xmin, double xmax) throw(HistoContainerContentException){
106 * Create a new TH1 within the container. The histogram name also contains the parent group(s) according to the common
109 * @param name: Name of the histogram
110 * @param title: Title of the histogram
111 * @param nbins: number of bins
112 * @param xmin: min. value of the range
113 * @param xmax: max. value of the range
114 * @throw HistoContainerContentException
116 TString dirname(basename(name)), hname(histname(name));
117 THashList *parent(FindGroup(dirname.Data()));
119 throw HistoContainerContentException(NULL, dirname.Data(), HistoContainerContentException::kGroupException);
120 if(parent->FindObject(hname.Data()))
121 throw HistoContainerContentException(hname.Data(), dirname.Data(), HistoContainerContentException::kHistDuplicationException);
122 parent->Add(new TH1D(hname.Data(), title, nbins, xmin, xmax));
125 //______________________________________________________________________________
126 void AliEMCalHistoContainer::CreateTH1(const char *name, const char *title, int nbins, const double *xbins) throw(HistoContainerContentException){
128 * Create a new TH1 within the container. The histogram name also contains the parent group(s) according to the common
131 * @param name: Name of the histogram
132 * @param title: Title of the histogram
133 * @param nbins: number of bins
134 * @param xbins: array of bin limits
135 * @throw HistoContainerContentException
137 TString dirname(basename(name)), hname(histname(name));
138 THashList *parent(FindGroup(dirname));
140 throw HistoContainerContentException(NULL, dirname.Data(), HistoContainerContentException::kGroupException);
141 if(parent->FindObject(hname.Data()))
142 throw HistoContainerContentException(hname, dirname.Data(), HistoContainerContentException::kHistDuplicationException);
143 parent->Add(new TH1D(hname.Data(), title, nbins, xbins));
146 //______________________________________________________________________________
147 void AliEMCalHistoContainer::CreateTH1(const char *name, const char *title, const TArrayD &xbins) throw(HistoContainerContentException){
149 * Create a new TH1 within the container. The histogram name also contains the parent group(s) according to the common
152 * @param name: Name of the histogram
153 * @param title: Title of the histogram
154 * @param xbins: array of bin limits (contains also number of bins)
155 * @throw HistoContainerContentException
157 TString dirname(basename(name)), hname(histname(name));
158 THashList *parent(FindGroup(dirname));
160 throw HistoContainerContentException(NULL, dirname.Data(), HistoContainerContentException::kGroupException);
161 if(parent->FindObject(hname.Data()))
162 throw HistoContainerContentException(hname.Data(), dirname.Data(), HistoContainerContentException::kHistDuplicationException);
163 parent->Add(new TH1D(hname.Data(), title, xbins.GetSize()-1, xbins.GetArray()));
166 //______________________________________________________________________________
167 void AliEMCalHistoContainer::CreateTH2(const char *name, const char *title,
168 int nbinsx, double xmin, double xmax, int nbinsy, double ymin, double ymax) throw(HistoContainerContentException){
170 * Create a new TH2 within the container. The histogram name also contains the parent group(s) according to the common
173 * @param name: Name of the histogram
174 * @param title: Title of the histogram
175 * @param nbinsx: number of bins in x-direction
176 * @param xmin: min. value of the range in x-direction
177 * @param xmax: max. value of the range in x-direction
178 * @param nbinsy: number of bins in y-direction
179 * @param ymin: min. value of the range in y-direction
180 * @param ymax: max. value of the range in y-direction
181 * @throw HistoContainerContentException
183 TString dirname(basename(name)), hname(histname(name));
184 THashList *parent(FindGroup(dirname.Data()));
186 throw HistoContainerContentException(NULL, dirname.Data(), HistoContainerContentException::kGroupException);
187 if(parent->FindObject(hname.Data()))
188 throw HistoContainerContentException(hname.Data(), dirname.Data(), HistoContainerContentException::kHistDuplicationException);
189 parent->Add(new TH2D(hname.Data(), title, nbinsx, xmin, xmax, nbinsy, ymin, ymax));
192 //______________________________________________________________________________
193 void AliEMCalHistoContainer::CreateTH2(const char *name, const char *title,
194 int nbinsx, const double *xbins, int nbinsy, const double *ybins) throw(HistoContainerContentException){
196 * Create a new TH2 within the container. The histogram name also contains the parent group(s) according to the common
199 * @param name: Name of the histogram
200 * @param title: Title of the histogram
201 * @param nbinsx: number of bins in x-direction
202 * @param xbins: array of bin limits in x-direction
203 * @param nbinsy: number of bins in y-direction
204 * @param ybins: array of bin limits in y-direction
205 * @throw HistoContainerContentException
207 TString dirname(basename(name)), hname(histname(name));
208 THashList *parent(FindGroup(dirname.Data()));
210 throw HistoContainerContentException(NULL, dirname.Data(), HistoContainerContentException::kGroupException);
211 if(parent->FindObject(hname.Data()))
212 throw HistoContainerContentException(hname.Data(), dirname.Data(), HistoContainerContentException::kHistDuplicationException);
213 parent->Add(new TH2D(hname.Data(), title, nbinsx, xbins, nbinsy, ybins));
216 //______________________________________________________________________________
217 void AliEMCalHistoContainer::CreateTH2(const char *name, const char *title, const TArrayD &xbins, const TArrayD &ybins) throw(HistoContainerContentException){
219 * Create a new TH2 within the container. The histogram name also contains the parent group(s) according to the common
222 * @param name: Name of the histogram
223 * @param title: Title of the histogram
224 * @param xbins: array of bin limits in x-direction (contains also the number of bins)
225 * @param ybins: array of bin limits in y-direction (contains also the number of bins)
226 * @throw HistoContainerContentException
228 TString dirname(basename(name)), hname(histname(name));
229 THashList *parent(FindGroup(dirname.Data()));
231 throw HistoContainerContentException(NULL, dirname.Data(), HistoContainerContentException::kGroupException);
232 if(parent->FindObject(hname.Data()))
233 throw HistoContainerContentException(hname.Data(), dirname.Data(), HistoContainerContentException::kHistDuplicationException);
234 parent->Add(new TH2D(hname.Data(), title, xbins.GetSize() - 1, xbins.GetArray(), ybins.GetSize() - 1, ybins.GetArray()));
237 //______________________________________________________________________________
238 void AliEMCalHistoContainer::CreateTH3(const char* name, const char* title, int nbinsx, double xmin, double xmax,
239 int nbinsy, double ymin, double ymax, int nbinsz, double zmin, double zmax) throw (HistoContainerContentException) {
241 * Create a new TH3 within the container. The histogram name also contains the parent group(s) according to the common
244 * @param nbinsx: number of bins in x-direction
245 * @param xmin: min. value of the range in x-direction
246 * @param xmax: max. value of the range in x-direction
247 * @param nbinsy: number of bins in y-direction
248 * @param ymin: min. value of the range in y-direction
249 * @param ymax: max. value of the range in y-direction
250 * @param nbinsz: number of bins in z-direction
251 * @param zmin: min. value of the range in z-direction
252 * @param zmax: max. value of the range in z-direction
253 * @throw HistoContainerContentException
255 TString dirname(basename(name)), hname(histname(name));
256 THashList *parent(FindGroup(dirname.Data()));
258 throw HistoContainerContentException(NULL, dirname.Data(), HistoContainerContentException::kGroupException);
259 if(parent->FindObject(hname.Data()))
260 throw HistoContainerContentException(hname.Data(), dirname.Data(), HistoContainerContentException::kHistDuplicationException);
261 parent->Add(new TH3D(hname.Data(), title, nbinsx, xmin, xmax, nbinsy, ymin, ymax, nbinsz, zmin, zmax));
264 //______________________________________________________________________________
265 void AliEMCalHistoContainer::CreateTH3(const char* name, const char* title, int nbinsx, const double* xbins,
266 int nbinsy, const double* ybins, int nbinsz, const double* zbins) throw (HistoContainerContentException) {
268 * Create a new TH3 within the container. The histogram name also contains the parent group(s) according to the common
271 * @param name: Name of the histogram
272 * @param title: Title of the histogram
273 * @param nbinsx: number of bins in x-direction
274 * @param xbins: array of bin limits in x-direction
275 * @param nbinsy: number of bins in y-direction
276 * @param ybins: array of bin limits in y-direction
277 * @param nbinsz: number of bins in z-direction
278 * @param zbins: array of bin limits in z-direction
279 * @throw HistoContainerContentException
281 TString dirname(basename(name)), hname(histname(name));
282 THashList *parent(FindGroup(dirname.Data()));
284 throw HistoContainerContentException(NULL, dirname.Data(), HistoContainerContentException::kGroupException);
285 if(parent->FindObject(hname.Data()))
286 throw HistoContainerContentException(hname.Data(), dirname.Data(), HistoContainerContentException::kHistDuplicationException);
287 parent->Add(new TH3D(hname.Data(), title, nbinsx, xbins, nbinsy, ybins, nbinsz, zbins));
290 //______________________________________________________________________________
291 void AliEMCalHistoContainer::CreateTH3(const char* name, const char* title, const TArrayD& xbins, const TArrayD& ybins,
292 const TArrayD& zbins) throw (HistoContainerContentException) {
294 * Create a new TH3 within the container. The histogram name also contains the parent group(s) according to the common
297 * @param name: Name of the histogram
298 * @param title: Title of the histogram
299 * @param xbins: array of bin limits in x-direction (contains also the number of bins)
300 * @param ybins: array of bin limits in y-direction (contains also the number of bins)
301 * @param zbins: array of bin limits in z-direction (contains also the number of bins)
302 * @throw HistoContainerContentException
304 TString dirname(basename(name)), hname(histname(name));
305 THashList *parent(FindGroup(dirname.Data()));
307 throw HistoContainerContentException(NULL, dirname.Data(), HistoContainerContentException::kGroupException);
308 if(parent->FindObject(hname.Data()))
309 throw HistoContainerContentException(hname.Data(), dirname.Data(), HistoContainerContentException::kHistDuplicationException);
310 parent->Add(new TH3D(hname.Data(), title, xbins.GetSize()-1, xbins.GetArray(), ybins.GetSize()-1, ybins.GetArray(), zbins.GetSize()-1, zbins.GetArray()));
313 //______________________________________________________________________________
314 void AliEMCalHistoContainer::CreateTHnSparse(const char *name, const char *title,
315 int ndim, const int *nbins, const double *min, const double *max) throw(HistoContainerContentException){
317 * Create a new THnSparse within the container. The histogram name also contains the parent group(s) according to the common
320 * @param name: Name of the histogram
321 * @param title: Title of the histogram
322 * @param ndim: Number of dimensions
323 * @param nbins: Number of bins per dimension
324 * @param min: min. value of the range for each dimension
325 * @param max: max. value of the range for each dimension
326 * @throw HistoContainerContentException
328 TString dirname(basename(name)), hname(histname(name));
329 THashList *parent(FindGroup(dirname.Data()));
331 throw HistoContainerContentException(NULL, dirname.Data(), HistoContainerContentException::kGroupException);
332 if(parent->FindObject(hname.Data()))
333 throw HistoContainerContentException(hname.Data(), dirname.Data(), HistoContainerContentException::kHistDuplicationException);
334 parent->Add(new THnSparseD(hname.Data(), title, ndim, nbins, min, max));
337 //______________________________________________________________________________
338 void AliEMCalHistoContainer::CreateTHnSparse(const char *name, const char *title, int ndim, const TAxis **axes) throw(HistoContainerContentException){
340 * Create a new THnSparse within the container. The histogram name also contains the parent group(s) according to the common
343 * @param name: Name of the histogram
344 * @param title: Title of the histogram
345 * @param ndim: Number of dimensions
346 * @param axes: Array of pointers to TAxis for containing the axis definition for each dimension
347 * @throw HistoContainerContentException
349 TString dirname(basename(name)), hname(histname(name));
350 THashList *parent(FindGroup(dirname.Data()));
352 throw HistoContainerContentException(NULL, dirname.Data(), HistoContainerContentException::kGroupException);
353 if(parent->FindObject(hname))
354 throw HistoContainerContentException(hname.Data(), dirname.Data(), HistoContainerContentException::kHistDuplicationException);
355 TArrayD xmin(ndim), xmax(ndim);
357 for(int idim = 0; idim < ndim; ++idim){
358 const TAxis &myaxis = *(axes[idim]);
359 nbins[idim] = myaxis.GetNbins();
360 xmin[idim] = myaxis.GetXmin();
361 xmax[idim] = myaxis.GetXmax();
363 THnSparseD *hsparse = new THnSparseD(hname.Data(), title, ndim, nbins.GetArray(), xmin.GetArray(), xmax.GetArray());
364 for(int id = 0; id < ndim; ++id)
365 *(hsparse->GetAxis(id)) = *(axes[id]);
366 parent->Add(hsparse);
369 //______________________________________________________________________________
370 void AliEMCalHistoContainer::SetObject(TObject * const o, const char *group) throw(HistoContainerContentException){
372 * Set a new group into the container into the parent group
374 * @param o: the object ot be included
377 THashList *parent(FindGroup(group));
379 throw HistoContainerContentException(NULL, strcmp(group, "/") ? group : "", HistoContainerContentException::kGroupException);
380 if(parent->FindObject(o->GetName()))
381 throw HistoContainerContentException(o->GetName(), strcmp(group, "/") ? group : "", HistoContainerContentException::kHistDuplicationException);
382 if(!(dynamic_cast<THnBase *>(o) || dynamic_cast<TH1 *>(o)))
383 throw HistoContainerContentException(o->GetName(), strcmp(group, "/") ? group : "", HistoContainerContentException::kTypeException);
387 //______________________________________________________________________________
388 void AliEMCalHistoContainer::FillTH1(const char *name, double x, double weight) throw(HistoContainerContentException){
390 * Fill a 1D histogram within the container. The histogram name also contains the parent group(s) according to the common
393 * @param name: Name of the histogram
394 * @param x: x-coordinate
395 * @param weight (@default 1): optional weight of the entry
396 * @throw HistoContainerContentException
398 TString dirname(basename(name)), hname(histname(name));
399 THashList *parent(FindGroup(dirname.Data()));
401 throw HistoContainerContentException(NULL, dirname.Data(), HistoContainerContentException::kGroupException);
402 TH1 *hist = dynamic_cast<TH1 *>(parent->FindObject(hname.Data()));
404 throw HistoContainerContentException(hname.Data(), dirname.Data(), HistoContainerContentException::kHistNotFoundException);
405 hist->Fill(x, weight);
408 //______________________________________________________________________________
409 void AliEMCalHistoContainer::FillTH2(const char *name, double x, double y, double weight) throw(HistoContainerContentException){
411 * Fill a 2D histogram within the container. The histogram name also contains the parent group(s) according to the common
414 * @param name: Name of the histogram
415 * @param x: x-coordinate
416 * @param y: y-coordinate
417 * @param weight (@default 1): optional weight of the entry
418 * @throw HistoContainerContentException
420 TString dirname(basename(name)), hname(histname(name));
421 THashList *parent(FindGroup(dirname.Data()));
423 throw HistoContainerContentException(NULL, dirname.Data(), HistoContainerContentException::kGroupException);
424 TH2 *hist = dynamic_cast<TH2 *>(parent->FindObject(hname.Data()));
426 throw HistoContainerContentException(hname.Data(), dirname.Data(), HistoContainerContentException::kHistNotFoundException);
427 hist->Fill(x, y, weight);
430 //______________________________________________________________________________
431 void AliEMCalHistoContainer::FillTH2(const char *name, double *point, double weight) throw(HistoContainerContentException){
433 * Fill a 2D histogram within the container. The histogram name also contains the parent group(s) according to the common
436 * @param name: Name of the histogram
437 * @param point: coordinates of the data
438 * @param weight (@default 1): optional weight of the entry
439 * @throw HistoContainerContentException
441 TString dirname(basename(name)), hname(histname(name));
442 THashList *parent(FindGroup(dirname.Data()));
444 throw HistoContainerContentException(NULL, dirname.Data(), HistoContainerContentException::kGroupException);
445 TH2 *hist = dynamic_cast<TH2 *>(parent->FindObject(hname.Data()));
447 throw HistoContainerContentException(hname.Data(), dirname.Data(), HistoContainerContentException::kHistNotFoundException);
448 hist->Fill(point[0], point[1], weight);
451 //______________________________________________________________________________
452 void AliEMCalHistoContainer::FillTH3(const char* name, double x, double y, double z, double weight) throw (HistoContainerContentException) {
454 * Fill a 3D histogram within the container. The histogram name also contains the parent group(s) according to the common
457 * @param name: Name of the histogram
458 * @param x: x-coordinate
459 * @param y: y-coordinate
460 * @param z: z-coordinate
461 * @param weight (@default 1): optional weight of the entry
462 * @throw HistoContainerContentException
464 TString dirname(basename(name)), hname(histname(name));
465 THashList *parent(FindGroup(dirname.Data()));
467 throw HistoContainerContentException(NULL, dirname.Data(), HistoContainerContentException::kGroupException);
468 TH3 *hist = dynamic_cast<TH3 *>(parent->FindObject(hname.Data()));
470 throw HistoContainerContentException(hname.Data(), dirname.Data(), HistoContainerContentException::kHistNotFoundException);
471 hist->Fill(x, y, z, weight);
474 //______________________________________________________________________________
475 void AliEMCalHistoContainer::FillTH3(const char* name, const double* point, double weight) throw (HistoContainerContentException) {
476 TString dirname(basename(name)), hname(histname(name));
477 THashList *parent(FindGroup(dirname.Data()));
479 throw HistoContainerContentException(NULL, dirname.Data(), HistoContainerContentException::kGroupException);
480 TH3 *hist = dynamic_cast<TH3 *>(parent->FindObject(hname.Data()));
482 throw HistoContainerContentException(hname.Data(), dirname.Data(), HistoContainerContentException::kHistNotFoundException);
483 hist->Fill(point[0], point[1], point[2], weight);
487 //______________________________________________________________________________
488 void AliEMCalHistoContainer::FillTHnSparse(const char *name, const double *x, double weight) throw(HistoContainerContentException){
490 * Fill a nD histogram within the container. The histogram name also contains the parent group(s) according to the common
493 * @param name: Name of the histogram
494 * @param x: coordinates of the data
495 * @param weight (@default 1): optional weight of the entry
496 * @throw HistoContainerContentException
498 TString dirname(basename(name)), hname(histname(name));
499 THashList *parent(FindGroup(dirname.Data()));
501 throw HistoContainerContentException(NULL, dirname.Data(), HistoContainerContentException::kGroupException);
502 THnSparseD *hist = dynamic_cast<THnSparseD *>(parent->FindObject(hname.Data()));
504 throw HistoContainerContentException(hname.Data(), dirname.Data(), HistoContainerContentException::kHistNotFoundException);
505 hist->Fill(x, weight);
508 //______________________________________________________________________________
509 TObject *AliEMCalHistoContainer::FindObject(const char *name) const {
511 * Find an object inside the container. The object can also be within a
512 * histogram group. For this the name has to follow the common notation
514 * @param name: Name of the object to find inside the container
515 * @return: pointer to the object (NULL if not found)
517 TString dirname(basename(name)), hname(histname(name));
518 THashList *parent(FindGroup(dirname.Data()));
519 if(!parent) return NULL;
520 return parent->FindObject(name);
523 //______________________________________________________________________________
524 THashList *AliEMCalHistoContainer::FindGroup(const char *dirname) const {
526 * Find histogram group. Name is using common notation
528 * @param dirname: Path of the group (treat empty path as top node
529 * @return: TList of objects (NULL if group does not exist)
531 if(!strlen(dirname) || !strcmp(dirname, "/")) return fHistos;
532 std::vector<std::string> tokens;
533 TokenizeFilename(dirname, "/", tokens);
534 THashList *currentdir(fHistos);
535 for(std::vector<std::string>::iterator it = tokens.begin(); it != tokens.end(); ++it){
536 currentdir = dynamic_cast<THashList *>(currentdir->FindObject(it->c_str()));
537 if(!currentdir) break;
542 //______________________________________________________________________________
543 void AliEMCalHistoContainer::TokenizeFilename(const char *name, const char *delim, std::vector<std::string> &listoftokens) const {
545 * Tokenizes a string. Results are stored inside the vector listoftokens
547 * @ param name: string to be tokenised
548 * @ param delim: delimiter string
549 * @ param listoftokens: list of tokens (C++ strings)
552 TObjArray *arr = s.Tokenize(delim);
553 TObjString *ostr(NULL);
555 while((ostr = dynamic_cast<TObjString *>(toks()))){
556 listoftokens.push_back(std::string(ostr->String().Data()));
561 //______________________________________________________________________________
562 const char *AliEMCalHistoContainer::basename(const char *path) const {
564 * Helper function extracting the basename from a given histogram path.
566 * @param path: histogram path
567 * @return: basename extracted
570 int index = s.Last('/');
571 if(index < 0) return ""; // no directory structure
572 return TString(s(0, index)).Data();
575 //______________________________________________________________________________
576 const char *AliEMCalHistoContainer::histname(const char *path) const {
578 * Helper function extracting the histogram name from a given histogram path.
580 * @param path: histogram path
581 * @return: basename extracted
584 int index = s.Last('/');
585 if(index < 0) return path; // no directory structure
586 return TString(s(index+1, s.Length() - (index+1))).Data();