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