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