1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 // Author: Andrei Gheata, 31/05/2006
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.
25 // The class should not be directly created by users - it is created by
26 // each AliAnalysisTask when defining its input/output slots using:
28 // AliAnalysisTask::SetInput(Int_t index, TClass *type);
29 // AliAnalysisTask::SetOutput(TClass *type);
31 // An existing data contaner (AliAnalysisDataContainer) can be connected to the
32 // input/output slots of an analysis task using:
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
40 //==============================================================================
42 #include <Riostream.h>
47 #include "AliAnalysisDataSlot.h"
48 #include "AliAnalysisTask.h"
49 #include "AliAnalysisDataContainer.h"
51 ClassImp(AliAnalysisDataSlot)
53 //______________________________________________________________________________
54 AliAnalysisDataSlot::AliAnalysisDataSlot(TClass *type, AliAnalysisTask *task)
60 // Default constructor.
61 SetTitle(fType->GetName());
64 //______________________________________________________________________________
65 AliAnalysisDataSlot::AliAnalysisDataSlot(const AliAnalysisDataSlot &slot)
68 fParent(slot.fParent),
69 fContainer(slot.fContainer)
75 //______________________________________________________________________________
76 AliAnalysisDataSlot& AliAnalysisDataSlot::operator=(const AliAnalysisDataSlot &slot)
79 if (&slot == this) return *this;
80 TNamed::operator=(slot);
82 fParent = slot.fParent;
83 fContainer = slot.fContainer;
87 //______________________________________________________________________________
88 Bool_t AliAnalysisDataSlot::ConnectContainer(AliAnalysisDataContainer *cont)
90 // Connect the data slot with a given container. The operation will succeed only
91 // if the type defined by the slot inherits from the type enforced by the container.
92 // The error message in case of failure is posted by the caller.
93 if (!cont || !GetType()) return kFALSE;
94 if (!fType->InheritsFrom(cont->GetType())) {
95 cout<<"Data slot of type "<<GetTitle()<<" of task "<<fParent->GetName()<<" cannot be connected to data container "<<cont->GetName()<<" of type "<<cont->GetTitle()<<endl;
96 //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()));
103 //______________________________________________________________________________
104 TClass *AliAnalysisDataSlot::GetType() const
106 // Get class type for this slot.
107 AliAnalysisDataSlot *slot = (AliAnalysisDataSlot*)this;
108 if (!fType) slot->SetType(gROOT->GetClass(fTitle.Data()));
109 if (!fType) printf("AliAnalysisDataSlot: Unknown class: %s\n", GetTitle());
113 //______________________________________________________________________________
114 void *AliAnalysisDataSlot::GetBranchAddress(const char *branchname) const
116 // Retrieve the address for a given branch. One should always test this before
117 // using SetBranchAddress because the address gets set by the first caller.
118 // Call this in MyTask::Init()
119 if (!GetType()) return NULL;
120 if (!fType->InheritsFrom(TTree::Class())) {
121 cout<<"Cannot call GetBranchAddress() for data slot of task "<<fParent->GetName()<<" not pointing to tree-type data"<<endl;
122 //AliFatal(Form("Cannot call GetBranchAddress() for data slot of task %s not pointing to tree-type data", fParent->GetName()));
125 if (!IsDataReady()) {
126 cout<<"Cannot call GetBranchAddress() for data slot of task "<<fParent->GetName()<<" while data is not ready"<<endl;
127 //AliFatal(Form("Cannot call GetBranchAddress() for data slot of task %s while data is not ready", fParent->GetName()));
130 TTree *tree = (TTree*)GetData();
131 TBranch *br = tree->GetBranch(branchname);
133 cout<<"Branch "<<branchname<<" not found in tree "<<tree->GetName()<<" as input of task "<<fParent->GetName()<<"..."<<endl;
134 //AliFatal(Form("Branch %s not found in tree %s as input of task %s...", branchname, tree->GetName(), fParent->GetName()));
137 return br->GetAddress();
140 //______________________________________________________________________________
141 Bool_t AliAnalysisDataSlot::SetBranchAddress(const char *branchname, void *address)
143 // Set a branch address for input tree. To be called during MyTask::Init()
144 // only if GetBranchAddress() returns a NULL pointer for a tree-type slot.
145 if (GetBranchAddress(branchname)) {
146 cout<<"Branch address for "<<branchname<<" already set by other task. Call first GetBranchAddress() in "<<fParent->GetName()<<"::Init()"<<endl;
147 //AliError(Form("Branch address for %s already set by other task. Call first GetBranchAddress() in %s::Init()",branchname, fParent->GetName()));
150 TTree *tree = (TTree*)GetData();
151 tree->SetBranchAddress(branchname, address);
155 //______________________________________________________________________________
156 TObject *AliAnalysisDataSlot::GetData() const
158 // Retreives the data from the container if it is ready.
160 cout<<"Data slot of type "<<GetTitle()<<" of task "<<fParent->GetName()<<" has no connected data container"<<endl;
161 //AliError(Form("Data slot of type %s of task %s has no connected data container",fType->GetName(), fParent->GetName()));
164 if (!fContainer->IsDataReady()) return NULL;
165 return fContainer->GetData();
168 //______________________________________________________________________________
169 Bool_t AliAnalysisDataSlot::IsDataReady() const
171 // Check if data for this slot is ready in its container.
173 cout<<"Data slot of type "<<GetTitle()<<" of task "<<fParent->GetName()<<" has no connected data container"<<endl;
174 //AliError(Form("Data slot of type %s of task %s has no connected data container",fType->GetName(), fParent->GetName()));
177 return fContainer->IsDataReady();