]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliReconstruction.cxx
ooooooooooops
[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         AliCDBId* id=0;
1471         while((id = dynamic_cast<AliCDBId*> (iter2.Next()))){    
1472          cdbListCopy->Add(new TObjString(id->ToString().Data()));        
1473    }     
1474          
1475    ftree->GetUserInfo()->Add(cdbMapCopy);        
1476    ftree->GetUserInfo()->Add(cdbListCopy);
1477
1478
1479   if(fESDPar.Contains("ESD.par")){
1480     AliInfo("Attaching ESD.par to Tree");
1481     TNamed *fn = CopyFileToTNamed(fESDPar.Data(),"ESD.par");
1482     ftree->GetUserInfo()->Add(fn);
1483   }
1484
1485
1486   ffile->cd();
1487
1488   if (fWriteESDfriend)
1489     ftree->SetBranchStatus("ESDfriend*",0);
1490   // we want to have only one tree version number
1491   ftree->Write(ftree->GetName(),TObject::kOverwrite);
1492   fhlttree->Write();
1493
1494 // Finish with Plane Efficiency evaluation: before of CleanUp !!!
1495   if (fRunPlaneEff && !FinishPlaneEff()) {
1496    AliWarning("Finish PlaneEff evaluation failed");
1497   }
1498
1499   gROOT->cd();
1500   CleanUp(ffile, ffileOld);
1501     
1502   if (fWriteAOD) {
1503     AliWarning("AOD creation not supported anymore during reconstruction. See ANALYSIS/AliAnalysisTaskESDfilter.cxx instead.");
1504   }
1505
1506   // Create tags for the events in the ESD tree (the ESD tree is always present)
1507   // In case of empty events the tags will contain dummy values
1508   AliESDTagCreator *esdtagCreator = new AliESDTagCreator();
1509   esdtagCreator->CreateESDTags(fFirstEvent,fLastEvent,fGRPData);
1510   if (fWriteAOD) {
1511     AliWarning("AOD tag creation not supported anymore during reconstruction.");
1512   }
1513
1514   //Finish QA and end of cycle for out-of-loop QA
1515   if (!fInLoopQA && fRunQA) 
1516                 fQASteer->Run(fRunLocalReconstruction.Data(), AliQA::kNULLTASKINDEX, fSameQACycle) ; 
1517         if (!fInLoopQA && fRunGlobalQA) {
1518                 AliQADataMaker *qadm = fQASteer->GetQADataMaker(AliQA::kGLOBAL);
1519                         if (qadm) {
1520                                 if (fQATasks.Contains(Form("%d", AliQA::kRECPOINTS))) 
1521                                         qadm->EndOfCycle(AliQA::kRECPOINTS);
1522                                 if (fQATasks.Contains(Form("%d", AliQA::kESDS))) 
1523                                         qadm->EndOfCycle(AliQA::kESDS);
1524                                 qadm->Finish();
1525                         }
1526                 }
1527
1528   // Cleanup of CDB manager: cache and active storages!
1529   AliCDBManager::Instance()->ClearCache();
1530   
1531   return kTRUE;
1532 }
1533
1534
1535 //_____________________________________________________________________________
1536 Bool_t AliReconstruction::RunLocalReconstruction(const TString& /*detectors*/)
1537 {
1538 // run the local reconstruction
1539   static Int_t eventNr=0;
1540   AliCodeTimerAuto("")
1541
1542  //  AliCDBManager* man = AliCDBManager::Instance();
1543 //   Bool_t origCache = man->GetCacheFlag();
1544
1545 //   TString detStr = detectors;
1546 //   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1547 //     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1548 //     AliReconstructor* reconstructor = GetReconstructor(iDet);
1549 //     if (!reconstructor) continue;
1550 //     if (reconstructor->HasLocalReconstruction()) continue;
1551
1552 //     AliCodeTimerStart(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1553 //     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1554     
1555 //     AliCodeTimerStart(Form("Loading calibration data from OCDB for %s", fgkDetectorName[iDet]));                          
1556 //     AliInfo(Form("Loading calibration data from OCDB for %s", fgkDetectorName[iDet]));
1557
1558 //     man->SetCacheFlag(kTRUE);
1559 //     TString calibPath = Form("%s/Calib/*", fgkDetectorName[iDet]);
1560 //     man->GetAll(calibPath); // entries are cached!
1561
1562 //     AliCodeTimerStop(Form("Loading calibration data from OCDB for %s", fgkDetectorName[iDet]));
1563      
1564 //     if (fRawReader) {
1565 //       fRawReader->RewindEvents();
1566 //       reconstructor->Reconstruct(fRunLoader, fRawReader);
1567 //     } else {
1568 //       reconstructor->Reconstruct(fRunLoader);
1569 //     }
1570      
1571 //      AliCodeTimerStop(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1572     // AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr));
1573
1574 //     // unload calibration data
1575 //     man->UnloadFromCache(calibPath);
1576 //     //man->ClearCache();
1577 //   }
1578
1579 //   man->SetCacheFlag(origCache);
1580
1581 //   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1582 //     AliError(Form("the following detectors were not found: %s",
1583 //                   detStr.Data()));
1584 //     if (fStopOnError) return kFALSE;
1585 //   }
1586
1587           eventNr++;
1588   return kTRUE;
1589 }
1590
1591 //_____________________________________________________________________________
1592 Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
1593 {
1594 // run the local reconstruction
1595
1596   static Int_t eventNr=0;
1597   AliCodeTimerAuto("")
1598
1599   TString detStr = detectors;
1600   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1601     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1602     AliReconstructor* reconstructor = GetReconstructor(iDet);
1603     if (!reconstructor) continue;
1604     AliLoader* loader = fLoader[iDet];
1605     // Matthias April 2008: temporary fix to run HLT reconstruction
1606     // although the HLT loader is missing
1607     if (strcmp(fgkDetectorName[iDet], "HLT")==0) {
1608       if (fRawReader) {
1609         reconstructor->Reconstruct(fRawReader, NULL);
1610       } else {
1611         TTree* dummy=NULL;
1612         reconstructor->Reconstruct(dummy, NULL);
1613       }
1614       continue;
1615     }
1616     if (!loader) {
1617       AliWarning(Form("No loader is defined for %s!",fgkDetectorName[iDet]));
1618       continue;
1619     }
1620     // conversion of digits
1621     if (fRawReader && reconstructor->HasDigitConversion()) {
1622       AliInfo(Form("converting raw data digits into root objects for %s", 
1623                    fgkDetectorName[iDet]));
1624 //      AliCodeTimerAuto(Form("converting raw data digits into root objects for %s", 
1625 //                            fgkDetectorName[iDet]));
1626       loader->LoadDigits("update");
1627       loader->CleanDigits();
1628       loader->MakeDigitsContainer();
1629       TTree* digitsTree = loader->TreeD();
1630       reconstructor->ConvertDigits(fRawReader, digitsTree);
1631       loader->WriteDigits("OVERWRITE");
1632       loader->UnloadDigits();
1633     }
1634     // local reconstruction
1635     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1636     //AliCodeTimerAuto(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1637     loader->LoadRecPoints("update");
1638     loader->CleanRecPoints();
1639     loader->MakeRecPointsContainer();
1640     TTree* clustersTree = loader->TreeR();
1641     if (fRawReader && !reconstructor->HasDigitConversion()) {
1642       reconstructor->Reconstruct(fRawReader, clustersTree);
1643     } else {
1644       loader->LoadDigits("read");
1645       TTree* digitsTree = loader->TreeD();
1646       if (!digitsTree) {
1647         AliError(Form("Can't get the %s digits tree", fgkDetectorName[iDet]));
1648         if (fStopOnError) return kFALSE;
1649       } else {
1650         reconstructor->Reconstruct(digitsTree, clustersTree);
1651       }
1652       loader->UnloadDigits();
1653     }
1654
1655     // In-loop QA for local reconstrucion 
1656                 TString detQAStr(fQADetectors) ; 
1657                 if (fRunQA && fInLoopQA) 
1658                         fQASteer->RunOneEventInOneDetector(iDet, clustersTree) ; 
1659     
1660         loader->WriteRecPoints("OVERWRITE");
1661         loader->UnloadRecPoints();
1662         AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr), iDet,1,eventNr);
1663         }
1664         if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1665     AliError(Form("the following detectors were not found: %s",
1666                   detStr.Data()));
1667     if (fStopOnError) return kFALSE;
1668   }
1669   eventNr++;
1670   return kTRUE;
1671 }
1672
1673 //_____________________________________________________________________________
1674 Bool_t AliReconstruction::RunVertexFinder(AliESDEvent*& esd)
1675 {
1676 // run the barrel tracking
1677
1678   AliCodeTimerAuto("")
1679
1680   AliESDVertex* vertex = NULL;
1681   Double_t vtxPos[3] = {0, 0, 0};
1682   Double_t vtxErr[3] = {0.07, 0.07, 0.1};
1683   TArrayF mcVertex(3); 
1684   if (fRunLoader->GetHeader() && fRunLoader->GetHeader()->GenEventHeader()) {
1685     fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(mcVertex);
1686     for (Int_t i = 0; i < 3; i++) vtxPos[i] = mcVertex[i];
1687   }
1688
1689   if (fVertexer) {
1690     AliInfo("running the ITS vertex finder");
1691     if (fLoader[0]) {
1692       fLoader[0]->LoadRecPoints();
1693       TTree* cltree = fLoader[0]->TreeR();
1694       if (cltree) {
1695         if(fDiamondProfile) fVertexer->SetVtxStart(fDiamondProfile);
1696         vertex = fVertexer->FindVertexForCurrentEvent(cltree);
1697       }
1698       else {
1699         AliError("Can't get the ITS cluster tree");
1700       }
1701       fLoader[0]->UnloadRecPoints();
1702     }
1703     else {
1704       AliError("Can't get the ITS loader");
1705     }
1706     if(!vertex){
1707       AliWarning("Vertex not found");
1708       vertex = new AliESDVertex();
1709       vertex->SetName("default");
1710     }
1711     else {
1712       vertex->SetName("reconstructed");
1713     }
1714
1715   } else {
1716     AliInfo("getting the primary vertex from MC");
1717     vertex = new AliESDVertex(vtxPos, vtxErr);
1718   }
1719
1720   if (vertex) {
1721     vertex->GetXYZ(vtxPos);
1722     vertex->GetSigmaXYZ(vtxErr);
1723   } else {
1724     AliWarning("no vertex reconstructed");
1725     vertex = new AliESDVertex(vtxPos, vtxErr);
1726   }
1727   esd->SetPrimaryVertexSPD(vertex);
1728   // if SPD multiplicity has been determined, it is stored in the ESD
1729   AliMultiplicity *mult = fVertexer->GetMultiplicity();
1730   if(mult)esd->SetMultiplicity(mult);
1731
1732   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1733     if (fTracker[iDet]) fTracker[iDet]->SetVertex(vtxPos, vtxErr);
1734   }  
1735   delete vertex;
1736
1737   return kTRUE;
1738 }
1739
1740 //_____________________________________________________________________________
1741 Bool_t AliReconstruction::RunHLTTracking(AliESDEvent*& esd)
1742 {
1743 // run the HLT barrel tracking
1744
1745   AliCodeTimerAuto("")
1746
1747   if (!fRunLoader) {
1748     AliError("Missing runLoader!");
1749     return kFALSE;
1750   }
1751
1752   AliInfo("running HLT tracking");
1753
1754   // Get a pointer to the HLT reconstructor
1755   AliReconstructor *reconstructor = GetReconstructor(fgkNDetectors-1);
1756   if (!reconstructor) return kFALSE;
1757
1758   // TPC + ITS
1759   for (Int_t iDet = 1; iDet >= 0; iDet--) {
1760     TString detName = fgkDetectorName[iDet];
1761     AliDebug(1, Form("%s HLT tracking", detName.Data()));
1762     reconstructor->SetOption(detName.Data());
1763     AliTracker *tracker = reconstructor->CreateTracker();
1764     if (!tracker) {
1765       AliWarning(Form("couldn't create a HLT tracker for %s", detName.Data()));
1766       if (fStopOnError) return kFALSE;
1767       continue;
1768     }
1769     Double_t vtxPos[3];
1770     Double_t vtxErr[3]={0.005,0.005,0.010};
1771     const AliESDVertex *vertex = esd->GetVertex();
1772     vertex->GetXYZ(vtxPos);
1773     tracker->SetVertex(vtxPos,vtxErr);
1774     if(iDet != 1) {
1775       fLoader[iDet]->LoadRecPoints("read");
1776       TTree* tree = fLoader[iDet]->TreeR();
1777       if (!tree) {
1778         AliError(Form("Can't get the %s cluster tree", detName.Data()));
1779         return kFALSE;
1780       }
1781       tracker->LoadClusters(tree);
1782     }
1783     if (tracker->Clusters2Tracks(esd) != 0) {
1784       AliError(Form("HLT %s Clusters2Tracks failed", fgkDetectorName[iDet]));
1785       return kFALSE;
1786     }
1787     if(iDet != 1) {
1788       tracker->UnloadClusters();
1789     }
1790     delete tracker;
1791   }
1792
1793   return kTRUE;
1794 }
1795
1796 //_____________________________________________________________________________
1797 Bool_t AliReconstruction::RunMuonTracking(AliESDEvent*& esd)
1798 {
1799 // run the muon spectrometer tracking
1800
1801   AliCodeTimerAuto("")
1802
1803   if (!fRunLoader) {
1804     AliError("Missing runLoader!");
1805     return kFALSE;
1806   }
1807   Int_t iDet = 7; // for MUON
1808
1809   AliInfo("is running...");
1810
1811   // Get a pointer to the MUON reconstructor
1812   AliReconstructor *reconstructor = GetReconstructor(iDet);
1813   if (!reconstructor) return kFALSE;
1814
1815   
1816   TString detName = fgkDetectorName[iDet];
1817   AliDebug(1, Form("%s tracking", detName.Data()));
1818   AliTracker *tracker =  reconstructor->CreateTracker();
1819   if (!tracker) {
1820     AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
1821     return kFALSE;
1822   }
1823      
1824   // read RecPoints
1825   fLoader[iDet]->LoadRecPoints("read");  
1826
1827   tracker->LoadClusters(fLoader[iDet]->TreeR());
1828   
1829   Int_t rv = tracker->Clusters2Tracks(esd);
1830   
1831   if ( rv )
1832   {
1833     AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
1834     return kFALSE;
1835   }
1836   
1837   fLoader[iDet]->UnloadRecPoints();
1838
1839   tracker->UnloadClusters();
1840   
1841   delete tracker;
1842   
1843   return kTRUE;
1844 }
1845
1846
1847 //_____________________________________________________________________________
1848 Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd)
1849 {
1850 // run the barrel tracking
1851   static Int_t eventNr=0;
1852   AliCodeTimerAuto("")
1853
1854   AliInfo("running tracking");
1855
1856   //Fill the ESD with the T0 info (will be used by the TOF) 
1857   if (fReconstructor[11] && fLoader[11]) {
1858     fLoader[11]->LoadRecPoints("READ");
1859     TTree *treeR = fLoader[11]->TreeR();
1860     GetReconstructor(11)->FillESD((TTree *)NULL,treeR,esd);
1861   }
1862
1863   // pass 1: TPC + ITS inwards
1864   for (Int_t iDet = 1; iDet >= 0; iDet--) {
1865     if (!fTracker[iDet]) continue;
1866     AliDebug(1, Form("%s tracking", fgkDetectorName[iDet]));
1867
1868     // load clusters
1869     fLoader[iDet]->LoadRecPoints("read");
1870     AliSysInfo::AddStamp(Form("RLoadCluster%s_%d",fgkDetectorName[iDet],eventNr),iDet,1, eventNr);
1871     TTree* tree = fLoader[iDet]->TreeR();
1872     if (!tree) {
1873       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
1874       return kFALSE;
1875     }
1876     fTracker[iDet]->LoadClusters(tree);
1877     AliSysInfo::AddStamp(Form("TLoadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
1878     // run tracking
1879     if (fTracker[iDet]->Clusters2Tracks(esd) != 0) {
1880       AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
1881       return kFALSE;
1882     }
1883     if (fCheckPointLevel > 1) {
1884       WriteESD(esd, Form("%s.tracking", fgkDetectorName[iDet]));
1885     }
1886     // preliminary PID in TPC needed by the ITS tracker
1887     if (iDet == 1) {
1888       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
1889       AliESDpid::MakePID(esd);
1890     } 
1891     AliSysInfo::AddStamp(Form("Tracking0%s_%d",fgkDetectorName[iDet],eventNr), iDet,3,eventNr);
1892   }
1893
1894   // pass 2: ALL backwards
1895
1896   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1897     if (!fTracker[iDet]) continue;
1898     AliDebug(1, Form("%s back propagation", fgkDetectorName[iDet]));
1899
1900     // load clusters
1901     if (iDet > 1) {     // all except ITS, TPC
1902       TTree* tree = NULL;
1903       fLoader[iDet]->LoadRecPoints("read");
1904       AliSysInfo::AddStamp(Form("RLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,1, eventNr);
1905       tree = fLoader[iDet]->TreeR();
1906       if (!tree) {
1907         AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
1908         return kFALSE;
1909       }
1910       fTracker[iDet]->LoadClusters(tree); 
1911       AliSysInfo::AddStamp(Form("TLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
1912     }
1913
1914     // run tracking
1915     if (iDet>1) // start filling residuals for the "outer" detectors
1916     if (fRunGlobalQA) AliTracker::SetFillResiduals(kTRUE);     
1917
1918     if (fTracker[iDet]->PropagateBack(esd) != 0) {
1919       AliError(Form("%s backward propagation failed", fgkDetectorName[iDet]));
1920       //      return kFALSE;
1921     }
1922     if (fCheckPointLevel > 1) {
1923       WriteESD(esd, Form("%s.back", fgkDetectorName[iDet]));
1924     }
1925
1926     // unload clusters
1927     if (iDet > 3) {     // all except ITS, TPC, TRD and TOF
1928       fTracker[iDet]->UnloadClusters();
1929       fLoader[iDet]->UnloadRecPoints();
1930     }
1931     // updated PID in TPC needed by the ITS tracker -MI
1932     if (iDet == 1) {
1933       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
1934       AliESDpid::MakePID(esd);
1935     }
1936     AliSysInfo::AddStamp(Form("Tracking1%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
1937   }
1938   //stop filling residuals for the "outer" detectors
1939   if (fRunGlobalQA) AliTracker::SetFillResiduals(kFALSE);     
1940
1941   // pass 3: TRD + TPC + ITS refit inwards
1942
1943   for (Int_t iDet = 2; iDet >= 0; iDet--) {
1944     if (!fTracker[iDet]) continue;
1945     AliDebug(1, Form("%s inward refit", fgkDetectorName[iDet]));
1946
1947     // run tracking
1948     if (iDet<2) // start filling residuals for TPC and ITS
1949     if (fRunGlobalQA) AliTracker::SetFillResiduals(kTRUE);     
1950
1951     if (fTracker[iDet]->RefitInward(esd) != 0) {
1952       AliError(Form("%s inward refit failed", fgkDetectorName[iDet]));
1953       //      return kFALSE;
1954     }
1955     // run postprocessing
1956     if (fTracker[iDet]->PostProcess(esd) != 0) {
1957       AliError(Form("%s postprocessing failed", fgkDetectorName[iDet]));
1958       //      return kFALSE;
1959     }
1960     if (fCheckPointLevel > 1) {
1961       WriteESD(esd, Form("%s.refit", fgkDetectorName[iDet]));
1962     }
1963     AliSysInfo::AddStamp(Form("Tracking2%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
1964   }
1965
1966   // write space-points to the ESD in case alignment data output
1967   // is switched on
1968   if (fWriteAlignmentData)
1969     WriteAlignmentData(esd);
1970
1971   for (Int_t iDet = 3; iDet >= 0; iDet--) {
1972     if (!fTracker[iDet]) continue;
1973     // unload clusters
1974     fTracker[iDet]->UnloadClusters();
1975     AliSysInfo::AddStamp(Form("TUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,4, eventNr);
1976     fLoader[iDet]->UnloadRecPoints();
1977     AliSysInfo::AddStamp(Form("RUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,5, eventNr);
1978   }
1979   // stop filling residuals for TPC and ITS
1980   if (fRunGlobalQA) AliTracker::SetFillResiduals(kFALSE);     
1981
1982   eventNr++;
1983   return kTRUE;
1984 }
1985
1986 //_____________________________________________________________________________
1987 Bool_t AliReconstruction::CleanESD(AliESDEvent *esd){
1988   //
1989   // Remove the data which are not needed for the physics analysis.
1990   //
1991
1992   Int_t nTracks=esd->GetNumberOfTracks();
1993   Int_t nV0s=esd->GetNumberOfV0s();
1994   AliInfo
1995   (Form("Number of ESD tracks and V0s before cleaning: %d %d",nTracks,nV0s));
1996
1997   Float_t cleanPars[]={fV0DCAmax,fV0CsPmin,fDmax,fZmax};
1998   Bool_t rc=esd->Clean(cleanPars);
1999
2000   nTracks=esd->GetNumberOfTracks();
2001   nV0s=esd->GetNumberOfV0s();
2002   AliInfo
2003   (Form("Number of ESD tracks and V0s after cleaning %d %d",nTracks,nV0s));
2004
2005   return rc;
2006 }
2007
2008 //_____________________________________________________________________________
2009 Bool_t AliReconstruction::FillESD(AliESDEvent*& esd, const TString& detectors)
2010 {
2011 // fill the event summary data
2012
2013   AliCodeTimerAuto("")
2014     static Int_t eventNr=0; 
2015   TString detStr = detectors;
2016   
2017   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
2018   if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2019     AliReconstructor* reconstructor = GetReconstructor(iDet);
2020     if (!reconstructor) continue;
2021     if (!ReadESD(esd, fgkDetectorName[iDet])) {
2022       AliDebug(1, Form("filling ESD for %s", fgkDetectorName[iDet]));
2023       TTree* clustersTree = NULL;
2024       if (fLoader[iDet]) {
2025         fLoader[iDet]->LoadRecPoints("read");
2026         clustersTree = fLoader[iDet]->TreeR();
2027         if (!clustersTree) {
2028           AliError(Form("Can't get the %s clusters tree", 
2029                         fgkDetectorName[iDet]));
2030           if (fStopOnError) return kFALSE;
2031         }
2032       }
2033       if (fRawReader && !reconstructor->HasDigitConversion()) {
2034         reconstructor->FillESD(fRawReader, clustersTree, esd);
2035       } else {
2036         TTree* digitsTree = NULL;
2037         if (fLoader[iDet]) {
2038           fLoader[iDet]->LoadDigits("read");
2039           digitsTree = fLoader[iDet]->TreeD();
2040           if (!digitsTree) {
2041             AliError(Form("Can't get the %s digits tree", 
2042                           fgkDetectorName[iDet]));
2043             if (fStopOnError) return kFALSE;
2044           }
2045         }
2046         reconstructor->FillESD(digitsTree, clustersTree, esd);
2047         if (fLoader[iDet]) fLoader[iDet]->UnloadDigits();
2048       }
2049       if (fLoader[iDet]) {
2050         fLoader[iDet]->UnloadRecPoints();
2051       }
2052
2053       if (fCheckPointLevel > 2) WriteESD(esd, fgkDetectorName[iDet]);
2054     }
2055   }
2056
2057   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2058     AliError(Form("the following detectors were not found: %s", 
2059                   detStr.Data()));
2060     if (fStopOnError) return kFALSE;
2061   }
2062   AliSysInfo::AddStamp(Form("FillESD%d",eventNr), 0,1, eventNr);
2063   eventNr++;
2064   return kTRUE;
2065 }
2066
2067 //_____________________________________________________________________________
2068 Bool_t AliReconstruction::FillTriggerESD(AliESDEvent*& esd)
2069 {
2070   // Reads the trigger decision which is
2071   // stored in Trigger.root file and fills
2072   // the corresponding esd entries
2073
2074   AliCodeTimerAuto("")
2075   
2076   AliInfo("Filling trigger information into the ESD");
2077
2078   if (fRawReader) {
2079     AliCTPRawStream input(fRawReader);
2080     if (!input.Next()) {
2081       AliWarning("No valid CTP (trigger) DDL raw data is found ! The trigger info is taken from the event header!");
2082     }
2083     else {
2084       if (esd->GetTriggerMask() != input.GetClassMask())
2085         AliError(Form("Invalid trigger pattern found in CTP raw-data: %llx %llx",
2086                       input.GetClassMask(),esd->GetTriggerMask()));
2087       if (esd->GetOrbitNumber() != input.GetOrbitID())
2088         AliError(Form("Invalid orbit id found in CTP raw-data: %x %x",
2089                       input.GetOrbitID(),esd->GetOrbitNumber()));
2090       if (esd->GetBunchCrossNumber() != input.GetBCID())
2091         AliError(Form("Invalid bunch-crossing id found in CTP raw-data: %x %x",
2092                       input.GetBCID(),esd->GetBunchCrossNumber()));
2093     }
2094
2095   // Here one has to add the filling of trigger inputs and
2096   // interaction records
2097   // ...
2098   }
2099   return kTRUE;
2100 }
2101
2102
2103
2104
2105
2106 //_____________________________________________________________________________
2107 Bool_t AliReconstruction::FillRawEventHeaderESD(AliESDEvent*& esd)
2108 {
2109   // 
2110   // Filling information from RawReader Header
2111   // 
2112
2113   if (!fRawReader) return kFALSE;
2114
2115   AliInfo("Filling information from RawReader Header");
2116
2117   esd->SetBunchCrossNumber(fRawReader->GetBCID());
2118   esd->SetOrbitNumber(fRawReader->GetOrbitID());
2119   esd->SetPeriodNumber(fRawReader->GetPeriod());
2120
2121   esd->SetTimeStamp(fRawReader->GetTimestamp());  
2122   esd->SetEventType(fRawReader->GetType());
2123
2124   return kTRUE;
2125 }
2126
2127
2128 //_____________________________________________________________________________
2129 Bool_t AliReconstruction::IsSelected(TString detName, TString& detectors) const
2130 {
2131 // check whether detName is contained in detectors
2132 // if yes, it is removed from detectors
2133
2134   // check if all detectors are selected
2135   if ((detectors.CompareTo("ALL") == 0) ||
2136       detectors.BeginsWith("ALL ") ||
2137       detectors.EndsWith(" ALL") ||
2138       detectors.Contains(" ALL ")) {
2139     detectors = "ALL";
2140     return kTRUE;
2141   }
2142
2143   // search for the given detector
2144   Bool_t result = kFALSE;
2145   if ((detectors.CompareTo(detName) == 0) ||
2146       detectors.BeginsWith(detName+" ") ||
2147       detectors.EndsWith(" "+detName) ||
2148       detectors.Contains(" "+detName+" ")) {
2149     detectors.ReplaceAll(detName, "");
2150     result = kTRUE;
2151   }
2152
2153   // clean up the detectors string
2154   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
2155   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
2156   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
2157
2158   return result;
2159 }
2160
2161 //_____________________________________________________________________________
2162 Bool_t AliReconstruction::InitRunLoader()
2163 {
2164 // get or create the run loader
2165
2166   if (gAlice) delete gAlice;
2167   gAlice = NULL;
2168
2169   if (!gSystem->AccessPathName(fGAliceFileName.Data())) { // galice.root exists
2170     // load all base libraries to get the loader classes
2171     TString libs = gSystem->GetLibraries();
2172     for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
2173       TString detName = fgkDetectorName[iDet];
2174       if (detName == "HLT") continue;
2175       if (libs.Contains("lib" + detName + "base.so")) continue;
2176       gSystem->Load("lib" + detName + "base.so");
2177     }
2178     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data());
2179     if (!fRunLoader) {
2180       AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
2181       CleanUp();
2182       return kFALSE;
2183     }
2184
2185     fRunLoader->CdGAFile();
2186     fRunLoader->LoadgAlice();
2187
2188     //PH This is a temporary fix to give access to the kinematics
2189     //PH that is needed for the labels of ITS clusters
2190     fRunLoader->LoadHeader();
2191     fRunLoader->LoadKinematics();
2192
2193   } else {               // galice.root does not exist
2194     if (!fRawReader) {
2195       AliError(Form("the file %s does not exist", fGAliceFileName.Data()));
2196       CleanUp();
2197       return kFALSE;
2198     }
2199     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data(),
2200                                     AliConfig::GetDefaultEventFolderName(),
2201                                     "recreate");
2202     if (!fRunLoader) {
2203       AliError(Form("could not create run loader in file %s", 
2204                     fGAliceFileName.Data()));
2205       CleanUp();
2206       return kFALSE;
2207     }
2208     fIsNewRunLoader = kTRUE;
2209     fRunLoader->MakeTree("E");
2210
2211     if (fNumberOfEventsPerFile > 0)
2212       fRunLoader->SetNumberOfEventsPerFile(fNumberOfEventsPerFile);
2213     else
2214       fRunLoader->SetNumberOfEventsPerFile((UInt_t)-1);
2215   }
2216
2217   return kTRUE;
2218 }
2219
2220 //_____________________________________________________________________________
2221 AliReconstructor* AliReconstruction::GetReconstructor(Int_t iDet)
2222 {
2223 // get the reconstructor object and the loader for a detector
2224
2225   if (fReconstructor[iDet]) {
2226     if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
2227       const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
2228       fReconstructor[iDet]->SetRecoParam(par);
2229     }
2230     return fReconstructor[iDet];
2231   }
2232
2233   // load the reconstructor object
2234   TPluginManager* pluginManager = gROOT->GetPluginManager();
2235   TString detName = fgkDetectorName[iDet];
2236   TString recName = "Ali" + detName + "Reconstructor";
2237
2238   if (!fIsNewRunLoader && !fRunLoader->GetLoader(detName+"Loader") && (detName != "HLT")) return NULL;
2239
2240   AliReconstructor* reconstructor = NULL;
2241   // first check if a plugin is defined for the reconstructor
2242   TPluginHandler* pluginHandler = 
2243     pluginManager->FindHandler("AliReconstructor", detName);
2244   // if not, add a plugin for it
2245   if (!pluginHandler) {
2246     AliDebug(1, Form("defining plugin for %s", recName.Data()));
2247     TString libs = gSystem->GetLibraries();
2248     if (libs.Contains("lib" + detName + "base.so") ||
2249         (gSystem->Load("lib" + detName + "base.so") >= 0)) {
2250       pluginManager->AddHandler("AliReconstructor", detName, 
2251                                 recName, detName + "rec", recName + "()");
2252     } else {
2253       pluginManager->AddHandler("AliReconstructor", detName, 
2254                                 recName, detName, recName + "()");
2255     }
2256     pluginHandler = pluginManager->FindHandler("AliReconstructor", detName);
2257   }
2258   if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
2259     reconstructor = (AliReconstructor*) pluginHandler->ExecPlugin(0);
2260   }
2261   if (reconstructor) {
2262     TObject* obj = fOptions.FindObject(detName.Data());
2263     if (obj) reconstructor->SetOption(obj->GetTitle());
2264     reconstructor->Init();
2265     fReconstructor[iDet] = reconstructor;
2266   }
2267
2268   // get or create the loader
2269   if (detName != "HLT") {
2270     fLoader[iDet] = fRunLoader->GetLoader(detName + "Loader");
2271     if (!fLoader[iDet]) {
2272       AliConfig::Instance()
2273         ->CreateDetectorFolders(fRunLoader->GetEventFolder(), 
2274                                 detName, detName);
2275       // first check if a plugin is defined for the loader
2276       pluginHandler = 
2277         pluginManager->FindHandler("AliLoader", detName);
2278       // if not, add a plugin for it
2279       if (!pluginHandler) {
2280         TString loaderName = "Ali" + detName + "Loader";
2281         AliDebug(1, Form("defining plugin for %s", loaderName.Data()));
2282         pluginManager->AddHandler("AliLoader", detName, 
2283                                   loaderName, detName + "base", 
2284                                   loaderName + "(const char*, TFolder*)");
2285         pluginHandler = pluginManager->FindHandler("AliLoader", detName);
2286       }
2287       if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
2288         fLoader[iDet] = 
2289           (AliLoader*) pluginHandler->ExecPlugin(2, detName.Data(), 
2290                                                  fRunLoader->GetEventFolder());
2291       }
2292       if (!fLoader[iDet]) {   // use default loader
2293         fLoader[iDet] = new AliLoader(detName, fRunLoader->GetEventFolder());
2294       }
2295       if (!fLoader[iDet]) {
2296         AliWarning(Form("couldn't get loader for %s", detName.Data()));
2297         if (fStopOnError) return NULL;
2298       } else {
2299         fRunLoader->AddLoader(fLoader[iDet]);
2300         fRunLoader->CdGAFile();
2301         if (gFile && !gFile->IsWritable()) gFile->ReOpen("UPDATE");
2302         fRunLoader->Write(0, TObject::kOverwrite);
2303       }
2304     }
2305   }
2306       
2307   if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
2308     const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
2309     reconstructor->SetRecoParam(par);
2310   }
2311   return reconstructor;
2312 }
2313
2314 //_____________________________________________________________________________
2315 Bool_t AliReconstruction::CreateVertexer()
2316 {
2317 // create the vertexer
2318
2319   fVertexer = NULL;
2320   AliReconstructor* itsReconstructor = GetReconstructor(0);
2321   if (itsReconstructor) {
2322     fVertexer = itsReconstructor->CreateVertexer();
2323   }
2324   if (!fVertexer) {
2325     AliWarning("couldn't create a vertexer for ITS");
2326     if (fStopOnError) return kFALSE;
2327   }
2328
2329   return kTRUE;
2330 }
2331
2332 //_____________________________________________________________________________
2333 Bool_t AliReconstruction::CreateTrackers(const TString& detectors)
2334 {
2335 // create the trackers
2336
2337   TString detStr = detectors;
2338   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
2339     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2340     AliReconstructor* reconstructor = GetReconstructor(iDet);
2341     if (!reconstructor) continue;
2342     TString detName = fgkDetectorName[iDet];
2343     if (detName == "HLT") {
2344       fRunHLTTracking = kTRUE;
2345       continue;
2346     }
2347     if (detName == "MUON") {
2348       fRunMuonTracking = kTRUE;
2349       continue;
2350     }
2351
2352
2353     fTracker[iDet] = reconstructor->CreateTracker();
2354     if (!fTracker[iDet] && (iDet < 7)) {
2355       AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
2356       if (fStopOnError) return kFALSE;
2357     }
2358     AliSysInfo::AddStamp(Form("LTracker%s",fgkDetectorName[iDet]), iDet,0);
2359   }
2360
2361   return kTRUE;
2362 }
2363
2364 //_____________________________________________________________________________
2365 void AliReconstruction::CleanUp(TFile* file, TFile* fileOld)
2366 {
2367 // delete trackers and the run loader and close and delete the file
2368
2369   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
2370     delete fReconstructor[iDet];
2371     fReconstructor[iDet] = NULL;
2372     fLoader[iDet] = NULL;
2373     delete fTracker[iDet];
2374     fTracker[iDet] = NULL;
2375   }
2376   if (fRunInfo) delete fRunInfo;
2377   fRunInfo = NULL;
2378
2379   delete fVertexer;
2380   fVertexer = NULL;
2381
2382   if (ftVertexer) delete ftVertexer;
2383   ftVertexer = NULL;
2384   
2385   if(!(AliCDBManager::Instance()->GetCacheFlag())) {
2386         delete fDiamondProfile;
2387         fDiamondProfile = NULL;
2388         delete fDiamondProfileTPC;
2389         fDiamondProfileTPC = NULL;
2390         delete fGRPData;
2391         fGRPData = NULL;
2392   }
2393
2394
2395   delete fRunLoader;
2396   fRunLoader = NULL;
2397   delete fRawReader;
2398   fRawReader = NULL;
2399   if (fParentRawReader) delete fParentRawReader;
2400   fParentRawReader=NULL;
2401
2402   if (file) {
2403     file->Close();
2404     delete file;
2405   }
2406
2407   if (fileOld) {
2408     fileOld->Close();
2409     delete fileOld;
2410     gSystem->Unlink("AliESDs.old.root");
2411   }
2412
2413 }
2414
2415 //_____________________________________________________________________________
2416
2417 Bool_t AliReconstruction::ReadESD(AliESDEvent*& esd, const char* recStep) const
2418 {
2419 // read the ESD event from a file
2420
2421   if (!esd) return kFALSE;
2422   char fileName[256];
2423   sprintf(fileName, "ESD_%d.%d_%s.root", 
2424           esd->GetRunNumber(), esd->GetEventNumberInFile(), recStep);
2425   if (gSystem->AccessPathName(fileName)) return kFALSE;
2426
2427   AliInfo(Form("reading ESD from file %s", fileName));
2428   AliDebug(1, Form("reading ESD from file %s", fileName));
2429   TFile* file = TFile::Open(fileName);
2430   if (!file || !file->IsOpen()) {
2431     AliError(Form("opening %s failed", fileName));
2432     delete file;
2433     return kFALSE;
2434   }
2435
2436   gROOT->cd();
2437   delete esd;
2438   esd = (AliESDEvent*) file->Get("ESD");
2439   file->Close();
2440   delete file;
2441   return kTRUE;
2442
2443 }
2444
2445
2446
2447 //_____________________________________________________________________________
2448 void AliReconstruction::WriteESD(AliESDEvent* esd, const char* recStep) const
2449 {
2450 // write the ESD event to a file
2451
2452   if (!esd) return;
2453   char fileName[256];
2454   sprintf(fileName, "ESD_%d.%d_%s.root", 
2455           esd->GetRunNumber(), esd->GetEventNumberInFile(), recStep);
2456
2457   AliDebug(1, Form("writing ESD to file %s", fileName));
2458   TFile* file = TFile::Open(fileName, "recreate");
2459   if (!file || !file->IsOpen()) {
2460     AliError(Form("opening %s failed", fileName));
2461   } else {
2462     esd->Write("ESD");
2463     file->Close();
2464   }
2465   delete file;
2466 }
2467
2468
2469 void AliReconstruction::WriteAlignmentData(AliESDEvent* esd)
2470 {
2471   // Write space-points which are then used in the alignment procedures
2472   // For the moment only ITS, TPC, TRD and TOF
2473
2474   Int_t ntracks = esd->GetNumberOfTracks();
2475   for (Int_t itrack = 0; itrack < ntracks; itrack++)
2476     {
2477       AliESDtrack *track = esd->GetTrack(itrack);
2478       Int_t nsp = 0;
2479       Int_t idx[200];
2480       for (Int_t iDet = 3; iDet >= 0; iDet--) {// TOF, TRD, TPC, ITS clusters
2481           nsp += track->GetNcls(iDet);
2482
2483           if (iDet==0) { // ITS "extra" clusters
2484              track->GetClusters(iDet,idx);
2485              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nsp++;
2486           }  
2487       }
2488
2489       if (nsp) {
2490         AliTrackPointArray *sp = new AliTrackPointArray(nsp);
2491         track->SetTrackPointArray(sp);
2492         Int_t isptrack = 0;
2493         for (Int_t iDet = 3; iDet >= 0; iDet--) {
2494           AliTracker *tracker = fTracker[iDet];
2495           if (!tracker) continue;
2496           Int_t nspdet = track->GetClusters(iDet,idx);
2497
2498           if (iDet==0) // ITS "extra" clusters             
2499              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nspdet++;
2500
2501           if (nspdet <= 0) continue;
2502           AliTrackPoint p;
2503           Int_t isp = 0;
2504           Int_t isp2 = 0;
2505           while (isp2 < nspdet) {
2506             Bool_t isvalid=kTRUE;
2507
2508             Int_t index=idx[isp++];
2509             if (index < 0) continue;
2510
2511             TString dets = fgkDetectorName[iDet];
2512             if ((fUseTrackingErrorsForAlignment.CompareTo(dets) == 0) ||
2513             fUseTrackingErrorsForAlignment.BeginsWith(dets+" ") ||
2514             fUseTrackingErrorsForAlignment.EndsWith(" "+dets) ||
2515             fUseTrackingErrorsForAlignment.Contains(" "+dets+" ")) {
2516               isvalid = tracker->GetTrackPointTrackingError(index,p,track);
2517             } else {
2518               isvalid = tracker->GetTrackPoint(index,p); 
2519             } 
2520             isp2++;
2521             if (!isvalid) continue;
2522             sp->AddPoint(isptrack,&p); isptrack++;
2523           }
2524         }       
2525       }
2526     }
2527 }
2528
2529 //_____________________________________________________________________________
2530 void AliReconstruction::FillRawDataErrorLog(Int_t iEvent, AliESDEvent* esd)
2531 {
2532   // The method reads the raw-data error log
2533   // accumulated within the rawReader.
2534   // It extracts the raw-data errors related to
2535   // the current event and stores them into
2536   // a TClonesArray inside the esd object.
2537
2538   if (!fRawReader) return;
2539
2540   for(Int_t i = 0; i < fRawReader->GetNumberOfErrorLogs(); i++) {
2541
2542     AliRawDataErrorLog *log = fRawReader->GetErrorLog(i);
2543     if (!log) continue;
2544     if (iEvent != log->GetEventNumber()) continue;
2545
2546     esd->AddRawDataErrorLog(log);
2547   }
2548
2549 }
2550
2551 TNamed* AliReconstruction::CopyFileToTNamed(TString fPath,TString pName){
2552   // Dump a file content into a char in TNamed
2553   ifstream in;
2554   in.open(fPath.Data(),ios::in | ios::binary|ios::ate);
2555   Int_t kBytes = (Int_t)in.tellg();
2556   printf("Size: %d \n",kBytes);
2557   TNamed *fn = 0;
2558   if(in.good()){
2559     char* memblock = new char [kBytes];
2560     in.seekg (0, ios::beg);
2561     in.read (memblock, kBytes);
2562     in.close();
2563     TString fData(memblock,kBytes);
2564     fn = new TNamed(pName,fData);
2565     printf("fData Size: %d \n",fData.Sizeof());
2566     printf("pName Size: %d \n",pName.Sizeof());
2567     printf("fn    Size: %d \n",fn->Sizeof());
2568     delete[] memblock;
2569   }
2570   else{
2571     AliInfo(Form("Could not Open %s\n",fPath.Data()));
2572   }
2573
2574   return fn;
2575 }
2576
2577 void AliReconstruction::TNamedToFile(TTree* fTree, TString pName){
2578   // This is not really needed in AliReconstruction at the moment
2579   // but can serve as a template
2580
2581   TList *fList = fTree->GetUserInfo();
2582   TNamed *fn = (TNamed*)fList->FindObject(pName.Data());
2583   printf("fn Size: %d \n",fn->Sizeof());
2584
2585   TString fTmp(fn->GetName()); // to be 100% sure in principle pName also works
2586   const char* cdata = fn->GetTitle();
2587   printf("fTmp Size %d\n",fTmp.Sizeof());
2588
2589   int size = fn->Sizeof()-fTmp.Sizeof()-sizeof(UChar_t)-sizeof(Int_t); // see dfinition of TString::SizeOf()...
2590   printf("calculated size %d\n",size);
2591   ofstream out(pName.Data(),ios::out | ios::binary);
2592   out.write(cdata,size);
2593   out.close();
2594
2595 }
2596   
2597 //_____________________________________________________________________________
2598 void AliReconstruction::CheckQA()
2599 {
2600 // check the QA of SIM for this run and remove the detectors 
2601 // with status Fatal
2602   
2603         TString newRunLocalReconstruction ; 
2604         TString newRunTracking ;
2605         TString newFillESD ;
2606          
2607         for (Int_t iDet = 0; iDet < AliQA::kNDET; iDet++) {
2608                 TString detName(AliQA::GetDetName(iDet)) ;
2609                 AliQA * qa = AliQA::Instance(AliQA::DETECTORINDEX_t(iDet)) ; 
2610                 if ( qa->IsSet(AliQA::DETECTORINDEX_t(iDet), AliQA::kSIM, AliQA::kFATAL)) {
2611                                 AliInfo(Form("QA status for %s in Hits and/or SDIGITS  and/or Digits was Fatal; No reconstruction performed", detName.Data())) ;
2612                 } else {
2613                         if ( fRunLocalReconstruction.Contains(AliQA::GetDetName(iDet)) || 
2614                                         fRunLocalReconstruction.Contains("ALL") )  {
2615                                 newRunLocalReconstruction += detName ; 
2616                                 newRunLocalReconstruction += " " ;                      
2617                         }
2618                         if ( fRunTracking.Contains(AliQA::GetDetName(iDet)) || 
2619                                         fRunTracking.Contains("ALL") )  {
2620                                 newRunTracking += detName ; 
2621                                 newRunTracking += " " ;                         
2622                         }
2623                         if ( fFillESD.Contains(AliQA::GetDetName(iDet)) || 
2624                                         fFillESD.Contains("ALL") )  {
2625                                 newFillESD += detName ; 
2626                                 newFillESD += " " ;                     
2627                         }
2628                 }
2629         }
2630         fRunLocalReconstruction = newRunLocalReconstruction ; 
2631         fRunTracking            = newRunTracking ; 
2632         fFillESD                = newFillESD ; 
2633 }
2634
2635 //_____________________________________________________________________________
2636 Int_t AliReconstruction::GetDetIndex(const char* detector)
2637 {
2638   // return the detector index corresponding to detector
2639   Int_t index = -1 ; 
2640   for (index = 0; index < fgkNDetectors ; index++) {
2641     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
2642         break ; 
2643   }     
2644   return index ; 
2645 }
2646 //_____________________________________________________________________________
2647 Bool_t AliReconstruction::FinishPlaneEff() {
2648  //
2649  // Here execute all the necessary operationis, at the end of the tracking phase,
2650  // in case that evaluation of PlaneEfficiencies was required for some detector.
2651  // E.g., write into a DataBase file the PlaneEfficiency which have been evaluated.
2652  //
2653  // This Preliminary version works only FOR ITS !!!!!
2654  // other detectors (TOF,TRD, etc. have to develop their specific codes)
2655  //
2656  //  Input: none
2657  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
2658  //
2659  Bool_t ret=kFALSE;
2660  //for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
2661  for (Int_t iDet = 0; iDet < 1; iDet++) { // for the time being only ITS
2662    //if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2663    if(fTracker[iDet]) {
2664       AliPlaneEff *planeeff=fTracker[iDet]->GetPlaneEff();
2665       TString name=planeeff->GetName();
2666       name+=".root";
2667       TFile* pefile = TFile::Open(name, "RECREATE");
2668       ret=(Bool_t)planeeff->Write();
2669       pefile->Close();
2670       if(planeeff->GetCreateHistos()) {
2671         TString hname=planeeff->GetName();
2672         hname+="Histo.root";
2673         ret*=planeeff->WriteHistosToFile(hname,"RECREATE");
2674       }
2675    }
2676  }
2677  return ret;
2678 }
2679 //_____________________________________________________________________________
2680 Bool_t AliReconstruction::InitPlaneEff() {
2681 //
2682  // Here execute all the necessary operations, before of the tracking phase,
2683  // for the evaluation of PlaneEfficiencies, in case required for some detectors.
2684  // E.g., read from a DataBase file a first evaluation of the PlaneEfficiency 
2685  // which should be updated/recalculated.
2686  //
2687  // This Preliminary version will work only FOR ITS !!!!!
2688  // other detectors (TOF,TRD, etc. have to develop their specific codes)
2689  //
2690  //  Input: none
2691  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
2692  //
2693  AliWarning(Form("Implementation of this method not yet done !! Method return kTRUE"));
2694  return kTRUE;
2695 }
2696
2697 //_____________________________________________________________________________
2698 Bool_t AliReconstruction::InitAliEVE()
2699 {
2700   // This method should be called only in case 
2701   // AliReconstruction is run
2702   // within the alieve environment.
2703   // It will initialize AliEVE in a way
2704   // so that it can visualize event processed
2705   // by AliReconstruction.
2706   // The return flag shows whenever the
2707   // AliEVE initialization was successful or not.
2708
2709   TString macroStr;
2710   macroStr.Form("%s/EVE/macros/alieve_online.C",gSystem->ExpandPathName("$ALICE_ROOT"));
2711   AliInfo(Form("Loading AliEVE macro: %s",macroStr.Data()));
2712   if (gROOT->LoadMacro(macroStr.Data()) != 0) return kFALSE;
2713
2714   gROOT->ProcessLine("if (!gAliEveEvent) {gAliEveEvent = new AliEveEventManager();gAliEveEvent->SetAutoLoad(kTRUE);gAliEveEvent->AddNewEventCommand(\"alieve_online_on_new_event()\");gEve->AddEvent(gAliEveEvent);};");
2715   gROOT->ProcessLine("alieve_online_init()");
2716
2717   return kTRUE;
2718 }
2719   
2720 //_____________________________________________________________________________
2721 void AliReconstruction::RunAliEVE()
2722 {
2723   // Runs AliEVE visualisation of
2724   // the current event.
2725   // Should be executed only after
2726   // successful initialization of AliEVE.
2727
2728   AliInfo("Running AliEVE...");
2729   gROOT->ProcessLine(Form("gAliEveEvent->SetEvent((AliRunLoader*)%p,(AliRawReader*)%p,(AliESDEvent*)%p);",fRunLoader,fRawReader,fesd));
2730   gROOT->ProcessLine("gAliEveEvent->StartStopAutoLoadTimer();");
2731   gSystem->Run();
2732 }
2733
2734 //_____________________________________________________________________________
2735 Bool_t AliReconstruction::SetRunQA(TString detAndAction) 
2736 {
2737         // Allows to run QA for a selected set of detectors
2738         // and a selected set of tasks among RAWS, RECPOINTS and ESDS
2739         // all selected detectors run the same selected tasks
2740         
2741         if (!detAndAction.Contains(":")) {
2742                 AliError( Form("%s is a wrong syntax, use \"DetectorList:ActionList\" \n", detAndAction.Data()) ) ;
2743                 fRunQA = kFALSE ;
2744                 return kFALSE ;                 
2745         }
2746         Int_t colon = detAndAction.Index(":") ; 
2747         fQADetectors = detAndAction(0, colon) ; 
2748         if (fQADetectors.Contains("ALL") )
2749                 fQADetectors = fFillESD ; 
2750                 fQATasks   = detAndAction(colon+1, detAndAction.Sizeof() ) ; 
2751         if (fQATasks.Contains("ALL") ) {
2752                 fQATasks = Form("%d %d %d", AliQA::kRAWS, AliQA::kRECPOINTS, AliQA::kESDS) ; 
2753         } else {
2754                 fQATasks.ToUpper() ; 
2755                 TString tempo("") ; 
2756                 if ( fQATasks.Contains("RAW") ) 
2757                         tempo = Form("%d ", AliQA::kRAWS) ; 
2758                 if ( fQATasks.Contains("RECPOINT") ) 
2759                         tempo += Form("%d ", AliQA::kRECPOINTS) ; 
2760                 if ( fQATasks.Contains("ESD") ) 
2761                         tempo += Form("%d ", AliQA::kESDS) ; 
2762                 fQATasks = tempo ; 
2763                 if (fQATasks.IsNull()) {
2764                         AliInfo("No QA requested\n")  ;
2765                         fRunQA = kFALSE ;
2766                         return kTRUE ; 
2767                 }
2768         }       
2769         TString tempo(fQATasks) ; 
2770         tempo.ReplaceAll(Form("%d", AliQA::kRAWS), AliQA::GetTaskName(AliQA::kRAWS))    ;
2771         tempo.ReplaceAll(Form("%d", AliQA::kRECPOINTS), AliQA::GetTaskName(AliQA::kRECPOINTS)) ;        
2772         tempo.ReplaceAll(Form("%d", AliQA::kESDS), AliQA::GetTaskName(AliQA::kESDS)) ;  
2773         fQASteer->SetActiveDetectors(fQADetectors) ; 
2774         fQASteer->SetTasks(fQATasks) ; 
2775         AliInfo( Form("QA will be done on \"%s\" for \"%s\"\n", fQADetectors.Data(), tempo.Data()) ) ;  
2776         fRunQA = kTRUE ;
2777         return kTRUE; 
2778
2779
2780 //_____________________________________________________________________________
2781 Bool_t AliReconstruction::InitRecoParams() 
2782 {
2783   // The method accesses OCDB and retrieves all
2784   // the available reco-param objects from there.
2785
2786   Bool_t isOK = kTRUE;
2787
2788   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
2789
2790     if (fRecoParam.GetDetRecoParamArray(iDet)) {
2791       AliInfo(Form("Using custom reconstruction parameters for detector %s",fgkDetectorName[iDet]));
2792       continue;
2793     }
2794
2795     AliDebug(1, Form("Loading RecoParam objects for detector: %s",fgkDetectorName[iDet]));
2796   
2797     AliCDBPath path(fgkDetectorName[iDet],"Calib","RecoParam");
2798     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
2799     if(!entry){ 
2800       AliWarning(Form("Couldn't find RecoParam entry in OCDB for detector %s",fgkDetectorName[iDet]));
2801       isOK = kFALSE;
2802     }
2803     else {
2804       TObject *recoParamObj = entry->GetObject();
2805       if (dynamic_cast<TObjArray*>(recoParamObj)) {
2806         // The detector has a normal TobjArray of AliDetectorRecoParam objects
2807         // Registering them in AliRecoParam
2808         fRecoParam.AddDetRecoParamArray(iDet,dynamic_cast<TObjArray*>(recoParamObj));
2809       }
2810       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
2811         // The detector has only onse set of reco parameters
2812         // Registering it in AliRecoParam
2813         AliInfo(Form("Single set of reco parameters found for detector %s",fgkDetectorName[iDet]));
2814         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
2815         fRecoParam.AddDetRecoParam(iDet,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
2816       }
2817       else {
2818         AliError(Form("No valid RecoParam object found in the OCDB for detector %s",fgkDetectorName[iDet]));
2819         isOK = kFALSE;
2820       }
2821       entry->SetOwner(0);
2822     }
2823   }
2824
2825   return isOK;
2826 }
2827
2828 //_____________________________________________________________________________
2829 Bool_t AliReconstruction::GetEventInfo() 
2830 {
2831   // Fill the event info object
2832   // ...
2833   AliCodeTimerAuto("")
2834
2835   AliCentralTrigger *aCTP = NULL;
2836   if (fRawReader) {
2837     fEventInfo.SetEventType(fRawReader->GetType());
2838
2839     ULong64_t mask = fRawReader->GetClassMask();
2840     fEventInfo.SetTriggerMask(mask);
2841     UInt_t clmask = fRawReader->GetDetectorPattern()[0];
2842     fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(clmask));
2843
2844     aCTP = new AliCentralTrigger();
2845     TString configstr("");
2846     if (!aCTP->LoadConfiguration(configstr)) { // Load CTP config from OCDB
2847       AliError("No trigger configuration found in OCDB! The trigger configuration information will not be used!");
2848       delete aCTP;
2849       return kFALSE;
2850     }
2851     aCTP->SetClassMask(mask);
2852     aCTP->SetClusterMask(clmask);
2853   }
2854   else {
2855     fEventInfo.SetEventType(AliRawEventHeaderBase::kPhysicsEvent);
2856
2857     if (fRunLoader && (!fRunLoader->LoadTrigger())) {
2858       aCTP = fRunLoader->GetTrigger();
2859       fEventInfo.SetTriggerMask(aCTP->GetClassMask());
2860       fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(aCTP->GetClusterMask()));
2861     }
2862     else {
2863       AliWarning("No trigger can be loaded! The trigger information will not be used!");
2864       return kFALSE;
2865     }
2866   }
2867
2868   AliTriggerConfiguration *config = aCTP->GetConfiguration();
2869   if (!config) {
2870     AliError("No trigger configuration has been found! The trigger configuration information will not be used!");
2871     if (fRawReader) delete aCTP;
2872     return kFALSE;
2873   }
2874
2875   TString trclasses;
2876   ULong64_t trmask = fEventInfo.GetTriggerMask();
2877   const TObjArray& classesArray = config->GetClasses();
2878   Int_t nclasses = classesArray.GetEntriesFast();
2879   for( Int_t iclass=0; iclass < nclasses; iclass++ ) {
2880     AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At(iclass);
2881     if (trclass) {
2882       Int_t trindex = (Int_t)TMath::Log2(trclass->GetMask());
2883       fesd->SetTriggerClass(trclass->GetName(),trindex);
2884       if (trmask & (1 << trindex)) {
2885         trclasses += " ";
2886         trclasses += trclass->GetName();
2887         trclasses += " ";
2888       }
2889     }
2890   }
2891   fEventInfo.SetTriggerClasses(trclasses);
2892
2893   if (!aCTP->CheckTriggeredDetectors()) {
2894     if (fRawReader) delete aCTP;
2895     return kFALSE;
2896   }    
2897
2898   if (fRawReader) delete aCTP;
2899
2900   // We have to fill also the HLT decision here!!
2901   // ...
2902
2903   return kTRUE;
2904 }
2905
2906 const char *AliReconstruction::MatchDetectorList(const char *detectorList, UInt_t detectorMask)
2907 {
2908   // Match the detector list found in the rec.C or the default 'ALL'
2909   // to the list found in the GRP (stored there by the shuttle PP which
2910   // gets the information from ECS)
2911   static TString resultList;
2912   TString detList = detectorList;
2913
2914   resultList = "";
2915
2916   for(Int_t iDet = 0; iDet < (AliDAQ::kNDetectors-1); iDet++) {
2917     if ((detectorMask >> iDet) & 0x1) {
2918       TString det = AliDAQ::OfflineModuleName(iDet);
2919       if ((detList.CompareTo("ALL") == 0) ||
2920           detList.BeginsWith("ALL ") ||
2921           detList.EndsWith(" ALL") ||
2922           detList.Contains(" ALL ") ||
2923           (detList.CompareTo(det) == 0) ||
2924           detList.BeginsWith(det) ||
2925           detList.EndsWith(det) ||
2926           detList.Contains( " "+det+" " )) {
2927         if (!resultList.EndsWith(det + " ")) {
2928           resultList += det;
2929           resultList += " ";
2930         }
2931       }        
2932     }
2933   }
2934
2935   // HLT
2936   if ((detectorMask >> AliDAQ::kHLTId) & 0x1) {
2937     TString hltDet = AliDAQ::OfflineModuleName(AliDAQ::kNDetectors-1);
2938     if ((detList.CompareTo("ALL") == 0) ||
2939         detList.BeginsWith("ALL ") ||
2940         detList.EndsWith(" ALL") ||
2941         detList.Contains(" ALL ") ||
2942         (detList.CompareTo(hltDet) == 0) ||
2943         detList.BeginsWith(hltDet) ||
2944         detList.EndsWith(hltDet) ||
2945         detList.Contains( " "+hltDet+" " )) {
2946       resultList += hltDet;
2947     }
2948   }
2949
2950   return resultList.Data();
2951
2952 }