]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliReconstruction.cxx
Moving the efficiency calculations before the cleanup (Guiseppe)
[u/mrichter/AliRoot.git] / STEER / AliReconstruction.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, 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 // class for running the reconstruction                                      //
21 //                                                                           //
22 // Clusters and tracks are created for all detectors and all events by       //
23 // typing:                                                                   //
24 //                                                                           //
25 //   AliReconstruction rec;                                                  //
26 //   rec.Run();                                                              //
27 //                                                                           //
28 // The Run method returns kTRUE in case of successful execution.             //
29 //                                                                           //
30 // If the input to the reconstruction are not simulated digits but raw data, //
31 // this can be specified by an argument of the Run method or by the method   //
32 //                                                                           //
33 //   rec.SetInput("...");                                                    //
34 //                                                                           //
35 // The input formats and the corresponding argument are:                     //
36 // - DDL raw data files: directory name, ends with "/"                       //
37 // - raw data root file: root file name, extension ".root"                   //
38 // - raw data DATE file: DATE file name, any other non-empty string          //
39 // - MC root files     : empty string, default                               //
40 //                                                                           //
41 // By default all events are reconstructed. The reconstruction can be        //
42 // limited to a range of events by giving the index of the first and the     //
43 // last event as an argument to the Run method or by calling                 //
44 //                                                                           //
45 //   rec.SetEventRange(..., ...);                                            //
46 //                                                                           //
47 // The index -1 (default) can be used for the last event to indicate no      //
48 // upper limit of the event range.                                           //
49 //                                                                           //
50 // In case of raw-data reconstruction the user can modify the default        //
51 // number of events per digits/clusters/tracks file. In case the option      //
52 // is not used the number is set 1. In case the user provides 0, than        //
53 // the number of events is equal to the number of events inside the          //
54 // raw-data file (i.e. one digits/clusters/tracks file):                     //
55 //                                                                           //
56 //   rec.SetNumberOfEventsPerFile(...);                                      //
57 //                                                                           //
58 //                                                                           //
59 // The name of the galice file can be changed from the default               //
60 // "galice.root" by passing it as argument to the AliReconstruction          //
61 // constructor or by                                                         //
62 //                                                                           //
63 //   rec.SetGAliceFile("...");                                               //
64 //                                                                           //
65 // The local reconstruction can be switched on or off for individual         //
66 // detectors by                                                              //
67 //                                                                           //
68 //   rec.SetRunLocalReconstruction("...");                                   //
69 //                                                                           //
70 // The argument is a (case sensitive) string with the names of the           //
71 // detectors separated by a space. The special string "ALL" selects all      //
72 // available detectors. This is the default.                                 //
73 //                                                                           //
74 // The reconstruction of the primary vertex position can be switched off by  //
75 //                                                                           //
76 //   rec.SetRunVertexFinder(kFALSE);                                         //
77 //                                                                           //
78 // The tracking and the creation of ESD tracks can be switched on for        //
79 // selected detectors by                                                     //
80 //                                                                           //
81 //   rec.SetRunTracking("...");                                              //
82 //                                                                           //
83 // Uniform/nonuniform field tracking switches (default: uniform field)       //
84 //                                                                           //
85 //   rec.SetUniformFieldTracking(); ( rec.SetUniformFieldTracking(kFALSE); ) //
86 //                                                                           //
87 // The filling of additional ESD information can be steered by               //
88 //                                                                           //
89 //   rec.SetFillESD("...");                                                  //
90 //                                                                           //
91 // Again, for both methods the string specifies the list of detectors.       //
92 // The default is "ALL".                                                     //
93 //                                                                           //
94 // The call of the shortcut method                                           //
95 //                                                                           //
96 //   rec.SetRunReconstruction("...");                                        //
97 //                                                                           //
98 // is equivalent to calling SetRunLocalReconstruction, SetRunTracking and    //
99 // SetFillESD with the same detector selecting string as argument.           //
100 //                                                                           //
101 // The reconstruction requires digits or raw data as input. For the creation //
102 // of digits and raw data have a look at the class AliSimulation.            //
103 //                                                                           //
104 // For debug purposes the method SetCheckPointLevel can be used. If the      //
105 // argument is greater than 0, files with ESD events will be written after   //
106 // selected steps of the reconstruction for each event:                      //
107 //   level 1: after tracking and after filling of ESD (final)                //
108 //   level 2: in addition after each tracking step                           //
109 //   level 3: in addition after the filling of ESD for each detector         //
110 // If a final check point file exists for an event, this event will be       //
111 // skipped in the reconstruction. The tracking and the filling of ESD for    //
112 // a detector will be skipped as well, if the corresponding check point      //
113 // file exists. The ESD event will then be loaded from the file instead.     //
114 //                                                                           //
115 ///////////////////////////////////////////////////////////////////////////////
116
117 #include <TArrayF.h>
118 #include <TFile.h>
119 #include <TList.h>
120 #include <TSystem.h>
121 #include <TROOT.h>
122 #include <TPluginManager.h>
123 #include <TGeoManager.h>
124 #include <TLorentzVector.h>
125 #include <TArrayS.h>
126 #include <TArrayD.h>
127
128 #include "AliReconstruction.h"
129 #include "AliCodeTimer.h"
130 #include "AliReconstructor.h"
131 #include "AliLog.h"
132 #include "AliRunLoader.h"
133 #include "AliRun.h"
134 #include "AliRawReaderFile.h"
135 #include "AliRawReaderDate.h"
136 #include "AliRawReaderRoot.h"
137 #include "AliRawEventHeaderBase.h"
138 #include "AliESDEvent.h"
139 #include "AliESDMuonTrack.h"
140 #include "AliESDfriend.h"
141 #include "AliESDVertex.h"
142 #include "AliESDcascade.h"
143 #include "AliESDkink.h"
144 #include "AliESDtrack.h"
145 #include "AliESDCaloCluster.h"
146 #include "AliESDCaloCells.h"
147 #include "AliMultiplicity.h"
148 #include "AliTracker.h"
149 #include "AliVertexer.h"
150 #include "AliVertexerTracks.h"
151 #include "AliV0vertexer.h"
152 #include "AliCascadeVertexer.h"
153 #include "AliHeader.h"
154 #include "AliGenEventHeader.h"
155 #include "AliPID.h"
156 #include "AliESDpid.h"
157 #include "AliESDtrack.h"
158 #include "AliESDPmdTrack.h"
159
160 #include "AliESDTagCreator.h"
161 #include "AliAODTagCreator.h"
162
163 #include "AliGeomManager.h"
164 #include "AliTrackPointArray.h"
165 #include "AliCDBManager.h"
166 #include "AliCDBStorage.h"
167 #include "AliCDBEntry.h"
168 #include "AliAlignObj.h"
169
170 #include "AliCentralTrigger.h"
171 #include "AliCTPRawStream.h"
172
173 #include "AliAODEvent.h"
174 #include "AliAODHeader.h"
175 #include "AliAODTrack.h"
176 #include "AliAODVertex.h"
177 #include "AliAODv0.h"
178 #include "AliAODJet.h"
179 #include "AliAODCaloCells.h"
180 #include "AliAODCaloCluster.h"
181 #include "AliAODPmdCluster.h"
182 #include "AliAODFmdCluster.h"
183 #include "AliAODTracklets.h"
184
185 #include "AliQADataMakerRec.h" 
186 #include "AliGlobalQADataMaker.h" 
187 #include "AliQA.h"
188 #include "AliQADataMakerSteer.h"
189
190 #include "AliPlaneEff.h"
191
192 #include "AliSysInfo.h" // memory snapshots
193
194
195 ClassImp(AliReconstruction)
196
197
198 //_____________________________________________________________________________
199 const char* AliReconstruction::fgkDetectorName[AliReconstruction::fgkNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT"};
200
201 //_____________________________________________________________________________
202 AliReconstruction::AliReconstruction(const char* gAliceFilename,
203                                      const char* name, const char* title) :
204   TNamed(name, title),
205
206   fUniformField(kTRUE),
207   fRunVertexFinder(kTRUE),
208   fRunHLTTracking(kFALSE),
209   fRunMuonTracking(kFALSE),
210   fRunV0Finder(kTRUE),
211   fRunCascadeFinder(kTRUE),
212   fStopOnError(kFALSE),
213   fWriteAlignmentData(kFALSE),
214   fWriteESDfriend(kFALSE),
215   fWriteAOD(kFALSE),
216   fFillTriggerESD(kTRUE),
217
218   fCleanESD(kTRUE),
219   fV0DCAmax(3.),
220   fV0CsPmin(0.),
221   fDmax(50.),
222   fZmax(50.),
223
224   fRunLocalReconstruction("ALL"),
225   fRunTracking("ALL"),
226   fFillESD("ALL"),
227   fUseTrackingErrorsForAlignment(""),
228   fGAliceFileName(gAliceFilename),
229   fInput(""),
230   fEquipIdMap(""),
231   fFirstEvent(0),
232   fLastEvent(-1),
233   fNumberOfEventsPerFile(1),
234   fCheckPointLevel(0),
235   fOptions(),
236   fLoadAlignFromCDB(kTRUE),
237   fLoadAlignData("ALL"),
238   fESDPar(""),
239
240   fRunLoader(NULL),
241   fRawReader(NULL),
242
243   fVertexer(NULL),
244   fDiamondProfile(NULL),
245   fMeanVertexConstraint(kTRUE),
246
247   fGRPList(NULL),
248
249   fAlignObjArray(NULL),
250   fCDBUri(),
251   fSpecCDBUri(), 
252   fInitCDBCalled(kFALSE),
253   fSetRunNumberFromDataCalled(kFALSE),
254   fRunQA(kTRUE),  
255   fRunGlobalQA(kFALSE),
256   fInLoopQA(kFALSE),
257
258   fRunPlaneEff(kFALSE)
259 {
260 // create reconstruction object with default parameters
261   
262   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
263     fReconstructor[iDet] = NULL;
264     fLoader[iDet] = NULL;
265     fTracker[iDet] = NULL;
266     fQADataMaker[iDet] = NULL;
267         fQACycles[iDet] = 999999;       
268   }
269   fQADataMaker[fgkNDetectors]=NULL;  //Global QA
270   AliPID pid;
271 }
272
273 //_____________________________________________________________________________
274 AliReconstruction::AliReconstruction(const AliReconstruction& rec) :
275   TNamed(rec),
276
277   fUniformField(rec.fUniformField),
278   fRunVertexFinder(rec.fRunVertexFinder),
279   fRunHLTTracking(rec.fRunHLTTracking),
280   fRunMuonTracking(rec.fRunMuonTracking),
281   fRunV0Finder(rec.fRunV0Finder),
282   fRunCascadeFinder(rec.fRunCascadeFinder),
283   fStopOnError(rec.fStopOnError),
284   fWriteAlignmentData(rec.fWriteAlignmentData),
285   fWriteESDfriend(rec.fWriteESDfriend),
286   fWriteAOD(rec.fWriteAOD),
287   fFillTriggerESD(rec.fFillTriggerESD),
288
289   fCleanESD(rec.fCleanESD),
290   fV0DCAmax(rec.fV0DCAmax),
291   fV0CsPmin(rec.fV0CsPmin),
292   fDmax(rec.fDmax),
293   fZmax(rec.fZmax),
294
295   fRunLocalReconstruction(rec.fRunLocalReconstruction),
296   fRunTracking(rec.fRunTracking),
297   fFillESD(rec.fFillESD),
298   fUseTrackingErrorsForAlignment(rec.fUseTrackingErrorsForAlignment),
299   fGAliceFileName(rec.fGAliceFileName),
300   fInput(rec.fInput),
301   fEquipIdMap(rec.fEquipIdMap),
302   fFirstEvent(rec.fFirstEvent),
303   fLastEvent(rec.fLastEvent),
304   fNumberOfEventsPerFile(rec.fNumberOfEventsPerFile),
305   fCheckPointLevel(0),
306   fOptions(),
307   fLoadAlignFromCDB(rec.fLoadAlignFromCDB),
308   fLoadAlignData(rec.fLoadAlignData),
309   fESDPar(rec.fESDPar),
310
311   fRunLoader(NULL),
312   fRawReader(NULL),
313
314   fVertexer(NULL),
315   fDiamondProfile(NULL),
316   fMeanVertexConstraint(rec.fMeanVertexConstraint),
317
318   fGRPList(NULL),
319
320   fAlignObjArray(rec.fAlignObjArray),
321   fCDBUri(rec.fCDBUri),
322   fSpecCDBUri(), 
323   fInitCDBCalled(rec.fInitCDBCalled),
324   fSetRunNumberFromDataCalled(rec.fSetRunNumberFromDataCalled),
325   fRunQA(rec.fRunQA),  
326   fRunGlobalQA(rec.fRunGlobalQA),
327   fInLoopQA(rec.fInLoopQA),
328   fRunPlaneEff(rec.fRunPlaneEff)
329 {
330 // copy constructor
331
332   for (Int_t i = 0; i < rec.fOptions.GetEntriesFast(); i++) {
333     if (rec.fOptions[i]) fOptions.Add(rec.fOptions[i]->Clone());
334   }
335   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
336     fReconstructor[iDet] = NULL;
337     fLoader[iDet] = NULL;
338     fTracker[iDet] = NULL;
339     fQADataMaker[iDet] = NULL;
340         fQACycles[iDet] = rec.fQACycles[iDet];  
341   }
342   fQADataMaker[fgkNDetectors]=NULL;  //Global QA
343   for (Int_t i = 0; i < rec.fSpecCDBUri.GetEntriesFast(); i++) {
344     if (rec.fSpecCDBUri[i]) fSpecCDBUri.Add(rec.fSpecCDBUri[i]->Clone());
345   }
346 }
347
348 //_____________________________________________________________________________
349 AliReconstruction& AliReconstruction::operator = (const AliReconstruction& rec)
350 {
351 // assignment operator
352
353   this->~AliReconstruction();
354   new(this) AliReconstruction(rec);
355   return *this;
356 }
357
358 //_____________________________________________________________________________
359 AliReconstruction::~AliReconstruction()
360 {
361 // clean up
362
363   CleanUp();
364   fOptions.Delete();
365   fSpecCDBUri.Delete();
366
367   AliCodeTimer::Instance()->Print();
368 }
369
370 //_____________________________________________________________________________
371 void AliReconstruction::InitCDB()
372 {
373 // activate a default CDB storage
374 // First check if we have any CDB storage set, because it is used 
375 // to retrieve the calibration and alignment constants
376
377   if (fInitCDBCalled) return;
378   fInitCDBCalled = kTRUE;
379
380   AliCDBManager* man = AliCDBManager::Instance();
381   if (man->IsDefaultStorageSet())
382   {
383     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
384     AliWarning("Default CDB storage has been already set !");
385     AliWarning(Form("Ignoring the default storage declared in AliReconstruction: %s",fCDBUri.Data()));
386     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
387     fCDBUri = man->GetDefaultStorage()->GetURI();
388   }
389   else {
390     if (fCDBUri.Length() > 0) 
391     {
392         AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
393         AliDebug(2, Form("Default CDB storage is set to: %s", fCDBUri.Data()));
394         AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
395     } else {
396         fCDBUri="local://$ALICE_ROOT";
397         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
398         AliWarning("Default CDB storage not yet set !!!!");
399         AliWarning(Form("Setting it now to: %s", fCDBUri.Data()));
400         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
401                 
402     }
403     man->SetDefaultStorage(fCDBUri);
404   }
405
406   // Now activate the detector specific CDB storage locations
407   for (Int_t i = 0; i < fSpecCDBUri.GetEntriesFast(); i++) {
408     TObject* obj = fSpecCDBUri[i];
409     if (!obj) continue;
410     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
411     AliDebug(2, Form("Specific CDB storage for %s is set to: %s",obj->GetName(),obj->GetTitle()));
412     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
413     man->SetSpecificStorage(obj->GetName(), obj->GetTitle());
414   }
415   
416 }
417
418 //_____________________________________________________________________________
419 void AliReconstruction::SetDefaultStorage(const char* uri) {
420 // Store the desired default CDB storage location
421 // Activate it later within the Run() method
422
423   fCDBUri = uri;
424
425 }
426
427 //_____________________________________________________________________________
428 void AliReconstruction::SetSpecificStorage(const char* calibType, const char* uri) {
429 // Store a detector-specific CDB storage location
430 // Activate it later within the Run() method
431
432   AliCDBPath aPath(calibType);
433   if(!aPath.IsValid()){
434         // if calibType is not wildcard but it is a valid detector, add "/*" to make it a valid path
435         for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
436                 if(!strcmp(calibType, fgkDetectorName[iDet])) {
437                         aPath.SetPath(Form("%s/*", calibType));
438                         AliInfo(Form("Path for specific storage set to %s", aPath.GetPath().Data()));
439                         break;
440                 }
441         }
442         if(!aPath.IsValid()){
443                 AliError(Form("Not a valid path or detector: %s", calibType));
444                 return;
445         }
446   }
447
448 //  // check that calibType refers to a "valid" detector name
449 //  Bool_t isDetector = kFALSE;
450 //  for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
451 //    TString detName = fgkDetectorName[iDet];
452 //    if(aPath.GetLevel0() == detName) {
453 //      isDetector = kTRUE;
454 //      break;
455 //    }
456 //  }
457 //
458 //  if(!isDetector) {
459 //      AliError(Form("Not a valid detector: %s", aPath.GetLevel0().Data()));
460 //      return;
461 //  }
462
463   TObject* obj = fSpecCDBUri.FindObject(aPath.GetPath().Data());
464   if (obj) fSpecCDBUri.Remove(obj);
465   fSpecCDBUri.Add(new TNamed(aPath.GetPath().Data(), uri));
466
467 }
468
469 //_____________________________________________________________________________
470 Bool_t AliReconstruction::SetRunNumberFromData()
471 {
472   // The method is called in Run() in order
473   // to set a correct run number.
474   // In case of raw data reconstruction the
475   // run number is taken from the raw data header
476
477   if (fSetRunNumberFromDataCalled) return kTRUE;
478   fSetRunNumberFromDataCalled = kTRUE;
479   
480   AliCDBManager* man = AliCDBManager::Instance();
481   
482   if(man->GetRun() > 0) {
483         AliWarning("Run number is taken from event header! Ignoring settings in AliCDBManager!");
484   } 
485   
486   if (!fRunLoader) {
487       AliError("No run loader is found !"); 
488       return kFALSE;
489     }
490     // read run number from gAlice
491     if(fRunLoader->GetAliRun())
492       AliCDBManager::Instance()->SetRun(fRunLoader->GetHeader()->GetRun());
493     else {
494       if(fRawReader) {
495         if(fRawReader->NextEvent()) {
496           AliCDBManager::Instance()->SetRun(fRawReader->GetRunNumber());
497           fRawReader->RewindEvents();
498         }
499         else {
500           AliError("No raw-data events found !");
501           return kFALSE;
502         }
503       }
504       else {
505         AliError("Neither gAlice nor RawReader objects are found !");
506         return kFALSE;
507       }
508   }
509
510   man->Print();  
511   
512   return kTRUE;
513 }
514
515 //_____________________________________________________________________________
516 void AliReconstruction::SetCDBLock() {
517   // Set CDB lock: from now on it is forbidden to reset the run number
518   // or the default storage or to activate any further storage!
519   
520   AliCDBManager::Instance()->SetLock(1);
521 }
522
523 //_____________________________________________________________________________
524 Bool_t AliReconstruction::MisalignGeometry(const TString& detectors)
525 {
526   // Read the alignment objects from CDB.
527   // Each detector is supposed to have the
528   // alignment objects in DET/Align/Data CDB path.
529   // All the detector objects are then collected,
530   // sorted by geometry level (starting from ALIC) and
531   // then applied to the TGeo geometry.
532   // Finally an overlaps check is performed.
533
534   // Load alignment data from CDB and fill fAlignObjArray 
535   if(fLoadAlignFromCDB){
536         
537     TString detStr = detectors;
538     TString loadAlObjsListOfDets = "";
539     
540     for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
541       if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
542       loadAlObjsListOfDets += fgkDetectorName[iDet];
543       loadAlObjsListOfDets += " ";
544     } // end loop over detectors
545     loadAlObjsListOfDets.Prepend("GRP "); //add alignment objects for non-sensitive modules
546     AliGeomManager::ApplyAlignObjsFromCDB(loadAlObjsListOfDets.Data());
547   }else{
548     // Check if the array with alignment objects was
549     // provided by the user. If yes, apply the objects
550     // to the present TGeo geometry
551     if (fAlignObjArray) {
552       if (gGeoManager && gGeoManager->IsClosed()) {
553         if (AliGeomManager::ApplyAlignObjsToGeom(*fAlignObjArray) == kFALSE) {
554           AliError("The misalignment of one or more volumes failed!"
555                    "Compare the list of simulated detectors and the list of detector alignment data!");
556           return kFALSE;
557         }
558       }
559       else {
560         AliError("Can't apply the misalignment! gGeoManager doesn't exist or it is still opened!");
561         return kFALSE;
562       }
563     }
564   }
565   
566   delete fAlignObjArray; fAlignObjArray=0;
567
568   return kTRUE;
569 }
570
571 //_____________________________________________________________________________
572 void AliReconstruction::SetGAliceFile(const char* fileName)
573 {
574 // set the name of the galice file
575
576   fGAliceFileName = fileName;
577 }
578
579 //_____________________________________________________________________________
580 void AliReconstruction::SetOption(const char* detector, const char* option)
581 {
582 // set options for the reconstruction of a detector
583
584   TObject* obj = fOptions.FindObject(detector);
585   if (obj) fOptions.Remove(obj);
586   fOptions.Add(new TNamed(detector, option));
587 }
588
589
590 //_____________________________________________________________________________
591 Bool_t AliReconstruction::Run(const char* input, Bool_t IsOnline)
592 {
593 // run the reconstruction
594
595   AliCodeTimerAuto("")
596   
597   // set the input
598   if (!IsOnline) {
599     if (!input) input = fInput.Data();
600     TString fileName(input);
601     if (fileName.EndsWith("/")) {
602       fRawReader = new AliRawReaderFile(fileName);
603     } else if (fileName.EndsWith(".root")) {
604       fRawReader = new AliRawReaderRoot(fileName);
605     } else if (!fileName.IsNull()) {
606       fRawReader = new AliRawReaderDate(fileName);
607     }
608   }
609   else {
610     if (!input) {
611       AliError("Null pointer to the event structure!");
612       return kFALSE;
613     }
614     fRawReader = new AliRawReaderDate((void *)input);
615   }
616
617   if (!fEquipIdMap.IsNull() && fRawReader)
618     fRawReader->LoadEquipmentIdsMap(fEquipIdMap);
619
620    AliSysInfo::AddStamp("Start");
621   // get the run loader
622   if (!InitRunLoader()) return kFALSE;
623    AliSysInfo::AddStamp("LoadLoader");
624
625   // Initialize the CDB storage
626   InitCDB();
627   
628   AliSysInfo::AddStamp("LoadCDB");
629
630   // Set run number in CDBManager (if it is not already set by the user)
631   if (!SetRunNumberFromData()) if (fStopOnError) return kFALSE;
632   
633   // Set CDB lock: from now on it is forbidden to reset the run number
634   // or the default storage or to activate any further storage!
635   SetCDBLock();
636   
637   // Import ideal TGeo geometry and apply misalignment
638   if (!gGeoManager) {
639     TString geom(gSystem->DirName(fGAliceFileName));
640     geom += "/geometry.root";
641     AliGeomManager::LoadGeometry(geom.Data());
642     if (!gGeoManager) if (fStopOnError) return kFALSE;
643   }
644
645   if (!MisalignGeometry(fLoadAlignData)) if (fStopOnError) return kFALSE;
646    AliSysInfo::AddStamp("LoadGeom");
647
648   //QA 
649   AliQADataMakerSteer qas ; 
650   if (fRunQA && fRawReader) qas.Run(fRunLocalReconstruction, fRawReader) ; 
651   // checking the QA of previous steps
652   //CheckQA() ; 
653  
654   /*
655   // local reconstruction
656   if (!fRunLocalReconstruction.IsNull()) {
657     if (!RunLocalReconstruction(fRunLocalReconstruction)) {
658       if (fStopOnError) {CleanUp(); return kFALSE;}
659     }
660   }
661   */
662
663   // get vertexer
664   if (fRunVertexFinder && !CreateVertexer()) {
665     if (fStopOnError) {
666       CleanUp(); 
667       return kFALSE;
668     }
669   }
670    AliSysInfo::AddStamp("Vertexer");
671
672   // get trackers
673   if (!fRunTracking.IsNull() && !CreateTrackers(fRunTracking)) {
674     if (fStopOnError) {
675       CleanUp(); 
676       return kFALSE;
677     }      
678   }
679    AliSysInfo::AddStamp("LoadTrackers");
680
681   // get the possibly already existing ESD file and tree
682   AliESDEvent* esd = new AliESDEvent(); AliESDEvent* hltesd = new AliESDEvent();
683   TFile* fileOld = NULL;
684   TTree* treeOld = NULL; TTree *hlttreeOld = NULL;
685   if (!gSystem->AccessPathName("AliESDs.root")){
686     gSystem->CopyFile("AliESDs.root", "AliESDs.old.root", kTRUE);
687     fileOld = TFile::Open("AliESDs.old.root");
688     if (fileOld && fileOld->IsOpen()) {
689       treeOld = (TTree*) fileOld->Get("esdTree");
690       if (treeOld)esd->ReadFromTree(treeOld);
691       hlttreeOld = (TTree*) fileOld->Get("HLTesdTree");
692       if (hlttreeOld)   hltesd->ReadFromTree(hlttreeOld);
693     }
694   }
695
696   // create the ESD output file and tree
697   TFile* file = TFile::Open("AliESDs.root", "RECREATE");
698   file->SetCompressionLevel(2);
699   if (!file->IsOpen()) {
700     AliError("opening AliESDs.root failed");
701     if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}    
702   }
703
704   TTree* tree = new TTree("esdTree", "Tree with ESD objects");
705   esd = new AliESDEvent();
706   esd->CreateStdContent();
707   esd->WriteToTree(tree);
708
709   TTree* hlttree = new TTree("HLTesdTree", "Tree with HLT ESD objects");
710   hltesd = new AliESDEvent();
711   hltesd->CreateStdContent();
712   hltesd->WriteToTree(hlttree);
713
714   /* CKB Why?
715   delete esd; delete hltesd;
716   esd = NULL; hltesd = NULL;
717   */
718   // create the branch with ESD additions
719
720
721
722   AliESDfriend *esdf = 0; 
723   if (fWriteESDfriend) {
724     esdf = new AliESDfriend();
725     TBranch *br=tree->Branch("ESDfriend.","AliESDfriend", &esdf);
726     br->SetFile("AliESDfriends.root");
727     esd->AddObject(esdf);
728   }
729
730   
731   // Get the GRP CDB entry
732   AliCDBEntry* entryGRP = AliCDBManager::Instance()->Get("GRP/GRP/Data");
733         
734   if(entryGRP) {
735         fGRPList = dynamic_cast<TList*> (entryGRP->GetObject());  
736   } else {
737         AliError("No GRP entry found in OCDB!");
738   }
739
740   // Get the diamond profile from OCDB
741   AliCDBEntry* entry = AliCDBManager::Instance()
742         ->Get("GRP/Calib/MeanVertex");
743         
744   if(entry) {
745         fDiamondProfile = dynamic_cast<AliESDVertex*> (entry->GetObject());  
746   } else {
747         AliError("No diamond profile found in OCDB!");
748   }
749
750   AliVertexerTracks tVertexer(AliTracker::GetBz());
751   if(fDiamondProfile && fMeanVertexConstraint) tVertexer.SetVtxStart(fDiamondProfile);
752
753   if (fRawReader) fRawReader->RewindEvents();
754
755   ProcInfo_t ProcInfo;
756   gSystem->GetProcInfo(&ProcInfo);
757   AliInfo(Form("Current memory usage %d %d", ProcInfo.fMemResident, ProcInfo.fMemVirtual));
758   
759
760   //Initialize the QA and start of cycle for out-of-cycle QA
761   if (fRunQA) {
762      TString detStr(fFillESD); 
763      for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
764         if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
765         AliQADataMakerRec *qadm = GetQADataMaker(iDet);  
766         if (!qadm) continue;
767         AliInfo(Form("Initializing the QA data maker for %s", 
768                fgkDetectorName[iDet]));
769         qadm->Init(AliQA::kRECPOINTS, AliCDBManager::Instance()->GetRun());
770         qadm->Init(AliQA::kESDS, AliCDBManager::Instance()->GetRun());
771         if (!fInLoopQA) {
772            qadm->StartOfCycle(AliQA::kRECPOINTS);
773            qadm->StartOfCycle(AliQA::kESDS,"same");
774         }
775      }
776      if (fRunGlobalQA) {
777         AliQADataMakerRec *qadm = GetQADataMaker(fgkNDetectors);
778         AliInfo(Form("Initializing the global QA data maker"));
779         TObjArray *arr=
780           qadm->Init(AliQA::kRECPOINTS, AliCDBManager::Instance()->GetRun());
781         AliTracker::SetResidualsArray(arr);
782         if (!fInLoopQA) {
783            qadm->StartOfCycle(AliQA::kRECPOINTS);
784         }
785      }
786   }
787
788   //Initialize the Plane Efficiency framework
789   if (fRunPlaneEff && !InitPlaneEff()) {
790     if(fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
791   }
792
793   //******* The loop over events
794   for (Int_t iEvent = 0; iEvent < fRunLoader->GetNumberOfEvents(); iEvent++) {
795     if (fRawReader) fRawReader->NextEvent();
796     if ((iEvent < fFirstEvent) || ((fLastEvent >= 0) && (iEvent > fLastEvent))) {
797       // copy old ESD to the new one
798       if (treeOld) {
799         esd->ReadFromTree(treeOld);
800         treeOld->GetEntry(iEvent);
801       }
802       tree->Fill();
803       if (hlttreeOld) {
804         esd->ReadFromTree(hlttreeOld);
805         hlttreeOld->GetEntry(iEvent);
806       }
807       hlttree->Fill();
808       continue;
809     }
810     
811     AliInfo(Form("processing event %d", iEvent));
812
813     //Start of cycle for the in-loop QA
814     if (fRunQA && fInLoopQA) {
815        TString detStr(fFillESD); 
816        for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
817           if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
818           AliQADataMakerRec *qadm = GetQADataMaker(iDet);  
819           if (!qadm) continue;
820           qadm->StartOfCycle(AliQA::kRECPOINTS);
821           qadm->StartOfCycle(AliQA::kESDS, "same") ;    
822        }
823        if (fRunGlobalQA) {
824           AliQADataMakerRec *qadm = GetQADataMaker(fgkNDetectors);
825           qadm->StartOfCycle(AliQA::kRECPOINTS);
826        }
827     }
828
829     fRunLoader->GetEvent(iEvent);
830
831     char aFileName[256];
832     sprintf(aFileName, "ESD_%d.%d_final.root", 
833             fRunLoader->GetHeader()->GetRun(), 
834             fRunLoader->GetHeader()->GetEventNrInRun());
835     if (!gSystem->AccessPathName(aFileName)) continue;
836
837     // local signle event reconstruction
838     if (!fRunLocalReconstruction.IsNull()) {
839       if (!RunLocalEventReconstruction(fRunLocalReconstruction)) {
840         if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
841       }
842     }
843
844     esd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
845     hltesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
846     esd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
847     hltesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
848     
849     // Set magnetic field from the tracker
850     esd->SetMagneticField(AliTracker::GetBz());
851     hltesd->SetMagneticField(AliTracker::GetBz());
852
853     
854     
855     // Fill raw-data error log into the ESD
856     if (fRawReader) FillRawDataErrorLog(iEvent,esd);
857
858     // vertex finder
859     if (fRunVertexFinder) {
860       if (!ReadESD(esd, "vertex")) {
861         if (!RunVertexFinder(esd)) {
862           if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
863         }
864         if (fCheckPointLevel > 0) WriteESD(esd, "vertex");
865       }
866     }
867
868     // HLT tracking
869     if (!fRunTracking.IsNull()) {
870       if (fRunHLTTracking) {
871         hltesd->SetVertex(esd->GetVertex());
872         if (!RunHLTTracking(hltesd)) {
873           if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
874         }
875       }
876     }
877
878     // Muon tracking
879     if (!fRunTracking.IsNull()) {
880       if (fRunMuonTracking) {
881         if (!RunMuonTracking(esd)) {
882           if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
883         }
884       }
885     }
886
887     // barrel tracking
888     if (!fRunTracking.IsNull()) {
889       if (!ReadESD(esd, "tracking")) {
890         if (!RunTracking(esd)) {
891           if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
892         }
893         if (fCheckPointLevel > 0) WriteESD(esd, "tracking");
894       }
895     }
896
897     // fill ESD
898     if (!fFillESD.IsNull()) {
899       if (!FillESD(esd, fFillESD)) {
900         if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
901       }
902     }
903   
904     // fill Event header information from the RawEventHeader
905     if (fRawReader){FillRawEventHeaderESD(esd);}
906
907     // combined PID
908     AliESDpid::MakePID(esd);
909     if (fCheckPointLevel > 1) WriteESD(esd, "PID");
910
911     if (fFillTriggerESD) {
912       if (!ReadESD(esd, "trigger")) {
913         if (!FillTriggerESD(esd)) {
914           if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
915         }
916         if (fCheckPointLevel > 1) WriteESD(esd, "trigger");
917       }
918     }
919
920     file->cd();
921
922     //Try to improve the reconstructed primary vertex position using the tracks
923     AliESDVertex *pvtx=0;
924     Bool_t dovertex=kTRUE;
925     TObject* obj = fOptions.FindObject("ITS");
926     if (obj) {
927       TString optITS = obj->GetTitle();
928       if (optITS.Contains("cosmics") || optITS.Contains("COSMICS")) 
929         dovertex=kFALSE;
930     }
931     if(dovertex) pvtx=tVertexer.FindPrimaryVertex(esd);
932     if(fDiamondProfile) esd->SetDiamond(fDiamondProfile);
933     
934     if (pvtx)
935     if (pvtx->GetStatus()) {
936        // Store the improved primary vertex
937        esd->SetPrimaryVertex(pvtx);
938        // Propagate the tracks to the DCA to the improved primary vertex
939        Double_t somethingbig = 777.;
940        Double_t bz = esd->GetMagneticField();
941        Int_t nt=esd->GetNumberOfTracks();
942        while (nt--) {
943          AliESDtrack *t = esd->GetTrack(nt);
944          t->RelateToVertex(pvtx, bz, somethingbig);
945        } 
946     }
947
948     if (fRunV0Finder) {
949        // V0 finding
950        AliV0vertexer vtxer;
951        vtxer.Tracks2V0vertices(esd);
952
953        if (fRunCascadeFinder) {
954           // Cascade finding
955           AliCascadeVertexer cvtxer;
956           cvtxer.V0sTracks2CascadeVertices(esd);
957        }
958     }
959  
960     // write ESD
961     if (fCleanESD) CleanESD(esd);
962     if (fWriteESDfriend) {
963       esdf->~AliESDfriend();
964       new (esdf) AliESDfriend(); // Reset...
965       esd->GetESDfriend(esdf);
966     }
967     tree->Fill();
968
969     // write HLT ESD
970     hlttree->Fill();
971
972     if (fCheckPointLevel > 0)  WriteESD(esd, "final"); 
973     esd->Reset();
974     hltesd->Reset();
975     if (fWriteESDfriend) {
976       esdf->~AliESDfriend();
977       new (esdf) AliESDfriend(); // Reset...
978     }
979  
980     gSystem->GetProcInfo(&ProcInfo);
981     AliInfo(Form("Event %d -> Current memory usage %d %d",iEvent, ProcInfo.fMemResident, ProcInfo.fMemVirtual));
982   
983
984   // End of cycle for the in-loop QA
985      if (fRunQA && fInLoopQA) {
986         RunQA(fFillESD.Data(), esd);
987         TString detStr(fFillESD); 
988         for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
989            if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
990            AliQADataMakerRec * qadm = GetQADataMaker(iDet);
991            if (!qadm) continue;
992            qadm->EndOfCycle(AliQA::kRECPOINTS);
993            qadm->EndOfCycle(AliQA::kESDS);
994            qadm->Finish();
995         }
996         if (fRunGlobalQA) {
997            AliQADataMakerRec *qadm = GetQADataMaker(fgkNDetectors);
998            if (qadm) {
999               qadm->EndOfCycle(AliQA::kRECPOINTS);
1000               qadm->Finish();
1001            }
1002         }
1003      }
1004   } 
1005   //******** End of the loop over events 
1006
1007
1008
1009   tree->GetUserInfo()->Add(esd);
1010   hlttree->GetUserInfo()->Add(hltesd);
1011   
1012   const TMap *cdbMap = AliCDBManager::Instance()->GetStorageMap();       
1013   const TList *cdbList = AliCDBManager::Instance()->GetRetrievedIds();   
1014                  
1015    TMap *cdbMapCopy = new TMap(cdbMap->GetEntries());    
1016    cdbMapCopy->SetOwner(1);      
1017    cdbMapCopy->SetName("cdbMap");        
1018    TIter iter(cdbMap->GetTable());       
1019          
1020    TPair* pair = 0;      
1021    while((pair = dynamic_cast<TPair*> (iter.Next()))){   
1022          TObjString* keyStr = dynamic_cast<TObjString*> (pair->Key());   
1023          TObjString* valStr = dynamic_cast<TObjString*> (pair->Value());         
1024          cdbMapCopy->Add(new TObjString(keyStr->GetName()), new TObjString(valStr->GetName()));  
1025    }     
1026          
1027    TList *cdbListCopy = new TList();     
1028    cdbListCopy->SetOwner(1);     
1029    cdbListCopy->SetName("cdbList");      
1030          
1031    TIter iter2(cdbList);         
1032          
1033    AliCDBId* id=0;       
1034    while((id = dynamic_cast<AliCDBId*> (iter2.Next()))){         
1035          cdbListCopy->Add(new TObjString(id->ToString().Data()));        
1036    }     
1037          
1038    tree->GetUserInfo()->Add(cdbMapCopy);         
1039    tree->GetUserInfo()->Add(cdbListCopy);
1040
1041
1042   if(fESDPar.Contains("ESD.par")){
1043     AliInfo("Attaching ESD.par to Tree");
1044     TNamed *fn = CopyFileToTNamed(fESDPar.Data(),"ESD.par");
1045     tree->GetUserInfo()->Add(fn);
1046   }
1047
1048
1049   file->cd();
1050
1051   if (fWriteESDfriend)
1052     tree->SetBranchStatus("ESDfriend*",0);
1053   // we want to have only one tree version number
1054   tree->Write(tree->GetName(),TObject::kOverwrite);
1055   hlttree->Write();
1056
1057 // Finish with Plane Efficiency evaluation: before of CleanUp !!!
1058   if (fRunPlaneEff && !FinishPlaneEff()) {
1059    AliWarning("Finish PlaneEff evaluation failed");
1060   }
1061
1062   gROOT->cd();
1063   CleanUp(file, fileOld);
1064     
1065   if (fWriteAOD) {
1066     TFile *esdFile = TFile::Open("AliESDs.root", "READONLY");
1067     TFile *aodFile = TFile::Open("AliAOD.root", "RECREATE");
1068     ESDFile2AODFile(esdFile, aodFile);
1069     aodFile->Close();
1070     esdFile->Close();
1071   }
1072
1073   // Create tags for the events in the ESD tree (the ESD tree is always present)
1074   // In case of empty events the tags will contain dummy values
1075   AliESDTagCreator *esdtagCreator = new AliESDTagCreator();
1076   esdtagCreator->CreateESDTags(fFirstEvent,fLastEvent,fGRPList);
1077   if (fWriteAOD) {
1078     AliAODTagCreator *aodtagCreator = new AliAODTagCreator();
1079     aodtagCreator->CreateAODTags(fFirstEvent,fLastEvent,fGRPList);
1080   }
1081
1082   //Finish QA and end of cycle for out-of-loop QA
1083   if (fRunQA && !fInLoopQA) {
1084      qas.Run(fRunLocalReconstruction.Data(), AliQA::kRECPOINTS);
1085      //qas.Reset() ;
1086      qas.Run(fRunTracking.Data(), AliQA::kESDS);
1087
1088      if (fRunGlobalQA) {
1089         AliQADataMakerRec *qadm = GetQADataMaker(fgkNDetectors);
1090         if (qadm) {
1091            qadm->EndOfCycle(AliQA::kRECPOINTS);
1092            qadm->Finish();
1093         }
1094      }
1095   }
1096   
1097   // Cleanup of CDB manager: cache and active storages!
1098   AliCDBManager::Instance()->ClearCache();
1099   
1100   
1101   return kTRUE;
1102 }
1103
1104
1105 //_____________________________________________________________________________
1106 Bool_t AliReconstruction::RunLocalReconstruction(const TString& /*detectors*/)
1107 {
1108 // run the local reconstruction
1109   static Int_t eventNr=0;
1110   AliCodeTimerAuto("")
1111
1112  //  AliCDBManager* man = AliCDBManager::Instance();
1113 //   Bool_t origCache = man->GetCacheFlag();
1114
1115 //   TString detStr = detectors;
1116 //   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1117 //     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1118 //     AliReconstructor* reconstructor = GetReconstructor(iDet);
1119 //     if (!reconstructor) continue;
1120 //     if (reconstructor->HasLocalReconstruction()) continue;
1121
1122 //     AliCodeTimerStart(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1123 //     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1124     
1125 //     AliCodeTimerStart(Form("Loading calibration data from OCDB for %s", fgkDetectorName[iDet]));                          
1126 //     AliInfo(Form("Loading calibration data from OCDB for %s", fgkDetectorName[iDet]));
1127
1128 //     man->SetCacheFlag(kTRUE);
1129 //     TString calibPath = Form("%s/Calib/*", fgkDetectorName[iDet]);
1130 //     man->GetAll(calibPath); // entries are cached!
1131
1132 //     AliCodeTimerStop(Form("Loading calibration data from OCDB for %s", fgkDetectorName[iDet]));
1133      
1134 //     if (fRawReader) {
1135 //       fRawReader->RewindEvents();
1136 //       reconstructor->Reconstruct(fRunLoader, fRawReader);
1137 //     } else {
1138 //       reconstructor->Reconstruct(fRunLoader);
1139 //     }
1140      
1141 //      AliCodeTimerStop(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1142     // AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr));
1143
1144 //     // unload calibration data
1145 //     man->UnloadFromCache(calibPath);
1146 //     //man->ClearCache();
1147 //   }
1148
1149 //   man->SetCacheFlag(origCache);
1150
1151 //   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1152 //     AliError(Form("the following detectors were not found: %s",
1153 //                   detStr.Data()));
1154 //     if (fStopOnError) return kFALSE;
1155 //   }
1156
1157           eventNr++;
1158   return kTRUE;
1159 }
1160
1161 //_____________________________________________________________________________
1162 Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
1163 {
1164 // run the local reconstruction
1165
1166   static Int_t eventNr=0;
1167   AliCodeTimerAuto("")
1168
1169   TString detStr = detectors;
1170   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1171     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1172     AliReconstructor* reconstructor = GetReconstructor(iDet);
1173     if (!reconstructor) continue;
1174     AliLoader* loader = fLoader[iDet];
1175     if (!loader) {
1176       AliWarning(Form("No loader is defined for %s!",fgkDetectorName[iDet]));
1177       continue;
1178     }
1179     // conversion of digits
1180     if (fRawReader && reconstructor->HasDigitConversion()) {
1181       AliInfo(Form("converting raw data digits into root objects for %s", 
1182                    fgkDetectorName[iDet]));
1183       AliCodeTimerAuto(Form("converting raw data digits into root objects for %s", 
1184                             fgkDetectorName[iDet]));
1185       loader->LoadDigits("update");
1186       loader->CleanDigits();
1187       loader->MakeDigitsContainer();
1188       TTree* digitsTree = loader->TreeD();
1189       reconstructor->ConvertDigits(fRawReader, digitsTree);
1190       loader->WriteDigits("OVERWRITE");
1191       loader->UnloadDigits();
1192     }
1193     // local reconstruction
1194     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1195     AliCodeTimerAuto(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1196     loader->LoadRecPoints("update");
1197     loader->CleanRecPoints();
1198     loader->MakeRecPointsContainer();
1199     TTree* clustersTree = loader->TreeR();
1200     if (fRawReader && !reconstructor->HasDigitConversion()) {
1201       reconstructor->Reconstruct(fRawReader, clustersTree);
1202     } else {
1203       loader->LoadDigits("read");
1204       TTree* digitsTree = loader->TreeD();
1205       if (!digitsTree) {
1206         AliError(Form("Can't get the %s digits tree", fgkDetectorName[iDet]));
1207         if (fStopOnError) return kFALSE;
1208       } else {
1209         reconstructor->Reconstruct(digitsTree, clustersTree);
1210       }
1211       loader->UnloadDigits();
1212     }
1213
1214     // In-loop QA for local reconstrucion 
1215     if (fRunQA && fInLoopQA) {
1216        AliQADataMakerRec * qadm = GetQADataMaker(iDet);
1217        if (qadm) {
1218           //AliCodeTimerStart
1219           //(Form("Running QA data maker for %s", fgkDetectorName[iDet]));
1220           //AliInfo
1221           //(Form("Running QA data maker for %s", fgkDetectorName[iDet]));
1222
1223           qadm->Exec(AliQA::kRECPOINTS, clustersTree) ;
1224  
1225           //AliCodeTimerStop
1226           //(Form("Running QA data maker for %s", fgkDetectorName[iDet]));
1227        }
1228     }
1229
1230     loader->WriteRecPoints("OVERWRITE");
1231     loader->UnloadRecPoints();
1232     AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr), iDet,1,eventNr);
1233   }
1234
1235   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1236     AliError(Form("the following detectors were not found: %s",
1237                   detStr.Data()));
1238     if (fStopOnError) return kFALSE;
1239   }
1240   eventNr++;
1241   return kTRUE;
1242 }
1243
1244 //_____________________________________________________________________________
1245 Bool_t AliReconstruction::RunVertexFinder(AliESDEvent*& esd)
1246 {
1247 // run the barrel tracking
1248
1249   AliCodeTimerAuto("")
1250
1251   AliESDVertex* vertex = NULL;
1252   Double_t vtxPos[3] = {0, 0, 0};
1253   Double_t vtxErr[3] = {0.07, 0.07, 0.1};
1254   TArrayF mcVertex(3); 
1255   if (fRunLoader->GetHeader() && fRunLoader->GetHeader()->GenEventHeader()) {
1256     fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(mcVertex);
1257     for (Int_t i = 0; i < 3; i++) vtxPos[i] = mcVertex[i];
1258   }
1259
1260   if (fVertexer) {
1261     if(fDiamondProfile) fVertexer->SetVtxStart(fDiamondProfile);
1262     AliInfo("running the ITS vertex finder");
1263     if (fLoader[0]) fLoader[0]->LoadRecPoints();
1264     vertex = fVertexer->FindVertexForCurrentEvent(fRunLoader->GetEventNumber());
1265     if (fLoader[0]) fLoader[0]->UnloadRecPoints();
1266     if(!vertex){
1267       AliWarning("Vertex not found");
1268       vertex = new AliESDVertex();
1269       vertex->SetName("default");
1270     }
1271     else {
1272       vertex->SetName("reconstructed");
1273     }
1274
1275   } else {
1276     AliInfo("getting the primary vertex from MC");
1277     vertex = new AliESDVertex(vtxPos, vtxErr);
1278   }
1279
1280   if (vertex) {
1281     vertex->GetXYZ(vtxPos);
1282     vertex->GetSigmaXYZ(vtxErr);
1283   } else {
1284     AliWarning("no vertex reconstructed");
1285     vertex = new AliESDVertex(vtxPos, vtxErr);
1286   }
1287   esd->SetVertex(vertex);
1288   // if SPD multiplicity has been determined, it is stored in the ESD
1289   AliMultiplicity *mult = fVertexer->GetMultiplicity();
1290   if(mult)esd->SetMultiplicity(mult);
1291
1292   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1293     if (fTracker[iDet]) fTracker[iDet]->SetVertex(vtxPos, vtxErr);
1294   }  
1295   delete vertex;
1296
1297   return kTRUE;
1298 }
1299
1300 //_____________________________________________________________________________
1301 Bool_t AliReconstruction::RunHLTTracking(AliESDEvent*& esd)
1302 {
1303 // run the HLT barrel tracking
1304
1305   AliCodeTimerAuto("")
1306
1307   if (!fRunLoader) {
1308     AliError("Missing runLoader!");
1309     return kFALSE;
1310   }
1311
1312   AliInfo("running HLT tracking");
1313
1314   // Get a pointer to the HLT reconstructor
1315   AliReconstructor *reconstructor = GetReconstructor(fgkNDetectors-1);
1316   if (!reconstructor) return kFALSE;
1317
1318   // TPC + ITS
1319   for (Int_t iDet = 1; iDet >= 0; iDet--) {
1320     TString detName = fgkDetectorName[iDet];
1321     AliDebug(1, Form("%s HLT tracking", detName.Data()));
1322     reconstructor->SetOption(detName.Data());
1323     AliTracker *tracker = reconstructor->CreateTracker();
1324     if (!tracker) {
1325       AliWarning(Form("couldn't create a HLT tracker for %s", detName.Data()));
1326       if (fStopOnError) return kFALSE;
1327       continue;
1328     }
1329     Double_t vtxPos[3];
1330     Double_t vtxErr[3]={0.005,0.005,0.010};
1331     const AliESDVertex *vertex = esd->GetVertex();
1332     vertex->GetXYZ(vtxPos);
1333     tracker->SetVertex(vtxPos,vtxErr);
1334     if(iDet != 1) {
1335       fLoader[iDet]->LoadRecPoints("read");
1336       TTree* tree = fLoader[iDet]->TreeR();
1337       if (!tree) {
1338         AliError(Form("Can't get the %s cluster tree", detName.Data()));
1339         return kFALSE;
1340       }
1341       tracker->LoadClusters(tree);
1342     }
1343     if (tracker->Clusters2Tracks(esd) != 0) {
1344       AliError(Form("HLT %s Clusters2Tracks failed", fgkDetectorName[iDet]));
1345       return kFALSE;
1346     }
1347     if(iDet != 1) {
1348       tracker->UnloadClusters();
1349     }
1350     delete tracker;
1351   }
1352
1353   return kTRUE;
1354 }
1355
1356 //_____________________________________________________________________________
1357 Bool_t AliReconstruction::RunMuonTracking(AliESDEvent*& esd)
1358 {
1359 // run the muon spectrometer tracking
1360
1361   AliCodeTimerAuto("")
1362
1363   if (!fRunLoader) {
1364     AliError("Missing runLoader!");
1365     return kFALSE;
1366   }
1367   Int_t iDet = 7; // for MUON
1368
1369   AliInfo("is running...");
1370
1371   // Get a pointer to the MUON reconstructor
1372   AliReconstructor *reconstructor = GetReconstructor(iDet);
1373   if (!reconstructor) return kFALSE;
1374
1375   
1376   TString detName = fgkDetectorName[iDet];
1377   AliDebug(1, Form("%s tracking", detName.Data()));
1378   AliTracker *tracker =  reconstructor->CreateTracker();
1379   if (!tracker) {
1380     AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
1381     return kFALSE;
1382   }
1383      
1384   // read RecPoints
1385   fLoader[iDet]->LoadRecPoints("read");  
1386
1387   tracker->LoadClusters(fLoader[iDet]->TreeR());
1388   
1389   Int_t rv = tracker->Clusters2Tracks(esd);
1390   
1391   if ( rv )
1392   {
1393     AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
1394     return kFALSE;
1395   }
1396   
1397   fLoader[iDet]->UnloadRecPoints();
1398
1399   tracker->UnloadClusters();
1400   
1401   delete tracker;
1402   
1403   return kTRUE;
1404 }
1405
1406
1407 //_____________________________________________________________________________
1408 Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd)
1409 {
1410 // run the barrel tracking
1411   static Int_t eventNr=0;
1412   AliCodeTimerAuto("")
1413
1414   AliInfo("running tracking");
1415
1416   //Fill the ESD with the T0 info (will be used by the TOF) 
1417   if (fReconstructor[11] && fLoader[11]) {
1418     fLoader[11]->LoadRecPoints("READ");
1419     TTree *treeR = fLoader[11]->TreeR();
1420     GetReconstructor(11)->FillESD((TTree *)NULL,treeR,esd);
1421   }
1422
1423   // pass 1: TPC + ITS inwards
1424   for (Int_t iDet = 1; iDet >= 0; iDet--) {
1425     if (!fTracker[iDet]) continue;
1426     AliDebug(1, Form("%s tracking", fgkDetectorName[iDet]));
1427
1428     // load clusters
1429     fLoader[iDet]->LoadRecPoints("read");
1430     AliSysInfo::AddStamp(Form("RLoadCluster%s_%d",fgkDetectorName[iDet],eventNr),iDet,1, eventNr);
1431     TTree* tree = fLoader[iDet]->TreeR();
1432     if (!tree) {
1433       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
1434       return kFALSE;
1435     }
1436     fTracker[iDet]->LoadClusters(tree);
1437     AliSysInfo::AddStamp(Form("TLoadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
1438     // run tracking
1439     if (fTracker[iDet]->Clusters2Tracks(esd) != 0) {
1440       AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
1441       return kFALSE;
1442     }
1443     if (fCheckPointLevel > 1) {
1444       WriteESD(esd, Form("%s.tracking", fgkDetectorName[iDet]));
1445     }
1446     // preliminary PID in TPC needed by the ITS tracker
1447     if (iDet == 1) {
1448       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
1449       AliESDpid::MakePID(esd);
1450     } 
1451     AliSysInfo::AddStamp(Form("Tracking0%s_%d",fgkDetectorName[iDet],eventNr), iDet,3,eventNr);
1452   }
1453
1454   // pass 2: ALL backwards
1455
1456   if (fRunQA && fRunGlobalQA) AliTracker::SetFillResiduals(kTRUE);     
1457
1458   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1459     if (!fTracker[iDet]) continue;
1460     AliDebug(1, Form("%s back propagation", fgkDetectorName[iDet]));
1461
1462     // load clusters
1463     if (iDet > 1) {     // all except ITS, TPC
1464       TTree* tree = NULL;
1465       fLoader[iDet]->LoadRecPoints("read");
1466       AliSysInfo::AddStamp(Form("RLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,1, eventNr);
1467       tree = fLoader[iDet]->TreeR();
1468       if (!tree) {
1469         AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
1470         return kFALSE;
1471       }
1472       fTracker[iDet]->LoadClusters(tree); 
1473       AliSysInfo::AddStamp(Form("TLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
1474     }
1475
1476     // run tracking
1477     if (fTracker[iDet]->PropagateBack(esd) != 0) {
1478       AliError(Form("%s backward propagation failed", fgkDetectorName[iDet]));
1479       //      return kFALSE;
1480     }
1481     if (fCheckPointLevel > 1) {
1482       WriteESD(esd, Form("%s.back", fgkDetectorName[iDet]));
1483     }
1484
1485     // unload clusters
1486     if (iDet > 2) {     // all except ITS, TPC, TRD
1487       fTracker[iDet]->UnloadClusters();
1488       fLoader[iDet]->UnloadRecPoints();
1489     }
1490     // updated PID in TPC needed by the ITS tracker -MI
1491     if (iDet == 1) {
1492       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
1493       AliESDpid::MakePID(esd);
1494     }
1495     AliSysInfo::AddStamp(Form("Tracking1%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
1496   }
1497
1498   if (fRunQA && fRunGlobalQA) AliTracker::SetFillResiduals(kFALSE);     
1499
1500   // write space-points to the ESD in case alignment data output
1501   // is switched on
1502   if (fWriteAlignmentData)
1503     WriteAlignmentData(esd);
1504
1505   // pass 3: TRD + TPC + ITS refit inwards
1506
1507
1508   for (Int_t iDet = 2; iDet >= 0; iDet--) {
1509     if (!fTracker[iDet]) continue;
1510     AliDebug(1, Form("%s inward refit", fgkDetectorName[iDet]));
1511
1512     // run tracking
1513     if (fTracker[iDet]->RefitInward(esd) != 0) {
1514       AliError(Form("%s inward refit failed", fgkDetectorName[iDet]));
1515       //      return kFALSE;
1516     }
1517     // run postprocessing
1518     if (fTracker[iDet]->PostProcess(esd) != 0) {
1519       AliError(Form("%s postprocessing failed", fgkDetectorName[iDet]));
1520       //      return kFALSE;
1521     }
1522     if (fCheckPointLevel > 1) {
1523       WriteESD(esd, Form("%s.refit", fgkDetectorName[iDet]));
1524     }
1525     AliSysInfo::AddStamp(Form("Tracking2%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
1526     // unload clusters
1527     fTracker[iDet]->UnloadClusters();
1528     AliSysInfo::AddStamp(Form("TUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,4, eventNr);
1529     fLoader[iDet]->UnloadRecPoints();
1530     AliSysInfo::AddStamp(Form("RUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,5, eventNr);
1531   }
1532
1533   //
1534   // Propagate track to the vertex - if not done by ITS
1535   //
1536   Int_t ntracks = esd->GetNumberOfTracks();
1537   for (Int_t itrack=0; itrack<ntracks; itrack++){
1538     const Double_t kRadius  = 3;   // beam pipe radius
1539     const Double_t kMaxStep = 5;   // max step
1540     const Double_t kMaxD    = 123456;  // max distance to prim vertex
1541     Double_t       fieldZ   = AliTracker::GetBz();  //
1542     AliESDtrack * track = esd->GetTrack(itrack);
1543     if (!track) continue;
1544     if (track->IsOn(AliESDtrack::kITSrefit)) continue;
1545    AliTracker::PropagateTrackTo(track,kRadius,track->GetMass(),kMaxStep,kTRUE);
1546     track->RelateToVertex(esd->GetVertex(),fieldZ, kMaxD);
1547   }
1548   eventNr++;
1549   return kTRUE;
1550 }
1551
1552 //_____________________________________________________________________________
1553 Bool_t AliReconstruction::CleanESD(AliESDEvent *esd){
1554   //
1555   // Remove the data which are not needed for the physics analysis.
1556   //
1557
1558   Int_t nTracks=esd->GetNumberOfTracks();
1559   Int_t nV0s=esd->GetNumberOfV0s();
1560   AliInfo
1561   (Form("Number of ESD tracks and V0s before cleaning: %d %d",nTracks,nV0s));
1562
1563   Float_t cleanPars[]={fV0DCAmax,fV0CsPmin,fDmax,fZmax};
1564   Bool_t rc=esd->Clean(cleanPars);
1565
1566   nTracks=esd->GetNumberOfTracks();
1567   nV0s=esd->GetNumberOfV0s();
1568   AliInfo
1569   (Form("Number of ESD tracks and V0s after cleaning %d %d",nTracks,nV0s));
1570
1571   return rc;
1572 }
1573
1574 //_____________________________________________________________________________
1575 Bool_t AliReconstruction::FillESD(AliESDEvent*& esd, const TString& detectors)
1576 {
1577 // fill the event summary data
1578
1579   AliCodeTimerAuto("")
1580     static Int_t eventNr=0; 
1581   TString detStr = detectors;
1582   
1583   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1584   if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1585     AliReconstructor* reconstructor = GetReconstructor(iDet);
1586     if (!reconstructor) continue;
1587     if (!ReadESD(esd, fgkDetectorName[iDet])) {
1588       AliDebug(1, Form("filling ESD for %s", fgkDetectorName[iDet]));
1589       TTree* clustersTree = NULL;
1590       if (fLoader[iDet]) {
1591         fLoader[iDet]->LoadRecPoints("read");
1592         clustersTree = fLoader[iDet]->TreeR();
1593         if (!clustersTree) {
1594           AliError(Form("Can't get the %s clusters tree", 
1595                         fgkDetectorName[iDet]));
1596           if (fStopOnError) return kFALSE;
1597         }
1598       }
1599       if (fRawReader && !reconstructor->HasDigitConversion()) {
1600         reconstructor->FillESD(fRawReader, clustersTree, esd);
1601       } else {
1602         TTree* digitsTree = NULL;
1603         if (fLoader[iDet]) {
1604           fLoader[iDet]->LoadDigits("read");
1605           digitsTree = fLoader[iDet]->TreeD();
1606           if (!digitsTree) {
1607             AliError(Form("Can't get the %s digits tree", 
1608                           fgkDetectorName[iDet]));
1609             if (fStopOnError) return kFALSE;
1610           }
1611         }
1612         reconstructor->FillESD(digitsTree, clustersTree, esd);
1613         if (fLoader[iDet]) fLoader[iDet]->UnloadDigits();
1614       }
1615       if (fLoader[iDet]) {
1616         fLoader[iDet]->UnloadRecPoints();
1617       }
1618
1619       if (fCheckPointLevel > 2) WriteESD(esd, fgkDetectorName[iDet]);
1620     }
1621   }
1622
1623   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1624     AliError(Form("the following detectors were not found: %s", 
1625                   detStr.Data()));
1626     if (fStopOnError) return kFALSE;
1627   }
1628   AliSysInfo::AddStamp(Form("FillESD%d",eventNr), 0,1, eventNr);
1629   eventNr++;
1630   return kTRUE;
1631 }
1632
1633 //_____________________________________________________________________________
1634 Bool_t AliReconstruction::FillTriggerESD(AliESDEvent*& esd)
1635 {
1636   // Reads the trigger decision which is
1637   // stored in Trigger.root file and fills
1638   // the corresponding esd entries
1639
1640   AliCodeTimerAuto("")
1641   
1642   AliInfo("Filling trigger information into the ESD");
1643
1644   if (fRawReader) {
1645     AliCTPRawStream input(fRawReader);
1646     if (!input.Next()) {
1647       AliError("No valid CTP (trigger) DDL raw data is found ! The trigger information is not stored in the ESD !");
1648       return kFALSE;
1649     }
1650     esd->SetTriggerMask(input.GetClassMask());
1651     esd->SetTriggerCluster(input.GetClusterMask());
1652   }
1653   else {
1654     AliRunLoader *runloader = AliRunLoader::GetRunLoader();
1655     if (runloader) {
1656       if (!runloader->LoadTrigger()) {
1657         AliCentralTrigger *aCTP = runloader->GetTrigger();
1658         esd->SetTriggerMask(aCTP->GetClassMask());
1659         esd->SetTriggerCluster(aCTP->GetClusterMask());
1660       }
1661       else {
1662         AliWarning("No trigger can be loaded! The trigger information is not stored in the ESD !");
1663         return kFALSE;
1664       }
1665     }
1666     else {
1667       AliError("No run loader is available! The trigger information is not stored in the ESD !");
1668       return kFALSE;
1669     }
1670   }
1671
1672   return kTRUE;
1673 }
1674
1675
1676
1677
1678
1679 //_____________________________________________________________________________
1680 Bool_t AliReconstruction::FillRawEventHeaderESD(AliESDEvent*& esd)
1681 {
1682   // 
1683   // Filling information from RawReader Header
1684   // 
1685
1686   AliInfo("Filling information from RawReader Header");
1687   esd->SetBunchCrossNumber(0);
1688   esd->SetOrbitNumber(0);
1689   esd->SetPeriodNumber(0);
1690   esd->SetTimeStamp(0);
1691   esd->SetEventType(0);
1692   const AliRawEventHeaderBase * eventHeader = fRawReader->GetEventHeader();
1693   if (eventHeader){
1694
1695     const UInt_t *id = eventHeader->GetP("Id");
1696     esd->SetBunchCrossNumber((id)[1]&0x00000fff);
1697     esd->SetOrbitNumber((((id)[0]<<20)&0xf00000)|(((id)[1]>>12)&0xfffff));
1698     esd->SetPeriodNumber(((id)[0]>>4)&0x0fffffff);
1699
1700     esd->SetTimeStamp((eventHeader->Get("Timestamp")));  
1701     esd->SetEventType((eventHeader->Get("Type")));
1702   }
1703
1704   return kTRUE;
1705 }
1706
1707
1708 //_____________________________________________________________________________
1709 Bool_t AliReconstruction::IsSelected(TString detName, TString& detectors) const
1710 {
1711 // check whether detName is contained in detectors
1712 // if yes, it is removed from detectors
1713
1714   // check if all detectors are selected
1715   if ((detectors.CompareTo("ALL") == 0) ||
1716       detectors.BeginsWith("ALL ") ||
1717       detectors.EndsWith(" ALL") ||
1718       detectors.Contains(" ALL ")) {
1719     detectors = "ALL";
1720     return kTRUE;
1721   }
1722
1723   // search for the given detector
1724   Bool_t result = kFALSE;
1725   if ((detectors.CompareTo(detName) == 0) ||
1726       detectors.BeginsWith(detName+" ") ||
1727       detectors.EndsWith(" "+detName) ||
1728       detectors.Contains(" "+detName+" ")) {
1729     detectors.ReplaceAll(detName, "");
1730     result = kTRUE;
1731   }
1732
1733   // clean up the detectors string
1734   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
1735   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
1736   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
1737
1738   return result;
1739 }
1740
1741 //_____________________________________________________________________________
1742 Bool_t AliReconstruction::InitRunLoader()
1743 {
1744 // get or create the run loader
1745
1746   if (gAlice) delete gAlice;
1747   gAlice = NULL;
1748
1749   if (!gSystem->AccessPathName(fGAliceFileName.Data())) { // galice.root exists
1750     // load all base libraries to get the loader classes
1751     TString libs = gSystem->GetLibraries();
1752     for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1753       TString detName = fgkDetectorName[iDet];
1754       if (detName == "HLT") continue;
1755       if (libs.Contains("lib" + detName + "base.so")) continue;
1756       gSystem->Load("lib" + detName + "base.so");
1757     }
1758     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data());
1759     if (!fRunLoader) {
1760       AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
1761       CleanUp();
1762       return kFALSE;
1763     }
1764     fRunLoader->CdGAFile();
1765     if (gFile->GetKey(AliRunLoader::GetGAliceName())) {
1766       if (fRunLoader->LoadgAlice() == 0) {
1767         gAlice = fRunLoader->GetAliRun();
1768         AliTracker::SetFieldMap(gAlice->Field(),fUniformField);
1769       }
1770     }
1771     if (!gAlice && !fRawReader) {
1772       AliError(Form("no gAlice object found in file %s",
1773                     fGAliceFileName.Data()));
1774       CleanUp();
1775       return kFALSE;
1776     }
1777
1778     //PH This is a temporary fix to give access to the kinematics
1779     //PH that is needed for the labels of ITS clusters
1780     fRunLoader->LoadHeader();
1781     fRunLoader->LoadKinematics();
1782
1783   } else {               // galice.root does not exist
1784     if (!fRawReader) {
1785       AliError(Form("the file %s does not exist", fGAliceFileName.Data()));
1786       CleanUp();
1787       return kFALSE;
1788     }
1789     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data(),
1790                                     AliConfig::GetDefaultEventFolderName(),
1791                                     "recreate");
1792     if (!fRunLoader) {
1793       AliError(Form("could not create run loader in file %s", 
1794                     fGAliceFileName.Data()));
1795       CleanUp();
1796       return kFALSE;
1797     }
1798     fRunLoader->MakeTree("E");
1799     Int_t iEvent = 0;
1800     while (fRawReader->NextEvent()) {
1801       fRunLoader->SetEventNumber(iEvent);
1802       fRunLoader->GetHeader()->Reset(fRawReader->GetRunNumber(), 
1803                                      iEvent, iEvent);
1804       fRunLoader->MakeTree("H");
1805       fRunLoader->TreeE()->Fill();
1806       iEvent++;
1807     }
1808     fRawReader->RewindEvents();
1809     if (fNumberOfEventsPerFile > 0)
1810       fRunLoader->SetNumberOfEventsPerFile(fNumberOfEventsPerFile);
1811     else
1812       fRunLoader->SetNumberOfEventsPerFile(iEvent);
1813     fRunLoader->WriteHeader("OVERWRITE");
1814     fRunLoader->CdGAFile();
1815     fRunLoader->Write(0, TObject::kOverwrite);
1816 //    AliTracker::SetFieldMap(???);
1817   }
1818
1819   return kTRUE;
1820 }
1821
1822 //_____________________________________________________________________________
1823 AliReconstructor* AliReconstruction::GetReconstructor(Int_t iDet)
1824 {
1825 // get the reconstructor object and the loader for a detector
1826
1827   if (fReconstructor[iDet]) return fReconstructor[iDet];
1828
1829   // load the reconstructor object
1830   TPluginManager* pluginManager = gROOT->GetPluginManager();
1831   TString detName = fgkDetectorName[iDet];
1832   TString recName = "Ali" + detName + "Reconstructor";
1833   if (gAlice && !gAlice->GetDetector(detName) && (detName != "HLT")) return NULL;
1834
1835   AliReconstructor* reconstructor = NULL;
1836   // first check if a plugin is defined for the reconstructor
1837   TPluginHandler* pluginHandler = 
1838     pluginManager->FindHandler("AliReconstructor", detName);
1839   // if not, add a plugin for it
1840   if (!pluginHandler) {
1841     AliDebug(1, Form("defining plugin for %s", recName.Data()));
1842     TString libs = gSystem->GetLibraries();
1843     if (libs.Contains("lib" + detName + "base.so") ||
1844         (gSystem->Load("lib" + detName + "base.so") >= 0)) {
1845       pluginManager->AddHandler("AliReconstructor", detName, 
1846                                 recName, detName + "rec", recName + "()");
1847     } else {
1848       pluginManager->AddHandler("AliReconstructor", detName, 
1849                                 recName, detName, recName + "()");
1850     }
1851     pluginHandler = pluginManager->FindHandler("AliReconstructor", detName);
1852   }
1853   if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
1854     reconstructor = (AliReconstructor*) pluginHandler->ExecPlugin(0);
1855   }
1856   if (reconstructor) {
1857     TObject* obj = fOptions.FindObject(detName.Data());
1858     if (obj) reconstructor->SetOption(obj->GetTitle());
1859     reconstructor->Init();
1860     fReconstructor[iDet] = reconstructor;
1861   }
1862
1863   // get or create the loader
1864   if (detName != "HLT") {
1865     fLoader[iDet] = fRunLoader->GetLoader(detName + "Loader");
1866     if (!fLoader[iDet]) {
1867       AliConfig::Instance()
1868         ->CreateDetectorFolders(fRunLoader->GetEventFolder(), 
1869                                 detName, detName);
1870       // first check if a plugin is defined for the loader
1871       pluginHandler = 
1872         pluginManager->FindHandler("AliLoader", detName);
1873       // if not, add a plugin for it
1874       if (!pluginHandler) {
1875         TString loaderName = "Ali" + detName + "Loader";
1876         AliDebug(1, Form("defining plugin for %s", loaderName.Data()));
1877         pluginManager->AddHandler("AliLoader", detName, 
1878                                   loaderName, detName + "base", 
1879                                   loaderName + "(const char*, TFolder*)");
1880         pluginHandler = pluginManager->FindHandler("AliLoader", detName);
1881       }
1882       if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
1883         fLoader[iDet] = 
1884           (AliLoader*) pluginHandler->ExecPlugin(2, detName.Data(), 
1885                                                  fRunLoader->GetEventFolder());
1886       }
1887       if (!fLoader[iDet]) {   // use default loader
1888         fLoader[iDet] = new AliLoader(detName, fRunLoader->GetEventFolder());
1889       }
1890       if (!fLoader[iDet]) {
1891         AliWarning(Form("couldn't get loader for %s", detName.Data()));
1892         if (fStopOnError) return NULL;
1893       } else {
1894         fRunLoader->AddLoader(fLoader[iDet]);
1895         fRunLoader->CdGAFile();
1896         if (gFile && !gFile->IsWritable()) gFile->ReOpen("UPDATE");
1897         fRunLoader->Write(0, TObject::kOverwrite);
1898       }
1899     }
1900   }
1901       
1902   return reconstructor;
1903 }
1904
1905 //_____________________________________________________________________________
1906 Bool_t AliReconstruction::CreateVertexer()
1907 {
1908 // create the vertexer
1909
1910   fVertexer = NULL;
1911   AliReconstructor* itsReconstructor = GetReconstructor(0);
1912   if (itsReconstructor) {
1913     fVertexer = itsReconstructor->CreateVertexer();
1914   }
1915   if (!fVertexer) {
1916     AliWarning("couldn't create a vertexer for ITS");
1917     if (fStopOnError) return kFALSE;
1918   }
1919
1920   return kTRUE;
1921 }
1922
1923 //_____________________________________________________________________________
1924 Bool_t AliReconstruction::CreateTrackers(const TString& detectors)
1925 {
1926 // create the trackers
1927
1928   TString detStr = detectors;
1929   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1930     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1931     AliReconstructor* reconstructor = GetReconstructor(iDet);
1932     if (!reconstructor) continue;
1933     TString detName = fgkDetectorName[iDet];
1934     if (detName == "HLT") {
1935       fRunHLTTracking = kTRUE;
1936       continue;
1937     }
1938     if (detName == "MUON") {
1939       fRunMuonTracking = kTRUE;
1940       continue;
1941     }
1942
1943
1944     fTracker[iDet] = reconstructor->CreateTracker();
1945     if (!fTracker[iDet] && (iDet < 7)) {
1946       AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
1947       if (fStopOnError) return kFALSE;
1948     }
1949     AliSysInfo::AddStamp(Form("LTracker%s",fgkDetectorName[iDet]), iDet,0);
1950   }
1951
1952   return kTRUE;
1953 }
1954
1955 //_____________________________________________________________________________
1956 void AliReconstruction::CleanUp(TFile* file, TFile* fileOld)
1957 {
1958 // delete trackers and the run loader and close and delete the file
1959
1960   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1961     delete fReconstructor[iDet];
1962     fReconstructor[iDet] = NULL;
1963     fLoader[iDet] = NULL;
1964     delete fTracker[iDet];
1965     fTracker[iDet] = NULL;
1966 //    delete fQADataMaker[iDet];
1967 //    fQADataMaker[iDet] = NULL;
1968   }
1969   delete fVertexer;
1970   fVertexer = NULL;
1971   
1972   if(!(AliCDBManager::Instance()->GetCacheFlag())) {
1973         delete fDiamondProfile;
1974         fDiamondProfile = NULL;
1975   }
1976
1977   delete fGRPList;
1978   fGRPList = NULL;
1979
1980   delete fRunLoader;
1981   fRunLoader = NULL;
1982   delete fRawReader;
1983   fRawReader = NULL;
1984
1985   if (file) {
1986     file->Close();
1987     delete file;
1988   }
1989
1990   if (fileOld) {
1991     fileOld->Close();
1992     delete fileOld;
1993     gSystem->Unlink("AliESDs.old.root");
1994   }
1995 }
1996
1997 //_____________________________________________________________________________
1998
1999 Bool_t AliReconstruction::ReadESD(AliESDEvent*& esd, const char* recStep) const
2000 {
2001 // read the ESD event from a file
2002
2003   if (!esd) return kFALSE;
2004   char fileName[256];
2005   sprintf(fileName, "ESD_%d.%d_%s.root", 
2006           esd->GetRunNumber(), esd->GetEventNumberInFile(), recStep);
2007   if (gSystem->AccessPathName(fileName)) return kFALSE;
2008
2009   AliInfo(Form("reading ESD from file %s", fileName));
2010   AliDebug(1, Form("reading ESD from file %s", fileName));
2011   TFile* file = TFile::Open(fileName);
2012   if (!file || !file->IsOpen()) {
2013     AliError(Form("opening %s failed", fileName));
2014     delete file;
2015     return kFALSE;
2016   }
2017
2018   gROOT->cd();
2019   delete esd;
2020   esd = (AliESDEvent*) file->Get("ESD");
2021   file->Close();
2022   delete file;
2023   return kTRUE;
2024
2025 }
2026
2027
2028
2029 //_____________________________________________________________________________
2030 void AliReconstruction::WriteESD(AliESDEvent* esd, const char* recStep) const
2031 {
2032 // write the ESD event to a file
2033
2034   if (!esd) return;
2035   char fileName[256];
2036   sprintf(fileName, "ESD_%d.%d_%s.root", 
2037           esd->GetRunNumber(), esd->GetEventNumberInFile(), recStep);
2038
2039   AliDebug(1, Form("writing ESD to file %s", fileName));
2040   TFile* file = TFile::Open(fileName, "recreate");
2041   if (!file || !file->IsOpen()) {
2042     AliError(Form("opening %s failed", fileName));
2043   } else {
2044     esd->Write("ESD");
2045     file->Close();
2046   }
2047   delete file;
2048 }
2049
2050
2051
2052
2053
2054 //_____________________________________________________________________________
2055 void AliReconstruction::ESDFile2AODFile(TFile* esdFile, TFile* aodFile)
2056 {
2057   // write all files from the given esd file to an aod file
2058
2059   // create an AliAOD object 
2060   AliAODEvent *aod = new AliAODEvent();
2061   aod->CreateStdContent();
2062   
2063   // go to the file
2064   aodFile->cd();
2065   
2066   // create the tree
2067   TTree *aodTree = new TTree("aodTree", "AliAOD tree");
2068   aodTree->Branch(aod->GetList());
2069
2070   // connect to ESD
2071   TTree *t = (TTree*) esdFile->Get("esdTree");
2072   AliESDEvent *esd = new AliESDEvent();
2073   esd->ReadFromTree(t);
2074
2075   Int_t nEvents = t->GetEntries();
2076
2077   // set arrays and pointers
2078   Float_t posF[3];
2079   Double_t pos[3];
2080   Double_t p[3];
2081   Double_t p_pos[3];
2082   Double_t p_neg[3];
2083   Double_t covVtx[6];
2084   Double_t covTr[21];
2085   Double_t pid[10];
2086
2087   // loop over events and fill them
2088   for (Int_t iEvent = 0; iEvent < nEvents; ++iEvent) {
2089     //cout << "event: " << iEvent << endl;
2090     t->GetEntry(iEvent);
2091
2092     // Multiplicity information needed by the header (to be revised!)
2093     Int_t nTracks   = esd->GetNumberOfTracks();
2094     Int_t nPosTracks = 0;
2095     for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) 
2096       if (esd->GetTrack(iTrack)->Charge()> 0) nPosTracks++;
2097
2098     // Access the header
2099     AliAODHeader *header = aod->GetHeader();
2100
2101     // fill the header
2102     header->SetRunNumber       (esd->GetRunNumber()       );
2103     header->SetBunchCrossNumber(esd->GetBunchCrossNumber());
2104     header->SetOrbitNumber     (esd->GetOrbitNumber()     );
2105     header->SetPeriodNumber    (esd->GetPeriodNumber()    );
2106     header->SetTriggerMask     (esd->GetTriggerMask()     ); 
2107     header->SetTriggerCluster  (esd->GetTriggerCluster()  );
2108     header->SetEventType       (esd->GetEventType()       );
2109     header->SetMagneticField   (esd->GetMagneticField()   );
2110     header->SetZDCN1Energy     (esd->GetZDCN1Energy()     );
2111     header->SetZDCP1Energy     (esd->GetZDCP1Energy()     );
2112     header->SetZDCN2Energy     (esd->GetZDCN2Energy()     );
2113     header->SetZDCP2Energy     (esd->GetZDCP2Energy()     );
2114     header->SetZDCEMEnergy     (esd->GetZDCEMEnergy(0),esd->GetZDCEMEnergy(1));
2115     header->SetRefMultiplicity   (nTracks);
2116     header->SetRefMultiplicityPos(nPosTracks);
2117     header->SetRefMultiplicityNeg(nTracks - nPosTracks);
2118     header->SetMuonMagFieldScale(-999.); // FIXME
2119     header->SetCentrality(-999.);        // FIXME
2120
2121     Int_t nV0s      = esd->GetNumberOfV0s();
2122     Int_t nCascades = esd->GetNumberOfCascades();
2123     Int_t nKinks    = esd->GetNumberOfKinks();
2124         Int_t nVertices = nV0s + 2*nCascades /*could lead to two vertices, one V0 and the Xi */+ nKinks + 1 /* = prim. vtx*/;    
2125         Int_t nJets     = 0;
2126     Int_t nCaloClus = esd->GetNumberOfCaloClusters();
2127     Int_t nFmdClus  = 0;
2128     Int_t nPmdClus  = esd->GetNumberOfPmdTracks();
2129    
2130     aod->ResetStd(nTracks, nVertices, nV0s+nCascades, nJets, nCaloClus, nFmdClus, nPmdClus);
2131     
2132     // Array to take into account the tracks already added to the AOD
2133     Bool_t * usedTrack = NULL;
2134     if (nTracks>0) {
2135       usedTrack = new Bool_t[nTracks];
2136       for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) usedTrack[iTrack]=kFALSE;
2137     }
2138     // Array to take into account the V0s already added to the AOD
2139     Bool_t * usedV0 = NULL;
2140     if (nV0s>0) {
2141       usedV0 = new Bool_t[nV0s];
2142       for (Int_t iV0=0; iV0<nV0s; ++iV0) usedV0[iV0]=kFALSE;
2143     }
2144     // Array to take into account the kinks already added to the AOD
2145     Bool_t * usedKink = NULL;
2146     if (nKinks>0) {
2147       usedKink = new Bool_t[nKinks];
2148       for (Int_t iKink=0; iKink<nKinks; ++iKink) usedKink[iKink]=kFALSE;
2149     }
2150     
2151     // Access to the AOD container of vertices
2152     TClonesArray &vertices = *(aod->GetVertices());
2153     Int_t jVertices=0;
2154
2155     // Access to the AOD container of tracks
2156     TClonesArray &tracks = *(aod->GetTracks());
2157     Int_t jTracks=0; 
2158    
2159     // Access to the AOD container of V0s
2160     TClonesArray &V0s = *(aod->GetV0s());
2161     Int_t jV0s=0;
2162     
2163     // Add primary vertex. The primary tracks will be defined
2164     // after the loops on the composite objects (V0, cascades, kinks)
2165     const AliESDVertex *vtx = esd->GetPrimaryVertex();
2166       
2167     vtx->GetXYZ(pos); // position
2168     vtx->GetCovMatrix(covVtx); //covariance matrix
2169
2170     AliAODVertex * primary = new(vertices[jVertices++])
2171       AliAODVertex(pos, covVtx, vtx->GetChi2toNDF(), NULL, -1, AliAODVertex::kPrimary);
2172          
2173
2174     AliAODTrack *aodTrack = 0x0;
2175     
2176     // Create vertices starting from the most complex objects
2177
2178     // Cascades
2179     for (Int_t nCascade = 0; nCascade < nCascades; ++nCascade) {
2180       AliESDcascade *cascade = esd->GetCascade(nCascade);
2181       
2182       cascade->GetXYZ(pos[0], pos[1], pos[2]);
2183       cascade->GetPosCovXi(covVtx);
2184      
2185       // Add the cascade vertex
2186       AliAODVertex * vcascade = new(vertices[jVertices++]) AliAODVertex(pos,
2187                                                                         covVtx,
2188                                                                         cascade->GetChi2Xi(), // = chi2/NDF since NDF = 2*2-3
2189                                                                         primary,
2190                                                                         nCascade,
2191                                                                         AliAODVertex::kCascade);
2192
2193       primary->AddDaughter(vcascade); // the cascade 'particle' (represented by a vertex) is added as a daughter to the primary vertex
2194
2195       // Add the V0 from the cascade. The ESD class have to be optimized...
2196       // Now we have to search for the corresponding V0 in the list of V0s
2197       // using the indeces of the positive and negative tracks
2198
2199       Int_t posFromV0 = cascade->GetPindex();
2200       Int_t negFromV0 = cascade->GetNindex();
2201
2202
2203       AliESDv0 * v0 = 0x0;
2204       Int_t indV0 = -1;
2205
2206       for (Int_t iV0=0; iV0<nV0s; ++iV0) {
2207
2208         v0 = esd->GetV0(iV0);
2209         Int_t posV0 = v0->GetPindex();
2210         Int_t negV0 = v0->GetNindex();
2211
2212         if (posV0==posFromV0 && negV0==negFromV0) {
2213           indV0 = iV0;
2214           break;
2215         }
2216       }
2217
2218       AliAODVertex * vV0FromCascade = 0x0;
2219
2220       if (indV0>-1 && !usedV0[indV0]) {
2221         
2222         // the V0 exists in the array of V0s and is not used
2223
2224         usedV0[indV0] = kTRUE;
2225         
2226         v0->GetXYZ(pos[0], pos[1], pos[2]);
2227         v0->GetPosCov(covVtx);
2228         
2229         vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
2230                                                                  covVtx,
2231                                                                  v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
2232                                                                  vcascade,
2233                                                                  indV0,
2234                                                                  AliAODVertex::kV0);
2235       } else {
2236
2237         // the V0 doesn't exist in the array of V0s or was used
2238         cerr << "Error: event " << iEvent << " cascade " << nCascade
2239              << " The V0 " << indV0 
2240              << " doesn't exist in the array of V0s or was used!" << endl;
2241
2242         cascade->GetXYZ(pos[0], pos[1], pos[2]);
2243         cascade->GetPosCov(covVtx);
2244       
2245         vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
2246                                                                  covVtx,
2247                                                                  v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
2248                                                                  vcascade,
2249                                                                  indV0,
2250                                                                  AliAODVertex::kV0);
2251         vcascade->AddDaughter(vV0FromCascade);
2252
2253       }
2254
2255       // Add the positive tracks from the V0
2256
2257       if (! usedTrack[posFromV0]) {
2258
2259         usedTrack[posFromV0] = kTRUE;
2260
2261         AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
2262         esdTrack->GetPxPyPz(p_pos);
2263         esdTrack->GetXYZ(pos);
2264         esdTrack->GetCovarianceXYZPxPyPz(covTr);
2265         esdTrack->GetESDpid(pid);
2266         
2267         vV0FromCascade->AddDaughter(aodTrack =
2268                                     new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2269                                            esdTrack->GetLabel(), 
2270                                            p_pos, 
2271                                            kTRUE,
2272                                            pos,
2273                                            kFALSE,
2274                                            covTr, 
2275                                            (Short_t)esdTrack->Charge(),
2276                                            esdTrack->GetITSClusterMap(), 
2277                                            pid,
2278                                            vV0FromCascade,
2279                                            kTRUE,  // check if this is right
2280                                            kFALSE, // check if this is right
2281                                            AliAODTrack::kSecondary)
2282                 );
2283         aodTrack->ConvertAliPIDtoAODPID();
2284       }
2285       else {
2286         cerr << "Error: event " << iEvent << " cascade " << nCascade
2287              << " track " << posFromV0 << " has already been used!" << endl;
2288       }
2289
2290       // Add the negative tracks from the V0
2291
2292       if (!usedTrack[negFromV0]) {
2293         
2294         usedTrack[negFromV0] = kTRUE;
2295         
2296         AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
2297         esdTrack->GetPxPyPz(p_neg);
2298         esdTrack->GetXYZ(pos);
2299         esdTrack->GetCovarianceXYZPxPyPz(covTr);
2300         esdTrack->GetESDpid(pid);
2301         
2302         vV0FromCascade->AddDaughter(aodTrack =
2303                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2304                                            esdTrack->GetLabel(),
2305                                            p_neg,
2306                                            kTRUE,
2307                                            pos,
2308                                            kFALSE,
2309                                            covTr, 
2310                                            (Short_t)esdTrack->Charge(),
2311                                            esdTrack->GetITSClusterMap(), 
2312                                            pid,
2313                                            vV0FromCascade,
2314                                            kTRUE,  // check if this is right
2315                                            kFALSE, // check if this is right
2316                                            AliAODTrack::kSecondary)
2317                 );
2318         aodTrack->ConvertAliPIDtoAODPID();
2319       }
2320       else {
2321         cerr << "Error: event " << iEvent << " cascade " << nCascade
2322              << " track " << negFromV0 << " has already been used!" << endl;
2323       }
2324
2325       // add it to the V0 array as well
2326       Double_t d0[2] = { -999., -99.};
2327       // counting is probably wrong
2328       new(V0s[jV0s++]) AliAODv0(vV0FromCascade, -999., -99., p_pos, p_neg, d0); // to be refined
2329
2330       // Add the bachelor track from the cascade
2331
2332       Int_t bachelor = cascade->GetBindex();
2333       
2334       if(!usedTrack[bachelor]) {
2335       
2336         usedTrack[bachelor] = kTRUE;
2337         
2338         AliESDtrack *esdTrack = esd->GetTrack(bachelor);
2339         esdTrack->GetPxPyPz(p);
2340         esdTrack->GetXYZ(pos);
2341         esdTrack->GetCovarianceXYZPxPyPz(covTr);
2342         esdTrack->GetESDpid(pid);
2343
2344         vcascade->AddDaughter(aodTrack =
2345                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2346                                            esdTrack->GetLabel(),
2347                                            p,
2348                                            kTRUE,
2349                                            pos,
2350                                            kFALSE,
2351                                            covTr, 
2352                                            (Short_t)esdTrack->Charge(),
2353                                            esdTrack->GetITSClusterMap(), 
2354                                            pid,
2355                                            vcascade,
2356                                            kTRUE,  // check if this is right
2357                                            kFALSE, // check if this is right
2358                                            AliAODTrack::kSecondary)
2359                 );
2360         aodTrack->ConvertAliPIDtoAODPID();
2361      }
2362       else {
2363         cerr << "Error: event " << iEvent << " cascade " << nCascade
2364              << " track " << bachelor << " has already been used!" << endl;
2365       }
2366       
2367       // Add the primary track of the cascade (if any)
2368       
2369     } // end of the loop on cascades
2370  
2371     // V0s
2372         
2373     for (Int_t nV0 = 0; nV0 < nV0s; ++nV0) {
2374
2375       if (usedV0[nV0]) continue; // skip if aready added to the AOD
2376
2377       AliESDv0 *v0 = esd->GetV0(nV0); 
2378      
2379       v0->GetXYZ(pos[0], pos[1], pos[2]);
2380       v0->GetPosCov(covVtx);
2381
2382       AliAODVertex * vV0 = 
2383         new(vertices[jVertices++]) AliAODVertex(pos,
2384                                                 covVtx,
2385                                                 v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
2386                                                 primary,
2387                                                 nV0,
2388                                                 AliAODVertex::kV0);
2389       primary->AddDaughter(vV0);
2390
2391       Int_t posFromV0 = v0->GetPindex();
2392       Int_t negFromV0 = v0->GetNindex();
2393       
2394       // Add the positive tracks from the V0
2395
2396       if (!usedTrack[posFromV0]) {
2397         
2398         usedTrack[posFromV0] = kTRUE;
2399
2400         AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
2401         esdTrack->GetPxPyPz(p_pos);
2402         esdTrack->GetXYZ(pos);
2403         esdTrack->GetCovarianceXYZPxPyPz(covTr);
2404         esdTrack->GetESDpid(pid);
2405         
2406         vV0->AddDaughter(aodTrack =
2407                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2408                                            esdTrack->GetLabel(), 
2409                                            p_pos, 
2410                                            kTRUE,
2411                                            pos,
2412                                            kFALSE,
2413                                            covTr, 
2414                                            (Short_t)esdTrack->Charge(),
2415                                            esdTrack->GetITSClusterMap(), 
2416                                            pid,
2417                                            vV0,
2418                                            kTRUE,  // check if this is right
2419                                            kFALSE, // check if this is right
2420                                            AliAODTrack::kSecondary)
2421                 );
2422         aodTrack->ConvertAliPIDtoAODPID();
2423       }
2424       else {
2425         cerr << "Error: event " << iEvent << " V0 " << nV0
2426              << " track " << posFromV0 << " has already been used!" << endl;
2427       }
2428
2429       // Add the negative tracks from the V0
2430
2431       if (!usedTrack[negFromV0]) {
2432
2433         usedTrack[negFromV0] = kTRUE;
2434
2435         AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
2436         esdTrack->GetPxPyPz(p_neg);
2437         esdTrack->GetXYZ(pos);
2438         esdTrack->GetCovarianceXYZPxPyPz(covTr);
2439         esdTrack->GetESDpid(pid);
2440
2441         vV0->AddDaughter(aodTrack =
2442                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2443                                            esdTrack->GetLabel(),
2444                                            p_neg,
2445                                            kTRUE,
2446                                            pos,
2447                                            kFALSE,
2448                                            covTr, 
2449                                            (Short_t)esdTrack->Charge(),
2450                                            esdTrack->GetITSClusterMap(), 
2451                                            pid,
2452                                            vV0,
2453                                            kTRUE,  // check if this is right
2454                                            kFALSE, // check if this is right
2455                                            AliAODTrack::kSecondary)
2456                 );
2457         aodTrack->ConvertAliPIDtoAODPID();
2458       }
2459       else {
2460         cerr << "Error: event " << iEvent << " V0 " << nV0
2461              << " track " << negFromV0 << " has already been used!" << endl;
2462       }
2463
2464       // add it to the V0 array as well
2465       Double_t d0[2] = { 999., 99.};
2466       new(V0s[jV0s++]) AliAODv0(vV0, 999., 99., p_pos, p_neg, d0); // to be refined
2467     }
2468         V0s.Expand(jV0s);        
2469     // end of the loop on V0s
2470     
2471     // Kinks: it is a big mess the access to the information in the kinks
2472     // The loop is on the tracks in order to find the mother and daugther of each kink
2473
2474
2475     for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) {
2476
2477       AliESDtrack * esdTrack = esd->GetTrack(iTrack);
2478
2479       Int_t ikink = esdTrack->GetKinkIndex(0);
2480
2481       if (ikink) {
2482         // Negative kink index: mother, positive: daughter
2483
2484         // Search for the second track of the kink
2485
2486         for (Int_t jTrack = iTrack+1; jTrack<nTracks; ++jTrack) {
2487
2488           AliESDtrack * esdTrack1 = esd->GetTrack(jTrack);
2489
2490           Int_t jkink = esdTrack1->GetKinkIndex(0);
2491
2492           if ( TMath::Abs(ikink)==TMath::Abs(jkink) ) {
2493
2494             // The two tracks are from the same kink
2495           
2496             if (usedKink[TMath::Abs(ikink)-1]) continue; // skip used kinks
2497
2498             Int_t imother = -1;
2499             Int_t idaughter = -1;
2500
2501             if (ikink<0 && jkink>0) {
2502
2503               imother = iTrack;
2504               idaughter = jTrack;
2505             }
2506             else if (ikink>0 && jkink<0) {
2507
2508               imother = jTrack;
2509               idaughter = iTrack;
2510             }
2511             else {
2512               cerr << "Error: Wrong combination of kink indexes: "
2513               << ikink << " " << jkink << endl;
2514               continue;
2515             }
2516
2517             // Add the mother track
2518
2519             AliAODTrack * mother = NULL;
2520
2521             if (!usedTrack[imother]) {
2522         
2523               usedTrack[imother] = kTRUE;
2524         
2525               AliESDtrack *esdTrack = esd->GetTrack(imother);
2526               esdTrack->GetPxPyPz(p);
2527               esdTrack->GetXYZ(pos);
2528               esdTrack->GetCovarianceXYZPxPyPz(covTr);
2529               esdTrack->GetESDpid(pid);
2530
2531               mother = 
2532                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2533                                            esdTrack->GetLabel(),
2534                                            p,
2535                                            kTRUE,
2536                                            pos,
2537                                            kFALSE,
2538                                            covTr, 
2539                                            (Short_t)esdTrack->Charge(),
2540                                            esdTrack->GetITSClusterMap(), 
2541                                            pid,
2542                                            primary,
2543                                            kTRUE, // check if this is right
2544                                            kTRUE, // check if this is right
2545                                            AliAODTrack::kPrimary);
2546               primary->AddDaughter(mother);
2547               mother->ConvertAliPIDtoAODPID();
2548             }
2549             else {
2550               cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
2551               << " track " << imother << " has already been used!" << endl;
2552             }
2553
2554             // Add the kink vertex
2555             AliESDkink * kink = esd->GetKink(TMath::Abs(ikink)-1);
2556
2557             AliAODVertex * vkink = 
2558             new(vertices[jVertices++]) AliAODVertex(kink->GetPosition(),
2559                                                     NULL,
2560                                                     0.,
2561                                                     mother,
2562                                                     esdTrack->GetID(), // This is the track ID of the mother's track!
2563                                                     AliAODVertex::kKink);
2564             // Add the daughter track
2565
2566             AliAODTrack * daughter = NULL;
2567
2568             if (!usedTrack[idaughter]) {
2569         
2570               usedTrack[idaughter] = kTRUE;
2571         
2572               AliESDtrack *esdTrack = esd->GetTrack(idaughter);
2573               esdTrack->GetPxPyPz(p);
2574               esdTrack->GetXYZ(pos);
2575               esdTrack->GetCovarianceXYZPxPyPz(covTr);
2576               esdTrack->GetESDpid(pid);
2577
2578               daughter = 
2579                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2580                                            esdTrack->GetLabel(),
2581                                            p,
2582                                            kTRUE,
2583                                            pos,
2584                                            kFALSE,
2585                                            covTr, 
2586                                            (Short_t)esdTrack->Charge(),
2587                                            esdTrack->GetITSClusterMap(), 
2588                                            pid,
2589                                            vkink,
2590                                            kTRUE, // check if this is right
2591                                            kTRUE, // check if this is right
2592                                            AliAODTrack::kPrimary);
2593               vkink->AddDaughter(daughter);
2594               daughter->ConvertAliPIDtoAODPID();
2595             }
2596             else {
2597               cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
2598               << " track " << idaughter << " has already been used!" << endl;
2599             }
2600           }
2601         }
2602       }
2603     }
2604     vertices.Expand(jVertices);
2605
2606     // Tracks (primary and orphan)
2607     for (Int_t nTrack = 0; nTrack < nTracks; ++nTrack) {
2608
2609       if (usedTrack[nTrack]) continue;
2610
2611       AliESDtrack *esdTrack = esd->GetTrack(nTrack);
2612       esdTrack->GetPxPyPz(p);
2613       esdTrack->GetXYZ(pos);
2614       esdTrack->GetCovarianceXYZPxPyPz(covTr);
2615       esdTrack->GetESDpid(pid);
2616
2617       Float_t impactXY, impactZ;
2618
2619       esdTrack->GetImpactParameters(impactXY,impactZ);
2620
2621       if (impactXY<3.) {
2622         // track inside the beam pipe
2623       
2624         primary->AddDaughter(aodTrack =
2625             new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2626                                          esdTrack->GetLabel(),
2627                                          p,
2628                                          kTRUE,
2629                                          pos,
2630                                          kFALSE,
2631                                          covTr, 
2632                                          (Short_t)esdTrack->Charge(),
2633                                          esdTrack->GetITSClusterMap(), 
2634                                          pid,
2635                                          primary,
2636                                          kTRUE, // check if this is right
2637                                          kTRUE, // check if this is right
2638                                          AliAODTrack::kPrimary)
2639             );
2640         aodTrack->ConvertAliPIDtoAODPID();
2641       }
2642       else {
2643         // outside the beam pipe: orphan track
2644         // Don't write them anymore!
2645         continue;
2646       } 
2647     } // end of loop on tracks
2648     
2649     // muon tracks
2650     Int_t nMuTracks = esd->GetNumberOfMuonTracks();
2651     for (Int_t nMuTrack = 0; nMuTrack < nMuTracks; ++nMuTrack) {
2652       
2653       AliESDMuonTrack *esdMuTrack = esd->GetMuonTrack(nMuTrack);     
2654       p[0] = esdMuTrack->Px(); 
2655       p[1] = esdMuTrack->Py(); 
2656       p[2] = esdMuTrack->Pz();
2657       pos[0] = primary->GetX(); 
2658       pos[1] = primary->GetY(); 
2659       pos[2] = primary->GetZ();
2660       
2661       // has to be changed once the muon pid is provided by the ESD
2662       for (Int_t i = 0; i < 10; pid[i++] = 0.); pid[AliAODTrack::kMuon]=1.;
2663       
2664       primary->AddDaughter(aodTrack =
2665           new(tracks[jTracks++]) AliAODTrack(0, // no ID provided
2666                                              0, // no label provided
2667                                              p,
2668                                              kTRUE,
2669                                              pos,
2670                                              kFALSE,
2671                                              NULL, // no covariance matrix provided
2672                                              esdMuTrack->Charge(),
2673                                              0, // ITSClusterMap is set below
2674                                              pid,
2675                                              primary,
2676                                              kFALSE,  // muon tracks are not used to fit the primary vtx
2677                                              kFALSE,  // not used for vertex fit
2678                                              AliAODTrack::kPrimary)
2679           );
2680
2681       aodTrack->SetHitsPatternInTrigCh(esdMuTrack->GetHitsPatternInTrigCh());
2682       Int_t track2Trigger = esdMuTrack->GetMatchTrigger();
2683       aodTrack->SetMatchTrigger(track2Trigger);
2684       if (track2Trigger) 
2685         aodTrack->SetChi2MatchTrigger(esdMuTrack->GetChi2MatchTrigger());
2686       else 
2687         aodTrack->SetChi2MatchTrigger(0.);
2688     }
2689     tracks.Expand(jTracks); // remove 'empty slots' due to unwritten tracks
2690         
2691     // Access to the AOD container of PMD clusters
2692     TClonesArray &pmdClusters = *(aod->GetPmdClusters());
2693     Int_t jPmdClusters=0;
2694   
2695     for (Int_t iPmd = 0; iPmd < nPmdClus; ++iPmd) {
2696       // file pmd clusters, to be revised!
2697       AliESDPmdTrack *pmdTrack = esd->GetPmdTrack(iPmd);
2698       Int_t nLabel = 0;
2699       Int_t *label = 0x0;
2700       Double_t pos[3] = { pmdTrack->GetClusterX(), pmdTrack->GetClusterY(), pmdTrack->GetClusterZ() };
2701       Double_t pid[9] = { 0., 0., 0., 0., 0., 0., 0., 0., 0. }; // to be revised!
2702       // type not set!
2703       // assoc cluster not set
2704       new(pmdClusters[jPmdClusters++]) AliAODPmdCluster(iPmd, nLabel, label, pmdTrack->GetClusterADC(), pos, pid);
2705     }
2706
2707     // Access to the AOD container of clusters
2708     TClonesArray &caloClusters = *(aod->GetCaloClusters());
2709     Int_t jClusters=0;
2710  
2711     for (Int_t iClust=0; iClust<nCaloClus; ++iClust) {
2712
2713       AliESDCaloCluster * cluster = esd->GetCaloCluster(iClust);
2714
2715       Int_t id = cluster->GetID();
2716       Int_t nLabel = 0;
2717       Int_t *label = 0x0;
2718       Float_t energy = cluster->E();
2719       cluster->GetPosition(posF);
2720       Char_t ttype=AliAODCluster::kUndef;
2721
2722       if (cluster->GetClusterType() == AliESDCaloCluster::kPHOSCluster) {
2723         ttype=AliAODCluster::kPHOSNeutral;
2724       } 
2725       else if (cluster->GetClusterType() == AliESDCaloCluster::kEMCALClusterv1) {
2726         ttype = AliAODCluster::kEMCALClusterv1;
2727       }
2728
2729       
2730       AliAODCaloCluster *caloCluster = new(caloClusters[jClusters++]) AliAODCaloCluster(id,
2731                                                                                         nLabel,
2732                                                                                         label,
2733                                                                                         energy,
2734                                                                                         pos,
2735                                                                                         NULL,
2736                                                                                         ttype);
2737       
2738       caloCluster->SetCaloCluster(); // to be refined!
2739
2740     } 
2741     caloClusters.Expand(jClusters); // resize TObjArray to 'remove' slots for pseudo clusters    
2742     // end of loop on calo clusters
2743
2744     // fill EMCAL cell info
2745     if (esd->GetEMCALCells()) { // protection against missing ESD information
2746       AliESDCaloCells &esdEMcells = *(esd->GetEMCALCells());
2747       Int_t nEMcell = esdEMcells.GetNumberOfCells() ;
2748       
2749       AliAODCaloCells &aodEMcells = *(aod->GetEMCALCells());
2750       aodEMcells.CreateContainer(nEMcell);
2751       aodEMcells.SetType(AliAODCaloCells::kEMCAL);
2752       for (Int_t iCell = 0; iCell < nEMcell; iCell++) {      
2753         aodEMcells.SetCell(iCell,esdEMcells.GetCellNumber(iCell),esdEMcells.GetAmplitude(iCell));
2754       }
2755       aodEMcells.Sort();
2756     }
2757
2758     // fill PHOS cell info
2759     if (esd->GetPHOSCells()) { // protection against missing ESD information
2760       AliESDCaloCells &esdPHcells = *(esd->GetPHOSCells());
2761       Int_t nPHcell = esdPHcells.GetNumberOfCells() ;
2762       
2763       AliAODCaloCells &aodPHcells = *(aod->GetPHOSCells());
2764       aodPHcells.CreateContainer(nPHcell);
2765       aodPHcells.SetType(AliAODCaloCells::kPHOS);
2766       for (Int_t iCell = 0; iCell < nPHcell; iCell++) {      
2767         aodPHcells.SetCell(iCell,esdPHcells.GetCellNumber(iCell),esdPHcells.GetAmplitude(iCell));
2768       }
2769       aodPHcells.Sort();
2770     }
2771
2772     // tracklets    
2773     AliAODTracklets &SPDTracklets = *(aod->GetTracklets());
2774     const AliMultiplicity *mult = esd->GetMultiplicity();
2775     if (mult) {
2776       if (mult->GetNumberOfTracklets()>0) {
2777         SPDTracklets.CreateContainer(mult->GetNumberOfTracklets());
2778
2779         for (Int_t n=0; n<mult->GetNumberOfTracklets(); n++) {
2780           SPDTracklets.SetTracklet(n, mult->GetTheta(n), mult->GetPhi(n), mult->GetDeltaPhi(n), mult->GetLabel(n));
2781         }
2782       }
2783     } else {
2784       Printf("ERROR: AliMultiplicity could not be retrieved from ESD");
2785     }
2786
2787     delete [] usedTrack;
2788     delete [] usedV0;
2789     delete [] usedKink;
2790
2791     // fill the tree for this event
2792     aodTree->Fill();
2793   } // end of event loop
2794
2795   aodTree->GetUserInfo()->Add(aod);
2796
2797   // write the tree to the specified file
2798   aodFile = aodTree->GetCurrentFile();
2799   aodFile->cd();
2800   aodTree->Write();
2801
2802   return;
2803 }
2804
2805 void AliReconstruction::WriteAlignmentData(AliESDEvent* esd)
2806 {
2807   // Write space-points which are then used in the alignment procedures
2808   // For the moment only ITS, TRD and TPC
2809
2810   // Load TOF clusters
2811   if (fTracker[3]){
2812     fLoader[3]->LoadRecPoints("read");
2813     TTree* tree = fLoader[3]->TreeR();
2814     if (!tree) {
2815       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[3]));
2816       return;
2817     }
2818     fTracker[3]->LoadClusters(tree);
2819   }
2820   Int_t ntracks = esd->GetNumberOfTracks();
2821   for (Int_t itrack = 0; itrack < ntracks; itrack++)
2822     {
2823       AliESDtrack *track = esd->GetTrack(itrack);
2824       Int_t nsp = 0;
2825       Int_t idx[200];
2826       for (Int_t iDet = 3; iDet >= 0; iDet--)
2827         nsp += track->GetNcls(iDet);
2828       if (nsp) {
2829         AliTrackPointArray *sp = new AliTrackPointArray(nsp);
2830         track->SetTrackPointArray(sp);
2831         Int_t isptrack = 0;
2832         for (Int_t iDet = 3; iDet >= 0; iDet--) {
2833           AliTracker *tracker = fTracker[iDet];
2834           if (!tracker) continue;
2835           Int_t nspdet = track->GetNcls(iDet);
2836           if (nspdet <= 0) continue;
2837           track->GetClusters(iDet,idx);
2838           AliTrackPoint p;
2839           Int_t isp = 0;
2840           Int_t isp2 = 0;
2841           while (isp2 < nspdet) {
2842             Bool_t isvalid;
2843             TString dets = fgkDetectorName[iDet];
2844             if ((fUseTrackingErrorsForAlignment.CompareTo(dets) == 0) ||
2845             fUseTrackingErrorsForAlignment.BeginsWith(dets+" ") ||
2846             fUseTrackingErrorsForAlignment.EndsWith(" "+dets) ||
2847             fUseTrackingErrorsForAlignment.Contains(" "+dets+" ")) {
2848               isvalid = tracker->GetTrackPointTrackingError(idx[isp2],p,track);
2849             } else {
2850               isvalid = tracker->GetTrackPoint(idx[isp2],p); 
2851             } 
2852             isp2++;
2853             const Int_t kNTPCmax = 159;
2854             if (iDet==1 && isp2>kNTPCmax) break;   // to be fixed
2855             if (!isvalid) continue;
2856             sp->AddPoint(isptrack,&p); isptrack++; isp++;
2857           }
2858         }       
2859       }
2860     }
2861   if (fTracker[3]){
2862     fTracker[3]->UnloadClusters();
2863     fLoader[3]->UnloadRecPoints();
2864   }
2865 }
2866
2867 //_____________________________________________________________________________
2868 void AliReconstruction::FillRawDataErrorLog(Int_t iEvent, AliESDEvent* esd)
2869 {
2870   // The method reads the raw-data error log
2871   // accumulated within the rawReader.
2872   // It extracts the raw-data errors related to
2873   // the current event and stores them into
2874   // a TClonesArray inside the esd object.
2875
2876   if (!fRawReader) return;
2877
2878   for(Int_t i = 0; i < fRawReader->GetNumberOfErrorLogs(); i++) {
2879
2880     AliRawDataErrorLog *log = fRawReader->GetErrorLog(i);
2881     if (!log) continue;
2882     if (iEvent != log->GetEventNumber()) continue;
2883
2884     esd->AddRawDataErrorLog(log);
2885   }
2886
2887 }
2888
2889 TNamed* AliReconstruction::CopyFileToTNamed(TString fPath,TString fName){
2890   // Dump a file content into a char in TNamed
2891   ifstream in;
2892   in.open(fPath.Data(),ios::in | ios::binary|ios::ate);
2893   Int_t kBytes = (Int_t)in.tellg();
2894   printf("Size: %d \n",kBytes);
2895   TNamed *fn = 0;
2896   if(in.good()){
2897     char* memblock = new char [kBytes];
2898     in.seekg (0, ios::beg);
2899     in.read (memblock, kBytes);
2900     in.close();
2901     TString fData(memblock,kBytes);
2902     fn = new TNamed(fName,fData);
2903     printf("fData Size: %d \n",fData.Sizeof());
2904     printf("fName Size: %d \n",fName.Sizeof());
2905     printf("fn    Size: %d \n",fn->Sizeof());
2906     delete[] memblock;
2907   }
2908   else{
2909     AliInfo(Form("Could not Open %s\n",fPath.Data()));
2910   }
2911
2912   return fn;
2913 }
2914
2915 void AliReconstruction::TNamedToFile(TTree* fTree, TString fName){
2916   // This is not really needed in AliReconstruction at the moment
2917   // but can serve as a template
2918
2919   TList *fList = fTree->GetUserInfo();
2920   TNamed *fn = (TNamed*)fList->FindObject(fName.Data());
2921   printf("fn Size: %d \n",fn->Sizeof());
2922
2923   TString fTmp(fn->GetName()); // to be 100% sure in principle fName also works
2924   const char* cdata = fn->GetTitle();
2925   printf("fTmp Size %d\n",fTmp.Sizeof());
2926
2927   int size = fn->Sizeof()-fTmp.Sizeof()-sizeof(UChar_t)-sizeof(Int_t); // see dfinition of TString::SizeOf()...
2928   printf("calculated size %d\n",size);
2929   ofstream out(fName.Data(),ios::out | ios::binary);
2930   out.write(cdata,size);
2931   out.close();
2932
2933 }
2934   
2935 //_____________________________________________________________________________
2936 AliQADataMakerRec * AliReconstruction::GetQADataMaker(Int_t iDet)
2937 {
2938  // get the quality assurance data maker object and the loader for a detector
2939
2940   if (fQADataMaker[iDet]) 
2941     return fQADataMaker[iDet];
2942
2943   AliQADataMakerRec * qadm = NULL;
2944   if (iDet == fgkNDetectors) { //Global QA
2945      qadm = new AliGlobalQADataMaker();
2946      fQADataMaker[iDet] = qadm;
2947      return qadm;
2948   }
2949
2950   // load the QA data maker object
2951   TPluginManager* pluginManager = gROOT->GetPluginManager();
2952   TString detName = fgkDetectorName[iDet];
2953   TString qadmName = "Ali" + detName + "QADataMakerRec";
2954   if (gAlice && !gAlice->GetDetector(detName) && (detName != "HLT")) 
2955     return NULL;
2956
2957   // first check if a plugin is defined for the quality assurance data maker
2958   TPluginHandler* pluginHandler = pluginManager->FindHandler("AliQADataMakerRec", detName);
2959   // if not, add a plugin for it
2960   if (!pluginHandler) {
2961     AliDebug(1, Form("defining plugin for %s", qadmName.Data()));
2962     TString libs = gSystem->GetLibraries();
2963     if (libs.Contains("lib" + detName + "base.so") ||
2964         (gSystem->Load("lib" + detName + "base.so") >= 0)) {
2965       pluginManager->AddHandler("AliQADataMakerRec", detName, 
2966                                 qadmName, detName + "qadm", qadmName + "()");
2967     } else {
2968       pluginManager->AddHandler("AliQADataMakerRec", detName, 
2969                                 qadmName, detName, qadmName + "()");
2970     }
2971     pluginHandler = pluginManager->FindHandler("AliQADataMakerRec", detName);
2972   }
2973   if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
2974     qadm = (AliQADataMakerRec *) pluginHandler->ExecPlugin(0);
2975   }
2976
2977   fQADataMaker[iDet] = qadm;
2978
2979   return qadm;
2980 }
2981
2982 //_____________________________________________________________________________
2983 Bool_t AliReconstruction::RunQA(const char* detectors, AliESDEvent *& esd)
2984 {
2985   // run the Quality Assurance data producer
2986
2987   AliCodeTimerAuto("")
2988   TString detStr = detectors;
2989   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
2990    if (!IsSelected(fgkDetectorName[iDet], detStr)) 
2991      continue;
2992    AliQADataMakerRec * qadm = GetQADataMaker(iDet);
2993    if (!qadm) 
2994      continue;
2995    AliCodeTimerStart(Form("running quality assurance data maker for %s", fgkDetectorName[iDet]));
2996    AliInfo(Form("running quality assurance data maker for %s", fgkDetectorName[iDet]));
2997     
2998    qadm->Exec(AliQA::kESDS, esd) ; 
2999    qadm->Increment() ; 
3000
3001    AliCodeTimerStop(Form("running quality assurance data maker for %s", fgkDetectorName[iDet]));
3002  }
3003  if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
3004    AliError(Form("the following detectors were not found: %s",
3005                  detStr.Data()));
3006    if (fStopOnError) 
3007      return kFALSE;
3008  }
3009  
3010  return kTRUE;
3011   
3012 }
3013
3014 //_____________________________________________________________________________
3015 void AliReconstruction::CheckQA()
3016 {
3017 // check the QA of SIM for this run and remove the detectors 
3018 // with status Fatal
3019   
3020         TString newRunLocalReconstruction ; 
3021         TString newRunTracking ;
3022         TString newFillESD ;
3023          
3024         for (Int_t iDet = 0; iDet < AliQA::kNDET; iDet++) {
3025                 TString detName(AliQA::GetDetName(iDet)) ;
3026                 AliQA * qa = AliQA::Instance(AliQA::DETECTORINDEX(iDet)) ; 
3027                 if ( qa->IsSet(AliQA::DETECTORINDEX(iDet), AliQA::kSIM, AliQA::kFATAL)) {
3028                                 AliInfo(Form("QA status for %s in Hits and/or SDIGITS  and/or Digits was Fatal; No reconstruction performed", detName.Data())) ;
3029                 } else {
3030                         if ( fRunLocalReconstruction.Contains(AliQA::GetDetName(iDet)) || 
3031                                         fRunLocalReconstruction.Contains("ALL") )  {
3032                                 newRunLocalReconstruction += detName ; 
3033                                 newRunLocalReconstruction += " " ;                      
3034                         }
3035                         if ( fRunTracking.Contains(AliQA::GetDetName(iDet)) || 
3036                                         fRunTracking.Contains("ALL") )  {
3037                                 newRunTracking += detName ; 
3038                                 newRunTracking += " " ;                         
3039                         }
3040                         if ( fFillESD.Contains(AliQA::GetDetName(iDet)) || 
3041                                         fFillESD.Contains("ALL") )  {
3042                                 newFillESD += detName ; 
3043                                 newFillESD += " " ;                     
3044                         }
3045                 }
3046         }
3047         fRunLocalReconstruction = newRunLocalReconstruction ; 
3048         fRunTracking            = newRunTracking ; 
3049         fFillESD                = newFillESD ; 
3050 }
3051
3052 //_____________________________________________________________________________
3053 Int_t AliReconstruction::GetDetIndex(const char* detector)
3054 {
3055   // return the detector index corresponding to detector
3056   Int_t index = -1 ; 
3057   for (index = 0; index < fgkNDetectors ; index++) {
3058     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
3059         break ; 
3060   }     
3061   return index ; 
3062 }
3063 //_____________________________________________________________________________
3064 Bool_t AliReconstruction::FinishPlaneEff() {
3065  //
3066  // Here execute all the necessary operationis, at the end of the tracking phase,
3067  // in case that evaluation of PlaneEfficiencies was required for some detector. 
3068  // E.g., write into a DataBase file the PlaneEfficiency which have been evaluated. 
3069  //
3070  // This Preliminary version works only FOR ITS !!!!!
3071  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3072  //
3073  //  Input: none
3074  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise 
3075  //
3076  Bool_t ret=kFALSE;
3077  //for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
3078  for (Int_t iDet = 0; iDet < 1; iDet++) { // for the time being only ITS  
3079    //if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3080    if(fTracker[iDet]) ret=fTracker[iDet]->GetPlaneEff()->WriteIntoCDB();
3081  }
3082  return ret;
3083 }
3084 //_____________________________________________________________________________
3085 Bool_t AliReconstruction::InitPlaneEff() {
3086 //
3087  // Here execute all the necessary operations, before of the tracking phase,
3088  // for the evaluation of PlaneEfficiencies, in case required for some detectors.
3089  // E.g., read from a DataBase file a first evaluation of the PlaneEfficiency 
3090  // which should be updated/recalculated.
3091  //
3092  // This Preliminary version will work only FOR ITS !!!!!
3093  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3094  //
3095  //  Input: none
3096  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3097  //
3098  AliWarning(Form("Implementation of this method not yet done !! Method return kTRUE"));
3099  return kTRUE;
3100 }