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$ */
// Author: Andrei Gheata, 31/05/2006

//==============================================================================
//   AliAnalysysDataSlot - Class representing a data slot of an analysis task.
//      An analysis slot enforces a certain data type required by the Exec()
//      method of the analysis task. The slot must be connected to a data 
//      container with data of the same type.
//
// The class should not be directly created by users - it is created by
// each AliAnalysisTask when defining its input/output slots using:
//
//    AliAnalysisTask::SetInput(Int_t index, TClass *type);
//    AliAnalysisTask::SetOutput(TClass *type);
//
// An existing data contaner (AliAnalysisDataContainer) can be connected to the
// input/output slots of an analysis task using:
//
//   AliAnalysisModule::ConnectInput(AliAnalysisTask *task, Int_t islot,
//                                   AliAnalysisDataContainer *cont)
//   AliAnalysisModule::ConnectOutput(AliAnalysisTask *task,
//                                    AliAnalysisDataContainer *cont)
// To connect a slot to a data container, the data types declared by both must
// match.
//==============================================================================

#include <Riostream.h>
#include <TROOT.h>
#include <TClass.h>
#include <TTree.h>
#include <TLeaf.h>

#include "AliAnalysisDataSlot.h"
#include "AliAnalysisTask.h"
#include "AliAnalysisDataContainer.h"

using std::endl;
using std::cout;
ClassImp(AliAnalysisDataSlot)

//______________________________________________________________________________
AliAnalysisDataSlot::AliAnalysisDataSlot(TClass *type, AliAnalysisTask *task)
                    :TNamed(), 
                     fType(type),
                     fParent(task), 
                     fContainer(NULL)
{
// Default constructor.
   SetTitle(fType->GetName());
}

//______________________________________________________________________________
AliAnalysisDataSlot::AliAnalysisDataSlot(const AliAnalysisDataSlot &slot)
                    :TNamed(slot), 
                     fType(NULL), 
                     fParent(slot.fParent), 
                     fContainer(slot.fContainer)
{
// Copy ctor.
   GetType();
}                        

//______________________________________________________________________________
AliAnalysisDataSlot& AliAnalysisDataSlot::operator=(const AliAnalysisDataSlot &slot)
{
// Assignment
   if (&slot == this) return *this;
   TNamed::operator=(slot);
   GetType();
   fParent = slot.fParent;
   fContainer = slot.fContainer;   
   return *this;
}

//______________________________________________________________________________
Bool_t AliAnalysisDataSlot::ConnectContainer(AliAnalysisDataContainer *cont)
{
// Connect the data slot with a given container. The operation will succeed only
// if the type defined by the slot inherits from the type enforced by the container.
// The error message in case of failure is posted by the caller.
   if (!cont || !GetType()) return kFALSE;
   if (!fType->InheritsFrom(cont->GetType())) {
     cout<<"Data slot of type "<<GetTitle()<<" of task "<<fParent->GetName()<<" cannot be connected to data container "<<cont->GetName()<<" of type "<<cont->GetTitle()<<endl;
     //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()));
      return kFALSE;
   }   
   fContainer = cont;
   return kTRUE;
}   

//______________________________________________________________________________
TClass *AliAnalysisDataSlot::GetType() const
{
// Get class type for this slot.
   AliAnalysisDataSlot *slot = (AliAnalysisDataSlot*)this;
   if (!fType) slot->SetType(gROOT->GetClass(fTitle.Data()));
   if (!fType) printf("AliAnalysisDataSlot: Unknown class: %s\n", GetTitle());
   return fType;
}
   
//______________________________________________________________________________
void *AliAnalysisDataSlot::GetBranchAddress(const char *branchname) const
{
// Retrieve the address for a given branch. One should always test this before
// using SetBranchAddress because the address gets set by the first caller.
// Call this in MyTask::Init()
   if (!GetType()) return NULL;
   if (!fType->InheritsFrom(TTree::Class())) {
     cout<<"Cannot call GetBranchAddress() for data slot of task "<<fParent->GetName()<<" not pointing to tree-type data"<<endl;
     //AliFatal(Form("Cannot call GetBranchAddress() for data slot of task %s not pointing to tree-type data", fParent->GetName()));
      return NULL;
   }
   if (!IsDataReady()) {
     cout<<"Cannot call GetBranchAddress() for data slot of task "<<fParent->GetName()<<" while data is not ready"<<endl;
     //AliFatal(Form("Cannot call GetBranchAddress() for data slot of task %s while data is not ready", fParent->GetName()));
      return NULL;
   }
   TTree *tree = (TTree*)GetData();
   TBranch *br = tree->GetBranch(branchname);
   if (!br) {   
     cout<<"Branch "<<branchname<<" not found in tree "<<tree->GetName()<<" as input of task "<<fParent->GetName()<<"..."<<endl;
     //AliFatal(Form("Branch %s not found in tree %s as input of task %s...", branchname, tree->GetName(), fParent->GetName()));
      return NULL;
   }
   return br->GetAddress();
}   

