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