ROOT logo
/**************************************************************************
* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
*                                                                        *
* Author: The ALICE Off-line Project.                                    *
* Contributors are mentioned in the code where appropriate.              *
*                                                                        *
* Permission to use, copy, modify and distribute this software and its   *
* documentation strictly for non-commercial purposes is hereby granted   *
* without fee, provided that the above copyright notice appears in all   *
* copies and that both the copyright notice and this permission notice   *
* appear in the supporting documentation. The authors make no claims     *
* about the suitability of this software for any purpose. It is          *
* provided "as is" without express or implied warranty.                  *
**************************************************************************/

// $Id$

//-----------------------------------------------------------------------------
/// \class AliMUONTreeManager
///
/// Helper class to handle the relationships TTree<->MUON data containers
/// 
/// The general way of dealing with I/O for MUON is a two stage process :
/// 
/// 1) first get a TTree pointer using the AliLoader mechanism (this is AliRoot
///    general)
///
/// 2) connect that TTree to a MUON (virtual) data container using
///    the container's Connect(TTree&) method (this is MUON specific)
///
/// This class helps implementing stage 2 in the relevant store implementations
///
/// \see AliMUONVStore
///
/// Basically, the relationship Tree<->Store is possible because
/// the TreeManager, when creating branches, uses the UserInfo part of the
/// TTree to store the relationship branch -> MUON store classname.
///
/// \author Laurent Aphecetche, Subatech
//-----------------------------------------------------------------------------

#include "AliMUONTreeManager.h"

#include "AliLog.h"
#include "AliMUONObjectPair.h"
#include <TList.h>
#include <TObjString.h>
#include <TTree.h>
#include <TBranch.h>
#include <Riostream.h>

using std::cout;
using std::endl;
/// \cond CLASSIMP 
ClassImp(AliMUONTreeManager)
/// \endcond

//_____________________________________________________________________________
AliMUONTreeManager::AliMUONTreeManager() : TObject()
{
  /// Default ctor
}

//_____________________________________________________________________________
AliMUONTreeManager::~AliMUONTreeManager()
{
  /// Dtor
}

//_____________________________________________________________________________
void
AliMUONTreeManager::GetEvent(TTree& tree, Int_t event) const
{
  /// Equivalent to tree.GetEvent(event) is NDEBUG is not defined,
  /// otherwise insure that selected branches have a non-zero address
  /// (the contrary indicating we'll get a memory leak when reading the
  /// tree).
  
#ifndef NDEBUG
    TObjArray* branches = tree.GetListOfBranches();
    TIter next(branches);
    TBranch* branch;
    Bool_t error(kFALSE);
    
    while ( ( branch = static_cast<TBranch*>(next()) ) )
    {
      TString bname(branch->GetName());
      if ( branch->GetAddress() == 0 &&
           tree.GetBranchStatus(bname.Data()) == 1 ) 
      {
        AliError(Form("Branch %s has status 1 and no address",bname.Data()));
        error = kTRUE;
      }
    }
    
    if ( error ) 
    {
      ShowStatus(tree);
    }
#endif
  
  tree.GetEvent(event);
}

//_____________________________________________________________________________
void
AliMUONTreeManager::ShowStatus(TTree& tree) const
{
  /// Show main branches status and address
  TObjArray* branches = tree.GetListOfBranches();
  TIter next(branches);
  TBranch* branch;
  
  while ( ( branch = static_cast<TBranch*>(next()) ) )
  {
    TString bname(branch->GetName());
    Int_t status = tree.GetBranchStatus(bname.Data());
    cout << Form("%50s Status %d Address %p",bname.Data(),status,branch->GetAddress()) << endl;
  }
}

//_____________________________________________________________________________
void 
AliMUONTreeManager::AddClassName(TTree& tree, const char* pattern, 
                                 const char* className) const
{
  /// Adds a association (pattern,className) to the UserInfo() of tree
  /// It is mandatory to use this method in MakeBranches(), as this is the key
  /// to get an automatic container creation from a tree.
  
  TString test(GetClassName(tree,pattern,kFALSE));
  if ( test.Length() == 0 )
  {
    // not already there
    TList* userInfo = tree.GetUserInfo();
    userInfo->Add(new AliMUONObjectPair(new TObjString(pattern),
                                        new TObjString(className),
                                        kTRUE,kTRUE));
  }
}

//_____________________________________________________________________________
Bool_t
AliMUONTreeManager::MakeBranch(TTree& tree, const char* storeClassName,
                               const char* branchClassName,
                               const char* branchName, 
                               void* address,
                               Int_t bufferSize, Int_t splitLevel) const
{
  /// Create a branch in the tree
  AddClassName(tree,branchName,storeClassName);
  TBranch* branch = tree.Branch(branchName,branchClassName,address,bufferSize,splitLevel);
  return ( branch != 0x0 );
}

