]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG3/muon/AliHistogramCollection.cxx
Coverity fix (an obsolete constructor removed)
[u/mrichter/AliRoot.git] / PWG3 / 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"
33#include "THashList.h"
34#include "TKey.h"
35#include "TMap.h"
36#include "TObjArray.h"
37#include "TObjString.h"
38#include "TRegexp.h"
39#include "TROOT.h"
40#include "TSystem.h"
41
42ClassImp(AliHistogramCollection)
43
44//_____________________________________________________________________________
45AliHistogramCollection::AliHistogramCollection(const char* name, const char* title)
46: TNamed(name,title), fMap(0x0), fMustShowEmptyHistogram(kFALSE)
47{
48 /// Ctor
49}
50
51//_____________________________________________________________________________
52AliHistogramCollection::~AliHistogramCollection()
53{
54 /// dtor. Note that the map is owner
55 if ( fMap ) fMap->DeleteAll();
56 delete fMap;
57}
58
59//_____________________________________________________________________________
60Bool_t
61AliHistogramCollection::Adopt(const char* key, TH1* histo)
62{
63 /// Adopt a given histogram, and associate it with pair (keyA)
64 return InternalAdopt(Form("/%s/./././",key),histo);
65}
66
67//_____________________________________________________________________________
68Bool_t
69AliHistogramCollection::Adopt(const char* keyA, const char* keyB, TH1* histo)
70{
71 /// Adopt a given histogram, and associate it with pair (keyA,keyB)
72 return InternalAdopt(Form("/%s/%s/././",keyA,keyB),histo);
73}
74
75//_____________________________________________________________________________
76Bool_t
77AliHistogramCollection::Adopt(const char* keyA, const char* keyB, const char* keyC, TH1* histo)
78{
79 /// Adopt a given histogram, and associate it with pair (keyA,keyB,keyC)
80 return InternalAdopt(Form("/%s/%s/%s/./",keyA,keyB,keyC),histo);
81}
82
83//_____________________________________________________________________________
84Bool_t
85AliHistogramCollection::Adopt(const char* keyA, const char* keyB, const char* keyC, const char* keyD, TH1* histo)
86{
87 /// Adopt a given histogram, and associate it with pair (keyA,keyB,keyC,keyD)
88 return InternalAdopt(Form("/%s/%s/%s/%s/",keyA,keyB,keyC,keyD),histo);
89}
90
91//_____________________________________________________________________________
92TIterator*
93AliHistogramCollection::CreateIterator(Bool_t direction) const
94{
95 /// Create an iterator (must be deleted by the client)
96 return fMap ? new AliHistogramCollectionIterator(this,direction) : 0x0;
97}
98
99//_____________________________________________________________________________
100void
101AliHistogramCollection::Delete(Option_t*)
102{
103 /// Delete all the histograms
104 fMap->DeleteAll();
105 delete fMap;
106 fMap=0x0;
107}
108
109//_____________________________________________________________________________
110TObject*
111AliHistogramCollection::FindObject(const char* identifier) const
112{
113 /// Find an object by its full identifier.
114
115 return Histo(KeyA(identifier),
116 KeyB(identifier),
117 KeyC(identifier),
118 KeyD(identifier),
119 HistoName(identifier));
120}
121
122//_____________________________________________________________________________
123TObject*
124AliHistogramCollection::FindObject(const TObject *key) const
125{
126 /// Find an object
127 AliWarning("This method is awfully inefficient. Please improve it or use FindObject(const char*)");
128 TIter next(CreateIterator());
129 TObject* o;
130 while ( ( o=next() ) )
131 {
132 if ( o->IsEqual(key) ) return o;
133 }
134 return 0x0;
135}
136
137//_____________________________________________________________________________
138TH1*
139AliHistogramCollection::Histo(const char* keyA,
140 const char* histoname) const
141{
142 /// Get histo for (keyA,histoname) triplet
143
144 return InternalHisto(Form("/%s/./././",keyA),histoname);
145}
146
147//_____________________________________________________________________________
148TH1*
149AliHistogramCollection::Histo(const char* keyA, const char* keyB,
150 const char* histoname) const
151{
152 /// Get histo for (keyA,keyB,histoname) triplet
153
154 return InternalHisto(Form("/%s/%s/././",keyA,keyB),histoname);
155}
156
157//_____________________________________________________________________________
158TH1*
159AliHistogramCollection::Histo(const char* keyA, const char* keyB, const char* keyC,
160 const char* histoname) const
161{
162 /// Get histo for (keyA,keyB,keyC,histoname) quad
163
164 return InternalHisto(Form("/%s/%s/%s/./",keyA,keyB,keyC),histoname);
165}
166
167//_____________________________________________________________________________
168TH1*
169AliHistogramCollection::Histo(const char* keyA, const char* keyB,
170 const char* keyC, const char* keyD,
171 const char* histoname) const
172{
173 /// Get histo for (keyA,keyB,keyC,histoname) quad
174
175 return InternalHisto(Form("/%s/%s/%s/%s/",keyA,keyB,keyC,keyD),histoname);
176}
177
178//_____________________________________________________________________________
179TString
180AliHistogramCollection::HistoName(const char* identifier) const
181{
182 /// Extract the histogram name from an identifier
183
184 return InternalDecode(identifier,4);
185}
186
187//_____________________________________________________________________________
188Bool_t AliHistogramCollection::InternalAdopt(const char* identifier, TH1* histo)
189{
190 /// Adopt an histogram
191
192 if (!histo)
193 {
194 Error("Adopt","Cannot adopt a null histogram");
195 return kFALSE;
196 }
197
198 THashList* hlist = 0x0;
199
200 if ( !fMap )
201 {
202 fMap = new TMap;
203 fMap->SetOwner(kTRUE);
204 }
205
206 hlist = static_cast<THashList*>(fMap->GetValue(identifier));
207
208 if (!hlist)
209 {
210 hlist = new THashList;
211 hlist->SetOwner(kTRUE);
212 fMap->Add(new TObjString(identifier),hlist);
213 hlist->SetName(identifier);
214 }
215
216 TH1* h = static_cast<TH1*>(hlist->FindObject(histo->GetName()));
217
218 if (h)
219 {
220 AliError(Form("Cannot adopt an already existing histogram : %s -> %s",identifier,h->GetName()));
221 return kFALSE;
222 }
223
224
225 histo->SetDirectory(0);
226
227 hlist->AddLast(histo);
228
229 return kTRUE;
230
231}
232
233//_____________________________________________________________________________
234TH1*
235AliHistogramCollection::Histo(const char* identifier) const
236{
237 /// Get histogram keyA/keyB/keyC/keyD/histoname
238 return Histo(InternalDecode(identifier,0),
239 InternalDecode(identifier,1),
240 InternalDecode(identifier,2),
241 InternalDecode(identifier,3),
242 InternalDecode(identifier,4));
243}
244
245//_____________________________________________________________________________
246TString
247AliHistogramCollection::InternalDecode(const char* identifier, Int_t index) const
248{
249 /// Extract the index-th element of the identifier (/keyA/keyB/keyC/keyD/histoname)
250 /// keyA is index=0
251 /// keyB is index=1
252 /// keyC is index=2
253 /// keyD is index=3
254 /// histo is index=4
255
256 if ( identifier[0] != '/' )
257 {
258 AliError(Form("identifier %s is malformed.",identifier));
259 return "";
260 }
261
262 TObjArray* array = TString(identifier).Tokenize("/");
263
264 if ( array->GetLast()>5 )
265 {
266 AliError(Form("identifier %s is malformed.",identifier));
267 delete array;
268 return "";
269 }
270
271 TString value("");
272
273 if ( index <= array->GetLast() )
274 {
275 value = static_cast<TObjString*>(array->At(index))->String();
276 }
277
278 delete array;
279
280 return value;
281
282// "Custom" implementation below is even slower that Tokenize... ??
283// or at least did not change the timing result enough to be worthwhile (indicating
284// the cpu time is wasted elsewhere ?)
285//
286// Int_t slashPos[6] = {0};
287// Int_t nslashes(0);
288//
289// for ( Int_t i = 0; i < identifier.Length(); ++i )
290// {
291// if ( identifier[i] == '/' )
292// {
293// slashPos[nslashes++]=i;
294// }
295// if ( nslashes > 5 )
296// {
297// AliError(Form("identifier %s is malformed.",identifier.Data()));
298// return "";
299// }
300// }
301//
302// slashPos[nslashes++]=identifier.Length();
303// --nslashes;
304//
305// if ( index < nslashes )
306// {
307// return TString(identifier(slashPos[index]+1,slashPos[index+1]-slashPos[index]-1));
308// }
309// return "";
310}
311
312//_____________________________________________________________________________
313TH1*
314AliHistogramCollection::InternalHisto(const char* identifier,
315 const char* histoname) const
316{
317 /// Get histo for (identifier,histoname)
318
319 if (!fMap)
320 {
321 return 0x0;
322 }
323
324 THashList* hlist = static_cast<THashList*>(fMap->GetValue(identifier));
325 if (!hlist)
326 {
327 return 0x0;
328 }
329
330 return static_cast<TH1*>(hlist->FindObject(histoname));
331}
332
333
334//_____________________________________________________________________________
335TString
336AliHistogramCollection::KeyA(const char* identifier) const
337{
338 /// Extract the first element of the key pair from an identifier
339
340 return InternalDecode(identifier,0);
341}
342
343//_____________________________________________________________________________
344TString
345AliHistogramCollection::KeyB(const char* identifier) const
346{
347 /// Extract the second element (if present)
348 return InternalDecode(identifier,1);
349}
350
351//_____________________________________________________________________________
352TString
353AliHistogramCollection::KeyC(const char* identifier) const
354{
355 /// Extract the 3rd element (if present)
356 return InternalDecode(identifier,2);
357}
358
359//_____________________________________________________________________________
360TString
361AliHistogramCollection::KeyD(const char* identifier) const
362{
363 /// Extract the 4th element (if present)
364 return InternalDecode(identifier,3);
365}
366
367//_____________________________________________________________________________
368Long64_t
369AliHistogramCollection::Merge(TCollection* list)
370{
371 // Merge a list of AliHistogramCollection objects with this
372 // Returns the number of merged objects (including this).
373
374 if (!list) return 0;
375
376 if (list->IsEmpty()) return 1;
377
378 TIter next(list);
379 TObject* o;
380 TList mapList;
381 Int_t count(0);
382
383 while ( ( o = next() ) )
384 {
385 AliHistogramCollection* hcol = dynamic_cast<AliHistogramCollection*>(o);
e6e96cea 386 if (!hcol) {
387 AliFatal(Form("object named \"%s\" is a %s instead of an AliHistogramCollection!", o->GetName(), o->ClassName()));
388 continue;
389 }
d899f664 390
391 ++count;
392
393 TIter nextIdentifier(hcol->fMap);
394 TObjString* identifier;
395
396 while ( ( identifier = static_cast<TObjString*>(nextIdentifier()) ) )
397 {
398 THashList* otherList = static_cast<THashList*>(hcol->fMap->GetValue(identifier->String().Data()));
399
400 TIter nextHisto(otherList);
401 TH1* h;
402
403 while ( ( h = static_cast<TH1*>(nextHisto()) ) )
404 {
405 TH1* thisHisto = Histo(KeyA(identifier->String()).Data(),
406 KeyB(identifier->String()).Data(),
407 KeyC(identifier->String()).Data(),
408 KeyD(identifier->String()).Data(),
409 h->GetName());
410
411 if (!thisHisto)
412 {
413 AliDebug(1,Form("Adopting a new histo = %s/%s",identifier->String().Data(),h->GetName()));
414
415 // this is an histogram we don't have yet. Let's add it
416 Adopt(KeyA(identifier->String()),
417 KeyB(identifier->String()),
418 KeyC(identifier->String()),
419 KeyD(identifier->String()),
420 static_cast<TH1*>(h->Clone()));
421 }
422 else
423 {
424 // add it...
425 AliDebug(1,Form("Merging histo = %s/%s (%g vs %g)",
426 identifier->String().Data(),
427 h->GetName(),
428 h->GetSumOfWeights(),
429 thisHisto->GetSumOfWeights()));
430 TList l;
431 l.Add(h);
432
433 thisHisto->Merge(&l);
434 }
435 }
436 }
437 }
438
439 AliDebug(1,Form("count=%d",count));
440
441 return count+1;
442}
443
444//_____________________________________________________________________________
445Int_t
446AliHistogramCollection::NumberOfHistograms() const
447{
448 /// Get the number of histograms we hold
449 TIter next(CreateIterator(this));
450 Int_t n(0);
451 while ( next() ) ++n;
452 return n;
453}
454
455//_____________________________________________________________________________
456Int_t
457AliHistogramCollection::NumberOfKeys() const
458{
459 /// Get the number of keys we have
460 return fMap ? fMap->GetSize() : 0;
461}
462
463//_____________________________________________________________________________
464void
465AliHistogramCollection::Print(Option_t* option) const
466{
467 /// Print all the histograms we hold, in a hopefully visually pleasing
468 /// way.
469 ///
470 /// Option can be used to select given part only, using the schema :
471 /// /*/*/*/*/*
472 /// Where the stars are wilcards for /keyA/keyB/keyC/KeyD/histoname
473 ///
474 /// if * is used it is assumed to be a wildcard for histoname
475 ///
476 /// For other selections the full syntax /*/*/*/*/* must be used.
477 ///
478 /// Use "-" as histoname to disable histogram's name output
479
480 cout << Form("AliHistogramCollection : %d keys and %d histos",
481 NumberOfKeys(), NumberOfHistograms()) << endl;
482
483 if (!strlen(option)) return;
484
485 TString sreKeyA("*");
486 TString sreKeyB("*");
487 TString sreKeyC("*");
488 TString sreKeyD("*");
489 TString sreHistoname("*");
490
491 TObjArray* select = TString(option).Tokenize("/");
492 Int_t n = select->GetLast();
493
494 if (n>=0)
495 {
496 sreHistoname = static_cast<TObjString*>(select->At(n))->String();
497 }
498 if (n>=1)
499 {
500 sreKeyD = static_cast<TObjString*>(select->At(n-1))->String();
501 }
502 if (n>=2)
503 {
504 sreKeyC = static_cast<TObjString*>(select->At(n-2))->String();
505 }
506 if (n>=3)
507 {
508 sreKeyB = static_cast<TObjString*>(select->At(n-3))->String();
509 }
510 if (n>=4)
511 {
512 sreKeyA = static_cast<TObjString*>(select->At(n-3))->String();
513 }
514
515 TRegexp reKeyA(sreKeyA,kTRUE);
516 TRegexp reKeyB(sreKeyB,kTRUE);
517 TRegexp reKeyC(sreKeyC,kTRUE);
518 TRegexp reKeyD(sreKeyD,kTRUE);
519 TRegexp reHistoname(sreHistoname,kTRUE);
520
521 delete select;
522
523 TObjArray* identifiers = SortAllIdentifiers();
524
525 TIter nextIdentifier(identifiers);
526
527 TObjString* sid(0x0);
528
529 while ( ( sid = static_cast<TObjString*>(nextIdentifier()) ) )
530 {
531 Bool_t identifierPrinted(kFALSE);
532
533 TString identifier(sid->String());
534
535 if ( InternalDecode(identifier,0).Contains(reKeyA) &&
536 InternalDecode(identifier,1).Contains(reKeyB) &&
537 InternalDecode(identifier,2).Contains(reKeyC) &&
538 InternalDecode(identifier,3).Contains(reKeyD)
539 )
540 {
541 if ( sreHistoname == "*" )
542 {
543 identifierPrinted = kTRUE;
544 cout << identifier.Data() << endl;
545 }
546
547 THashList * list = static_cast<THashList*>(fMap->GetValue(sid->String().Data()));
548 TObjArray names;
549 names.SetOwner(kTRUE);
550 TIter nextUnsortedHisto(list);
551 TH1* h;
552 while ( ( h = static_cast<TH1*>(nextUnsortedHisto()) ) )
553 {
554 names.Add(new TObjString(h->GetName()));
555 }
556 names.Sort();
557 TIter nextHistoName(&names);
558 TObjString* hname;
559 while ( ( hname = static_cast<TObjString*>(nextHistoName()) ) )
560 {
561 TString histoName(hname->String());
562 if (histoName.Contains(reHistoname) )
563 {
564 h = static_cast<TH1*>(list->FindObject(histoName.Data()));
565 if ( h->GetEntries()==0 && !fMustShowEmptyHistogram ) continue;
566 if (!identifierPrinted)
567 {
568 cout << identifier.Data() << endl;
569 identifierPrinted = kTRUE;
570 }
571 cout << Form(" %s %s Entries=%d Sum=%g",h->GetName(),h->GetTitle(),Int_t(h->GetEntries()),h->GetSumOfWeights()) << endl;
572 }
573 }
574 if (!identifierPrinted && sreHistoname=="-" )
575 {
576 // to handle the case where we used histoname="-" to disable showing the histonames,
577 // but we still want to see the matching keys maybe...
578 cout << identifier.Data() << endl;
579 }
580 }
581 }
582
583 delete identifiers;
584}
585
586//_____________________________________________________________________________
587UInt_t
588AliHistogramCollection::EstimateSize(Bool_t show) const
589{
590 /// Estimate the memory (in kilobytes) used by our histograms
591
592// sizeof(TH1) + (nbins+2)*(nbytes_per_bin) +name+title_sizes
593// if you have errors add (nbins+2)*8
594
595 TIter next(CreateIterator());
596 TH1* h;
597 UInt_t n(0);
598
599 while ( ( h = static_cast<TH1*>(next()) ) )
600 {
601 Int_t nbins = (h->GetNbinsX()+2);
602
603 if (h->GetNbinsY()>1)
604 {
605 nbins *= (h->GetNbinsY()+2);
606 }
607
608 if (h->GetNbinsZ()>1)
609 {
610 nbins *= (h->GetNbinsZ()+2);
611 }
612
613 Bool_t hasErrors = ( h->GetSumw2N() > 0 );
614
615 TString cname(h->ClassName());
616
617 Int_t nbytesPerBin(0);
618
619 if (cname.Contains(TRegexp("C$")) ) nbytesPerBin = sizeof(Char_t);
620 if (cname.Contains(TRegexp("S$")) ) nbytesPerBin = sizeof(Short_t);
621 if (cname.Contains(TRegexp("I$")) ) nbytesPerBin = sizeof(Int_t);
622 if (cname.Contains(TRegexp("F$")) ) nbytesPerBin = sizeof(Float_t);
623 if (cname.Contains(TRegexp("D$")) ) nbytesPerBin = sizeof(Double_t);
624
625 if (!nbytesPerBin)
626 {
627 AliError(Form("Could not get the number of bytes per bin for histo %s of class %s. Thus the size estimate will be wrong !",
628 h->GetName(),h->ClassName()));
629 continue;
630 }
631
632 UInt_t thissize = sizeof(h) + nbins*(nbytesPerBin) + strlen(h->GetName())
633 + strlen(h->GetTitle());
634
635 if ( hasErrors) thissize += nbins*8;
636
637 n += thissize;
638
639 if ( show )
640 {
641 AliInfo(Form("Size of %30s is %20d bytes",h->GetName(),thissize));
642 }
643 }
644
645 return n;
646}
647
648//_____________________________________________________________________________
649void AliHistogramCollection::PruneEmptyHistograms()
650{
651 /// Delete the empty histograms
652 TIter next(fMap);
653 TObjString* key;
654
655 TList toBeRemoved;
656 toBeRemoved.SetOwner(kTRUE);
657
658 while ( ( key = static_cast<TObjString*>(next()) ) )
659 {
660 TString identifier(key->String());
661 THashList* hlist = static_cast<THashList*>(fMap->GetValue(identifier.Data()));
662 TIter nextHisto(hlist);
663 TH1* h;
664 while ( ( h = static_cast<TH1*>(nextHisto())))
665 {
666 if ( h->GetEntries()==0)
667 {
668 toBeRemoved.Add(new TObjString(Form("%s%s",identifier.Data(),h->GetName())));
669 }
670 }
671 }
672
673 TIter nextTBR(&toBeRemoved);
674 while ( ( key = static_cast<TObjString*>(nextTBR()) ) )
675 {
676 Remove(key);
677 }
678}
679
680//_____________________________________________________________________________
681AliHistogramCollection*
682AliHistogramCollection::Project(const char* /*keyA*/, const char* /*keyB*/) const
683{
684 /// To be implemented : would create a new collection starting at keyA/keyB
685 AliError("Implement me !");
686 return 0x0;
687}
688
689//_____________________________________________________________________________
690TObject*
691AliHistogramCollection::Remove(TObject* key)
692{
693 ///
694 /// Remove a given histogram (given its key=full identifier=/keyA/keyB/keyC/keyD/histoname)
695 ///
696 /// Note that we do *not* remove the /keyA/keyB/keyC/keyD entry even if there's no
697 /// more histogram for this triplet.
698 ///
699 /// Not very efficient. Could be improved ?
700 ///
701
702 TObjString* str = dynamic_cast<TObjString*>(key);
703
704 if (!str)
705 {
706 AliError(Form("key is not of the expected TObjString type, but of %s",key->ClassName()));
707 return 0x0;
708 }
709
710 TString identifier(str->String());
711
712 TString skey = Form("/%s/%s/%s/%s/",
713 KeyA(identifier).Data(),
714 KeyB(identifier).Data(),
715 KeyC(identifier).Data(),
716 KeyD(identifier).Data());
717
718 THashList* hlist = dynamic_cast<THashList*>(fMap->GetValue(skey.Data()));
719
720 if (!hlist)
721 {
722 AliWarning(Form("Could not get hlist for key=%s",skey.Data()));
723 return 0x0;
724 }
725
726 TH1* h = InternalHisto(skey,HistoName(identifier.Data()));
727 if (!h)
728 {
729 AliError(Form("Could not find histo %s",identifier.Data()));
730 return 0x0;
731 }
732
733 TObject* o = hlist->Remove(h);
734 if (!o)
735 {
736 AliError("Remove failed");
737 return 0x0;
738 }
739
740// if ( hlist->IsEmpty() )
741// {
742// // we should remove the key as well
743// TObject* k = fMap->Remove(key);
744// if (!k)
745// {
746// AliError("Removal of the key failed");
747// }
748// }
749
750 return o;
751}
752
753//_____________________________________________________________________________
754TObjArray*
755AliHistogramCollection::SortAllIdentifiers() const
756{
757 /// Sort our internal identifiers. Returned array must be deleted.
758 TObjArray* identifiers = new TObjArray;
759 identifiers->SetOwner(kFALSE);
760 TIter next(fMap);
761 TObjString* sid;
762
763 while ( ( sid = static_cast<TObjString*>(next()) ) )
764 {
765 if ( !identifiers->FindObject(sid->String().Data()) )
766 {
767 identifiers->Add(sid);
768 }
769 }
770 identifiers->Sort();
771 return identifiers;
772}
773
774
775///////////////////////////////////////////////////////////////////////////////
776//
777// AliHistogramCollectionIterator
778//
779///////////////////////////////////////////////////////////////////////////////
780
781class AliHistogramCollectionIterator;
782
783//_____________________________________________________________________________
784AliHistogramCollectionIterator::AliHistogramCollectionIterator(const AliHistogramCollection* hcol, Bool_t dir)
785: fkHistogramCollection(hcol), fMapIterator(0x0), fHashListIterator(0x0), fDirection(dir)
786{
787 /// Default ctor
788}
789
790//_____________________________________________________________________________
791AliHistogramCollectionIterator&
792AliHistogramCollectionIterator::operator=(const TIterator&)
793{
794 /// Overriden operator= (imposed by Root's declaration of TIterator ?)
795 Fatal("TIterator::operator=","Not implementeable"); // because there's no clone in TIterator :-(
796 return *this;
797}
798
799//_____________________________________________________________________________
800AliHistogramCollectionIterator::~AliHistogramCollectionIterator()
801{
802 /// dtor
803 Reset();
804}
805
806//_____________________________________________________________________________
807TObject* AliHistogramCollectionIterator::Next()
808{
809 /// Advance to next object in the collection
810
811 if (!fHashListIterator)
812 {
813 if ( !fMapIterator )
814 {
815 fMapIterator = fkHistogramCollection->fMap->MakeIterator(fDirection);
816 }
817 TObjString* key = static_cast<TObjString*>(fMapIterator->Next());
818 if (!key)
819 {
820 // we are done
821 return 0x0;
822 }
823 THashList* list = static_cast<THashList*>(fkHistogramCollection->fMap->GetValue(key->String().Data()));
824 if (!list) return 0x0;
825 fHashListIterator = list->MakeIterator(fDirection);
826 }
827
828 TObject* o = fHashListIterator->Next();
829
830 if (!o)
831 {
832 delete fHashListIterator;
833 fHashListIterator = 0x0;
834 return Next();
835 }
836
837 return o;
838}
839
840//_____________________________________________________________________________
841void AliHistogramCollectionIterator::Reset()
842{
843 /// Reset the iterator
844 delete fHashListIterator;
845 delete fMapIterator;
846}