Last fixes before declaring (almost) success
[u/mrichter/AliRoot.git] / FMD / AliFMDInput.cxx
1 /**************************************************************************
2  * Copyright(c) 2004, 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 //
20 // The classes defined here, are utility classes for reading in data
21 // for the FMD.  They are  put in a seperate library to not polute the
22 // normal libraries.  The classes are intended to be used as base
23 // classes for customized class that do some sort of analysis on the
24 // various types of data produced by the FMD. 
25 //
26 // Latest changes by Christian Holm Christensen
27 //
28 #include "AliFMDInput.h"        // ALIFMDHIT_H
29 #include "AliLog.h"             // ALILOG_H
30 #include "AliLoader.h"          // ALILOADER_H
31 #include "AliRunLoader.h"       // ALIRUNLOADER_H
32 #include "AliRun.h"             // ALIRUN_H
33 #include "AliStack.h"           // ALISTACK_H
34 #include "AliRawReaderFile.h"   // ALIRAWREADERFILE_H
35 #include "AliFMD.h"             // ALIFMD_H
36 #include "AliFMDHit.h"          // ALIFMDHIT_H
37 #include "AliFMDDigit.h"        // ALIFMDDigit_H
38 #include "AliFMDRecPoint.h"     // ALIFMDRECPOINT_H
39 #include "AliFMDRawReader.h"    // ALIFMDRAWREADER_H
40 #include <AliESD.h>
41 #include <AliESDFMD.h>
42 #include <AliCDBManager.h>
43 #include <AliCDBEntry.h>
44 #include <AliAlignObjAngles.h>
45 #include <TTree.h>              // ROOT_TTree
46 #include <TChain.h>             // ROOT_TChain
47 #include <TParticle.h>          // ROOT_TParticle
48 #include <TString.h>            // ROOT_TString
49 #include <TDatabasePDG.h>       // ROOT_TDatabasePDG
50 #include <TMath.h>              // ROOT_TMath
51 #include <TGeoManager.h>        // ROOT_TGeoManager 
52 #include <TSystemDirectory.h>   // ROOT_TSystemDirectory
53 #include <Riostream.h>          // ROOT_Riostream
54
55 //____________________________________________________________________
56 ClassImp(AliFMDInput)
57 #if 0
58   ; // This is here to keep Emacs for indenting the next line
59 #endif
60
61
62 //____________________________________________________________________
63 AliFMDInput::AliFMDInput()
64   : fGAliceFile(""), 
65     fLoader(0),
66     fRun(0), 
67     fStack(0),
68     fFMDLoader(0), 
69     fReader(0),
70     fFMD(0),
71     fMainESD(0),
72     fESD(0),
73     fTreeE(0),
74     fTreeH(0),
75     fTreeD(0),
76     fTreeS(0),
77     fTreeR(0), 
78     fChainE(0),
79     fArrayE(0),
80     fArrayH(0),
81     fArrayD(0),
82     fArrayS(0), 
83     fArrayR(0), 
84     fArrayA(0), 
85     fTreeMask(0), 
86     fIsInit(kFALSE)
87 {
88   // Constructor of an FMD input object.  Specify what data to read in
89   // using the AddLoad member function.   Sub-classes should at a
90   // minimum overload the member function Event.   A full job can be
91   // executed using the member function Run. 
92 }
93
94   
95
96 //____________________________________________________________________
97 AliFMDInput::AliFMDInput(const char* gAliceFile)
98   : fGAliceFile(gAliceFile),
99     fLoader(0),
100     fRun(0), 
101     fStack(0),
102     fFMDLoader(0), 
103     fReader(0),
104     fFMD(0),
105     fMainESD(0),
106     fESD(0),
107     fTreeE(0),
108     fTreeH(0),
109     fTreeD(0),
110     fTreeS(0),
111     fTreeR(0), 
112     fChainE(0),
113     fArrayE(0),
114     fArrayH(0),
115     fArrayD(0),
116     fArrayS(0), 
117     fArrayR(0), 
118     fArrayA(0), 
119     fTreeMask(0), 
120     fIsInit(kFALSE)
121 {
122   // Constructor of an FMD input object.  Specify what data to read in
123   // using the AddLoad member function.   Sub-classes should at a
124   // minimum overload the member function Event.   A full job can be
125   // executed using the member function Run. 
126 }
127
128 //____________________________________________________________________
129 Int_t
130 AliFMDInput::NEvents() const 
131 {
132   // Get number of events
133   if (fTreeE) return fTreeE->GetEntries();
134   return -1;
135 }
136
137 //____________________________________________________________________
138 Bool_t
139 AliFMDInput::Init()
140 {
141   // Initialize the object.  Get the needed loaders, and such. 
142
143   // Check if we have been initialized
144   if (fIsInit) { 
145     AliWarning("Already initialized");
146     return fIsInit;
147   }
148   if (fGAliceFile.IsNull()) fGAliceFile = "galice.root";
149   // Get the loader
150   fLoader = AliRunLoader::Open(fGAliceFile.Data(), "Alice", "read");
151   if (!fLoader) {
152     AliError(Form("Coulnd't read the file %s", fGAliceFile.Data()));
153     return kFALSE;
154   }
155   
156   // Get the run 
157   if  (fLoader->LoadgAlice()) return kFALSE;
158   fRun = fLoader->GetAliRun();
159   
160   // Get the FMD 
161   fFMD = static_cast<AliFMD*>(fRun->GetDetector("FMD"));
162   if (!fFMD) {
163     AliError("Failed to get detector FMD from loader");
164     return kFALSE;
165   }
166   
167   // Get the FMD loader
168   fFMDLoader = fLoader->GetLoader("FMDLoader");
169   if (!fFMDLoader) {
170     AliError("Failed to get detector FMD loader from loader");
171     return kFALSE;
172   }
173   if (fLoader->LoadHeader()) { 
174     AliError("Failed to get event header information from loader");
175     return kFALSE;
176   }
177   fTreeE = fLoader->TreeE();
178
179   // Optionally, get the ESD files
180   if (TESTBIT(fTreeMask, kESD)) {
181     fChainE = new TChain("esdTree");
182     TSystemDirectory dir;
183     TList*           files = dir.GetListOfFiles();
184     TSystemFile*     file;
185     files->Sort();
186     TIter            next(files);
187     while ((file = static_cast<TSystemFile*>(next()))) {
188       TString fname(file->GetName());
189       if (fname.Contains("AliESDs")) fChainE->AddFile(fname.Data());
190     }
191     fChainE->SetBranchAddress("ESD", &fMainESD);
192   }
193     
194   if (TESTBIT(fTreeMask, kRaw)) {
195     AliInfo("Getting FMD raw data digits");
196     fArrayA = new TClonesArray("AliFMDDigit");
197     fReader = new AliRawReaderFile(-1);
198   }
199   
200   // Optionally, get the geometry 
201   if (TESTBIT(fTreeMask, kGeometry)) {
202     TString fname(fRun->GetGeometryFileName());
203     if (fname.IsNull()) {
204       Warning("Init", "No file name for the geometry from AliRun");
205       fname = gSystem->DirName(fGAliceFile);
206       fname.Append("/geometry.root");
207     }
208     fGeoManager = TGeoManager::Import(fname.Data());
209     if (!fGeoManager) {
210       Fatal("Init", "No geometry manager found");
211       return kFALSE;
212     }
213     AliCDBManager* cdb   = AliCDBManager::Instance();
214     AliCDBEntry*   align = cdb->Get("FMD/Align/Data");
215     if (align) {
216       AliInfo("Got alignment data from CDB");
217       TClonesArray* array = dynamic_cast<TClonesArray*>(align->GetObject());
218       if (!array) {
219         AliWarning("Invalid align data from CDB");
220       }
221       else {
222         Int_t nAlign = array->GetEntries();
223         for (Int_t i = 0; i < nAlign; i++) {
224           AliAlignObjAngles* a = static_cast<AliAlignObjAngles*>(array->At(i));
225           if (!a->ApplyToGeometry()) {
226             AliWarning(Form("Failed to apply alignment to %s", 
227                             a->GetVolPath()));
228           }
229         }
230       }
231     }
232   }
233
234   
235   fIsInit = kTRUE;
236   return fIsInit;
237 }
238
239 //____________________________________________________________________
240 Bool_t
241 AliFMDInput::Begin(Int_t event)
242 {
243   // Called at the begining of each event.  Per default, it gets the
244   // data trees and gets pointers to the output arrays.   Users can
245   // overload this, but should call this member function in the
246   // overloaded member function of the derived class. 
247
248   // Check if we have been initialized
249   if (!fIsInit) { 
250     AliError("Not initialized");
251     return fIsInit;
252   }
253   // Get the event 
254   if (fLoader->GetEvent(event)) return kFALSE;
255   AliInfo(Form("Now in event %d/%d", event, NEvents()));
256
257   // Possibly load global kinematics information 
258   if (TESTBIT(fTreeMask, kKinematics)) {
259     AliInfo("Getting kinematics");
260     if (fLoader->LoadKinematics()) return kFALSE;
261     fStack = fLoader->Stack();
262   }
263   // Possibly load FMD Hit information 
264   if (TESTBIT(fTreeMask, kHits)) {
265     AliInfo("Getting FMD hits");
266     if (fFMDLoader->LoadHits()) return kFALSE;
267     fTreeH = fFMDLoader->TreeH();
268     if (!fArrayH) fArrayH = fFMD->Hits(); 
269   }
270   // Possibly load FMD Digit information 
271   if (TESTBIT(fTreeMask, kDigits)) {
272     AliInfo("Getting FMD digits");
273     if (fFMDLoader->LoadDigits()) return kFALSE;
274     fTreeD = fFMDLoader->TreeD();
275     if (!fArrayD) fArrayD = fFMD->Digits();
276   }
277   // Possibly load FMD Sdigit information 
278   if (TESTBIT(fTreeMask, kSDigits)) {
279     AliInfo("Getting FMD summable digits");
280     if (fFMDLoader->LoadSDigits()) return kFALSE;
281     fTreeS = fFMDLoader->TreeS();
282     if (!fArrayS) fArrayS = fFMD->SDigits();
283   }
284   // Possibly load FMD RecPoints information 
285   if (TESTBIT(fTreeMask, kRecPoints)) {
286     AliInfo("Getting FMD reconstructed points");
287     if (fFMDLoader->LoadRecPoints()) return kFALSE;
288     fTreeR = fFMDLoader->TreeR();
289     if (!fArrayR) fArrayR = new TClonesArray("AliFMDRecPoint");
290     fTreeR->SetBranchAddress("FMD",  &fArrayR);
291   }  // Possibly load FMD ESD information 
292   if (TESTBIT(fTreeMask, kESD)) {
293     AliInfo("Getting FMD event summary data");
294     Int_t read = fChainE->GetEntry(event);
295     if (read <= 0) return kFALSE;
296     fESD = fMainESD->GetFMDData();
297     if (!fESD) return kFALSE;
298   }
299   // Possibly load FMD Digit information 
300   if (TESTBIT(fTreeMask, kRaw)) {
301     AliInfo("Getting FMD raw data digits");
302     if (!fReader->NextEvent()) return kFALSE;
303     AliFMDRawReader r(fReader, 0);
304     fArrayA->Clear();
305     r.ReadAdcs(fArrayA);
306   }
307   
308   return kTRUE;
309 }
310
311
312 //____________________________________________________________________
313 Bool_t 
314 AliFMDInput::Event()
315 {
316   // Process one event.  The default implementation one or more of 
317   //
318   //   -  ProcessHits       if the hits are loaded. 
319   //   -  ProcessDigits     if the digits are loaded. 
320   //   -  ProcessSDigits    if the sumbable digits are loaded. 
321   //   -  ProcessRecPoints  if the reconstructed points are loaded. 
322   //   -  ProcessESD        if the event summary data is loaded
323   // 
324   if (TESTBIT(fTreeMask, kHits)) 
325     if (!ProcessHits()) return kFALSE; 
326   if (TESTBIT(fTreeMask, kDigits)) 
327     if (!ProcessDigits()) return kFALSE;
328   if (TESTBIT(fTreeMask, kSDigits)) 
329     if (!ProcessSDigits()) return kFALSE;
330   if (TESTBIT(fTreeMask, kRaw)) 
331     if (!ProcessRawDigits()) return kFALSE;
332   if (TESTBIT(fTreeMask, kRecPoints)) 
333     if (!ProcessRecPoints()) return kFALSE;
334   if (TESTBIT(fTreeMask, kESD))
335     if (!ProcessESD(fESD)) return kFALSE;
336   
337   return kTRUE;
338 }
339
340 //____________________________________________________________________
341 Bool_t 
342 AliFMDInput::ProcessHits()
343 {
344   if (!fTreeH) {
345     AliError("No hit tree defined");
346     return kFALSE;
347   }
348   Int_t nTracks = fTreeH->GetEntries();
349   for (Int_t i = 0; i < nTracks; i++) {
350     Int_t hitRead  = fTreeH->GetEntry(i);
351     if (hitRead <= 0) continue;
352     if (!fArrayH) {
353       AliError("No hit array defined");
354       return kFALSE;
355     }
356     Int_t nHit = fArrayH->GetEntries();
357     if (nHit <= 0) continue;
358     for (Int_t j = 0; j < nHit; j++) {
359       AliFMDHit* hit = static_cast<AliFMDHit*>(fArrayH->At(j));
360       if (!hit) continue;
361       TParticle* track = 0;
362       if (TESTBIT(fTreeMask, kKinematics) && fStack) {
363         Int_t trackno = hit->Track();
364         track = fStack->Particle(trackno);
365       }
366       if (!ProcessHit(hit, track)) return kFALSE;
367     }    
368   }
369   return kTRUE;
370 }
371
372 //____________________________________________________________________
373 Bool_t 
374 AliFMDInput::ProcessDigits()
375 {
376   // Read the digit tree, and pass each digit to the member function
377   // ProcessDigit.
378   Int_t nEv = fTreeD->GetEntries();
379   for (Int_t i = 0; i < nEv; i++) {
380     Int_t digitRead  = fTreeD->GetEntry(i);
381     if (digitRead <= 0) continue;
382     Int_t nDigit = fArrayD->GetEntries();
383     if (nDigit <= 0) continue;
384     for (Int_t j = 0; j < nDigit; j++) {
385       AliFMDDigit* digit = static_cast<AliFMDDigit*>(fArrayD->At(j));
386       if (!digit) continue;
387       if (!ProcessDigit(digit)) return kFALSE;
388     }    
389   }
390   return kTRUE;
391 }
392
393 //____________________________________________________________________
394 Bool_t 
395 AliFMDInput::ProcessSDigits()
396 {
397   // Read the summable digit tree, and pass each sumable digit to the
398   // member function ProcessSdigit.
399   Int_t nEv = fTreeD->GetEntries();
400   for (Int_t i = 0; i < nEv; i++) {
401     Int_t sdigitRead  = fTreeS->GetEntry(i);
402     if (sdigitRead <= 0) continue;
403     Int_t nSdigit = fArrayS->GetEntries();
404     if (nSdigit <= 0) continue;
405     for (Int_t j = 0; j < nSdigit; j++) {
406       AliFMDSDigit* sdigit = static_cast<AliFMDSDigit*>(fArrayS->At(j));
407       if (!sdigit) continue;
408       if (!ProcessSDigit(sdigit)) return kFALSE;
409     }    
410   }
411   return kTRUE;
412 }
413
414 //____________________________________________________________________
415 Bool_t 
416 AliFMDInput::ProcessRawDigits()
417 {
418   // Read the digit tree, and pass each digit to the member function
419   // ProcessDigit.
420   Int_t nDigit = fArrayA->GetEntries();
421   if (nDigit <= 0) return kTRUE;
422   for (Int_t j = 0; j < nDigit; j++) {
423     AliFMDDigit* digit = static_cast<AliFMDDigit*>(fArrayA->At(j));
424     if (!digit) continue;
425     if (!ProcessRawDigit(digit)) return kFALSE;
426   }    
427   return kTRUE;
428 }
429
430 //____________________________________________________________________
431 Bool_t 
432 AliFMDInput::ProcessRecPoints()
433 {
434   // Read the reconstrcted points tree, and pass each reconstruction
435   // object (AliFMDRecPoint) to either ProcessRecPoint.
436   Int_t nEv = fTreeR->GetEntries();
437   for (Int_t i = 0; i < nEv; i++) {
438     Int_t recRead  = fTreeR->GetEntry(i);
439     if (recRead <= 0) continue;
440     Int_t nRecPoint = fArrayR->GetEntries();
441     for (Int_t j = 0; j < nRecPoint; j++) {
442       AliFMDRecPoint* recPoint = static_cast<AliFMDRecPoint*>(fArrayR->At(j));
443       if (!recPoint) continue;
444       if (!ProcessRecPoint(recPoint)) return kFALSE;
445     }    
446   }
447   return kTRUE;
448 }
449
450 //____________________________________________________________________
451 Bool_t
452 AliFMDInput::End()
453 {
454   // Called at the end of each event.  Per default, it unloads the
455   // data trees and resets the pointers to the output arrays.   Users
456   // can overload this, but should call this member function in the
457   // overloaded member function of the derived class. 
458
459   // Check if we have been initialized
460   if (!fIsInit) { 
461     AliError("Not initialized");
462     return fIsInit;
463   }
464   // Possibly unload global kinematics information 
465   if (TESTBIT(fTreeMask, kKinematics)) {
466     fLoader->UnloadKinematics();
467     // fTreeK = 0;
468     fStack = 0;
469   }
470   // Possibly unload FMD Hit information 
471   if (TESTBIT(fTreeMask, kHits)) {
472     fFMDLoader->UnloadHits();
473     fTreeH = 0;
474   }
475   // Possibly unload FMD Digit information 
476   if (TESTBIT(fTreeMask, kDigits)) {
477     fFMDLoader->UnloadDigits();
478     fTreeD = 0;
479   }
480   // Possibly unload FMD Sdigit information 
481   if (TESTBIT(fTreeMask, kSDigits)) {
482     fFMDLoader->UnloadSDigits();
483     fTreeS = 0;
484   }
485   // Possibly unload FMD RecPoints information 
486   if (TESTBIT(fTreeMask, kRecPoints)) {
487     fFMDLoader->UnloadRecPoints();
488     fTreeR = 0;
489   }
490   AliInfo("Now out event");
491   return kTRUE;
492 }
493
494 //____________________________________________________________________
495 Bool_t
496 AliFMDInput::Run()
497 {
498   // Run over all events and files references in galice.root 
499
500   Bool_t retval;
501   if (!(retval = Init())) return retval;
502
503   Int_t nEvents = NEvents();
504   for (Int_t event = 0; event < nEvents; event++) {
505     if (!(retval = Begin(event))) break;
506     if (!(retval = Event())) break;
507     if (!(retval = End())) break;
508   }
509   if (!retval) return retval;
510   retval = Finish();
511   return retval;
512 }
513
514 //====================================================================
515 ClassImp(AliFMDInputHits)
516 #if 0
517   ;
518 #endif
519
520
521 //====================================================================
522 ClassImp(AliFMDInputDigits)
523 #if 0
524   ;
525 #endif
526
527 //====================================================================
528 ClassImp(AliFMDInputSDigits)
529 #if 0
530   ;
531 #endif
532
533 //====================================================================
534 ClassImp(AliFMDInputRecPoints)
535 #if 0
536   ;
537 #endif
538
539 //____________________________________________________________________
540 //
541 // EOF
542 //