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