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