//______________________________________________________________________________
Int_t AliAnalysisDataSlot::EnableBranch(const char *bname, TTree *tree)
{
// Static method to enable recursively a branch in a tree (why this in not in ROOT?)
   TBranch *branch = tree->GetBranch(bname);
   Int_t count = 0;
//   static Int_t indent = 0;
   if (!branch) return count;
//   TString s;
//   for (Int_t i=0; i<indent; i++) s += " ";
   count++;
//   printf("%sbranch %s: kDoNotProcess=%d\n",s.Data(), branch->GetName(), branch->TestBit(kDoNotProcess));
   branch->SetBit(kDoNotProcess, kFALSE);
   TIter next(branch->GetListOfBranches());
   TBranch *branch_sub;
   // Activate all sub-branches
//   indent++;
   while ((branch_sub=(TBranch*)next())) {
      count += AliAnalysisDataSlot::EnableBranch(branch_sub->GetName(), tree);
   }
//   indent--;
   return count;   
}   

//______________________________________________________________________________
Bool_t AliAnalysisDataSlot::SetBranchAddress(const char *branchname, void *address)
{
// Set a branch address for input tree. To be called during MyTask::Init()
// only if GetBranchAddress() returns a NULL pointer for a tree-type slot.
   if (GetBranchAddress(branchname)) {
      Error("SetBranchAddress","Branch address for %s already set by other task. Call first GetBranchAddress() in %s::ConnectInputData()",branchname, fParent->GetName());
      return kFALSE;
   }
   TTree *tree = (TTree*)GetData();
   tree->SetBranchAddress(branchname, address);
   return kTRUE;
}   
      
//______________________________________________________________________________
TObject *AliAnalysisDataSlot::GetData() const
{
// Retreives the data from the container if it is ready.
   if (!fContainer) {
     //AliError(Form("Data slot of type %s of task %s has no connected data container",fType->GetName(), fParent->GetName()));    
      return NULL;
   }
   if (!fContainer->IsDataReady()) return NULL;
   return fContainer->GetData();
}

