]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/ESD/AliESDInputHandler.cxx
Make friends available after the AliAnalysisManager::Init() phase
[u/mrichter/AliRoot.git] / STEER / ESD / AliESDInputHandler.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-2007, 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
18 //-------------------------------------------------------------------------
19 //     Event handler for ESD input 
20 //     Author: Andreas Morsch, CERN
21 //-------------------------------------------------------------------------
22
23 #include <TTree.h>
24 #include <TChain.h>
25 #include <TFile.h>
26 #include <TArchiveFile.h>
27 #include <TObjArray.h>
28 #include <TSystem.h>
29 #include <TString.h>
30 #include <TObjString.h>
31 #include <TProcessID.h>
32 #include <TMap.h>
33
34 #include "AliESDInputHandler.h"
35 #include "AliESDEvent.h"
36 #include "AliESDfriend.h"
37 #include "AliVCuts.h"
38 #include "AliESD.h"
39 #include "AliRunTag.h"
40 #include "AliEventTag.h"
41 #include "AliLog.h"
42 #include "AliESDpid.h"
43
44 ClassImp(AliESDInputHandler)
45
46 static Option_t *gESDDataType = "ESD";
47
48 //______________________________________________________________________________
49 AliESDInputHandler::AliESDInputHandler() :
50   AliInputEventHandler(),
51   fEvent(0x0),
52   fFriend(0x0),
53   fESDpid(0x0),
54   fAnalysisType(0),
55   fNEvents(0),
56   fHLTEvent(0x0),
57   fHLTTree(0x0),
58   fUseHLT(kFALSE),
59   fTagCutSumm(0x0),
60   fUseTags(kFALSE),
61   fChainT(0),
62   fTreeT(0),
63   fRunTag(0),
64   fEventTag(0),
65   fReadFriends(0),
66   fFriendFileName("AliESDfriends.root")
67 {
68   // default constructor
69 }
70
71 //______________________________________________________________________________
72 AliESDInputHandler::~AliESDInputHandler() 
73 {
74   //  destructor
75   if (fRunTag) delete fRunTag;
76   delete fESDpid;
77 }
78
79 //______________________________________________________________________________
80 AliESDInputHandler::AliESDInputHandler(const char* name, const char* title):
81     AliInputEventHandler(name, title), fEvent(0x0), fFriend(0x0), fESDpid(0x0), fAnalysisType(0),
82     fNEvents(0),  fHLTEvent(0x0), fHLTTree(0x0), fUseHLT(kFALSE), fTagCutSumm(0x0), fUseTags(kFALSE), fChainT(0), fTreeT(0), fRunTag(0), fEventTag(0), fReadFriends(0), fFriendFileName("AliESDfriends.root")
83 {
84     // Constructor
85 }
86
87 //______________________________________________________________________________
88 Bool_t AliESDInputHandler::Init(TTree* tree,  Option_t* opt)
89 {
90     //
91     // Initialisation necessary for each new tree 
92     // 
93     fAnalysisType = opt;
94     fTree = tree;
95     
96     if (!fTree) return kFALSE;
97 //    fTree->GetEntry(0);
98     
99
100     if (!fEvent) fEvent = new AliESDEvent();
101     fEvent->ReadFromTree(fTree);
102     fNEvents = fTree->GetEntries();
103     if (fReadFriends) ConnectFriends();
104
105     if (fMixingHandler) fMixingHandler->Init(tree,  opt);
106     return kTRUE;
107 }
108
109 //______________________________________________________________________________
110 Bool_t AliESDInputHandler::BeginEvent(Long64_t entry)
111 {
112     
113     // Copy from old to new format if necessary
114   static Bool_t called = kFALSE;
115   if (!called && fEventCuts && IsUserCallSelectionMask())
116      AliInfo(Form("The ESD input handler expects that the first task calls AliESDInputHandler::CheckSelectionMask() %s", fEventCuts->ClassName()));
117   AliESD* old = ((AliESDEvent*) fEvent)->GetAliESDOld();
118   if (old) {
119    ((AliESDEvent*)fEvent)->CopyFromOldESD();
120    old->Reset();
121   }
122
123   if (fHLTTree) {
124       fHLTTree->GetEntry(entry);
125   }
126   
127   fNewEvent = kTRUE;
128   //
129   // Event selection
130   // 
131   fIsSelectedResult = 0;
132   if (fEventCuts && !IsUserCallSelectionMask())
133       fIsSelectedResult = fEventCuts->GetSelectionMask((AliESDEvent*)fEvent); 
134   //
135   // Friends
136   ((AliESDEvent*)fEvent)->SetESDfriend(fFriend);
137   called = kTRUE;
138
139   if (fMixingHandler) fMixingHandler->BeginEvent(entry);
140   if (fUseTags && fRunTag) {
141     fEventTag = 0;
142     if (entry >= fRunTag->GetNEvents()) {
143       AliError(Form("Current event %d does not match max range from run tag: 0-%d", (Int_t)entry, fRunTag->GetNEvents()));
144       return kTRUE;
145     }
146     fEventTag = fRunTag->GetEventTag(entry);   
147   }      
148   return kTRUE;
149 }
150
151 //______________________________________________________________________________
152 void AliESDInputHandler::CheckSelectionMask()
153 {
154 // This method can be called by a task only if IsUserCallSelectionMask is true.
155    if (!fEventCuts || !IsUserCallSelectionMask()) return;
156    fIsSelectedResult = fEventCuts->GetSelectionMask((AliESDEvent*)fEvent);
157 }
158
159 //______________________________________________________________________________
160 void AliESDInputHandler::ConnectFriends()
161 {
162 // Connect the friends tree as soon as available.
163   //
164   // Handle the friends first
165   //
166   if (!fTree->FindBranch("ESDfriend.")) {
167     // Try to add ESDfriend. branch as friend
168       TString esdFriendTreeFName;
169       esdFriendTreeFName = (fTree->GetCurrentFile())->GetName();
170     
171
172     if(esdFriendTreeFName.Contains("AliESDs.root")) {
173       esdFriendTreeFName.ReplaceAll("AliESDs.root", fFriendFileName.Data());
174     } else if(esdFriendTreeFName.Contains("AliESDs_wSDD.root")) {
175       esdFriendTreeFName.ReplaceAll("AliESDs_wSDD.root", fFriendFileName.Data());
176     }
177
178     TTree* cTree = fTree->GetTree();
179     if (!cTree) cTree = fTree;      
180     cTree->AddFriend("esdFriendTree", esdFriendTreeFName.Data());
181     cTree->SetBranchStatus("ESDfriend.", 1);
182     fFriend = (AliESDfriend*)(fEvent->FindListObject("AliESDfriend"));
183     if (fFriend) cTree->SetBranchAddress("ESDfriend.", &fFriend);
184   }
185 }
186
187 //______________________________________________________________________________
188 Bool_t  AliESDInputHandler::FinishEvent()
189 {
190     // Finish the event 
191   if(fEvent)fEvent->Reset();
192   if (fMixingHandler) fMixingHandler->FinishEvent();
193   return kTRUE;
194
195
196 //______________________________________________________________________________
197 Bool_t AliESDInputHandler::Notify(const char* path)
198 {
199   // Notify a directory change
200   static Bool_t firsttime = kFALSE;
201   AliInfo(Form("Directory change %s \n", path));
202   //
203   // Handle the friends first
204   //
205   if (fReadFriends) ConnectFriends();
206   //
207   //
208   SwitchOffBranches();
209   SwitchOnBranches();
210   fFriend = (AliESDfriend*)(fEvent->FindListObject("AliESDfriend"));
211   //
212   if (fUseHLT) {
213     // Get HLTesdTree from current file
214     TTree* cTree = fTree;
215     if (fTree->GetTree()) cTree = fTree->GetTree();
216     TFile* cFile = cTree->GetCurrentFile();
217     cFile->GetObject("HLTesdTree", fHLTTree);
218         
219     if (fHLTTree) {
220            if (!fHLTEvent) fHLTEvent = new AliESDEvent();
221            fHLTEvent->ReadFromTree(fHLTTree);
222     }
223   }
224
225   if (!fUseTags) {
226     if (fMixingHandler) fMixingHandler->Notify(path);
227     return kTRUE;
228   }
229     
230   Bool_t zip = kFALSE;
231     
232   // Setup the base path
233   TString pathName(path);
234   Int_t index = pathName.Index("#");
235   if (index>=0) {
236     zip = kTRUE;
237     pathName = pathName(0,index);
238   } else {
239     pathName = gSystem->DirName(pathName);
240   }
241   if (fTree->GetCurrentFile()->GetArchive()) zip = kTRUE;
242   if (pathName.IsNull()) pathName = "./";  
243   printf("AliESDInputHandler::Notify() Path: %s\n", pathName.Data());
244
245   if (fRunTag) {
246     fRunTag->Clear();
247   } else {
248     fRunTag = new AliRunTag();
249   }
250     
251   const char* tagPattern = "ESD.tag.root";
252   TString sname;
253   TString tagFilename;
254   if (zip) {
255     TObjArray* arr = fTree->GetCurrentFile()->GetArchive()->GetMembers();
256     TIter next(arr);
257     TObject *objarchive;
258     while ((objarchive = next())) {
259       sname = objarchive->GetName();
260            if (sname.Contains(tagPattern)) { 
261         tagFilename = pathName;
262         if (index>=0) tagFilename += "#";
263         else tagFilename += "/";
264         tagFilename += sname;
265         AliInfo(Form("Tag file found: %s\n", tagFilename.Data()));
266         break; // There should be only one such file in the archive
267       }//pattern check
268     } // archive file loop
269   } else {
270     void * dirp = gSystem->OpenDirectory(pathName.Data());
271     while(1) {
272       sname = gSystem->GetDirEntry(dirp);
273       if (sname.IsNull()) break;
274       if (sname.Contains(tagPattern)) { 
275         tagFilename = pathName;
276         tagFilename += "/";
277         tagFilename += sname;
278         AliInfo(Form("Tag file found: %s\n", tagFilename.Data()));
279         break;
280       }//pattern check
281     }//directory loop
282     gSystem->FreeDirectory(dirp);
283   }
284   if (tagFilename.IsNull()) {
285     if (firsttime) AliWarning(Form("Tag file not found in directory: %s", pathName.Data()));
286     firsttime = kFALSE;
287     delete fRunTag; fRunTag = 0;
288     return kTRUE;
289   }
290   TFile *tagfile = TFile::Open(tagFilename);
291   if (!tagfile) {
292     AliError(Form("Cannot open tag file: %s", tagFilename.Data()));
293     delete fRunTag; fRunTag = 0;
294     return kTRUE;
295   }   
296   fTreeT = (TTree*)tagfile->Get("T"); // file is the owner
297   if (!fTreeT) {
298     AliError(Form("Cannot get tree of tags from file: %s", tagFilename.Data()));
299     delete fRunTag; fRunTag = 0;
300     return kTRUE;
301   }
302     
303   fTreeT->SetBranchAddress("AliTAG",&fRunTag);
304   fTreeT->GetEntry(0);
305   delete tagfile;
306   // Notify the mixing handler after the tags are loaded
307   if (fMixingHandler) fMixingHandler->Notify(path);
308   return kTRUE;
309 }
310
311 //______________________________________________________________________________
312 Option_t *AliESDInputHandler::GetDataType() const
313 {
314 // Returns handled data type.
315    return gESDDataType;
316 }
317
318 //______________________________________________________________________________
319 Int_t AliESDInputHandler::GetNEventAcceptedInFile()
320 {
321   // Get number of events in file accepted by the tag cuts
322   // return -1 if no info is available
323   if (!fTagCutSumm) {
324     TList *luo = fTree->GetUserInfo();
325     if (!luo) {
326       AliInfo(Form("No user info in input tree - no tag cut summary\n"));
327       return -1;
328     }
329     for (int iluo=0; iluo<luo->GetEntries(); iluo++) {
330       fTagCutSumm = dynamic_cast<TMap *>(luo->At(iluo));
331       if (fTagCutSumm) break;
332     }
333     if (!fTagCutSumm) {
334       AliInfo(Form("No tag summary map in input tree\n"));
335       return -1;
336     }
337   }
338
339   TObjString *ostr = 0;
340   if (fTagCutSumm->FindObject(fTree->GetCurrentFile()->GetName()))
341     ostr = (TObjString *) fTagCutSumm->GetValue(fTree->GetCurrentFile()->GetName());
342   else {
343     AliInfo(Form("No tag cut summary for file %s\n", fTree->GetCurrentFile()->GetName()));
344     return -1;
345   }
346   char *iTagInfo;
347   iTagInfo = strdup(ostr->GetString().Data());
348
349   Int_t iAcc = atoi(strtok(iTagInfo, ","));
350   
351   AliInfo(Form("Got %i accepted events for file %s", iAcc,  fTree->GetCurrentFile()->GetName()));
352   
353   free(iTagInfo);
354
355   return iAcc;
356 }
357
358 //______________________________________________________________________________
359 Int_t AliESDInputHandler::GetNEventRejectedInFile()
360 {
361   // Get number of events in file rejected by the tag cuts
362   // return -1 if no info is available
363   if (!fTagCutSumm) {
364     TList *luo = fTree->GetUserInfo();
365     if (!luo) {
366       AliInfo(Form("No user info in input tree - no tag cut summary\n"));
367       return -1;
368     }
369     for (int iluo=0; iluo<luo->GetEntries(); iluo++) {
370       fTagCutSumm = dynamic_cast<TMap *>(luo->At(iluo));
371       if (fTagCutSumm) break;
372     }
373     if (!fTagCutSumm) {
374       AliInfo(Form("No tag summary map in input tree\n"));
375       return -1;
376     }
377   }
378
379   TObjString *ostr = 0;
380   if (fTagCutSumm->FindObject(fTree->GetCurrentFile()->GetName()))
381     ostr = (TObjString *) fTagCutSumm->GetValue(fTree->GetCurrentFile()->GetName());
382   else {
383     AliInfo(Form("No tag cut summary for file %s\n", fTree->GetCurrentFile()->GetName()));
384     return -1;
385   }
386   char *iTagInfo;
387   iTagInfo = strdup(ostr->GetString().Data());
388
389   strtok(iTagInfo, ",");
390   Int_t iRej = atoi(strtok(NULL, ","));
391   
392   AliInfo(Form("Got %i accepted events for file %s", iRej,  fTree->GetCurrentFile()->GetName()));
393   
394   free(iTagInfo);
395
396   return iRej;
397 }
398
399 //______________________________________________________________________________
400 Bool_t AliESDInputHandler::GetCutSummaryForChain(Int_t *aTotal,  Int_t *aAccepted,  Int_t *aRejected)
401 {
402   // Get number of events in the full chain
403   // Count accepted and rejected events
404   // return kFALSE if no info is available
405   if (!fTagCutSumm) {
406     TList *luo = fTree->GetUserInfo();
407     if (!luo) {
408       AliInfo(Form("No user info in input tree - no tag cut summary\n"));
409       return kFALSE;
410     }
411     for (int iluo=0; iluo<luo->GetEntries(); iluo++) {
412       fTagCutSumm = dynamic_cast<TMap *>(luo->At(iluo));
413       if (fTagCutSumm) break;
414     }
415     if (!fTagCutSumm) {
416       AliInfo(Form("No tag summary map in input tree\n"));
417       return kFALSE;
418     }
419   }
420   
421   TMapIter *tIter = new TMapIter(fTagCutSumm);
422   
423   Int_t iTotList=0, iAccList=0, iRejList=0;
424
425   TObject *cobj;
426   while ((cobj = tIter->Next())) {
427     TObjString *kstr = (TObjString *) cobj;
428     TObjString *vstr = (TObjString *) fTagCutSumm->GetValue(kstr->GetString().Data());
429     //    printf("Got object value %s %s\n", kstr->GetString().Data(), vstr->GetString().Data());
430     char *iTagInfo;
431     iTagInfo = strdup(vstr->GetString().Data());
432     
433     Int_t iAcc = atoi(strtok(iTagInfo, ","));
434     Int_t iRej = atoi(strtok(NULL, ","));
435     free(iTagInfo);
436     
437     iAccList += iAcc;
438     iRejList += iRej;
439     iTotList += (iAcc+iRej);
440   }
441
442   *aTotal = iTotList;
443   *aAccepted = iAccList;
444   *aRejected = iRejList;
445
446   return kTRUE;
447 }
448
449 //______________________________________________________________________________
450 Int_t AliESDInputHandler::GetNFilesEmpty()
451 {
452   // Count number of files in which all events were de-selected
453   // For such files Notify() will NOT be called
454   // return -1 if no info is available
455   if (!fTagCutSumm) {
456     TList *luo = fTree->GetUserInfo();
457     if (!luo) {
458       AliInfo(Form("No user info in input tree - no tag cut summary\n"));
459       return -1;
460     }
461     for (int iluo=0; iluo<luo->GetEntries(); iluo++) {
462       fTagCutSumm = dynamic_cast<TMap *>(luo->At(iluo));
463       if (fTagCutSumm) break;
464     }
465     if (!fTagCutSumm) {
466       AliInfo(Form("No tag summary map in input tree\n"));
467       return -1;
468     }
469   }
470   
471   TMapIter *tIter = new TMapIter(fTagCutSumm);
472   
473   Int_t iFilesEmpty = 0;
474
475   TObject *cobj;
476   while ((cobj = tIter->Next())) {
477     TObjString *kstr = (TObjString *) cobj;
478     TObjString *vstr = (TObjString *) fTagCutSumm->GetValue(kstr->GetString().Data());
479     //    printf("Got object value %s %s\n", kstr->GetString().Data(), vstr->GetString().Data());
480     char *iTagInfo;
481     iTagInfo = strdup(vstr->GetString().Data());
482     
483     Int_t iAcc = atoi(strtok(iTagInfo, ","));
484     Int_t iRej = atoi(strtok(NULL, ","));
485     free(iTagInfo);
486     if ((iAcc == 0) && ((iRej+iAcc)>0))
487       iFilesEmpty++;
488   }
489
490   return iFilesEmpty;
491   
492 }
493
494 //______________________________________________________________________________
495 TObject *AliESDInputHandler::GetStatistics(Option_t *option) const
496 {
497 // Get the statistics histogram(s) from the physics selection object. This
498 // should be called during FinishTaskOutput(). Option can be empty (default
499 // statistics histogram) or BIN0.
500    if (!fEventCuts) return NULL;
501    TString opt(option);
502    opt.ToUpper();
503    if (opt=="BIN0") return fEventCuts->GetStatistics("BIN0");
504    else return fEventCuts->GetStatistics("ALL");
505 }   
506
507 //______________________________________________________________________________
508 void AliESDInputHandler::CreatePIDResponse(Bool_t isMC/*=kFALSE*/)
509 {
510   //
511   // create the pid response object if it does not exist yet
512   //
513   if (fESDpid) return;
514   fESDpid=new AliESDpid(isMC);
515
516 }
517