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