//_____________________________________________________________________________
Bool_t 
AliMUONTreeManager::SetAddress(TTree& tree, const char* branchName, 
                               void* address) const
{
  /// Set the address for one branch
  TBranch* branch = tree.GetBranch(branchName);
  if (branch)
  {
    branch->SetAddress(address);
    return kTRUE;
  }
  AliError(Form("Did not find branch %s in tree %s",branchName,tree.GetName()));
  return kFALSE;
}

//_____________________________________________________________________________
TObject* 
AliMUONTreeManager::CreateObject(const TTree& tree, const char* detail) const
{
  /// Object creation from tree, using
  /// the (pattern,className) pairs stored in the UserInfo() of TTree.
  TString className(GetClassName(tree,detail,kTRUE));
  TClass* classPtr = TClass::GetClass(className.Data());
  if (!classPtr)
  {
    AliError(Form("Could not get class %s",className.Data()));
    return 0x0;
  }
  return reinterpret_cast<TObject*>(classPtr->New());
}

//_____________________________________________________________________________
void 
AliMUONTreeManager::UpdateBranchStatuses(TTree& tree, const char* pattern) const
{
  /// Loop over tree branches and set their status if their name matches
  /// the pattern : 
  /// - zero if branch address is null and 
  /// - one otherwise
  /// This will avoid memory leak, if we set the address to only part
  /// of the branches before doing a tree.GetEvent(i)
  ///
  /// WARNING : this is a time consuming operation, as we loop over branches
  /// at least twice (one here, and the TTree::SetBranchStatus is itself
  /// a loop). So use only when necessary.
  ///
  
  TIter next(tree.GetListOfBranches());
  TBranch* branch;
  
  while ( ( branch = static_cast<TBranch*>(next()) ) )
  {
    TString bname(branch->GetName());
    if ( bname.Contains(pattern) )
    {
      tree.SetBranchStatus(Form("%s*",branch->GetName()),1);
    }
    else
    {
      if ( !branch->GetAddress() )
      {
        tree.SetBranchStatus(Form("%s*",branch->GetName()),0);
      }
    }
  }

}

//_____________________________________________________________________________
TString
AliMUONTreeManager::GetClassName(const TTree& tree, const char* pattern,
                                 Bool_t makeDefault) const
{
  /// Find out, using the TTree::UserInfo, the classname corresponding to 
  /// pattern.
  /// If makeDefault=true and we cannot find the pattern in the UserInfo,
  /// we return DefaultClassName(pattern)
  ///
  
  TTree& vtree = const_cast<TTree&>(tree); // not pretty, but the GetUserInfo is not const...
  
  TIter next(vtree.GetUserInfo());
  
  TObject* object;
  
  while ( ( object = next() ) )
  {
    AliMUONObjectPair* pair = static_cast<AliMUONObjectPair*>(object);
    TString key = (static_cast<TObjString*>(pair->First()))->String();
    TString value = (static_cast<TObjString*>(pair->Second()))->String();
    if ( key.Contains(pattern,TString::kIgnoreCase) ) 
    {
      return value;
    }
  }
  
  if ( makeDefault ) return DefaultClassName(tree.GetName(),pattern);
  
  return "";
}

