Possibility to create an independent par file containing the new analysis framework...
[u/mrichter/AliRoot.git] / ANALYSIS / AliAnalysisDataSlot.cxx
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
42 #include "Riostream.h"
43
44 #include "TClass.h"
45 #include "TTree.h"
46 //#include "AliLog.h"
47
48 #include "AliAnalysisDataSlot.h"
49 #include "AliAnalysisTask.h"
50 #include "AliAnalysisDataContainer.h"
51
52 ClassImp(AliAnalysisDataSlot)
53
54 //______________________________________________________________________________
55 AliAnalysisDataSlot& AliAnalysisDataSlot::operator=(const AliAnalysisDataSlot &slot)
56 {
57 // Assignment
58    if (&slot == this) return *this;
59    TObject::operator=(slot);
60    fType = slot.fType;
61    fParent = slot.fParent;
62    fContainer = slot.fContainer;   
63    return *this;
64 }
65
66 //______________________________________________________________________________
67 Bool_t AliAnalysisDataSlot::ConnectContainer(AliAnalysisDataContainer *cont)
68 {
69 // Connect the data slot with a given container. The operation will succeed only
70 // if the type defined by the slot inherits from the type enforced by the container.
71 // The error message in case of failure is posted by the caller.
72    if (!cont || !fType) return kFALSE;
73    if (!fType->InheritsFrom(cont->GetType())) {
74      cout<<"Data slot of type "<<fType->GetName()<<" of task "<<fParent->GetName()<<" cannot be connected to data container "<<cont->GetName()<<" of type "<<cont->GetType()->GetName()<<endl;
75      //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()));
76       return kFALSE;
77    }   
78    fContainer = cont;
79    return kTRUE;
80 }   
81
82 //______________________________________________________________________________
83 void *AliAnalysisDataSlot::GetBranchAddress(const char *branchname) const
84 {
85 // Retrieve the address for a given branch. One should always test this before
86 // using SetBranchAddress because the address gets set by the first caller.
87 // Call this in MyTask::Init()
88    if (!fType->InheritsFrom(TTree::Class())) {
89      cout<<"Cannot call GetBranchAddress() for data slot of task "<<fParent->GetName()<<" not pointing to tree-type data"<<endl;
90      //AliFatal(Form("Cannot call GetBranchAddress() for data slot of task %s not pointing to tree-type data", fParent->GetName()));
91       return NULL;
92    }
93    if (!IsDataReady()) {
94      cout<<"Cannot call GetBranchAddress() for data slot of task "<<fParent->GetName()<<" while data is not ready"<<endl;
95      //AliFatal(Form("Cannot call GetBranchAddress() for data slot of task %s while data is not ready", fParent->GetName()));
96       return NULL;
97    }
98    TTree *tree = (TTree*)GetData();
99    TBranch *br = tree->GetBranch(branchname);
100    if (!br) {   
101      cout<<"Branch "<<branchname<<" not found in tree "<<tree->GetName()<<" as input of task "<<fParent->GetName()<<"..."<<endl;
102      //AliFatal(Form("Branch %s not found in tree %s as input of task %s...", branchname, tree->GetName(), fParent->GetName()));
103       return NULL;
104    }
105    return br->GetAddress();
106 }   
107
108 //______________________________________________________________________________
109 Bool_t AliAnalysisDataSlot::SetBranchAddress(const char *branchname, void *address)
110 {
111 // Set a branch address for input tree. To be called during MyTask::Init()
112 // only if GetBranchAddress() returns a NULL pointer for a tree-type slot.
113    if (GetBranchAddress(branchname)) {
114      cout<<"Branch address for "<<branchname<<" already set by other task. Call first GetBranchAddress() in "<<fParent->GetName()<<"::Init()"<<endl;
115      //AliError(Form("Branch address for %s already set by other task. Call first GetBranchAddress() in %s::Init()",branchname, fParent->GetName()));
116       return kFALSE;
117    }
118    TTree *tree = (TTree*)GetData();
119    tree->SetBranchAddress(branchname, address);
120    return kTRUE;
121 }   
122       
123 //______________________________________________________________________________
124 TObject *AliAnalysisDataSlot::GetData() const
125 {
126 // Retreives the data from the container if it is ready.
127    if (!fContainer) {
128      cout<<"Data slot of type "<<fType->GetName()<<" of task "<<fParent->GetName()<<" has no connected data container"<<endl;
129      //AliError(Form("Data slot of type %s of task %s has no connected data container",fType->GetName(), fParent->GetName()));    
130       return NULL;
131    }
132    if (!fContainer->IsDataReady()) return NULL;
133    return fContainer->GetData();
134 }
135
136 //______________________________________________________________________________
137 Bool_t  AliAnalysisDataSlot::IsDataReady() const
138 {
139 // Check if data for this slot is ready in its container.
140    if (!fContainer) {
141      cout<<"Data slot of type "<<fType->GetName()<<" of task "<<fParent->GetName()<<" has no connected data container"<<endl;
142      //AliError(Form("Data slot of type %s of task %s has no connected data container",fType->GetName(), fParent->GetName()));    
143       return kFALSE;
144    }
145    return fContainer->IsDataReady();
146 }
147