switch to fill only events added
[u/mrichter/AliRoot.git] / ANALYSIS / AliAnalysisDataSlot.cxx
CommitLineData
d3106602 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// Author: Andrei Gheata, 31/05/2006
18
19//==============================================================================
20// AliAnalysysDataSlot - Class representing a data slot of an analysis task.
21// An analysis slot enforces a certain data type required by the Exec()
22// method of the analysis task. The slot must be connected to a data
23// container with data of the same type.
24//
25// The class should not be directly created by users - it is created by
26// each AliAnalysisTask when defining its input/output slots using:
27//
28// AliAnalysisTask::SetInput(Int_t index, TClass *type);
29// AliAnalysisTask::SetOutput(TClass *type);
30//
31// An existing data contaner (AliAnalysisDataContainer) can be connected to the
32// input/output slots of an analysis task using:
33//
34// AliAnalysisModule::ConnectInput(AliAnalysisTask *task, Int_t islot,
35// AliAnalysisDataContainer *cont)
36// AliAnalysisModule::ConnectOutput(AliAnalysisTask *task,
37// AliAnalysisDataContainer *cont)
38// To connect a slot to a data container, the data types declared by both must
39// match.
40//==============================================================================
41
c52c2132 42#include <Riostream.h>
43#include <TROOT.h>
44#include <TClass.h>
45#include <TTree.h>
521adffd 46#include <TLeaf.h>
d3106602 47
48#include "AliAnalysisDataSlot.h"
49#include "AliAnalysisTask.h"
50#include "AliAnalysisDataContainer.h"
51
c82bb898 52using std::endl;
53using std::cout;
d3106602 54ClassImp(AliAnalysisDataSlot)
55
56//______________________________________________________________________________
c52c2132 57AliAnalysisDataSlot::AliAnalysisDataSlot(TClass *type, AliAnalysisTask *task)
58 :TNamed(),
59 fType(type),
60 fParent(task),
61 fContainer(NULL)
62{
63// Default constructor.
64 SetTitle(fType->GetName());
65}
66
67//______________________________________________________________________________
68AliAnalysisDataSlot::AliAnalysisDataSlot(const AliAnalysisDataSlot &slot)
69 :TNamed(slot),
70 fType(NULL),
71 fParent(slot.fParent),
72 fContainer(slot.fContainer)
73{
74// Copy ctor.
75 GetType();
76}
77
78//______________________________________________________________________________
37a26056 79AliAnalysisDataSlot& AliAnalysisDataSlot::operator=(const AliAnalysisDataSlot &slot)
80{
81// Assignment
82 if (&slot == this) return *this;
c52c2132 83 TNamed::operator=(slot);
84 GetType();
37a26056 85 fParent = slot.fParent;
86 fContainer = slot.fContainer;
87 return *this;
88}
89
90//______________________________________________________________________________
d3106602 91Bool_t AliAnalysisDataSlot::ConnectContainer(AliAnalysisDataContainer *cont)
92{
93// Connect the data slot with a given container. The operation will succeed only
94// if the type defined by the slot inherits from the type enforced by the container.
95// The error message in case of failure is posted by the caller.
c52c2132 96 if (!cont || !GetType()) return kFALSE;
d3106602 97 if (!fType->InheritsFrom(cont->GetType())) {
c52c2132 98 cout<<"Data slot of type "<<GetTitle()<<" of task "<<fParent->GetName()<<" cannot be connected to data container "<<cont->GetName()<<" of type "<<cont->GetTitle()<<endl;
11026a80 99 //AliError(Form("Data slot of type %s of task %s cannot be connected to data container %s of type %s", fType->GetName(), fParent->GetName(), cont->GetName(), cont->GetType()->GetName()));
d3106602 100 return kFALSE;
101 }
102 fContainer = cont;
103 return kTRUE;
104}
105
106//______________________________________________________________________________
c52c2132 107TClass *AliAnalysisDataSlot::GetType() const
108{
109// Get class type for this slot.
110 AliAnalysisDataSlot *slot = (AliAnalysisDataSlot*)this;
111 if (!fType) slot->SetType(gROOT->GetClass(fTitle.Data()));
112 if (!fType) printf("AliAnalysisDataSlot: Unknown class: %s\n", GetTitle());
113 return fType;
114}
115
116//______________________________________________________________________________
327eaf46 117void *AliAnalysisDataSlot::GetBranchAddress(const char *branchname) const
118{
119// Retrieve the address for a given branch. One should always test this before
120// using SetBranchAddress because the address gets set by the first caller.
121// Call this in MyTask::Init()
c52c2132 122 if (!GetType()) return NULL;
327eaf46 123 if (!fType->InheritsFrom(TTree::Class())) {
11026a80 124 cout<<"Cannot call GetBranchAddress() for data slot of task "<<fParent->GetName()<<" not pointing to tree-type data"<<endl;
125 //AliFatal(Form("Cannot call GetBranchAddress() for data slot of task %s not pointing to tree-type data", fParent->GetName()));
327eaf46 126 return NULL;
127 }
128 if (!IsDataReady()) {
11026a80 129 cout<<"Cannot call GetBranchAddress() for data slot of task "<<fParent->GetName()<<" while data is not ready"<<endl;
130 //AliFatal(Form("Cannot call GetBranchAddress() for data slot of task %s while data is not ready", fParent->GetName()));
327eaf46 131 return NULL;
132 }
133 TTree *tree = (TTree*)GetData();
134 TBranch *br = tree->GetBranch(branchname);
135 if (!br) {
11026a80 136 cout<<"Branch "<<branchname<<" not found in tree "<<tree->GetName()<<" as input of task "<<fParent->GetName()<<"..."<<endl;
137 //AliFatal(Form("Branch %s not found in tree %s as input of task %s...", branchname, tree->GetName(), fParent->GetName()));
327eaf46 138 return NULL;
139 }
140 return br->GetAddress();
141}
142
143//______________________________________________________________________________
b1310ef5 144Int_t AliAnalysisDataSlot::EnableBranch(const char *bname, TTree *tree)
145{
146// Static method to enable recursively a branch in a tree (why this in not in ROOT?)
147 TBranch *branch = tree->GetBranch(bname);
148 Int_t count = 0;
149// static Int_t indent = 0;
150 if (!branch) return count;
151// TString s;
152// for (Int_t i=0; i<indent; i++) s += " ";
153 count++;
154// printf("%sbranch %s: kDoNotProcess=%d\n",s.Data(), branch->GetName(), branch->TestBit(kDoNotProcess));
155 branch->SetBit(kDoNotProcess, kFALSE);
156 TIter next(branch->GetListOfBranches());
157 TBranch *branch_sub;
158 // Activate all sub-branches
159// indent++;
160 while ((branch_sub=(TBranch*)next())) {
161 count += AliAnalysisDataSlot::EnableBranch(branch_sub->GetName(), tree);
162 }
163// indent--;
164 return count;
165}
166
167//______________________________________________________________________________
327eaf46 168Bool_t AliAnalysisDataSlot::SetBranchAddress(const char *branchname, void *address)
169{
170// Set a branch address for input tree. To be called during MyTask::Init()
171// only if GetBranchAddress() returns a NULL pointer for a tree-type slot.
172 if (GetBranchAddress(branchname)) {
981f2614 173 Error("SetBranchAddress","Branch address for %s already set by other task. Call first GetBranchAddress() in %s::ConnectInputData()",branchname, fParent->GetName());
327eaf46 174 return kFALSE;
175 }
176 TTree *tree = (TTree*)GetData();
177 tree->SetBranchAddress(branchname, address);
178 return kTRUE;
179}
180
181//______________________________________________________________________________
d3106602 182TObject *AliAnalysisDataSlot::GetData() const
183{
184// Retreives the data from the container if it is ready.
185 if (!fContainer) {
11026a80 186 //AliError(Form("Data slot of type %s of task %s has no connected data container",fType->GetName(), fParent->GetName()));
d3106602 187 return NULL;
188 }
189 if (!fContainer->IsDataReady()) return NULL;
190 return fContainer->GetData();
191}
192
193//______________________________________________________________________________
194Bool_t AliAnalysisDataSlot::IsDataReady() const
195{
196// Check if data for this slot is ready in its container.
197 if (!fContainer) {
c52c2132 198 cout<<"Data slot of type "<<GetTitle()<<" of task "<<fParent->GetName()<<" has no connected data container"<<endl;
11026a80 199 //AliError(Form("Data slot of type %s of task %s has no connected data container",fType->GetName(), fParent->GetName()));
d3106602 200 return kFALSE;
201 }
202 return fContainer->IsDataReady();
203}
204