a99e2f8974426ebaeae80b55873e89628e4b713b
[u/mrichter/AliRoot.git] / STEER / AliESDInputHandlerRP.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 reading the RecPoint Trees in parallel
20 //     Author: Andreas Morsch, CERN
21 //-------------------------------------------------------------------------
22
23 #include <TTree.h>
24 #include <TList.h>
25 #include <TFile.h>
26 #include <TArchiveFile.h>
27 #include <TSystemDirectory.h>
28 #include <TString.h>
29 #include <TObjString.h>
30 #include <TObjArray.h>
31 #include <TProcessID.h>
32 #include <TSystem.h>
33
34 #include "AliESDInputHandlerRP.h"
35 #include "AliESDEvent.h"
36 #include "AliESD.h"
37 #include "AliLog.h"
38
39 ClassImp(AliESDInputHandlerRP)
40
41 //______________________________________________________________________________
42 AliESDInputHandlerRP::AliESDInputHandlerRP() :
43     AliESDInputHandler(),
44     fRTrees(   new TObjArray()),
45     fRFiles(   new TList()),
46     fDetectors(new TList()),
47     fDirR(0),
48     fEventNumber(-1),
49     fFileNumber(0),
50     fEventsPerFile(0),
51     fExtension(""),
52     fPathName(new TString("./")),
53     fIsArchive(kFALSE)
54 {
55   // Default constructor
56 }
57
58
59 //______________________________________________________________________________
60 AliESDInputHandlerRP::AliESDInputHandlerRP(const char* name, const char* title):
61     AliESDInputHandler(name, title),
62     fRTrees(   new TObjArray()),
63     fRFiles(   new TList()),
64     fDetectors(new TList()),
65     fDirR(0),
66     fEventNumber(-1),
67     fFileNumber(0),
68     fEventsPerFile(0),
69     fExtension(""),
70     fPathName(new TString("./")),
71     fIsArchive(kFALSE)
72 {
73     // Constructor
74 }
75
76 //______________________________________________________________________________
77 AliESDInputHandlerRP::~AliESDInputHandlerRP() 
78 {
79   // Destructor
80 }
81
82 Bool_t AliESDInputHandlerRP::Init(Option_t* opt)
83 {
84     //
85     // Initialize input
86     //
87     if (!(strcmp(opt, "proof")) || !(strcmp(opt, "local"))) return kTRUE;
88     //
89     TIter next(fDetectors);
90     TNamed* det;
91     TFile* file = 0;
92     while ((det = (TNamed*) next()))
93     {
94         if (!fIsArchive) {
95             file = TFile::Open(Form("%s%s.RecPoints.root", fPathName->Data(), det->GetName()));
96         } else {
97             file = TFile::Open(Form("%s#%s.RecPoints.root", fPathName->Data(), det->GetName()));
98         }
99         if (!file) AliFatal(Form("AliESDInputHandlerRP: %s.RecPoints.root not found in %s ! \n", det->GetName(), fPathName->Data()));
100         fRFiles->Add(file);
101     }
102
103     if (file) {
104         fEventsPerFile = file->GetNkeys() - file->GetNProcessIDs();
105     } else {
106         AliFatal(Form("AliESDInputHandlerRP: No file with RecPoints found in %s ! \n", fPathName->Data()));
107     }
108     
109
110     // Reset the event number
111     fEventNumber      = -1;
112     fFileNumber       =  0;
113     // Get number of events from esd tree 
114     printf("AliESDInputHandlerRP::Init() %d %d\n",__LINE__, fNEvents);
115     return kTRUE;
116 }
117
118 Bool_t AliESDInputHandlerRP::BeginEvent(Long64_t entry)
119 {
120     // Begin the next event
121     // Delegate first to base class
122     AliESDInputHandler::BeginEvent(entry);
123 //
124     if (entry == -1) {
125         fEventNumber++;
126         entry = fEventNumber;
127     } else {
128         fEventNumber = entry;
129     }
130     
131     if (entry >= fNEvents) {
132         AliWarning(Form("AliESDInputHandlerRP: Event number out of range %5d %5d\n", entry, fNEvents));
133         return kFALSE;
134     }
135     return LoadEvent(entry);
136 }
137
138 Bool_t AliESDInputHandlerRP::LoadEvent(Int_t iev)
139 {
140     // Load the event number iev
141     //
142     // Calculate the file number
143     Int_t inew  = iev / fEventsPerFile;
144     if (inew != fFileNumber) {
145         fFileNumber = inew;
146         if (!OpenFile(fFileNumber)){
147             return kFALSE;
148         }
149     }
150     // Folder name
151     char folder[20];
152     sprintf(folder, "Event%d", iev);
153     // Tree R
154     TIter next(fRFiles);
155     TFile* file;
156     Int_t idx = 0;
157     
158     while ((file = (TFile*) next()))
159     {
160         file->GetObject(folder, fDirR);
161         if (!fDirR) {
162             AliWarning(Form("AliESDInputHandlerRP: Event #%5d not found\n", iev));
163             return kFALSE;
164         }
165         TTree* tree = 0;
166         fDirR->GetObject("TreeR", tree);
167         fRTrees->AddAt(tree, idx++);
168     }
169     return kTRUE;
170 }
171
172 Bool_t AliESDInputHandlerRP::OpenFile(Int_t i)
173 {
174     // Open file i
175     Bool_t ok = kTRUE;
176     if (i > 0) {
177         fExtension = Form("%d", i);
178     } else {
179         fExtension = "";
180     }
181     
182     fRFiles->Delete();
183     TIter next(fDetectors);
184     TNamed* det;
185     TFile* file;
186     while ((det = (TNamed*) next()))
187     {
188         if (!fIsArchive) {
189             file = TFile::Open(Form("%s%s.RecPoints%s.root", fPathName->Data(), det->GetName(), fExtension));
190         } else {
191             file = TFile::Open(Form("%s#%s.RecPoints%s.root", fPathName->Data(), det->GetName(), fExtension));
192         }
193         if (!file) AliFatal(Form("AliESDInputHandlerRP: RecPoints.root not found in %s ! \n", fPathName->Data()));
194         fRFiles->Add(file);
195     }
196     return ok;
197 }
198
199 Bool_t AliESDInputHandlerRP::Notify(const char *path)
200 {
201   // Notify about directory change
202   // The directory is taken from the 'path' argument
203   // 
204     AliInfo(Form("Directory change %s \n", path));
205     // Get path to directory
206     TString fileName(path);
207
208     if(fileName.Contains("#")){
209     // If this is an archive it will contain a # 
210       fIsArchive = kTRUE;
211     } else  if(fileName.Contains("AliESDs.root")){
212       fileName.ReplaceAll("AliESDs.root", "");
213     }
214
215     //
216     // At this point we have a path to the directory or to the archive anchor
217     *fPathName = fileName;
218     //
219     // Now filter the files containing RecPoints *.RecPoints.*
220
221     TSeqCollection* members;
222
223     
224     if (fIsArchive) {
225         // Archive
226       TFile* file = TFile::Open(fPathName->Data());
227       TArchiveFile* arch = file->GetArchive();
228       members = arch->GetMembers();
229     } else {
230         // Directory or alien archive
231       if (fileName.BeginsWith("alien:")) {
232         TFile* file = TFile::Open(Form("%s/root_archive.zip", fPathName->Data()));
233         TArchiveFile* arch = file->GetArchive();
234         members = arch->GetMembers();
235       } else {  
236         TString wd = gSystem->WorkingDirectory();
237         TSystemDirectory dir(".", fPathName->Data());
238         members = dir.GetListOfFiles();
239         gSystem->cd(wd);
240       }  
241     }
242
243     TIter next(members);
244     TFile* entry;
245     Int_t ien = 0;
246     fDetectors->Delete();
247     
248     while ( (entry = (TFile*) next()) )
249     {
250         TString name(entry->GetName());
251         TObjArray* tokens = name.Tokenize(".");
252         Int_t ntok = tokens->GetEntries();
253         if (ntok <= 1) continue;
254         TString str = ((TObjString*) tokens->At(1))->GetString();
255         if (!(strcmp(str.Data(), "RecPoints"))){
256             TString det = ((TObjString*) tokens->At(0))->GetString();
257             printf("Found file with RecPoints for %s \n", det.Data());
258             TNamed* ent = new TNamed(det.Data(), det.Data());
259             fRTrees->AddAt(0, ien);
260             ent->SetUniqueID(ien++);
261             fDetectors->Add(ent);
262         }
263         if(tokens) delete tokens;
264     } // loop over files
265
266
267     // Now we have the path and the list of detectors
268     
269     printf("AliESDInputHandlerRP::Notify() Path: %s\n", fPathName->Data());
270     //
271     ResetIO();
272     InitIO("");
273     // Some clean-up
274     members->Delete();
275
276     return kTRUE;
277 }
278
279 Bool_t AliESDInputHandlerRP::FinishEvent()
280 {
281     // Clean-up after each event
282     delete fDirR;  fDirR = 0;
283     AliESDInputHandler::FinishEvent();
284     return kTRUE;
285 }
286
287 void AliESDInputHandlerRP::ResetIO()
288 {
289 // Delete trees and files
290     fRFiles->Delete();
291     fExtension="";
292 }
293
294 TTree* AliESDInputHandlerRP::GetTreeR(const char* det)
295 {
296 // Return pointer to RecPoint tree for detector det
297     TNamed* entry = (TNamed*) (fDetectors->FindObject(det));
298     if (!entry) {
299         AliWarning(Form("AliESDInputHandlerRP: No RecPoints for detector %s available \n", det));
300         return 0;
301     } else {
302         Int_t ien = entry->GetUniqueID();
303         return ((TTree*) (fRTrees->At(ien)));
304     }
305 }