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