]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliReconstruction.cxx
Restoring the correct track-to-primary-vertex association lost in revision 25245...
[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 #include <TMap.h>
133
134 #include "AliReconstruction.h"
135 #include "AliCodeTimer.h"
136 #include "AliReconstructor.h"
137 #include "AliLog.h"
138 #include "AliRunLoader.h"
139 #include "AliRun.h"
140 #include "AliRawReaderFile.h"
141 #include "AliRawReaderDate.h"
142 #include "AliRawReaderRoot.h"
143 #include "AliRawEventHeaderBase.h"
144 #include "AliESDEvent.h"
145 #include "AliESDMuonTrack.h"
146 #include "AliESDfriend.h"
147 #include "AliESDVertex.h"
148 #include "AliESDcascade.h"
149 #include "AliESDkink.h"
150 #include "AliESDtrack.h"
151 #include "AliESDCaloCluster.h"
152 #include "AliESDCaloCells.h"
153 #include "AliMultiplicity.h"
154 #include "AliTracker.h"
155 #include "AliVertexer.h"
156 #include "AliVertexerTracks.h"
157 #include "AliV0vertexer.h"
158 #include "AliCascadeVertexer.h"
159 #include "AliHeader.h"
160 #include "AliGenEventHeader.h"
161 #include "AliPID.h"
162 #include "AliESDpid.h"
163 #include "AliESDtrack.h"
164 #include "AliESDPmdTrack.h"
165
166 #include "AliESDTagCreator.h"
167 #include "AliAODTagCreator.h"
168
169 #include "AliGeomManager.h"
170 #include "AliTrackPointArray.h"
171 #include "AliCDBManager.h"
172 #include "AliCDBStorage.h"
173 #include "AliCDBEntry.h"
174 #include "AliAlignObj.h"
175
176 #include "AliCentralTrigger.h"
177 #include "AliTriggerConfiguration.h"
178 #include "AliTriggerClass.h"
179 #include "AliCTPRawStream.h"
180
181 #include "AliQADataMakerRec.h" 
182 #include "AliGlobalQADataMaker.h" 
183 #include "AliQA.h"
184 #include "AliQADataMakerSteer.h"
185
186 #include "AliPlaneEff.h"
187
188 #include "AliSysInfo.h" // memory snapshots
189 #include "AliRawHLTManager.h"
190
191 #include "AliMagWrapCheb.h"
192
193 ClassImp(AliReconstruction)
194
195
196 //_____________________________________________________________________________
197 const char* AliReconstruction::fgkDetectorName[AliReconstruction::fgkNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT"};
198
199 //_____________________________________________________________________________
200 AliReconstruction::AliReconstruction(const char* gAliceFilename,
201                                      const char* name, const char* title) :
202   TNamed(name, title),
203
204   fUniformField(kFALSE),
205   fRunVertexFinder(kTRUE),
206   fRunVertexFinderTracks(kTRUE),
207   fRunHLTTracking(kFALSE),
208   fRunMuonTracking(kFALSE),
209   fRunV0Finder(kTRUE),
210   fRunCascadeFinder(kTRUE),
211   fStopOnError(kFALSE),
212   fWriteAlignmentData(kFALSE),
213   fWriteESDfriend(kFALSE),
214   fWriteAOD(kFALSE),
215   fFillTriggerESD(kTRUE),
216
217   fCleanESD(kTRUE),
218   fV0DCAmax(3.),
219   fV0CsPmin(0.),
220   fDmax(50.),
221   fZmax(50.),
222
223   fRunLocalReconstruction("ALL"),
224   fRunTracking("ALL"),
225   fFillESD("ALL"),
226   fUseTrackingErrorsForAlignment(""),
227   fGAliceFileName(gAliceFilename),
228   fInput(""),
229   fEquipIdMap(""),
230   fFirstEvent(0),
231   fLastEvent(-1),
232   fNumberOfEventsPerFile(1),
233   fCheckPointLevel(0),
234   fOptions(),
235   fLoadAlignFromCDB(kTRUE),
236   fLoadAlignData("ALL"),
237   fESDPar(""),
238   fUseHLTData(),
239
240   fRunLoader(NULL),
241   fRawReader(NULL),
242   fParentRawReader(NULL),
243
244   fVertexer(NULL),
245   fDiamondProfile(NULL),
246   fDiamondProfileTPC(NULL),
247   fMeanVertexConstraint(kTRUE),
248
249   fGRPData(NULL),
250
251   fAlignObjArray(NULL),
252   fCDBUri(),
253   fSpecCDBUri(), 
254   fInitCDBCalled(kFALSE),
255   fSetRunNumberFromDataCalled(kFALSE),
256   fQADetectors("ALL"), 
257   fQATasks("ALL"), 
258   fRunQA(kTRUE),  
259   fRunGlobalQA(kTRUE),
260   fInLoopQA(kFALSE),
261   fSameQACycle(kFALSE),
262
263   fRunPlaneEff(kFALSE),
264
265   fesd(NULL),
266   fhltesd(NULL),
267   fesdf(NULL),
268   ffile(NULL),
269   ftree(NULL),
270   fhlttree(NULL),
271   ffileOld(NULL),
272   ftreeOld(NULL),
273   fhlttreeOld(NULL),
274   ftVertexer(NULL),
275   fIsNewRunLoader(kFALSE),
276   fRunAliEVE(kFALSE)
277 {
278 // create reconstruction object with default parameters
279   
280   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
281     fReconstructor[iDet] = NULL;
282     fLoader[iDet] = NULL;
283     fTracker[iDet] = NULL;
284     fQADataMaker[iDet] = NULL;
285         fQACycles[iDet] = 999999;       
286   }
287   fQADataMaker[fgkNDetectors]=NULL;  //Global QA
288   AliPID pid;
289 }
290
291 //_____________________________________________________________________________
292 AliReconstruction::AliReconstruction(const AliReconstruction& rec) :
293   TNamed(rec),
294
295   fUniformField(rec.fUniformField),
296   fRunVertexFinder(rec.fRunVertexFinder),
297   fRunVertexFinderTracks(rec.fRunVertexFinderTracks),
298   fRunHLTTracking(rec.fRunHLTTracking),
299   fRunMuonTracking(rec.fRunMuonTracking),
300   fRunV0Finder(rec.fRunV0Finder),
301   fRunCascadeFinder(rec.fRunCascadeFinder),
302   fStopOnError(rec.fStopOnError),
303   fWriteAlignmentData(rec.fWriteAlignmentData),
304   fWriteESDfriend(rec.fWriteESDfriend),
305   fWriteAOD(rec.fWriteAOD),
306   fFillTriggerESD(rec.fFillTriggerESD),
307
308   fCleanESD(rec.fCleanESD),
309   fV0DCAmax(rec.fV0DCAmax),
310   fV0CsPmin(rec.fV0CsPmin),
311   fDmax(rec.fDmax),
312   fZmax(rec.fZmax),
313
314   fRunLocalReconstruction(rec.fRunLocalReconstruction),
315   fRunTracking(rec.fRunTracking),
316   fFillESD(rec.fFillESD),
317   fUseTrackingErrorsForAlignment(rec.fUseTrackingErrorsForAlignment),
318   fGAliceFileName(rec.fGAliceFileName),
319   fInput(rec.fInput),
320   fEquipIdMap(rec.fEquipIdMap),
321   fFirstEvent(rec.fFirstEvent),
322   fLastEvent(rec.fLastEvent),
323   fNumberOfEventsPerFile(rec.fNumberOfEventsPerFile),
324   fCheckPointLevel(0),
325   fOptions(),
326   fLoadAlignFromCDB(rec.fLoadAlignFromCDB),
327   fLoadAlignData(rec.fLoadAlignData),
328   fESDPar(rec.fESDPar),
329   fUseHLTData(rec.fUseHLTData),
330
331   fRunLoader(NULL),
332   fRawReader(NULL),
333   fParentRawReader(NULL),
334
335   fVertexer(NULL),
336   fDiamondProfile(NULL),
337   fDiamondProfileTPC(NULL),
338   fMeanVertexConstraint(rec.fMeanVertexConstraint),
339
340   fGRPData(NULL),
341
342   fAlignObjArray(rec.fAlignObjArray),
343   fCDBUri(rec.fCDBUri),
344   fSpecCDBUri(), 
345   fInitCDBCalled(rec.fInitCDBCalled),
346   fSetRunNumberFromDataCalled(rec.fSetRunNumberFromDataCalled),
347   fQADetectors(rec.fQADetectors), 
348   fQATasks(rec.fQATasks), 
349   fRunQA(rec.fRunQA),  
350   fRunGlobalQA(rec.fRunGlobalQA),
351   fInLoopQA(rec.fInLoopQA),
352   fSameQACycle(rec.fSameQACycle),
353   fRunPlaneEff(rec.fRunPlaneEff),
354
355   fesd(NULL),
356   fhltesd(NULL),
357   fesdf(NULL),
358   ffile(NULL),
359   ftree(NULL),
360   fhlttree(NULL),
361   ffileOld(NULL),
362   ftreeOld(NULL),
363   fhlttreeOld(NULL),
364   ftVertexer(NULL),
365   fIsNewRunLoader(rec.fIsNewRunLoader),
366   fRunAliEVE(kFALSE)
367 {
368 // copy constructor
369
370   for (Int_t i = 0; i < rec.fOptions.GetEntriesFast(); i++) {
371     if (rec.fOptions[i]) fOptions.Add(rec.fOptions[i]->Clone());
372   }
373   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
374     fReconstructor[iDet] = NULL;
375     fLoader[iDet] = NULL;
376     fTracker[iDet] = NULL;
377     fQADataMaker[iDet] = NULL;
378         fQACycles[iDet] = rec.fQACycles[iDet];  
379   }
380   fQADataMaker[fgkNDetectors]=NULL;  //Global QA
381   for (Int_t i = 0; i < rec.fSpecCDBUri.GetEntriesFast(); i++) {
382     if (rec.fSpecCDBUri[i]) fSpecCDBUri.Add(rec.fSpecCDBUri[i]->Clone());
383   }
384 }
385
386 //_____________________________________________________________________________
387 AliReconstruction& AliReconstruction::operator = (const AliReconstruction& rec)
388 {
389 // assignment operator
390
391   this->~AliReconstruction();
392   new(this) AliReconstruction(rec);
393   return *this;
394 }
395
396 //_____________________________________________________________________________
397 AliReconstruction::~AliReconstruction()
398 {
399 // clean up
400
401   CleanUp();
402   fOptions.Delete();
403   fSpecCDBUri.Delete();
404
405   AliCodeTimer::Instance()->Print();
406 }
407
408 //_____________________________________________________________________________
409 void AliReconstruction::InitCDB()
410 {
411 // activate a default CDB storage
412 // First check if we have any CDB storage set, because it is used 
413 // to retrieve the calibration and alignment constants
414
415   if (fInitCDBCalled) return;
416   fInitCDBCalled = kTRUE;
417
418   AliCDBManager* man = AliCDBManager::Instance();
419   if (man->IsDefaultStorageSet())
420   {
421     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
422     AliWarning("Default CDB storage has been already set !");
423     AliWarning(Form("Ignoring the default storage declared in AliReconstruction: %s",fCDBUri.Data()));
424     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
425     fCDBUri = man->GetDefaultStorage()->GetURI();
426   }
427   else {
428     if (fCDBUri.Length() > 0) 
429     {
430         AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
431         AliDebug(2, Form("Default CDB storage is set to: %s", fCDBUri.Data()));
432         AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
433     } else {
434         fCDBUri="local://$ALICE_ROOT";
435         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
436         AliWarning("Default CDB storage not yet set !!!!");
437         AliWarning(Form("Setting it now to: %s", fCDBUri.Data()));
438         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
439                 
440     }
441     man->SetDefaultStorage(fCDBUri);
442   }
443
444   // Now activate the detector specific CDB storage locations
445   for (Int_t i = 0; i < fSpecCDBUri.GetEntriesFast(); i++) {
446     TObject* obj = fSpecCDBUri[i];
447     if (!obj) continue;
448     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
449     AliDebug(2, Form("Specific CDB storage for %s is set to: %s",obj->GetName(),obj->GetTitle()));
450     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
451     man->SetSpecificStorage(obj->GetName(), obj->GetTitle());
452   }
453   
454 }
455
456 //_____________________________________________________________________________
457 void AliReconstruction::SetDefaultStorage(const char* uri) {
458 // Store the desired default CDB storage location
459 // Activate it later within the Run() method
460
461   fCDBUri = uri;
462
463 }
464
465 //_____________________________________________________________________________
466 void AliReconstruction::SetSpecificStorage(const char* calibType, const char* uri) {
467 // Store a detector-specific CDB storage location
468 // Activate it later within the Run() method
469
470   AliCDBPath aPath(calibType);
471   if(!aPath.IsValid()){
472         // if calibType is not wildcard but it is a valid detector, add "/*" to make it a valid path
473         for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
474                 if(!strcmp(calibType, fgkDetectorName[iDet])) {
475                         aPath.SetPath(Form("%s/*", calibType));
476                         AliInfo(Form("Path for specific storage set to %s", aPath.GetPath().Data()));
477                         break;
478                 }
479         }
480         if(!aPath.IsValid()){
481                 AliError(Form("Not a valid path or detector: %s", calibType));
482                 return;
483         }
484   }
485
486 //  // check that calibType refers to a "valid" detector name
487 //  Bool_t isDetector = kFALSE;
488 //  for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
489 //    TString detName = fgkDetectorName[iDet];
490 //    if(aPath.GetLevel0() == detName) {
491 //      isDetector = kTRUE;
492 //      break;
493 //    }
494 //  }
495 //
496 //  if(!isDetector) {
497 //      AliError(Form("Not a valid detector: %s", aPath.GetLevel0().Data()));
498 //      return;
499 //  }
500
501   TObject* obj = fSpecCDBUri.FindObject(aPath.GetPath().Data());
502   if (obj) fSpecCDBUri.Remove(obj);
503   fSpecCDBUri.Add(new TNamed(aPath.GetPath().Data(), uri));
504
505 }
506
507 //_____________________________________________________________________________
508 Bool_t AliReconstruction::SetRunNumberFromData()
509 {
510   // The method is called in Run() in order
511   // to set a correct run number.
512   // In case of raw data reconstruction the
513   // run number is taken from the raw data header
514
515   if (fSetRunNumberFromDataCalled) return kTRUE;
516   fSetRunNumberFromDataCalled = kTRUE;
517   
518   AliCDBManager* man = AliCDBManager::Instance();
519   
520   if(man->GetRun() > 0) {
521         AliWarning("Run number is taken from raw-event header! Ignoring settings in AliCDBManager!");
522   } 
523   
524   if (!fRunLoader) {
525       AliError("No run loader is found !"); 
526       return kFALSE;
527     }
528     // read run number from gAlice
529     if(fRunLoader->GetAliRun())
530       AliCDBManager::Instance()->SetRun(fRunLoader->GetHeader()->GetRun());
531     else {
532       if(fRawReader) {
533         if(fRawReader->NextEvent()) {
534           AliCDBManager::Instance()->SetRun(fRawReader->GetRunNumber());
535           fRawReader->RewindEvents();
536         }
537         else {
538           if(man->GetRun() > 0) {
539             AliWarning("No raw events is found ! Using settings in AliCDBManager !");
540             man->Print();  
541             return kTRUE;
542           }
543           else {
544             AliWarning("Neither raw events nor settings in AliCDBManager are found !");
545             return kFALSE;
546           }
547         }
548       }
549       else {
550         AliError("Neither gAlice nor RawReader objects are found !");
551         return kFALSE;
552       }
553   }
554
555   man->Print();  
556   
557   return kTRUE;
558 }
559
560 //_____________________________________________________________________________
561 void AliReconstruction::SetCDBLock() {
562   // Set CDB lock: from now on it is forbidden to reset the run number
563   // or the default storage or to activate any further storage!
564   
565   AliCDBManager::Instance()->SetLock(1);
566 }
567
568 //_____________________________________________________________________________
569 Bool_t AliReconstruction::MisalignGeometry(const TString& detectors)
570 {
571   // Read the alignment objects from CDB.
572   // Each detector is supposed to have the
573   // alignment objects in DET/Align/Data CDB path.
574   // All the detector objects are then collected,
575   // sorted by geometry level (starting from ALIC) and
576   // then applied to the TGeo geometry.
577   // Finally an overlaps check is performed.
578
579   // Load alignment data from CDB and fill fAlignObjArray 
580   if(fLoadAlignFromCDB){
581         
582     TString detStr = detectors;
583     TString loadAlObjsListOfDets = "";
584     
585     for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
586       if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
587       loadAlObjsListOfDets += fgkDetectorName[iDet];
588       loadAlObjsListOfDets += " ";
589     } // end loop over detectors
590     loadAlObjsListOfDets.Prepend("GRP "); //add alignment objects for non-sensitive modules
591     AliGeomManager::ApplyAlignObjsFromCDB(loadAlObjsListOfDets.Data());
592   }else{
593     // Check if the array with alignment objects was
594     // provided by the user. If yes, apply the objects
595     // to the present TGeo geometry
596     if (fAlignObjArray) {
597       if (gGeoManager && gGeoManager->IsClosed()) {
598         if (AliGeomManager::ApplyAlignObjsToGeom(*fAlignObjArray) == kFALSE) {
599           AliError("The misalignment of one or more volumes failed!"
600                    "Compare the list of simulated detectors and the list of detector alignment data!");
601           return kFALSE;
602         }
603       }
604       else {
605         AliError("Can't apply the misalignment! gGeoManager doesn't exist or it is still opened!");
606         return kFALSE;
607       }
608     }
609   }
610   
611   delete fAlignObjArray; fAlignObjArray=0;
612
613   return kTRUE;
614 }
615
616 //_____________________________________________________________________________
617 void AliReconstruction::SetGAliceFile(const char* fileName)
618 {
619 // set the name of the galice file
620
621   fGAliceFileName = fileName;
622 }
623
624 //_____________________________________________________________________________
625 void AliReconstruction::SetInput(const char* input) 
626 {
627   // In case the input string starts with 'mem://', we run in an online mode
628   // and AliRawReaderDateOnline object is created. In all other cases a raw-data
629   // file is assumed. One can give as an input:
630   // mem://: - events taken from DAQ monitoring libs online
631   //  or
632   // mem://<filename> - emulation of the above mode (via DATE monitoring libs)
633   fInput = input;
634 }
635
636 //_____________________________________________________________________________
637 void AliReconstruction::SetOption(const char* detector, const char* option)
638 {
639 // set options for the reconstruction of a detector
640
641   TObject* obj = fOptions.FindObject(detector);
642   if (obj) fOptions.Remove(obj);
643   fOptions.Add(new TNamed(detector, option));
644 }
645
646 //_____________________________________________________________________________
647 Bool_t AliReconstruction::Run(const char* input)
648 {
649   // Run Run Run
650   AliCodeTimerAuto("");
651
652   if (!InitRun(input)) return kFALSE;
653   //******* The loop over events
654   Int_t iEvent = 0;
655   while ((iEvent < fRunLoader->GetNumberOfEvents()) ||
656          (fRawReader && fRawReader->NextEvent())) {
657     if (!RunEvent(iEvent)) return kFALSE;
658     iEvent++;
659   }
660
661   if (!FinishRun()) return kFALSE;
662
663   return kTRUE;
664 }
665
666 //_____________________________________________________________________________
667 Bool_t AliReconstruction::InitRun(const char* input)
668 {
669   // Initialize all the stuff before
670   // going into the event loop
671   // If the second argument is given, the first one is ignored and
672   // the reconstruction works in an online mode
673   AliCodeTimerAuto("");
674
675   // Overwrite the previous setting
676   if (input) fInput = input;
677
678   // set the input in case of raw data
679   fRawReader = AliRawReader::Create(fInput.Data());
680   if (!fRawReader)
681     AliInfo("Reconstruction will run over digits");
682
683   if (!fEquipIdMap.IsNull() && fRawReader)
684     fRawReader->LoadEquipmentIdsMap(fEquipIdMap);
685
686   if (!fUseHLTData.IsNull()) {
687     // create the RawReaderHLT which performs redirection of HLT input data for
688     // the specified detectors
689     AliRawReader* pRawReader=AliRawHLTManager::CreateRawReaderHLT(fRawReader, fUseHLTData.Data());
690     if (pRawReader) {
691       fParentRawReader=fRawReader;
692       fRawReader=pRawReader;
693     } else {
694       AliError(Form("can not create Raw Reader for HLT input %s", fUseHLTData.Data()));
695     }
696   }
697
698    AliSysInfo::AddStamp("Start");
699   // get the run loader
700   if (!InitRunLoader()) return kFALSE;
701    AliSysInfo::AddStamp("LoadLoader");
702
703   // Initialize the CDB storage
704   InitCDB();
705   
706   AliSysInfo::AddStamp("LoadCDB");
707
708   // Set run number in CDBManager (if it is not already set by the user)
709   if (!SetRunNumberFromData()) if (fStopOnError) return kFALSE;
710   
711   // Set CDB lock: from now on it is forbidden to reset the run number
712   // or the default storage or to activate any further storage!
713   SetCDBLock();
714   
715   // Import ideal TGeo geometry and apply misalignment
716   if (!gGeoManager) {
717     TString geom(gSystem->DirName(fGAliceFileName));
718     geom += "/geometry.root";
719     AliGeomManager::LoadGeometry(geom.Data());
720
721     TString detsToCheck=fRunLocalReconstruction;
722     if(!AliGeomManager::CheckSymNamesLUT(detsToCheck.Data()))
723           AliFatalClass("Current loaded geometry differs in the definition of symbolic names!");
724     if (!gGeoManager) if (fStopOnError) return kFALSE;
725   }
726
727   if (!MisalignGeometry(fLoadAlignData)) if (fStopOnError) return kFALSE;
728    AliSysInfo::AddStamp("LoadGeom");
729
730
731   // Get the GRP CDB entry
732   AliCDBEntry* entryGRP = AliCDBManager::Instance()->Get("GRP/GRP/Data");
733
734   if (entryGRP) 
735         fGRPData = dynamic_cast<TMap*>(entryGRP->GetObject());  
736
737   if (!fGRPData) {
738         AliError("No GRP entry found in OCDB!");
739         return kFALSE;
740   }
741
742
743   // Magnetic field map
744   if (!AliTracker::GetFieldMap()) {
745     // Construct the field map out of the information retrieved from GRP.
746     //
747     // For the moment, this is a dummy piece of code.
748     // The actual map is expected to be already created in rec.C ! 
749     //
750
751     Float_t factor=1.;
752     Int_t map=AliMagWrapCheb::k5kG;
753     Bool_t dipoleON=kTRUE;
754
755     // L3
756     TObjString *l3Current=
757        dynamic_cast<TObjString*>(fGRPData->GetValue("fL3Current"));
758     if (!l3Current) {
759       AliError("GRP/GRP/Data entry:  missing value for the L3 current !");
760       return kFALSE;
761     }
762     TObjString *l3Polarity=
763        dynamic_cast<TObjString*>(fGRPData->GetValue("fL3Polarity"));
764     if (!l3Polarity) {
765       AliError("GRP/GRP/Data entry:  missing value for the L3 polarity !");
766       return kFALSE;
767     }
768
769     // Dipole
770     TObjString *diCurrent=
771        dynamic_cast<TObjString*>(fGRPData->GetValue("fDipoleCurrent"));
772     if (!diCurrent) {
773       AliError("GRP/GRP/Data entry:  missing value for the dipole current !");
774       return kFALSE;
775     }
776     TObjString *diPolarity=
777        dynamic_cast<TObjString*>(fGRPData->GetValue("fDipolePolarity"));
778     if (!diPolarity) {
779       AliError("GRP/GRP/Data entry:  missing value for the dipole polarity !");
780       return kFALSE;
781     }
782
783
784     AliMagF *field=
785       new AliMagWrapCheb("Maps","Maps",2,factor,10.,map,dipoleON);
786     AliTracker::SetFieldMap(field,fUniformField);    
787
788     //Temporary measure
789     AliFatal("Please, provide the field map !  Crashing deliberately...");
790
791   }
792
793
794   // Get the diamond profile from OCDB
795   AliCDBEntry* entry = AliCDBManager::Instance()
796         ->Get("GRP/Calib/MeanVertex");
797         
798   if(entry) {
799         fDiamondProfile = dynamic_cast<AliESDVertex*> (entry->GetObject());  
800   } else {
801         AliError("No diamond profile found in OCDB!");
802   }
803
804   entry = 0;
805   entry = AliCDBManager::Instance()
806         ->Get("GRP/Calib/MeanVertexTPC");
807         
808   if(entry) {
809         fDiamondProfileTPC = dynamic_cast<AliESDVertex*> (entry->GetObject());  
810   } else {
811         AliError("No diamond profile found in OCDB!");
812   }
813
814   ftVertexer = new AliVertexerTracks(AliTracker::GetBz());
815   if(fDiamondProfile && fMeanVertexConstraint) ftVertexer->SetVtxStart(fDiamondProfile);
816
817   // get vertexer
818   if (fRunVertexFinder && !CreateVertexer()) {
819     if (fStopOnError) {
820       CleanUp(); 
821       return kFALSE;
822     }
823   }
824    AliSysInfo::AddStamp("Vertexer");
825
826   // get trackers
827   if (!fRunTracking.IsNull() && !CreateTrackers(fRunTracking)) {
828     if (fStopOnError) {
829       CleanUp(); 
830       return kFALSE;
831     }      
832   }
833    AliSysInfo::AddStamp("LoadTrackers");
834
835   // get the possibly already existing ESD file and tree
836   fesd = new AliESDEvent(); fhltesd = new AliESDEvent();
837   if (!gSystem->AccessPathName("AliESDs.root")){
838     gSystem->CopyFile("AliESDs.root", "AliESDs.old.root", kTRUE);
839     ffileOld = TFile::Open("AliESDs.old.root");
840     if (ffileOld && ffileOld->IsOpen()) {
841       ftreeOld = (TTree*) ffileOld->Get("esdTree");
842       if (ftreeOld)fesd->ReadFromTree(ftreeOld);
843       fhlttreeOld = (TTree*) ffileOld->Get("HLTesdTree");
844       if (fhlttreeOld)  fhltesd->ReadFromTree(fhlttreeOld);
845     }
846   }
847
848   // create the ESD output file and tree
849   ffile = TFile::Open("AliESDs.root", "RECREATE");
850   ffile->SetCompressionLevel(2);
851   if (!ffile->IsOpen()) {
852     AliError("opening AliESDs.root failed");
853     if (fStopOnError) {CleanUp(ffile, ffileOld); return kFALSE;}    
854   }
855
856   ftree = new TTree("esdTree", "Tree with ESD objects");
857   fesd = new AliESDEvent();
858   fesd->CreateStdContent();
859   fesd->WriteToTree(ftree);
860
861   fhlttree = new TTree("HLTesdTree", "Tree with HLT ESD objects");
862   fhltesd = new AliESDEvent();
863   fhltesd->CreateStdContent();
864   fhltesd->WriteToTree(fhlttree);
865
866
867   if (fWriteESDfriend) {
868     fesdf = new AliESDfriend();
869     TBranch *br=ftree->Branch("ESDfriend.","AliESDfriend", &fesdf);
870     br->SetFile("AliESDfriends.root");
871     fesd->AddObject(fesdf);
872   }
873
874
875
876   if (fRawReader) fRawReader->RewindEvents();
877
878   ProcInfo_t ProcInfo;
879   gSystem->GetProcInfo(&ProcInfo);
880   AliInfo(Form("Current memory usage %d %d", ProcInfo.fMemResident, ProcInfo.fMemVirtual));
881   
882   //QA
883   if (fRunQA && fRawReader && fQATasks.Contains(Form("%d", AliQA::kRAWS))) { 
884                 AliQADataMakerSteer qas ; 
885                 qas.Run(fRunLocalReconstruction, fRawReader) ; 
886                 fSameQACycle = kTRUE ; 
887   }
888   //Initialize the QA and start of cycle for out-of-cycle QA
889   if (fRunQA) {
890           TString detStr(fQADetectors) ; 
891       for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
892          if (!IsSelected(fgkDetectorName[iDet], detStr)) 
893                          continue;
894          AliQADataMakerRec *qadm = GetQADataMaker(iDet);  
895          if (!qadm) 
896                          continue;
897          AliInfo(Form("Initializing the QA data maker for %s", 
898                 fgkDetectorName[iDet]));
899                  if (fQATasks.Contains(Form("%d", AliQA::kRECPOINTS))) 
900                          qadm->Init(AliQA::kRECPOINTS, AliCDBManager::Instance()->GetRun());
901                  if (fQATasks.Contains(Form("%d", AliQA::kESDS)))  
902                          qadm->Init(AliQA::kESDS, AliCDBManager::Instance()->GetRun());
903          if (!fInLoopQA) {
904                          if (fQATasks.Contains(Form("%d", AliQA::kRECPOINTS))) {
905                                  qadm->StartOfCycle(AliQA::kRECPOINTS, fSameQACycle);
906                                  fSameQACycle = kTRUE;
907                          }
908                          if (fQATasks.Contains(Form("%d", AliQA::kESDS))) {  
909                                  qadm->StartOfCycle(AliQA::kESDS, fSameQACycle);
910                                  fSameQACycle = kTRUE;
911                          }
912                  }
913       }
914           if (fRunGlobalQA) {
915                   AliQADataMakerRec *qadm = GetQADataMaker(AliQA::kGLOBAL);
916                   AliInfo(Form("Initializing the global QA data maker"));
917                   if (fQATasks.Contains(Form("%d", AliQA::kRECPOINTS))) {
918                           TObjArray *arr=
919                                 qadm->Init(AliQA::kRECPOINTS, AliCDBManager::Instance()->GetRun());
920                           AliTracker::SetResidualsArray(arr);
921                   }
922                   if (fQATasks.Contains(Form("%d", AliQA::kESDS))) {
923                           qadm->Init(AliQA::kESDS, AliCDBManager::Instance()->GetRun());
924                   }
925                   if (!fInLoopQA) {
926                           fSameQACycle = kFALSE;
927                           if (fQATasks.Contains(Form("%d", AliQA::kRECPOINTS))) {                                 
928                                   qadm->StartOfCycle(AliQA::kRECPOINTS, fSameQACycle);
929                                   fSameQACycle = kTRUE;
930                           }
931                           if (fQATasks.Contains(Form("%d", AliQA::kESDS))) { 
932                                   qadm->StartOfCycle(AliQA::kESDS, fSameQACycle);
933                                   fSameQACycle = kTRUE; 
934                           }
935                   }
936           }
937   }
938
939   //Initialize the Plane Efficiency framework
940   if (fRunPlaneEff && !InitPlaneEff()) {
941     if(fStopOnError) {CleanUp(ffile, ffileOld); return kFALSE;}
942   }
943
944   if (strcmp(gProgName,"alieve") == 0)
945     fRunAliEVE = InitAliEVE();
946
947   return kTRUE;
948 }
949
950 //_____________________________________________________________________________
951 Bool_t AliReconstruction::RunEvent(Int_t iEvent)
952 {
953   // run the reconstruction over a single event
954   // The event loop is steered in Run method
955
956   AliCodeTimerAuto("");
957
958   if (iEvent >= fRunLoader->GetNumberOfEvents()) {
959     fRunLoader->SetEventNumber(iEvent);
960     fRunLoader->GetHeader()->Reset(fRawReader->GetRunNumber(), 
961                                    iEvent, iEvent);
962     //??      fRunLoader->MakeTree("H");
963     fRunLoader->TreeE()->Fill();
964   }
965
966   if ((iEvent < fFirstEvent) || ((fLastEvent >= 0) && (iEvent > fLastEvent))) {
967     // copy old ESD to the new one
968     if (ftreeOld) {
969       fesd->ReadFromTree(ftreeOld);
970       ftreeOld->GetEntry(iEvent);
971       ftree->Fill();
972     }
973     if (fhlttreeOld) {
974       fhltesd->ReadFromTree(fhlttreeOld);
975       fhlttreeOld->GetEntry(iEvent);
976       fhlttree->Fill();
977     }
978     return kTRUE;
979   }
980
981   AliInfo(Form("processing event %d", iEvent));
982
983     //Start of cycle for the in-loop QA
984     if (fInLoopQA) {
985        if (fRunQA) {
986                   fSameQACycle = kFALSE ;
987           TString detStr(fQADetectors); 
988           for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
989              if (!IsSelected(fgkDetectorName[iDet], detStr)) 
990                                  continue;
991              AliQADataMakerRec *qadm = GetQADataMaker(iDet);  
992              if (!qadm) 
993                                  continue;
994                           if (fQATasks.Contains(Form("%d", AliQA::kRECPOINTS))) {
995                                   qadm->StartOfCycle(AliQA::kRECPOINTS, fSameQACycle);
996                                   fSameQACycle = kTRUE;
997                           }
998                           if (fQATasks.Contains(Form("%d", AliQA::kESDS))) {
999                                   qadm->StartOfCycle(AliQA::kESDS, fSameQACycle) ;
1000                                   fSameQACycle = kTRUE;
1001                           }
1002           }
1003                    if (fRunGlobalQA) {
1004                            fSameQACycle = kFALSE;
1005                            AliQADataMakerRec *qadm = GetQADataMaker(AliQA::kGLOBAL);
1006                            if (fQATasks.Contains(Form("%d", AliQA::kRECPOINTS))) {
1007                                    qadm->StartOfCycle(AliQA::kRECPOINTS, fSameQACycle);
1008                                    fSameQACycle = kTRUE;
1009                            }
1010                            if (fQATasks.Contains(Form("%d", AliQA::kESDS))) {
1011                                    qadm->StartOfCycle(AliQA::kESDS, fSameQACycle);
1012                                    fSameQACycle = kTRUE;
1013                            }
1014                    }               
1015            }
1016     }
1017
1018     fRunLoader->GetEvent(iEvent);
1019
1020     char aFileName[256];
1021     sprintf(aFileName, "ESD_%d.%d_final.root", 
1022             fRunLoader->GetHeader()->GetRun(), 
1023             fRunLoader->GetHeader()->GetEventNrInRun());
1024     if (!gSystem->AccessPathName(aFileName)) return kTRUE;
1025
1026     // local single event reconstruction
1027     if (!fRunLocalReconstruction.IsNull()) {
1028       TString detectors=fRunLocalReconstruction;
1029       // run HLT event reconstruction first
1030       // ;-( IsSelected changes the string
1031       if (IsSelected("HLT", detectors) &&
1032           !RunLocalEventReconstruction("HLT")) {
1033         if (fStopOnError) {CleanUp(ffile, ffileOld); return kFALSE;}
1034       }
1035       detectors=fRunLocalReconstruction;
1036       detectors.ReplaceAll("HLT", "");
1037       if (!RunLocalEventReconstruction(detectors)) {
1038         if (fStopOnError) {CleanUp(ffile, ffileOld); return kFALSE;}
1039       }
1040     }
1041
1042     fesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
1043     fhltesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
1044     fesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
1045     fhltesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
1046     
1047     // Set magnetic field from the tracker
1048     fesd->SetMagneticField(AliTracker::GetBz());
1049     fhltesd->SetMagneticField(AliTracker::GetBz());
1050
1051     
1052     
1053     // Fill raw-data error log into the ESD
1054     if (fRawReader) FillRawDataErrorLog(iEvent,fesd);
1055
1056     // vertex finder
1057     if (fRunVertexFinder) {
1058       if (!ReadESD(fesd, "vertex")) {
1059         if (!RunVertexFinder(fesd)) {
1060           if (fStopOnError) {CleanUp(ffile, ffileOld); return kFALSE;}
1061         }
1062         if (fCheckPointLevel > 0) WriteESD(fesd, "vertex");
1063       }
1064     }
1065
1066     // Muon tracking
1067     if (!fRunTracking.IsNull()) {
1068       if (fRunMuonTracking) {
1069         if (!RunMuonTracking(fesd)) {
1070           if (fStopOnError) {CleanUp(ffile, ffileOld); return kFALSE;}
1071         }
1072       }
1073     }
1074
1075     // barrel tracking
1076     if (!fRunTracking.IsNull()) {
1077       if (!ReadESD(fesd, "tracking")) {
1078         if (!RunTracking(fesd)) {
1079           if (fStopOnError) {CleanUp(ffile, ffileOld); return kFALSE;}
1080         }
1081         if (fCheckPointLevel > 0) WriteESD(fesd, "tracking");
1082       }
1083     }
1084
1085     // fill ESD
1086     if (!fFillESD.IsNull()) {
1087       TString detectors=fFillESD;
1088       // run HLT first and on hltesd
1089       // ;-( IsSelected changes the string
1090       if (IsSelected("HLT", detectors) &&
1091           !FillESD(fhltesd, "HLT")) {
1092         if (fStopOnError) {CleanUp(ffile, ffileOld); return kFALSE;}
1093       }
1094       detectors=fFillESD;
1095       // Temporary fix to avoid problems with HLT that overwrites the offline ESDs
1096       if (detectors.Contains("ALL")) {
1097         detectors="";
1098         for (Int_t idet=0; idet<fgkNDetectors; ++idet){
1099           detectors += fgkDetectorName[idet];
1100           detectors += " ";
1101         }
1102       }
1103       detectors.ReplaceAll("HLT", "");
1104       if (!FillESD(fesd, detectors)) {
1105         if (fStopOnError) {CleanUp(ffile, ffileOld); return kFALSE;}
1106       }
1107     }
1108   
1109     // fill Event header information from the RawEventHeader
1110     if (fRawReader){FillRawEventHeaderESD(fesd);}
1111
1112     // combined PID
1113     AliESDpid::MakePID(fesd);
1114     if (fCheckPointLevel > 1) WriteESD(fesd, "PID");
1115
1116     if (fFillTriggerESD) {
1117       if (!ReadESD(fesd, "trigger")) {
1118         if (!FillTriggerESD(fesd)) {
1119           if (fStopOnError) {CleanUp(ffile, ffileOld); return kFALSE;}
1120         }
1121         if (fCheckPointLevel > 1) WriteESD(fesd, "trigger");
1122       }
1123     }
1124
1125     ffile->cd();
1126
1127     //
1128     // Propagate track to the beam pipe  (if not already done by ITS)
1129     //
1130     const Int_t ntracks = fesd->GetNumberOfTracks();
1131     const Double_t kBz = fesd->GetMagneticField();
1132     const Double_t kRadius  = 2.8; //something less than the beam pipe radius
1133
1134     TObjArray trkArray;
1135     UShort_t *selectedIdx=new UShort_t[ntracks];
1136
1137     for (Int_t itrack=0; itrack<ntracks; itrack++){
1138       const Double_t kMaxStep = 5;   //max step over the material
1139       Bool_t ok;
1140
1141       AliESDtrack *track = fesd->GetTrack(itrack);
1142       if (!track) continue;
1143
1144       AliExternalTrackParam *tpcTrack =
1145            (AliExternalTrackParam *)track->GetTPCInnerParam();
1146       ok = kFALSE;
1147       if (tpcTrack)
1148         ok = AliTracker::
1149           PropagateTrackTo(tpcTrack,kRadius,track->GetMass(),kMaxStep,kTRUE);
1150
1151       if (ok) {
1152         Int_t n=trkArray.GetEntriesFast();
1153         selectedIdx[n]=track->GetID();
1154         trkArray.AddLast(tpcTrack);
1155       }
1156
1157       //Tracks refitted by ITS should already be at the SPD vertex
1158       if (track->IsOn(AliESDtrack::kITSrefit)) continue;
1159
1160       AliTracker::
1161          PropagateTrackTo(track,kRadius,track->GetMass(),kMaxStep,kTRUE);
1162       track->RelateToVertex(fesd->GetPrimaryVertexSPD(), kBz, kVeryBig);
1163
1164     }
1165
1166     //
1167     // Improve the reconstructed primary vertex position using the tracks
1168     //
1169     TObject *obj = fOptions.FindObject("ITS");
1170     if (obj) {
1171       TString optITS = obj->GetTitle();
1172       if (optITS.Contains("cosmics") || optITS.Contains("COSMICS")) 
1173         fRunVertexFinderTracks=kFALSE;
1174     }
1175     if (fRunVertexFinderTracks) {
1176        // TPC + ITS primary vertex
1177        ftVertexer->SetITSrefitRequired();
1178        if(fDiamondProfile && fMeanVertexConstraint) {
1179          ftVertexer->SetVtxStart(fDiamondProfile);
1180        } else {
1181          ftVertexer->SetConstraintOff();
1182        }
1183        AliESDVertex *pvtx=ftVertexer->FindPrimaryVertex(fesd);
1184        if (pvtx) {
1185           if (pvtx->GetStatus()) {
1186              fesd->SetPrimaryVertex(pvtx);
1187              for (Int_t i=0; i<ntracks; i++) {
1188                  AliESDtrack *t = fesd->GetTrack(i);
1189                  t->RelateToVertex(pvtx, kBz, kVeryBig);
1190              } 
1191           }
1192        }
1193
1194        // TPC-only primary vertex
1195        ftVertexer->SetITSrefitNotRequired();
1196        if(fDiamondProfileTPC && fMeanVertexConstraint) {
1197          ftVertexer->SetVtxStart(fDiamondProfileTPC);
1198        } else {
1199          ftVertexer->SetConstraintOff();
1200        }
1201        pvtx=ftVertexer->FindPrimaryVertex(&trkArray,selectedIdx);
1202        if (pvtx) {
1203           if (pvtx->GetStatus()) {
1204              fesd->SetPrimaryVertexTPC(pvtx);
1205              for (Int_t i=0; i<ntracks; i++) {
1206                  AliESDtrack *t = fesd->GetTrack(i);
1207                  t->RelateToVertexTPC(pvtx, kBz, kVeryBig);
1208              } 
1209           }
1210        }
1211
1212     }
1213     delete[] selectedIdx;
1214
1215     if(fDiamondProfile) fesd->SetDiamond(fDiamondProfile);
1216     
1217
1218     if (fRunV0Finder) {
1219        // V0 finding
1220        AliV0vertexer vtxer;
1221        vtxer.Tracks2V0vertices(fesd);
1222
1223        if (fRunCascadeFinder) {
1224           // Cascade finding
1225           AliCascadeVertexer cvtxer;
1226           cvtxer.V0sTracks2CascadeVertices(fesd);
1227        }
1228     }
1229  
1230     // write ESD
1231     if (fCleanESD) CleanESD(fesd);
1232
1233         if (fRunQA) {
1234                 if (fRunGlobalQA) {
1235                         AliQADataMakerRec *qadm = GetQADataMaker(AliQA::kGLOBAL);
1236                         if (qadm && fQATasks.Contains(Form("%d", AliQA::kESDS)))
1237                                 qadm->Exec(AliQA::kESDS, fesd);
1238                 }
1239         }
1240
1241     if (fWriteESDfriend) {
1242       fesdf->~AliESDfriend();
1243       new (fesdf) AliESDfriend(); // Reset...
1244       fesd->GetESDfriend(fesdf);
1245     }
1246     ftree->Fill();
1247
1248     // write HLT ESD
1249     fhlttree->Fill();
1250
1251     // call AliEVE
1252     if (fRunAliEVE) RunAliEVE();
1253
1254     if (fCheckPointLevel > 0)  WriteESD(fesd, "final"); 
1255     fesd->Reset();
1256     fhltesd->Reset();
1257     if (fWriteESDfriend) {
1258       fesdf->~AliESDfriend();
1259       new (fesdf) AliESDfriend(); // Reset...
1260     }
1261  
1262     ProcInfo_t ProcInfo;
1263     gSystem->GetProcInfo(&ProcInfo);
1264     AliInfo(Form("Event %d -> Current memory usage %d %d",iEvent, ProcInfo.fMemResident, ProcInfo.fMemVirtual));
1265   
1266
1267   // End of cycle for the in-loop  
1268      if (fInLoopQA) {
1269         if (fRunQA) {
1270            RunQA(fesd);
1271            for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1272                            if (!IsSelected(fgkDetectorName[iDet], fQADetectors)) 
1273                                    continue;
1274                            AliQADataMakerRec * qadm = GetQADataMaker(iDet);
1275                            if (!qadm)
1276                                    continue;
1277                            if (fQATasks.Contains(Form("%d", AliQA::kRECPOINTS))) 
1278                                    qadm->EndOfCycle(AliQA::kRECPOINTS);
1279                            if (fQATasks.Contains(Form("%d", AliQA::kESDS))) 
1280                                    qadm->EndOfCycle(AliQA::kESDS);
1281                            qadm->Finish();
1282                    }
1283         }
1284         if (fRunGlobalQA) {
1285            AliQADataMakerRec *qadm = GetQADataMaker(AliQA::kGLOBAL);
1286            if (qadm) {
1287                            if (fQATasks.Contains(Form("%d", AliQA::kRECPOINTS))) 
1288                                    qadm->EndOfCycle(AliQA::kRECPOINTS);
1289                            if (fQATasks.Contains(Form("%d", AliQA::kESDS))) 
1290                                    qadm->EndOfCycle(AliQA::kESDS);
1291                            qadm->Finish();
1292                    }
1293         }
1294      }
1295
1296      return kTRUE;
1297 }
1298
1299 //_____________________________________________________________________________
1300 Bool_t AliReconstruction::FinishRun()
1301 {
1302   // Finalize the run
1303   // Called after the exit
1304   // from the event loop
1305   AliCodeTimerAuto("");
1306
1307   if (fIsNewRunLoader) { // galice.root didn't exist
1308     fRunLoader->WriteHeader("OVERWRITE");
1309     fRunLoader->CdGAFile();
1310     fRunLoader->Write(0, TObject::kOverwrite);
1311   }
1312
1313   ftree->GetUserInfo()->Add(fesd);
1314   fhlttree->GetUserInfo()->Add(fhltesd);
1315   
1316   const TMap *cdbMap = AliCDBManager::Instance()->GetStorageMap();       
1317   const TList *cdbList = AliCDBManager::Instance()->GetRetrievedIds();   
1318                  
1319    TMap *cdbMapCopy = new TMap(cdbMap->GetEntries());    
1320    cdbMapCopy->SetOwner(1);      
1321    cdbMapCopy->SetName("cdbMap");        
1322    TIter iter(cdbMap->GetTable());       
1323          
1324    TPair* pair = 0;      
1325    while((pair = dynamic_cast<TPair*> (iter.Next()))){   
1326          TObjString* keyStr = dynamic_cast<TObjString*> (pair->Key());   
1327          TObjString* valStr = dynamic_cast<TObjString*> (pair->Value());         
1328          cdbMapCopy->Add(new TObjString(keyStr->GetName()), new TObjString(valStr->GetName()));  
1329    }     
1330          
1331    TList *cdbListCopy = new TList();     
1332    cdbListCopy->SetOwner(1);     
1333    cdbListCopy->SetName("cdbList");      
1334          
1335    TIter iter2(cdbList);         
1336          
1337    AliCDBId* id=0;       
1338    while((id = dynamic_cast<AliCDBId*> (iter2.Next()))){         
1339          cdbListCopy->Add(new TObjString(id->ToString().Data()));        
1340    }     
1341          
1342    ftree->GetUserInfo()->Add(cdbMapCopy);        
1343    ftree->GetUserInfo()->Add(cdbListCopy);
1344
1345
1346   if(fESDPar.Contains("ESD.par")){
1347     AliInfo("Attaching ESD.par to Tree");
1348     TNamed *fn = CopyFileToTNamed(fESDPar.Data(),"ESD.par");
1349     ftree->GetUserInfo()->Add(fn);
1350   }
1351
1352
1353   ffile->cd();
1354
1355   if (fWriteESDfriend)
1356     ftree->SetBranchStatus("ESDfriend*",0);
1357   // we want to have only one tree version number
1358   ftree->Write(ftree->GetName(),TObject::kOverwrite);
1359   fhlttree->Write();
1360
1361 // Finish with Plane Efficiency evaluation: before of CleanUp !!!
1362   if (fRunPlaneEff && !FinishPlaneEff()) {
1363    AliWarning("Finish PlaneEff evaluation failed");
1364   }
1365
1366   gROOT->cd();
1367   CleanUp(ffile, ffileOld);
1368     
1369   if (fWriteAOD) {
1370     AliWarning("AOD creation not supported anymore during reconstruction. See ANALYSIS/AliAnalysisTaskESDfilter.cxx instead.");
1371   }
1372
1373   // Create tags for the events in the ESD tree (the ESD tree is always present)
1374   // In case of empty events the tags will contain dummy values
1375   AliESDTagCreator *esdtagCreator = new AliESDTagCreator();
1376   esdtagCreator->CreateESDTags(fFirstEvent,fLastEvent,fGRPData);
1377   if (fWriteAOD) {
1378     AliWarning("AOD tag creation not supported anymore during reconstruction.");
1379   }
1380
1381   //Finish QA and end of cycle for out-of-loop QA
1382   if (!fInLoopQA) {
1383           if (fRunQA) {
1384                   AliQADataMakerSteer qas;
1385                   if (fQATasks.Contains(Form("%d", AliQA::kRECPOINTS))) 
1386                           qas.Run(fRunLocalReconstruction.Data(), AliQA::kRECPOINTS, fSameQACycle);
1387                   //qas.Reset() ;
1388                   if (fQATasks.Contains(Form("%d", AliQA::kESDS))) 
1389                           qas.Run(fRunLocalReconstruction.Data(), AliQA::kESDS, fSameQACycle);
1390                   if (fRunGlobalQA) {
1391                          AliQADataMakerRec *qadm = GetQADataMaker(AliQA::kGLOBAL);
1392                           if (qadm) {
1393                                   if (fQATasks.Contains(Form("%d", AliQA::kRECPOINTS))) 
1394                                           qadm->EndOfCycle(AliQA::kRECPOINTS);
1395                                   if (fQATasks.Contains(Form("%d", AliQA::kESDS))) 
1396                                           qadm->EndOfCycle(AliQA::kESDS);
1397                                   qadm->Finish();
1398                           }
1399                   }
1400           }
1401   }
1402   
1403   // Cleanup of CDB manager: cache and active storages!
1404   AliCDBManager::Instance()->ClearCache();
1405   
1406   return kTRUE;
1407 }
1408
1409
1410 //_____________________________________________________________________________
1411 Bool_t AliReconstruction::RunLocalReconstruction(const TString& /*detectors*/)
1412 {
1413 // run the local reconstruction
1414   static Int_t eventNr=0;
1415   AliCodeTimerAuto("")
1416
1417  //  AliCDBManager* man = AliCDBManager::Instance();
1418 //   Bool_t origCache = man->GetCacheFlag();
1419
1420 //   TString detStr = detectors;
1421 //   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1422 //     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1423 //     AliReconstructor* reconstructor = GetReconstructor(iDet);
1424 //     if (!reconstructor) continue;
1425 //     if (reconstructor->HasLocalReconstruction()) continue;
1426
1427 //     AliCodeTimerStart(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1428 //     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1429     
1430 //     AliCodeTimerStart(Form("Loading calibration data from OCDB for %s", fgkDetectorName[iDet]));                          
1431 //     AliInfo(Form("Loading calibration data from OCDB for %s", fgkDetectorName[iDet]));
1432
1433 //     man->SetCacheFlag(kTRUE);
1434 //     TString calibPath = Form("%s/Calib/*", fgkDetectorName[iDet]);
1435 //     man->GetAll(calibPath); // entries are cached!
1436
1437 //     AliCodeTimerStop(Form("Loading calibration data from OCDB for %s", fgkDetectorName[iDet]));
1438      
1439 //     if (fRawReader) {
1440 //       fRawReader->RewindEvents();
1441 //       reconstructor->Reconstruct(fRunLoader, fRawReader);
1442 //     } else {
1443 //       reconstructor->Reconstruct(fRunLoader);
1444 //     }
1445      
1446 //      AliCodeTimerStop(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1447     // AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr));
1448
1449 //     // unload calibration data
1450 //     man->UnloadFromCache(calibPath);
1451 //     //man->ClearCache();
1452 //   }
1453
1454 //   man->SetCacheFlag(origCache);
1455
1456 //   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1457 //     AliError(Form("the following detectors were not found: %s",
1458 //                   detStr.Data()));
1459 //     if (fStopOnError) return kFALSE;
1460 //   }
1461
1462           eventNr++;
1463   return kTRUE;
1464 }
1465
1466 //_____________________________________________________________________________
1467 Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
1468 {
1469 // run the local reconstruction
1470
1471   static Int_t eventNr=0;
1472   AliCodeTimerAuto("")
1473
1474   TString detStr = detectors;
1475   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1476     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1477     AliReconstructor* reconstructor = GetReconstructor(iDet);
1478     if (!reconstructor) continue;
1479     AliLoader* loader = fLoader[iDet];
1480     // Matthias April 2008: temporary fix to run HLT reconstruction
1481     // although the HLT loader is missing
1482     if (strcmp(fgkDetectorName[iDet], "HLT")==0) {
1483       if (fRawReader) {
1484         reconstructor->Reconstruct(fRawReader, NULL);
1485       } else {
1486         TTree* dummy=NULL;
1487         reconstructor->Reconstruct(dummy, NULL);
1488       }
1489       continue;
1490     }
1491     if (!loader) {
1492       AliWarning(Form("No loader is defined for %s!",fgkDetectorName[iDet]));
1493       continue;
1494     }
1495     // conversion of digits
1496     if (fRawReader && reconstructor->HasDigitConversion()) {
1497       AliInfo(Form("converting raw data digits into root objects for %s", 
1498                    fgkDetectorName[iDet]));
1499       AliCodeTimerAuto(Form("converting raw data digits into root objects for %s", 
1500                             fgkDetectorName[iDet]));
1501       loader->LoadDigits("update");
1502       loader->CleanDigits();
1503       loader->MakeDigitsContainer();
1504       TTree* digitsTree = loader->TreeD();
1505       reconstructor->ConvertDigits(fRawReader, digitsTree);
1506       loader->WriteDigits("OVERWRITE");
1507       loader->UnloadDigits();
1508     }
1509     // local reconstruction
1510     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1511     AliCodeTimerAuto(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1512     loader->LoadRecPoints("update");
1513     loader->CleanRecPoints();
1514     loader->MakeRecPointsContainer();
1515     TTree* clustersTree = loader->TreeR();
1516     if (fRawReader && !reconstructor->HasDigitConversion()) {
1517       reconstructor->Reconstruct(fRawReader, clustersTree);
1518     } else {
1519       loader->LoadDigits("read");
1520       TTree* digitsTree = loader->TreeD();
1521       if (!digitsTree) {
1522         AliError(Form("Can't get the %s digits tree", fgkDetectorName[iDet]));
1523         if (fStopOnError) return kFALSE;
1524       } else {
1525         reconstructor->Reconstruct(digitsTree, clustersTree);
1526       }
1527       loader->UnloadDigits();
1528     }
1529
1530     // In-loop QA for local reconstrucion 
1531     if (fRunQA && fInLoopQA) {
1532        AliQADataMakerRec * qadm = GetQADataMaker(iDet);
1533        if (qadm) {
1534           //AliCodeTimerStart
1535           //(Form("Running QA data maker for %s", fgkDetectorName[iDet]));
1536           //AliInfo
1537           //(Form("Running QA data maker for %s", fgkDetectorName[iDet]));
1538
1539                    if (fQATasks.Contains(Form("%d", AliQA::kRECPOINTS))) 
1540                            qadm->Exec(AliQA::kRECPOINTS, clustersTree) ;
1541           //AliCodeTimerStop
1542           //(Form("Running QA data maker for %s", fgkDetectorName[iDet]));
1543        }
1544     }
1545
1546     loader->WriteRecPoints("OVERWRITE");
1547     loader->UnloadRecPoints();
1548     AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr), iDet,1,eventNr);
1549   }
1550
1551   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1552     AliError(Form("the following detectors were not found: %s",
1553                   detStr.Data()));
1554     if (fStopOnError) return kFALSE;
1555   }
1556   eventNr++;
1557   return kTRUE;
1558 }
1559
1560 //_____________________________________________________________________________
1561 Bool_t AliReconstruction::RunVertexFinder(AliESDEvent*& esd)
1562 {
1563 // run the barrel tracking
1564
1565   AliCodeTimerAuto("")
1566
1567   AliESDVertex* vertex = NULL;
1568   Double_t vtxPos[3] = {0, 0, 0};
1569   Double_t vtxErr[3] = {0.07, 0.07, 0.1};
1570   TArrayF mcVertex(3); 
1571   if (fRunLoader->GetHeader() && fRunLoader->GetHeader()->GenEventHeader()) {
1572     fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(mcVertex);
1573     for (Int_t i = 0; i < 3; i++) vtxPos[i] = mcVertex[i];
1574   }
1575
1576   if (fVertexer) {
1577     AliInfo("running the ITS vertex finder");
1578     if (fLoader[0]) {
1579       fLoader[0]->LoadRecPoints();
1580       TTree* cltree = fLoader[0]->TreeR();
1581       if (cltree) {
1582         if(fDiamondProfile) fVertexer->SetVtxStart(fDiamondProfile);
1583         vertex = fVertexer->FindVertexForCurrentEvent(cltree);
1584       }
1585       else {
1586         AliError("Can't get the ITS cluster tree");
1587       }
1588       fLoader[0]->UnloadRecPoints();
1589     }
1590     else {
1591       AliError("Can't get the ITS loader");
1592     }
1593     if(!vertex){
1594       AliWarning("Vertex not found");
1595       vertex = new AliESDVertex();
1596       vertex->SetName("default");
1597     }
1598     else {
1599       vertex->SetName("reconstructed");
1600     }
1601
1602   } else {
1603     AliInfo("getting the primary vertex from MC");
1604     vertex = new AliESDVertex(vtxPos, vtxErr);
1605   }
1606
1607   if (vertex) {
1608     vertex->GetXYZ(vtxPos);
1609     vertex->GetSigmaXYZ(vtxErr);
1610   } else {
1611     AliWarning("no vertex reconstructed");
1612     vertex = new AliESDVertex(vtxPos, vtxErr);
1613   }
1614   esd->SetPrimaryVertexSPD(vertex);
1615   // if SPD multiplicity has been determined, it is stored in the ESD
1616   AliMultiplicity *mult = fVertexer->GetMultiplicity();
1617   if(mult)esd->SetMultiplicity(mult);
1618
1619   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1620     if (fTracker[iDet]) fTracker[iDet]->SetVertex(vtxPos, vtxErr);
1621   }  
1622   delete vertex;
1623
1624   return kTRUE;
1625 }
1626
1627 //_____________________________________________________________________________
1628 Bool_t AliReconstruction::RunHLTTracking(AliESDEvent*& esd)
1629 {
1630 // run the HLT barrel tracking
1631
1632   AliCodeTimerAuto("")
1633
1634   if (!fRunLoader) {
1635     AliError("Missing runLoader!");
1636     return kFALSE;
1637   }
1638
1639   AliInfo("running HLT tracking");
1640
1641   // Get a pointer to the HLT reconstructor
1642   AliReconstructor *reconstructor = GetReconstructor(fgkNDetectors-1);
1643   if (!reconstructor) return kFALSE;
1644
1645   // TPC + ITS
1646   for (Int_t iDet = 1; iDet >= 0; iDet--) {
1647     TString detName = fgkDetectorName[iDet];
1648     AliDebug(1, Form("%s HLT tracking", detName.Data()));
1649     reconstructor->SetOption(detName.Data());
1650     AliTracker *tracker = reconstructor->CreateTracker();
1651     if (!tracker) {
1652       AliWarning(Form("couldn't create a HLT tracker for %s", detName.Data()));
1653       if (fStopOnError) return kFALSE;
1654       continue;
1655     }
1656     Double_t vtxPos[3];
1657     Double_t vtxErr[3]={0.005,0.005,0.010};
1658     const AliESDVertex *vertex = esd->GetVertex();
1659     vertex->GetXYZ(vtxPos);
1660     tracker->SetVertex(vtxPos,vtxErr);
1661     if(iDet != 1) {
1662       fLoader[iDet]->LoadRecPoints("read");
1663       TTree* tree = fLoader[iDet]->TreeR();
1664       if (!tree) {
1665         AliError(Form("Can't get the %s cluster tree", detName.Data()));
1666         return kFALSE;
1667       }
1668       tracker->LoadClusters(tree);
1669     }
1670     if (tracker->Clusters2Tracks(esd) != 0) {
1671       AliError(Form("HLT %s Clusters2Tracks failed", fgkDetectorName[iDet]));
1672       return kFALSE;
1673     }
1674     if(iDet != 1) {
1675       tracker->UnloadClusters();
1676     }
1677     delete tracker;
1678   }
1679
1680   return kTRUE;
1681 }
1682
1683 //_____________________________________________________________________________
1684 Bool_t AliReconstruction::RunMuonTracking(AliESDEvent*& esd)
1685 {
1686 // run the muon spectrometer tracking
1687
1688   AliCodeTimerAuto("")
1689
1690   if (!fRunLoader) {
1691     AliError("Missing runLoader!");
1692     return kFALSE;
1693   }
1694   Int_t iDet = 7; // for MUON
1695
1696   AliInfo("is running...");
1697
1698   // Get a pointer to the MUON reconstructor
1699   AliReconstructor *reconstructor = GetReconstructor(iDet);
1700   if (!reconstructor) return kFALSE;
1701
1702   
1703   TString detName = fgkDetectorName[iDet];
1704   AliDebug(1, Form("%s tracking", detName.Data()));
1705   AliTracker *tracker =  reconstructor->CreateTracker();
1706   if (!tracker) {
1707     AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
1708     return kFALSE;
1709   }
1710      
1711   // read RecPoints
1712   fLoader[iDet]->LoadRecPoints("read");  
1713
1714   tracker->LoadClusters(fLoader[iDet]->TreeR());
1715   
1716   Int_t rv = tracker->Clusters2Tracks(esd);
1717   
1718   if ( rv )
1719   {
1720     AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
1721     return kFALSE;
1722   }
1723   
1724   fLoader[iDet]->UnloadRecPoints();
1725
1726   tracker->UnloadClusters();
1727   
1728   delete tracker;
1729   
1730   return kTRUE;
1731 }
1732
1733
1734 //_____________________________________________________________________________
1735 Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd)
1736 {
1737 // run the barrel tracking
1738   static Int_t eventNr=0;
1739   AliCodeTimerAuto("")
1740
1741   AliInfo("running tracking");
1742
1743   //Fill the ESD with the T0 info (will be used by the TOF) 
1744   if (fReconstructor[11] && fLoader[11]) {
1745     fLoader[11]->LoadRecPoints("READ");
1746     TTree *treeR = fLoader[11]->TreeR();
1747     GetReconstructor(11)->FillESD((TTree *)NULL,treeR,esd);
1748   }
1749
1750   // pass 1: TPC + ITS inwards
1751   for (Int_t iDet = 1; iDet >= 0; iDet--) {
1752     if (!fTracker[iDet]) continue;
1753     AliDebug(1, Form("%s tracking", fgkDetectorName[iDet]));
1754
1755     // load clusters
1756     fLoader[iDet]->LoadRecPoints("read");
1757     AliSysInfo::AddStamp(Form("RLoadCluster%s_%d",fgkDetectorName[iDet],eventNr),iDet,1, eventNr);
1758     TTree* tree = fLoader[iDet]->TreeR();
1759     if (!tree) {
1760       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
1761       return kFALSE;
1762     }
1763     fTracker[iDet]->LoadClusters(tree);
1764     AliSysInfo::AddStamp(Form("TLoadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
1765     // run tracking
1766     if (fTracker[iDet]->Clusters2Tracks(esd) != 0) {
1767       AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
1768       return kFALSE;
1769     }
1770     if (fCheckPointLevel > 1) {
1771       WriteESD(esd, Form("%s.tracking", fgkDetectorName[iDet]));
1772     }
1773     // preliminary PID in TPC needed by the ITS tracker
1774     if (iDet == 1) {
1775       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
1776       AliESDpid::MakePID(esd);
1777     } 
1778     AliSysInfo::AddStamp(Form("Tracking0%s_%d",fgkDetectorName[iDet],eventNr), iDet,3,eventNr);
1779   }
1780
1781   // pass 2: ALL backwards
1782
1783   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1784     if (!fTracker[iDet]) continue;
1785     AliDebug(1, Form("%s back propagation", fgkDetectorName[iDet]));
1786
1787     // load clusters
1788     if (iDet > 1) {     // all except ITS, TPC
1789       TTree* tree = NULL;
1790       fLoader[iDet]->LoadRecPoints("read");
1791       AliSysInfo::AddStamp(Form("RLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,1, eventNr);
1792       tree = fLoader[iDet]->TreeR();
1793       if (!tree) {
1794         AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
1795         return kFALSE;
1796       }
1797       fTracker[iDet]->LoadClusters(tree); 
1798       AliSysInfo::AddStamp(Form("TLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
1799     }
1800
1801     // run tracking
1802     if (iDet>1) // start filling residuals for the "outer" detectors
1803     if (fRunGlobalQA) AliTracker::SetFillResiduals(kTRUE);     
1804
1805     if (fTracker[iDet]->PropagateBack(esd) != 0) {
1806       AliError(Form("%s backward propagation failed", fgkDetectorName[iDet]));
1807       //      return kFALSE;
1808     }
1809     if (fCheckPointLevel > 1) {
1810       WriteESD(esd, Form("%s.back", fgkDetectorName[iDet]));
1811     }
1812
1813     // unload clusters
1814     if (iDet > 2) {     // all except ITS, TPC, TRD
1815       fTracker[iDet]->UnloadClusters();
1816       fLoader[iDet]->UnloadRecPoints();
1817     }
1818     // updated PID in TPC needed by the ITS tracker -MI
1819     if (iDet == 1) {
1820       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
1821       AliESDpid::MakePID(esd);
1822     }
1823     AliSysInfo::AddStamp(Form("Tracking1%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
1824   }
1825   //stop filling residuals for the "outer" detectors
1826   if (fRunGlobalQA) AliTracker::SetFillResiduals(kFALSE);     
1827
1828   // write space-points to the ESD in case alignment data output
1829   // is switched on
1830   if (fWriteAlignmentData)
1831     WriteAlignmentData(esd);
1832
1833   // pass 3: TRD + TPC + ITS refit inwards
1834
1835   for (Int_t iDet = 2; iDet >= 0; iDet--) {
1836     if (!fTracker[iDet]) continue;
1837     AliDebug(1, Form("%s inward refit", fgkDetectorName[iDet]));
1838
1839     // run tracking
1840     if (iDet<2) // start filling residuals for TPC and ITS
1841     if (fRunGlobalQA) AliTracker::SetFillResiduals(kTRUE);     
1842
1843     if (fTracker[iDet]->RefitInward(esd) != 0) {
1844       AliError(Form("%s inward refit failed", fgkDetectorName[iDet]));
1845       //      return kFALSE;
1846     }
1847     // run postprocessing
1848     if (fTracker[iDet]->PostProcess(esd) != 0) {
1849       AliError(Form("%s postprocessing failed", fgkDetectorName[iDet]));
1850       //      return kFALSE;
1851     }
1852     if (fCheckPointLevel > 1) {
1853       WriteESD(esd, Form("%s.refit", fgkDetectorName[iDet]));
1854     }
1855     AliSysInfo::AddStamp(Form("Tracking2%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
1856     // unload clusters
1857     fTracker[iDet]->UnloadClusters();
1858     AliSysInfo::AddStamp(Form("TUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,4, eventNr);
1859     fLoader[iDet]->UnloadRecPoints();
1860     AliSysInfo::AddStamp(Form("RUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,5, eventNr);
1861   }
1862   // stop filling residuals for TPC and ITS
1863   if (fRunGlobalQA) AliTracker::SetFillResiduals(kFALSE);     
1864
1865   eventNr++;
1866   return kTRUE;
1867 }
1868
1869 //_____________________________________________________________________________
1870 Bool_t AliReconstruction::CleanESD(AliESDEvent *esd){
1871   //
1872   // Remove the data which are not needed for the physics analysis.
1873   //
1874
1875   Int_t nTracks=esd->GetNumberOfTracks();
1876   Int_t nV0s=esd->GetNumberOfV0s();
1877   AliInfo
1878   (Form("Number of ESD tracks and V0s before cleaning: %d %d",nTracks,nV0s));
1879
1880   Float_t cleanPars[]={fV0DCAmax,fV0CsPmin,fDmax,fZmax};
1881   Bool_t rc=esd->Clean(cleanPars);
1882
1883   nTracks=esd->GetNumberOfTracks();
1884   nV0s=esd->GetNumberOfV0s();
1885   AliInfo
1886   (Form("Number of ESD tracks and V0s after cleaning %d %d",nTracks,nV0s));
1887
1888   return rc;
1889 }
1890
1891 //_____________________________________________________________________________
1892 Bool_t AliReconstruction::FillESD(AliESDEvent*& esd, const TString& detectors)
1893 {
1894 // fill the event summary data
1895
1896   AliCodeTimerAuto("")
1897     static Int_t eventNr=0; 
1898   TString detStr = detectors;
1899   
1900   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1901   if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1902     AliReconstructor* reconstructor = GetReconstructor(iDet);
1903     if (!reconstructor) continue;
1904     if (!ReadESD(esd, fgkDetectorName[iDet])) {
1905       AliDebug(1, Form("filling ESD for %s", fgkDetectorName[iDet]));
1906       TTree* clustersTree = NULL;
1907       if (fLoader[iDet]) {
1908         fLoader[iDet]->LoadRecPoints("read");
1909         clustersTree = fLoader[iDet]->TreeR();
1910         if (!clustersTree) {
1911           AliError(Form("Can't get the %s clusters tree", 
1912                         fgkDetectorName[iDet]));
1913           if (fStopOnError) return kFALSE;
1914         }
1915       }
1916       if (fRawReader && !reconstructor->HasDigitConversion()) {
1917         reconstructor->FillESD(fRawReader, clustersTree, esd);
1918       } else {
1919         TTree* digitsTree = NULL;
1920         if (fLoader[iDet]) {
1921           fLoader[iDet]->LoadDigits("read");
1922           digitsTree = fLoader[iDet]->TreeD();
1923           if (!digitsTree) {
1924             AliError(Form("Can't get the %s digits tree", 
1925                           fgkDetectorName[iDet]));
1926             if (fStopOnError) return kFALSE;
1927           }
1928         }
1929         reconstructor->FillESD(digitsTree, clustersTree, esd);
1930         if (fLoader[iDet]) fLoader[iDet]->UnloadDigits();
1931       }
1932       if (fLoader[iDet]) {
1933         fLoader[iDet]->UnloadRecPoints();
1934       }
1935
1936       if (fCheckPointLevel > 2) WriteESD(esd, fgkDetectorName[iDet]);
1937     }
1938   }
1939
1940   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1941     AliError(Form("the following detectors were not found: %s", 
1942                   detStr.Data()));
1943     if (fStopOnError) return kFALSE;
1944   }
1945   AliSysInfo::AddStamp(Form("FillESD%d",eventNr), 0,1, eventNr);
1946   eventNr++;
1947   return kTRUE;
1948 }
1949
1950 //_____________________________________________________________________________
1951 Bool_t AliReconstruction::FillTriggerESD(AliESDEvent*& esd)
1952 {
1953   // Reads the trigger decision which is
1954   // stored in Trigger.root file and fills
1955   // the corresponding esd entries
1956
1957   AliCodeTimerAuto("")
1958   
1959   AliInfo("Filling trigger information into the ESD");
1960
1961   AliCentralTrigger *aCTP = NULL;
1962
1963   if (fRawReader) {
1964     AliCTPRawStream input(fRawReader);
1965     if (!input.Next()) {
1966       AliWarning("No valid CTP (trigger) DDL raw data is found ! The trigger mask will be taken from the event header, trigger cluster mask will be empty !");
1967       ULong_t mask = (((ULong_t)fRawReader->GetTriggerPattern()[1]) << 32) +
1968         fRawReader->GetTriggerPattern()[0];
1969       esd->SetTriggerMask(mask);
1970       esd->SetTriggerCluster(0);
1971     }
1972     else {
1973       esd->SetTriggerMask(input.GetClassMask());
1974       esd->SetTriggerCluster(input.GetClusterMask());
1975     }
1976
1977     aCTP = new AliCentralTrigger();
1978     TString configstr("");
1979     if (!aCTP->LoadConfiguration(configstr)) { // Load CTP config from OCDB
1980       AliError("No trigger configuration found in OCDB! The trigger classes information will no be stored in ESD!");
1981       delete aCTP;
1982       return kFALSE;
1983     }
1984   }
1985   else {
1986     AliRunLoader *runloader = AliRunLoader::GetRunLoader();
1987     if (runloader) {
1988       if (!runloader->LoadTrigger()) {
1989         aCTP = runloader->GetTrigger();
1990         esd->SetTriggerMask(aCTP->GetClassMask());
1991         esd->SetTriggerCluster(aCTP->GetClusterMask());
1992       }
1993       else {
1994         AliWarning("No trigger can be loaded! The trigger information is not stored in the ESD !");
1995         return kFALSE;
1996       }
1997     }
1998     else {
1999       AliError("No run loader is available! The trigger information is not stored in the ESD !");
2000       return kFALSE;
2001     }
2002   }
2003
2004   // Now fill the trigger class names into AliESDRun object
2005   AliTriggerConfiguration *config = aCTP->GetConfiguration();
2006   if (!config) {
2007     AliError("No trigger configuration has been found! The trigger classes information will not be stored in ESD!");
2008     if (fRawReader) delete aCTP;
2009     return kFALSE;
2010   }
2011
2012   const TObjArray& classesArray = config->GetClasses();
2013   Int_t nclasses = classesArray.GetEntriesFast();
2014   for( Int_t j=0; j<nclasses; j++ ) {
2015     AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At( j );
2016     Int_t trindex = (Int_t)TMath::Log2(trclass->GetMask());
2017     esd->SetTriggerClass(trclass->GetName(),trindex);
2018   }
2019
2020   if (fRawReader) delete aCTP;
2021   return kTRUE;
2022 }
2023
2024
2025
2026
2027
2028 //_____________________________________________________________________________
2029 Bool_t AliReconstruction::FillRawEventHeaderESD(AliESDEvent*& esd)
2030 {
2031   // 
2032   // Filling information from RawReader Header
2033   // 
2034
2035   AliInfo("Filling information from RawReader Header");
2036   esd->SetBunchCrossNumber(0);
2037   esd->SetOrbitNumber(0);
2038   esd->SetPeriodNumber(0);
2039   esd->SetTimeStamp(0);
2040   esd->SetEventType(0);
2041   const AliRawEventHeaderBase * eventHeader = fRawReader->GetEventHeader();
2042   if (eventHeader){
2043
2044     const UInt_t *id = eventHeader->GetP("Id");
2045     esd->SetBunchCrossNumber((id)[1]&0x00000fff);
2046     esd->SetOrbitNumber((((id)[0]<<20)&0xf00000)|(((id)[1]>>12)&0xfffff));
2047     esd->SetPeriodNumber(((id)[0]>>4)&0x0fffffff);
2048
2049     esd->SetTimeStamp((eventHeader->Get("Timestamp")));  
2050     esd->SetEventType((eventHeader->Get("Type")));
2051   }
2052
2053   return kTRUE;
2054 }
2055
2056
2057 //_____________________________________________________________________________
2058 Bool_t AliReconstruction::IsSelected(TString detName, TString& detectors) const
2059 {
2060 // check whether detName is contained in detectors
2061 // if yes, it is removed from detectors
2062
2063   // check if all detectors are selected
2064   if ((detectors.CompareTo("ALL") == 0) ||
2065       detectors.BeginsWith("ALL ") ||
2066       detectors.EndsWith(" ALL") ||
2067       detectors.Contains(" ALL ")) {
2068     detectors = "ALL";
2069     return kTRUE;
2070   }
2071
2072   // search for the given detector
2073   Bool_t result = kFALSE;
2074   if ((detectors.CompareTo(detName) == 0) ||
2075       detectors.BeginsWith(detName+" ") ||
2076       detectors.EndsWith(" "+detName) ||
2077       detectors.Contains(" "+detName+" ")) {
2078     detectors.ReplaceAll(detName, "");
2079     result = kTRUE;
2080   }
2081
2082   // clean up the detectors string
2083   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
2084   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
2085   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
2086
2087   return result;
2088 }
2089
2090 //_____________________________________________________________________________
2091 Bool_t AliReconstruction::InitRunLoader()
2092 {
2093 // get or create the run loader
2094
2095   if (gAlice) delete gAlice;
2096   gAlice = NULL;
2097
2098   if (!gSystem->AccessPathName(fGAliceFileName.Data())) { // galice.root exists
2099     // load all base libraries to get the loader classes
2100     TString libs = gSystem->GetLibraries();
2101     for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
2102       TString detName = fgkDetectorName[iDet];
2103       if (detName == "HLT") continue;
2104       if (libs.Contains("lib" + detName + "base.so")) continue;
2105       gSystem->Load("lib" + detName + "base.so");
2106     }
2107     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data());
2108     if (!fRunLoader) {
2109       AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
2110       CleanUp();
2111       return kFALSE;
2112     }
2113
2114     fRunLoader->CdGAFile();
2115     fRunLoader->LoadgAlice();
2116
2117     //PH This is a temporary fix to give access to the kinematics
2118     //PH that is needed for the labels of ITS clusters
2119     fRunLoader->LoadHeader();
2120     fRunLoader->LoadKinematics();
2121
2122   } else {               // galice.root does not exist
2123     if (!fRawReader) {
2124       AliError(Form("the file %s does not exist", fGAliceFileName.Data()));
2125       CleanUp();
2126       return kFALSE;
2127     }
2128     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data(),
2129                                     AliConfig::GetDefaultEventFolderName(),
2130                                     "recreate");
2131     if (!fRunLoader) {
2132       AliError(Form("could not create run loader in file %s", 
2133                     fGAliceFileName.Data()));
2134       CleanUp();
2135       return kFALSE;
2136     }
2137     fIsNewRunLoader = kTRUE;
2138     fRunLoader->MakeTree("E");
2139
2140     if (fNumberOfEventsPerFile > 0)
2141       fRunLoader->SetNumberOfEventsPerFile(fNumberOfEventsPerFile);
2142     else
2143       fRunLoader->SetNumberOfEventsPerFile((UInt_t)-1);
2144   }
2145
2146   return kTRUE;
2147 }
2148
2149 //_____________________________________________________________________________
2150 AliReconstructor* AliReconstruction::GetReconstructor(Int_t iDet)
2151 {
2152 // get the reconstructor object and the loader for a detector
2153
2154   if (fReconstructor[iDet]) return fReconstructor[iDet];
2155
2156   // load the reconstructor object
2157   TPluginManager* pluginManager = gROOT->GetPluginManager();
2158   TString detName = fgkDetectorName[iDet];
2159   TString recName = "Ali" + detName + "Reconstructor";
2160
2161   if (!fIsNewRunLoader && !fRunLoader->GetLoader(detName+"Loader") && (detName != "HLT")) return NULL;
2162
2163   AliReconstructor* reconstructor = NULL;
2164   // first check if a plugin is defined for the reconstructor
2165   TPluginHandler* pluginHandler = 
2166     pluginManager->FindHandler("AliReconstructor", detName);
2167   // if not, add a plugin for it
2168   if (!pluginHandler) {
2169     AliDebug(1, Form("defining plugin for %s", recName.Data()));
2170     TString libs = gSystem->GetLibraries();
2171     if (libs.Contains("lib" + detName + "base.so") ||
2172         (gSystem->Load("lib" + detName + "base.so") >= 0)) {
2173       pluginManager->AddHandler("AliReconstructor", detName, 
2174                                 recName, detName + "rec", recName + "()");
2175     } else {
2176       pluginManager->AddHandler("AliReconstructor", detName, 
2177                                 recName, detName, recName + "()");
2178     }
2179     pluginHandler = pluginManager->FindHandler("AliReconstructor", detName);
2180   }
2181   if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
2182     reconstructor = (AliReconstructor*) pluginHandler->ExecPlugin(0);
2183   }
2184   if (reconstructor) {
2185     TObject* obj = fOptions.FindObject(detName.Data());
2186     if (obj) reconstructor->SetOption(obj->GetTitle());
2187     reconstructor->Init();
2188     fReconstructor[iDet] = reconstructor;
2189   }
2190
2191   // get or create the loader
2192   if (detName != "HLT") {
2193     fLoader[iDet] = fRunLoader->GetLoader(detName + "Loader");
2194     if (!fLoader[iDet]) {
2195       AliConfig::Instance()
2196         ->CreateDetectorFolders(fRunLoader->GetEventFolder(), 
2197                                 detName, detName);
2198       // first check if a plugin is defined for the loader
2199       pluginHandler = 
2200         pluginManager->FindHandler("AliLoader", detName);
2201       // if not, add a plugin for it
2202       if (!pluginHandler) {
2203         TString loaderName = "Ali" + detName + "Loader";
2204         AliDebug(1, Form("defining plugin for %s", loaderName.Data()));
2205         pluginManager->AddHandler("AliLoader", detName, 
2206                                   loaderName, detName + "base", 
2207                                   loaderName + "(const char*, TFolder*)");
2208         pluginHandler = pluginManager->FindHandler("AliLoader", detName);
2209       }
2210       if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
2211         fLoader[iDet] = 
2212           (AliLoader*) pluginHandler->ExecPlugin(2, detName.Data(), 
2213                                                  fRunLoader->GetEventFolder());
2214       }
2215       if (!fLoader[iDet]) {   // use default loader
2216         fLoader[iDet] = new AliLoader(detName, fRunLoader->GetEventFolder());
2217       }
2218       if (!fLoader[iDet]) {
2219         AliWarning(Form("couldn't get loader for %s", detName.Data()));
2220         if (fStopOnError) return NULL;
2221       } else {
2222         fRunLoader->AddLoader(fLoader[iDet]);
2223         fRunLoader->CdGAFile();
2224         if (gFile && !gFile->IsWritable()) gFile->ReOpen("UPDATE");
2225         fRunLoader->Write(0, TObject::kOverwrite);
2226       }
2227     }
2228   }
2229       
2230   return reconstructor;
2231 }
2232
2233 //_____________________________________________________________________________
2234 Bool_t AliReconstruction::CreateVertexer()
2235 {
2236 // create the vertexer
2237
2238   fVertexer = NULL;
2239   AliReconstructor* itsReconstructor = GetReconstructor(0);
2240   if (itsReconstructor) {
2241     fVertexer = itsReconstructor->CreateVertexer();
2242   }
2243   if (!fVertexer) {
2244     AliWarning("couldn't create a vertexer for ITS");
2245     if (fStopOnError) return kFALSE;
2246   }
2247
2248   return kTRUE;
2249 }
2250
2251 //_____________________________________________________________________________
2252 Bool_t AliReconstruction::CreateTrackers(const TString& detectors)
2253 {
2254 // create the trackers
2255
2256   TString detStr = detectors;
2257   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
2258     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2259     AliReconstructor* reconstructor = GetReconstructor(iDet);
2260     if (!reconstructor) continue;
2261     TString detName = fgkDetectorName[iDet];
2262     if (detName == "HLT") {
2263       fRunHLTTracking = kTRUE;
2264       continue;
2265     }
2266     if (detName == "MUON") {
2267       fRunMuonTracking = kTRUE;
2268       continue;
2269     }
2270
2271
2272     fTracker[iDet] = reconstructor->CreateTracker();
2273     if (!fTracker[iDet] && (iDet < 7)) {
2274       AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
2275       if (fStopOnError) return kFALSE;
2276     }
2277     AliSysInfo::AddStamp(Form("LTracker%s",fgkDetectorName[iDet]), iDet,0);
2278   }
2279
2280   return kTRUE;
2281 }
2282
2283 //_____________________________________________________________________________
2284 void AliReconstruction::CleanUp(TFile* file, TFile* fileOld)
2285 {
2286 // delete trackers and the run loader and close and delete the file
2287
2288   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
2289     delete fReconstructor[iDet];
2290     fReconstructor[iDet] = NULL;
2291     fLoader[iDet] = NULL;
2292     delete fTracker[iDet];
2293     fTracker[iDet] = NULL;
2294 //    delete fQADataMaker[iDet];
2295 //    fQADataMaker[iDet] = NULL;
2296   }
2297   delete fVertexer;
2298   fVertexer = NULL;
2299
2300   if (ftVertexer) delete ftVertexer;
2301   ftVertexer = NULL;
2302   
2303   if(!(AliCDBManager::Instance()->GetCacheFlag())) {
2304         delete fDiamondProfile;
2305         fDiamondProfile = NULL;
2306         delete fDiamondProfileTPC;
2307         fDiamondProfileTPC = NULL;
2308         delete fGRPData;
2309         fGRPData = NULL;
2310   }
2311
2312
2313   delete fRunLoader;
2314   fRunLoader = NULL;
2315   delete fRawReader;
2316   fRawReader = NULL;
2317   if (fParentRawReader) delete fParentRawReader;
2318   fParentRawReader=NULL;
2319
2320   if (file) {
2321     file->Close();
2322     delete file;
2323   }
2324
2325   if (fileOld) {
2326     fileOld->Close();
2327     delete fileOld;
2328     gSystem->Unlink("AliESDs.old.root");
2329   }
2330
2331 }
2332
2333 //_____________________________________________________________________________
2334
2335 Bool_t AliReconstruction::ReadESD(AliESDEvent*& esd, const char* recStep) const
2336 {
2337 // read the ESD event from a file
2338
2339   if (!esd) return kFALSE;
2340   char fileName[256];
2341   sprintf(fileName, "ESD_%d.%d_%s.root", 
2342           esd->GetRunNumber(), esd->GetEventNumberInFile(), recStep);
2343   if (gSystem->AccessPathName(fileName)) return kFALSE;
2344
2345   AliInfo(Form("reading ESD from file %s", fileName));
2346   AliDebug(1, Form("reading ESD from file %s", fileName));
2347   TFile* file = TFile::Open(fileName);
2348   if (!file || !file->IsOpen()) {
2349     AliError(Form("opening %s failed", fileName));
2350     delete file;
2351     return kFALSE;
2352   }
2353
2354   gROOT->cd();
2355   delete esd;
2356   esd = (AliESDEvent*) file->Get("ESD");
2357   file->Close();
2358   delete file;
2359   return kTRUE;
2360
2361 }
2362
2363
2364
2365 //_____________________________________________________________________________
2366 void AliReconstruction::WriteESD(AliESDEvent* esd, const char* recStep) const
2367 {
2368 // write the ESD event to a file
2369
2370   if (!esd) return;
2371   char fileName[256];
2372   sprintf(fileName, "ESD_%d.%d_%s.root", 
2373           esd->GetRunNumber(), esd->GetEventNumberInFile(), recStep);
2374
2375   AliDebug(1, Form("writing ESD to file %s", fileName));
2376   TFile* file = TFile::Open(fileName, "recreate");
2377   if (!file || !file->IsOpen()) {
2378     AliError(Form("opening %s failed", fileName));
2379   } else {
2380     esd->Write("ESD");
2381     file->Close();
2382   }
2383   delete file;
2384 }
2385
2386
2387 void AliReconstruction::WriteAlignmentData(AliESDEvent* esd)
2388 {
2389   // Write space-points which are then used in the alignment procedures
2390   // For the moment only ITS, TRD and TPC
2391
2392   // Load TOF clusters
2393   if (fTracker[3]){
2394     fLoader[3]->LoadRecPoints("read");
2395     TTree* tree = fLoader[3]->TreeR();
2396     if (!tree) {
2397       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[3]));
2398       return;
2399     }
2400     fTracker[3]->LoadClusters(tree);
2401   }
2402   Int_t ntracks = esd->GetNumberOfTracks();
2403   for (Int_t itrack = 0; itrack < ntracks; itrack++)
2404     {
2405       AliESDtrack *track = esd->GetTrack(itrack);
2406       Int_t nsp = 0;
2407       Int_t idx[200];
2408       for (Int_t iDet = 3; iDet >= 0; iDet--)
2409         nsp += track->GetNcls(iDet);
2410       if (nsp) {
2411         AliTrackPointArray *sp = new AliTrackPointArray(nsp);
2412         track->SetTrackPointArray(sp);
2413         Int_t isptrack = 0;
2414         for (Int_t iDet = 3; iDet >= 0; iDet--) {
2415           AliTracker *tracker = fTracker[iDet];
2416           if (!tracker) continue;
2417           Int_t nspdet = track->GetNcls(iDet);
2418           if (nspdet <= 0) continue;
2419           track->GetClusters(iDet,idx);
2420           AliTrackPoint p;
2421           Int_t isp = 0;
2422           Int_t isp2 = 0;
2423           while (isp2 < nspdet) {
2424             Bool_t isvalid;
2425             TString dets = fgkDetectorName[iDet];
2426             if ((fUseTrackingErrorsForAlignment.CompareTo(dets) == 0) ||
2427             fUseTrackingErrorsForAlignment.BeginsWith(dets+" ") ||
2428             fUseTrackingErrorsForAlignment.EndsWith(" "+dets) ||
2429             fUseTrackingErrorsForAlignment.Contains(" "+dets+" ")) {
2430               isvalid = tracker->GetTrackPointTrackingError(idx[isp2],p,track);
2431             } else {
2432               isvalid = tracker->GetTrackPoint(idx[isp2],p); 
2433             } 
2434             isp2++;
2435             const Int_t kNTPCmax = 159;
2436             if (iDet==1 && isp2>kNTPCmax) break;   // to be fixed
2437             if (!isvalid) continue;
2438             sp->AddPoint(isptrack,&p); isptrack++; isp++;
2439           }
2440         }       
2441       }
2442     }
2443   if (fTracker[3]){
2444     fTracker[3]->UnloadClusters();
2445     fLoader[3]->UnloadRecPoints();
2446   }
2447 }
2448
2449 //_____________________________________________________________________________
2450 void AliReconstruction::FillRawDataErrorLog(Int_t iEvent, AliESDEvent* esd)
2451 {
2452   // The method reads the raw-data error log
2453   // accumulated within the rawReader.
2454   // It extracts the raw-data errors related to
2455   // the current event and stores them into
2456   // a TClonesArray inside the esd object.
2457
2458   if (!fRawReader) return;
2459
2460   for(Int_t i = 0; i < fRawReader->GetNumberOfErrorLogs(); i++) {
2461
2462     AliRawDataErrorLog *log = fRawReader->GetErrorLog(i);
2463     if (!log) continue;
2464     if (iEvent != log->GetEventNumber()) continue;
2465
2466     esd->AddRawDataErrorLog(log);
2467   }
2468
2469 }
2470
2471 TNamed* AliReconstruction::CopyFileToTNamed(TString fPath,TString pName){
2472   // Dump a file content into a char in TNamed
2473   ifstream in;
2474   in.open(fPath.Data(),ios::in | ios::binary|ios::ate);
2475   Int_t kBytes = (Int_t)in.tellg();
2476   printf("Size: %d \n",kBytes);
2477   TNamed *fn = 0;
2478   if(in.good()){
2479     char* memblock = new char [kBytes];
2480     in.seekg (0, ios::beg);
2481     in.read (memblock, kBytes);
2482     in.close();
2483     TString fData(memblock,kBytes);
2484     fn = new TNamed(pName,fData);
2485     printf("fData Size: %d \n",fData.Sizeof());
2486     printf("pName Size: %d \n",pName.Sizeof());
2487     printf("fn    Size: %d \n",fn->Sizeof());
2488     delete[] memblock;
2489   }
2490   else{
2491     AliInfo(Form("Could not Open %s\n",fPath.Data()));
2492   }
2493
2494   return fn;
2495 }
2496
2497 void AliReconstruction::TNamedToFile(TTree* fTree, TString pName){
2498   // This is not really needed in AliReconstruction at the moment
2499   // but can serve as a template
2500
2501   TList *fList = fTree->GetUserInfo();
2502   TNamed *fn = (TNamed*)fList->FindObject(pName.Data());
2503   printf("fn Size: %d \n",fn->Sizeof());
2504
2505   TString fTmp(fn->GetName()); // to be 100% sure in principle pName also works
2506   const char* cdata = fn->GetTitle();
2507   printf("fTmp Size %d\n",fTmp.Sizeof());
2508
2509   int size = fn->Sizeof()-fTmp.Sizeof()-sizeof(UChar_t)-sizeof(Int_t); // see dfinition of TString::SizeOf()...
2510   printf("calculated size %d\n",size);
2511   ofstream out(pName.Data(),ios::out | ios::binary);
2512   out.write(cdata,size);
2513   out.close();
2514
2515 }
2516   
2517 //_____________________________________________________________________________
2518 AliQADataMakerRec * AliReconstruction::GetQADataMaker(Int_t iDet)
2519 {
2520  // get the quality assurance data maker object and the loader for a detector
2521
2522   if (fQADataMaker[iDet]) 
2523     return fQADataMaker[iDet];
2524
2525   AliQADataMakerRec * qadm = NULL;
2526   if (iDet == fgkNDetectors) { //Global QA
2527      qadm = new AliGlobalQADataMaker();
2528      fQADataMaker[iDet] = qadm;
2529      return qadm;
2530   }
2531
2532   // load the QA data maker object
2533   TPluginManager* pluginManager = gROOT->GetPluginManager();
2534   TString detName = fgkDetectorName[iDet];
2535   TString qadmName = "Ali" + detName + "QADataMakerRec";
2536   if (!fIsNewRunLoader && !fRunLoader->GetLoader(detName+"Loader") && (detName != "HLT")) 
2537     return NULL;
2538
2539   // first check if a plugin is defined for the quality assurance data maker
2540   TPluginHandler* pluginHandler = pluginManager->FindHandler("AliQADataMakerRec", detName);
2541   // if not, add a plugin for it
2542   if (!pluginHandler) {
2543     AliDebug(1, Form("defining plugin for %s", qadmName.Data()));
2544     TString libs = gSystem->GetLibraries();
2545     if (libs.Contains("lib" + detName + "base.so") ||
2546         (gSystem->Load("lib" + detName + "base.so") >= 0)) {
2547       pluginManager->AddHandler("AliQADataMakerRec", detName, 
2548                                 qadmName, detName + "qadm", qadmName + "()");
2549     } else {
2550       pluginManager->AddHandler("AliQADataMakerRec", detName, 
2551                                 qadmName, detName, qadmName + "()");
2552     }
2553     pluginHandler = pluginManager->FindHandler("AliQADataMakerRec", detName);
2554   }
2555   if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
2556     qadm = (AliQADataMakerRec *) pluginHandler->ExecPlugin(0);
2557   }
2558
2559   fQADataMaker[iDet] = qadm;
2560
2561   return qadm;
2562 }
2563
2564 //_____________________________________________________________________________
2565 Bool_t AliReconstruction::RunQA(AliESDEvent *& esd)
2566 {
2567   // run the Quality Assurance data producer
2568
2569   AliCodeTimerAuto("")
2570   TString detStr = fQADetectors ;
2571   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
2572    if (!IsSelected(fgkDetectorName[iDet], detStr)) 
2573      continue;
2574    AliQADataMakerRec * qadm = GetQADataMaker(iDet);
2575    if (!qadm) 
2576      continue;
2577    AliCodeTimerStart(Form("running quality assurance data maker for %s", fgkDetectorName[iDet]));
2578    AliInfo(Form("running quality assurance data maker for %s", fgkDetectorName[iDet]));
2579     
2580    if (fQATasks.Contains(Form("%d", AliQA::kESDS))) {
2581            qadm->Exec(AliQA::kESDS, esd) ; 
2582            qadm->Increment() ; 
2583    }
2584    AliCodeTimerStop(Form("running quality assurance data maker for %s", fgkDetectorName[iDet]));
2585  }
2586  if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2587    AliError(Form("the following detectors were not found: %s",
2588                  detStr.Data()));
2589    if (fStopOnError) 
2590      return kFALSE;
2591  }
2592  
2593  return kTRUE;
2594   
2595 }
2596
2597 //_____________________________________________________________________________
2598 void AliReconstruction::CheckQA()
2599 {
2600 // check the QA of SIM for this run and remove the detectors 
2601 // with status Fatal
2602   
2603         TString newRunLocalReconstruction ; 
2604         TString newRunTracking ;
2605         TString newFillESD ;
2606          
2607         for (Int_t iDet = 0; iDet < AliQA::kNDET; iDet++) {
2608                 TString detName(AliQA::GetDetName(iDet)) ;
2609                 AliQA * qa = AliQA::Instance(AliQA::DETECTORINDEX_t(iDet)) ; 
2610                 if ( qa->IsSet(AliQA::DETECTORINDEX_t(iDet), AliQA::kSIM, AliQA::kFATAL)) {
2611                                 AliInfo(Form("QA status for %s in Hits and/or SDIGITS  and/or Digits was Fatal; No reconstruction performed", detName.Data())) ;
2612                 } else {
2613                         if ( fRunLocalReconstruction.Contains(AliQA::GetDetName(iDet)) || 
2614                                         fRunLocalReconstruction.Contains("ALL") )  {
2615                                 newRunLocalReconstruction += detName ; 
2616                                 newRunLocalReconstruction += " " ;                      
2617                         }
2618                         if ( fRunTracking.Contains(AliQA::GetDetName(iDet)) || 
2619                                         fRunTracking.Contains("ALL") )  {
2620                                 newRunTracking += detName ; 
2621                                 newRunTracking += " " ;                         
2622                         }
2623                         if ( fFillESD.Contains(AliQA::GetDetName(iDet)) || 
2624                                         fFillESD.Contains("ALL") )  {
2625                                 newFillESD += detName ; 
2626                                 newFillESD += " " ;                     
2627                         }
2628                 }
2629         }
2630         fRunLocalReconstruction = newRunLocalReconstruction ; 
2631         fRunTracking            = newRunTracking ; 
2632         fFillESD                = newFillESD ; 
2633 }
2634
2635 //_____________________________________________________________________________
2636 Int_t AliReconstruction::GetDetIndex(const char* detector)
2637 {
2638   // return the detector index corresponding to detector
2639   Int_t index = -1 ; 
2640   for (index = 0; index < fgkNDetectors ; index++) {
2641     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
2642         break ; 
2643   }     
2644   return index ; 
2645 }
2646 //_____________________________________________________________________________
2647 Bool_t AliReconstruction::FinishPlaneEff() {
2648  //
2649  // Here execute all the necessary operationis, at the end of the tracking phase,
2650  // in case that evaluation of PlaneEfficiencies was required for some detector. 
2651  // E.g., write into a DataBase file the PlaneEfficiency which have been evaluated. 
2652  //
2653  // This Preliminary version works only FOR ITS !!!!!
2654  // other detectors (TOF,TRD, etc. have to develop their specific codes)
2655  //
2656  //  Input: none
2657  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise 
2658  //
2659  Bool_t ret=kFALSE;
2660  //for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
2661  for (Int_t iDet = 0; iDet < 1; iDet++) { // for the time being only ITS  
2662    //if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2663    if(fTracker[iDet]) {
2664       AliPlaneEff *planeeff=fTracker[iDet]->GetPlaneEff(); 
2665       ret=planeeff->WriteIntoCDB();
2666       if(planeeff->GetCreateHistos()) {
2667         TString name="PlaneEffHisto";
2668         name+=fgkDetectorName[iDet];
2669         name+=".root";
2670         ret*=planeeff->WriteHistosToFile(name,"RECREATE");
2671       }
2672    }
2673  }
2674  return ret;
2675 }
2676 //_____________________________________________________________________________
2677 Bool_t AliReconstruction::InitPlaneEff() {
2678 //
2679  // Here execute all the necessary operations, before of the tracking phase,
2680  // for the evaluation of PlaneEfficiencies, in case required for some detectors.
2681  // E.g., read from a DataBase file a first evaluation of the PlaneEfficiency 
2682  // which should be updated/recalculated.
2683  //
2684  // This Preliminary version will work only FOR ITS !!!!!
2685  // other detectors (TOF,TRD, etc. have to develop their specific codes)
2686  //
2687  //  Input: none
2688  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
2689  //
2690  AliWarning(Form("Implementation of this method not yet done !! Method return kTRUE"));
2691  return kTRUE;
2692 }
2693
2694 //_____________________________________________________________________________
2695 Bool_t AliReconstruction::InitAliEVE()
2696 {
2697   // This method should be called only in case 
2698   // AliReconstruction is run
2699   // within the alieve environment.
2700   // It will initialize AliEVE in a way
2701   // so that it can visualize event processed
2702   // by AliReconstruction.
2703   // The return flag shows whenever the
2704   // AliEVE initialization was successful or not.
2705
2706   TString macroStr;
2707   macroStr.Form("%s/EVE/macros/alieve_online.C",gSystem->ExpandPathName("$ALICE_ROOT"));
2708   AliInfo(Form("Loading AliEVE macro: %s",macroStr.Data()));
2709   if (gROOT->LoadMacro(macroStr.Data()) != 0) return kFALSE;
2710
2711   gROOT->ProcessLine("if (!gAliEveEvent) {gAliEveEvent = new AliEveEventManager();gAliEveEvent->SetAutoLoad(kTRUE);gAliEveEvent->AddNewEventCommand(\"alieve_online_on_new_event()\");gEve->AddEvent(gAliEveEvent);};");
2712   gROOT->ProcessLine("alieve_online_init()");
2713
2714   return kTRUE;
2715 }
2716   
2717 //_____________________________________________________________________________
2718 void AliReconstruction::RunAliEVE()
2719 {
2720   // Runs AliEVE visualisation of
2721   // the current event.
2722   // Should be executed only after
2723   // successful initialization of AliEVE.
2724
2725   AliInfo("Running AliEVE...");
2726   gROOT->ProcessLine(Form("gAliEveEvent->SetEvent((AliRunLoader*)%p,(AliRawReader*)%p,(AliESDEvent*)%p);",fRunLoader,fRawReader,fesd));
2727   gROOT->ProcessLine("gAliEveEvent->StartStopAutoLoadTimer();");
2728   gSystem->Run();
2729 }
2730
2731 //_____________________________________________________________________________
2732 Bool_t AliReconstruction::SetRunQA(TString detAndAction) 
2733 {
2734         // Allows to run QA for a selected set of detectors
2735         // and a selected set of tasks among RAWS, RECPOINTS and ESDS
2736         // all selected detectors run the same selected tasks
2737         
2738         if (!detAndAction.Contains(":")) {
2739                 AliError( Form("%s is a wrong syntax, use \"DetectorList:ActionList\" \n", detAndAction.Data()) ) ;
2740                 fRunQA = kFALSE ;
2741                 return kFALSE ;                 
2742         }
2743         Int_t colon = detAndAction.Index(":") ; 
2744         fQADetectors = detAndAction(0, colon) ; 
2745         if (fQADetectors.Contains("ALL") )
2746                 fQADetectors = fFillESD ; 
2747         fQATasks   = detAndAction(colon+1, detAndAction.Sizeof() ) ; 
2748         if (fQATasks.Contains("ALL") ) {
2749                 fQATasks = Form("%d %d %d", AliQA::kRAWS, AliQA::kRECPOINTS, AliQA::kESDS) ; 
2750         } else {
2751                 fQATasks.ToUpper() ; 
2752                 TString tempo("") ; 
2753                 if ( fQATasks.Contains("RAW") ) 
2754                         tempo = Form("%d ", AliQA::kRAWS) ; 
2755                 if ( fQATasks.Contains("RECPOINT") ) 
2756                         tempo += Form("%d ", AliQA::kRECPOINTS) ; 
2757                 if ( fQATasks.Contains("ESD") ) 
2758                         tempo += Form("%d ", AliQA::kESDS) ; 
2759                 fQATasks = tempo ; 
2760                 if (fQATasks.IsNull()) {
2761                         AliInfo("No QA requested\n")  ;
2762                         fRunQA = kFALSE ;
2763                         return kTRUE ; 
2764                 }
2765         }       
2766         TString tempo(fQATasks) ; 
2767     tempo.ReplaceAll(Form("%d", AliQA::kRAWS), AliQA::GetTaskName(AliQA::kRAWS))        ;
2768     tempo.ReplaceAll(Form("%d", AliQA::kRECPOINTS), AliQA::GetTaskName(AliQA::kRECPOINTS)) ;    
2769     tempo.ReplaceAll(Form("%d", AliQA::kESDS), AliQA::GetTaskName(AliQA::kESDS)) ;      
2770         AliInfo( Form("QA will be done on \"%s\" for \"%s\"\n", fQADetectors.Data(), tempo.Data()) ) ;  
2771         fRunQA = kTRUE ;
2772         return kTRUE; 
2773
2774
2775