Make the Scan method public
[u/mrichter/AliRoot.git] / MUON / AliMUONTreeManager.cxx
CommitLineData
de6dbd08 1/**************************************************************************
2* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3* *
4* Author: The ALICE Off-line Project. *
5* Contributors are mentioned in the code where appropriate. *
6* *
7* Permission to use, copy, modify and distribute this software and its *
8* documentation strictly for non-commercial purposes is hereby granted *
9* without fee, provided that the above copyright notice appears in all *
10* copies and that both the copyright notice and this permission notice *
11* appear in the supporting documentation. The authors make no claims *
12* about the suitability of this software for any purpose. It is *
13* provided "as is" without express or implied warranty. *
14**************************************************************************/
15
16// $Id$
17
3d1463c8 18//-----------------------------------------------------------------------------
de6dbd08 19/// \class AliMUONTreeManager
20///
21/// Helper class to handle the relationships TTree<->MUON data containers
22///
23/// The general way of dealing with I/O for MUON is a two stage process :
24///
25/// 1) first get a TTree pointer using the AliLoader mechanism (this is AliRoot
26/// general)
27///
28/// 2) connect that TTree to a MUON (virtual) data container using
29/// the container's Connect(TTree&) method (this is MUON specific)
30///
31/// This class helps implementing stage 2 in the relevant store implementations
32///
33/// \see AliMUONVStore
34///
35/// Basically, the relationship Tree<->Store is possible because
36/// the TreeManager, when creating branches, uses the UserInfo part of the
37/// TTree to store the relationship branch -> MUON store classname.
38///
39/// \author Laurent Aphecetche, Subatech
3d1463c8 40//-----------------------------------------------------------------------------
de6dbd08 41
42#include "AliMUONTreeManager.h"
43
44#include "AliLog.h"
45#include "AliMUONObjectPair.h"
46#include <TList.h>
47#include <TObjString.h>
48#include <TTree.h>
49#include <TBranch.h>
50#include <Riostream.h>
51
b80faac0 52using std::cout;
53using std::endl;
de6dbd08 54/// \cond CLASSIMP
55ClassImp(AliMUONTreeManager)
56/// \endcond
57
58//_____________________________________________________________________________
59AliMUONTreeManager::AliMUONTreeManager() : TObject()
60{
61 /// Default ctor
62}
63
64//_____________________________________________________________________________
65AliMUONTreeManager::~AliMUONTreeManager()
66{
67 /// Dtor
68}
69
70//_____________________________________________________________________________
71void
72AliMUONTreeManager::GetEvent(TTree& tree, Int_t event) const
73{
74 /// Equivalent to tree.GetEvent(event) is NDEBUG is not defined,
75 /// otherwise insure that selected branches have a non-zero address
76 /// (the contrary indicating we'll get a memory leak when reading the
77 /// tree).
78
79#ifndef NDEBUG
80 TObjArray* branches = tree.GetListOfBranches();
81 TIter next(branches);
82 TBranch* branch;
83 Bool_t error(kFALSE);
84
85 while ( ( branch = static_cast<TBranch*>(next()) ) )
86 {
87 TString bname(branch->GetName());
88 if ( branch->GetAddress() == 0 &&
89 tree.GetBranchStatus(bname.Data()) == 1 )
90 {
91 AliError(Form("Branch %s has status 1 and no address",bname.Data()));
92 error = kTRUE;
93 }
94 }
95
96 if ( error )
97 {
98 ShowStatus(tree);
99 }
100#endif
101
102 tree.GetEvent(event);
103}
104
105//_____________________________________________________________________________
106void
107AliMUONTreeManager::ShowStatus(TTree& tree) const
108{
109 /// Show main branches status and address
110 TObjArray* branches = tree.GetListOfBranches();
111 TIter next(branches);
112 TBranch* branch;
113
114 while ( ( branch = static_cast<TBranch*>(next()) ) )
115 {
116 TString bname(branch->GetName());
117 Int_t status = tree.GetBranchStatus(bname.Data());
118 cout << Form("%50s Status %d Address %p",bname.Data(),status,branch->GetAddress()) << endl;
119 }
120}
121
122//_____________________________________________________________________________
123void
124AliMUONTreeManager::AddClassName(TTree& tree, const char* pattern,
125 const char* className) const
126{
127 /// Adds a association (pattern,className) to the UserInfo() of tree
128 /// It is mandatory to use this method in MakeBranches(), as this is the key
129 /// to get an automatic container creation from a tree.
130
131 TString test(GetClassName(tree,pattern,kFALSE));
132 if ( test.Length() == 0 )
133 {
134 // not already there
135 TList* userInfo = tree.GetUserInfo();
136 userInfo->Add(new AliMUONObjectPair(new TObjString(pattern),
137 new TObjString(className),
138 kTRUE,kTRUE));
139 }
140}
141
142//_____________________________________________________________________________
143Bool_t
144AliMUONTreeManager::MakeBranch(TTree& tree, const char* storeClassName,
145 const char* branchClassName,
146 const char* branchName,
147 void* address,
148 Int_t bufferSize, Int_t splitLevel) const
149{
150 /// Create a branch in the tree
151 AddClassName(tree,branchName,storeClassName);
152 TBranch* branch = tree.Branch(branchName,branchClassName,address,bufferSize,splitLevel);
153 return ( branch != 0x0 );
154}
155
156//_____________________________________________________________________________
157Bool_t
158AliMUONTreeManager::SetAddress(TTree& tree, const char* branchName,
159 void* address) const
160{
161 /// Set the address for one branch
162 TBranch* branch = tree.GetBranch(branchName);
163 if (branch)
164 {
165 branch->SetAddress(address);
166 return kTRUE;
167 }
168 AliError(Form("Did not find branch %s in tree %s",branchName,tree.GetName()));
169 return kFALSE;
170}
171
172//_____________________________________________________________________________
173TObject*
174AliMUONTreeManager::CreateObject(const TTree& tree, const char* detail) const
175{
176 /// Object creation from tree, using
177 /// the (pattern,className) pairs stored in the UserInfo() of TTree.
178 TString className(GetClassName(tree,detail,kTRUE));
179 TClass* classPtr = TClass::GetClass(className.Data());
180 if (!classPtr)
181 {
182 AliError(Form("Could not get class %s",className.Data()));
183 return 0x0;
184 }
185 return reinterpret_cast<TObject*>(classPtr->New());
186}
187
188//_____________________________________________________________________________
189void
190AliMUONTreeManager::UpdateBranchStatuses(TTree& tree, const char* pattern) const
191{
192 /// Loop over tree branches and set their status if their name matches
193 /// the pattern :
194 /// - zero if branch address is null and
195 /// - one otherwise
196 /// This will avoid memory leak, if we set the address to only part
197 /// of the branches before doing a tree.GetEvent(i)
198 ///
199 /// WARNING : this is a time consuming operation, as we loop over branches
200 /// at least twice (one here, and the TTree::SetBranchStatus is itself
201 /// a loop). So use only when necessary.
202 ///
203
204 TIter next(tree.GetListOfBranches());
205 TBranch* branch;
206
207 while ( ( branch = static_cast<TBranch*>(next()) ) )
208 {
209 TString bname(branch->GetName());
210 if ( bname.Contains(pattern) )
211 {
212 tree.SetBranchStatus(Form("%s*",branch->GetName()),1);
213 }
214 else
215 {
216 if ( !branch->GetAddress() )
217 {
218 tree.SetBranchStatus(Form("%s*",branch->GetName()),0);
219 }
220 }
221 }
222
223}
224
225//_____________________________________________________________________________
d725888e 226TString
de6dbd08 227AliMUONTreeManager::GetClassName(const TTree& tree, const char* pattern,
228 Bool_t makeDefault) const
229{
230 /// Find out, using the TTree::UserInfo, the classname corresponding to
231 /// pattern.
232 /// If makeDefault=true and we cannot find the pattern in the UserInfo,
233 /// we return DefaultClassName(pattern)
234 ///
235
236 TTree& vtree = const_cast<TTree&>(tree); // not pretty, but the GetUserInfo is not const...
237
238 TIter next(vtree.GetUserInfo());
239
240 TObject* object;
241
242 while ( ( object = next() ) )
243 {
244 AliMUONObjectPair* pair = static_cast<AliMUONObjectPair*>(object);
245 TString key = (static_cast<TObjString*>(pair->First()))->String();
246 TString value = (static_cast<TObjString*>(pair->Second()))->String();
247 if ( key.Contains(pattern,TString::kIgnoreCase) )
248 {
d725888e 249 return value;
de6dbd08 250 }
251 }
252
253 if ( makeDefault ) return DefaultClassName(tree.GetName(),pattern);
254
4e08d74e 255 return "";
de6dbd08 256}
257
258//_____________________________________________________________________________
d725888e 259TString
de6dbd08 260AliMUONTreeManager::DefaultClassName(const char* treeName, const char* pattern) const
261{
262 /// For backward compatibility only. Decides, based on the tree name and a
263 /// pattern, which store class should be used.
264
265 TString name(treeName);
266 TString spattern(pattern);
267 spattern.ToUpper();
268
269 if ( name == "TreeH" )
270 {
271 return "AliMUONHitStoreV1";
272 }
273
274 if ( name == "TreeD" || name == "TreeS" )
275 {
276 if ( spattern.Contains("TRIGGER") ) return "AliMUONTriggerStoreV1";
277 if ( spattern.Contains("DIGIT") ) return "AliMUONDigitStoreV1";
278 }
279
280 if ( name == "TreeR" )
281 {
282 if ( spattern.Contains("CLUSTER") ) return "AliMUONClusterStoreV1";
283 if ( spattern.Contains("TRIGGER") ) return "AliMUONTriggerStoreV1";
284 }
285
286 if ( name == "TreeT" )
287 {
288 if ( spattern.Contains("TRIGGER" ) ) return "AliMUONTriggerTrackStoreV1";
289 if ( spattern.Contains("TRACK") ) return "AliMUONTrackStoreV1";
290 }
291
292 AliError(Form("Do not know how to create default class for tree %s pattern %s",
293 treeName,pattern));
294 return "";
295}
296
297
298
299
300
301
302