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