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