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