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