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"
44 ClassImp(AliHistogramCollection)
46 //_____________________________________________________________________________
47 AliHistogramCollection::AliHistogramCollection(const char* name, const char* title)
48 : TNamed(name,title), fMap(0x0), fMustShowEmptyHistogram(kFALSE), fMapVersion(0), fMessages()
53 //_____________________________________________________________________________
54 AliHistogramCollection::~AliHistogramCollection()
56 /// dtor. Note that the map is owner
57 if ( fMap ) fMap->DeleteAll();
59 // PrintMessages("AliHistogramCollection::~AliHistogramCollection");
62 //_____________________________________________________________________________
64 AliHistogramCollection::Adopt(TH1* histo)
66 /// Adopt a given histogram at top level (i.e. no key)
67 return InternalAdopt("",histo);
70 //_____________________________________________________________________________
72 AliHistogramCollection::Adopt(const char* key, TH1* histo)
74 /// Adopt a given histogram, and associate it with pair (keyA)
75 return InternalAdopt(Form("/%s/",key),histo);
78 //_____________________________________________________________________________
80 AliHistogramCollection::Adopt(const char* keyA, const char* keyB, TH1* histo)
82 /// Adopt a given histogram, and associate it with pair (keyA,keyB)
83 return InternalAdopt(Form("/%s/%s/",keyA,keyB),histo);
86 //_____________________________________________________________________________
88 AliHistogramCollection::Adopt(const char* keyA, const char* keyB, const char* keyC, TH1* histo)
90 /// Adopt a given histogram, and associate it with pair (keyA,keyB,keyC)
91 return InternalAdopt(Form("/%s/%s/%s/",keyA,keyB,keyC),histo);
94 //_____________________________________________________________________________
96 AliHistogramCollection::Adopt(const char* keyA, const char* keyB, const char* keyC, const char* keyD, TH1* histo)
98 /// Adopt a given histogram, and associate it with pair (keyA,keyB,keyC,keyD)
99 return InternalAdopt(Form("/%s/%s/%s/%s/",keyA,keyB,keyC,keyD),histo);
102 //_____________________________________________________________________________
103 void AliHistogramCollection::ClearMessages()
105 /// clear pending messages
109 //_____________________________________________________________________________
111 AliHistogramCollection::CreateIterator(Bool_t direction) const
113 /// Create an iterator (must be deleted by the client)
114 return fMap ? new AliHistogramCollectionIterator(this,direction) : 0x0;
117 //_____________________________________________________________________________
118 AliHistogramCollection*
119 AliHistogramCollection::Clone(const char* name) const
121 /// Clone this collection.
122 /// We loose the messages.
124 AliHistogramCollection* newone = new AliHistogramCollection(name,GetTitle());
126 newone->fMap = static_cast<TMap*>(fMap->Clone());
127 newone->fMustShowEmptyHistogram = fMustShowEmptyHistogram;
128 newone->fMapVersion = fMapVersion;
133 //_____________________________________________________________________________
135 AliHistogramCollection::Delete(Option_t*)
137 /// Delete all the histograms
143 //_____________________________________________________________________________
145 AliHistogramCollection::FindObject(const char* identifier) const
147 /// Find an object by its full identifier.
149 return Histo(KeyA(identifier),
153 HistoName(identifier));
156 //_____________________________________________________________________________
158 AliHistogramCollection::FindObject(const TObject *key) const
161 AliWarning("This method is awfully inefficient. Please improve it or use FindObject(const char*)");
162 TIter next(CreateIterator());
164 while ( ( o=next() ) )
166 if ( o->IsEqual(key) ) return o;
171 //_____________________________________________________________________________
173 AliHistogramCollection::Histo(const char* keyA,
174 const char* histoname) const
176 /// Get histo for (keyA,histoname) triplet
178 return InternalHisto(Form("/%s/",keyA),histoname);
181 //_____________________________________________________________________________
183 AliHistogramCollection::Histo(const char* keyA, const char* keyB,
184 const char* histoname) const
186 /// Get histo for (keyA,keyB,histoname) triplet
188 return InternalHisto(Form("/%s/%s/",keyA,keyB),histoname);
191 //_____________________________________________________________________________
193 AliHistogramCollection::Histo(const char* keyA, const char* keyB, const char* keyC,
194 const char* histoname) const
196 /// Get histo for (keyA,keyB,keyC,histoname) quad
198 return InternalHisto(Form("/%s/%s/%s/",keyA,keyB,keyC),histoname);
201 //_____________________________________________________________________________
203 AliHistogramCollection::Histo(const char* keyA, const char* keyB,
204 const char* keyC, const char* keyD,
205 const char* histoname) const
207 /// Get histo for (keyA,keyB,keyC,histoname) quad
209 return InternalHisto(Form("/%s/%s/%s/%s/",keyA,keyB,keyC,keyD),histoname);
212 //_____________________________________________________________________________
214 AliHistogramCollection::HistoName(const char* identifier) const
216 /// Extract the histogram name from an identifier
218 return InternalDecode(identifier,-1);
221 //_____________________________________________________________________________
222 Bool_t AliHistogramCollection::InternalAdopt(const char* identifier, TH1* histo)
224 /// Adopt an histogram
228 Error("Adopt","Cannot adopt a null histogram");
232 THashList* hlist = 0x0;
234 hlist = static_cast<THashList*>(Map()->GetValue(identifier));
238 hlist = new THashList;
239 hlist->SetOwner(kTRUE);
240 Map()->Add(new TObjString(identifier),hlist);
241 hlist->SetName(identifier);
244 TH1* h = static_cast<TH1*>(hlist->FindObject(histo->GetName()));
248 AliError(Form("Cannot adopt an already existing histogram : %s -> %s",identifier,h->GetName()));
253 histo->SetDirectory(0);
255 hlist->AddLast(histo);
261 //_____________________________________________________________________________
263 AliHistogramCollection::Histo(const char* sidentifier) const
265 /// Get histogram keyA/keyB/keyC/keyD/histoname:action
267 TObjArray* a = TString(sidentifier).Tokenize(":");
269 TString identifier(static_cast<TObjString*>(a->At(0))->String());
272 if ( a->GetLast() > 0 )
274 action = static_cast<TObjString*>(a->At(1))->String();
278 Int_t nslashes = identifier.CountChar('/');
286 // no slash : the identifier is just the histogram name
287 h = InternalHisto("",identifier);
290 h = Histo(InternalDecode(identifier,0),
291 InternalDecode(identifier,-1));
294 h = Histo(InternalDecode(identifier,0),
295 InternalDecode(identifier,1),
296 InternalDecode(identifier,-1));
299 h = Histo(InternalDecode(identifier,0),
300 InternalDecode(identifier,1),
301 InternalDecode(identifier,2),
302 InternalDecode(identifier,-1));
305 h = Histo(InternalDecode(identifier,0),
306 InternalDecode(identifier,1),
307 InternalDecode(identifier,2),
308 InternalDecode(identifier,3),
309 InternalDecode(identifier,-1));
312 AliError(Form("Invalid identifier %s",identifier.Data()));
320 if ( action == "PX" && ( (h2 = dynamic_cast<TH2*>(h)) ) )
322 return h2->ProjectionX(NormalizeName(identifier.Data(),action.Data()).Data());
324 else if ( action == "PY" && ( (h2 = dynamic_cast<TH2*>(h)) ) )
326 return h2->ProjectionY(NormalizeName(identifier.Data(),action.Data()).Data());
328 else if ( action == "PFX" && ( (h2 = dynamic_cast<TH2*>(h)) ) )
330 return h2->ProfileX(NormalizeName(identifier.Data(),action.Data()).Data());
332 else if ( action == "PFY" && ( (h2 = dynamic_cast<TH2*>(h)) ) )
334 return h2->ProfileY(NormalizeName(identifier.Data(),action.Data()).Data());
340 AliDebug(1,Form("histogram %s not found",sidentifier));
345 //_____________________________________________________________________________
347 AliHistogramCollection::InternalDecode(const char* identifier, Int_t index) const
349 /// Extract the index-th element of the identifier (/keyA/keyB/keyC/keyD/histoname)
354 /// histo is index=-1 (i.e. last)
356 if ( strlen(identifier) > 0 && identifier[0] != '/' )
358 AliError(Form("identifier %s is malformed (should start with /)",identifier));
362 TObjArray* array = TString(identifier).Tokenize("/");
364 if ( array->GetLast()>5 )
366 AliError(Form("identifier %s is malformed (more than 5 /)",identifier));
375 value = static_cast<TObjString*>(array->Last())->String();
377 else if ( index <= array->GetLast() )
379 value = static_cast<TObjString*>(array->At(index))->String();
387 //_____________________________________________________________________________
389 AliHistogramCollection::InternalHisto(const char* identifier,
390 const char* histoname) const
392 /// Get histo for (identifier,histoname)
399 THashList* hlist = static_cast<THashList*>(Map()->GetValue(identifier));
402 TString msg(Form("Did not find hashlist for identifier=%s dir=%s",identifier,gDirectory ? gDirectory->GetName() : "" ));
403 fMessages[msg.Data()]++;
407 TH1* h = static_cast<TH1*>(hlist->FindObject(histoname));
410 TString msg(Form("Did not find histoname=%s in %s",histoname,identifier));
411 fMessages[msg.Data()]++;
417 //_____________________________________________________________________________
419 AliHistogramCollection::KeyA(const char* identifier) const
421 /// Extract the first element of the key pair from an identifier
423 return InternalDecode(identifier,0);
426 //_____________________________________________________________________________
428 AliHistogramCollection::KeyB(const char* identifier) const
430 /// Extract the second element (if present)
431 return InternalDecode(identifier,1);
434 //_____________________________________________________________________________
436 AliHistogramCollection::KeyC(const char* identifier) const
438 /// Extract the 3rd element (if present)
439 return InternalDecode(identifier,2);
442 //_____________________________________________________________________________
444 AliHistogramCollection::KeyD(const char* identifier) const
446 /// Extract the 4th element (if present)
447 return InternalDecode(identifier,3);
450 //_____________________________________________________________________________
451 TMap* AliHistogramCollection::Map() const
453 /// Wrapper to insure proper key formats (i.e. new vs old)
458 fMap->SetOwnerKeyValue(kTRUE,kTRUE);
463 if ( fMapVersion < 1 )
469 while ( ( str = static_cast<TObjString*>(next()) ) )
471 if ( str->String().Contains("./") )
473 TString newkey(str->String());
475 newkey.ReplaceAll("./","");
477 TObject* o = fMap->GetValue(str);
479 TPair* p = fMap->RemoveEntry(str);
482 AliError("oups oups oups");
486 fMap->Add(new TObjString(newkey.Data()),o);
499 //_____________________________________________________________________________
501 AliHistogramCollection::Merge(TCollection* list)
503 // Merge a list of AliHistogramCollection objects with this
504 // Returns the number of merged objects (including this).
508 if (list->IsEmpty()) return 1;
515 while ( ( o = next() ) )
517 AliHistogramCollection* hcol = dynamic_cast<AliHistogramCollection*>(o);
519 AliFatal(Form("object named \"%s\" is a %s instead of an AliHistogramCollection!", o->GetName(), o->ClassName()));
525 if ( hcol->fMap ) hcol->Map(); // to insure keys in the new format
527 TIter nextIdentifier(hcol->fMap);
528 TObjString* identifier;
530 while ( ( identifier = static_cast<TObjString*>(nextIdentifier()) ) )
532 THashList* otherList = static_cast<THashList*>(hcol->fMap->GetValue(identifier->String().Data()));
534 TIter nextHisto(otherList);
537 while ( ( h = static_cast<TH1*>(nextHisto()) ) )
539 TString newid(Form("%s%s",identifier->String().Data(),h->GetName()));
541 TH1* thisHisto = Histo(newid.Data());
545 AliDebug(1,Form("Adopting a new histo = %s%s",identifier->String().Data(),h->GetName()));
547 // this is an histogram we don't have yet. Let's add it
549 Int_t nslashes = TString(newid).CountChar('/');
556 ok = Adopt(KeyA(identifier->String()),
557 static_cast<TH1*>(h->Clone()));
560 ok = Adopt(KeyA(identifier->String()),
561 KeyB(identifier->String()),
562 static_cast<TH1*>(h->Clone()));
565 ok = Adopt(KeyA(identifier->String()),
566 KeyB(identifier->String()),
567 KeyC(identifier->String()),
568 static_cast<TH1*>(h->Clone()));
571 ok = Adopt(KeyA(identifier->String()),
572 KeyB(identifier->String()),
573 KeyC(identifier->String()),
574 KeyD(identifier->String()),
575 static_cast<TH1*>(h->Clone()));
578 AliError(Form("Invalid identifier %s",identifier->String().Data()));
584 AliError(Form("Adoption of histogram %s failed",h->GetName()));
590 AliDebug(1,Form("Merging histo = %s%s (%g vs %g)",
591 identifier->String().Data(),
593 h->GetSumOfWeights(),
594 thisHisto->GetSumOfWeights()));
596 if ( HistoSameAxis(h,thisHisto) )
605 thisHisto->Merge(&l);
612 AliDebug(1,Form("count=%d",count));
617 //_____________________________________________________________________________
618 TString AliHistogramCollection::NormalizeName(const char* identifier,const char* action) const
620 // Replace / by _ to build a root-compliant histo name
621 TString name(identifier);
624 name.ReplaceAll("/","_");
628 //_____________________________________________________________________________
630 AliHistogramCollection::NumberOfHistograms() const
632 /// Get the number of histograms we hold
633 TIter next(CreateIterator(this));
635 while ( next() ) ++n;
639 //_____________________________________________________________________________
641 AliHistogramCollection::NumberOfKeys() const
643 /// Get the number of keys we have
644 return fMap ? fMap->GetSize() : 0;
647 //_____________________________________________________________________________
649 AliHistogramCollection::Print(Option_t* option) const
651 /// Print all the histograms we hold, in a hopefully visually pleasing
654 /// Option can be used to select given part only, using the schema :
656 /// Where the stars are wilcards for /keyA/keyB/keyC/KeyD/histoname
658 /// if * is used it is assumed to be a wildcard for histoname
660 /// For other selections the full syntax /*/*/*/*/* must be used.
662 /// Use "-" as histoname to disable histogram's name output
664 cout << Form("AliHistogramCollection : %d keys and %d histos",
665 NumberOfKeys(), NumberOfHistograms()) << endl;
667 if (!strlen(option)) return;
669 TString sreKeyA("*");
670 TString sreKeyB("*");
671 TString sreKeyC("*");
672 TString sreKeyD("*");
673 TString sreHistoname("*");
675 TObjArray* select = TString(option).Tokenize("/");
676 Int_t n = select->GetLast();
680 sreHistoname = static_cast<TObjString*>(select->At(n))->String();
684 sreKeyD = static_cast<TObjString*>(select->At(n-1))->String();
688 sreKeyC = static_cast<TObjString*>(select->At(n-2))->String();
692 sreKeyB = static_cast<TObjString*>(select->At(n-3))->String();
696 sreKeyA = static_cast<TObjString*>(select->At(n-3))->String();
699 TRegexp reKeyA(sreKeyA,kTRUE);
700 TRegexp reKeyB(sreKeyB,kTRUE);
701 TRegexp reKeyC(sreKeyC,kTRUE);
702 TRegexp reKeyD(sreKeyD,kTRUE);
703 TRegexp reHistoname(sreHistoname,kTRUE);
707 TObjArray* identifiers = SortAllIdentifiers();
709 TIter nextIdentifier(identifiers);
711 TObjString* sid(0x0);
713 while ( ( sid = static_cast<TObjString*>(nextIdentifier()) ) )
715 Bool_t identifierPrinted(kFALSE);
717 TString identifier(sid->String());
719 if ( ( InternalDecode(identifier,0).Contains(reKeyA) &&
720 InternalDecode(identifier,1).Contains(reKeyB) &&
721 InternalDecode(identifier,2).Contains(reKeyC) &&
722 InternalDecode(identifier,3).Contains(reKeyD) )
725 if ( sreHistoname == "*" )
727 identifierPrinted = kTRUE;
728 cout << identifier.Data() << endl;
731 THashList * list = static_cast<THashList*>(Map()->GetValue(sid->String().Data()));
733 names.SetOwner(kTRUE);
734 TIter nextUnsortedHisto(list);
736 while ( ( h = static_cast<TH1*>(nextUnsortedHisto()) ) )
738 names.Add(new TObjString(h->GetName()));
741 TIter nextHistoName(&names);
743 while ( ( hname = static_cast<TObjString*>(nextHistoName()) ) )
745 TString histoName(hname->String());
746 if (histoName.Contains(reHistoname) )
748 h = static_cast<TH1*>(list->FindObject(histoName.Data()));
749 if ( h->GetEntries()==0 && !fMustShowEmptyHistogram ) continue;
750 if (!identifierPrinted)
752 cout << identifier.Data() << endl;
753 identifierPrinted = kTRUE;
755 cout << Form(" %s %s Entries=%d Sum=%g",h->GetName(),h->GetTitle(),Int_t(h->GetEntries()),h->GetSumOfWeights()) << endl;
758 if (!identifierPrinted && sreHistoname=="-" )
760 // to handle the case where we used histoname="-" to disable showing the histonames,
761 // but we still want to see the matching keys maybe...
762 cout << identifier.Data() << endl;
770 //_____________________________________________________________________________
772 AliHistogramCollection::PrintMessages(const char* prefix) const
774 /// Print pending messages
776 std::map<std::string,int>::const_iterator it;
778 for ( it = fMessages.begin(); it != fMessages.end(); ++it )
780 cout << Form("%s : message %s appeared %5d times",prefix,it->first.c_str(),it->second) << endl;
785 //_____________________________________________________________________________
787 AliHistogramCollection::EstimateSize(Bool_t show) const
789 /// Estimate the memory (in kilobytes) used by our histograms
791 // sizeof(TH1) + (nbins+2)*(nbytes_per_bin) +name+title_sizes
792 // if you have errors add (nbins+2)*8
794 TIter next(CreateIterator());
798 while ( ( h = static_cast<TH1*>(next()) ) )
800 Int_t nbins = (h->GetNbinsX()+2);
802 if (h->GetNbinsY()>1)
804 nbins *= (h->GetNbinsY()+2);
807 if (h->GetNbinsZ()>1)
809 nbins *= (h->GetNbinsZ()+2);
812 Bool_t hasErrors = ( h->GetSumw2N() > 0 );
814 TString cname(h->ClassName());
816 Int_t nbytesPerBin(0);
818 if (cname.Contains(TRegexp("C$")) ) nbytesPerBin = sizeof(Char_t);
819 if (cname.Contains(TRegexp("S$")) ) nbytesPerBin = sizeof(Short_t);
820 if (cname.Contains(TRegexp("I$")) ) nbytesPerBin = sizeof(Int_t);
821 if (cname.Contains(TRegexp("F$")) ) nbytesPerBin = sizeof(Float_t);
822 if (cname.Contains(TRegexp("D$")) ) nbytesPerBin = sizeof(Double_t);
826 AliError(Form("Could not get the number of bytes per bin for histo %s of class %s. Thus the size estimate will be wrong !",
827 h->GetName(),h->ClassName()));
831 UInt_t thissize = sizeof(h) + nbins*(nbytesPerBin) + strlen(h->GetName())
832 + strlen(h->GetTitle());
834 if ( hasErrors) thissize += nbins*8;
840 AliInfo(Form("Size of %30s is %20d bytes",h->GetName(),thissize));
847 //_____________________________________________________________________________
848 void AliHistogramCollection::PruneEmptyHistograms()
850 /// Delete the empty histograms
855 toBeRemoved.SetOwner(kTRUE);
857 while ( ( key = static_cast<TObjString*>(next()) ) )
859 TString identifier(key->String());
860 THashList* hlist = static_cast<THashList*>(Map()->GetValue(identifier.Data()));
861 TIter nextHisto(hlist);
863 while ( ( h = static_cast<TH1*>(nextHisto())))
865 if ( h->GetEntries()==0)
867 toBeRemoved.Add(new TObjString(Form("%s%s",identifier.Data(),h->GetName())));
872 TIter nextTBR(&toBeRemoved);
873 while ( ( key = static_cast<TObjString*>(nextTBR()) ) )
879 //_____________________________________________________________________________
880 AliHistogramCollection*
881 AliHistogramCollection::Project(const char* keyA, const char* keyB, const char* keyC, const char* keyD) const
883 /// To be implemented : would create a new collection starting at keyA/keyB/keyC/keyD
885 if (!fMap) return 0x0;
887 AliHistogramCollection* hc = new AliHistogramCollection(Form("%s %s/%s/%s/%s",GetName(),keyA,keyB,keyC,keyD),
893 while ( ( str = static_cast<TObjString*>(next()) ) )
895 TString identifier = str->String();
897 Bool_t copy= ( KeyA(identifier) == keyA &&
898 ( strlen(keyB)==0 || KeyB(identifier)==keyB ) &&
899 ( strlen(keyC)==0 || KeyC(identifier)==keyC ) &&
900 ( strlen(keyD)==0 || KeyD(identifier)==keyD ));
902 if ( !copy ) continue;
904 THashList* list = static_cast<THashList*>(Map()->GetValue(identifier.Data()));
906 TIter nextHisto(list);
909 while ( ( h = static_cast<TH1*>(nextHisto()) ) )
911 TH1* hclone = static_cast<TH1*>(h->Clone());
913 TString newkey(identifier.Data());
915 if ( strlen(keyD) > 0 ) newkey.ReplaceAll(Form("/%s",keyD),"");
916 if ( strlen(keyC) > 0 ) newkey.ReplaceAll(Form("/%s",keyC),"");
917 if ( strlen(keyB) > 0 ) newkey.ReplaceAll(Form("/%s",keyB),"");
918 if ( strlen(keyA) > 0 ) newkey.ReplaceAll(Form("/%s",keyA),"");
920 if (newkey=="/") newkey="";
922 hc->InternalAdopt(newkey.Data(),hclone);
929 //_____________________________________________________________________________
931 AliHistogramCollection::Remove(TObject* key)
934 /// Remove a given histogram (given its key=full identifier=/keyA/keyB/keyC/keyD/histoname)
936 /// Note that we do *not* remove the /keyA/keyB/keyC/keyD entry even if there's no
937 /// more histogram for this triplet.
939 /// Not very efficient. Could be improved ?
942 TObjString* str = dynamic_cast<TObjString*>(key);
946 AliError(Form("key is not of the expected TObjString type, but of %s",key->ClassName()));
950 TString identifier(str->String());
952 Int_t nslashes = TString(identifier).CountChar('/');
960 KeyA(identifier).Data());
963 skey = Form("/%s/%s/",
964 KeyA(identifier).Data(),
965 KeyB(identifier).Data());
968 skey = Form("/%s/%s/%s/",
969 KeyA(identifier).Data(),
970 KeyB(identifier).Data(),
971 KeyC(identifier).Data());
974 skey = Form("/%s/%s/%s/%s/",
975 KeyA(identifier).Data(),
976 KeyB(identifier).Data(),
977 KeyC(identifier).Data(),
978 KeyD(identifier).Data()
986 THashList* hlist = dynamic_cast<THashList*>(Map()->GetValue(skey.Data()));
990 AliWarning(Form("Could not get hlist for key=%s",skey.Data()));
994 TH1* h = InternalHisto(skey,HistoName(identifier.Data()));
997 AliError(Form("Could not find histo %s",identifier.Data()));
1001 TObject* o = hlist->Remove(h);
1004 AliError("Remove failed");
1008 // if ( hlist->IsEmpty() )
1010 // // we should remove the key as well
1011 // TObject* k = fMap->Remove(key);
1014 // AliError("Removal of the key failed");
1021 //______________________________________________________________________________
1022 Bool_t AliHistogramCollection::HistoSameAxis(TH1 *h0, TH1 *h1) const
1024 // shameless copy from TProofPlayerRemote::HistoSameAxis
1026 // Return kTRUE is the histograms 'h0' and 'h1' have the same binning and ranges
1027 // on the axis (i.e. if they can be just Add-ed for merging).
1030 if (!h0 || !h1) return rc;
1032 TAxis *a0 = 0, *a1 = 0;
1035 a0 = h0->GetXaxis();
1036 a1 = h1->GetXaxis();
1037 if (a0->GetNbins() == a1->GetNbins())
1038 if (TMath::Abs(a0->GetXmax() - a1->GetXmax()) < 1.e-9)
1039 if (TMath::Abs(a0->GetXmin() - a1->GetXmin()) < 1.e-9) rc = kTRUE;
1041 // Check Y, if needed
1042 if (h0->GetDimension() > 1) {
1044 a0 = h0->GetYaxis();
1045 a1 = h1->GetYaxis();
1046 if (a0->GetNbins() == a1->GetNbins())
1047 if (TMath::Abs(a0->GetXmax() - a1->GetXmax()) < 1.e-9)
1048 if (TMath::Abs(a0->GetXmin() - a1->GetXmin()) < 1.e-9) rc = kTRUE;
1051 // Check Z, if needed
1052 if (h0->GetDimension() > 2) {
1054 a0 = h0->GetZaxis();
1055 a1 = h1->GetZaxis();
1056 if (a0->GetNbins() == a1->GetNbins())
1057 if (TMath::Abs(a0->GetXmax() - a1->GetXmax()) < 1.e-9)
1058 if (TMath::Abs(a0->GetXmin() - a1->GetXmin()) < 1.e-9) rc = kTRUE;
1065 //_____________________________________________________________________________
1067 AliHistogramCollection::SortAllIdentifiers() const
1069 /// Sort our internal identifiers. Returned array must be deleted.
1070 TObjArray* identifiers = new TObjArray;
1071 identifiers->SetOwner(kFALSE);
1075 while ( ( sid = static_cast<TObjString*>(next()) ) )
1077 if ( !identifiers->FindObject(sid->String().Data()) )
1079 identifiers->Add(sid);
1082 identifiers->Sort();
1087 ///////////////////////////////////////////////////////////////////////////////
1089 // AliHistogramCollectionIterator
1091 ///////////////////////////////////////////////////////////////////////////////
1093 class AliHistogramCollectionIterator;
1095 //_____________________________________________________________________________
1096 AliHistogramCollectionIterator::AliHistogramCollectionIterator(const AliHistogramCollection* hcol, Bool_t dir)
1097 : fkHistogramCollection(hcol), fMapIterator(0x0), fHashListIterator(0x0), fDirection(dir)
1102 //_____________________________________________________________________________
1103 AliHistogramCollectionIterator&
1104 AliHistogramCollectionIterator::operator=(const TIterator&)
1106 /// Overriden operator= (imposed by Root's declaration of TIterator ?)
1107 Fatal("TIterator::operator=","Not implementeable"); // because there's no clone in TIterator :-(
1111 //_____________________________________________________________________________
1112 AliHistogramCollectionIterator::~AliHistogramCollectionIterator()
1118 //_____________________________________________________________________________
1119 TObject* AliHistogramCollectionIterator::Next()
1121 /// Advance to next object in the collection
1123 if (!fHashListIterator)
1125 if ( !fMapIterator )
1127 fMapIterator = fkHistogramCollection->fMap->MakeIterator(fDirection);
1129 TObjString* key = static_cast<TObjString*>(fMapIterator->Next());
1135 THashList* list = static_cast<THashList*>(fkHistogramCollection->Map()->GetValue(key->String().Data()));
1136 if (!list) return 0x0;
1137 fHashListIterator = list->MakeIterator(fDirection);
1140 TObject* o = fHashListIterator->Next();
1144 delete fHashListIterator;
1145 fHashListIterator = 0x0;
1152 //_____________________________________________________________________________
1153 void AliHistogramCollectionIterator::Reset()
1155 /// Reset the iterator
1156 delete fHashListIterator;
1157 delete fMapIterator;