LCOV - code coverage report
Current view: top level - STEER/STEERBase - AliMergeableCollection.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 663 0.2 %
Date: 2016-06-14 17:26:59 Functions: 1 70 1.4 %

          Line data    Source code
       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: AliMergeableCollection.cxx 50593 2011-07-14 17:42:28Z martinez $
      17             : 
      18             : ///
      19             : /// A mergeable object container. 
      20             : ///
      21             : /// For each tuple (key1,key2,..,keyN) a (hash)list of mergeable objects is associated.
      22             : /// Note that key1, key2 (optional), ..., keyN (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 "AliMergeableCollection.h"
      28             : #include <iostream>
      29             : 
      30             : using std::cout;
      31             : using std::endl;
      32         176 : ClassImp(AliMergeableCollection)
      33             : 
      34             : #include "AliLog.h"
      35             : #include "Riostream.h"
      36             : #include "TError.h"
      37             : #include "TFolder.h"
      38             : #include "TGraph.h"
      39             : #include "TH1.h"
      40             : #include "TH2.h"
      41             : #include "THashList.h"
      42             : #include "THnSparse.h"
      43             : #include "TKey.h"
      44             : #include "TMap.h"
      45             : #include "TObjArray.h"
      46             : #include "TObjString.h"
      47             : #include "TProfile.h"
      48             : #include "TRegexp.h"
      49             : #include "TROOT.h"
      50             : #include "TSystem.h"
      51             : #include <cassert>
      52             : #include <vector>
      53             : #include "TBrowser.h"
      54             : 
      55             : //_____________________________________________________________________________
      56             : AliMergeableCollection::AliMergeableCollection(const char* name, const char* title) 
      57           0 : : TFolder(name,title), fMap(0x0), fMustShowEmptyObject(0), fMapVersion(0), fMessages()
      58           0 : {
      59             :   /// Ctor
      60           0 : }
      61             : 
      62             : //_____________________________________________________________________________
      63             : AliMergeableCollection::~AliMergeableCollection()
      64           0 : {
      65             :   /// dtor. Note that the map is owner
      66           0 :   delete fMap;
      67           0 : }
      68             : 
      69             : //_____________________________________________________________________________
      70             : Bool_t 
      71             : AliMergeableCollection::Adopt(TObject* obj)
      72             : {
      73             :   /// Adopt a given object at top level (i.e. no key)
      74           0 :   return InternalAdopt("",obj);
      75             : }
      76             : 
      77             : //_____________________________________________________________________________
      78             : void
      79             : AliMergeableCollection::CorrectIdentifier(TString& sidentifier)
      80             : {
      81             :   /// Insure identifier has the right number of slashes...
      82             :   
      83           0 :   if ( ! sidentifier.IsNull() )
      84             :   {
      85           0 :     if ( ! sidentifier.EndsWith("/") ) sidentifier.Append("/");
      86           0 :     if ( ! sidentifier.BeginsWith("/") ) sidentifier.Prepend("/");
      87           0 :     sidentifier.ReplaceAll("//","/");
      88           0 :   }
      89           0 : }
      90             : 
      91             : //_____________________________________________________________________________
      92             : Bool_t 
      93             : AliMergeableCollection::Adopt(const char* identifier, TObject* obj)
      94             : {
      95             :   /// Adopt a given object, and associate it with pair key
      96           0 :   TString sidentifier(identifier);
      97             :   
      98           0 :   CorrectIdentifier(sidentifier);
      99             :   
     100           0 :   return InternalAdopt(sidentifier.Data(),obj);
     101           0 : }
     102             : 
     103             : //_____________________________________________________________________________
     104             : Bool_t AliMergeableCollection::Attach(AliMergeableCollection* mc, const char* identifier, Bool_t pruneFirstIfAlreadyExists)
     105             : {
     106             :   /// Attach an already existing mergeable collection to this one.
     107             :   /// It is attached at level identifier/
     108             :   /// We take ownership of mc
     109             :   /// If identifier is already existing we kill it if pruneFirstIfAlreadyExists is kTRUE
     110             :   /// (and attach mc) otherwise we return kFALSE (and do *not* attach mc)
     111             :   
     112           0 :   THashList* hlist = dynamic_cast<THashList*>(Map()->GetValue(identifier));
     113             :   
     114           0 :   if (hlist)
     115             :   {
     116           0 :     if (!pruneFirstIfAlreadyExists)
     117             :     {
     118           0 :       AliError(Form("%s already exist. Will not overwrite it.",identifier));
     119           0 :       return kFALSE;
     120             :     }
     121             :     else
     122             :     {
     123           0 :       Int_t n = Prune(identifier);
     124           0 :       if (!n)
     125             :       {
     126           0 :         AliError(Form("Could not prune pre-existing %s",identifier));
     127           0 :         return kFALSE;        
     128             :       }
     129           0 :     }
     130             :   }
     131             : 
     132           0 :   TIter next(mc->fMap);
     133             :   TObjString* str;
     134             :   
     135           0 :   while ( ( str = static_cast<TObjString*>(next())) )
     136             :   {
     137           0 :     THashList* hl = dynamic_cast<THashList*>(mc->Map()->GetValue(str->String()));
     138           0 :     TString newid(Form("/%s%s",identifier,str->String().Data()));
     139           0 :     newid.ReplaceAll("//","/");                  
     140           0 :     Map()->Add(new TObjString(newid.Data()),hl);
     141           0 :   }
     142             :   
     143             :   return kTRUE;
     144           0 : }
     145             : 
     146             : //_____________________________________________________________________________
     147             : void AliMergeableCollection::Browse(TBrowser* b)
     148             : {
     149             :   /// Create a TFolder structure pointing to our objects, so we
     150             :   /// can be "browsed"
     151             :   
     152           0 :   if ( !fFolders ) return;
     153             :   
     154           0 :   TObjArray* ids = SortAllIdentifiers();
     155           0 :   TIter nextIdentifier(ids);
     156             :   TObjString* str;
     157             :   
     158           0 :   while ( ( str = static_cast<TObjString*>(nextIdentifier()) ) )
     159             :   {
     160           0 :     TObjArray* parts = str->String().Tokenize("/");
     161             :     TObjString* s;
     162           0 :     TIter nextPart(parts);
     163             :     TFolder* base = this;
     164             :     
     165           0 :     while ( ( s = static_cast<TObjString*>(nextPart())))
     166             :     {
     167           0 :       TFolder* f = static_cast<TFolder*>(base->TFolder::FindObject(s->String()));
     168           0 :       if (!f)
     169             :       {
     170           0 :         f = new TFolder(s->String(),"");
     171           0 :         base->Add(f);
     172             :       }
     173             :       base = f;
     174             :     }
     175           0 :     delete parts;
     176             : 
     177           0 :     TList* list = CreateListOfObjectNames(str->String());
     178           0 :     if (list)
     179             :     {
     180             :       TObjString* oname;
     181           0 :       TIter nextObject(list);
     182           0 :       while ( ( oname = static_cast<TObjString*>(nextObject())) )
     183             :       {
     184           0 :         TObject* o = GetObject(str->String(),oname->String());
     185           0 :         base->Add(o);
     186             :       }
     187           0 :     }
     188             :     else
     189             :     {
     190           0 :       AliError("got list=0x0");
     191             :     }
     192           0 :     delete list;
     193           0 :   }
     194             : 
     195           0 :   TList* top = CreateListOfKeys(0);
     196             :   TObjString* stop;
     197           0 :   TIter nextTop(top);
     198             :   
     199           0 :   while ( ( stop = static_cast<TObjString*>(nextTop())) )
     200             :   {
     201           0 :     b->Add(TFolder::FindObject(stop->String()));
     202             :   }
     203             :   
     204           0 :   delete top;
     205             :   
     206           0 :   delete ids;
     207           0 : }
     208             : 
     209             : //_____________________________________________________________________________
     210             : void AliMergeableCollection::ClearMessages()
     211             : {
     212             :   /// clear pending messages
     213           0 :   fMessages.clear();
     214           0 : }
     215             : 
     216             : //_____________________________________________________________________________
     217             : TIterator*
     218             : AliMergeableCollection::CreateIterator(Bool_t direction) const
     219             : {
     220             :   /// Create an iterator (must be deleted by the client)
     221           0 :   return fMap ? new AliMergeableCollectionIterator(this,direction) : 0x0;
     222           0 : }
     223             : 
     224             : //_____________________________________________________________________________
     225             : AliMergeableCollectionProxy*
     226             : AliMergeableCollection::CreateProxy(const char* identifier, Bool_t createIfNeeded)
     227             : {
     228             :   /// Create a proxy starting at identifier.
     229             :   /// If createIfNeeded is true, then the identifier is inserted into
     230             :   /// the collection if it does not exist yet (in which case this method always
     231             :   /// returns a non null proxy)
     232             :   
     233           0 :   TString sidentifier(identifier);
     234           0 :   CorrectIdentifier(sidentifier);
     235             : 
     236           0 :   THashList* list = static_cast<THashList*>(Map()->GetValue(sidentifier));
     237           0 :   if (!list)
     238             :   {
     239           0 :     if (!createIfNeeded)
     240             :     {
     241           0 :       return 0x0;
     242             :     }
     243             :     
     244           0 :     list = new THashList;
     245           0 :     list->SetOwner(kTRUE);
     246             : 
     247           0 :     Map()->Add(new TObjString(sidentifier),list);
     248           0 :     list->SetName(sidentifier);
     249             :   }
     250           0 :   return new AliMergeableCollectionProxy(*this,*list);
     251           0 : }
     252             : 
     253             : //_____________________________________________________________________________
     254             : AliMergeableCollection*
     255             : AliMergeableCollection::Clone(const char* name) const
     256             : {
     257             :   /// Clone this collection.
     258             :   /// We loose the messages.
     259             :   
     260           0 :   AliMergeableCollection* newone = new AliMergeableCollection(name,GetTitle());
     261             :   
     262           0 :   newone->fMap = static_cast<TMap*>(fMap->Clone());
     263           0 :   newone->fMustShowEmptyObject = fMustShowEmptyObject;
     264           0 :   newone->fMapVersion = fMapVersion;  
     265             :   
     266           0 :   return newone;
     267           0 : }
     268             : 
     269             : //_____________________________________________________________________________
     270             : void 
     271             : AliMergeableCollection::Delete(Option_t*)
     272             : {
     273             :   /// Delete all the objects
     274           0 :   if (fMap)
     275             :   {
     276           0 :     fMap->DeleteAll();
     277           0 :     delete fMap;
     278           0 :     fMap=0x0;
     279           0 :   }
     280           0 : }
     281             : 
     282             : //_____________________________________________________________________________
     283             : TObject* 
     284             : AliMergeableCollection::FindObject(const char* fullIdentifier) const
     285             : {
     286             :   /// Find an object by its full identifier.
     287             :   
     288           0 :   return GetObject(fullIdentifier);
     289             : }
     290             : 
     291             : //_____________________________________________________________________________
     292             : TObject* 
     293             : AliMergeableCollection::FindObject(const TObject *object) const
     294             : {
     295             :   /// Find an object 
     296           0 :   AliWarning("This method is awfully inefficient. Please improve it or use FindObject(const char*)");
     297           0 :   TIter next(CreateIterator());
     298             :   TObject* obj;
     299           0 :   while ( ( obj=next() ) )
     300             :   {
     301           0 :     if ( obj->IsEqual(object) ) return obj;
     302             :   }
     303           0 :   return 0x0;
     304           0 : }
     305             : 
     306             : 
     307             : //_____________________________________________________________________________
     308             : TList*
     309             : AliMergeableCollection::CreateListOfKeys(Int_t index) const
     310             : {
     311             :   /// Create the list of keys at level index
     312             :   
     313           0 :   TList* list = new TList;
     314           0 :   list->SetOwner(kTRUE);
     315             :   
     316           0 :   TObjArray* ids = SortAllIdentifiers();
     317           0 :   TIter next(ids);
     318             :   TObjString* str;
     319             :   
     320           0 :   while ( ( str = static_cast<TObjString*>(next()) ) )
     321             :   {
     322           0 :     TString oneid = GetKey(str->String().Data(),index,kFALSE);
     323           0 :     if (oneid.Length()>0 && !list->Contains(oneid))
     324             :     {
     325           0 :       list->Add(new TObjString(oneid));
     326             :     }
     327           0 :   }
     328             :   
     329           0 :   delete ids;
     330             :   return list;
     331           0 : }
     332             : 
     333             : //_____________________________________________________________________________
     334             : TList* 
     335             : AliMergeableCollection::CreateListOfObjectNames(const char* identifier) const
     336             : {
     337             :   /// Create list of object names for /key1/key2/key...
     338             :   /// Returned list must be deleted by client
     339             :   
     340           0 :   TList* listOfNames = new TList;
     341           0 :   listOfNames->SetOwner(kTRUE);
     342             :   
     343           0 :   TIter next(Map());
     344             :   TObjString* str;
     345             :   
     346           0 :   while ( ( str = static_cast<TObjString*>(next()) ) )
     347             :   {
     348           0 :     TString currIdentifier = str->String();
     349           0 :     if ( currIdentifier.CompareTo(identifier) ) continue;
     350             :     
     351           0 :     THashList* list = static_cast<THashList*>(Map()->GetValue(identifier));
     352             :     
     353           0 :     TIter nextObject(list);
     354             :     TObject* obj;
     355             :     
     356           0 :     while ( ( obj = nextObject() ) )
     357             :     {
     358           0 :       listOfNames->Add(new TObjString(obj->GetName()));
     359             :     }    
     360           0 :   }
     361             :   
     362             :   return listOfNames;
     363           0 : }
     364             : 
     365             : 
     366             : //_____________________________________________________________________________
     367             : TString
     368             : AliMergeableCollection::GetIdentifier(const char* fullIdentifier) const
     369             : {
     370             :   /// Extract the identifier from the fullIdentifier
     371             : 
     372           0 :   TString identifier;
     373             :   
     374           0 :   Int_t n = TString(fullIdentifier).CountChar('/')-1;
     375             :   
     376           0 :   for (Int_t i=0; i < n; ++i)
     377             :   {
     378           0 :     identifier += "/";
     379           0 :     identifier += InternalDecode(fullIdentifier,i);
     380             :   }
     381           0 :   identifier += "/";
     382             :   return identifier;
     383           0 : }
     384             : 
     385             : //_____________________________________________________________________________
     386             : TString
     387             : AliMergeableCollection::GetKey(const char* identifier, Int_t index, Bool_t idContainsObjName) const
     388             : {
     389             :   /// Extract the index element of the key pair from the fullIdentifier
     390             : 
     391           0 :   if ( ! idContainsObjName )
     392             :   {
     393           0 :     TString sidentifier(identifier);
     394           0 :     sidentifier.Append("/dummy");
     395           0 :     return InternalDecode(sidentifier.Data(),index);
     396           0 :   }
     397             :   
     398           0 :   return InternalDecode(identifier,index);
     399           0 : }
     400             : 
     401             : //_____________________________________________________________________________
     402             : TString
     403             : AliMergeableCollection::GetObjectName(const char* fullIdentifier) const
     404             : {
     405             :   /// Extract the object name from an identifier
     406             :   
     407           0 :   return InternalDecode(fullIdentifier,-1);  
     408             : }
     409             : 
     410             : //_____________________________________________________________________________
     411             : TH1*
     412             : AliMergeableCollection::Histo(const char* fullIdentifier) const
     413             : {
     414             :   /// Get histogram key1/key2/.../objectName:action
     415             :   /// action is used for 2D histograms :
     416             :   /// might be px for projection along x-axis
     417             :   /// py for projection along y-axis
     418             :   /// pfx for profile along x-axis
     419             :   /// pfy for profile along y-axis
     420             :   
     421           0 :   TString sfullIdentifier(fullIdentifier);
     422             :   
     423           0 :   TString fullIdWithoutAction(fullIdentifier);
     424           0 :   TString action;
     425             :   
     426           0 :   if ( sfullIdentifier.First(':') != kNPOS )
     427             :   {
     428           0 :     TObjArray* arr = sfullIdentifier.Tokenize(":");
     429             :   
     430           0 :     fullIdWithoutAction = static_cast<TObjString*>(arr->At(0))->String();
     431             :   
     432           0 :     if ( arr->GetLast() > 0 )
     433             :     {
     434           0 :       action = static_cast<TObjString*>(arr->At(1))->String();
     435           0 :       action.ToUpper();
     436             :     }
     437             :   
     438           0 :     delete arr;
     439           0 :   }
     440             :   
     441           0 :   Int_t nslashes = sfullIdentifier.CountChar('/');
     442             :   
     443             :   TObject* o(0x0);
     444             :   
     445           0 :   if (!nslashes)
     446             :   {
     447           0 :     o = GetObject("", fullIdWithoutAction);    
     448           0 :   }  
     449             :   else
     450             :   {
     451           0 :     o = GetObject(GetIdentifier(fullIdWithoutAction).Data(), GetObjectName(fullIdWithoutAction));
     452             :   }
     453             :   
     454           0 :   return HistoWithAction(fullIdWithoutAction.Data(),o,action);
     455           0 : }
     456             : 
     457             : //_____________________________________________________________________________
     458             : TH1*
     459             : AliMergeableCollection::Histo(const char* identifier,
     460             :                               const char* objectName) const
     461             : {
     462             :   /// Get histogram key1/key2/.../objectName:action
     463             :   /// action is used for 2D histograms :
     464             :   /// might be px for projection along x-axis
     465             :   /// py for projection along y-axis
     466             :   /// pfx for profile along x-axis
     467             :   /// pfy for profile along y-axis
     468             :   
     469           0 :   TObject* o = GetObject(identifier,objectName);
     470             :   
     471           0 :   TString action;
     472             : 
     473           0 :   if ( strchr(objectName,':') )
     474             :   {
     475           0 :     TObjArray* arr = TString(objectName).Tokenize(":");
     476             :   
     477           0 :     if ( arr->GetLast() > 0 )
     478             :     {
     479           0 :       action = static_cast<TObjString*>(arr->At(1))->String();
     480           0 :       action.ToUpper();
     481             :     }
     482             :   
     483           0 :     delete arr;
     484             : 
     485           0 :     return HistoWithAction(identifier,o,action);
     486             :   }
     487             :   
     488           0 :   if (o && o->IsA()->InheritsFrom(TH1::Class()))
     489             :   {
     490           0 :     return static_cast<TH1*>(o);
     491             :   }
     492           0 :   return 0x0;
     493           0 : }
     494             : 
     495             : 
     496             : //_____________________________________________________________________________
     497             : TH1*
     498             : AliMergeableCollection::HistoWithAction(const char* identifier, TObject* o, const TString& action) const
     499             : {
     500             :   /// Convert o to an histogram if possible, applying a given action if there
     501             : 
     502           0 :   if (!o) return 0x0;
     503             :   
     504           0 :   if (!o->InheritsFrom("TH1"))
     505             :   {
     506           0 :     AliError(Form("%s is not an histogram",o->GetName()));
     507           0 :     return 0x0;
     508             :   }
     509             :   
     510           0 :   TH2* h2 = dynamic_cast<TH2*>(o);
     511             :   
     512           0 :   if (h2)
     513             :   {
     514           0 :     if ( action == "PX" )
     515             :     {
     516           0 :       return h2->ProjectionX(NormalizeName(Form("%s/%s",identifier,o->GetName()),action.Data()).Data());
     517             :     }
     518           0 :     if ( action == "PY" )
     519             :     {
     520           0 :       return h2->ProjectionY(NormalizeName(Form("%s/%s",identifier,o->GetName()),action.Data()).Data());
     521             :     }
     522           0 :     if ( action == "PFX" )
     523             :     {
     524           0 :       return h2->ProfileX(NormalizeName(Form("%s/%s",identifier,o->GetName()),action.Data()).Data());
     525             :     }
     526           0 :     if ( action == "PFY" )
     527             :     {
     528           0 :       return h2->ProfileY(NormalizeName(Form("%s/%s",identifier,o->GetName()),action.Data()).Data());
     529             :     }
     530             :   }
     531             :   
     532           0 :   return static_cast<TH1*>(o);
     533           0 : }
     534             : 
     535             : //_____________________________________________________________________________
     536             : TH2*
     537             : AliMergeableCollection::H2(const char* fullIdentifier) const
     538             : {
     539             :   /// Short-cut method to grab a 2D histogram
     540             :   /// Will return 0x0 if the object if not a TH2xxx
     541             : 
     542           0 :   TObject* o = GetObject(fullIdentifier);
     543             :   
     544           0 :   if (o->IsA()->InheritsFrom(TH2::Class()))
     545             :   {
     546           0 :     return static_cast<TH2*>(o);
     547             :   }
     548           0 :   return 0x0;
     549           0 : }
     550             : 
     551             : //_____________________________________________________________________________
     552             : TH2*
     553             : AliMergeableCollection::H2(const char* identifier,
     554             :                            const char* objectName) const
     555             : {
     556             :   /// Short-cut method to grab a 2D histogram
     557             :   /// Will return 0x0 if the object if not a TH2xxx
     558             :   
     559           0 :   TObject* o = GetObject(identifier,objectName);
     560             :   
     561           0 :   if (o->IsA()->InheritsFrom(TH2::Class()))
     562             :   {
     563           0 :     return static_cast<TH2*>(o);
     564             :   }
     565           0 :   return 0x0;
     566           0 : }
     567             : 
     568             : //_____________________________________________________________________________
     569             : TProfile*
     570             : AliMergeableCollection::Prof(const char* fullIdentifier) const
     571             : {
     572             :   /// Short-cut method to grab a TProfile histogram
     573             :   /// Will return 0x0 if the object if not a TProfile
     574             :   
     575           0 :   TObject* o = GetObject(fullIdentifier);
     576             :   
     577           0 :   if (o->IsA()->InheritsFrom(TProfile::Class()))
     578             :   {
     579           0 :     return static_cast<TProfile*>(o);
     580             :   }
     581           0 :   return 0x0;
     582           0 : }
     583             : 
     584             : //_____________________________________________________________________________
     585             : TProfile*
     586             : AliMergeableCollection::Prof(const char* identifier,
     587             :                            const char* objectName) const
     588             : {
     589             :   /// Short-cut method to grab a TProfile histogram
     590             :   /// Will return 0x0 if the object if not a TProfile
     591             :   
     592           0 :   TObject* o = GetObject(identifier,objectName);
     593             :   
     594           0 :   if (o->IsA()->InheritsFrom(TProfile::Class()))
     595             :   {
     596           0 :     return static_cast<TProfile*>(o);
     597             :   }
     598           0 :   return 0x0;
     599           0 : }
     600             : 
     601             : //_____________________________________________________________________________
     602             : TObject* 
     603             : AliMergeableCollection::GetObject(const char* fullIdentifier) const
     604             : {
     605             :   /// Get object key1/key2/.../objectName
     606             :   /// Note that no action is allowed for generic objects (only for histograms,
     607             :   /// see Histo() methods)
     608             :   
     609           0 :   TString sfullIdentifier(fullIdentifier);
     610             :   
     611           0 :   Int_t nslashes = sfullIdentifier.CountChar('/');
     612             :   
     613           0 :   if (!nslashes)
     614             :   {
     615           0 :     return GetObject("", sfullIdentifier);
     616             :   }
     617             :   else
     618             :   {
     619           0 :     return GetObject(GetIdentifier(fullIdentifier).Data(), GetObjectName(fullIdentifier));
     620             :   }
     621           0 : }
     622             : 
     623             : //_____________________________________________________________________________
     624             : TObject* 
     625             : AliMergeableCollection::GetObject(const char* identifier, 
     626             :                                   const char* objectName) const
     627             : {
     628             :   /// Get object for (identifier,objectName) triplet
     629             :   
     630           0 :   TString sidentifier(identifier);
     631           0 :   if ( ! sidentifier.IsNull() ) {
     632           0 :     if ( ! sidentifier.BeginsWith("/") ) sidentifier.Prepend("/");
     633           0 :     if ( ! sidentifier.EndsWith("/") ) sidentifier.Append("/");
     634             :   }
     635           0 :   return InternalObject(sidentifier.Data(),objectName);
     636           0 : }
     637             : 
     638             : //_____________________________________________________________________________
     639             : TObject* AliMergeableCollection::GetSum(const char* idPattern) const
     640             : {
     641             :   /// Sum objects
     642             :   /// The pattern must be in the form:
     643             :   /// /key1_1,key1_2,.../key2_1,key2_2,.../.../objectName_1,objectName_2...
     644             :   /// The logical or between patterns separated by commas is taken
     645             :   /// Exact match is required for keys and objectNames
     646             :   
     647             :   TObject* sumObject = 0x0;
     648             :   TObjString* str = 0x0;
     649             :   
     650             :   // Build array of lists of pattern
     651           0 :   TString idPatternString(idPattern);
     652           0 :   TObjArray* keyList = idPatternString.Tokenize("/");
     653           0 :   TObjArray keyMatrix(keyList->GetEntriesFast());
     654           0 :   keyMatrix.SetOwner();
     655           0 :   TIter nextKey(keyList);
     656           0 :   while ( ( str = static_cast<TObjString*>(nextKey()) ) ) {
     657           0 :     TObjArray* subKeyList = str->String().Tokenize(",");
     658           0 :     keyMatrix.Add(subKeyList);
     659             :   }
     660           0 :   delete keyList;
     661             :   
     662           0 :   TString debugMsg = "Adding objects:";
     663             :   
     664             :   //
     665             :   // First handle the keys
     666             :   //
     667             :   TObjString* subKey = 0x0;
     668           0 :   TIter next(Map());
     669           0 :   while ( ( str = static_cast<TObjString*>(next()) ) )
     670             :   {
     671           0 :     TString identifier = str->String();
     672             :     
     673             :     Bool_t listMatchPattern = kTRUE;
     674           0 :     for ( Int_t ikey=0; ikey<keyMatrix.GetEntries()-1; ikey++ ) {
     675           0 :       TString currKey = GetKey(identifier, ikey, kFALSE);
     676             :       Bool_t matchKey = kFALSE;
     677           0 :       TObjArray* subKeyList = static_cast<TObjArray*> ( keyMatrix.At(ikey) );
     678           0 :       TIter nextSubKey(subKeyList);
     679           0 :       while ( (subKey=static_cast<TObjString*>(nextSubKey())) ) {
     680           0 :         TString subKeyString = subKey->String();
     681           0 :         if ( currKey == subKeyString ) {
     682             :           matchKey = kTRUE;
     683           0 :           break;
     684             :         }
     685           0 :       } // loop on the list of patterns of each key
     686           0 :       if ( ! matchKey ) {
     687             :         listMatchPattern = kFALSE;
     688           0 :         break;
     689             :       }
     690           0 :     } // loop on keys in the idPattern
     691           0 :     if ( ! listMatchPattern ) continue;
     692             :     
     693             :     
     694             :     //
     695             :     // Then handle the object name
     696             :     //
     697           0 :     THashList* list = static_cast<THashList*>(Map()->GetValue(identifier.Data()));
     698             :     
     699           0 :     TIter nextObj(list);
     700             :     TObject* obj;
     701             :     
     702           0 :     while ( ( obj = nextObj()) )
     703             :     {
     704           0 :       TString currKey = obj->GetName();
     705             :       Bool_t matchKey = kFALSE;
     706           0 :       TObjArray* subKeyList = static_cast<TObjArray*> ( keyMatrix.Last() );
     707           0 :       TIter nextSubKey(subKeyList);
     708           0 :       while ( (subKey=static_cast<TObjString*>(nextSubKey())) ) {
     709           0 :         TString subKeyString = subKey->String();
     710           0 :         if ( currKey == subKeyString ) {
     711             :           matchKey = kTRUE;
     712           0 :           break;
     713             :         }
     714           0 :       }
     715           0 :       if ( ! matchKey ) continue;
     716           0 :       if ( ! sumObject ) sumObject = obj->Clone();
     717           0 :       else MergeObject(sumObject, obj);
     718           0 :       debugMsg += Form(" %s%s",identifier.Data(),obj->GetName());
     719           0 :     } // loop on objects in list
     720           0 :   } // loop on identifiers in map
     721             :   
     722           0 :   AliDebug(1,debugMsg.Data());
     723             :   
     724             :   return sumObject;
     725           0 : }
     726             : 
     727             : //_____________________________________________________________________________
     728             : Bool_t AliMergeableCollection::InternalAdopt(const char* identifier, TObject* obj)
     729             : {
     730             :   /// Adopt an obj
     731             :   
     732           0 :   if (!obj)
     733             :   {
     734           0 :     Error("Adopt","Cannot adopt a null object");
     735           0 :     return kFALSE;
     736             :   }
     737             :   
     738           0 :   if ( ! obj->IsA()->InheritsFrom(TObject::Class()) ||
     739           0 :         ! obj->IsA()->GetMethodWithPrototype("Merge", "TCollection*") ) {
     740           0 :     Error("Adopt","Cannot adopt an object which is not mergeable!"); 
     741           0 :   }
     742             :   
     743             :   THashList* hlist = 0x0;
     744             :   
     745           0 :   hlist = static_cast<THashList*>(Map()->GetValue(identifier));
     746             :   
     747           0 :   if (!hlist)
     748             :   {
     749           0 :     hlist = new THashList;
     750           0 :     hlist->SetOwner(kTRUE);
     751           0 :     Map()->Add(new TObjString(identifier),hlist);
     752           0 :     hlist->SetName(identifier);
     753           0 :   }
     754             :   
     755           0 :   TObject* existingObj = hlist->FindObject(obj->GetName());
     756             :   
     757           0 :   if (existingObj)
     758             :   {
     759           0 :     AliError(Form("Cannot adopt an already existing object : %s -> %s",identifier,existingObj->GetName()));
     760           0 :     return kFALSE;
     761             :   }
     762             :   
     763           0 :   if ( obj->IsA()->InheritsFrom(TH1::Class()) ) (static_cast<TH1*> ( obj ))->SetDirectory(0);  
     764             :   
     765           0 :   hlist->AddLast(obj);
     766             :     
     767           0 :   return kTRUE;
     768             :   
     769           0 : }
     770             : 
     771             : //_____________________________________________________________________________
     772             : TString
     773             : AliMergeableCollection::InternalDecode(const char* identifier, Int_t index) const
     774             : {
     775             :   /// Extract the index-th element of the identifier (/key1/key2/.../keyN/objectName)
     776             :   /// object is index=-1 (i.e. last)
     777             :   
     778           0 :   if ( strlen(identifier) > 0 && identifier[0] != '/' ) 
     779             :   {    
     780           0 :     AliError(Form("identifier %s is malformed (should start with /)",identifier));
     781           0 :     return "";
     782             :   }
     783             :   
     784           0 :   std::vector<Int_t> splitIndex;
     785             :   
     786             :   Int_t start(0);
     787           0 :   TString sidentifier(identifier);
     788             :   
     789           0 :   while (start < sidentifier.Length())
     790             :   {
     791           0 :     Int_t pos = sidentifier.Index('/', start);
     792           0 :     if (pos == kNPOS) break;
     793           0 :     splitIndex.push_back(pos);
     794           0 :     start = pos + 1;
     795           0 :   }
     796             : 
     797           0 :   Int_t nkeys = splitIndex.size() - 1;
     798             :   
     799           0 :   if ( index >= nkeys )
     800             :   {
     801           0 :     AliError(Form("Requiring index %i of identifier %s which only have %i",index, identifier, nkeys));
     802           0 :     return "";
     803             :   }
     804             : 
     805           0 :   if ( index < 0 )
     806             :   {
     807           0 :     return sidentifier(splitIndex.back()+1,sidentifier.Length()-splitIndex.back()-1);
     808             :   }
     809             : 
     810           0 :   return sidentifier(splitIndex[index]+1,splitIndex[index+1]-splitIndex[index]-1);
     811           0 : }
     812             : 
     813             : //_____________________________________________________________________________
     814             : TObject* 
     815             : AliMergeableCollection::InternalObject(const char* identifier,
     816             :                                        const char* objectName) const
     817             : {
     818             :   /// Get object for (identifier,objectName) 
     819             :   
     820           0 :   if (!fMap) 
     821             :   {
     822           0 :     return 0x0;
     823             :   }
     824             :   
     825           0 :   THashList* hlist = static_cast<THashList*>(Map()->GetValue(identifier));
     826           0 :   if (!hlist) 
     827             :   {
     828           0 :     TString msg(Form("Did not find hashlist for identifier=%s dir=%s",identifier,gDirectory ? gDirectory->GetName() : "" ));
     829           0 :     fMessages[msg.Data()]++;
     830             :     return 0x0;
     831           0 :   }
     832             :   
     833           0 :   TObject* obj = hlist->FindObject(objectName);
     834           0 :   if (!obj)
     835             :   {
     836           0 :     TString msg(Form("Did not find objectName=%s in %s",objectName,identifier));
     837           0 :     fMessages[msg.Data()]++;
     838           0 :   }
     839             :   return obj;
     840           0 : }
     841             : 
     842             : 
     843             : //_____________________________________________________________________________
     844             : Bool_t AliMergeableCollection::IsEmptyObject(TObject* obj) const
     845             : {
     846             :   /// Check if object is empty
     847             :   /// (done only for TH1, so far)
     848             :     
     849           0 :   if ( obj->IsA()->InheritsFrom(TH1::Class()) ) {
     850           0 :     TH1* histo = static_cast<TH1*> (obj);
     851           0 :     if ( histo->GetEntries() == 0 ) return kTRUE;
     852           0 :   }
     853             : 
     854           0 :   return kFALSE;
     855             : 
     856           0 : }
     857             : 
     858             : 
     859             : //_____________________________________________________________________________
     860             : TMap* AliMergeableCollection::Map() const
     861             : {
     862             :   /// Wrapper to insure proper key formats (i.e. new vs old)
     863             :   
     864           0 :   if (!fMap)
     865             :   {
     866           0 :     fMap = new TMap;
     867           0 :     fMap->SetOwnerKeyValue(kTRUE,kTRUE);
     868           0 :     fMapVersion = 1;
     869           0 :   }
     870             :   else
     871             :   {
     872           0 :     if ( fMapVersion < 1 ) 
     873             :     {
     874           0 :       AliInfo("Remapping");
     875             :       // change the keys
     876           0 :       TIter next(fMap);
     877             :       TObjString* str;
     878             :       
     879           0 :       while ( ( str = static_cast<TObjString*>(next()) ) )
     880             :       {
     881           0 :         if ( str->String().Contains("./") )
     882             :         {
     883           0 :           TString newkey(str->String());
     884             :           
     885           0 :           newkey.ReplaceAll("./","");
     886             :           
     887           0 :           TObject* o = fMap->GetValue(str);
     888             :           
     889           0 :           TPair* p = fMap->RemoveEntry(str);
     890           0 :           if (!p)
     891             :           {
     892           0 :             AliError("oups oups oups");
     893           0 :             return 0x0;
     894             :           }
     895             :           
     896           0 :           fMap->Add(new TObjString(newkey.Data()),o);
     897             :           
     898           0 :           delete p;
     899           0 :         }
     900             :       }
     901             :       
     902           0 :       fMapVersion = 1;
     903           0 :     }
     904             :   }
     905             :   
     906           0 :   return fMap;
     907           0 : }
     908             : 
     909             : //_____________________________________________________________________________
     910             : Long64_t
     911             : AliMergeableCollection::Merge(TCollection* list)
     912             : {
     913             :   // Merge a list of AliMergeableCollection objects with this
     914             :   // Returns the number of merged objects (including this).
     915             :   
     916           0 :   if (!list) return 0;
     917             :   
     918           0 :   if (list->IsEmpty()) return 1;
     919             :   
     920           0 :   TIter next(list);
     921             :   TObject* currObj;
     922           0 :   TList mapList;
     923             :   Long64_t count(0);
     924             :   
     925           0 :   while ( ( currObj = next() ) )
     926             :   {
     927           0 :     AliMergeableCollection* mergeCol = dynamic_cast<AliMergeableCollection*>(currObj);
     928           0 :     if (!mergeCol) {
     929           0 :       AliFatal(Form("object named \"%s\" is a %s instead of an AliMergeableCollection!", currObj->GetName(), currObj->ClassName()));
     930           0 :       continue;
     931             :     }
     932             :     
     933           0 :     ++count;
     934             :     
     935           0 :     if ( mergeCol->fMap ) mergeCol->Map(); // to insure keys in the new format
     936             :     
     937           0 :     TIter nextIdentifier(mergeCol->fMap);
     938             :     TObjString* identifier;
     939             : 
     940           0 :     while ( ( identifier = static_cast<TObjString*>(nextIdentifier()) ) )
     941             :     {
     942           0 :       THashList* otherList = static_cast<THashList*>(mergeCol->fMap->GetValue(identifier->String().Data()));
     943             : 
     944           0 :       TIter nextObject(otherList);
     945             :       TObject* obj;
     946             :       
     947           0 :       while ( ( obj = nextObject() ) )
     948             :       {
     949           0 :         TString newid(Form("%s%s",identifier->String().Data(),obj->GetName()));
     950             :         
     951           0 :         TObject* thisObject = GetObject(newid.Data());
     952             :         
     953           0 :         if (!thisObject)
     954             :         {
     955           0 :           Bool_t ok = Adopt(identifier->String(), obj->Clone());
     956             :           
     957           0 :           if (!ok)
     958             :           {
     959           0 :             AliError(Form("Adoption of object %s failed",obj->GetName()));
     960             :           }
     961           0 :         }
     962             :         else
     963             :         {
     964             :           // add it...
     965           0 :           MergeObject(thisObject, obj);
     966             :         }
     967           0 :       } // loop on objects in map
     968           0 :     } // loop on identifiers
     969           0 :   } // loop on collections in list
     970             :          
     971           0 :   return count+1;
     972           0 : }
     973             : 
     974             : //_____________________________________________________________________________
     975             : Bool_t AliMergeableCollection::MergeObject(TObject* baseObject, TObject* objToAdd)
     976             : {
     977             :   /// Add objToAdd to baseObject
     978             :   
     979           0 :   if ( baseObject->IsA()->Class() != objToAdd->IsA()->Class() ) {
     980           0 :     printf("MergeObject: Cannot add %s to %s", objToAdd->ClassName(), baseObject->ClassName());
     981           0 :     return kFALSE;
     982             :   }
     983           0 :   if ( ! baseObject->IsA()->InheritsFrom(TObject::Class()) ||
     984           0 :       ! baseObject->IsA()->GetMethodWithPrototype("Merge", "TCollection*") ) {
     985           0 :     printf("MergeObject: Objects are not mergeable!");
     986           0 :     return kFALSE;
     987             :   }  
     988             :   
     989           0 :   TList list;
     990           0 :   list.Add(objToAdd);
     991             :   
     992           0 :   TString listArgs = Form("((TCollection*)0x%lx)", (ULong_t)&list);
     993           0 :   Int_t error = 0;
     994           0 :   baseObject->Execute("Merge", listArgs.Data(), &error);
     995             :   return kTRUE;
     996           0 : }
     997             : 
     998             : //_____________________________________________________________________________
     999             : TString AliMergeableCollection::NormalizeName(const char* identifier,const char* action) const
    1000             : {
    1001             :   /// Replace / by _ to build a root-compliant histo name
    1002           0 :   TString name(GetName());
    1003             :   
    1004           0 :   name += "_";
    1005           0 :   name += identifier;
    1006           0 :   name += "_";
    1007           0 :   name += action;
    1008           0 :   name.ReplaceAll("/","_");
    1009           0 :   name.ReplaceAll("-","_");
    1010             :   return name;
    1011           0 : }
    1012             : 
    1013             : //_____________________________________________________________________________
    1014             : Int_t 
    1015             : AliMergeableCollection::NumberOfObjects() const
    1016             : {
    1017             :   /// Get the number of objects we hold
    1018           0 :   TIter next(CreateIterator());
    1019             :   Int_t count(0);
    1020           0 :   while ( next() ) ++count;
    1021             :   return count;
    1022           0 : }
    1023             : 
    1024             : //_____________________________________________________________________________
    1025             : Int_t 
    1026             : AliMergeableCollection::NumberOfKeys() const
    1027             : {
    1028             :   /// Get the number of keys we have
    1029           0 :   return fMap ? fMap->GetSize() : 0;
    1030             : }
    1031             : 
    1032             : //_____________________________________________________________________________
    1033             : void 
    1034             : AliMergeableCollection::Print(Option_t* option) const
    1035             : {
    1036             :   /// Print all the objects we hold, in a hopefully visually pleasing
    1037             :   /// way.
    1038             :   ///
    1039             :   /// Option can be used to select given part only, using the schema :
    1040             :   /// /*/*/*/*/*
    1041             :   /// Where the stars are wilcards for /key1/key2/.../objectName
    1042             :   ///
    1043             :   /// if * is used it is assumed to be a wildcard for objectName
    1044             :   ///
    1045             :   /// For other selections the full syntax /*/*/*/*/* must be used.
    1046             :   /// 
    1047             :   /// Use "-" as objectName to disable object's name output
    1048             :   ///
    1049             :   /// One might also use /*/*/*/*/:classname syntax to restrict
    1050             :   /// output to only those objects matching a given classname pattern
    1051             :   ///
    1052             :   
    1053           0 :   cout << Form("AliMergeableCollection(%s,%s)[%p] : %d keys and %d objects",
    1054           0 :                GetName(),GetTitle(),this,
    1055           0 :                NumberOfKeys(), NumberOfObjects()) << endl;
    1056             :   
    1057           0 :   if (!strlen(option)) return;
    1058             :   
    1059           0 :   TString soption(option);
    1060             :   
    1061           0 :   TObjArray* classes = soption.Tokenize(":");
    1062             :   
    1063             :   TRegexp* classPattern(0x0);
    1064             :   
    1065           0 :   if ( classes->GetLast() > 0 )
    1066             :   {
    1067           0 :     TString pat = static_cast<TObjString*>(classes->At(1))->String();
    1068           0 :     classPattern = new TRegexp(pat,kTRUE);
    1069           0 :     soption = static_cast<TObjString*>(classes->At(0))->String();
    1070           0 :   }
    1071             :   
    1072           0 :   delete classes;
    1073             : 
    1074           0 :   TObjArray* select = soption.Tokenize("/");
    1075             :   
    1076           0 :   TString sreObjectName(select->Last()->GetName());
    1077           0 :   TRegexp reObjectName(sreObjectName.Data(),kTRUE);
    1078             :   
    1079           0 :   TObjArray* identifiers = SortAllIdentifiers();
    1080             :   
    1081           0 :   std::cout << Form("Number of identifiers %d", identifiers->GetEntries()) << std::endl;
    1082             :     
    1083           0 :   TIter nextIdentifier(identifiers);
    1084             :   
    1085             :   TObjString* sid(0x0);
    1086             :   
    1087           0 :   while ( ( sid = static_cast<TObjString*>(nextIdentifier()) ) )
    1088             :   {
    1089             :     Bool_t identifierPrinted(kFALSE);
    1090             : 
    1091           0 :     TString identifier(sid->String());
    1092             :     
    1093             :     Bool_t matchPattern = kTRUE;
    1094           0 :     for ( Int_t isel=0; isel<select->GetLast(); isel++ ) {
    1095           0 :       if ( ! GetKey(identifier.Data(), isel, kFALSE).Contains(TRegexp(select->At(isel)->GetName(),kTRUE)) ) {
    1096             :         matchPattern = kFALSE;
    1097           0 :         break;
    1098             :       }
    1099             :     }
    1100           0 :     if ( ! matchPattern ) continue;
    1101             :     
    1102           0 :     if ( sreObjectName == "*" && !classPattern)
    1103             :     {
    1104             :       identifierPrinted = kTRUE;
    1105           0 :       cout << identifier.Data() << endl;
    1106             :     }
    1107             :       
    1108           0 :     THashList * list = static_cast<THashList*>(Map()->GetValue(sid->String().Data()));
    1109             : 
    1110           0 :     TObjArray names;
    1111           0 :     names.SetOwner(kTRUE);
    1112           0 :     TIter nextUnsortedObj(list);
    1113             :     TObject* obj;
    1114           0 :     while ( ( obj = nextUnsortedObj() ) )
    1115             :     {
    1116           0 :       TString cname(obj->ClassName());
    1117           0 :       if ( classPattern && !cname.Contains((*classPattern)) )
    1118             :       {
    1119           0 :         continue;
    1120             :       }
    1121           0 :       names.Add(new TObjString(obj->GetName()));
    1122           0 :     }
    1123           0 :     names.Sort();
    1124           0 :     TIter nextObjName(&names);
    1125             :     TObjString* oname;
    1126           0 :     while ( ( oname = static_cast<TObjString*>(nextObjName()) ) )
    1127             :     {
    1128           0 :       TString objName(oname->String());
    1129           0 :       if (objName.Contains(reObjectName) )
    1130             :       {
    1131           0 :         obj = list->FindObject(objName.Data());
    1132           0 :         if ( IsEmptyObject(obj) && ! fMustShowEmptyObject ) continue;
    1133             :         
    1134           0 :         if (!identifierPrinted)
    1135             :         {
    1136           0 :           cout << identifier.Data() << endl;
    1137             :           identifierPrinted = kTRUE;
    1138           0 :         }
    1139             :         
    1140           0 :         TString extra;
    1141           0 :         TString warning("   ");
    1142             :         
    1143           0 :         if ( obj->IsA()->InheritsFrom(TH1::Class()) )
    1144             :         {
    1145             :           
    1146           0 :           TH1* histo = static_cast<TH1*> (obj);
    1147           0 :           extra.Form("%s | Entries=%d Sum=%g",histo->GetTitle(),Int_t(histo->GetEntries()),histo->GetSumOfWeights());
    1148           0 :         }
    1149           0 :         else if ( obj->IsA()->InheritsFrom(TGraph::Class()) )
    1150             :         {
    1151           0 :           TGraph* graph = static_cast<TGraph*> (obj);
    1152           0 :           if ( ! TMath::Finite(graph->GetMean(2) ) )
    1153             :           {
    1154           0 :             warning = " ! ";
    1155             :           }
    1156           0 :           extra.Form("%s | Npts=%d Mean=%g RMS=%g",graph->GetTitle(),graph->GetN(),
    1157           0 :                        graph->GetMean(2),graph->GetRMS(2));
    1158             :           
    1159           0 :         }
    1160             :         
    1161           0 :         std::cout << Form("    (%s) %s %s", obj->ClassName(),
    1162           0 :                      warning.Data(),
    1163           0 :                           obj->GetName());
    1164             :         
    1165           0 :         if ( extra.Length() )
    1166             :         {
    1167           0 :           std::cout << " | " << extra.Data();
    1168             :         }
    1169           0 :         std::cout << std::endl;
    1170           0 :       }
    1171           0 :     }
    1172           0 :     if (!identifierPrinted && sreObjectName=="-" )
    1173             :     { 
    1174             :       // to handle the case where we used objectName="-" to disable showing the objectNames,
    1175             :       // but we still want to see the matching keys maybe...
    1176           0 :       cout << identifier.Data() << endl;
    1177             :     }
    1178           0 :   }
    1179             :   
    1180           0 :   delete select;
    1181             :   
    1182           0 :   delete identifiers;
    1183           0 : }
    1184             : 
    1185             : //_____________________________________________________________________________
    1186             : void 
    1187             : AliMergeableCollection::PrintMessages(const char* prefix) const
    1188             : {
    1189             :   /// Print pending messages
    1190             :   
    1191           0 :   std::map<std::string,int>::const_iterator it;
    1192             :   
    1193           0 :   for ( it = fMessages.begin(); it != fMessages.end(); ++it ) 
    1194             :   {
    1195           0 :     cout << Form("%s : message %s appeared %5d times",prefix,it->first.c_str(),it->second) << endl;
    1196             :   }
    1197           0 : }
    1198             : 
    1199             : 
    1200             : //_____________________________________________________________________________
    1201             : UInt_t 
    1202             : AliMergeableCollection::EstimateSize(Bool_t show) const
    1203             : {
    1204             :   /// Estimate the memory (in kilobytes) used by some objects
    1205             : 
    1206             : //  For TH1:
    1207             : //  sizeof(TH1) + (nbins+2)*(nbytes_per_bin) +name+title_sizes 
    1208             : //  if you have errors add (nbins+2)*8 
    1209             :     
    1210           0 :   TIter next(CreateIterator());
    1211             :   
    1212             :   TObject* obj;
    1213             :   UInt_t size(0);
    1214             :   
    1215           0 :   while ( ( obj = next() ) )
    1216             :   {
    1217             :     UInt_t thissize=0;
    1218           0 :     if ( obj->IsA()->InheritsFrom(TH1::Class()) || obj->IsA()->InheritsFrom(TProfile::Class()) )
    1219             :     {
    1220           0 :       TH1* histo = static_cast<TH1*> (obj);
    1221           0 :       Int_t nbins = (histo->GetNbinsX()+2);
    1222             :     
    1223           0 :       if (histo->GetNbinsY()>1)
    1224             :       {
    1225           0 :         nbins *= (histo->GetNbinsY()+2);
    1226           0 :       }
    1227             :     
    1228           0 :       if (histo->GetNbinsZ()>1)
    1229             :       {
    1230           0 :         nbins *= (histo->GetNbinsZ()+2);
    1231           0 :       }
    1232             :       
    1233           0 :       Bool_t hasErrors = ( histo->GetSumw2N() > 0 );
    1234             :     
    1235           0 :       TString cname(histo->ClassName());
    1236             :     
    1237             :       Int_t nbytesPerBin(0);
    1238             :     
    1239           0 :       if (cname.Contains(TRegexp("C$")) ) nbytesPerBin = sizeof(Char_t);
    1240           0 :       if (cname.Contains(TRegexp("S$")) ) nbytesPerBin = sizeof(Short_t);
    1241           0 :       if (cname.Contains(TRegexp("I$")) ) nbytesPerBin = sizeof(Int_t);
    1242           0 :       if (cname.Contains(TRegexp("F$")) ) nbytesPerBin = sizeof(Float_t);
    1243           0 :       if (cname.Contains(TRegexp("D$")) ) nbytesPerBin = sizeof(Double_t);
    1244           0 :       if (cname=="TProfile") nbytesPerBin = sizeof(Double_t);
    1245             :         
    1246           0 :       if (!nbytesPerBin)
    1247             :       {
    1248           0 :         AliError(Form("Could not get the number of bytes per bin for histo %s of class %s. Thus the size estimate will be wrong !",
    1249             :                       histo->GetName(),histo->ClassName()));
    1250           0 :         continue;
    1251             :       }
    1252             :     
    1253           0 :       thissize = sizeof(histo) + nbins*(nbytesPerBin) + strlen(histo->GetName())
    1254           0 :       + strlen(histo->GetTitle());
    1255             :       
    1256           0 :       if ( hasErrors) thissize += nbins*8;
    1257             :       
    1258           0 :       if ( obj->IsA()->InheritsFrom(TProfile::Class()) )
    1259             :       {
    1260           0 :         TProfile* prof = static_cast<TProfile*>(obj);
    1261           0 :         TArrayD* d = prof->GetBinSumw2();
    1262           0 :         thissize += d->GetSize()*8*2; // 2 TArrayD
    1263           0 :         thissize += sizeof(prof) - sizeof(histo);
    1264           0 :       }
    1265           0 :     }
    1266           0 :     else if ( obj->IsA()->InheritsFrom(THnSparse::Class()) ) {
    1267           0 :       THnSparse* sparse = static_cast<THnSparse*> (obj);
    1268           0 :       thissize = sizeof(Float_t) * (UInt_t)sparse->GetNbins();
    1269             :     }
    1270             : //    else if ( obj->IsA() == AliCFGridSparse::Class() ) {
    1271             : //      AliCFGridSparse* sparse = static_cast<AliCFGridSparse*> (obj);
    1272             : //      thissize = sizeof(Float_t) * (UInt_t)sparse->GetNFilledBins();
    1273             : //    }
    1274             : //    else if ( obj->IsA() == AliCFContainer::Class() ) {
    1275             : //      AliCFContainer* cont = static_cast<AliCFContainer*> (obj);
    1276             : //      for ( Int_t istep=0; istep<cont->GetNStep(); istep++ ) {
    1277             : //        thissize += sizeof(Float_t) * (UInt_t)cont->GetGrid(istep)->GetNFilledBins();
    1278             : //      }
    1279             : //    }
    1280             :     else {
    1281           0 :       AliWarning(Form("Cannot estimate size of %s\n", obj->ClassName()));
    1282           0 :       continue;
    1283             :     }
    1284             : 
    1285           0 :     size += thissize;
    1286             :     
    1287           0 :     if ( show ) 
    1288             :     {
    1289           0 :       AliInfo(Form("Size of %30s is %20d bytes",obj->GetName(),thissize));
    1290             :     }
    1291           0 :   } // loop on objects
    1292             : 
    1293             :   return size;
    1294           0 : }
    1295             : 
    1296             : //_____________________________________________________________________________
    1297             : Int_t AliMergeableCollection::Prune(const char* identifier)
    1298             : {
    1299             :   // Delete all objects which match the beginning of the identifier
    1300             :   // returns the number of entries removed from the Map()
    1301             :   // (not to be confused with the number of leaf objects removed)
    1302             :   //
    1303             :   
    1304           0 :   TIter next(Map());
    1305             :   TObjString* key;
    1306             :   Int_t ndeleted(0);
    1307             :   
    1308           0 :   while ( ( key = static_cast<TObjString*>(next())) )
    1309             :   {
    1310           0 :       if (key->String().BeginsWith(identifier))
    1311             :       {
    1312           0 :         Bool_t ok = Map()->DeleteEntry(key);
    1313           0 :         if (ok) ++ndeleted;
    1314           0 :       }
    1315             :   }
    1316             :   
    1317             :   return ndeleted;
    1318           0 : }
    1319             : 
    1320             : //_____________________________________________________________________________
    1321             : void AliMergeableCollection::PruneEmptyObjects()
    1322             : {
    1323             :   /// Delete the empty objects
    1324             :   /// (Implemented for TH1 only)
    1325           0 :   TIter next(Map());
    1326             :   TObjString* key;
    1327             :   
    1328           0 :   TList toBeRemoved;
    1329           0 :   toBeRemoved.SetOwner(kTRUE);
    1330             :   
    1331           0 :   while ( ( key = static_cast<TObjString*>(next()) ) )
    1332             :   {
    1333           0 :     TString identifier(key->String());
    1334           0 :     THashList* hlist = static_cast<THashList*>(Map()->GetValue(identifier.Data()));
    1335           0 :     TIter nextObject(hlist);
    1336             :     TObject* obj;
    1337           0 :     while ( ( obj = nextObject() ) )
    1338             :     {
    1339           0 :       if ( IsEmptyObject(obj) ) toBeRemoved.Add(new TObjString(Form("%s%s",identifier.Data(),obj->GetName())));
    1340             :     }
    1341           0 :   }
    1342             :   
    1343           0 :   TIter nextTBR(&toBeRemoved);
    1344           0 :   while ( ( key = static_cast<TObjString*>(nextTBR()) ) )
    1345             :   {
    1346           0 :     Remove(key->GetString().Data());
    1347           0 :     AliDebug(2,Form("Removing %s", key->GetString().Data()));
    1348             :   }
    1349           0 : }
    1350             : 
    1351             : //_____________________________________________________________________________
    1352             : AliMergeableCollection* 
    1353             : AliMergeableCollection::Project(const char* identifier) const
    1354             : {
    1355             :   /// To be implemented : would create a new collection starting at /key1/key2/...
    1356             :   
    1357           0 :   if (!fMap) return 0x0;
    1358             :   
    1359           0 :   AliMergeableCollection* mergCol = new AliMergeableCollection(Form("%s %s",GetName(),identifier),
    1360           0 :                                                                GetTitle());
    1361             :   
    1362           0 :   TIter next(Map());
    1363             :   TObjString* str;
    1364             :   
    1365           0 :   while ( ( str = static_cast<TObjString*>(next()) ) )
    1366             :   {
    1367           0 :     TString currIdentifier = str->String();
    1368           0 :     if ( ! currIdentifier.Contains(identifier) ) continue;
    1369             :     
    1370           0 :     THashList* list = static_cast<THashList*>(Map()->GetValue(identifier));
    1371             :     
    1372           0 :     TIter nextObj(list);
    1373             :     TObject* obj;
    1374             :     
    1375           0 :     while ( ( obj = nextObj()) )
    1376             :     {
    1377           0 :       TObject* clone = obj->Clone();
    1378             : 
    1379           0 :       TString newkey(currIdentifier.Data());
    1380           0 :       newkey.ReplaceAll(identifier,"");
    1381             : 
    1382           0 :       if (newkey=="/") newkey="";
    1383             :       
    1384           0 :       mergCol->InternalAdopt(newkey.Data(),clone);
    1385           0 :     }    
    1386           0 :   }
    1387             : 
    1388             :   return mergCol;
    1389           0 : }
    1390             : 
    1391             : //_____________________________________________________________________________
    1392             : TObject* 
    1393             : AliMergeableCollection::Remove(const char* fullIdentifier)
    1394             : {
    1395             :   ///
    1396             :   /// Remove a given object (given its fullIdentifier=/key1/key2/.../objectName)
    1397             :   ///
    1398             :   /// Note that we do *not* remove the /key1/key2/... entry even if there's no
    1399             :   /// more object for this triplet.
    1400             :   ///
    1401             :   /// Not very efficient. Could be improved ?
    1402             :   ///
    1403             :   
    1404           0 :   TString identifier = GetIdentifier(fullIdentifier);
    1405             :   
    1406           0 :   THashList* hlist = dynamic_cast<THashList*>(Map()->GetValue(identifier.Data()));
    1407             :   
    1408           0 :   if (!hlist)
    1409             :   {
    1410           0 :     AliWarning(Form("Could not get hlist for key=%s",identifier.Data()));
    1411           0 :     return 0x0;
    1412             :   }
    1413             :     
    1414           0 :   TObject* obj = GetObject(fullIdentifier);
    1415           0 :   if (!obj)
    1416             :   {
    1417           0 :     AliError(Form("Could not find object %s",fullIdentifier));
    1418           0 :     return 0x0;
    1419             :   }
    1420             :   
    1421           0 :   TObject* rmObj = hlist->Remove(obj);
    1422           0 :   if (!rmObj)
    1423             :   {
    1424           0 :     AliError("Remove failed");
    1425           0 :     return 0x0;
    1426             :   }
    1427             :   
    1428           0 :   return rmObj;
    1429           0 : }
    1430             : 
    1431             : //_____________________________________________________________________________
    1432             : Int_t AliMergeableCollection::RemoveByType(const char* typeName)
    1433             : {
    1434             :   /// Remove all the objects in this collection that are of a given type
    1435           0 :   TIter nextIdentifier(Map());
    1436             :   TObjString* identifier;
    1437             :   Int_t nremoved(0);
    1438             :   
    1439           0 :   while ( (identifier = static_cast<TObjString*>(nextIdentifier()) ) )
    1440             :   {
    1441           0 :     THashList* list  = static_cast<THashList*>(Map()->GetValue(identifier->String()));
    1442           0 :     TIter next(list);
    1443             :     TObject* o;
    1444             :     
    1445           0 :     while ( ( o = next() ) )
    1446             :     {
    1447           0 :       if ( strcmp(o->ClassName(),typeName) == 0 )
    1448             :       {
    1449           0 :         list->Remove(o);
    1450           0 :         ++nremoved;
    1451           0 :       }
    1452             :     }
    1453           0 :   }
    1454             :   return nremoved;
    1455           0 : }
    1456             : 
    1457             : 
    1458             : //_____________________________________________________________________________
    1459             : TObjArray*
    1460             : AliMergeableCollection::SortAllIdentifiers() const
    1461             : {
    1462             :   /// Sort our internal identifiers. Returned array must be deleted.
    1463           0 :   TObjArray* identifiers = new TObjArray;
    1464           0 :   identifiers->SetOwner(kFALSE); 
    1465           0 :   TIter next(Map());
    1466             :   TObjString* sid;
    1467             :   
    1468           0 :   while ( ( sid = static_cast<TObjString*>(next()) ) )
    1469             :   {
    1470           0 :     if ( !identifiers->FindObject(sid->String().Data()) )
    1471             :     {
    1472           0 :       identifiers->Add(sid);      
    1473             :     }
    1474             :   }
    1475           0 :   identifiers->Sort();
    1476             :   return identifiers;
    1477           0 : }
    1478             : 
    1479             : 
    1480             : ///////////////////////////////////////////////////////////////////////////////
    1481             : //
    1482             : // AliMergeableCollectionIterator
    1483             : //
    1484             : ///////////////////////////////////////////////////////////////////////////////
    1485             : 
    1486             : class AliMergeableCollectionIterator;
    1487             : 
    1488             : //_____________________________________________________________________________
    1489           0 : AliMergeableCollectionIterator::AliMergeableCollectionIterator(const AliMergeableCollection* mcol, Bool_t dir)
    1490           0 : : fkMergeableCollection(mcol), fMapIterator(0x0), fHashListIterator(0x0), fDirection(dir)
    1491           0 : {
    1492             :   /// Default ctor
    1493           0 : }
    1494             : 
    1495             : //_____________________________________________________________________________
    1496             : AliMergeableCollectionIterator&
    1497             : AliMergeableCollectionIterator::operator=(const TIterator&)
    1498             : {
    1499             :   /// Overriden operator= (imposed by Root's declaration of TIterator ?)
    1500           0 :   Fatal("TIterator::operator=","Not implementeable"); // because there's no clone in TIterator :-(
    1501           0 :   return *this;
    1502             : }
    1503             : 
    1504             : //_____________________________________________________________________________
    1505             : AliMergeableCollectionIterator::~AliMergeableCollectionIterator()
    1506           0 : {
    1507             :   /// dtor
    1508           0 :   Reset();
    1509           0 : }
    1510             : 
    1511             : //_____________________________________________________________________________
    1512             : TObject* AliMergeableCollectionIterator::Next()
    1513             : {
    1514             :   /// Advance to next object in the collection
    1515             :   
    1516           0 :   if (!fHashListIterator)
    1517             :   {
    1518           0 :     if ( !fMapIterator ) 
    1519             :     {
    1520           0 :       fMapIterator = fkMergeableCollection->fMap->MakeIterator(fDirection);
    1521           0 :     }
    1522           0 :     TObjString* key = static_cast<TObjString*>(fMapIterator->Next());
    1523           0 :     if (!key)
    1524             :     {
    1525             :       // we are done
    1526           0 :       return 0x0;
    1527             :     }      
    1528           0 :     THashList* list = static_cast<THashList*>(fkMergeableCollection->Map()->GetValue(key->String().Data()));
    1529           0 :     if (!list) return 0x0;
    1530           0 :     fHashListIterator = list->MakeIterator(fDirection);
    1531           0 :   }
    1532             : 
    1533           0 :   TObject* obj = fHashListIterator->Next();
    1534             :   
    1535           0 :   if (!obj) 
    1536             :   {
    1537           0 :     delete fHashListIterator;
    1538           0 :     fHashListIterator = 0x0;
    1539           0 :     return Next();
    1540             :   }
    1541             :   
    1542           0 :   return obj;
    1543           0 : }
    1544             : 
    1545             : //_____________________________________________________________________________
    1546             : void AliMergeableCollectionIterator::Reset()
    1547             : {
    1548             :   /// Reset the iterator
    1549           0 :   delete fHashListIterator;
    1550           0 :   delete fMapIterator;
    1551           0 : }
    1552             : 
    1553             : 
    1554             : ///////////////////////////////////////////////////////////////////////////////
    1555             : //
    1556             : // AliMergeableCollectionProxy
    1557             : //
    1558             : ///////////////////////////////////////////////////////////////////////////////
    1559             : 
    1560             : class AliMergeableCollectionProxy;
    1561             : 
    1562             : //_____________________________________________________________________________
    1563           0 : AliMergeableCollectionProxy::AliMergeableCollectionProxy(AliMergeableCollection& oc,
    1564             :                                                          THashList& list)
    1565           0 : : fOC(oc), fList(list)
    1566           0 : {
    1567           0 :   fName = fList.GetName();
    1568           0 : }
    1569             : 
    1570             : //_____________________________________________________________________________
    1571             : Bool_t AliMergeableCollectionProxy::Adopt(TObject* obj)
    1572             : {
    1573           0 :   return fOC.Adopt(fList.GetName(),obj);
    1574             : }
    1575             : 
    1576             : //_____________________________________________________________________________
    1577             : Bool_t
    1578             : AliMergeableCollectionProxy::Adopt(const char* identifier, TObject* obj)
    1579             : {
    1580             :   /// Adopt a given object, and associate it with pair key
    1581             :   
    1582           0 :   TString path;
    1583           0 :   path.Form("%s%s",fList.GetName(),identifier);
    1584           0 :   return fOC.Adopt(path,obj);
    1585           0 : }
    1586             : 
    1587             : //_____________________________________________________________________________
    1588             : TObject* AliMergeableCollectionProxy::GetObject(const char* objectName) const
    1589             : {
    1590           0 :   return fList.FindObject(objectName);
    1591             : }
    1592             : 
    1593             : //_____________________________________________________________________________
    1594             : TH1* AliMergeableCollectionProxy::Histo(const char* objectName) const
    1595             : {
    1596           0 :   if ( strchr(objectName,':') )
    1597             :   {
    1598           0 :     TString action;
    1599             :     
    1600           0 :     TObjArray* arr = TString(objectName).Tokenize(":");
    1601             :     
    1602           0 :     if ( arr->GetLast() > 0 )
    1603             :     {
    1604           0 :       action = static_cast<TObjString*>(arr->At(1))->String();
    1605           0 :       action.ToUpper();
    1606             :     }
    1607             :     
    1608           0 :     TString oname = static_cast<TObjString*>(arr->At(0))->String();
    1609             :     
    1610           0 :     delete arr;
    1611             : 
    1612           0 :     TObject* o = GetObject(oname);
    1613             :     
    1614           0 :     return fOC.HistoWithAction("",o,action);
    1615           0 :   }
    1616             : 
    1617           0 :   TObject* o = GetObject(objectName);
    1618             : 
    1619           0 :   if (o && o->IsA()->InheritsFrom(TH1::Class()))
    1620             :   {
    1621           0 :     return static_cast<TH1*>(o);
    1622             :   }
    1623             :   
    1624           0 :   return 0x0;
    1625           0 : }
    1626             : 
    1627             : //_____________________________________________________________________________
    1628             : TH2* AliMergeableCollectionProxy::H2(const char* objectName) const
    1629             : {
    1630           0 :   TObject* o = GetObject(objectName);
    1631             :   
    1632           0 :   if (o->IsA()->InheritsFrom(TH2::Class()))
    1633             :   {
    1634           0 :     return static_cast<TH2*>(o);
    1635             :   }
    1636           0 :   return 0x0;
    1637           0 : }
    1638             : 
    1639             : //_____________________________________________________________________________
    1640             : TProfile* AliMergeableCollectionProxy::Prof(const char* objectName) const
    1641             : {
    1642           0 :   TObject* o = GetObject(objectName);
    1643             :   
    1644           0 :   if (o->IsA()->InheritsFrom(TProfile::Class()))
    1645             :   {
    1646           0 :     return static_cast<TProfile*>(o);
    1647             :   }
    1648           0 :   return 0x0;
    1649           0 : }
    1650             : 
    1651             : //_____________________________________________________________________________
    1652             : void AliMergeableCollectionProxy::Print(Option_t* opt) const
    1653             : {
    1654           0 :   fList.Print(opt);
    1655           0 : }
    1656             : 
    1657             : //_____________________________________________________________________________
    1658             : TIterator* AliMergeableCollectionProxy::CreateIterator(Bool_t dir) const
    1659             : {
    1660           0 :   return fList.MakeIterator(dir);
    1661             : }

Generated by: LCOV version 1.11