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