]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/ESD/AliESDInputHandler.cxx
28ee6eb5eccddca6cd167fe0e7d70d15ebe3c272
[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   static Int_t prevRunNumber = -1;
130   if (prevRunNumber != fEvent->GetRunNumber() && NeedField()) {
131     fEvent->InitMagneticField();
132     prevRunNumber = fEvent->GetRunNumber();
133   } 
134   //
135   // Event selection
136   // 
137   fIsSelectedResult = 0;
138   if (fEventCuts && !IsUserCallSelectionMask())
139       fIsSelectedResult = fEventCuts->GetSelectionMask((AliESDEvent*)fEvent); 
140   //
141   // Friends
142   ((AliESDEvent*)fEvent)->SetESDfriend(fFriend);
143   called = kTRUE;
144
145   // set transient pointer to event inside tracks
146   fEvent->ConnectTracks();
147
148   if (fMixingHandler) fMixingHandler->BeginEvent(entry);
149   if (fUseTags && fRunTag) {
150     fEventTag = 0;
151     if (entry >= fRunTag->GetNEvents()) {
152       AliError(Form("Current event %d does not match max range from run tag: 0-%d", (Int_t)entry, fRunTag->GetNEvents()));
153       return kTRUE;
154     }
155     fEventTag = fRunTag->GetEventTag(entry);   
156   }      
157   return kTRUE;
158 }
159
160 //______________________________________________________________________________
161 void AliESDInputHandler::CheckSelectionMask()
162 {
163 // This method can be called by a task only if IsUserCallSelectionMask is true.
164    if (!fEventCuts || !IsUserCallSelectionMask()) return;
165    fIsSelectedResult = fEventCuts->GetSelectionMask((AliESDEvent*)fEvent);
166 }
167
168 //______________________________________________________________________________
169 void AliESDInputHandler::ConnectFriends()
170 {
171 // Connect the friends tree as soon as available.
172   //
173   // Handle the friends first
174   //
175   if (!fTree->FindBranch("ESDfriend.")) {
176     // Try to add ESDfriend. branch as friend
177       TString esdFriendTreeFName;
178       esdFriendTreeFName = (fTree->GetCurrentFile())->GetName();    
179       TString basename = gSystem->BaseName(esdFriendTreeFName);
180       Int_t index = basename.Index("#")+1;
181       basename.Remove(index);
182       basename += fFriendFileName;
183       TString dirname = gSystem->DirName(esdFriendTreeFName);
184       dirname += "/";
185       esdFriendTreeFName = dirname + basename;
186
187     TTree* cTree = fTree->GetTree();
188     if (!cTree) cTree = fTree;      
189     cTree->AddFriend("esdFriendTree", esdFriendTreeFName.Data());
190     cTree->SetBranchStatus("ESDfriend.", 1);
191     fFriend = (AliESDfriend*)(fEvent->FindListObject("AliESDfriend"));
192     if (fFriend) cTree->SetBranchAddress("ESDfriend.", &fFriend);
193   }
194 }
195
196 //______________________________________________________________________________
197 Bool_t  AliESDInputHandler::FinishEvent()
198 {
199     // Finish the event 
200   if(fEvent)fEvent->Reset();
201   if (fMixingHandler) fMixingHandler->FinishEvent();
202   return kTRUE;
203
204
205 //______________________________________________________________________________
206 Bool_t AliESDInputHandler::Notify(const char* path)
207 {
208   // Notify a directory change
209   static Bool_t firsttime = kFALSE;
210   AliInfo(Form("Directory change %s \n", path));
211   //
212   // Handle the friends first
213   //
214   if (fReadFriends) ConnectFriends();
215   //
216   //
217   SwitchOffBranches();
218   SwitchOnBranches();
219   fFriend = (AliESDfriend*)(fEvent->FindListObject("AliESDfriend"));
220   fUserInfo=fTree->GetTree()->GetUserInfo();
221
222   //
223   if (fUseHLT) {
224     // Get HLTesdTree from current file
225     TTree* cTree = fTree;
226     if (fTree->GetTree()) cTree = fTree->GetTree();
227     TFile* cFile = cTree->GetCurrentFile();
228     cFile->GetObject("HLTesdTree", fHLTTree);
229         
230     if (fHLTTree) {
231            if (!fHLTEvent) fHLTEvent = new AliESDEvent();
232            fHLTEvent->ReadFromTree(fHLTTree);
233     }
234   }
235
236   if (!fUseTags) {
237     if (fMixingHandler) fMixingHandler->Notify(path);
238     return kTRUE;
239   }
240     
241   Bool_t zip = kFALSE;
242     
243   // Setup the base path
244   TString pathName(path);
245   Int_t index = pathName.Index("#");
246   if (index>=0) {
247     zip = kTRUE;
248     pathName = pathName(0,index);
249   } else {
250     pathName = gSystem->DirName(pathName);
251   }
252   if (fTree->GetCurrentFile()->GetArchive()) zip = kTRUE;
253   if (pathName.IsNull()) pathName = "./";  
254   printf("AliESDInputHandler::Notify() Path: %s\n", pathName.Data());
255
256   if (fRunTag) {
257     fRunTag->Clear();
258   } else {
259     fRunTag = new AliRunTag();
260   }
261     
262   const char* tagPattern = "ESD.tag.root";
263   TString sname;
264   TString tagFilename;
265   if (zip) {
266     TObjArray* arr = fTree->GetCurrentFile()->GetArchive()->GetMembers();
267     TIter next(arr);
268     TObject *objarchive;
269     while ((objarchive = next())) {
270       sname = objarchive->GetName();
271            if (sname.Contains(tagPattern)) { 
272         tagFilename = pathName;
273         if (index>=0) tagFilename += "#";
274         else tagFilename += "/";
275         tagFilename += sname;
276         AliInfo(Form("Tag file found: %s\n", tagFilename.Data()));
277         break; // There should be only one such file in the archive
278       }//pattern check
279     } // archive file loop
280   } else {
281     void * dirp = gSystem->OpenDirectory(pathName.Data());
282     while(1) {
283       sname = gSystem->GetDirEntry(dirp);
284       if (sname.IsNull()) break;
285       if (sname.Contains(tagPattern)) { 
286         tagFilename = pathName;
287         tagFilename += "/";
288         tagFilename += sname;
289         AliInfo(Form("Tag file found: %s\n", tagFilename.Data()));
290         break;
291       }//pattern check
292     }//directory loop
293     gSystem->FreeDirectory(dirp);
294   }
295   if (tagFilename.IsNull()) {
296     if (firsttime) AliWarning(Form("Tag file not found in directory: %s", pathName.Data()));
297     firsttime = kFALSE;
298     delete fRunTag; fRunTag = 0;
299     return kTRUE;
300   }
301   TFile *tagfile = TFile::Open(tagFilename);
302   if (!tagfile) {
303     AliError(Form("Cannot open tag file: %s", tagFilename.Data()));
304     delete fRunTag; fRunTag = 0;
305     return kTRUE;
306   }   
307   fTreeT = (TTree*)tagfile->Get("T"); // file is the owner
308   if (!fTreeT) {
309     AliError(Form("Cannot get tree of tags from file: %s", tagFilename.Data()));
310     delete fRunTag; fRunTag = 0;
311     return kTRUE;
312   }
313     
314   fTreeT->SetBranchAddress("AliTAG",&fRunTag);
315   fTreeT->GetEntry(0);
316   delete tagfile;
317   // Notify the mixing handler after the tags are loaded
318   if (fMixingHandler) fMixingHandler->Notify(path);
319   return kTRUE;
320 }
321
322 //______________________________________________________________________________
323 Option_t *AliESDInputHandler::GetDataType() const
324 {
325 // Returns handled data type.
326    return gESDDataType;
327 }
328
329 //______________________________________________________________________________
330 Int_t AliESDInputHandler::GetNEventAcceptedInFile()
331 {
332   // Get number of events in file accepted by the tag cuts
333   // return -1 if no info is available
334   if (!fTagCutSumm) {
335     TList *luo = fTree->GetUserInfo();
336     if (!luo) {
337       AliInfo(Form("No user info in input tree - no tag cut summary\n"));
338       return -1;
339     }
340     for (int iluo=0; iluo<luo->GetEntries(); iluo++) {
341       fTagCutSumm = dynamic_cast<TMap *>(luo->At(iluo));
342       if (fTagCutSumm) break;
343     }
344     if (!fTagCutSumm) {
345       AliInfo(Form("No tag summary map in input tree\n"));
346       return -1;
347     }
348   }
349
350   TObjString *ostr = 0;
351   if (fTagCutSumm->FindObject(fTree->GetCurrentFile()->GetName()))
352     ostr = (TObjString *) fTagCutSumm->GetValue(fTree->GetCurrentFile()->GetName());
353   else {
354     AliInfo(Form("No tag cut summary for file %s\n", fTree->GetCurrentFile()->GetName()));
355     return -1;
356   }
357   char *iTagInfo;
358   iTagInfo = strdup(ostr->GetString().Data());
359
360   Int_t iAcc = atoi(strtok(iTagInfo, ","));
361   
362   AliInfo(Form("Got %i accepted events for file %s", iAcc,  fTree->GetCurrentFile()->GetName()));
363   
364   free(iTagInfo);
365
366   return iAcc;
367 }
368
369 //______________________________________________________________________________
370 Int_t AliESDInputHandler::GetNEventRejectedInFile()
371 {
372   // Get number of events in file rejected by the tag cuts
373   // return -1 if no info is available
374   if (!fTagCutSumm) {
375     TList *luo = fTree->GetUserInfo();
376     if (!luo) {
377       AliInfo(Form("No user info in input tree - no tag cut summary\n"));
378       return -1;
379     }
380     for (int iluo=0; iluo<luo->GetEntries(); iluo++) {
381       fTagCutSumm = dynamic_cast<TMap *>(luo->At(iluo));
382       if (fTagCutSumm) break;
383     }
384     if (!fTagCutSumm) {
385       AliInfo(Form("No tag summary map in input tree\n"));
386       return -1;
387     }
388   }
389
390   TObjString *ostr = 0;
391   if (fTagCutSumm->FindObject(fTree->GetCurrentFile()->GetName()))
392     ostr = (TObjString *) fTagCutSumm->GetValue(fTree->GetCurrentFile()->GetName());
393   else {
394     AliInfo(Form("No tag cut summary for file %s\n", fTree->GetCurrentFile()->GetName()));
395     return -1;
396   }
397   char *iTagInfo;
398   iTagInfo = strdup(ostr->GetString().Data());
399
400   strtok(iTagInfo, ",");
401   Int_t iRej = atoi(strtok(NULL, ","));
402   
403   AliInfo(Form("Got %i accepted events for file %s", iRej,  fTree->GetCurrentFile()->GetName()));
404   
405   free(iTagInfo);
406
407   return iRej;
408 }
409
410 //______________________________________________________________________________
411 Bool_t AliESDInputHandler::GetCutSummaryForChain(Int_t *aTotal,  Int_t *aAccepted,  Int_t *aRejected)
412 {
413   // Get number of events in the full chain
414   // Count accepted and rejected events
415   // return kFALSE if no info is available
416   if (!fTagCutSumm) {
417     TList *luo = fTree->GetUserInfo();
418     if (!luo) {
419       AliInfo(Form("No user info in input tree - no tag cut summary\n"));
420       return kFALSE;
421     }
422     for (int iluo=0; iluo<luo->GetEntries(); iluo++) {
423       fTagCutSumm = dynamic_cast<TMap *>(luo->At(iluo));
424       if (fTagCutSumm) break;
425     }
426     if (!fTagCutSumm) {
427       AliInfo(Form("No tag summary map in input tree\n"));
428       return kFALSE;
429     }
430   }
431   
432   TMapIter *tIter = new TMapIter(fTagCutSumm);
433   
434   Int_t iTotList=0, iAccList=0, iRejList=0;
435
436   TObject *cobj;
437   while ((cobj = tIter->Next())) {
438     TObjString *kstr = (TObjString *) cobj;
439     TObjString *vstr = (TObjString *) fTagCutSumm->GetValue(kstr->GetString().Data());
440     //    printf("Got object value %s %s\n", kstr->GetString().Data(), vstr->GetString().Data());
441     char *iTagInfo;
442     iTagInfo = strdup(vstr->GetString().Data());
443     
444     Int_t iAcc = atoi(strtok(iTagInfo, ","));
445     Int_t iRej = atoi(strtok(NULL, ","));
446     free(iTagInfo);
447     
448     iAccList += iAcc;
449     iRejList += iRej;
450     iTotList += (iAcc+iRej);
451   }
452
453   *aTotal = iTotList;
454   *aAccepted = iAccList;
455   *aRejected = iRejList;
456
457   return kTRUE;
458 }
459
460 //______________________________________________________________________________
461 Int_t AliESDInputHandler::GetNFilesEmpty()
462 {
463   // Count number of files in which all events were de-selected
464   // For such files Notify() will NOT be called
465   // return -1 if no info is available
466   if (!fTagCutSumm) {
467     TList *luo = fTree->GetUserInfo();
468     if (!luo) {
469       AliInfo(Form("No user info in input tree - no tag cut summary\n"));
470       return -1;
471     }
472     for (int iluo=0; iluo<luo->GetEntries(); iluo++) {
473       fTagCutSumm = dynamic_cast<TMap *>(luo->At(iluo));
474       if (fTagCutSumm) break;
475     }
476     if (!fTagCutSumm) {
477       AliInfo(Form("No tag summary map in input tree\n"));
478       return -1;
479     }
480   }
481   
482   TMapIter *tIter = new TMapIter(fTagCutSumm);
483   
484   Int_t iFilesEmpty = 0;
485
486   TObject *cobj;
487   while ((cobj = tIter->Next())) {
488     TObjString *kstr = (TObjString *) cobj;
489     TObjString *vstr = (TObjString *) fTagCutSumm->GetValue(kstr->GetString().Data());
490     //    printf("Got object value %s %s\n", kstr->GetString().Data(), vstr->GetString().Data());
491     char *iTagInfo;
492     iTagInfo = strdup(vstr->GetString().Data());
493     
494     Int_t iAcc = atoi(strtok(iTagInfo, ","));
495     Int_t iRej = atoi(strtok(NULL, ","));
496     free(iTagInfo);
497     if ((iAcc == 0) && ((iRej+iAcc)>0))
498       iFilesEmpty++;
499   }
500
501   return iFilesEmpty;
502   
503 }
504
505 //______________________________________________________________________________
506 TObject *AliESDInputHandler::GetStatistics(Option_t *option) const
507 {
508 // Get the statistics histogram(s) from the physics selection object. This
509 // should be called during FinishTaskOutput(). Option can be empty (default
510 // statistics histogram) or BIN0.
511    if (!fEventCuts) return NULL;
512    TString opt(option);
513    opt.ToUpper();
514    if (opt=="BIN0") return fEventCuts->GetStatistics("BIN0");
515    else return fEventCuts->GetStatistics("ALL");
516 }   
517
518 //______________________________________________________________________________
519 void AliESDInputHandler::CreatePIDResponse(Bool_t isMC/*=kFALSE*/)
520 {
521   //
522   // create the pid response object if it does not exist yet
523   //
524   if (fESDpid) return;
525   fESDpid=new AliESDpid(isMC);
526
527 }
528
529
530
531