//_____________________________________________________________________________
TString
AliMUONTreeManager::DefaultClassName(const char* treeName, const char* pattern) const
{
  /// For backward compatibility only. Decides, based on the tree name and a 
  /// pattern, which store class should be used.
  
  TString name(treeName);
  TString spattern(pattern);
  spattern.ToUpper();
  
  if ( name == "TreeH" ) 
  {
    return "AliMUONHitStoreV1";
  }
  
  if ( name == "TreeD" || name == "TreeS" ) 
  {
    if ( spattern.Contains("TRIGGER") ) return "AliMUONTriggerStoreV1";
    if ( spattern.Contains("DIGIT") ) return "AliMUONDigitStoreV1";
  }
  
  if ( name == "TreeR" ) 
  {
    if ( spattern.Contains("CLUSTER") ) return "AliMUONClusterStoreV1";
    if ( spattern.Contains("TRIGGER") ) return "AliMUONTriggerStoreV1";
  }
  
  if ( name == "TreeT" ) 
  {
    if ( spattern.Contains("TRIGGER" ) ) return "AliMUONTriggerTrackStoreV1";
    if ( spattern.Contains("TRACK") ) return "AliMUONTrackStoreV1";
  }
  
  AliError(Form("Do not know how to create default class for tree %s pattern %s",
                treeName,pattern));
  return "";
}







 AliMUONTreeManager.cxx:1
 AliMUONTreeManager.cxx:2
 AliMUONTreeManager.cxx:3
 AliMUONTreeManager.cxx:4
 AliMUONTreeManager.cxx:5
 AliMUONTreeManager.cxx:6
 AliMUONTreeManager.cxx:7
 AliMUONTreeManager.cxx:8
 AliMUONTreeManager.cxx:9
 AliMUONTreeManager.cxx:10
 AliMUONTreeManager.cxx:11
 AliMUONTreeManager.cxx:12
 AliMUONTreeManager.cxx:13
 AliMUONTreeManager.cxx:14
 AliMUONTreeManager.cxx:15
 AliMUONTreeManager.cxx:16
 AliMUONTreeManager.cxx:17
 AliMUONTreeManager.cxx:18
 AliMUONTreeManager.cxx:19
 AliMUONTreeManager.cxx:20
 AliMUONTreeManager.cxx:21
 AliMUONTreeManager.cxx:22
 AliMUONTreeManager.cxx:23
 AliMUONTreeManager.cxx:24
 AliMUONTreeManager.cxx:25
 AliMUONTreeManager.cxx:26
 AliMUONTreeManager.cxx:27
 AliMUONTreeManager.cxx:28
 AliMUONTreeManager.cxx:29
 AliMUONTreeManager.cxx:30
 AliMUONTreeManager.cxx:31
 AliMUONTreeManager.cxx:32
 AliMUONTreeManager.cxx:33
 AliMUONTreeManager.cxx:34
 AliMUONTreeManager.cxx:35
 AliMUONTreeManager.cxx:36
 AliMUONTreeManager.cxx:37
 AliMUONTreeManager.cxx:38
 AliMUONTreeManager.cxx:39
 AliMUONTreeManager.cxx:40
 AliMUONTreeManager.cxx:41
 AliMUONTreeManager.cxx:42
 AliMUONTreeManager.cxx:43
 AliMUONTreeManager.cxx:44
 AliMUONTreeManager.cxx:45
 AliMUONTreeManager.cxx:46
 AliMUONTreeManager.cxx:47
 AliMUONTreeManager.cxx:48
 AliMUONTreeManager.cxx:49
 AliMUONTreeManager.cxx:50
 AliMUONTreeManager.cxx:51
 AliMUONTreeManager.cxx:52
 AliMUONTreeManager.cxx:53
 AliMUONTreeManager.cxx:54
 AliMUONTreeManager.cxx:55
 AliMUONTreeManager.cxx:56
 AliMUONTreeManager.cxx:57
 AliMUONTreeManager.cxx:58
 AliMUONTreeManager.cxx:59
 AliMUONTreeManager.cxx:60
 AliMUONTreeManager.cxx:61
 AliMUONTreeManager.cxx:62
 AliMUONTreeManager.cxx:63
 AliMUONTreeManager.cxx:64
 AliMUONTreeManager.cxx:65
 AliMUONTreeManager.cxx:66
 AliMUONTreeManager.cxx:67
 AliMUONTreeManager.cxx:68
 AliMUONTreeManager.cxx:69
 AliMUONTreeManager.cxx:70
 AliMUONTreeManager.cxx:71
 AliMUONTreeManager.cxx:72
 AliMUONTreeManager.cxx:73
 AliMUONTreeManager.cxx:74
 AliMUONTreeManager.cxx:75
 AliMUONTreeManager.cxx:76
 AliMUONTreeManager.cxx:77
 AliMUONTreeManager.cxx:78
 AliMUONTreeManager.cxx:79
 AliMUONTreeManager.cxx:80
 AliMUONTreeManager.cxx:81
 AliMUONTreeManager.cxx:82
 AliMUONTreeManager.cxx:83
 AliMUONTreeManager.cxx:84
 AliMUONTreeManager.cxx:85
 AliMUONTreeManager.cxx:86
 AliMUONTreeManager.cxx:87
 AliMUONTreeManager.cxx:88
 AliMUONTreeManager.cxx:89
 AliMUONTreeManager.cxx:90
 AliMUONTreeManager.cxx:91
 AliMUONTreeManager.cxx:92
 AliMUONTreeManager.cxx:93
 AliMUONTreeManager.cxx:94
 AliMUONTreeManager.cxx:95
 AliMUONTreeManager.cxx:96
 AliMUONTreeManager.cxx:97
 AliMUONTreeManager.cxx:98
 AliMUONTreeManager.cxx:99
 AliMUONTreeManager.cxx:100
 AliMUONTreeManager.cxx:101
 AliMUONTreeManager.cxx:102
 AliMUONTreeManager.cxx:103
 AliMUONTreeManager.cxx:104
 AliMUONTreeManager.cxx:105
 AliMUONTreeManager.cxx:106
 AliMUONTreeManager.cxx:107
 AliMUONTreeManager.cxx:108
 AliMUONTreeManager.cxx:109
 AliMUONTreeManager.cxx:110
 AliMUONTreeManager.cxx:111
 AliMUONTreeManager.cxx:112
 AliMUONTreeManager.cxx:113
 AliMUONTreeManager.cxx:114
 AliMUONTreeManager.cxx:115
 AliMUONTreeManager.cxx:116
 AliMUONTreeManager.cxx:117
 AliMUONTreeManager.cxx:118
 AliMUONTreeManager.cxx:119
 AliMUONTreeManager.cxx:120
 AliMUONTreeManager.cxx:121
 AliMUONTreeManager.cxx:122
 AliMUONTreeManager.cxx:123
 AliMUONTreeManager.cxx:124
 AliMUONTreeManager.cxx:125
 AliMUONTreeManager.cxx:126
 AliMUONTreeManager.cxx:127
 AliMUONTreeManager.cxx:128
 AliMUONTreeManager.cxx:129
 AliMUONTreeManager.cxx:130
 AliMUONTreeManager.cxx:131
 AliMUONTreeManager.cxx:132
 AliMUONTreeManager.cxx:133
 AliMUONTreeManager.cxx:134
 AliMUONTreeManager.cxx:135
 AliMUONTreeManager.cxx:136
 AliMUONTreeManager.cxx:137
 AliMUONTreeManager.cxx:138
 AliMUONTreeManager.cxx:139
 AliMUONTreeManager.cxx:140
 AliMUONTreeManager.cxx:141
 AliMUONTreeManager.cxx:142
 AliMUONTreeManager.cxx:143
 AliMUONTreeManager.cxx:144
 AliMUONTreeManager.cxx:145
 AliMUONTreeManager.cxx:146
 AliMUONTreeManager.cxx:147
 AliMUONTreeManager.cxx:148
 AliMUONTreeManager.cxx:149
 AliMUONTreeManager.cxx:150
 AliMUONTreeManager.cxx:151
 AliMUONTreeManager.cxx:152
 AliMUONTreeManager.cxx:153
 AliMUONTreeManager.cxx:154
 AliMUONTreeManager.cxx:155
 AliMUONTreeManager.cxx:156
 AliMUONTreeManager.cxx:157
 AliMUONTreeManager.cxx:158
 AliMUONTreeManager.cxx:159
 AliMUONTreeManager.cxx:160
 AliMUONTreeManager.cxx:161
 AliMUONTreeManager.cxx:162
 AliMUONTreeManager.cxx:163
 AliMUONTreeManager.cxx:164
 AliMUONTreeManager.cxx:165
 AliMUONTreeManager.cxx:166
 AliMUONTreeManager.cxx:167
 AliMUONTreeManager.cxx:168
 AliMUONTreeManager.cxx:169
 AliMUONTreeManager.cxx:170
 AliMUONTreeManager.cxx:171
 AliMUONTreeManager.cxx:172
 AliMUONTreeManager.cxx:173
 AliMUONTreeManager.cxx:174
 AliMUONTreeManager.cxx:175
 AliMUONTreeManager.cxx:176
 AliMUONTreeManager.cxx:177
 AliMUONTreeManager.cxx:178
 AliMUONTreeManager.cxx:179
 AliMUONTreeManager.cxx:180
 AliMUONTreeManager.cxx:181
 AliMUONTreeManager.cxx:182
 AliMUONTreeManager.cxx:183
 AliMUONTreeManager.cxx:184
 AliMUONTreeManager.cxx:185
 AliMUONTreeManager.cxx:186
 AliMUONTreeManager.cxx:187
 AliMUONTreeManager.cxx:188
 AliMUONTreeManager.cxx:189
 AliMUONTreeManager.cxx:190
 AliMUONTreeManager.cxx:191
 AliMUONTreeManager.cxx:192
 AliMUONTreeManager.cxx:193
 AliMUONTreeManager.cxx:194
 AliMUONTreeManager.cxx:195
 AliMUONTreeManager.cxx:196
 AliMUONTreeManager.cxx:197
 AliMUONTreeManager.cxx:198
 AliMUONTreeManager.cxx:199
 AliMUONTreeManager.cxx:200
 AliMUONTreeManager.cxx:201
 AliMUONTreeManager.cxx:202
 AliMUONTreeManager.cxx:203
 AliMUONTreeManager.cxx:204
 AliMUONTreeManager.cxx:205
 AliMUONTreeManager.cxx:206
 AliMUONTreeManager.cxx:207
 AliMUONTreeManager.cxx:208
 AliMUONTreeManager.cxx:209
 AliMUONTreeManager.cxx:210
 AliMUONTreeManager.cxx:211
 AliMUONTreeManager.cxx:212
 AliMUONTreeManager.cxx:213
 AliMUONTreeManager.cxx:214
 AliMUONTreeManager.cxx:215
 AliMUONTreeManager.cxx:216
 AliMUONTreeManager.cxx:217
 AliMUONTreeManager.cxx:218
 AliMUONTreeManager.cxx:219
 AliMUONTreeManager.cxx:220
 AliMUONTreeManager.cxx:221
 AliMUONTreeManager.cxx:222
 AliMUONTreeManager.cxx:223
 AliMUONTreeManager.cxx:224
 AliMUONTreeManager.cxx:225
 AliMUONTreeManager.cxx:226
 AliMUONTreeManager.cxx:227
 AliMUONTreeManager.cxx:228
 AliMUONTreeManager.cxx:229
 AliMUONTreeManager.cxx:230
 AliMUONTreeManager.cxx:231
 AliMUONTreeManager.cxx:232
 AliMUONTreeManager.cxx:233
 AliMUONTreeManager.cxx:234
 AliMUONTreeManager.cxx:235
 AliMUONTreeManager.cxx:236
 AliMUONTreeManager.cxx:237
 AliMUONTreeManager.cxx:238
 AliMUONTreeManager.cxx:239
 AliMUONTreeManager.cxx:240
 AliMUONTreeManager.cxx:241
 AliMUONTreeManager.cxx:242
 AliMUONTreeManager.cxx:243
 AliMUONTreeManager.cxx:244
 AliMUONTreeManager.cxx:245
 AliMUONTreeManager.cxx:246
 AliMUONTreeManager.cxx:247
 AliMUONTreeManager.cxx:248
 AliMUONTreeManager.cxx:249
 AliMUONTreeManager.cxx:250
 AliMUONTreeManager.cxx:251
 AliMUONTreeManager.cxx:252
 AliMUONTreeManager.cxx:253
 AliMUONTreeManager.cxx:254
 AliMUONTreeManager.cxx:255
 AliMUONTreeManager.cxx:256
 AliMUONTreeManager.cxx:257
 AliMUONTreeManager.cxx:258
 AliMUONTreeManager.cxx:259
 AliMUONTreeManager.cxx:260
 AliMUONTreeManager.cxx:261
 AliMUONTreeManager.cxx:262
 AliMUONTreeManager.cxx:263
 AliMUONTreeManager.cxx:264
 AliMUONTreeManager.cxx:265
 AliMUONTreeManager.cxx:266
 AliMUONTreeManager.cxx:267
 AliMUONTreeManager.cxx:268
 AliMUONTreeManager.cxx:269
 AliMUONTreeManager.cxx:270
 AliMUONTreeManager.cxx:271
 AliMUONTreeManager.cxx:272
 AliMUONTreeManager.cxx:273
 AliMUONTreeManager.cxx:274
 AliMUONTreeManager.cxx:275
 AliMUONTreeManager.cxx:276
 AliMUONTreeManager.cxx:277
 AliMUONTreeManager.cxx:278
 AliMUONTreeManager.cxx:279
 AliMUONTreeManager.cxx:280
 AliMUONTreeManager.cxx:281
 AliMUONTreeManager.cxx:282
 AliMUONTreeManager.cxx:283
 AliMUONTreeManager.cxx:284
 AliMUONTreeManager.cxx:285
 AliMUONTreeManager.cxx:286
 AliMUONTreeManager.cxx:287
 AliMUONTreeManager.cxx:288
 AliMUONTreeManager.cxx:289
 AliMUONTreeManager.cxx:290
 AliMUONTreeManager.cxx:291
 AliMUONTreeManager.cxx:292
 AliMUONTreeManager.cxx:293
 AliMUONTreeManager.cxx:294
 AliMUONTreeManager.cxx:295
 AliMUONTreeManager.cxx:296
 AliMUONTreeManager.cxx:297
 AliMUONTreeManager.cxx:298
 AliMUONTreeManager.cxx:299
 AliMUONTreeManager.cxx:300
 AliMUONTreeManager.cxx:301
 AliMUONTreeManager.cxx:302