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