ff7df710f63546f4214bad3ff1ebf2f51b9cc86b
[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 = AliTracker::
969            PropagateTrackTo(tpcTrack,kRadius,track->GetMass(),kMaxStep,kTRUE);
970       if (ok) {
971         Int_t n=trkArray.GetEntriesFast();
972         selectedIdx[n]=track->GetID();
973         trkArray.AddLast(tpcTrack);
974       }
975
976       if (track->GetX() < kRadius) continue;
977
978       ok = AliTracker::
979            PropagateTrackTo(track,kRadius,track->GetMass(),kMaxStep,kTRUE);
980       if (ok) {
981          track->RelateToVertex(esd->GetPrimaryVertexSPD(), kBz, kRadius);
982       }
983     }
984
985     //
986     // Improve the reconstructed primary vertex position using the tracks
987     //
988     TObject *obj = fOptions.FindObject("ITS");
989     if (obj) {
990       TString optITS = obj->GetTitle();
991       if (optITS.Contains("cosmics") || optITS.Contains("COSMICS")) 
992         fRunVertexFinderTracks=kFALSE;
993     }
994     if (fRunVertexFinderTracks) {
995        // TPC + ITS primary vertex
996        AliESDVertex *pvtx=tVertexer.FindPrimaryVertex(esd);
997        if (pvtx) {
998           if (pvtx->GetStatus()) {
999              esd->SetPrimaryVertex(pvtx);
1000              for (Int_t i=0; i<ntracks; i++) {
1001                  AliESDtrack *t = esd->GetTrack(i);
1002                  t->RelateToVertex(pvtx, kBz, kRadius);
1003              } 
1004           }
1005        }
1006
1007        // TPC-only primary vertex
1008        pvtx=tVertexer.FindPrimaryVertex(&trkArray,selectedIdx);
1009        if (pvtx) {
1010           if (pvtx->GetStatus()) {
1011              esd->SetPrimaryVertexTPC(pvtx);
1012              Int_t nsel=trkArray.GetEntriesFast();
1013              for (Int_t i=0; i<nsel; i++) {
1014                  AliExternalTrackParam *t = 
1015                    (AliExternalTrackParam *)trkArray.UncheckedAt(i);
1016                  t->PropagateToDCA(pvtx, kBz, kRadius);
1017              } 
1018           }
1019        }
1020
1021     }
1022     delete[] selectedIdx;
1023
1024     if(fDiamondProfile) esd->SetDiamond(fDiamondProfile);
1025     
1026
1027     if (fRunV0Finder) {
1028        // V0 finding
1029        AliV0vertexer vtxer;
1030        vtxer.Tracks2V0vertices(esd);
1031
1032        if (fRunCascadeFinder) {
1033           // Cascade finding
1034           AliCascadeVertexer cvtxer;
1035           cvtxer.V0sTracks2CascadeVertices(esd);
1036        }
1037     }
1038  
1039     // write ESD
1040     if (fCleanESD) CleanESD(esd);
1041
1042     if (fRunQA && fRunGlobalQA) {
1043        AliQADataMakerRec *qadm = GetQADataMaker(fgkNDetectors);
1044        if (qadm) qadm->Exec(AliQA::kESDS, esd);
1045     }
1046
1047     if (fWriteESDfriend) {
1048       esdf->~AliESDfriend();
1049       new (esdf) AliESDfriend(); // Reset...
1050       esd->GetESDfriend(esdf);
1051     }
1052     tree->Fill();
1053
1054     // write HLT ESD
1055     hlttree->Fill();
1056
1057     if (fCheckPointLevel > 0)  WriteESD(esd, "final"); 
1058     esd->Reset();
1059     hltesd->Reset();
1060     if (fWriteESDfriend) {
1061       esdf->~AliESDfriend();
1062       new (esdf) AliESDfriend(); // Reset...
1063     }
1064  
1065     gSystem->GetProcInfo(&ProcInfo);
1066     AliInfo(Form("Event %d -> Current memory usage %d %d",iEvent, ProcInfo.fMemResident, ProcInfo.fMemVirtual));
1067   
1068
1069   // End of cycle for the in-loop QA
1070      if (fRunQA && fInLoopQA) {
1071         RunQA(fFillESD.Data(), esd);
1072         TString detStr(fFillESD); 
1073         for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1074            if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1075            AliQADataMakerRec * qadm = GetQADataMaker(iDet);
1076            if (!qadm) continue;
1077            qadm->EndOfCycle(AliQA::kRECPOINTS);
1078            qadm->EndOfCycle(AliQA::kESDS);
1079            qadm->Finish();
1080         }
1081         if (fRunGlobalQA) {
1082            AliQADataMakerRec *qadm = GetQADataMaker(fgkNDetectors);
1083            if (qadm) {
1084               qadm->EndOfCycle(AliQA::kRECPOINTS);
1085               qadm->EndOfCycle(AliQA::kESDS);
1086               qadm->Finish();
1087            }
1088         }
1089      }
1090   } 
1091   //******** End of the loop over events 
1092
1093
1094
1095   tree->GetUserInfo()->Add(esd);
1096   hlttree->GetUserInfo()->Add(hltesd);
1097   
1098   const TMap *cdbMap = AliCDBManager::Instance()->GetStorageMap();       
1099   const TList *cdbList = AliCDBManager::Instance()->GetRetrievedIds();   
1100                  
1101    TMap *cdbMapCopy = new TMap(cdbMap->GetEntries());    
1102    cdbMapCopy->SetOwner(1);      
1103    cdbMapCopy->SetName("cdbMap");        
1104    TIter iter(cdbMap->GetTable());       
1105          
1106    TPair* pair = 0;      
1107    while((pair = dynamic_cast<TPair*> (iter.Next()))){   
1108          TObjString* keyStr = dynamic_cast<TObjString*> (pair->Key());   
1109          TObjString* valStr = dynamic_cast<TObjString*> (pair->Value());         
1110          cdbMapCopy->Add(new TObjString(keyStr->GetName()), new TObjString(valStr->GetName()));  
1111    }     
1112          
1113    TList *cdbListCopy = new TList();     
1114    cdbListCopy->SetOwner(1);     
1115    cdbListCopy->SetName("cdbList");      
1116          
1117    TIter iter2(cdbList);         
1118          
1119    AliCDBId* id=0;       
1120    while((id = dynamic_cast<AliCDBId*> (iter2.Next()))){         
1121          cdbListCopy->Add(new TObjString(id->ToString().Data()));        
1122    }     
1123          
1124    tree->GetUserInfo()->Add(cdbMapCopy);         
1125    tree->GetUserInfo()->Add(cdbListCopy);
1126
1127
1128   if(fESDPar.Contains("ESD.par")){
1129     AliInfo("Attaching ESD.par to Tree");
1130     TNamed *fn = CopyFileToTNamed(fESDPar.Data(),"ESD.par");
1131     tree->GetUserInfo()->Add(fn);
1132   }
1133
1134
1135   file->cd();
1136
1137   if (fWriteESDfriend)
1138     tree->SetBranchStatus("ESDfriend*",0);
1139   // we want to have only one tree version number
1140   tree->Write(tree->GetName(),TObject::kOverwrite);
1141   hlttree->Write();
1142
1143 // Finish with Plane Efficiency evaluation: before of CleanUp !!!
1144   if (fRunPlaneEff && !FinishPlaneEff()) {
1145    AliWarning("Finish PlaneEff evaluation failed");
1146   }
1147
1148   gROOT->cd();
1149   CleanUp(file, fileOld);
1150     
1151   if (fWriteAOD) {
1152     TFile *esdFile = TFile::Open("AliESDs.root", "READONLY");
1153     TFile *aodFile = TFile::Open("AliAOD.root", "RECREATE");
1154     ESDFile2AODFile(esdFile, aodFile);
1155     aodFile->Close();
1156     esdFile->Close();
1157   }
1158
1159   // Create tags for the events in the ESD tree (the ESD tree is always present)
1160   // In case of empty events the tags will contain dummy values
1161   AliESDTagCreator *esdtagCreator = new AliESDTagCreator();
1162   esdtagCreator->CreateESDTags(fFirstEvent,fLastEvent,fGRPList);
1163   if (fWriteAOD) {
1164     AliAODTagCreator *aodtagCreator = new AliAODTagCreator();
1165     aodtagCreator->CreateAODTags(fFirstEvent,fLastEvent,fGRPList);
1166   }
1167
1168   //Finish QA and end of cycle for out-of-loop QA
1169   if (fRunQA && !fInLoopQA) {
1170      qas.Run(fRunLocalReconstruction.Data(), AliQA::kRECPOINTS);
1171      //qas.Reset() ;
1172      qas.Run(fRunTracking.Data(), AliQA::kESDS);
1173
1174      if (fRunGlobalQA) {
1175         AliQADataMakerRec *qadm = GetQADataMaker(fgkNDetectors);
1176         if (qadm) {
1177            qadm->EndOfCycle(AliQA::kRECPOINTS);
1178            qadm->EndOfCycle(AliQA::kESDS);
1179            qadm->Finish();
1180         }
1181      }
1182   }
1183   
1184   // Cleanup of CDB manager: cache and active storages!
1185   AliCDBManager::Instance()->ClearCache();
1186   
1187   
1188   return kTRUE;
1189 }
1190
1191
1192 //_____________________________________________________________________________
1193 Bool_t AliReconstruction::RunLocalReconstruction(const TString& /*detectors*/)
1194 {
1195 // run the local reconstruction
1196   static Int_t eventNr=0;
1197   AliCodeTimerAuto("")
1198
1199  //  AliCDBManager* man = AliCDBManager::Instance();
1200 //   Bool_t origCache = man->GetCacheFlag();
1201
1202 //   TString detStr = detectors;
1203 //   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1204 //     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1205 //     AliReconstructor* reconstructor = GetReconstructor(iDet);
1206 //     if (!reconstructor) continue;
1207 //     if (reconstructor->HasLocalReconstruction()) continue;
1208
1209 //     AliCodeTimerStart(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1210 //     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1211     
1212 //     AliCodeTimerStart(Form("Loading calibration data from OCDB for %s", fgkDetectorName[iDet]));                          
1213 //     AliInfo(Form("Loading calibration data from OCDB for %s", fgkDetectorName[iDet]));
1214
1215 //     man->SetCacheFlag(kTRUE);
1216 //     TString calibPath = Form("%s/Calib/*", fgkDetectorName[iDet]);
1217 //     man->GetAll(calibPath); // entries are cached!
1218
1219 //     AliCodeTimerStop(Form("Loading calibration data from OCDB for %s", fgkDetectorName[iDet]));
1220      
1221 //     if (fRawReader) {
1222 //       fRawReader->RewindEvents();
1223 //       reconstructor->Reconstruct(fRunLoader, fRawReader);
1224 //     } else {
1225 //       reconstructor->Reconstruct(fRunLoader);
1226 //     }
1227      
1228 //      AliCodeTimerStop(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1229     // AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr));
1230
1231 //     // unload calibration data
1232 //     man->UnloadFromCache(calibPath);
1233 //     //man->ClearCache();
1234 //   }
1235
1236 //   man->SetCacheFlag(origCache);
1237
1238 //   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1239 //     AliError(Form("the following detectors were not found: %s",
1240 //                   detStr.Data()));
1241 //     if (fStopOnError) return kFALSE;
1242 //   }
1243
1244           eventNr++;
1245   return kTRUE;
1246 }
1247
1248 //_____________________________________________________________________________
1249 Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
1250 {
1251 // run the local reconstruction
1252
1253   static Int_t eventNr=0;
1254   AliCodeTimerAuto("")
1255
1256   TString detStr = detectors;
1257   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1258     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1259     AliReconstructor* reconstructor = GetReconstructor(iDet);
1260     if (!reconstructor) continue;
1261     AliLoader* loader = fLoader[iDet];
1262     if (!loader) {
1263       AliWarning(Form("No loader is defined for %s!",fgkDetectorName[iDet]));
1264       continue;
1265     }
1266     // conversion of digits
1267     if (fRawReader && reconstructor->HasDigitConversion()) {
1268       AliInfo(Form("converting raw data digits into root objects for %s", 
1269                    fgkDetectorName[iDet]));
1270       AliCodeTimerAuto(Form("converting raw data digits into root objects for %s", 
1271                             fgkDetectorName[iDet]));
1272       loader->LoadDigits("update");
1273       loader->CleanDigits();
1274       loader->MakeDigitsContainer();
1275       TTree* digitsTree = loader->TreeD();
1276       reconstructor->ConvertDigits(fRawReader, digitsTree);
1277       loader->WriteDigits("OVERWRITE");
1278       loader->UnloadDigits();
1279     }
1280     // local reconstruction
1281     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1282     AliCodeTimerAuto(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1283     loader->LoadRecPoints("update");
1284     loader->CleanRecPoints();
1285     loader->MakeRecPointsContainer();
1286     TTree* clustersTree = loader->TreeR();
1287     if (fRawReader && !reconstructor->HasDigitConversion()) {
1288       reconstructor->Reconstruct(fRawReader, clustersTree);
1289     } else {
1290       loader->LoadDigits("read");
1291       TTree* digitsTree = loader->TreeD();
1292       if (!digitsTree) {
1293         AliError(Form("Can't get the %s digits tree", fgkDetectorName[iDet]));
1294         if (fStopOnError) return kFALSE;
1295       } else {
1296         reconstructor->Reconstruct(digitsTree, clustersTree);
1297       }
1298       loader->UnloadDigits();
1299     }
1300
1301     // In-loop QA for local reconstrucion 
1302     if (fRunQA && fInLoopQA) {
1303        AliQADataMakerRec * qadm = GetQADataMaker(iDet);
1304        if (qadm) {
1305           //AliCodeTimerStart
1306           //(Form("Running QA data maker for %s", fgkDetectorName[iDet]));
1307           //AliInfo
1308           //(Form("Running QA data maker for %s", fgkDetectorName[iDet]));
1309
1310           qadm->Exec(AliQA::kRECPOINTS, clustersTree) ;
1311  
1312           //AliCodeTimerStop
1313           //(Form("Running QA data maker for %s", fgkDetectorName[iDet]));
1314        }
1315     }
1316
1317     loader->WriteRecPoints("OVERWRITE");
1318     loader->UnloadRecPoints();
1319     AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr), iDet,1,eventNr);
1320   }
1321
1322   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1323     AliError(Form("the following detectors were not found: %s",
1324                   detStr.Data()));
1325     if (fStopOnError) return kFALSE;
1326   }
1327   eventNr++;
1328   return kTRUE;
1329 }
1330
1331 //_____________________________________________________________________________
1332 Bool_t AliReconstruction::RunVertexFinder(AliESDEvent*& esd)
1333 {
1334 // run the barrel tracking
1335
1336   AliCodeTimerAuto("")
1337
1338   AliESDVertex* vertex = NULL;
1339   Double_t vtxPos[3] = {0, 0, 0};
1340   Double_t vtxErr[3] = {0.07, 0.07, 0.1};
1341   TArrayF mcVertex(3); 
1342   if (fRunLoader->GetHeader() && fRunLoader->GetHeader()->GenEventHeader()) {
1343     fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(mcVertex);
1344     for (Int_t i = 0; i < 3; i++) vtxPos[i] = mcVertex[i];
1345   }
1346
1347   if (fVertexer) {
1348     if(fDiamondProfile) fVertexer->SetVtxStart(fDiamondProfile);
1349     AliInfo("running the ITS vertex finder");
1350     if (fLoader[0]) fLoader[0]->LoadRecPoints();
1351     vertex = fVertexer->FindVertexForCurrentEvent(fRunLoader->GetEventNumber());
1352     if (fLoader[0]) fLoader[0]->UnloadRecPoints();
1353     if(!vertex){
1354       AliWarning("Vertex not found");
1355       vertex = new AliESDVertex();
1356       vertex->SetName("default");
1357     }
1358     else {
1359       vertex->SetName("reconstructed");
1360     }
1361
1362   } else {
1363     AliInfo("getting the primary vertex from MC");
1364     vertex = new AliESDVertex(vtxPos, vtxErr);
1365   }
1366
1367   if (vertex) {
1368     vertex->GetXYZ(vtxPos);
1369     vertex->GetSigmaXYZ(vtxErr);
1370   } else {
1371     AliWarning("no vertex reconstructed");
1372     vertex = new AliESDVertex(vtxPos, vtxErr);
1373   }
1374   esd->SetPrimaryVertexSPD(vertex);
1375   // if SPD multiplicity has been determined, it is stored in the ESD
1376   AliMultiplicity *mult = fVertexer->GetMultiplicity();
1377   if(mult)esd->SetMultiplicity(mult);
1378
1379   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1380     if (fTracker[iDet]) fTracker[iDet]->SetVertex(vtxPos, vtxErr);
1381   }  
1382   delete vertex;
1383
1384   return kTRUE;
1385 }
1386
1387 //_____________________________________________________________________________
1388 Bool_t AliReconstruction::RunHLTTracking(AliESDEvent*& esd)
1389 {
1390 // run the HLT barrel tracking
1391
1392   AliCodeTimerAuto("")
1393
1394   if (!fRunLoader) {
1395     AliError("Missing runLoader!");
1396     return kFALSE;
1397   }
1398
1399   AliInfo("running HLT tracking");
1400
1401   // Get a pointer to the HLT reconstructor
1402   AliReconstructor *reconstructor = GetReconstructor(fgkNDetectors-1);
1403   if (!reconstructor) return kFALSE;
1404
1405   // TPC + ITS
1406   for (Int_t iDet = 1; iDet >= 0; iDet--) {
1407     TString detName = fgkDetectorName[iDet];
1408     AliDebug(1, Form("%s HLT tracking", detName.Data()));
1409     reconstructor->SetOption(detName.Data());
1410     AliTracker *tracker = reconstructor->CreateTracker();
1411     if (!tracker) {
1412       AliWarning(Form("couldn't create a HLT tracker for %s", detName.Data()));
1413       if (fStopOnError) return kFALSE;
1414       continue;
1415     }
1416     Double_t vtxPos[3];
1417     Double_t vtxErr[3]={0.005,0.005,0.010};
1418     const AliESDVertex *vertex = esd->GetVertex();
1419     vertex->GetXYZ(vtxPos);
1420     tracker->SetVertex(vtxPos,vtxErr);
1421     if(iDet != 1) {
1422       fLoader[iDet]->LoadRecPoints("read");
1423       TTree* tree = fLoader[iDet]->TreeR();
1424       if (!tree) {
1425         AliError(Form("Can't get the %s cluster tree", detName.Data()));
1426         return kFALSE;
1427       }
1428       tracker->LoadClusters(tree);
1429     }
1430     if (tracker->Clusters2Tracks(esd) != 0) {
1431       AliError(Form("HLT %s Clusters2Tracks failed", fgkDetectorName[iDet]));
1432       return kFALSE;
1433     }
1434     if(iDet != 1) {
1435       tracker->UnloadClusters();
1436     }
1437     delete tracker;
1438   }
1439
1440   return kTRUE;
1441 }
1442
1443 //_____________________________________________________________________________
1444 Bool_t AliReconstruction::RunMuonTracking(AliESDEvent*& esd)
1445 {
1446 // run the muon spectrometer tracking
1447
1448   AliCodeTimerAuto("")
1449
1450   if (!fRunLoader) {
1451     AliError("Missing runLoader!");
1452     return kFALSE;
1453   }
1454   Int_t iDet = 7; // for MUON
1455
1456   AliInfo("is running...");
1457
1458   // Get a pointer to the MUON reconstructor
1459   AliReconstructor *reconstructor = GetReconstructor(iDet);
1460   if (!reconstructor) return kFALSE;
1461
1462   
1463   TString detName = fgkDetectorName[iDet];
1464   AliDebug(1, Form("%s tracking", detName.Data()));
1465   AliTracker *tracker =  reconstructor->CreateTracker();
1466   if (!tracker) {
1467     AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
1468     return kFALSE;
1469   }
1470      
1471   // read RecPoints
1472   fLoader[iDet]->LoadRecPoints("read");  
1473
1474   tracker->LoadClusters(fLoader[iDet]->TreeR());
1475   
1476   Int_t rv = tracker->Clusters2Tracks(esd);
1477   
1478   if ( rv )
1479   {
1480     AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
1481     return kFALSE;
1482   }
1483   
1484   fLoader[iDet]->UnloadRecPoints();
1485
1486   tracker->UnloadClusters();
1487   
1488   delete tracker;
1489   
1490   return kTRUE;
1491 }
1492
1493
1494 //_____________________________________________________________________________
1495 Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd)
1496 {
1497 // run the barrel tracking
1498   static Int_t eventNr=0;
1499   AliCodeTimerAuto("")
1500
1501   AliInfo("running tracking");
1502
1503   //Fill the ESD with the T0 info (will be used by the TOF) 
1504   if (fReconstructor[11] && fLoader[11]) {
1505     fLoader[11]->LoadRecPoints("READ");
1506     TTree *treeR = fLoader[11]->TreeR();
1507     GetReconstructor(11)->FillESD((TTree *)NULL,treeR,esd);
1508   }
1509
1510   // pass 1: TPC + ITS inwards
1511   for (Int_t iDet = 1; iDet >= 0; iDet--) {
1512     if (!fTracker[iDet]) continue;
1513     AliDebug(1, Form("%s tracking", fgkDetectorName[iDet]));
1514
1515     // load clusters
1516     fLoader[iDet]->LoadRecPoints("read");
1517     AliSysInfo::AddStamp(Form("RLoadCluster%s_%d",fgkDetectorName[iDet],eventNr),iDet,1, eventNr);
1518     TTree* tree = fLoader[iDet]->TreeR();
1519     if (!tree) {
1520       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
1521       return kFALSE;
1522     }
1523     fTracker[iDet]->LoadClusters(tree);
1524     AliSysInfo::AddStamp(Form("TLoadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
1525     // run tracking
1526     if (fTracker[iDet]->Clusters2Tracks(esd) != 0) {
1527       AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
1528       return kFALSE;
1529     }
1530     if (fCheckPointLevel > 1) {
1531       WriteESD(esd, Form("%s.tracking", fgkDetectorName[iDet]));
1532     }
1533     // preliminary PID in TPC needed by the ITS tracker
1534     if (iDet == 1) {
1535       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
1536       AliESDpid::MakePID(esd);
1537     } 
1538     AliSysInfo::AddStamp(Form("Tracking0%s_%d",fgkDetectorName[iDet],eventNr), iDet,3,eventNr);
1539   }
1540
1541   // pass 2: ALL backwards
1542
1543   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1544     if (!fTracker[iDet]) continue;
1545     AliDebug(1, Form("%s back propagation", fgkDetectorName[iDet]));
1546
1547     // load clusters
1548     if (iDet > 1) {     // all except ITS, TPC
1549       TTree* tree = NULL;
1550       fLoader[iDet]->LoadRecPoints("read");
1551       AliSysInfo::AddStamp(Form("RLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,1, eventNr);
1552       tree = fLoader[iDet]->TreeR();
1553       if (!tree) {
1554         AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
1555         return kFALSE;
1556       }
1557       fTracker[iDet]->LoadClusters(tree); 
1558       AliSysInfo::AddStamp(Form("TLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
1559     }
1560
1561     // run tracking
1562     if (fTracker[iDet]->PropagateBack(esd) != 0) {
1563       AliError(Form("%s backward propagation failed", fgkDetectorName[iDet]));
1564       //      return kFALSE;
1565     }
1566     if (fCheckPointLevel > 1) {
1567       WriteESD(esd, Form("%s.back", fgkDetectorName[iDet]));
1568     }
1569
1570     // unload clusters
1571     if (iDet > 2) {     // all except ITS, TPC, TRD
1572       fTracker[iDet]->UnloadClusters();
1573       fLoader[iDet]->UnloadRecPoints();
1574     }
1575     // updated PID in TPC needed by the ITS tracker -MI
1576     if (iDet == 1) {
1577       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
1578       AliESDpid::MakePID(esd);
1579     }
1580     AliSysInfo::AddStamp(Form("Tracking1%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
1581   }
1582
1583   // write space-points to the ESD in case alignment data output
1584   // is switched on
1585   if (fWriteAlignmentData)
1586     WriteAlignmentData(esd);
1587
1588   // pass 3: TRD + TPC + ITS refit inwards
1589
1590   if (fRunQA && fRunGlobalQA) AliTracker::SetFillResiduals(kTRUE);     
1591
1592   for (Int_t iDet = 2; iDet >= 0; iDet--) {
1593     if (!fTracker[iDet]) continue;
1594     AliDebug(1, Form("%s inward refit", fgkDetectorName[iDet]));
1595
1596     // run tracking
1597     if (fTracker[iDet]->RefitInward(esd) != 0) {
1598       AliError(Form("%s inward refit failed", fgkDetectorName[iDet]));
1599       //      return kFALSE;
1600     }
1601     // run postprocessing
1602     if (fTracker[iDet]->PostProcess(esd) != 0) {
1603       AliError(Form("%s postprocessing failed", fgkDetectorName[iDet]));
1604       //      return kFALSE;
1605     }
1606     if (fCheckPointLevel > 1) {
1607       WriteESD(esd, Form("%s.refit", fgkDetectorName[iDet]));
1608     }
1609     AliSysInfo::AddStamp(Form("Tracking2%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
1610     // unload clusters
1611     fTracker[iDet]->UnloadClusters();
1612     AliSysInfo::AddStamp(Form("TUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,4, eventNr);
1613     fLoader[iDet]->UnloadRecPoints();
1614     AliSysInfo::AddStamp(Form("RUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,5, eventNr);
1615   }
1616
1617   if (fRunQA && fRunGlobalQA) AliTracker::SetFillResiduals(kFALSE);     
1618
1619   eventNr++;
1620   return kTRUE;
1621 }
1622
1623 //_____________________________________________________________________________
1624 Bool_t AliReconstruction::CleanESD(AliESDEvent *esd){
1625   //
1626   // Remove the data which are not needed for the physics analysis.
1627   //
1628
1629   Int_t nTracks=esd->GetNumberOfTracks();
1630   Int_t nV0s=esd->GetNumberOfV0s();
1631   AliInfo
1632   (Form("Number of ESD tracks and V0s before cleaning: %d %d",nTracks,nV0s));
1633
1634   Float_t cleanPars[]={fV0DCAmax,fV0CsPmin,fDmax,fZmax};
1635   Bool_t rc=esd->Clean(cleanPars);
1636
1637   nTracks=esd->GetNumberOfTracks();
1638   nV0s=esd->GetNumberOfV0s();
1639   AliInfo
1640   (Form("Number of ESD tracks and V0s after cleaning %d %d",nTracks,nV0s));
1641
1642   return rc;
1643 }
1644
1645 //_____________________________________________________________________________
1646 Bool_t AliReconstruction::FillESD(AliESDEvent*& esd, const TString& detectors)
1647 {
1648 // fill the event summary data
1649
1650   AliCodeTimerAuto("")
1651     static Int_t eventNr=0; 
1652   TString detStr = detectors;
1653   
1654   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1655   if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1656     AliReconstructor* reconstructor = GetReconstructor(iDet);
1657     if (!reconstructor) continue;
1658     if (!ReadESD(esd, fgkDetectorName[iDet])) {
1659       AliDebug(1, Form("filling ESD for %s", fgkDetectorName[iDet]));
1660       TTree* clustersTree = NULL;
1661       if (fLoader[iDet]) {
1662         fLoader[iDet]->LoadRecPoints("read");
1663         clustersTree = fLoader[iDet]->TreeR();
1664         if (!clustersTree) {
1665           AliError(Form("Can't get the %s clusters tree", 
1666                         fgkDetectorName[iDet]));
1667           if (fStopOnError) return kFALSE;
1668         }
1669       }
1670       if (fRawReader && !reconstructor->HasDigitConversion()) {
1671         reconstructor->FillESD(fRawReader, clustersTree, esd);
1672       } else {
1673         TTree* digitsTree = NULL;
1674         if (fLoader[iDet]) {
1675           fLoader[iDet]->LoadDigits("read");
1676           digitsTree = fLoader[iDet]->TreeD();
1677           if (!digitsTree) {
1678             AliError(Form("Can't get the %s digits tree", 
1679                           fgkDetectorName[iDet]));
1680             if (fStopOnError) return kFALSE;
1681           }
1682         }
1683         reconstructor->FillESD(digitsTree, clustersTree, esd);
1684         if (fLoader[iDet]) fLoader[iDet]->UnloadDigits();
1685       }
1686       if (fLoader[iDet]) {
1687         fLoader[iDet]->UnloadRecPoints();
1688       }
1689
1690       if (fCheckPointLevel > 2) WriteESD(esd, fgkDetectorName[iDet]);
1691     }
1692   }
1693
1694   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1695     AliError(Form("the following detectors were not found: %s", 
1696                   detStr.Data()));
1697     if (fStopOnError) return kFALSE;
1698   }
1699   AliSysInfo::AddStamp(Form("FillESD%d",eventNr), 0,1, eventNr);
1700   eventNr++;
1701   return kTRUE;
1702 }
1703
1704 //_____________________________________________________________________________
1705 Bool_t AliReconstruction::FillTriggerESD(AliESDEvent*& esd)
1706 {
1707   // Reads the trigger decision which is
1708   // stored in Trigger.root file and fills
1709   // the corresponding esd entries
1710
1711   AliCodeTimerAuto("")
1712   
1713   AliInfo("Filling trigger information into the ESD");
1714
1715   AliCentralTrigger *aCTP = NULL;
1716
1717   if (fRawReader) {
1718     AliCTPRawStream input(fRawReader);
1719     if (!input.Next()) {
1720       AliError("No valid CTP (trigger) DDL raw data is found ! The trigger information is not stored in the ESD !");
1721       return kFALSE;
1722     }
1723     esd->SetTriggerMask(input.GetClassMask());
1724     esd->SetTriggerCluster(input.GetClusterMask());
1725
1726     aCTP = new AliCentralTrigger();
1727     TString configstr("");
1728     if (!aCTP->LoadConfiguration(configstr)) { // Load CTP config from OCDB
1729       AliError("No trigger configuration found in OCDB! The trigger classes information will no be stored in ESD!");
1730       return kFALSE;
1731     }
1732   }
1733   else {
1734     AliRunLoader *runloader = AliRunLoader::GetRunLoader();
1735     if (runloader) {
1736       if (!runloader->LoadTrigger()) {
1737         aCTP = runloader->GetTrigger();
1738         esd->SetTriggerMask(aCTP->GetClassMask());
1739         esd->SetTriggerCluster(aCTP->GetClusterMask());
1740       }
1741       else {
1742         AliWarning("No trigger can be loaded! The trigger information is not stored in the ESD !");
1743         return kFALSE;
1744       }
1745     }
1746     else {
1747       AliError("No run loader is available! The trigger information is not stored in the ESD !");
1748       return kFALSE;
1749     }
1750   }
1751
1752   // Now fill the trigger class names into AliESDRun object
1753   AliTriggerConfiguration *config = aCTP->GetConfiguration();
1754   if (!config) {
1755     AliError("No trigger configuration has been found! The trigger classes information will no be stored in ESD!");
1756     return kFALSE;
1757   }
1758
1759   const TObjArray& classesArray = config->GetClasses();
1760   Int_t nclasses = classesArray.GetEntriesFast();
1761   for( Int_t j=0; j<nclasses; j++ ) {
1762     AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At( j );
1763     Int_t trindex = (Int_t)TMath::Log2(trclass->GetMask());
1764     esd->SetTriggerClass(trclass->GetName(),trindex);
1765   }
1766
1767   return kTRUE;
1768 }
1769
1770
1771
1772
1773
1774 //_____________________________________________________________________________
1775 Bool_t AliReconstruction::FillRawEventHeaderESD(AliESDEvent*& esd)
1776 {
1777   // 
1778   // Filling information from RawReader Header
1779   // 
1780
1781   AliInfo("Filling information from RawReader Header");
1782   esd->SetBunchCrossNumber(0);
1783   esd->SetOrbitNumber(0);
1784   esd->SetPeriodNumber(0);
1785   esd->SetTimeStamp(0);
1786   esd->SetEventType(0);
1787   const AliRawEventHeaderBase * eventHeader = fRawReader->GetEventHeader();
1788   if (eventHeader){
1789
1790     const UInt_t *id = eventHeader->GetP("Id");
1791     esd->SetBunchCrossNumber((id)[1]&0x00000fff);
1792     esd->SetOrbitNumber((((id)[0]<<20)&0xf00000)|(((id)[1]>>12)&0xfffff));
1793     esd->SetPeriodNumber(((id)[0]>>4)&0x0fffffff);
1794
1795     esd->SetTimeStamp((eventHeader->Get("Timestamp")));  
1796     esd->SetEventType((eventHeader->Get("Type")));
1797   }
1798
1799   return kTRUE;
1800 }
1801
1802
1803 //_____________________________________________________________________________
1804 Bool_t AliReconstruction::IsSelected(TString detName, TString& detectors) const
1805 {
1806 // check whether detName is contained in detectors
1807 // if yes, it is removed from detectors
1808
1809   // check if all detectors are selected
1810   if ((detectors.CompareTo("ALL") == 0) ||
1811       detectors.BeginsWith("ALL ") ||
1812       detectors.EndsWith(" ALL") ||
1813       detectors.Contains(" ALL ")) {
1814     detectors = "ALL";
1815     return kTRUE;
1816   }
1817
1818   // search for the given detector
1819   Bool_t result = kFALSE;
1820   if ((detectors.CompareTo(detName) == 0) ||
1821       detectors.BeginsWith(detName+" ") ||
1822       detectors.EndsWith(" "+detName) ||
1823       detectors.Contains(" "+detName+" ")) {
1824     detectors.ReplaceAll(detName, "");
1825     result = kTRUE;
1826   }
1827
1828   // clean up the detectors string
1829   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
1830   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
1831   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
1832
1833   return result;
1834 }
1835
1836 //_____________________________________________________________________________
1837 Bool_t AliReconstruction::InitRunLoader()
1838 {
1839 // get or create the run loader
1840
1841   if (gAlice) delete gAlice;
1842   gAlice = NULL;
1843
1844   if (!gSystem->AccessPathName(fGAliceFileName.Data())) { // galice.root exists
1845     // load all base libraries to get the loader classes
1846     TString libs = gSystem->GetLibraries();
1847     for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1848       TString detName = fgkDetectorName[iDet];
1849       if (detName == "HLT") continue;
1850       if (libs.Contains("lib" + detName + "base.so")) continue;
1851       gSystem->Load("lib" + detName + "base.so");
1852     }
1853     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data());
1854     if (!fRunLoader) {
1855       AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
1856       CleanUp();
1857       return kFALSE;
1858     }
1859     fRunLoader->CdGAFile();
1860     if (gFile->GetKey(AliRunLoader::GetGAliceName())) {
1861       if (fRunLoader->LoadgAlice() == 0) {
1862         gAlice = fRunLoader->GetAliRun();
1863         AliTracker::SetFieldMap(gAlice->Field(),fUniformField);
1864       }
1865     }
1866     if (!gAlice && !fRawReader) {
1867       AliError(Form("no gAlice object found in file %s",
1868                     fGAliceFileName.Data()));
1869       CleanUp();
1870       return kFALSE;
1871     }
1872
1873     //PH This is a temporary fix to give access to the kinematics
1874     //PH that is needed for the labels of ITS clusters
1875     fRunLoader->LoadHeader();
1876     fRunLoader->LoadKinematics();
1877
1878   } else {               // galice.root does not exist
1879     if (!fRawReader) {
1880       AliError(Form("the file %s does not exist", fGAliceFileName.Data()));
1881       CleanUp();
1882       return kFALSE;
1883     }
1884     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data(),
1885                                     AliConfig::GetDefaultEventFolderName(),
1886                                     "recreate");
1887     if (!fRunLoader) {
1888       AliError(Form("could not create run loader in file %s", 
1889                     fGAliceFileName.Data()));
1890       CleanUp();
1891       return kFALSE;
1892     }
1893     fRunLoader->MakeTree("E");
1894     Int_t iEvent = 0;
1895     while (fRawReader->NextEvent()) {
1896       fRunLoader->SetEventNumber(iEvent);
1897       fRunLoader->GetHeader()->Reset(fRawReader->GetRunNumber(), 
1898                                      iEvent, iEvent);
1899       fRunLoader->MakeTree("H");
1900       fRunLoader->TreeE()->Fill();
1901       iEvent++;
1902     }
1903     fRawReader->RewindEvents();
1904     if (fNumberOfEventsPerFile > 0)
1905       fRunLoader->SetNumberOfEventsPerFile(fNumberOfEventsPerFile);
1906     else
1907       fRunLoader->SetNumberOfEventsPerFile(iEvent);
1908     fRunLoader->WriteHeader("OVERWRITE");
1909     fRunLoader->CdGAFile();
1910     fRunLoader->Write(0, TObject::kOverwrite);
1911 //    AliTracker::SetFieldMap(???);
1912   }
1913
1914   return kTRUE;
1915 }
1916
1917 //_____________________________________________________________________________
1918 AliReconstructor* AliReconstruction::GetReconstructor(Int_t iDet)
1919 {
1920 // get the reconstructor object and the loader for a detector
1921
1922   if (fReconstructor[iDet]) return fReconstructor[iDet];
1923
1924   // load the reconstructor object
1925   TPluginManager* pluginManager = gROOT->GetPluginManager();
1926   TString detName = fgkDetectorName[iDet];
1927   TString recName = "Ali" + detName + "Reconstructor";
1928   if (gAlice && !gAlice->GetDetector(detName) && (detName != "HLT")) return NULL;
1929
1930   AliReconstructor* reconstructor = NULL;
1931   // first check if a plugin is defined for the reconstructor
1932   TPluginHandler* pluginHandler = 
1933     pluginManager->FindHandler("AliReconstructor", detName);
1934   // if not, add a plugin for it
1935   if (!pluginHandler) {
1936     AliDebug(1, Form("defining plugin for %s", recName.Data()));
1937     TString libs = gSystem->GetLibraries();
1938     if (libs.Contains("lib" + detName + "base.so") ||
1939         (gSystem->Load("lib" + detName + "base.so") >= 0)) {
1940       pluginManager->AddHandler("AliReconstructor", detName, 
1941                                 recName, detName + "rec", recName + "()");
1942     } else {
1943       pluginManager->AddHandler("AliReconstructor", detName, 
1944                                 recName, detName, recName + "()");
1945     }
1946     pluginHandler = pluginManager->FindHandler("AliReconstructor", detName);
1947   }
1948   if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
1949     reconstructor = (AliReconstructor*) pluginHandler->ExecPlugin(0);
1950   }
1951   if (reconstructor) {
1952     TObject* obj = fOptions.FindObject(detName.Data());
1953     if (obj) reconstructor->SetOption(obj->GetTitle());
1954     reconstructor->Init();
1955     fReconstructor[iDet] = reconstructor;
1956   }
1957
1958   // get or create the loader
1959   if (detName != "HLT") {
1960     fLoader[iDet] = fRunLoader->GetLoader(detName + "Loader");
1961     if (!fLoader[iDet]) {
1962       AliConfig::Instance()
1963         ->CreateDetectorFolders(fRunLoader->GetEventFolder(), 
1964                                 detName, detName);
1965       // first check if a plugin is defined for the loader
1966       pluginHandler = 
1967         pluginManager->FindHandler("AliLoader", detName);
1968       // if not, add a plugin for it
1969       if (!pluginHandler) {
1970         TString loaderName = "Ali" + detName + "Loader";
1971         AliDebug(1, Form("defining plugin for %s", loaderName.Data()));
1972         pluginManager->AddHandler("AliLoader", detName, 
1973                                   loaderName, detName + "base", 
1974                                   loaderName + "(const char*, TFolder*)");
1975         pluginHandler = pluginManager->FindHandler("AliLoader", detName);
1976       }
1977       if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
1978         fLoader[iDet] = 
1979           (AliLoader*) pluginHandler->ExecPlugin(2, detName.Data(), 
1980                                                  fRunLoader->GetEventFolder());
1981       }
1982       if (!fLoader[iDet]) {   // use default loader
1983         fLoader[iDet] = new AliLoader(detName, fRunLoader->GetEventFolder());
1984       }
1985       if (!fLoader[iDet]) {
1986         AliWarning(Form("couldn't get loader for %s", detName.Data()));
1987         if (fStopOnError) return NULL;
1988       } else {
1989         fRunLoader->AddLoader(fLoader[iDet]);
1990         fRunLoader->CdGAFile();
1991         if (gFile && !gFile->IsWritable()) gFile->ReOpen("UPDATE");
1992         fRunLoader->Write(0, TObject::kOverwrite);
1993       }
1994     }
1995   }
1996       
1997   return reconstructor;
1998 }
1999
2000 //_____________________________________________________________________________
2001 Bool_t AliReconstruction::CreateVertexer()
2002 {
2003 // create the vertexer
2004
2005   fVertexer = NULL;
2006   AliReconstructor* itsReconstructor = GetReconstructor(0);
2007   if (itsReconstructor) {
2008     fVertexer = itsReconstructor->CreateVertexer();
2009   }
2010   if (!fVertexer) {
2011     AliWarning("couldn't create a vertexer for ITS");
2012     if (fStopOnError) return kFALSE;
2013   }
2014
2015   return kTRUE;
2016 }
2017
2018 //_____________________________________________________________________________
2019 Bool_t AliReconstruction::CreateTrackers(const TString& detectors)
2020 {
2021 // create the trackers
2022
2023   TString detStr = detectors;
2024   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
2025     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2026     AliReconstructor* reconstructor = GetReconstructor(iDet);
2027     if (!reconstructor) continue;
2028     TString detName = fgkDetectorName[iDet];
2029     if (detName == "HLT") {
2030       fRunHLTTracking = kTRUE;
2031       continue;
2032     }
2033     if (detName == "MUON") {
2034       fRunMuonTracking = kTRUE;
2035       continue;
2036     }
2037
2038
2039     fTracker[iDet] = reconstructor->CreateTracker();
2040     if (!fTracker[iDet] && (iDet < 7)) {
2041       AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
2042       if (fStopOnError) return kFALSE;
2043     }
2044     AliSysInfo::AddStamp(Form("LTracker%s",fgkDetectorName[iDet]), iDet,0);
2045   }
2046
2047   return kTRUE;
2048 }
2049
2050 //_____________________________________________________________________________
2051 void AliReconstruction::CleanUp(TFile* file, TFile* fileOld)
2052 {
2053 // delete trackers and the run loader and close and delete the file
2054
2055   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
2056     delete fReconstructor[iDet];
2057     fReconstructor[iDet] = NULL;
2058     fLoader[iDet] = NULL;
2059     delete fTracker[iDet];
2060     fTracker[iDet] = NULL;
2061 //    delete fQADataMaker[iDet];
2062 //    fQADataMaker[iDet] = NULL;
2063   }
2064   delete fVertexer;
2065   fVertexer = NULL;
2066   
2067   if(!(AliCDBManager::Instance()->GetCacheFlag())) {
2068         delete fDiamondProfile;
2069         fDiamondProfile = NULL;
2070   }
2071
2072   delete fGRPList;
2073   fGRPList = NULL;
2074
2075   delete fRunLoader;
2076   fRunLoader = NULL;
2077   delete fRawReader;
2078   fRawReader = NULL;
2079   if (fParentRawReader) delete fParentRawReader;
2080   fParentRawReader=NULL;
2081
2082   if (file) {
2083     file->Close();
2084     delete file;
2085   }
2086
2087   if (fileOld) {
2088     fileOld->Close();
2089     delete fileOld;
2090     gSystem->Unlink("AliESDs.old.root");
2091   }
2092 }
2093
2094 //_____________________________________________________________________________
2095
2096 Bool_t AliReconstruction::ReadESD(AliESDEvent*& esd, const char* recStep) const
2097 {
2098 // read the ESD event from a file
2099
2100   if (!esd) return kFALSE;
2101   char fileName[256];
2102   sprintf(fileName, "ESD_%d.%d_%s.root", 
2103           esd->GetRunNumber(), esd->GetEventNumberInFile(), recStep);
2104   if (gSystem->AccessPathName(fileName)) return kFALSE;
2105
2106   AliInfo(Form("reading ESD from file %s", fileName));
2107   AliDebug(1, Form("reading ESD from file %s", fileName));
2108   TFile* file = TFile::Open(fileName);
2109   if (!file || !file->IsOpen()) {
2110     AliError(Form("opening %s failed", fileName));
2111     delete file;
2112     return kFALSE;
2113   }
2114
2115   gROOT->cd();
2116   delete esd;
2117   esd = (AliESDEvent*) file->Get("ESD");
2118   file->Close();
2119   delete file;
2120   return kTRUE;
2121
2122 }
2123
2124
2125
2126 //_____________________________________________________________________________
2127 void AliReconstruction::WriteESD(AliESDEvent* esd, const char* recStep) const
2128 {
2129 // write the ESD event to a file
2130
2131   if (!esd) return;
2132   char fileName[256];
2133   sprintf(fileName, "ESD_%d.%d_%s.root", 
2134           esd->GetRunNumber(), esd->GetEventNumberInFile(), recStep);
2135
2136   AliDebug(1, Form("writing ESD to file %s", fileName));
2137   TFile* file = TFile::Open(fileName, "recreate");
2138   if (!file || !file->IsOpen()) {
2139     AliError(Form("opening %s failed", fileName));
2140   } else {
2141     esd->Write("ESD");
2142     file->Close();
2143   }
2144   delete file;
2145 }
2146
2147
2148
2149
2150
2151 //_____________________________________________________________________________
2152 void AliReconstruction::ESDFile2AODFile(TFile* esdFile, TFile* aodFile)
2153 {
2154   // write all files from the given esd file to an aod file
2155
2156   // create an AliAOD object 
2157   AliAODEvent *aod = new AliAODEvent();
2158   aod->CreateStdContent();
2159   
2160   // go to the file
2161   aodFile->cd();
2162   
2163   // create the tree
2164   TTree *aodTree = new TTree("aodTree", "AliAOD tree");
2165   aodTree->Branch(aod->GetList());
2166
2167   // connect to ESD
2168   TTree *t = (TTree*) esdFile->Get("esdTree");
2169   AliESDEvent *esd = new AliESDEvent();
2170   esd->ReadFromTree(t);
2171
2172   Int_t nEvents = t->GetEntries();
2173
2174   // set arrays and pointers
2175   Float_t posF[3];
2176   Double_t pos[3];
2177   Double_t p[3];
2178   Double_t p_pos[3];
2179   Double_t p_neg[3];
2180   Double_t covVtx[6];
2181   Double_t covTr[21];
2182   Double_t pid[10];
2183
2184   // loop over events and fill them
2185   for (Int_t iEvent = 0; iEvent < nEvents; ++iEvent) {
2186     //cout << "event: " << iEvent << endl;
2187     t->GetEntry(iEvent);
2188
2189     // Multiplicity information needed by the header (to be revised!)
2190     Int_t nTracks   = esd->GetNumberOfTracks();
2191     Int_t nPosTracks = 0;
2192     for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) 
2193       if (esd->GetTrack(iTrack)->Charge()> 0) nPosTracks++;
2194
2195     // Access the header
2196     AliAODHeader *header = aod->GetHeader();
2197
2198     // fill the header
2199     header->SetRunNumber       (esd->GetRunNumber()       );
2200     header->SetBunchCrossNumber(esd->GetBunchCrossNumber());
2201     header->SetOrbitNumber     (esd->GetOrbitNumber()     );
2202     header->SetPeriodNumber    (esd->GetPeriodNumber()    );
2203     header->SetTriggerMask     (esd->GetTriggerMask()     ); 
2204     header->SetTriggerCluster  (esd->GetTriggerCluster()  );
2205     header->SetEventType       (esd->GetEventType()       );
2206     header->SetMagneticField   (esd->GetMagneticField()   );
2207     header->SetZDCN1Energy     (esd->GetZDCN1Energy()     );
2208     header->SetZDCP1Energy     (esd->GetZDCP1Energy()     );
2209     header->SetZDCN2Energy     (esd->GetZDCN2Energy()     );
2210     header->SetZDCP2Energy     (esd->GetZDCP2Energy()     );
2211     header->SetZDCEMEnergy     (esd->GetZDCEMEnergy(0),esd->GetZDCEMEnergy(1));
2212     header->SetRefMultiplicity   (nTracks);
2213     header->SetRefMultiplicityPos(nPosTracks);
2214     header->SetRefMultiplicityNeg(nTracks - nPosTracks);
2215     header->SetMuonMagFieldScale(-999.); // FIXME
2216     header->SetCentrality(-999.);        // FIXME
2217
2218     Int_t nV0s      = esd->GetNumberOfV0s();
2219     Int_t nCascades = esd->GetNumberOfCascades();
2220     Int_t nKinks    = esd->GetNumberOfKinks();
2221         Int_t nVertices = nV0s + 2*nCascades /*could lead to two vertices, one V0 and the Xi */+ nKinks + 1 /* = prim. vtx*/;    
2222         Int_t nJets     = 0;
2223     Int_t nCaloClus = esd->GetNumberOfCaloClusters();
2224     Int_t nFmdClus  = 0;
2225     Int_t nPmdClus  = esd->GetNumberOfPmdTracks();
2226    
2227     aod->ResetStd(nTracks, nVertices, nV0s+nCascades, nJets, nCaloClus, nFmdClus, nPmdClus);
2228     
2229     // Array to take into account the tracks already added to the AOD
2230     Bool_t * usedTrack = NULL;
2231     if (nTracks>0) {
2232       usedTrack = new Bool_t[nTracks];
2233       for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) usedTrack[iTrack]=kFALSE;
2234     }
2235     // Array to take into account the V0s already added to the AOD
2236     Bool_t * usedV0 = NULL;
2237     if (nV0s>0) {
2238       usedV0 = new Bool_t[nV0s];
2239       for (Int_t iV0=0; iV0<nV0s; ++iV0) usedV0[iV0]=kFALSE;
2240     }
2241     // Array to take into account the kinks already added to the AOD
2242     Bool_t * usedKink = NULL;
2243     if (nKinks>0) {
2244       usedKink = new Bool_t[nKinks];
2245       for (Int_t iKink=0; iKink<nKinks; ++iKink) usedKink[iKink]=kFALSE;
2246     }
2247     
2248     // Access to the AOD container of vertices
2249     TClonesArray &vertices = *(aod->GetVertices());
2250     Int_t jVertices=0;
2251
2252     // Access to the AOD container of tracks
2253     TClonesArray &tracks = *(aod->GetTracks());
2254     Int_t jTracks=0; 
2255    
2256     // Access to the AOD container of V0s
2257     TClonesArray &V0s = *(aod->GetV0s());
2258     Int_t jV0s=0;
2259     
2260     // Add primary vertex. The primary tracks will be defined
2261     // after the loops on the composite objects (V0, cascades, kinks)
2262     const AliESDVertex *vtx = esd->GetPrimaryVertex();
2263       
2264     vtx->GetXYZ(pos); // position
2265     vtx->GetCovMatrix(covVtx); //covariance matrix
2266
2267     AliAODVertex * primary = new(vertices[jVertices++])
2268       AliAODVertex(pos, covVtx, vtx->GetChi2toNDF(), NULL, -1, AliAODVertex::kPrimary);
2269          
2270
2271     AliAODTrack *aodTrack = 0x0;
2272     
2273     // Create vertices starting from the most complex objects
2274
2275     // Cascades
2276     for (Int_t nCascade = 0; nCascade < nCascades; ++nCascade) {
2277       AliESDcascade *cascade = esd->GetCascade(nCascade);
2278       
2279       cascade->GetXYZ(pos[0], pos[1], pos[2]);
2280       cascade->GetPosCovXi(covVtx);
2281      
2282       // Add the cascade vertex
2283       AliAODVertex * vcascade = new(vertices[jVertices++]) AliAODVertex(pos,
2284                                                                         covVtx,
2285                                                                         cascade->GetChi2Xi(), // = chi2/NDF since NDF = 2*2-3
2286                                                                         primary,
2287                                                                         nCascade,
2288                                                                         AliAODVertex::kCascade);
2289
2290       primary->AddDaughter(vcascade); // the cascade 'particle' (represented by a vertex) is added as a daughter to the primary vertex
2291
2292       // Add the V0 from the cascade. The ESD class have to be optimized...
2293       // Now we have to search for the corresponding V0 in the list of V0s
2294       // using the indeces of the positive and negative tracks
2295
2296       Int_t posFromV0 = cascade->GetPindex();
2297       Int_t negFromV0 = cascade->GetNindex();
2298
2299
2300       AliESDv0 * v0 = 0x0;
2301       Int_t indV0 = -1;
2302
2303       for (Int_t iV0=0; iV0<nV0s; ++iV0) {
2304
2305         v0 = esd->GetV0(iV0);
2306         Int_t posV0 = v0->GetPindex();
2307         Int_t negV0 = v0->GetNindex();
2308
2309         if (posV0==posFromV0 && negV0==negFromV0) {
2310           indV0 = iV0;
2311           break;
2312         }
2313       }
2314
2315       AliAODVertex * vV0FromCascade = 0x0;
2316
2317       if (indV0>-1 && !usedV0[indV0]) {
2318         
2319         // the V0 exists in the array of V0s and is not used
2320
2321         usedV0[indV0] = kTRUE;
2322         
2323         v0->GetXYZ(pos[0], pos[1], pos[2]);
2324         v0->GetPosCov(covVtx);
2325         
2326         vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
2327                                                                  covVtx,
2328                                                                  v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
2329                                                                  vcascade,
2330                                                                  indV0,
2331                                                                  AliAODVertex::kV0);
2332       } else {
2333
2334         // the V0 doesn't exist in the array of V0s or was used
2335         cerr << "Error: event " << iEvent << " cascade " << nCascade
2336              << " The V0 " << indV0 
2337              << " doesn't exist in the array of V0s or was used!" << endl;
2338
2339         cascade->GetXYZ(pos[0], pos[1], pos[2]);
2340         cascade->GetPosCov(covVtx);
2341       
2342         vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
2343                                                                  covVtx,
2344                                                                  v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
2345                                                                  vcascade,
2346                                                                  indV0,
2347                                                                  AliAODVertex::kV0);
2348         vcascade->AddDaughter(vV0FromCascade);
2349
2350       }
2351
2352       // Add the positive tracks from the V0
2353
2354       if (! usedTrack[posFromV0]) {
2355
2356         usedTrack[posFromV0] = kTRUE;
2357
2358         AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
2359         esdTrack->GetPxPyPz(p_pos);
2360         esdTrack->GetXYZ(pos);
2361         esdTrack->GetCovarianceXYZPxPyPz(covTr);
2362         esdTrack->GetESDpid(pid);
2363         
2364         vV0FromCascade->AddDaughter(aodTrack =
2365                                     new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2366                                            esdTrack->GetLabel(), 
2367                                            p_pos, 
2368                                            kTRUE,
2369                                            pos,
2370                                            kFALSE,
2371                                            covTr, 
2372                                            (Short_t)esdTrack->Charge(),
2373                                            esdTrack->GetITSClusterMap(), 
2374                                            pid,
2375                                            vV0FromCascade,
2376                                            kTRUE,  // check if this is right
2377                                            kFALSE, // check if this is right
2378                                            AliAODTrack::kSecondary)
2379                 );
2380         aodTrack->ConvertAliPIDtoAODPID();
2381       }
2382       else {
2383         cerr << "Error: event " << iEvent << " cascade " << nCascade
2384              << " track " << posFromV0 << " has already been used!" << endl;
2385       }
2386
2387       // Add the negative tracks from the V0
2388
2389       if (!usedTrack[negFromV0]) {
2390         
2391         usedTrack[negFromV0] = kTRUE;
2392         
2393         AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
2394         esdTrack->GetPxPyPz(p_neg);
2395         esdTrack->GetXYZ(pos);
2396         esdTrack->GetCovarianceXYZPxPyPz(covTr);
2397         esdTrack->GetESDpid(pid);
2398         
2399         vV0FromCascade->AddDaughter(aodTrack =
2400                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2401                                            esdTrack->GetLabel(),
2402                                            p_neg,
2403                                            kTRUE,
2404                                            pos,
2405                                            kFALSE,
2406                                            covTr, 
2407                                            (Short_t)esdTrack->Charge(),
2408                                            esdTrack->GetITSClusterMap(), 
2409                                            pid,
2410                                            vV0FromCascade,
2411                                            kTRUE,  // check if this is right
2412                                            kFALSE, // check if this is right
2413                                            AliAODTrack::kSecondary)
2414                 );
2415         aodTrack->ConvertAliPIDtoAODPID();
2416       }
2417       else {
2418         cerr << "Error: event " << iEvent << " cascade " << nCascade
2419              << " track " << negFromV0 << " has already been used!" << endl;
2420       }
2421
2422       // add it to the V0 array as well
2423       Double_t d0[2] = { -999., -99.};
2424       // counting is probably wrong
2425       new(V0s[jV0s++]) AliAODv0(vV0FromCascade, -999., -99., p_pos, p_neg, d0); // to be refined
2426
2427       // Add the bachelor track from the cascade
2428
2429       Int_t bachelor = cascade->GetBindex();
2430       
2431       if(!usedTrack[bachelor]) {
2432       
2433         usedTrack[bachelor] = kTRUE;
2434         
2435         AliESDtrack *esdTrack = esd->GetTrack(bachelor);
2436         esdTrack->GetPxPyPz(p);
2437         esdTrack->GetXYZ(pos);
2438         esdTrack->GetCovarianceXYZPxPyPz(covTr);
2439         esdTrack->GetESDpid(pid);
2440
2441         vcascade->AddDaughter(aodTrack =
2442                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2443                                            esdTrack->GetLabel(),
2444                                            p,
2445                                            kTRUE,
2446                                            pos,
2447                                            kFALSE,
2448                                            covTr, 
2449                                            (Short_t)esdTrack->Charge(),
2450                                            esdTrack->GetITSClusterMap(), 
2451                                            pid,
2452                                            vcascade,
2453                                            kTRUE,  // check if this is right
2454                                            kFALSE, // check if this is right
2455                                            AliAODTrack::kSecondary)
2456                 );
2457         aodTrack->ConvertAliPIDtoAODPID();
2458      }
2459       else {
2460         cerr << "Error: event " << iEvent << " cascade " << nCascade
2461              << " track " << bachelor << " has already been used!" << endl;
2462       }
2463       
2464       // Add the primary track of the cascade (if any)
2465       
2466     } // end of the loop on cascades
2467  
2468     // V0s
2469         
2470     for (Int_t nV0 = 0; nV0 < nV0s; ++nV0) {
2471
2472       if (usedV0[nV0]) continue; // skip if aready added to the AOD
2473
2474       AliESDv0 *v0 = esd->GetV0(nV0); 
2475      
2476       v0->GetXYZ(pos[0], pos[1], pos[2]);
2477       v0->GetPosCov(covVtx);
2478
2479       AliAODVertex * vV0 = 
2480         new(vertices[jVertices++]) AliAODVertex(pos,
2481                                                 covVtx,
2482                                                 v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
2483                                                 primary,
2484                                                 nV0,
2485                                                 AliAODVertex::kV0);
2486       primary->AddDaughter(vV0);
2487
2488       Int_t posFromV0 = v0->GetPindex();
2489       Int_t negFromV0 = v0->GetNindex();
2490       
2491       // Add the positive tracks from the V0
2492
2493       if (!usedTrack[posFromV0]) {
2494         
2495         usedTrack[posFromV0] = kTRUE;
2496
2497         AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
2498         esdTrack->GetPxPyPz(p_pos);
2499         esdTrack->GetXYZ(pos);
2500         esdTrack->GetCovarianceXYZPxPyPz(covTr);
2501         esdTrack->GetESDpid(pid);
2502         
2503         vV0->AddDaughter(aodTrack =
2504                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2505                                            esdTrack->GetLabel(), 
2506                                            p_pos, 
2507                                            kTRUE,
2508                                            pos,
2509                                            kFALSE,
2510                                            covTr, 
2511                                            (Short_t)esdTrack->Charge(),
2512                                            esdTrack->GetITSClusterMap(), 
2513                                            pid,
2514                                            vV0,
2515                                            kTRUE,  // check if this is right
2516                                            kFALSE, // check if this is right
2517                                            AliAODTrack::kSecondary)
2518                 );
2519         aodTrack->ConvertAliPIDtoAODPID();
2520       }
2521       else {
2522         cerr << "Error: event " << iEvent << " V0 " << nV0
2523              << " track " << posFromV0 << " has already been used!" << endl;
2524       }
2525
2526       // Add the negative tracks from the V0
2527
2528       if (!usedTrack[negFromV0]) {
2529
2530         usedTrack[negFromV0] = kTRUE;
2531
2532         AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
2533         esdTrack->GetPxPyPz(p_neg);
2534         esdTrack->GetXYZ(pos);
2535         esdTrack->GetCovarianceXYZPxPyPz(covTr);
2536         esdTrack->GetESDpid(pid);
2537
2538         vV0->AddDaughter(aodTrack =
2539                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2540                                            esdTrack->GetLabel(),
2541                                            p_neg,
2542                                            kTRUE,
2543                                            pos,
2544                                            kFALSE,
2545                                            covTr, 
2546                                            (Short_t)esdTrack->Charge(),
2547                                            esdTrack->GetITSClusterMap(), 
2548                                            pid,
2549                                            vV0,
2550                                            kTRUE,  // check if this is right
2551                                            kFALSE, // check if this is right
2552                                            AliAODTrack::kSecondary)
2553                 );
2554         aodTrack->ConvertAliPIDtoAODPID();
2555       }
2556       else {
2557         cerr << "Error: event " << iEvent << " V0 " << nV0
2558              << " track " << negFromV0 << " has already been used!" << endl;
2559       }
2560
2561       // add it to the V0 array as well
2562       Double_t d0[2] = { 999., 99.};
2563       new(V0s[jV0s++]) AliAODv0(vV0, 999., 99., p_pos, p_neg, d0); // to be refined
2564     }
2565         V0s.Expand(jV0s);        
2566     // end of the loop on V0s
2567     
2568     // Kinks: it is a big mess the access to the information in the kinks
2569     // The loop is on the tracks in order to find the mother and daugther of each kink
2570
2571
2572     for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) {
2573
2574       AliESDtrack * esdTrack = esd->GetTrack(iTrack);
2575
2576       Int_t ikink = esdTrack->GetKinkIndex(0);
2577
2578       if (ikink) {
2579         // Negative kink index: mother, positive: daughter
2580
2581         // Search for the second track of the kink
2582
2583         for (Int_t jTrack = iTrack+1; jTrack<nTracks; ++jTrack) {
2584
2585           AliESDtrack * esdTrack1 = esd->GetTrack(jTrack);
2586
2587           Int_t jkink = esdTrack1->GetKinkIndex(0);
2588
2589           if ( TMath::Abs(ikink)==TMath::Abs(jkink) ) {
2590
2591             // The two tracks are from the same kink
2592           
2593             if (usedKink[TMath::Abs(ikink)-1]) continue; // skip used kinks
2594
2595             Int_t imother = -1;
2596             Int_t idaughter = -1;
2597
2598             if (ikink<0 && jkink>0) {
2599
2600               imother = iTrack;
2601               idaughter = jTrack;
2602             }
2603             else if (ikink>0 && jkink<0) {
2604
2605               imother = jTrack;
2606               idaughter = iTrack;
2607             }
2608             else {
2609               cerr << "Error: Wrong combination of kink indexes: "
2610               << ikink << " " << jkink << endl;
2611               continue;
2612             }
2613
2614             // Add the mother track
2615
2616             AliAODTrack * mother = NULL;
2617
2618             if (!usedTrack[imother]) {
2619         
2620               usedTrack[imother] = kTRUE;
2621         
2622               AliESDtrack *esdTrack = esd->GetTrack(imother);
2623               esdTrack->GetPxPyPz(p);
2624               esdTrack->GetXYZ(pos);
2625               esdTrack->GetCovarianceXYZPxPyPz(covTr);
2626               esdTrack->GetESDpid(pid);
2627
2628               mother = 
2629                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2630                                            esdTrack->GetLabel(),
2631                                            p,
2632                                            kTRUE,
2633                                            pos,
2634                                            kFALSE,
2635                                            covTr, 
2636                                            (Short_t)esdTrack->Charge(),
2637                                            esdTrack->GetITSClusterMap(), 
2638                                            pid,
2639                                            primary,
2640                                            kTRUE, // check if this is right
2641                                            kTRUE, // check if this is right
2642                                            AliAODTrack::kPrimary);
2643               primary->AddDaughter(mother);
2644               mother->ConvertAliPIDtoAODPID();
2645             }
2646             else {
2647               cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
2648               << " track " << imother << " has already been used!" << endl;
2649             }
2650
2651             // Add the kink vertex
2652             AliESDkink * kink = esd->GetKink(TMath::Abs(ikink)-1);
2653
2654             AliAODVertex * vkink = 
2655             new(vertices[jVertices++]) AliAODVertex(kink->GetPosition(),
2656                                                     NULL,
2657                                                     0.,
2658                                                     mother,
2659                                                     esdTrack->GetID(), // This is the track ID of the mother's track!
2660                                                     AliAODVertex::kKink);
2661             // Add the daughter track
2662
2663             AliAODTrack * daughter = NULL;
2664
2665             if (!usedTrack[idaughter]) {
2666         
2667               usedTrack[idaughter] = kTRUE;
2668         
2669               AliESDtrack *esdTrack = esd->GetTrack(idaughter);
2670               esdTrack->GetPxPyPz(p);
2671               esdTrack->GetXYZ(pos);
2672               esdTrack->GetCovarianceXYZPxPyPz(covTr);
2673               esdTrack->GetESDpid(pid);
2674
2675               daughter = 
2676                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2677                                            esdTrack->GetLabel(),
2678                                            p,
2679                                            kTRUE,
2680                                            pos,
2681                                            kFALSE,
2682                                            covTr, 
2683                                            (Short_t)esdTrack->Charge(),
2684                                            esdTrack->GetITSClusterMap(), 
2685                                            pid,
2686                                            vkink,
2687                                            kTRUE, // check if this is right
2688                                            kTRUE, // check if this is right
2689                                            AliAODTrack::kPrimary);
2690               vkink->AddDaughter(daughter);
2691               daughter->ConvertAliPIDtoAODPID();
2692             }
2693             else {
2694               cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
2695               << " track " << idaughter << " has already been used!" << endl;
2696             }
2697           }
2698         }
2699       }
2700     }
2701     vertices.Expand(jVertices);
2702
2703     // Tracks (primary and orphan)
2704     for (Int_t nTrack = 0; nTrack < nTracks; ++nTrack) {
2705
2706       if (usedTrack[nTrack]) continue;
2707
2708       AliESDtrack *esdTrack = esd->GetTrack(nTrack);
2709       esdTrack->GetPxPyPz(p);
2710       esdTrack->GetXYZ(pos);
2711       esdTrack->GetCovarianceXYZPxPyPz(covTr);
2712       esdTrack->GetESDpid(pid);
2713
2714       Float_t impactXY, impactZ;
2715
2716       esdTrack->GetImpactParameters(impactXY,impactZ);
2717
2718       if (impactXY<3.) {
2719         // track inside the beam pipe
2720       
2721         primary->AddDaughter(aodTrack =
2722             new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2723                                          esdTrack->GetLabel(),
2724                                          p,
2725                                          kTRUE,
2726                                          pos,
2727                                          kFALSE,
2728                                          covTr, 
2729                                          (Short_t)esdTrack->Charge(),
2730                                          esdTrack->GetITSClusterMap(), 
2731                                          pid,
2732                                          primary,
2733                                          kTRUE, // check if this is right
2734                                          kTRUE, // check if this is right
2735                                          AliAODTrack::kPrimary)
2736             );
2737         aodTrack->ConvertAliPIDtoAODPID();
2738       }
2739       else {
2740         // outside the beam pipe: orphan track
2741         // Don't write them anymore!
2742         continue;
2743       } 
2744     } // end of loop on tracks
2745     
2746     // muon tracks
2747     Int_t nMuTracks = esd->GetNumberOfMuonTracks();
2748     for (Int_t nMuTrack = 0; nMuTrack < nMuTracks; ++nMuTrack) {
2749       
2750       AliESDMuonTrack *esdMuTrack = esd->GetMuonTrack(nMuTrack);     
2751       p[0] = esdMuTrack->Px(); 
2752       p[1] = esdMuTrack->Py(); 
2753       p[2] = esdMuTrack->Pz();
2754       pos[0] = primary->GetX(); 
2755       pos[1] = primary->GetY(); 
2756       pos[2] = primary->GetZ();
2757       
2758       // has to be changed once the muon pid is provided by the ESD
2759       for (Int_t i = 0; i < 10; pid[i++] = 0.); pid[AliAODTrack::kMuon]=1.;
2760       
2761       primary->AddDaughter(aodTrack =
2762           new(tracks[jTracks++]) AliAODTrack(0, // no ID provided
2763                                              0, // no label provided
2764                                              p,
2765                                              kTRUE,
2766                                              pos,
2767                                              kFALSE,
2768                                              NULL, // no covariance matrix provided
2769                                              esdMuTrack->Charge(),
2770                                              0, // ITSClusterMap is set below
2771                                              pid,
2772                                              primary,
2773                                              kFALSE,  // muon tracks are not used to fit the primary vtx
2774                                              kFALSE,  // not used for vertex fit
2775                                              AliAODTrack::kPrimary)
2776           );
2777
2778       aodTrack->SetHitsPatternInTrigCh(esdMuTrack->GetHitsPatternInTrigCh());
2779       Int_t track2Trigger = esdMuTrack->GetMatchTrigger();
2780       aodTrack->SetMatchTrigger(track2Trigger);
2781       if (track2Trigger) 
2782         aodTrack->SetChi2MatchTrigger(esdMuTrack->GetChi2MatchTrigger());
2783       else 
2784         aodTrack->SetChi2MatchTrigger(0.);
2785     }
2786     tracks.Expand(jTracks); // remove 'empty slots' due to unwritten tracks
2787         
2788     // Access to the AOD container of PMD clusters
2789     TClonesArray &pmdClusters = *(aod->GetPmdClusters());
2790     Int_t jPmdClusters=0;
2791   
2792     for (Int_t iPmd = 0; iPmd < nPmdClus; ++iPmd) {
2793       // file pmd clusters, to be revised!
2794       AliESDPmdTrack *pmdTrack = esd->GetPmdTrack(iPmd);
2795       Int_t nLabel = 0;
2796       Int_t *label = 0x0;
2797       Double_t pos[3] = { pmdTrack->GetClusterX(), pmdTrack->GetClusterY(), pmdTrack->GetClusterZ() };
2798       Double_t pid[9] = { 0., 0., 0., 0., 0., 0., 0., 0., 0. }; // to be revised!
2799       // type not set!
2800       // assoc cluster not set
2801       new(pmdClusters[jPmdClusters++]) AliAODPmdCluster(iPmd, nLabel, label, pmdTrack->GetClusterADC(), pos, pid);
2802     }
2803
2804     // Access to the AOD container of clusters
2805     TClonesArray &caloClusters = *(aod->GetCaloClusters());
2806     Int_t jClusters=0;
2807  
2808     for (Int_t iClust=0; iClust<nCaloClus; ++iClust) {
2809
2810       AliESDCaloCluster * cluster = esd->GetCaloCluster(iClust);
2811
2812       Int_t id = cluster->GetID();
2813       Int_t nLabel = 0;
2814       Int_t *label = 0x0;
2815       Float_t energy = cluster->E();
2816       cluster->GetPosition(posF);
2817       Char_t ttype=AliAODCluster::kUndef;
2818
2819       if (cluster->GetClusterType() == AliESDCaloCluster::kPHOSCluster) {
2820         ttype=AliAODCluster::kPHOSNeutral;
2821       } 
2822       else if (cluster->GetClusterType() == AliESDCaloCluster::kEMCALClusterv1) {
2823         ttype = AliAODCluster::kEMCALClusterv1;
2824       }
2825
2826       
2827       AliAODCaloCluster *caloCluster = new(caloClusters[jClusters++]) AliAODCaloCluster(id,
2828                                                                                         nLabel,
2829                                                                                         label,
2830                                                                                         energy,
2831                                                                                         pos,
2832                                                                                         NULL,
2833                                                                                         ttype);
2834       
2835       caloCluster->SetCaloCluster(); // to be refined!
2836
2837     } 
2838     caloClusters.Expand(jClusters); // resize TObjArray to 'remove' slots for pseudo clusters    
2839     // end of loop on calo clusters
2840
2841     // fill EMCAL cell info
2842     if (esd->GetEMCALCells()) { // protection against missing ESD information
2843       AliESDCaloCells &esdEMcells = *(esd->GetEMCALCells());
2844       Int_t nEMcell = esdEMcells.GetNumberOfCells() ;
2845       
2846       AliAODCaloCells &aodEMcells = *(aod->GetEMCALCells());
2847       aodEMcells.CreateContainer(nEMcell);
2848       aodEMcells.SetType(AliAODCaloCells::kEMCAL);
2849       for (Int_t iCell = 0; iCell < nEMcell; iCell++) {      
2850         aodEMcells.SetCell(iCell,esdEMcells.GetCellNumber(iCell),esdEMcells.GetAmplitude(iCell));
2851       }
2852       aodEMcells.Sort();
2853     }
2854
2855     // fill PHOS cell info
2856     if (esd->GetPHOSCells()) { // protection against missing ESD information
2857       AliESDCaloCells &esdPHcells = *(esd->GetPHOSCells());
2858       Int_t nPHcell = esdPHcells.GetNumberOfCells() ;
2859       
2860       AliAODCaloCells &aodPHcells = *(aod->GetPHOSCells());
2861       aodPHcells.CreateContainer(nPHcell);
2862       aodPHcells.SetType(AliAODCaloCells::kPHOS);
2863       for (Int_t iCell = 0; iCell < nPHcell; iCell++) {      
2864         aodPHcells.SetCell(iCell,esdPHcells.GetCellNumber(iCell),esdPHcells.GetAmplitude(iCell));
2865       }
2866       aodPHcells.Sort();
2867     }
2868
2869     // tracklets    
2870     AliAODTracklets &SPDTracklets = *(aod->GetTracklets());
2871     const AliMultiplicity *mult = esd->GetMultiplicity();
2872     if (mult) {
2873       if (mult->GetNumberOfTracklets()>0) {
2874         SPDTracklets.CreateContainer(mult->GetNumberOfTracklets());
2875
2876         for (Int_t n=0; n<mult->GetNumberOfTracklets(); n++) {
2877           SPDTracklets.SetTracklet(n, mult->GetTheta(n), mult->GetPhi(n), mult->GetDeltaPhi(n), mult->GetLabel(n));
2878         }
2879       }
2880     } else {
2881       Printf("ERROR: AliMultiplicity could not be retrieved from ESD");
2882     }
2883
2884     delete [] usedTrack;
2885     delete [] usedV0;
2886     delete [] usedKink;
2887
2888     // fill the tree for this event
2889     aodTree->Fill();
2890   } // end of event loop
2891
2892   aodTree->GetUserInfo()->Add(aod);
2893
2894   // write the tree to the specified file
2895   aodFile = aodTree->GetCurrentFile();
2896   aodFile->cd();
2897   aodTree->Write();
2898
2899   return;
2900 }
2901
2902 void AliReconstruction::WriteAlignmentData(AliESDEvent* esd)
2903 {
2904   // Write space-points which are then used in the alignment procedures
2905   // For the moment only ITS, TRD and TPC
2906
2907   // Load TOF clusters
2908   if (fTracker[3]){
2909     fLoader[3]->LoadRecPoints("read");
2910     TTree* tree = fLoader[3]->TreeR();
2911     if (!tree) {
2912       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[3]));
2913       return;
2914     }
2915     fTracker[3]->LoadClusters(tree);
2916   }
2917   Int_t ntracks = esd->GetNumberOfTracks();
2918   for (Int_t itrack = 0; itrack < ntracks; itrack++)
2919     {
2920       AliESDtrack *track = esd->GetTrack(itrack);
2921       Int_t nsp = 0;
2922       Int_t idx[200];
2923       for (Int_t iDet = 3; iDet >= 0; iDet--)
2924         nsp += track->GetNcls(iDet);
2925       if (nsp) {
2926         AliTrackPointArray *sp = new AliTrackPointArray(nsp);
2927         track->SetTrackPointArray(sp);
2928         Int_t isptrack = 0;
2929         for (Int_t iDet = 3; iDet >= 0; iDet--) {
2930           AliTracker *tracker = fTracker[iDet];
2931           if (!tracker) continue;
2932           Int_t nspdet = track->GetNcls(iDet);
2933           if (nspdet <= 0) continue;
2934           track->GetClusters(iDet,idx);
2935           AliTrackPoint p;
2936           Int_t isp = 0;
2937           Int_t isp2 = 0;
2938           while (isp2 < nspdet) {
2939             Bool_t isvalid;
2940             TString dets = fgkDetectorName[iDet];
2941             if ((fUseTrackingErrorsForAlignment.CompareTo(dets) == 0) ||
2942             fUseTrackingErrorsForAlignment.BeginsWith(dets+" ") ||
2943             fUseTrackingErrorsForAlignment.EndsWith(" "+dets) ||
2944             fUseTrackingErrorsForAlignment.Contains(" "+dets+" ")) {
2945               isvalid = tracker->GetTrackPointTrackingError(idx[isp2],p,track);
2946             } else {
2947               isvalid = tracker->GetTrackPoint(idx[isp2],p); 
2948             } 
2949             isp2++;
2950             const Int_t kNTPCmax = 159;
2951             if (iDet==1 && isp2>kNTPCmax) break;   // to be fixed
2952             if (!isvalid) continue;
2953             sp->AddPoint(isptrack,&p); isptrack++; isp++;
2954           }
2955         }       
2956       }
2957     }
2958   if (fTracker[3]){
2959     fTracker[3]->UnloadClusters();
2960     fLoader[3]->UnloadRecPoints();
2961   }
2962 }
2963
2964 //_____________________________________________________________________________
2965 void AliReconstruction::FillRawDataErrorLog(Int_t iEvent, AliESDEvent* esd)
2966 {
2967   // The method reads the raw-data error log
2968   // accumulated within the rawReader.
2969   // It extracts the raw-data errors related to
2970   // the current event and stores them into
2971   // a TClonesArray inside the esd object.
2972
2973   if (!fRawReader) return;
2974
2975   for(Int_t i = 0; i < fRawReader->GetNumberOfErrorLogs(); i++) {
2976
2977     AliRawDataErrorLog *log = fRawReader->GetErrorLog(i);
2978     if (!log) continue;
2979     if (iEvent != log->GetEventNumber()) continue;
2980
2981     esd->AddRawDataErrorLog(log);
2982   }
2983
2984 }
2985
2986 TNamed* AliReconstruction::CopyFileToTNamed(TString fPath,TString fName){
2987   // Dump a file content into a char in TNamed
2988   ifstream in;
2989   in.open(fPath.Data(),ios::in | ios::binary|ios::ate);
2990   Int_t kBytes = (Int_t)in.tellg();
2991   printf("Size: %d \n",kBytes);
2992   TNamed *fn = 0;
2993   if(in.good()){
2994     char* memblock = new char [kBytes];
2995     in.seekg (0, ios::beg);
2996     in.read (memblock, kBytes);
2997     in.close();
2998     TString fData(memblock,kBytes);
2999     fn = new TNamed(fName,fData);
3000     printf("fData Size: %d \n",fData.Sizeof());
3001     printf("fName Size: %d \n",fName.Sizeof());
3002     printf("fn    Size: %d \n",fn->Sizeof());
3003     delete[] memblock;
3004   }
3005   else{
3006     AliInfo(Form("Could not Open %s\n",fPath.Data()));
3007   }
3008
3009   return fn;
3010 }
3011
3012 void AliReconstruction::TNamedToFile(TTree* fTree, TString fName){
3013   // This is not really needed in AliReconstruction at the moment
3014   // but can serve as a template
3015
3016   TList *fList = fTree->GetUserInfo();
3017   TNamed *fn = (TNamed*)fList->FindObject(fName.Data());
3018   printf("fn Size: %d \n",fn->Sizeof());
3019
3020   TString fTmp(fn->GetName()); // to be 100% sure in principle fName also works
3021   const char* cdata = fn->GetTitle();
3022   printf("fTmp Size %d\n",fTmp.Sizeof());
3023
3024   int size = fn->Sizeof()-fTmp.Sizeof()-sizeof(UChar_t)-sizeof(Int_t); // see dfinition of TString::SizeOf()...
3025   printf("calculated size %d\n",size);
3026   ofstream out(fName.Data(),ios::out | ios::binary);
3027   out.write(cdata,size);
3028   out.close();
3029
3030 }
3031   
3032 //_____________________________________________________________________________
3033 AliQADataMakerRec * AliReconstruction::GetQADataMaker(Int_t iDet)
3034 {
3035  // get the quality assurance data maker object and the loader for a detector
3036
3037   if (fQADataMaker[iDet]) 
3038     return fQADataMaker[iDet];
3039
3040   AliQADataMakerRec * qadm = NULL;
3041   if (iDet == fgkNDetectors) { //Global QA
3042      qadm = new AliGlobalQADataMaker();
3043      fQADataMaker[iDet] = qadm;
3044      return qadm;
3045   }
3046
3047   // load the QA data maker object
3048   TPluginManager* pluginManager = gROOT->GetPluginManager();
3049   TString detName = fgkDetectorName[iDet];
3050   TString qadmName = "Ali" + detName + "QADataMakerRec";
3051   if (gAlice && !gAlice->GetDetector(detName) && (detName != "HLT")) 
3052     return NULL;
3053
3054   // first check if a plugin is defined for the quality assurance data maker
3055   TPluginHandler* pluginHandler = pluginManager->FindHandler("AliQADataMakerRec", detName);
3056   // if not, add a plugin for it
3057   if (!pluginHandler) {
3058     AliDebug(1, Form("defining plugin for %s", qadmName.Data()));
3059     TString libs = gSystem->GetLibraries();
3060     if (libs.Contains("lib" + detName + "base.so") ||
3061         (gSystem->Load("lib" + detName + "base.so") >= 0)) {
3062       pluginManager->AddHandler("AliQADataMakerRec", detName, 
3063                                 qadmName, detName + "qadm", qadmName + "()");
3064     } else {
3065       pluginManager->AddHandler("AliQADataMakerRec", detName, 
3066                                 qadmName, detName, qadmName + "()");
3067     }
3068     pluginHandler = pluginManager->FindHandler("AliQADataMakerRec", detName);
3069   }
3070   if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
3071     qadm = (AliQADataMakerRec *) pluginHandler->ExecPlugin(0);
3072   }
3073
3074   fQADataMaker[iDet] = qadm;
3075
3076   return qadm;
3077 }
3078
3079 //_____________________________________________________________________________
3080 Bool_t AliReconstruction::RunQA(const char* detectors, AliESDEvent *& esd)
3081 {
3082   // run the Quality Assurance data producer
3083
3084   AliCodeTimerAuto("")
3085   TString detStr = detectors;
3086   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
3087    if (!IsSelected(fgkDetectorName[iDet], detStr)) 
3088      continue;
3089    AliQADataMakerRec * qadm = GetQADataMaker(iDet);
3090    if (!qadm) 
3091      continue;
3092    AliCodeTimerStart(Form("running quality assurance data maker for %s", fgkDetectorName[iDet]));
3093    AliInfo(Form("running quality assurance data maker for %s", fgkDetectorName[iDet]));
3094     
3095    qadm->Exec(AliQA::kESDS, esd) ; 
3096    qadm->Increment() ; 
3097
3098    AliCodeTimerStop(Form("running quality assurance data maker for %s", fgkDetectorName[iDet]));
3099  }
3100  if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
3101    AliError(Form("the following detectors were not found: %s",
3102                  detStr.Data()));
3103    if (fStopOnError) 
3104      return kFALSE;
3105  }
3106  
3107  return kTRUE;
3108   
3109 }
3110
3111 //_____________________________________________________________________________
3112 void AliReconstruction::CheckQA()
3113 {
3114 // check the QA of SIM for this run and remove the detectors 
3115 // with status Fatal
3116   
3117         TString newRunLocalReconstruction ; 
3118         TString newRunTracking ;
3119         TString newFillESD ;
3120          
3121         for (Int_t iDet = 0; iDet < AliQA::kNDET; iDet++) {
3122                 TString detName(AliQA::GetDetName(iDet)) ;
3123                 AliQA * qa = AliQA::Instance(AliQA::DETECTORINDEX(iDet)) ; 
3124                 if ( qa->IsSet(AliQA::DETECTORINDEX(iDet), AliQA::kSIM, AliQA::kFATAL)) {
3125                                 AliInfo(Form("QA status for %s in Hits and/or SDIGITS  and/or Digits was Fatal; No reconstruction performed", detName.Data())) ;
3126                 } else {
3127                         if ( fRunLocalReconstruction.Contains(AliQA::GetDetName(iDet)) || 
3128                                         fRunLocalReconstruction.Contains("ALL") )  {
3129                                 newRunLocalReconstruction += detName ; 
3130                                 newRunLocalReconstruction += " " ;                      
3131                         }
3132                         if ( fRunTracking.Contains(AliQA::GetDetName(iDet)) || 
3133                                         fRunTracking.Contains("ALL") )  {
3134                                 newRunTracking += detName ; 
3135                                 newRunTracking += " " ;                         
3136                         }
3137                         if ( fFillESD.Contains(AliQA::GetDetName(iDet)) || 
3138                                         fFillESD.Contains("ALL") )  {
3139                                 newFillESD += detName ; 
3140                                 newFillESD += " " ;                     
3141                         }
3142                 }
3143         }
3144         fRunLocalReconstruction = newRunLocalReconstruction ; 
3145         fRunTracking            = newRunTracking ; 
3146         fFillESD                = newFillESD ; 
3147 }
3148
3149 //_____________________________________________________________________________
3150 Int_t AliReconstruction::GetDetIndex(const char* detector)
3151 {
3152   // return the detector index corresponding to detector
3153   Int_t index = -1 ; 
3154   for (index = 0; index < fgkNDetectors ; index++) {
3155     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
3156         break ; 
3157   }     
3158   return index ; 
3159 }
3160 //_____________________________________________________________________________
3161 Bool_t AliReconstruction::FinishPlaneEff() {
3162  //
3163  // Here execute all the necessary operationis, at the end of the tracking phase,
3164  // in case that evaluation of PlaneEfficiencies was required for some detector. 
3165  // E.g., write into a DataBase file the PlaneEfficiency which have been evaluated. 
3166  //
3167  // This Preliminary version works only FOR ITS !!!!!
3168  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3169  //
3170  //  Input: none
3171  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise 
3172  //
3173  Bool_t ret=kFALSE;
3174  //for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
3175  for (Int_t iDet = 0; iDet < 1; iDet++) { // for the time being only ITS  
3176    //if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3177    if(fTracker[iDet]) ret=fTracker[iDet]->GetPlaneEff()->WriteIntoCDB();
3178  }
3179  return ret;
3180 }
3181 //_____________________________________________________________________________
3182 Bool_t AliReconstruction::InitPlaneEff() {
3183 //
3184  // Here execute all the necessary operations, before of the tracking phase,
3185  // for the evaluation of PlaneEfficiencies, in case required for some detectors.
3186  // E.g., read from a DataBase file a first evaluation of the PlaneEfficiency 
3187  // which should be updated/recalculated.
3188  //
3189  // This Preliminary version will work only FOR ITS !!!!!
3190  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3191  //
3192  //  Input: none
3193  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3194  //
3195  AliWarning(Form("Implementation of this method not yet done !! Method return kTRUE"));
3196  return kTRUE;
3197 }