]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG/muon/AliHistogramCollection.cxx
adding cuts for muons
[u/mrichter/AliRoot.git] / PWG / muon / AliHistogramCollection.cxx
CommitLineData
d899f664 1/**************************************************************************
2* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3* *
4* Author: The ALICE Off-line Project. *
5* Contributors are mentioned in the code where appropriate. *
6* *
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**************************************************************************/
15
16// $Id$
17
18///
19/// A (fake) "4D" histogram container.
20///
21/// For each tuple (keyA,keyB,keyC,keyD) a (hash)list of histogram is associated.
22/// Note that keyA, keyB (optional), keyC (optional) and keyD (optional) are strings.
23/// Those strings should not contain "/" themselves.
24///
25/// More helper functions might be added in the future (e.g. Project, etc...)
26
27#include "AliHistogramCollection.h"
28
29#include "AliLog.h"
30#include "Riostream.h"
31#include "TError.h"
32#include "TH1.h"
5eabea87 33#include "TH2.h"
d899f664 34#include "THashList.h"
35#include "TKey.h"
36#include "TMap.h"
37#include "TObjArray.h"
38#include "TObjString.h"
39#include "TRegexp.h"
40#include "TROOT.h"
41#include "TSystem.h"
5eabea87 42#include "TProfile.h"
d899f664 43
3a7af7bd 44using std::cout;
45using std::endl;
d899f664 46ClassImp(AliHistogramCollection)
47
48//_____________________________________________________________________________
49AliHistogramCollection::AliHistogramCollection(const char* name, const char* title)
5eabea87 50: TNamed(name,title), fMap(0x0), fMustShowEmptyHistogram(kFALSE), fMapVersion(0), fMessages()
d899f664 51{
52 /// Ctor
53}
54
55//_____________________________________________________________________________
56AliHistogramCollection::~AliHistogramCollection()
57{
58 /// dtor. Note that the map is owner
59 if ( fMap ) fMap->DeleteAll();
60 delete fMap;
5eabea87 61// PrintMessages("AliHistogramCollection::~AliHistogramCollection");
62}
63
64//_____________________________________________________________________________
65Bool_t
66AliHistogramCollection::Adopt(TH1* histo)
67{
68 /// Adopt a given histogram at top level (i.e. no key)
69 return InternalAdopt("",histo);
d899f664 70}
71
72//_____________________________________________________________________________
73Bool_t
74AliHistogramCollection::Adopt(const char* key, TH1* histo)
75{
76 /// Adopt a given histogram, and associate it with pair (keyA)
5eabea87 77 return InternalAdopt(Form("/%s/",key),histo);
d899f664 78}
79
80//_____________________________________________________________________________
81Bool_t
82AliHistogramCollection::Adopt(const char* keyA, const char* keyB, TH1* histo)
83{
84 /// Adopt a given histogram, and associate it with pair (keyA,keyB)
5eabea87 85 return InternalAdopt(Form("/%s/%s/",keyA,keyB),histo);
d899f664 86}
87
88//_____________________________________________________________________________
89Bool_t
90AliHistogramCollection::Adopt(const char* keyA, const char* keyB, const char* keyC, TH1* histo)
91{
92 /// Adopt a given histogram, and associate it with pair (keyA,keyB,keyC)
5eabea87 93 return InternalAdopt(Form("/%s/%s/%s/",keyA,keyB,keyC),histo);
d899f664 94}
95
96//_____________________________________________________________________________
97Bool_t
98AliHistogramCollection::Adopt(const char* keyA, const char* keyB, const char* keyC, const char* keyD, TH1* histo)
99{
100 /// Adopt a given histogram, and associate it with pair (keyA,keyB,keyC,keyD)
101 return InternalAdopt(Form("/%s/%s/%s/%s/",keyA,keyB,keyC,keyD),histo);
102}
103
5eabea87 104//_____________________________________________________________________________
105void AliHistogramCollection::ClearMessages()
106{
107 /// clear pending messages
108 fMessages.clear();
109}
110
d899f664 111//_____________________________________________________________________________
112TIterator*
113AliHistogramCollection::CreateIterator(Bool_t direction) const
114{
115 /// Create an iterator (must be deleted by the client)
116 return fMap ? new AliHistogramCollectionIterator(this,direction) : 0x0;
117}
118
5eabea87 119//_____________________________________________________________________________
120AliHistogramCollection*
121AliHistogramCollection::Clone(const char* name) const
122{
123 /// Clone this collection.
124 /// We loose the messages.
125
126 AliHistogramCollection* newone = new AliHistogramCollection(name,GetTitle());
127
128 newone->fMap = static_cast<TMap*>(fMap->Clone());
129 newone->fMustShowEmptyHistogram = fMustShowEmptyHistogram;
130 newone->fMapVersion = fMapVersion;
131
132 return newone;
133}
134
d899f664 135//_____________________________________________________________________________
136void
137AliHistogramCollection::Delete(Option_t*)
138{
139 /// Delete all the histograms
140 fMap->DeleteAll();
141 delete fMap;
142 fMap=0x0;
143}
144
145//_____________________________________________________________________________
146TObject*
147AliHistogramCollection::FindObject(const char* identifier) const
148{
149 /// Find an object by its full identifier.
150
151 return Histo(KeyA(identifier),
152 KeyB(identifier),
153 KeyC(identifier),
154 KeyD(identifier),
155 HistoName(identifier));
156}
157
158//_____________________________________________________________________________
159TObject*
160AliHistogramCollection::FindObject(const TObject *key) const
161{
162 /// Find an object
163 AliWarning("This method is awfully inefficient. Please improve it or use FindObject(const char*)");
164 TIter next(CreateIterator());
165 TObject* o;
166 while ( ( o=next() ) )
167 {
168 if ( o->IsEqual(key) ) return o;
169 }
170 return 0x0;
171}
172
173//_____________________________________________________________________________
174TH1*
175AliHistogramCollection::Histo(const char* keyA,
176 const char* histoname) const
177{
178 /// Get histo for (keyA,histoname) triplet
179
5eabea87 180 return InternalHisto(Form("/%s/",keyA),histoname);
d899f664 181}
182
183//_____________________________________________________________________________
184TH1*
185AliHistogramCollection::Histo(const char* keyA, const char* keyB,
186 const char* histoname) const
187{
188 /// Get histo for (keyA,keyB,histoname) triplet
189
5eabea87 190 return InternalHisto(Form("/%s/%s/",keyA,keyB),histoname);
d899f664 191}
192
193//_____________________________________________________________________________
194TH1*
195AliHistogramCollection::Histo(const char* keyA, const char* keyB, const char* keyC,
196 const char* histoname) const
197{
198 /// Get histo for (keyA,keyB,keyC,histoname) quad
199
5eabea87 200 return InternalHisto(Form("/%s/%s/%s/",keyA,keyB,keyC),histoname);
d899f664 201}
202
203//_____________________________________________________________________________
204TH1*
205AliHistogramCollection::Histo(const char* keyA, const char* keyB,
206 const char* keyC, const char* keyD,
207 const char* histoname) const
208{
209 /// Get histo for (keyA,keyB,keyC,histoname) quad
210
211 return InternalHisto(Form("/%s/%s/%s/%s/",keyA,keyB,keyC,keyD),histoname);
212}
213
214//_____________________________________________________________________________
215TString
216AliHistogramCollection::HistoName(const char* identifier) const
217{
218 /// Extract the histogram name from an identifier
219
5eabea87 220 return InternalDecode(identifier,-1);
d899f664 221}
222
223//_____________________________________________________________________________
224Bool_t AliHistogramCollection::InternalAdopt(const char* identifier, TH1* histo)
225{
226 /// Adopt an histogram
227
228 if (!histo)
229 {
230 Error("Adopt","Cannot adopt a null histogram");
231 return kFALSE;
232 }
233
234 THashList* hlist = 0x0;
235
5eabea87 236 hlist = static_cast<THashList*>(Map()->GetValue(identifier));
d899f664 237
238 if (!hlist)
239 {
240 hlist = new THashList;
241 hlist->SetOwner(kTRUE);
5eabea87 242 Map()->Add(new TObjString(identifier),hlist);
d899f664 243 hlist->SetName(identifier);
244 }
245
246 TH1* h = static_cast<TH1*>(hlist->FindObject(histo->GetName()));
247
248 if (h)
249 {
250 AliError(Form("Cannot adopt an already existing histogram : %s -> %s",identifier,h->GetName()));
251 return kFALSE;
252 }
253
254
255 histo->SetDirectory(0);
256
257 hlist->AddLast(histo);
258
259 return kTRUE;
260
261}
262
263//_____________________________________________________________________________
264TH1*
5eabea87 265AliHistogramCollection::Histo(const char* sidentifier) const
d899f664 266{
5eabea87 267 /// Get histogram keyA/keyB/keyC/keyD/histoname:action
268
269 TObjArray* a = TString(sidentifier).Tokenize(":");
270
271 TString identifier(static_cast<TObjString*>(a->At(0))->String());
272 TString action;
273
274 if ( a->GetLast() > 0 )
275 {
276 action = static_cast<TObjString*>(a->At(1))->String();
277 action.ToUpper();
278 }
279
280 Int_t nslashes = identifier.CountChar('/');
281
282 TH1* h(0x0);
283
284 switch (nslashes)
285 {
286 case 0:
287 case 1:
288 // no slash : the identifier is just the histogram name
289 h = InternalHisto("",identifier);
290 break;
291 case 2:
292 h = Histo(InternalDecode(identifier,0),
293 InternalDecode(identifier,-1));
294 break;
295 case 3:
296 h = Histo(InternalDecode(identifier,0),
297 InternalDecode(identifier,1),
298 InternalDecode(identifier,-1));
299 break;
300 case 4:
301 h = Histo(InternalDecode(identifier,0),
302 InternalDecode(identifier,1),
303 InternalDecode(identifier,2),
304 InternalDecode(identifier,-1));
305 break;
306 case 5:
307 h = Histo(InternalDecode(identifier,0),
308 InternalDecode(identifier,1),
309 InternalDecode(identifier,2),
310 InternalDecode(identifier,3),
311 InternalDecode(identifier,-1));
312 break;
313 default:
314 AliError(Form("Invalid identifier %s",identifier.Data()));
315 break;
316 }
317
318 if (h)
319 {
320 TH2* h2(0x0);
321
322 if ( action == "PX" && ( (h2 = dynamic_cast<TH2*>(h)) ) )
323 {
324 return h2->ProjectionX(NormalizeName(identifier.Data(),action.Data()).Data());
325 }
326 else if ( action == "PY" && ( (h2 = dynamic_cast<TH2*>(h)) ) )
327 {
328 return h2->ProjectionY(NormalizeName(identifier.Data(),action.Data()).Data());
329 }
330 else if ( action == "PFX" && ( (h2 = dynamic_cast<TH2*>(h)) ) )
331 {
332 return h2->ProfileX(NormalizeName(identifier.Data(),action.Data()).Data());
333 }
334 else if ( action == "PFY" && ( (h2 = dynamic_cast<TH2*>(h)) ) )
335 {
336 return h2->ProfileY(NormalizeName(identifier.Data(),action.Data()).Data());
337 }
338
339 }
340 else
341 {
342 AliDebug(1,Form("histogram %s not found",sidentifier));
343 }
344 return h;
d899f664 345}
346
347//_____________________________________________________________________________
348TString
349AliHistogramCollection::InternalDecode(const char* identifier, Int_t index) const
350{
351 /// Extract the index-th element of the identifier (/keyA/keyB/keyC/keyD/histoname)
352 /// keyA is index=0
353 /// keyB is index=1
354 /// keyC is index=2
355 /// keyD is index=3
5eabea87 356 /// histo is index=-1 (i.e. last)
d899f664 357
5eabea87 358 if ( strlen(identifier) > 0 && identifier[0] != '/' )
d899f664 359 {
5eabea87 360 AliError(Form("identifier %s is malformed (should start with /)",identifier));
d899f664 361 return "";
362 }
363
364 TObjArray* array = TString(identifier).Tokenize("/");
365
366 if ( array->GetLast()>5 )
367 {
5eabea87 368 AliError(Form("identifier %s is malformed (more than 5 /)",identifier));
d899f664 369 delete array;
370 return "";
371 }
372
373 TString value("");
374
5eabea87 375 if ( index < 0 )
376 {
377 value = static_cast<TObjString*>(array->Last())->String();
378 }
379 else if ( index <= array->GetLast() )
d899f664 380 {
381 value = static_cast<TObjString*>(array->At(index))->String();
382 }
383
384 delete array;
385
386 return value;
d899f664 387}
388
389//_____________________________________________________________________________
390TH1*
391AliHistogramCollection::InternalHisto(const char* identifier,
392 const char* histoname) const
393{
394 /// Get histo for (identifier,histoname)
395
396 if (!fMap)
397 {
398 return 0x0;
399 }
400
5eabea87 401 THashList* hlist = static_cast<THashList*>(Map()->GetValue(identifier));
d899f664 402 if (!hlist)
403 {
5eabea87 404 TString msg(Form("Did not find hashlist for identifier=%s dir=%s",identifier,gDirectory ? gDirectory->GetName() : "" ));
405 fMessages[msg.Data()]++;
d899f664 406 return 0x0;
407 }
408
5eabea87 409 TH1* h = static_cast<TH1*>(hlist->FindObject(histoname));
410 if (!h)
411 {
412 TString msg(Form("Did not find histoname=%s in %s",histoname,identifier));
413 fMessages[msg.Data()]++;
414 }
415 return h;
d899f664 416}
417
418
419//_____________________________________________________________________________
420TString
421AliHistogramCollection::KeyA(const char* identifier) const
422{
423 /// Extract the first element of the key pair from an identifier
424
425 return InternalDecode(identifier,0);
426}
427
428//_____________________________________________________________________________
429TString
430AliHistogramCollection::KeyB(const char* identifier) const
431{
432 /// Extract the second element (if present)
433 return InternalDecode(identifier,1);
434}
435
436//_____________________________________________________________________________
437TString
438AliHistogramCollection::KeyC(const char* identifier) const
439{
440 /// Extract the 3rd element (if present)
441 return InternalDecode(identifier,2);
442}
443
444//_____________________________________________________________________________
445TString
446AliHistogramCollection::KeyD(const char* identifier) const
447{
448 /// Extract the 4th element (if present)
449 return InternalDecode(identifier,3);
450}
451
5eabea87 452//_____________________________________________________________________________
453TMap* AliHistogramCollection::Map() const
454{
455 /// Wrapper to insure proper key formats (i.e. new vs old)
456
457 if (!fMap)
458 {
459 fMap = new TMap;
460 fMap->SetOwnerKeyValue(kTRUE,kTRUE);
461 fMapVersion = 1;
462 }
463 else
464 {
465 if ( fMapVersion < 1 )
466 {
467 // change the keys
468 TIter next(fMap);
469 TObjString* str;
470
471 while ( ( str = static_cast<TObjString*>(next()) ) )
472 {
473 if ( str->String().Contains("./") )
474 {
475 TString newkey(str->String());
476
477 newkey.ReplaceAll("./","");
478
479 TObject* o = fMap->GetValue(str);
480
481 TPair* p = fMap->RemoveEntry(str);
482 if (!p)
483 {
484 AliError("oups oups oups");
485 return 0x0;
486 }
487
488 fMap->Add(new TObjString(newkey.Data()),o);
489
490 delete p;
491 }
492 }
493
494 fMapVersion = 1;
495 }
496 }
497
498 return fMap;
499}
500
d899f664 501//_____________________________________________________________________________
502Long64_t
503AliHistogramCollection::Merge(TCollection* list)
504{
505 // Merge a list of AliHistogramCollection objects with this
506 // Returns the number of merged objects (including this).
507
508 if (!list) return 0;
509
510 if (list->IsEmpty()) return 1;
511
512 TIter next(list);
513 TObject* o;
514 TList mapList;
515 Int_t count(0);
516
517 while ( ( o = next() ) )
518 {
519 AliHistogramCollection* hcol = dynamic_cast<AliHistogramCollection*>(o);
e6e96cea 520 if (!hcol) {
521 AliFatal(Form("object named \"%s\" is a %s instead of an AliHistogramCollection!", o->GetName(), o->ClassName()));
522 continue;
523 }
d899f664 524
525 ++count;
526
5eabea87 527 if ( hcol->fMap ) hcol->Map(); // to insure keys in the new format
528
d899f664 529 TIter nextIdentifier(hcol->fMap);
530 TObjString* identifier;
531
532 while ( ( identifier = static_cast<TObjString*>(nextIdentifier()) ) )
533 {
534 THashList* otherList = static_cast<THashList*>(hcol->fMap->GetValue(identifier->String().Data()));
535
536 TIter nextHisto(otherList);
537 TH1* h;
538
539 while ( ( h = static_cast<TH1*>(nextHisto()) ) )
540 {
5eabea87 541 TString newid(Form("%s%s",identifier->String().Data(),h->GetName()));
542
543 TH1* thisHisto = Histo(newid.Data());
d899f664 544
545 if (!thisHisto)
546 {
5eabea87 547 AliDebug(1,Form("Adopting a new histo = %s%s",identifier->String().Data(),h->GetName()));
d899f664 548
549 // this is an histogram we don't have yet. Let's add it
5eabea87 550
551 Int_t nslashes = TString(newid).CountChar('/');
552
553 Bool_t ok(kFALSE);
554
555 switch (nslashes)
556 {
557 case 2:
558 ok = Adopt(KeyA(identifier->String()),
559 static_cast<TH1*>(h->Clone()));
560 break;
561 case 3:
562 ok = Adopt(KeyA(identifier->String()),
563 KeyB(identifier->String()),
564 static_cast<TH1*>(h->Clone()));
565 break;
566 case 4:
567 ok = Adopt(KeyA(identifier->String()),
568 KeyB(identifier->String()),
569 KeyC(identifier->String()),
570 static_cast<TH1*>(h->Clone()));
571 break;
572 case 5:
573 ok = Adopt(KeyA(identifier->String()),
574 KeyB(identifier->String()),
575 KeyC(identifier->String()),
576 KeyD(identifier->String()),
577 static_cast<TH1*>(h->Clone()));
578 break;
579 default:
580 AliError(Form("Invalid identifier %s",identifier->String().Data()));
581 break;
582 }
583
584 if (!ok)
585 {
586 AliError(Form("Adoption of histogram %s failed",h->GetName()));
587 }
d899f664 588 }
589 else
590 {
591 // add it...
5eabea87 592 AliDebug(1,Form("Merging histo = %s%s (%g vs %g)",
d899f664 593 identifier->String().Data(),
594 h->GetName(),
595 h->GetSumOfWeights(),
596 thisHisto->GetSumOfWeights()));
d899f664 597
5eabea87 598 if ( HistoSameAxis(h,thisHisto) )
599 {
600 thisHisto->Add(h);
601 }
602 else
603 {
604 TList l;
605 l.Add(h);
606
607 thisHisto->Merge(&l);
608 }
d899f664 609 }
610 }
611 }
612 }
613
614 AliDebug(1,Form("count=%d",count));
615
616 return count+1;
617}
618
5eabea87 619//_____________________________________________________________________________
620TString AliHistogramCollection::NormalizeName(const char* identifier,const char* action) const
621{
622 // Replace / by _ to build a root-compliant histo name
623 TString name(identifier);
624 name += "_";
625 name += action;
626 name.ReplaceAll("/","_");
627 return name;
628}
629
d899f664 630//_____________________________________________________________________________
631Int_t
632AliHistogramCollection::NumberOfHistograms() const
633{
634 /// Get the number of histograms we hold
635 TIter next(CreateIterator(this));
636 Int_t n(0);
637 while ( next() ) ++n;
638 return n;
639}
640
641//_____________________________________________________________________________
642Int_t
643AliHistogramCollection::NumberOfKeys() const
644{
645 /// Get the number of keys we have
646 return fMap ? fMap->GetSize() : 0;
647}
648
649//_____________________________________________________________________________
650void
651AliHistogramCollection::Print(Option_t* option) const
652{
653 /// Print all the histograms we hold, in a hopefully visually pleasing
654 /// way.
655 ///
656 /// Option can be used to select given part only, using the schema :
657 /// /*/*/*/*/*
658 /// Where the stars are wilcards for /keyA/keyB/keyC/KeyD/histoname
659 ///
660 /// if * is used it is assumed to be a wildcard for histoname
661 ///
662 /// For other selections the full syntax /*/*/*/*/* must be used.
663 ///
664 /// Use "-" as histoname to disable histogram's name output
665
666 cout << Form("AliHistogramCollection : %d keys and %d histos",
667 NumberOfKeys(), NumberOfHistograms()) << endl;
668
669 if (!strlen(option)) return;
670
671 TString sreKeyA("*");
672 TString sreKeyB("*");
673 TString sreKeyC("*");
674 TString sreKeyD("*");
675 TString sreHistoname("*");
676
677 TObjArray* select = TString(option).Tokenize("/");
678 Int_t n = select->GetLast();
679
680 if (n>=0)
681 {
682 sreHistoname = static_cast<TObjString*>(select->At(n))->String();
683 }
684 if (n>=1)
685 {
686 sreKeyD = static_cast<TObjString*>(select->At(n-1))->String();
687 }
688 if (n>=2)
689 {
690 sreKeyC = static_cast<TObjString*>(select->At(n-2))->String();
691 }
692 if (n>=3)
693 {
694 sreKeyB = static_cast<TObjString*>(select->At(n-3))->String();
695 }
696 if (n>=4)
697 {
698 sreKeyA = static_cast<TObjString*>(select->At(n-3))->String();
699 }
700
701 TRegexp reKeyA(sreKeyA,kTRUE);
702 TRegexp reKeyB(sreKeyB,kTRUE);
703 TRegexp reKeyC(sreKeyC,kTRUE);
704 TRegexp reKeyD(sreKeyD,kTRUE);
705 TRegexp reHistoname(sreHistoname,kTRUE);
706
707 delete select;
708
709 TObjArray* identifiers = SortAllIdentifiers();
5eabea87 710
d899f664 711 TIter nextIdentifier(identifiers);
712
713 TObjString* sid(0x0);
714
715 while ( ( sid = static_cast<TObjString*>(nextIdentifier()) ) )
716 {
717 Bool_t identifierPrinted(kFALSE);
718
719 TString identifier(sid->String());
720
5eabea87 721 if ( ( InternalDecode(identifier,0).Contains(reKeyA) &&
722 InternalDecode(identifier,1).Contains(reKeyB) &&
723 InternalDecode(identifier,2).Contains(reKeyC) &&
724 InternalDecode(identifier,3).Contains(reKeyD) )
d899f664 725 )
726 {
727 if ( sreHistoname == "*" )
728 {
729 identifierPrinted = kTRUE;
730 cout << identifier.Data() << endl;
731 }
732
5eabea87 733 THashList * list = static_cast<THashList*>(Map()->GetValue(sid->String().Data()));
d899f664 734 TObjArray names;
735 names.SetOwner(kTRUE);
736 TIter nextUnsortedHisto(list);
737 TH1* h;
738 while ( ( h = static_cast<TH1*>(nextUnsortedHisto()) ) )
739 {
740 names.Add(new TObjString(h->GetName()));
741 }
742 names.Sort();
743 TIter nextHistoName(&names);
744 TObjString* hname;
745 while ( ( hname = static_cast<TObjString*>(nextHistoName()) ) )
746 {
747 TString histoName(hname->String());
748 if (histoName.Contains(reHistoname) )
749 {
750 h = static_cast<TH1*>(list->FindObject(histoName.Data()));
751 if ( h->GetEntries()==0 && !fMustShowEmptyHistogram ) continue;
752 if (!identifierPrinted)
753 {
754 cout << identifier.Data() << endl;
755 identifierPrinted = kTRUE;
756 }
757 cout << Form(" %s %s Entries=%d Sum=%g",h->GetName(),h->GetTitle(),Int_t(h->GetEntries()),h->GetSumOfWeights()) << endl;
758 }
759 }
760 if (!identifierPrinted && sreHistoname=="-" )
761 {
762 // to handle the case where we used histoname="-" to disable showing the histonames,
763 // but we still want to see the matching keys maybe...
764 cout << identifier.Data() << endl;
765 }
766 }
767 }
768
769 delete identifiers;
770}
771
5eabea87 772//_____________________________________________________________________________
773void
774AliHistogramCollection::PrintMessages(const char* prefix) const
775{
776 /// Print pending messages
777
778 std::map<std::string,int>::const_iterator it;
779
780 for ( it = fMessages.begin(); it != fMessages.end(); ++it )
781 {
782 cout << Form("%s : message %s appeared %5d times",prefix,it->first.c_str(),it->second) << endl;
783 }
784}
785
786
d899f664 787//_____________________________________________________________________________
788UInt_t
789AliHistogramCollection::EstimateSize(Bool_t show) const
790{
791 /// Estimate the memory (in kilobytes) used by our histograms
792
793// sizeof(TH1) + (nbins+2)*(nbytes_per_bin) +name+title_sizes
794// if you have errors add (nbins+2)*8
795
796 TIter next(CreateIterator());
797 TH1* h;
798 UInt_t n(0);
799
800 while ( ( h = static_cast<TH1*>(next()) ) )
801 {
802 Int_t nbins = (h->GetNbinsX()+2);
803
804 if (h->GetNbinsY()>1)
805 {
806 nbins *= (h->GetNbinsY()+2);
807 }
808
809 if (h->GetNbinsZ()>1)
810 {
811 nbins *= (h->GetNbinsZ()+2);
812 }
813
814 Bool_t hasErrors = ( h->GetSumw2N() > 0 );
815
816 TString cname(h->ClassName());
817
818 Int_t nbytesPerBin(0);
819
820 if (cname.Contains(TRegexp("C$")) ) nbytesPerBin = sizeof(Char_t);
821 if (cname.Contains(TRegexp("S$")) ) nbytesPerBin = sizeof(Short_t);
822 if (cname.Contains(TRegexp("I$")) ) nbytesPerBin = sizeof(Int_t);
823 if (cname.Contains(TRegexp("F$")) ) nbytesPerBin = sizeof(Float_t);
824 if (cname.Contains(TRegexp("D$")) ) nbytesPerBin = sizeof(Double_t);
825
826 if (!nbytesPerBin)
827 {
828 AliError(Form("Could not get the number of bytes per bin for histo %s of class %s. Thus the size estimate will be wrong !",
829 h->GetName(),h->ClassName()));
830 continue;
831 }
832
833 UInt_t thissize = sizeof(h) + nbins*(nbytesPerBin) + strlen(h->GetName())
834 + strlen(h->GetTitle());
835
836 if ( hasErrors) thissize += nbins*8;
837
838 n += thissize;
839
840 if ( show )
841 {
842 AliInfo(Form("Size of %30s is %20d bytes",h->GetName(),thissize));
843 }
844 }
845
846 return n;
847}
848
849//_____________________________________________________________________________
850void AliHistogramCollection::PruneEmptyHistograms()
851{
852 /// Delete the empty histograms
5eabea87 853 TIter next(Map());
d899f664 854 TObjString* key;
855
856 TList toBeRemoved;
857 toBeRemoved.SetOwner(kTRUE);
858
859 while ( ( key = static_cast<TObjString*>(next()) ) )
860 {
861 TString identifier(key->String());
5eabea87 862 THashList* hlist = static_cast<THashList*>(Map()->GetValue(identifier.Data()));
d899f664 863 TIter nextHisto(hlist);
864 TH1* h;
865 while ( ( h = static_cast<TH1*>(nextHisto())))
866 {
867 if ( h->GetEntries()==0)
868 {
869 toBeRemoved.Add(new TObjString(Form("%s%s",identifier.Data(),h->GetName())));
870 }
871 }
872 }
873
874 TIter nextTBR(&toBeRemoved);
875 while ( ( key = static_cast<TObjString*>(nextTBR()) ) )
876 {
877 Remove(key);
878 }
879}
880
881//_____________________________________________________________________________
882AliHistogramCollection*
5eabea87 883AliHistogramCollection::Project(const char* keyA, const char* keyB, const char* keyC, const char* keyD) const
d899f664 884{
5eabea87 885 /// To be implemented : would create a new collection starting at keyA/keyB/keyC/keyD
886
887 if (!fMap) return 0x0;
888
889 AliHistogramCollection* hc = new AliHistogramCollection(Form("%s %s/%s/%s/%s",GetName(),keyA,keyB,keyC,keyD),
890 GetTitle());
891
892 TIter next(Map());
893 TObjString* str;
894
895 while ( ( str = static_cast<TObjString*>(next()) ) )
896 {
897 TString identifier = str->String();
898
899 Bool_t copy= ( KeyA(identifier) == keyA &&
900 ( strlen(keyB)==0 || KeyB(identifier)==keyB ) &&
901 ( strlen(keyC)==0 || KeyC(identifier)==keyC ) &&
902 ( strlen(keyD)==0 || KeyD(identifier)==keyD ));
903
904 if ( !copy ) continue;
905
906 THashList* list = static_cast<THashList*>(Map()->GetValue(identifier.Data()));
907
908 TIter nextHisto(list);
909 TH1* h;
910
911 while ( ( h = static_cast<TH1*>(nextHisto()) ) )
912 {
913 TH1* hclone = static_cast<TH1*>(h->Clone());
914
915 TString newkey(identifier.Data());
916
917 if ( strlen(keyD) > 0 ) newkey.ReplaceAll(Form("/%s",keyD),"");
918 if ( strlen(keyC) > 0 ) newkey.ReplaceAll(Form("/%s",keyC),"");
919 if ( strlen(keyB) > 0 ) newkey.ReplaceAll(Form("/%s",keyB),"");
920 if ( strlen(keyA) > 0 ) newkey.ReplaceAll(Form("/%s",keyA),"");
921
922 if (newkey=="/") newkey="";
923
924 hc->InternalAdopt(newkey.Data(),hclone);
925 }
926 }
927
928 return hc;
d899f664 929}
930
931//_____________________________________________________________________________
932TObject*
933AliHistogramCollection::Remove(TObject* key)
934{
935 ///
936 /// Remove a given histogram (given its key=full identifier=/keyA/keyB/keyC/keyD/histoname)
937 ///
938 /// Note that we do *not* remove the /keyA/keyB/keyC/keyD entry even if there's no
939 /// more histogram for this triplet.
940 ///
941 /// Not very efficient. Could be improved ?
942 ///
943
944 TObjString* str = dynamic_cast<TObjString*>(key);
945
946 if (!str)
947 {
948 AliError(Form("key is not of the expected TObjString type, but of %s",key->ClassName()));
949 return 0x0;
950 }
951
952 TString identifier(str->String());
953
5eabea87 954 Int_t nslashes = TString(identifier).CountChar('/');
955
956 TString skey;
957
958 switch (nslashes )
959 {
960 case 2:
961 skey = Form("/%s/",
962 KeyA(identifier).Data());
963 break;
964 case 3:
965 skey = Form("/%s/%s/",
966 KeyA(identifier).Data(),
967 KeyB(identifier).Data());
968 break;
969 case 4:
970 skey = Form("/%s/%s/%s/",
971 KeyA(identifier).Data(),
972 KeyB(identifier).Data(),
973 KeyC(identifier).Data());
974 break;
975 case 5:
976 skey = Form("/%s/%s/%s/%s/",
977 KeyA(identifier).Data(),
978 KeyB(identifier).Data(),
979 KeyC(identifier).Data(),
980 KeyD(identifier).Data()
981 );
982 break;
983 default:
984 AliError("Oups");
985 break;
986 };
d899f664 987
5eabea87 988 THashList* hlist = dynamic_cast<THashList*>(Map()->GetValue(skey.Data()));
d899f664 989
990 if (!hlist)
991 {
992 AliWarning(Form("Could not get hlist for key=%s",skey.Data()));
993 return 0x0;
994 }
995
996 TH1* h = InternalHisto(skey,HistoName(identifier.Data()));
997 if (!h)
998 {
999 AliError(Form("Could not find histo %s",identifier.Data()));
1000 return 0x0;
1001 }
1002
1003 TObject* o = hlist->Remove(h);
1004 if (!o)
1005 {
1006 AliError("Remove failed");
1007 return 0x0;
1008 }
1009
1010// if ( hlist->IsEmpty() )
1011// {
1012// // we should remove the key as well
1013// TObject* k = fMap->Remove(key);
1014// if (!k)
1015// {
1016// AliError("Removal of the key failed");
1017// }
1018// }
1019
1020 return o;
1021}
1022
5eabea87 1023//______________________________________________________________________________
1024Bool_t AliHistogramCollection::HistoSameAxis(TH1 *h0, TH1 *h1) const
1025{
1026 // shameless copy from TProofPlayerRemote::HistoSameAxis
1027 //
1028 // Return kTRUE is the histograms 'h0' and 'h1' have the same binning and ranges
1029 // on the axis (i.e. if they can be just Add-ed for merging).
1030
1031 Bool_t rc = kFALSE;
1032 if (!h0 || !h1) return rc;
1033
1034 TAxis *a0 = 0, *a1 = 0;
1035
1036 // Check X
1037 a0 = h0->GetXaxis();
1038 a1 = h1->GetXaxis();
1039 if (a0->GetNbins() == a1->GetNbins())
1040 if (TMath::Abs(a0->GetXmax() - a1->GetXmax()) < 1.e-9)
1041 if (TMath::Abs(a0->GetXmin() - a1->GetXmin()) < 1.e-9) rc = kTRUE;
1042
1043 // Check Y, if needed
1044 if (h0->GetDimension() > 1) {
1045 rc = kFALSE;
1046 a0 = h0->GetYaxis();
1047 a1 = h1->GetYaxis();
1048 if (a0->GetNbins() == a1->GetNbins())
1049 if (TMath::Abs(a0->GetXmax() - a1->GetXmax()) < 1.e-9)
1050 if (TMath::Abs(a0->GetXmin() - a1->GetXmin()) < 1.e-9) rc = kTRUE;
1051 }
1052
1053 // Check Z, if needed
1054 if (h0->GetDimension() > 2) {
1055 rc = kFALSE;
1056 a0 = h0->GetZaxis();
1057 a1 = h1->GetZaxis();
1058 if (a0->GetNbins() == a1->GetNbins())
1059 if (TMath::Abs(a0->GetXmax() - a1->GetXmax()) < 1.e-9)
1060 if (TMath::Abs(a0->GetXmin() - a1->GetXmin()) < 1.e-9) rc = kTRUE;
1061 }
1062
1063 // Done
1064 return rc;
1065}
1066
d899f664 1067//_____________________________________________________________________________
1068TObjArray*
1069AliHistogramCollection::SortAllIdentifiers() const
1070{
1071 /// Sort our internal identifiers. Returned array must be deleted.
1072 TObjArray* identifiers = new TObjArray;
1073 identifiers->SetOwner(kFALSE);
5eabea87 1074 TIter next(Map());
d899f664 1075 TObjString* sid;
1076
1077 while ( ( sid = static_cast<TObjString*>(next()) ) )
1078 {
1079 if ( !identifiers->FindObject(sid->String().Data()) )
1080 {
1081 identifiers->Add(sid);
1082 }
1083 }
1084 identifiers->Sort();
1085 return identifiers;
1086}
1087
1088
1089///////////////////////////////////////////////////////////////////////////////
1090//
1091// AliHistogramCollectionIterator
1092//
1093///////////////////////////////////////////////////////////////////////////////
1094
1095class AliHistogramCollectionIterator;
1096
1097//_____________________________________________________________________________
1098AliHistogramCollectionIterator::AliHistogramCollectionIterator(const AliHistogramCollection* hcol, Bool_t dir)
1099: fkHistogramCollection(hcol), fMapIterator(0x0), fHashListIterator(0x0), fDirection(dir)
1100{
1101 /// Default ctor
1102}
1103
1104//_____________________________________________________________________________
1105AliHistogramCollectionIterator&
1106AliHistogramCollectionIterator::operator=(const TIterator&)
1107{
1108 /// Overriden operator= (imposed by Root's declaration of TIterator ?)
1109 Fatal("TIterator::operator=","Not implementeable"); // because there's no clone in TIterator :-(
1110 return *this;
1111}
1112
1113//_____________________________________________________________________________
1114AliHistogramCollectionIterator::~AliHistogramCollectionIterator()
1115{
1116 /// dtor
1117 Reset();
1118}
1119
1120//_____________________________________________________________________________
1121TObject* AliHistogramCollectionIterator::Next()
1122{
1123 /// Advance to next object in the collection
1124
1125 if (!fHashListIterator)
1126 {
1127 if ( !fMapIterator )
1128 {
1129 fMapIterator = fkHistogramCollection->fMap->MakeIterator(fDirection);
1130 }
1131 TObjString* key = static_cast<TObjString*>(fMapIterator->Next());
1132 if (!key)
1133 {
1134 // we are done
1135 return 0x0;
1136 }
5eabea87 1137 THashList* list = static_cast<THashList*>(fkHistogramCollection->Map()->GetValue(key->String().Data()));
d899f664 1138 if (!list) return 0x0;
1139 fHashListIterator = list->MakeIterator(fDirection);
1140 }
1141
1142 TObject* o = fHashListIterator->Next();
1143
1144 if (!o)
1145 {
1146 delete fHashListIterator;
1147 fHashListIterator = 0x0;
1148 return Next();
1149 }
1150
1151 return o;
1152}
1153
1154//_____________________________________________________________________________
1155void AliHistogramCollectionIterator::Reset()
1156{
1157 /// Reset the iterator
1158 delete fHashListIterator;
1159 delete fMapIterator;
1160}