1 /**************************************************************************
2 * Copyright(c) 1998-1999, 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 **************************************************************************/
19 /// A (fake) "4D" histogram container.
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.
25 /// More helper functions might be added in the future (e.g. Project, etc...)
27 #include "AliHistogramCollection.h"
30 #include "Riostream.h"
34 #include "THashList.h"
37 #include "TObjArray.h"
38 #include "TObjString.h"
46 ClassImp(AliHistogramCollection)
48 //_____________________________________________________________________________
49 AliHistogramCollection::AliHistogramCollection(const char* name, const char* title)
50 : TNamed(name,title), fMap(0x0), fMustShowEmptyHistogram(kFALSE), fMapVersion(0), fMessages()
55 //_____________________________________________________________________________
56 AliHistogramCollection::~AliHistogramCollection()
58 /// dtor. Note that the map is owner
59 if ( fMap ) fMap->DeleteAll();
61 // PrintMessages("AliHistogramCollection::~AliHistogramCollection");
64 //_____________________________________________________________________________
66 AliHistogramCollection::Adopt(TH1* histo)
68 /// Adopt a given histogram at top level (i.e. no key)
69 return InternalAdopt("",histo);
72 //_____________________________________________________________________________
74 AliHistogramCollection::Adopt(const char* key, TH1* histo)
76 /// Adopt a given histogram, and associate it with pair (keyA)
77 return InternalAdopt(Form("/%s/",key),histo);
80 //_____________________________________________________________________________
82 AliHistogramCollection::Adopt(const char* keyA, const char* keyB, TH1* histo)
84 /// Adopt a given histogram, and associate it with pair (keyA,keyB)
85 return InternalAdopt(Form("/%s/%s/",keyA,keyB),histo);
88 //_____________________________________________________________________________
90 AliHistogramCollection::Adopt(const char* keyA, const char* keyB, const char* keyC, TH1* histo)
92 /// Adopt a given histogram, and associate it with pair (keyA,keyB,keyC)
93 return InternalAdopt(Form("/%s/%s/%s/",keyA,keyB,keyC),histo);
96 //_____________________________________________________________________________
98 AliHistogramCollection::Adopt(const char* keyA, const char* keyB, const char* keyC, const char* keyD, TH1* histo)
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);
104 //_____________________________________________________________________________
105 void AliHistogramCollection::ClearMessages()
107 /// clear pending messages
111 //_____________________________________________________________________________
113 AliHistogramCollection::CreateIterator(Bool_t direction) const
115 /// Create an iterator (must be deleted by the client)
116 return fMap ? new AliHistogramCollectionIterator(this,direction) : 0x0;
119 //_____________________________________________________________________________
120 AliHistogramCollection*
121 AliHistogramCollection::Clone(const char* name) const
123 /// Clone this collection.
124 /// We loose the messages.
126 AliHistogramCollection* newone = new AliHistogramCollection(name,GetTitle());
128 newone->fMap = static_cast<TMap*>(fMap->Clone());
129 newone->fMustShowEmptyHistogram = fMustShowEmptyHistogram;
130 newone->fMapVersion = fMapVersion;
135 //_____________________________________________________________________________
137 AliHistogramCollection::Delete(Option_t*)
139 /// Delete all the histograms
145 //_____________________________________________________________________________
147 AliHistogramCollection::FindObject(const char* identifier) const
149 /// Find an object by its full identifier.
151 return Histo(KeyA(identifier),
155 HistoName(identifier));
158 //_____________________________________________________________________________
160 AliHistogramCollection::FindObject(const TObject *key) const
163 AliWarning("This method is awfully inefficient. Please improve it or use FindObject(const char*)");
164 TIter next(CreateIterator());
166 while ( ( o=next() ) )
168 if ( o->IsEqual(key) ) return o;
173 //_____________________________________________________________________________
175 AliHistogramCollection::Histo(const char* keyA,
176 const char* histoname) const
178 /// Get histo for (keyA,histoname) triplet
180 return InternalHisto(Form("/%s/",keyA),histoname);
183 //_____________________________________________________________________________
185 AliHistogramCollection::Histo(const char* keyA, const char* keyB,
186 const char* histoname) const
188 /// Get histo for (keyA,keyB,histoname) triplet
190 return InternalHisto(Form("/%s/%s/",keyA,keyB),histoname);
193 //_____________________________________________________________________________
195 AliHistogramCollection::Histo(const char* keyA, const char* keyB, const char* keyC,
196 const char* histoname) const
198 /// Get histo for (keyA,keyB,keyC,histoname) quad
200 return InternalHisto(Form("/%s/%s/%s/",keyA,keyB,keyC),histoname);
203 //_____________________________________________________________________________
205 AliHistogramCollection::Histo(const char* keyA, const char* keyB,
206 const char* keyC, const char* keyD,
207 const char* histoname) const
209 /// Get histo for (keyA,keyB,keyC,histoname) quad
211 return InternalHisto(Form("/%s/%s/%s/%s/",keyA,keyB,keyC,keyD),histoname);
214 //_____________________________________________________________________________
216 AliHistogramCollection::HistoName(const char* identifier) const
218 /// Extract the histogram name from an identifier
220 return InternalDecode(identifier,-1);
223 //_____________________________________________________________________________
224 Bool_t AliHistogramCollection::InternalAdopt(const char* identifier, TH1* histo)
226 /// Adopt an histogram
230 Error("Adopt","Cannot adopt a null histogram");
234 THashList* hlist = 0x0;
236 hlist = static_cast<THashList*>(Map()->GetValue(identifier));
240 hlist = new THashList;
241 hlist->SetOwner(kTRUE);
242 Map()->Add(new TObjString(identifier),hlist);
243 hlist->SetName(identifier);
246 TH1* h = static_cast<TH1*>(hlist->FindObject(histo->GetName()));
250 AliError(Form("Cannot adopt an already existing histogram : %s -> %s",identifier,h->GetName()));
255 histo->SetDirectory(0);
257 hlist->AddLast(histo);
263 //_____________________________________________________________________________
265 AliHistogramCollection::Histo(const char* sidentifier) const
267 /// Get histogram keyA/keyB/keyC/keyD/histoname:action
269 TObjArray* a = TString(sidentifier).Tokenize(":");
271 TString identifier(static_cast<TObjString*>(a->At(0))->String());
274 if ( a->GetLast() > 0 )
276 action = static_cast<TObjString*>(a->At(1))->String();
280 Int_t nslashes = identifier.CountChar('/');
288 // no slash : the identifier is just the histogram name
289 h = InternalHisto("",identifier);
292 h = Histo(InternalDecode(identifier,0),
293 InternalDecode(identifier,-1));
296 h = Histo(InternalDecode(identifier,0),
297 InternalDecode(identifier,1),
298 InternalDecode(identifier,-1));
301 h = Histo(InternalDecode(identifier,0),
302 InternalDecode(identifier,1),
303 InternalDecode(identifier,2),
304 InternalDecode(identifier,-1));
307 h = Histo(InternalDecode(identifier,0),
308 InternalDecode(identifier,1),
309 InternalDecode(identifier,2),
310 InternalDecode(identifier,3),
311 InternalDecode(identifier,-1));
314 AliError(Form("Invalid identifier %s",identifier.Data()));
322 if ( action == "PX" && ( (h2 = dynamic_cast<TH2*>(h)) ) )
324 return h2->ProjectionX(NormalizeName(identifier.Data(),action.Data()).Data());
326 else if ( action == "PY" && ( (h2 = dynamic_cast<TH2*>(h)) ) )
328 return h2->ProjectionY(NormalizeName(identifier.Data(),action.Data()).Data());
330 else if ( action == "PFX" && ( (h2 = dynamic_cast<TH2*>(h)) ) )
332 return h2->ProfileX(NormalizeName(identifier.Data(),action.Data()).Data());
334 else if ( action == "PFY" && ( (h2 = dynamic_cast<TH2*>(h)) ) )
336 return h2->ProfileY(NormalizeName(identifier.Data(),action.Data()).Data());
342 AliDebug(1,Form("histogram %s not found",sidentifier));
347 //_____________________________________________________________________________
349 AliHistogramCollection::InternalDecode(const char* identifier, Int_t index) const
351 /// Extract the index-th element of the identifier (/keyA/keyB/keyC/keyD/histoname)
356 /// histo is index=-1 (i.e. last)
358 if ( strlen(identifier) > 0 && identifier[0] != '/' )
360 AliError(Form("identifier %s is malformed (should start with /)",identifier));
364 TObjArray* array = TString(identifier).Tokenize("/");
366 if ( array->GetLast()>5 )
368 AliError(Form("identifier %s is malformed (more than 5 /)",identifier));
377 value = static_cast<TObjString*>(array->Last())->String();
379 else if ( index <= array->GetLast() )
381 value = static_cast<TObjString*>(array->At(index))->String();
389 //_____________________________________________________________________________
391 AliHistogramCollection::InternalHisto(const char* identifier,
392 const char* histoname) const
394 /// Get histo for (identifier,histoname)
401 THashList* hlist = static_cast<THashList*>(Map()->GetValue(identifier));
404 TString msg(Form("Did not find hashlist for identifier=%s dir=%s",identifier,gDirectory ? gDirectory->GetName() : "" ));
405 fMessages[msg.Data()]++;
409 TH1* h = static_cast<TH1*>(hlist->FindObject(histoname));
412 TString msg(Form("Did not find histoname=%s in %s",histoname,identifier));
413 fMessages[msg.Data()]++;
419 //_____________________________________________________________________________
421 AliHistogramCollection::KeyA(const char* identifier) const
423 /// Extract the first element of the key pair from an identifier
425 return InternalDecode(identifier,0);
428 //_____________________________________________________________________________
430 AliHistogramCollection::KeyB(const char* identifier) const
432 /// Extract the second element (if present)
433 return InternalDecode(identifier,1);
436 //_____________________________________________________________________________
438 AliHistogramCollection::KeyC(const char* identifier) const
440 /// Extract the 3rd element (if present)
441 return InternalDecode(identifier,2);
444 //_____________________________________________________________________________
446 AliHistogramCollection::KeyD(const char* identifier) const
448 /// Extract the 4th element (if present)
449 return InternalDecode(identifier,3);
452 //_____________________________________________________________________________
453 TMap* AliHistogramCollection::Map() const
455 /// Wrapper to insure proper key formats (i.e. new vs old)
460 fMap->SetOwnerKeyValue(kTRUE,kTRUE);
465 if ( fMapVersion < 1 )
471 while ( ( str = static_cast<TObjString*>(next()) ) )
473 if ( str->String().Contains("./") )
475 TString newkey(str->String());
477 newkey.ReplaceAll("./","");
479 TObject* o = fMap->GetValue(str);
481 TPair* p = fMap->RemoveEntry(str);
484 AliError("oups oups oups");
488 fMap->Add(new TObjString(newkey.Data()),o);
501 //_____________________________________________________________________________
503 AliHistogramCollection::Merge(TCollection* list)
505 // Merge a list of AliHistogramCollection objects with this
506 // Returns the number of merged objects (including this).
510 if (list->IsEmpty()) return 1;
517 while ( ( o = next() ) )
519 AliHistogramCollection* hcol = dynamic_cast<AliHistogramCollection*>(o);
521 AliFatal(Form("object named \"%s\" is a %s instead of an AliHistogramCollection!", o->GetName(), o->ClassName()));
527 if ( hcol->fMap ) hcol->Map(); // to insure keys in the new format
529 TIter nextIdentifier(hcol->fMap);
530 TObjString* identifier;
532 while ( ( identifier = static_cast<TObjString*>(nextIdentifier()) ) )
534 THashList* otherList = static_cast<THashList*>(hcol->fMap->GetValue(identifier->String().Data()));
536 TIter nextHisto(otherList);
539 while ( ( h = static_cast<TH1*>(nextHisto()) ) )
541 TString newid(Form("%s%s",identifier->String().Data(),h->GetName()));
543 TH1* thisHisto = Histo(newid.Data());
547 AliDebug(1,Form("Adopting a new histo = %s%s",identifier->String().Data(),h->GetName()));
549 // this is an histogram we don't have yet. Let's add it
551 Int_t nslashes = TString(newid).CountChar('/');
558 ok = Adopt(KeyA(identifier->String()),
559 static_cast<TH1*>(h->Clone()));
562 ok = Adopt(KeyA(identifier->String()),
563 KeyB(identifier->String()),
564 static_cast<TH1*>(h->Clone()));
567 ok = Adopt(KeyA(identifier->String()),
568 KeyB(identifier->String()),
569 KeyC(identifier->String()),
570 static_cast<TH1*>(h->Clone()));
573 ok = Adopt(KeyA(identifier->String()),
574 KeyB(identifier->String()),
575 KeyC(identifier->String()),
576 KeyD(identifier->String()),
577 static_cast<TH1*>(h->Clone()));
580 AliError(Form("Invalid identifier %s",identifier->String().Data()));
586 AliError(Form("Adoption of histogram %s failed",h->GetName()));
592 AliDebug(1,Form("Merging histo = %s%s (%g vs %g)",
593 identifier->String().Data(),
595 h->GetSumOfWeights(),
596 thisHisto->GetSumOfWeights()));
598 if ( HistoSameAxis(h,thisHisto) )
607 thisHisto->Merge(&l);
614 AliDebug(1,Form("count=%d",count));
619 //_____________________________________________________________________________
620 TString AliHistogramCollection::NormalizeName(const char* identifier,const char* action) const
622 // Replace / by _ to build a root-compliant histo name
623 TString name(identifier);
626 name.ReplaceAll("/","_");
630 //_____________________________________________________________________________
632 AliHistogramCollection::NumberOfHistograms() const
634 /// Get the number of histograms we hold
635 TIter next(CreateIterator(this));
637 while ( next() ) ++n;
641 //_____________________________________________________________________________
643 AliHistogramCollection::NumberOfKeys() const
645 /// Get the number of keys we have
646 return fMap ? fMap->GetSize() : 0;
649 //_____________________________________________________________________________
651 AliHistogramCollection::Print(Option_t* option) const
653 /// Print all the histograms we hold, in a hopefully visually pleasing
656 /// Option can be used to select given part only, using the schema :
658 /// Where the stars are wilcards for /keyA/keyB/keyC/KeyD/histoname
660 /// if * is used it is assumed to be a wildcard for histoname
662 /// For other selections the full syntax /*/*/*/*/* must be used.
664 /// Use "-" as histoname to disable histogram's name output
666 cout << Form("AliHistogramCollection : %d keys and %d histos",
667 NumberOfKeys(), NumberOfHistograms()) << endl;
669 if (!strlen(option)) return;
671 TString sreKeyA("*");
672 TString sreKeyB("*");
673 TString sreKeyC("*");
674 TString sreKeyD("*");
675 TString sreHistoname("*");
677 TObjArray* select = TString(option).Tokenize("/");
678 Int_t n = select->GetLast();
682 sreHistoname = static_cast<TObjString*>(select->At(n))->String();
686 sreKeyD = static_cast<TObjString*>(select->At(n-1))->String();
690 sreKeyC = static_cast<TObjString*>(select->At(n-2))->String();
694 sreKeyB = static_cast<TObjString*>(select->At(n-3))->String();
698 sreKeyA = static_cast<TObjString*>(select->At(n-3))->String();
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);
709 TObjArray* identifiers = SortAllIdentifiers();
711 TIter nextIdentifier(identifiers);
713 TObjString* sid(0x0);
715 while ( ( sid = static_cast<TObjString*>(nextIdentifier()) ) )
717 Bool_t identifierPrinted(kFALSE);
719 TString identifier(sid->String());
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) )
727 if ( sreHistoname == "*" )
729 identifierPrinted = kTRUE;
730 cout << identifier.Data() << endl;
733 THashList * list = static_cast<THashList*>(Map()->GetValue(sid->String().Data()));
735 names.SetOwner(kTRUE);
736 TIter nextUnsortedHisto(list);
738 while ( ( h = static_cast<TH1*>(nextUnsortedHisto()) ) )
740 names.Add(new TObjString(h->GetName()));
743 TIter nextHistoName(&names);
745 while ( ( hname = static_cast<TObjString*>(nextHistoName()) ) )
747 TString histoName(hname->String());
748 if (histoName.Contains(reHistoname) )
750 h = static_cast<TH1*>(list->FindObject(histoName.Data()));
751 if ( h->GetEntries()==0 && !fMustShowEmptyHistogram ) continue;
752 if (!identifierPrinted)
754 cout << identifier.Data() << endl;
755 identifierPrinted = kTRUE;
757 cout << Form(" %s %s Entries=%d Sum=%g",h->GetName(),h->GetTitle(),Int_t(h->GetEntries()),h->GetSumOfWeights()) << endl;
760 if (!identifierPrinted && sreHistoname=="-" )
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;
772 //_____________________________________________________________________________
774 AliHistogramCollection::PrintMessages(const char* prefix) const
776 /// Print pending messages
778 std::map<std::string,int>::const_iterator it;
780 for ( it = fMessages.begin(); it != fMessages.end(); ++it )
782 cout << Form("%s : message %s appeared %5d times",prefix,it->first.c_str(),it->second) << endl;
787 //_____________________________________________________________________________
789 AliHistogramCollection::EstimateSize(Bool_t show) const
791 /// Estimate the memory (in kilobytes) used by our histograms
793 // sizeof(TH1) + (nbins+2)*(nbytes_per_bin) +name+title_sizes
794 // if you have errors add (nbins+2)*8
796 TIter next(CreateIterator());
800 while ( ( h = static_cast<TH1*>(next()) ) )
802 Int_t nbins = (h->GetNbinsX()+2);
804 if (h->GetNbinsY()>1)
806 nbins *= (h->GetNbinsY()+2);
809 if (h->GetNbinsZ()>1)
811 nbins *= (h->GetNbinsZ()+2);
814 Bool_t hasErrors = ( h->GetSumw2N() > 0 );
816 TString cname(h->ClassName());
818 Int_t nbytesPerBin(0);
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);
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()));
833 UInt_t thissize = sizeof(h) + nbins*(nbytesPerBin) + strlen(h->GetName())
834 + strlen(h->GetTitle());
836 if ( hasErrors) thissize += nbins*8;
842 AliInfo(Form("Size of %30s is %20d bytes",h->GetName(),thissize));
849 //_____________________________________________________________________________
850 void AliHistogramCollection::PruneEmptyHistograms()
852 /// Delete the empty histograms
857 toBeRemoved.SetOwner(kTRUE);
859 while ( ( key = static_cast<TObjString*>(next()) ) )
861 TString identifier(key->String());
862 THashList* hlist = static_cast<THashList*>(Map()->GetValue(identifier.Data()));
863 TIter nextHisto(hlist);
865 while ( ( h = static_cast<TH1*>(nextHisto())))
867 if ( h->GetEntries()==0)
869 toBeRemoved.Add(new TObjString(Form("%s%s",identifier.Data(),h->GetName())));
874 TIter nextTBR(&toBeRemoved);
875 while ( ( key = static_cast<TObjString*>(nextTBR()) ) )
881 //_____________________________________________________________________________
882 AliHistogramCollection*
883 AliHistogramCollection::Project(const char* keyA, const char* keyB, const char* keyC, const char* keyD) const
885 /// To be implemented : would create a new collection starting at keyA/keyB/keyC/keyD
887 if (!fMap) return 0x0;
889 AliHistogramCollection* hc = new AliHistogramCollection(Form("%s %s/%s/%s/%s",GetName(),keyA,keyB,keyC,keyD),
895 while ( ( str = static_cast<TObjString*>(next()) ) )
897 TString identifier = str->String();
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 ));
904 if ( !copy ) continue;
906 THashList* list = static_cast<THashList*>(Map()->GetValue(identifier.Data()));
908 TIter nextHisto(list);
911 while ( ( h = static_cast<TH1*>(nextHisto()) ) )
913 TH1* hclone = static_cast<TH1*>(h->Clone());
915 TString newkey(identifier.Data());
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),"");
922 if (newkey=="/") newkey="";
924 hc->InternalAdopt(newkey.Data(),hclone);
931 //_____________________________________________________________________________
933 AliHistogramCollection::Remove(TObject* key)
936 /// Remove a given histogram (given its key=full identifier=/keyA/keyB/keyC/keyD/histoname)
938 /// Note that we do *not* remove the /keyA/keyB/keyC/keyD entry even if there's no
939 /// more histogram for this triplet.
941 /// Not very efficient. Could be improved ?
944 TObjString* str = dynamic_cast<TObjString*>(key);
948 AliError(Form("key is not of the expected TObjString type, but of %s",key->ClassName()));
952 TString identifier(str->String());
954 Int_t nslashes = TString(identifier).CountChar('/');
962 KeyA(identifier).Data());
965 skey = Form("/%s/%s/",
966 KeyA(identifier).Data(),
967 KeyB(identifier).Data());
970 skey = Form("/%s/%s/%s/",
971 KeyA(identifier).Data(),
972 KeyB(identifier).Data(),
973 KeyC(identifier).Data());
976 skey = Form("/%s/%s/%s/%s/",
977 KeyA(identifier).Data(),
978 KeyB(identifier).Data(),
979 KeyC(identifier).Data(),
980 KeyD(identifier).Data()
988 THashList* hlist = dynamic_cast<THashList*>(Map()->GetValue(skey.Data()));
992 AliWarning(Form("Could not get hlist for key=%s",skey.Data()));
996 TH1* h = InternalHisto(skey,HistoName(identifier.Data()));
999 AliError(Form("Could not find histo %s",identifier.Data()));
1003 TObject* o = hlist->Remove(h);
1006 AliError("Remove failed");
1010 // if ( hlist->IsEmpty() )
1012 // // we should remove the key as well
1013 // TObject* k = fMap->Remove(key);
1016 // AliError("Removal of the key failed");
1023 //______________________________________________________________________________
1024 Bool_t AliHistogramCollection::HistoSameAxis(TH1 *h0, TH1 *h1) const
1026 // shameless copy from TProofPlayerRemote::HistoSameAxis
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).
1032 if (!h0 || !h1) return rc;
1034 TAxis *a0 = 0, *a1 = 0;
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;
1043 // Check Y, if needed
1044 if (h0->GetDimension() > 1) {
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;
1053 // Check Z, if needed
1054 if (h0->GetDimension() > 2) {
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;
1067 //_____________________________________________________________________________
1069 AliHistogramCollection::SortAllIdentifiers() const
1071 /// Sort our internal identifiers. Returned array must be deleted.
1072 TObjArray* identifiers = new TObjArray;
1073 identifiers->SetOwner(kFALSE);
1077 while ( ( sid = static_cast<TObjString*>(next()) ) )
1079 if ( !identifiers->FindObject(sid->String().Data()) )
1081 identifiers->Add(sid);
1084 identifiers->Sort();
1089 ///////////////////////////////////////////////////////////////////////////////
1091 // AliHistogramCollectionIterator
1093 ///////////////////////////////////////////////////////////////////////////////
1095 class AliHistogramCollectionIterator;
1097 //_____________________________________________________________________________
1098 AliHistogramCollectionIterator::AliHistogramCollectionIterator(const AliHistogramCollection* hcol, Bool_t dir)
1099 : fkHistogramCollection(hcol), fMapIterator(0x0), fHashListIterator(0x0), fDirection(dir)
1104 //_____________________________________________________________________________
1105 AliHistogramCollectionIterator&
1106 AliHistogramCollectionIterator::operator=(const TIterator&)
1108 /// Overriden operator= (imposed by Root's declaration of TIterator ?)
1109 Fatal("TIterator::operator=","Not implementeable"); // because there's no clone in TIterator :-(
1113 //_____________________________________________________________________________
1114 AliHistogramCollectionIterator::~AliHistogramCollectionIterator()
1120 //_____________________________________________________________________________
1121 TObject* AliHistogramCollectionIterator::Next()
1123 /// Advance to next object in the collection
1125 if (!fHashListIterator)
1127 if ( !fMapIterator )
1129 fMapIterator = fkHistogramCollection->fMap->MakeIterator(fDirection);
1131 TObjString* key = static_cast<TObjString*>(fMapIterator->Next());
1137 THashList* list = static_cast<THashList*>(fkHistogramCollection->Map()->GetValue(key->String().Data()));
1138 if (!list) return 0x0;
1139 fHashListIterator = list->MakeIterator(fDirection);
1142 TObject* o = fHashListIterator->Next();
1146 delete fHashListIterator;
1147 fHashListIterator = 0x0;
1154 //_____________________________________________________________________________
1155 void AliHistogramCollectionIterator::Reset()
1157 /// Reset the iterator
1158 delete fHashListIterator;
1159 delete fMapIterator;