//______________________________________________________________________________
Bool_t  AliAnalysisDataSlot::IsDataReady() const
{
// Check if data for this slot is ready in its container.
   if (!fContainer) {
     cout<<"Data slot of type "<<GetTitle()<<" of task "<<fParent->GetName()<<" has no connected data container"<<endl;
     //AliError(Form("Data slot of type %s of task %s has no connected data container",fType->GetName(), fParent->GetName()));    
      return kFALSE;
   }
   return fContainer->IsDataReady();
}
   
 AliAnalysisDataSlot.cxx:1
 AliAnalysisDataSlot.cxx:2
 AliAnalysisDataSlot.cxx:3
 AliAnalysisDataSlot.cxx:4
 AliAnalysisDataSlot.cxx:5
 AliAnalysisDataSlot.cxx:6
 AliAnalysisDataSlot.cxx:7
 AliAnalysisDataSlot.cxx:8
 AliAnalysisDataSlot.cxx:9
 AliAnalysisDataSlot.cxx:10
 AliAnalysisDataSlot.cxx:11
 AliAnalysisDataSlot.cxx:12
 AliAnalysisDataSlot.cxx:13
 AliAnalysisDataSlot.cxx:14
 AliAnalysisDataSlot.cxx:15
 AliAnalysisDataSlot.cxx:16
 AliAnalysisDataSlot.cxx:17
 AliAnalysisDataSlot.cxx:18
 AliAnalysisDataSlot.cxx:19
 AliAnalysisDataSlot.cxx:20
 AliAnalysisDataSlot.cxx:21
 AliAnalysisDataSlot.cxx:22
 AliAnalysisDataSlot.cxx:23
 AliAnalysisDataSlot.cxx:24
 AliAnalysisDataSlot.cxx:25
 AliAnalysisDataSlot.cxx:26
 AliAnalysisDataSlot.cxx:27
 AliAnalysisDataSlot.cxx:28
 AliAnalysisDataSlot.cxx:29
 AliAnalysisDataSlot.cxx:30
 AliAnalysisDataSlot.cxx:31
 AliAnalysisDataSlot.cxx:32
 AliAnalysisDataSlot.cxx:33
 AliAnalysisDataSlot.cxx:34
 AliAnalysisDataSlot.cxx:35
 AliAnalysisDataSlot.cxx:36
 AliAnalysisDataSlot.cxx:37
 AliAnalysisDataSlot.cxx:38
 AliAnalysisDataSlot.cxx:39
 AliAnalysisDataSlot.cxx:40
 AliAnalysisDataSlot.cxx:41
 AliAnalysisDataSlot.cxx:42
 AliAnalysisDataSlot.cxx:43
 AliAnalysisDataSlot.cxx:44
 AliAnalysisDataSlot.cxx:45
 AliAnalysisDataSlot.cxx:46
 AliAnalysisDataSlot.cxx:47
 AliAnalysisDataSlot.cxx:48
 AliAnalysisDataSlot.cxx:49
 AliAnalysisDataSlot.cxx:50
 AliAnalysisDataSlot.cxx:51
 AliAnalysisDataSlot.cxx:52
 AliAnalysisDataSlot.cxx:53
 AliAnalysisDataSlot.cxx:54
 AliAnalysisDataSlot.cxx:55
 AliAnalysisDataSlot.cxx:56
 AliAnalysisDataSlot.cxx:57
 AliAnalysisDataSlot.cxx:58
 AliAnalysisDataSlot.cxx:59
 AliAnalysisDataSlot.cxx:60
 AliAnalysisDataSlot.cxx:61
 AliAnalysisDataSlot.cxx:62
 AliAnalysisDataSlot.cxx:63
 AliAnalysisDataSlot.cxx:64
 AliAnalysisDataSlot.cxx:65
 AliAnalysisDataSlot.cxx:66
 AliAnalysisDataSlot.cxx:67
 AliAnalysisDataSlot.cxx:68
 AliAnalysisDataSlot.cxx:69
 AliAnalysisDataSlot.cxx:70
 AliAnalysisDataSlot.cxx:71
 AliAnalysisDataSlot.cxx:72
 AliAnalysisDataSlot.cxx:73
 AliAnalysisDataSlot.cxx:74
 AliAnalysisDataSlot.cxx:75
 AliAnalysisDataSlot.cxx:76
 AliAnalysisDataSlot.cxx:77
 AliAnalysisDataSlot.cxx:78
 AliAnalysisDataSlot.cxx:79
 AliAnalysisDataSlot.cxx:80
 AliAnalysisDataSlot.cxx:81
 AliAnalysisDataSlot.cxx:82
 AliAnalysisDataSlot.cxx:83
 AliAnalysisDataSlot.cxx:84
 AliAnalysisDataSlot.cxx:85
 AliAnalysisDataSlot.cxx:86
 AliAnalysisDataSlot.cxx:87
 AliAnalysisDataSlot.cxx:88
 AliAnalysisDataSlot.cxx:89
 AliAnalysisDataSlot.cxx:90
 AliAnalysisDataSlot.cxx:91
 AliAnalysisDataSlot.cxx:92
 AliAnalysisDataSlot.cxx:93
 AliAnalysisDataSlot.cxx:94
 AliAnalysisDataSlot.cxx:95
 AliAnalysisDataSlot.cxx:96
 AliAnalysisDataSlot.cxx:97
 AliAnalysisDataSlot.cxx:98
 AliAnalysisDataSlot.cxx:99
 AliAnalysisDataSlot.cxx:100
 AliAnalysisDataSlot.cxx:101
 AliAnalysisDataSlot.cxx:102
 AliAnalysisDataSlot.cxx:103
 AliAnalysisDataSlot.cxx:104
 AliAnalysisDataSlot.cxx:105
 AliAnalysisDataSlot.cxx:106
 AliAnalysisDataSlot.cxx:107
 AliAnalysisDataSlot.cxx:108
 AliAnalysisDataSlot.cxx:109
 AliAnalysisDataSlot.cxx:110
 AliAnalysisDataSlot.cxx:111
 AliAnalysisDataSlot.cxx:112
 AliAnalysisDataSlot.cxx:113
 AliAnalysisDataSlot.cxx:114
 AliAnalysisDataSlot.cxx:115
 AliAnalysisDataSlot.cxx:116
 AliAnalysisDataSlot.cxx:117
 AliAnalysisDataSlot.cxx:118
 AliAnalysisDataSlot.cxx:119
 AliAnalysisDataSlot.cxx:120
 AliAnalysisDataSlot.cxx:121
 AliAnalysisDataSlot.cxx:122
 AliAnalysisDataSlot.cxx:123
 AliAnalysisDataSlot.cxx:124
 AliAnalysisDataSlot.cxx:125
 AliAnalysisDataSlot.cxx:126
 AliAnalysisDataSlot.cxx:127
 AliAnalysisDataSlot.cxx:128
 AliAnalysisDataSlot.cxx:129
 AliAnalysisDataSlot.cxx:130
 AliAnalysisDataSlot.cxx:131
 AliAnalysisDataSlot.cxx:132
 AliAnalysisDataSlot.cxx:133
 AliAnalysisDataSlot.cxx:134
 AliAnalysisDataSlot.cxx:135
 AliAnalysisDataSlot.cxx:136
 AliAnalysisDataSlot.cxx:137
 AliAnalysisDataSlot.cxx:138
 AliAnalysisDataSlot.cxx:139
 AliAnalysisDataSlot.cxx:140
 AliAnalysisDataSlot.cxx:141
 AliAnalysisDataSlot.cxx:142
 AliAnalysisDataSlot.cxx:143
 AliAnalysisDataSlot.cxx:144
 AliAnalysisDataSlot.cxx:145
 AliAnalysisDataSlot.cxx:146
 AliAnalysisDataSlot.cxx:147
 AliAnalysisDataSlot.cxx:148
 AliAnalysisDataSlot.cxx:149
 AliAnalysisDataSlot.cxx:150
 AliAnalysisDataSlot.cxx:151
 AliAnalysisDataSlot.cxx:152
 AliAnalysisDataSlot.cxx:153
 AliAnalysisDataSlot.cxx:154
 AliAnalysisDataSlot.cxx:155
 AliAnalysisDataSlot.cxx:156
 AliAnalysisDataSlot.cxx:157
 AliAnalysisDataSlot.cxx:158
 AliAnalysisDataSlot.cxx:159
 AliAnalysisDataSlot.cxx:160
 AliAnalysisDataSlot.cxx:161
 AliAnalysisDataSlot.cxx:162
 AliAnalysisDataSlot.cxx:163
 AliAnalysisDataSlot.cxx:164
 AliAnalysisDataSlot.cxx:165
 AliAnalysisDataSlot.cxx:166
 AliAnalysisDataSlot.cxx:167
 AliAnalysisDataSlot.cxx:168
 AliAnalysisDataSlot.cxx:169
 AliAnalysisDataSlot.cxx:170
 AliAnalysisDataSlot.cxx:171
 AliAnalysisDataSlot.cxx:172
 AliAnalysisDataSlot.cxx:173
 AliAnalysisDataSlot.cxx:174
 AliAnalysisDataSlot.cxx:175
 AliAnalysisDataSlot.cxx:176
 AliAnalysisDataSlot.cxx:177
 AliAnalysisDataSlot.cxx:178
 AliAnalysisDataSlot.cxx:179
 AliAnalysisDataSlot.cxx:180
 AliAnalysisDataSlot.cxx:181
 AliAnalysisDataSlot.cxx:182
 AliAnalysisDataSlot.cxx:183
 AliAnalysisDataSlot.cxx:184
 AliAnalysisDataSlot.cxx:185
 AliAnalysisDataSlot.cxx:186
 AliAnalysisDataSlot.cxx:187
 AliAnalysisDataSlot.cxx:188
 AliAnalysisDataSlot.cxx:189
 AliAnalysisDataSlot.cxx:190
 AliAnalysisDataSlot.cxx:191
 AliAnalysisDataSlot.cxx:192
 AliAnalysisDataSlot.cxx:193
 AliAnalysisDataSlot.cxx:194
 AliAnalysisDataSlot.cxx:195
 AliAnalysisDataSlot.cxx:196
 AliAnalysisDataSlot.cxx:197
 AliAnalysisDataSlot.cxx:198
 AliAnalysisDataSlot.cxx:199
 AliAnalysisDataSlot.cxx:200
 AliAnalysisDataSlot.cxx:201
 AliAnalysisDataSlot.cxx:202
 AliAnalysisDataSlot.cxx:203
 AliAnalysisDataSlot.cxx:204