Added to AliMagF the definition (const) of the polarities conventions.
[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 //                                                                           //
109 ///////////////////////////////////////////////////////////////////////////////
110
111 #include <TArrayD.h>
112 #include <TArrayF.h>
113 #include <TArrayS.h>
114 #include <TChain.h>
115 #include <TFile.h>
116 #include <TGeoGlobalMagField.h>
117 #include <TGeoManager.h>
118 #include <TList.h>
119 #include <TLorentzVector.h>
120 #include <TMap.h>
121 #include <TObjArray.h>
122 #include <TPRegexp.h>
123 #include <TParameter.h>
124 #include <TPluginManager.h>
125 #include <TProof.h>
126 #include <TProofOutputFile.h>
127 #include <TROOT.h>
128 #include <TSystem.h>
129 #include <THashTable.h>
130
131 #include "AliAlignObj.h"
132 #include "AliCDBEntry.h"
133 #include "AliCDBManager.h"
134 #include "AliCDBStorage.h"
135 #include "AliCTPRawStream.h"
136 #include "AliCascadeVertexer.h"
137 #include "AliCentralTrigger.h"
138 #include "AliCodeTimer.h"
139 #include "AliDAQ.h"
140 #include "AliDetectorRecoParam.h"
141 #include "AliESDCaloCells.h"
142 #include "AliESDCaloCluster.h"
143 #include "AliESDEvent.h"
144 #include "AliESDMuonTrack.h"
145 #include "AliESDPmdTrack.h"
146 #include "AliESDTagCreator.h"
147 #include "AliESDVertex.h"
148 #include "AliESDcascade.h"
149 #include "AliESDfriend.h"
150 #include "AliESDkink.h"
151 #include "AliESDpid.h"
152 #include "AliESDtrack.h"
153 #include "AliESDtrack.h"
154 #include "AliEventInfo.h"
155 #include "AliGRPObject.h"
156 #include "AliGRPRecoParam.h"
157 #include "AliGenEventHeader.h"
158 #include "AliGeomManager.h"
159 #include "AliGlobalQADataMaker.h" 
160 #include "AliHeader.h"
161 #include "AliLog.h"
162 #include "AliMagF.h"
163 #include "AliMultiplicity.h"
164 #include "AliPID.h"
165 #include "AliPlaneEff.h"
166 #include "AliQAv1.h"
167 #include "AliQADataMakerRec.h" 
168 #include "AliQAManager.h"
169 #include "AliRawVEvent.h"
170 #include "AliRawEventHeaderBase.h"
171 #include "AliRawHLTManager.h"
172 #include "AliRawReaderDate.h"
173 #include "AliRawReaderFile.h"
174 #include "AliRawReaderRoot.h"
175 #include "AliReconstruction.h"
176 #include "AliReconstructor.h"
177 #include "AliRun.h"
178 #include "AliRunInfo.h"
179 #include "AliRunLoader.h"
180 #include "AliSysInfo.h" // memory snapshots
181 #include "AliTrackPointArray.h"
182 #include "AliTracker.h"
183 #include "AliTriggerClass.h"
184 #include "AliTriggerCluster.h"
185 #include "AliTriggerIR.h"
186 #include "AliTriggerConfiguration.h"
187 #include "AliV0vertexer.h"
188 #include "AliVertexer.h"
189 #include "AliVertexerTracks.h"
190
191 ClassImp(AliReconstruction)
192
193 //_____________________________________________________________________________
194 const char* AliReconstruction::fgkDetectorName[AliReconstruction::kNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT"};
195
196 //_____________________________________________________________________________
197 AliReconstruction::AliReconstruction(const char* gAliceFilename) :
198   TSelector(),
199   fRunVertexFinder(kTRUE),
200   fRunVertexFinderTracks(kTRUE),
201   fRunHLTTracking(kFALSE),
202   fRunMuonTracking(kFALSE),
203   fRunV0Finder(kTRUE),
204   fRunCascadeFinder(kTRUE),
205   fStopOnError(kFALSE),
206   fWriteAlignmentData(kFALSE),
207   fWriteESDfriend(kFALSE),
208   fFillTriggerESD(kTRUE),
209
210   fCleanESD(kTRUE),
211   fV0DCAmax(3.),
212   fV0CsPmin(0.),
213   fDmax(50.),
214   fZmax(50.),
215
216   fRunLocalReconstruction("ALL"),
217   fRunTracking("ALL"),
218   fFillESD("ALL"),
219   fLoadCDB(""),
220   fUseTrackingErrorsForAlignment(""),
221   fGAliceFileName(gAliceFilename),
222   fRawInput(""),
223   fESDOutput(""),
224   fEquipIdMap(""),
225   fFirstEvent(0),
226   fLastEvent(-1),
227   fNumberOfEventsPerFile((UInt_t)-1),
228   fOptions(),
229   fLoadAlignFromCDB(kTRUE),
230   fLoadAlignData("ALL"),
231   fUseHLTData(),
232   fRunInfo(NULL),
233   fEventInfo(),
234   fRunScalers(NULL),
235
236   fRunLoader(NULL),
237   fRawReader(NULL),
238   fParentRawReader(NULL),
239
240   fRecoParam(),
241
242   fSPDTrackleter(NULL),
243
244   fDiamondProfileSPD(NULL),
245   fDiamondProfile(NULL),
246   fDiamondProfileTPC(NULL),
247   fListOfCosmicTriggers(NULL),
248   
249   fGRPData(NULL),
250
251   fAlignObjArray(NULL),
252   fCDBUri(),
253   fQARefUri(),
254   fSpecCDBUri(), 
255   fInitCDBCalled(kFALSE),
256   fSetRunNumberFromDataCalled(kFALSE),
257   fQADetectors("ALL"), 
258   fQATasks("ALL"), 
259   fRunQA(kTRUE),  
260   fRunGlobalQA(kTRUE),
261   fSameQACycle(kFALSE),
262   fInitQACalled(kFALSE), 
263   fWriteQAExpertData(kTRUE), 
264   fRunPlaneEff(kFALSE),
265
266   fesd(NULL),
267   fhltesd(NULL),
268   fesdf(NULL),
269   ffile(NULL),
270   ftree(NULL),
271   fhlttree(NULL),
272   ftVertexer(NULL),
273   fIsNewRunLoader(kFALSE),
274   fRunAliEVE(kFALSE),
275   fChain(NULL)
276 {
277 // create reconstruction object with default parameters
278   gGeoManager = NULL;
279   
280   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
281     fReconstructor[iDet] = NULL;
282     fLoader[iDet] = NULL;
283     fTracker[iDet] = NULL;
284   }
285   for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
286     fQACycles[iDet] = 999999 ;
287     fQAWriteExpert[iDet] = kFALSE ; 
288   }
289     
290   AliPID pid;
291 }
292
293 //_____________________________________________________________________________
294 AliReconstruction::AliReconstruction(const AliReconstruction& rec) :
295   TSelector(),
296   fRunVertexFinder(rec.fRunVertexFinder),
297   fRunVertexFinderTracks(rec.fRunVertexFinderTracks),
298   fRunHLTTracking(rec.fRunHLTTracking),
299   fRunMuonTracking(rec.fRunMuonTracking),
300   fRunV0Finder(rec.fRunV0Finder),
301   fRunCascadeFinder(rec.fRunCascadeFinder),
302   fStopOnError(rec.fStopOnError),
303   fWriteAlignmentData(rec.fWriteAlignmentData),
304   fWriteESDfriend(rec.fWriteESDfriend),
305   fFillTriggerESD(rec.fFillTriggerESD),
306
307   fCleanESD(rec.fCleanESD),
308   fV0DCAmax(rec.fV0DCAmax),
309   fV0CsPmin(rec.fV0CsPmin),
310   fDmax(rec.fDmax),
311   fZmax(rec.fZmax),
312
313   fRunLocalReconstruction(rec.fRunLocalReconstruction),
314   fRunTracking(rec.fRunTracking),
315   fFillESD(rec.fFillESD),
316   fLoadCDB(rec.fLoadCDB),
317   fUseTrackingErrorsForAlignment(rec.fUseTrackingErrorsForAlignment),
318   fGAliceFileName(rec.fGAliceFileName),
319   fRawInput(rec.fRawInput),
320   fESDOutput(rec.fESDOutput),
321   fEquipIdMap(rec.fEquipIdMap),
322   fFirstEvent(rec.fFirstEvent),
323   fLastEvent(rec.fLastEvent),
324   fNumberOfEventsPerFile(rec.fNumberOfEventsPerFile),
325   fOptions(),
326   fLoadAlignFromCDB(rec.fLoadAlignFromCDB),
327   fLoadAlignData(rec.fLoadAlignData),
328   fUseHLTData(rec.fUseHLTData),
329   fRunInfo(NULL),
330   fEventInfo(),
331   fRunScalers(NULL),
332
333   fRunLoader(NULL),
334   fRawReader(NULL),
335   fParentRawReader(NULL),
336
337   fRecoParam(rec.fRecoParam),
338
339   fSPDTrackleter(NULL),
340
341   fDiamondProfileSPD(rec.fDiamondProfileSPD),
342   fDiamondProfile(rec.fDiamondProfile),
343   fDiamondProfileTPC(rec.fDiamondProfileTPC),
344   fListOfCosmicTriggers(NULL),
345   
346   fGRPData(NULL),
347
348   fAlignObjArray(rec.fAlignObjArray),
349   fCDBUri(rec.fCDBUri),
350   fQARefUri(rec.fQARefUri),
351   fSpecCDBUri(), 
352   fInitCDBCalled(rec.fInitCDBCalled),
353   fSetRunNumberFromDataCalled(rec.fSetRunNumberFromDataCalled),
354   fQADetectors(rec.fQADetectors), 
355   fQATasks(rec.fQATasks), 
356   fRunQA(rec.fRunQA),  
357   fRunGlobalQA(rec.fRunGlobalQA),
358   fSameQACycle(rec.fSameQACycle),
359   fInitQACalled(rec.fInitQACalled),
360   fWriteQAExpertData(rec.fWriteQAExpertData), 
361   fRunPlaneEff(rec.fRunPlaneEff),
362
363   fesd(NULL),
364   fhltesd(NULL),
365   fesdf(NULL),
366   ffile(NULL),
367   ftree(NULL),
368   fhlttree(NULL),
369   ftVertexer(NULL),
370   fIsNewRunLoader(rec.fIsNewRunLoader),
371   fRunAliEVE(kFALSE),
372   fChain(NULL)
373 {
374 // copy constructor
375
376   for (Int_t i = 0; i < rec.fOptions.GetEntriesFast(); i++) {
377     if (rec.fOptions[i]) fOptions.Add(rec.fOptions[i]->Clone());
378   }
379   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
380     fReconstructor[iDet] = NULL;
381     fLoader[iDet] = NULL;
382     fTracker[iDet] = NULL;
383   }  
384   
385   for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
386     fQACycles[iDet] = rec.fQACycles[iDet];
387     fQAWriteExpert[iDet] = rec.fQAWriteExpert[iDet] ; 
388   }
389
390   for (Int_t i = 0; i < rec.fSpecCDBUri.GetEntriesFast(); i++) {
391     if (rec.fSpecCDBUri[i]) fSpecCDBUri.Add(rec.fSpecCDBUri[i]->Clone());
392   }
393 }
394
395 //_____________________________________________________________________________
396 AliReconstruction& AliReconstruction::operator = (const AliReconstruction& rec)
397 {
398 // assignment operator
399 // Used in PROOF mode
400 // Be very careful while modifing it!
401 // Simple rules to follow:
402 // for persistent data members - use their assignment operators
403 // for non-persistent ones - do nothing or take the default values from constructor
404 // TSelector members should not be touched
405   if(&rec == this) return *this;
406
407   fRunVertexFinder       = rec.fRunVertexFinder;
408   fRunVertexFinderTracks = rec.fRunVertexFinderTracks;
409   fRunHLTTracking        = rec.fRunHLTTracking;
410   fRunMuonTracking       = rec.fRunMuonTracking;
411   fRunV0Finder           = rec.fRunV0Finder;
412   fRunCascadeFinder      = rec.fRunCascadeFinder;
413   fStopOnError           = rec.fStopOnError;
414   fWriteAlignmentData    = rec.fWriteAlignmentData;
415   fWriteESDfriend        = rec.fWriteESDfriend;
416   fFillTriggerESD        = rec.fFillTriggerESD;
417
418   fCleanESD  = rec.fCleanESD;
419   fV0DCAmax  = rec.fV0DCAmax;
420   fV0CsPmin  = rec.fV0CsPmin;
421   fDmax      = rec.fDmax;
422   fZmax      = rec.fZmax;
423
424   fRunLocalReconstruction        = rec.fRunLocalReconstruction;
425   fRunTracking                   = rec.fRunTracking;
426   fFillESD                       = rec.fFillESD;
427   fLoadCDB                       = rec.fLoadCDB;
428   fUseTrackingErrorsForAlignment = rec.fUseTrackingErrorsForAlignment;
429   fGAliceFileName                = rec.fGAliceFileName;
430   fRawInput                      = rec.fRawInput;
431   fESDOutput                     = rec.fESDOutput;
432   fEquipIdMap                    = rec.fEquipIdMap;
433   fFirstEvent                    = rec.fFirstEvent;
434   fLastEvent                     = rec.fLastEvent;
435   fNumberOfEventsPerFile         = rec.fNumberOfEventsPerFile;
436
437   for (Int_t i = 0; i < rec.fOptions.GetEntriesFast(); i++) {
438     if (rec.fOptions[i]) fOptions.Add(rec.fOptions[i]->Clone());
439   }
440
441   fLoadAlignFromCDB              = rec.fLoadAlignFromCDB;
442   fLoadAlignData                 = rec.fLoadAlignData;
443   fUseHLTData                    = rec.fUseHLTData;
444
445   delete fRunInfo; fRunInfo = NULL;
446   if (rec.fRunInfo) fRunInfo = new AliRunInfo(*rec.fRunInfo);
447
448   fEventInfo                     = rec.fEventInfo;
449
450   delete fRunScalers; fRunScalers = NULL;
451   if (rec.fRunScalers) fRunScalers = new AliTriggerRunScalers(*rec.fRunScalers); 
452
453   
454   fRunLoader       = NULL;
455   fRawReader       = NULL;
456   fParentRawReader = NULL;
457
458   fRecoParam = rec.fRecoParam;
459
460   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
461     delete fReconstructor[iDet]; fReconstructor[iDet] = NULL;
462     delete fLoader[iDet]; fLoader[iDet] = NULL;
463     delete fTracker[iDet]; fTracker[iDet] = NULL;
464   }
465   
466   for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
467     fQACycles[iDet] = rec.fQACycles[iDet];
468     fQAWriteExpert[iDet] = rec.fQAWriteExpert[iDet] ;
469   } 
470
471   delete fSPDTrackleter; fSPDTrackleter = NULL;
472     
473   delete fDiamondProfileSPD; fDiamondProfileSPD = NULL;
474   if (rec.fDiamondProfileSPD) fDiamondProfileSPD = new AliESDVertex(*rec.fDiamondProfileSPD);
475   delete fDiamondProfile; fDiamondProfile = NULL;
476   if (rec.fDiamondProfile) fDiamondProfile = new AliESDVertex(*rec.fDiamondProfile);
477   delete fDiamondProfileTPC; fDiamondProfileTPC = NULL;
478   if (rec.fDiamondProfileTPC) fDiamondProfileTPC = new AliESDVertex(*rec.fDiamondProfileTPC);
479
480   delete fListOfCosmicTriggers; fListOfCosmicTriggers = NULL;
481   if (rec.fListOfCosmicTriggers) fListOfCosmicTriggers = (THashTable*)((rec.fListOfCosmicTriggers)->Clone());
482
483   delete fGRPData; fGRPData = NULL;
484   //  if (rec.fGRPData) fGRPData = (TMap*)((rec.fGRPData)->Clone());
485   if (rec.fGRPData) fGRPData = (AliGRPObject*)((rec.fGRPData)->Clone());
486
487   delete fAlignObjArray; fAlignObjArray = NULL;
488
489   fCDBUri        = "";
490   fQARefUri      = rec.fQARefUri;
491   fSpecCDBUri.Delete();
492   fInitCDBCalled               = rec.fInitCDBCalled;
493   fSetRunNumberFromDataCalled  = rec.fSetRunNumberFromDataCalled;
494   fQADetectors                 = rec.fQADetectors;
495   fQATasks                     = rec.fQATasks; 
496   fRunQA                       = rec.fRunQA;  
497   fRunGlobalQA                 = rec.fRunGlobalQA;
498   fSameQACycle                 = rec.fSameQACycle;
499   fInitQACalled                = rec.fInitQACalled;
500   fWriteQAExpertData           = rec.fWriteQAExpertData;
501   fRunPlaneEff                 = rec.fRunPlaneEff;
502
503   fesd     = NULL;
504   fhltesd  = NULL;
505   fesdf    = NULL;
506   ffile    = NULL;
507   ftree    = NULL;
508   fhlttree = NULL;
509   ftVertexer = NULL;
510   fIsNewRunLoader = rec.fIsNewRunLoader;
511   fRunAliEVE = kFALSE;
512   fChain = NULL;
513
514   return *this;
515 }
516
517 //_____________________________________________________________________________
518 AliReconstruction::~AliReconstruction()
519 {
520 // clean up
521
522   CleanUp();
523   if (fListOfCosmicTriggers) {
524     fListOfCosmicTriggers->Delete();
525     delete fListOfCosmicTriggers;
526   }
527   delete fGRPData;
528   delete fRunScalers;
529   fOptions.Delete();
530   if (fAlignObjArray) {
531     fAlignObjArray->Delete();
532     delete fAlignObjArray;
533   }
534   fSpecCDBUri.Delete();
535
536   AliCodeTimer::Instance()->Print();
537 }
538
539 //_____________________________________________________________________________
540 void AliReconstruction::InitQA()
541 {
542   //Initialize the QA and start of cycle 
543   AliCodeTimerAuto("");
544   
545   if (fInitQACalled) return;
546   fInitQACalled = kTRUE;
547   
548   AliQAManager * qam = AliQAManager::QAManager(AliQAv1::kRECMODE) ; 
549   if (fWriteQAExpertData)
550     qam->SetWriteExpert() ; 
551  
552   if (qam->IsDefaultStorageSet()) {
553     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
554     AliWarning("Default QA reference storage has been already set !");
555     AliWarning(Form("Ignoring the default storage declared in AliReconstruction: %s",fQARefUri.Data()));
556     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
557     fQARefUri = qam->GetDefaultStorage()->GetURI();
558   } else {
559     if (fQARefUri.Length() > 0) {
560         AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
561         AliDebug(2, Form("Default QA reference storage is set to: %s", fQARefUri.Data()));
562         AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
563       } else {
564         fQARefUri="local://$ALICE_ROOT/QAref";
565         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
566         AliWarning("Default QA refeference storage not yet set !!!!");
567         AliWarning(Form("Setting it now to: %s", fQARefUri.Data()));
568         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
569                 
570       }
571     qam->SetDefaultStorage(fQARefUri);
572   }
573   
574   if (fRunQA) {
575   qam->SetActiveDetectors(fQADetectors) ; 
576   for (Int_t det = 0 ; det < AliQAv1::kNDET ; det++) {
577     qam->SetCycleLength(AliQAv1::DETECTORINDEX_t(det), fQACycles[det]) ;  
578     qam->SetWriteExpert(AliQAv1::DETECTORINDEX_t(det)) ;
579   }
580   if (!fRawReader && !fInput && fQATasks.Contains(AliQAv1::kRAWS))
581     fQATasks.ReplaceAll(Form("%d",AliQAv1::kRAWS), "") ;
582   qam->SetTasks(fQATasks) ; 
583   qam->InitQADataMaker(AliCDBManager::Instance()->GetRun()) ; 
584   }
585   if (fRunGlobalQA) {
586     Bool_t sameCycle = kFALSE ;
587     AliQADataMaker *qadm = qam->GetQADataMaker(AliQAv1::kGLOBAL);
588     AliInfo(Form("Initializing the global QA data maker"));
589     if (fQATasks.Contains(Form("%d", AliQAv1::kRECPOINTS))) {
590       qadm->StartOfCycle(AliQAv1::kRECPOINTS, AliCDBManager::Instance()->GetRun(), sameCycle) ; 
591       TObjArray **arr=qadm->Init(AliQAv1::kRECPOINTS);
592       AliTracker::SetResidualsArray(arr);
593       sameCycle = kTRUE ; 
594     }
595     if (fQATasks.Contains(Form("%d", AliQAv1::kESDS))) {
596       qadm->StartOfCycle(AliQAv1::kESDS, AliCDBManager::Instance()->GetRun(), sameCycle) ; 
597       qadm->Init(AliQAv1::kESDS);
598     }
599   }
600     AliSysInfo::AddStamp("InitQA") ; 
601 }
602
603 //_____________________________________________________________________________
604 void AliReconstruction::MergeQA(const char *fileName)
605 {
606   //Initialize the QA and start of cycle 
607   AliCodeTimerAuto("") ;
608   AliQAManager::QAManager()->Merge(AliCDBManager::Instance()->GetRun(),fileName) ; 
609   AliSysInfo::AddStamp("MergeQA") ; 
610 }
611   
612 //_____________________________________________________________________________
613 void AliReconstruction::InitCDB()
614 {
615 // activate a default CDB storage
616 // First check if we have any CDB storage set, because it is used 
617 // to retrieve the calibration and alignment constants
618   AliCodeTimerAuto("");
619
620   if (fInitCDBCalled) return;
621   fInitCDBCalled = kTRUE;
622
623   AliCDBManager* man = AliCDBManager::Instance();
624   if (man->IsDefaultStorageSet())
625   {
626     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
627     AliWarning("Default CDB storage has been already set !");
628     AliWarning(Form("Ignoring the default storage declared in AliReconstruction: %s",fCDBUri.Data()));
629     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
630     fCDBUri = man->GetDefaultStorage()->GetURI();
631   }
632   else {
633     if (fCDBUri.Length() > 0) 
634     {
635         AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
636         AliDebug(2, Form("Default CDB storage is set to: %s", fCDBUri.Data()));
637         AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
638     } else {
639         fCDBUri="local://$ALICE_ROOT/OCDB";
640         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
641         AliWarning("Default CDB storage not yet set !!!!");
642         AliWarning(Form("Setting it now to: %s", fCDBUri.Data()));
643         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
644                 
645     }
646     man->SetDefaultStorage(fCDBUri);
647   }
648
649   // Now activate the detector specific CDB storage locations
650   for (Int_t i = 0; i < fSpecCDBUri.GetEntriesFast(); i++) {
651     TObject* obj = fSpecCDBUri[i];
652     if (!obj) continue;
653     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
654     AliDebug(2, Form("Specific CDB storage for %s is set to: %s",obj->GetName(),obj->GetTitle()));
655     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
656     man->SetSpecificStorage(obj->GetName(), obj->GetTitle());
657   }
658   AliSysInfo::AddStamp("InitCDB");
659 }
660
661 //_____________________________________________________________________________
662 void AliReconstruction::SetDefaultStorage(const char* uri) {
663 // Store the desired default CDB storage location
664 // Activate it later within the Run() method
665
666   fCDBUri = uri;
667
668 }
669
670 //_____________________________________________________________________________
671 void AliReconstruction::SetQARefDefaultStorage(const char* uri) {
672   // Store the desired default CDB storage location
673   // Activate it later within the Run() method
674   
675   fQARefUri = uri;
676   AliQAv1::SetQARefStorage(fQARefUri.Data()) ;
677   
678 }
679 //_____________________________________________________________________________
680 void AliReconstruction::SetSpecificStorage(const char* calibType, const char* uri) {
681 // Store a detector-specific CDB storage location
682 // Activate it later within the Run() method
683
684   AliCDBPath aPath(calibType);
685   if(!aPath.IsValid()){
686         // if calibType is not wildcard but it is a valid detector, add "/*" to make it a valid path
687         for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
688                 if(!strcmp(calibType, fgkDetectorName[iDet])) {
689                         aPath.SetPath(Form("%s/*", calibType));
690                         AliInfo(Form("Path for specific storage set to %s", aPath.GetPath().Data()));
691                         break;
692                 }
693         }
694         if(!aPath.IsValid()){
695                 AliError(Form("Not a valid path or detector: %s", calibType));
696                 return;
697         }
698   }
699
700 //  // check that calibType refers to a "valid" detector name
701 //  Bool_t isDetector = kFALSE;
702 //  for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
703 //    TString detName = fgkDetectorName[iDet];
704 //    if(aPath.GetLevel0() == detName) {
705 //      isDetector = kTRUE;
706 //      break;
707 //    }
708 //  }
709 //
710 //  if(!isDetector) {
711 //      AliError(Form("Not a valid detector: %s", aPath.GetLevel0().Data()));
712 //      return;
713 //  }
714
715   TObject* obj = fSpecCDBUri.FindObject(aPath.GetPath().Data());
716   if (obj) fSpecCDBUri.Remove(obj);
717   fSpecCDBUri.Add(new TNamed(aPath.GetPath().Data(), uri));
718
719 }
720
721 //_____________________________________________________________________________
722 Bool_t AliReconstruction::SetRunNumberFromData()
723 {
724   // The method is called in Run() in order
725   // to set a correct run number.
726   // In case of raw data reconstruction the
727   // run number is taken from the raw data header
728
729   if (fSetRunNumberFromDataCalled) return kTRUE;
730   fSetRunNumberFromDataCalled = kTRUE;
731   
732   AliCDBManager* man = AliCDBManager::Instance();
733  
734   if(fRawReader) {
735     if(fRawReader->NextEvent()) {
736       if(man->GetRun() > 0) {
737         AliWarning("Run number is taken from raw-event header! Ignoring settings in AliCDBManager!");
738       } 
739       man->SetRun(fRawReader->GetRunNumber());
740       fRawReader->RewindEvents();
741     }
742     else {
743       if(man->GetRun() > 0) {
744         AliWarning("No raw-data events are found ! Using settings in AliCDBManager !");
745       }
746       else {
747         AliWarning("Neither raw events nor settings in AliCDBManager are found !");
748         return kFALSE;
749       }
750     }
751   }
752   else {
753     AliRunLoader *rl = AliRunLoader::Open(fGAliceFileName.Data());
754     if (!rl) {
755       AliError(Form("No run loader found in file %s", fGAliceFileName.Data()));
756       return kFALSE;
757     }
758     else {
759       rl->LoadHeader();
760       // read run number from gAlice
761       if(rl->GetHeader()) {
762         man->SetRun(rl->GetHeader()->GetRun());
763         rl->UnloadHeader();
764         delete rl;
765       }
766       else {
767         AliError("Neither run-loader header nor RawReader objects are found !");
768         delete rl;
769         return kFALSE;
770       }
771     }
772   }
773
774   man->Print();  
775   
776   return kTRUE;
777 }
778
779 //_____________________________________________________________________________
780 void AliReconstruction::SetCDBLock() {
781   // Set CDB lock: from now on it is forbidden to reset the run number
782   // or the default storage or to activate any further storage!
783   
784   AliCDBManager::Instance()->SetLock(1);
785 }
786
787 //_____________________________________________________________________________
788 Bool_t AliReconstruction::MisalignGeometry(const TString& detectors)
789 {
790   // Read the alignment objects from CDB.
791   // Each detector is supposed to have the
792   // alignment objects in DET/Align/Data CDB path.
793   // All the detector objects are then collected,
794   // sorted by geometry level (starting from ALIC) and
795   // then applied to the TGeo geometry.
796   // Finally an overlaps check is performed.
797
798   // Load alignment data from CDB and fill fAlignObjArray 
799   if(fLoadAlignFromCDB){
800         
801     TString detStr = detectors;
802     TString loadAlObjsListOfDets = "";
803     
804     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
805       if(!IsSelected(fgkDetectorName[iDet], detStr)) continue;
806       if(!strcmp(fgkDetectorName[iDet],"HLT")) continue;
807       
808       if(AliGeomManager::GetNalignable(fgkDetectorName[iDet]) != 0)
809       {
810         loadAlObjsListOfDets += fgkDetectorName[iDet];
811         loadAlObjsListOfDets += " ";
812       }
813     } // end loop over detectors
814     
815     if(AliGeomManager::GetNalignable("GRP") != 0)
816       loadAlObjsListOfDets.Prepend("GRP "); //add alignment objects for non-sensitive modules
817     AliGeomManager::ApplyAlignObjsFromCDB(loadAlObjsListOfDets.Data());
818     AliCDBManager::Instance()->UnloadFromCache("*/Align/*");
819   }else{
820     // Check if the array with alignment objects was
821     // provided by the user. If yes, apply the objects
822     // to the present TGeo geometry
823     if (fAlignObjArray) {
824       if (gGeoManager && gGeoManager->IsClosed()) {
825         if (AliGeomManager::ApplyAlignObjsToGeom(*fAlignObjArray) == kFALSE) {
826           AliError("The misalignment of one or more volumes failed!"
827                    "Compare the list of simulated detectors and the list of detector alignment data!");
828           return kFALSE;
829         }
830       }
831       else {
832         AliError("Can't apply the misalignment! gGeoManager doesn't exist or it is still opened!");
833         return kFALSE;
834       }
835     }
836   }
837   
838   if (fAlignObjArray) {
839     fAlignObjArray->Delete();
840     delete fAlignObjArray; fAlignObjArray=NULL;
841   }
842
843   return kTRUE;
844 }
845
846 //_____________________________________________________________________________
847 void AliReconstruction::SetGAliceFile(const char* fileName)
848 {
849 // set the name of the galice file
850
851   fGAliceFileName = fileName;
852 }
853
854 //_____________________________________________________________________________
855 void AliReconstruction::SetInput(const char* input) 
856 {
857   // In case the input string starts with 'mem://', we run in an online mode
858   // and AliRawReaderDateOnline object is created. In all other cases a raw-data
859   // file is assumed. One can give as an input:
860   // mem://: - events taken from DAQ monitoring libs online
861   //  or
862   // mem://<filename> - emulation of the above mode (via DATE monitoring libs)
863   if (input) fRawInput = input;
864 }
865
866 //_____________________________________________________________________________
867 void AliReconstruction::SetOutput(const char* output) 
868 {
869   // Set the output ESD filename
870   // 'output' is a normalt ROOT url
871   // The method is used in case of raw-data reco with PROOF
872   if (output) fESDOutput.SetUrl(output);
873 }
874
875 //_____________________________________________________________________________
876 void AliReconstruction::SetOption(const char* detector, const char* option)
877 {
878 // set options for the reconstruction of a detector
879
880   TObject* obj = fOptions.FindObject(detector);
881   if (obj) fOptions.Remove(obj);
882   fOptions.Add(new TNamed(detector, option));
883 }
884
885 //_____________________________________________________________________________
886 void AliReconstruction::SetRecoParam(const char* detector, AliDetectorRecoParam *par)
887 {
888   // Set custom reconstruction parameters for a given detector
889   // Single set of parameters for all the events
890
891   // First check if the reco-params are global
892   if(!strcmp(detector, "GRP")) {
893     par->SetAsDefault();
894     fRecoParam.AddDetRecoParam(kNDetectors,par);
895     return;
896   }
897
898   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
899     if(!strcmp(detector, fgkDetectorName[iDet])) {
900       par->SetAsDefault();
901       fRecoParam.AddDetRecoParam(iDet,par);
902       break;
903     }
904   }
905
906 }
907
908 //_____________________________________________________________________________
909 Bool_t AliReconstruction::SetFieldMap(Float_t l3Cur, Float_t diCur, Float_t l3Pol, 
910                                       Float_t diPol, Float_t beamenergy, 
911                                       const Char_t *beamtype, const Char_t *path) 
912 {
913   //------------------------------------------------
914   // The magnetic field map, defined externally...
915   // L3 current 30000 A  -> 0.5 T
916   // L3 current 12000 A  -> 0.2 T
917   // dipole current 6000 A
918   // The polarities must be the same
919   //------------------------------------------------
920   const Float_t l3NominalCurrent1=30000.; // (A)
921   const Float_t l3NominalCurrent2=12000.; // (A)
922   const Float_t diNominalCurrent =6000. ; // (A)
923
924   const Float_t tolerance=0.03; // relative current tolerance
925   const Float_t zero=77.;       // "zero" current (A)
926   //
927   TString s=(l3Pol < 0) ? "L3: -" : "L3: +";
928   //
929   AliMagF::BMap_t map = AliMagF::k5kG;
930   //
931   double fcL3,fcDip;
932   //
933   l3Cur = TMath::Abs(l3Cur);
934   if (TMath::Abs(l3Cur-l3NominalCurrent1)/l3NominalCurrent1 < tolerance) {
935     fcL3 = l3Cur/l3NominalCurrent1;
936     map  = AliMagF::k5kG;
937     s   += "0.5 T;  ";
938   } else if (TMath::Abs(l3Cur-l3NominalCurrent2)/l3NominalCurrent2 < tolerance) {
939     fcL3 = l3Cur/l3NominalCurrent2;
940     map  = AliMagF::k2kG;
941     s   += "0.2 T;  ";
942   } else if (l3Cur <= zero) {
943     fcL3 = 0;
944     map  = AliMagF::k5kGUniform;
945     s   += "0.0 T;  ";
946   } else {
947     AliError(Form("Wrong L3 current (%f A)!",l3Cur));
948     return kFALSE;
949   }
950   //
951   diCur = TMath::Abs(diCur);
952   if (TMath::Abs(diCur-diNominalCurrent)/diNominalCurrent < tolerance) {
953     // 3% current tolerance...
954     fcDip = diCur/diNominalCurrent;
955     s    += "Dipole ON";
956   } else if (diCur <= zero) { // some small current..
957     fcDip = 0.;
958     s    += "Dipole OFF";
959   } else {
960     AliError(Form("Wrong dipole current (%f A)!",diCur));
961     return kFALSE;
962   }
963   //
964   //
965   if (fcDip!=0 && (map==AliMagF::k5kG || map==AliMagF::k2kG) && 
966       ((AliMagF::GetPolarityConvention()==AliMagF::kConvMap2005 && l3Pol!=diPol) ||
967        (AliMagF::GetPolarityConvention()==AliMagF::kConvDCS2008 && l3Pol==diPol) ||
968        (AliMagF::GetPolarityConvention()==AliMagF::kConvLHC     && l3Pol!=diPol)) ) {
969     AliError(Form("Wrong combination for L3/Dipole polarities (%c/%c) for convention %d",
970                   l3Pol>0?'+':'-',diPol>0?'+':'-',AliMagF::GetPolarityConvention()));
971     return kFALSE;
972   }
973   //
974   if (l3Pol<0) fcL3  = -fcL3;
975   if (diPol<0) fcDip = -fcDip;
976   //
977   AliMagF::BeamType_t btype = AliMagF::kNoBeamField;
978   TString btypestr = beamtype;
979   btypestr.ToLower();
980   TPRegexp protonBeam("(proton|p)\\s*-?\\s*\\1");
981   TPRegexp ionBeam("(lead|pb|ion|a)\\s*-?\\s*\\1");
982   if (btypestr.Contains(ionBeam)) btype = AliMagF::kBeamTypeAA;
983   else if (btypestr.Contains(protonBeam)) btype = AliMagF::kBeamTypepp;
984   else {
985     AliInfo(Form("Cannot determine the beam type from %s, assume no LHC magnet field",beamtype));
986   }
987   
988   AliMagF* fld = new AliMagF("MagneticFieldMap", s.Data(), 2, fcL3, fcDip, 10., map, path, 
989                              btype,beamenergy);
990   TGeoGlobalMagField::Instance()->SetField( fld );
991   TGeoGlobalMagField::Instance()->Lock();
992   //
993   return kTRUE;
994 }
995
996
997 Bool_t AliReconstruction::InitGRP() {
998   //------------------------------------
999   // Initialization of the GRP entry 
1000   //------------------------------------
1001   AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/GRP/Data");
1002
1003   if (entry) {
1004
1005     TMap* m = dynamic_cast<TMap*>(entry->GetObject());  // old GRP entry
1006
1007     if (m) {
1008        AliInfo("Found a TMap in GRP/GRP/Data, converting it into an AliGRPObject");
1009        m->Print();
1010        fGRPData = new AliGRPObject();
1011        fGRPData->ReadValuesFromMap(m);
1012     }
1013
1014     else {
1015        AliInfo("Found an AliGRPObject in GRP/GRP/Data, reading it");
1016        fGRPData = dynamic_cast<AliGRPObject*>(entry->GetObject());  // new GRP entry
1017        entry->SetOwner(0);
1018     }
1019
1020     //    FIX ME: The unloading of GRP entry is temporarily disabled
1021     //    because ZDC and VZERO are using it in order to initialize
1022     //    their reconstructor objects. In the future one has to think
1023     //    of propagating AliRunInfo to the reconstructors.
1024     //    AliCDBManager::Instance()->UnloadFromCache("GRP/GRP/Data");
1025   }
1026
1027   if (!fGRPData) {
1028      AliError("No GRP entry found in OCDB!");
1029      return kFALSE;
1030   }
1031
1032   TString lhcState = fGRPData->GetLHCState();
1033   if (lhcState==AliGRPObject::GetInvalidString()) {
1034     AliError("GRP/GRP/Data entry:  missing value for the LHC state ! Using UNKNOWN");
1035     lhcState = "UNKNOWN";
1036   }
1037
1038   TString beamType = fGRPData->GetBeamType();
1039   if (beamType==AliGRPObject::GetInvalidString()) {
1040     AliError("GRP/GRP/Data entry:  missing value for the beam type ! Using UNKNOWN");
1041     beamType = "UNKNOWN";
1042   }
1043
1044   Float_t beamEnergy = fGRPData->GetBeamEnergy();
1045   if (beamEnergy==AliGRPObject::GetInvalidFloat()) {
1046     AliError("GRP/GRP/Data entry:  missing value for the beam energy ! Using 0");
1047     beamEnergy = 0;
1048   }
1049   // energy is provided in MeV*120
1050   beamEnergy /= 120E3;
1051
1052   TString runType = fGRPData->GetRunType();
1053   if (runType==AliGRPObject::GetInvalidString()) {
1054     AliError("GRP/GRP/Data entry:  missing value for the run type ! Using UNKNOWN");
1055     runType = "UNKNOWN";
1056   }
1057
1058   Int_t activeDetectors = fGRPData->GetDetectorMask();
1059   if (activeDetectors==AliGRPObject::GetInvalidUInt()) {
1060     AliError("GRP/GRP/Data entry:  missing value for the detector mask ! Using 1074790399");
1061     activeDetectors = 1074790399;
1062   }
1063
1064   fRunInfo = new AliRunInfo(lhcState, beamType, beamEnergy, runType, activeDetectors);
1065   fRunInfo->Dump();
1066
1067
1068   // Process the list of active detectors
1069   if (activeDetectors) {
1070     UInt_t detMask = activeDetectors;
1071     fRunLocalReconstruction = MatchDetectorList(fRunLocalReconstruction,detMask);
1072     fRunTracking = MatchDetectorList(fRunTracking,detMask);
1073     fFillESD = MatchDetectorList(fFillESD,detMask);
1074     fQADetectors = MatchDetectorList(fQADetectors,detMask);
1075     fLoadCDB.Form("%s %s %s %s",
1076                   fRunLocalReconstruction.Data(),
1077                   fRunTracking.Data(),
1078                   fFillESD.Data(),
1079                   fQADetectors.Data());
1080     fLoadCDB = MatchDetectorList(fLoadCDB,detMask);
1081     if (!((detMask >> AliDAQ::DetectorID("ITSSPD")) & 0x1)) {
1082       // switch off the vertexer
1083       AliInfo("SPD is not in the list of active detectors. Vertexer switched off.");
1084       fRunVertexFinder = kFALSE;
1085     }
1086     if (!((detMask >> AliDAQ::DetectorID("TRG")) & 0x1)) {
1087       // switch off the reading of CTP raw-data payload
1088       if (fFillTriggerESD) {
1089         AliInfo("CTP is not in the list of active detectors. CTP data reading switched off.");
1090         fFillTriggerESD = kFALSE;
1091       }
1092     }
1093   }
1094
1095   AliInfo("===================================================================================");
1096   AliInfo(Form("Running local reconstruction for detectors: %s",fRunLocalReconstruction.Data()));
1097   AliInfo(Form("Running tracking for detectors: %s",fRunTracking.Data()));
1098   AliInfo(Form("Filling ESD for detectors: %s",fFillESD.Data()));
1099   AliInfo(Form("Quality assurance is active for detectors: %s",fQADetectors.Data()));
1100   AliInfo(Form("CDB and reconstruction parameters are loaded for detectors: %s",fLoadCDB.Data()));
1101   AliInfo("===================================================================================");
1102
1103   //*** Dealing with the magnetic field map
1104   if ( TGeoGlobalMagField::Instance()->IsLocked() ) {AliInfo("Running with the externally locked B field !");}
1105   else {
1106     // Construct the field map out of the information retrieved from GRP.
1107     Bool_t ok = kTRUE;
1108     // L3
1109     Float_t l3Current = fGRPData->GetL3Current((AliGRPObject::Stats)0);
1110     if (l3Current == AliGRPObject::GetInvalidFloat()) {
1111       AliError("GRP/GRP/Data entry:  missing value for the L3 current !");
1112       ok = kFALSE;
1113     }
1114     
1115     Char_t l3Polarity = fGRPData->GetL3Polarity();
1116     if (l3Polarity == AliGRPObject::GetInvalidChar()) {
1117       AliError("GRP/GRP/Data entry:  missing value for the L3 polarity !");
1118       ok = kFALSE;
1119     }
1120
1121     // Dipole
1122     Float_t diCurrent = fGRPData->GetDipoleCurrent((AliGRPObject::Stats)0);
1123     if (diCurrent == AliGRPObject::GetInvalidFloat()) {
1124       AliError("GRP/GRP/Data entry:  missing value for the dipole current !");
1125       ok = kFALSE;
1126     }
1127
1128     Char_t diPolarity = fGRPData->GetDipolePolarity();
1129     if (diPolarity == AliGRPObject::GetInvalidChar()) {
1130       AliError("GRP/GRP/Data entry:  missing value for the dipole polarity !");
1131       ok = kFALSE;
1132     }
1133
1134     /*
1135     TObjString *l3Current=
1136        dynamic_cast<TObjString*>(fGRPData->GetValue("fL3Current"));
1137     if (!l3Current) {
1138       AliError("GRP/GRP/Data entry:  missing value for the L3 current !");
1139       ok = kFALSE;
1140     }
1141     TObjString *l3Polarity=
1142        dynamic_cast<TObjString*>(fGRPData->GetValue("fL3Polarity"));
1143     if (!l3Polarity) {
1144       AliError("GRP/GRP/Data entry:  missing value for the L3 polarity !");
1145       ok = kFALSE;
1146     }
1147     
1148     // Dipole
1149     TObjString *diCurrent=
1150        dynamic_cast<TObjString*>(fGRPData->GetValue("fDipoleCurrent"));
1151     if (!diCurrent) {
1152       AliError("GRP/GRP/Data entry:  missing value for the dipole current !");
1153       ok = kFALSE;
1154     }
1155     TObjString *diPolarity=
1156        dynamic_cast<TObjString*>(fGRPData->GetValue("fDipolePolarity"));
1157     if (!diPolarity) {
1158       AliError("GRP/GRP/Data entry:  missing value for the dipole polarity !");
1159       ok = kFALSE;
1160     }
1161     */
1162
1163     if (ok) { 
1164       if ( !SetFieldMap(l3Current, diCurrent, l3Polarity ? -1:1, diPolarity ? -1:1) )
1165         AliFatal("Failed to creat a B field map ! Exiting...");
1166       AliInfo("Running with the B field constructed out of GRP !");
1167     }
1168     else AliFatal("B field is neither set nor constructed from GRP ! Exitig...");
1169     
1170   }
1171   
1172   //*** Get the diamond profiles from OCDB
1173   entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexSPD");
1174   if (entry) {
1175     fDiamondProfileSPD = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1176   } else {
1177      AliError("No SPD diamond profile found in OCDB!");
1178   }
1179
1180   entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertex");
1181   if (entry) {
1182     fDiamondProfile = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1183   } else {
1184      AliError("No diamond profile found in OCDB!");
1185   }
1186
1187   entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexTPC");
1188   if (entry) {
1189     fDiamondProfileTPC = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1190   } else {
1191      AliError("No TPC diamond profile found in OCDB!");
1192   }
1193
1194   entry = AliCDBManager::Instance()->Get("GRP/Calib/CosmicTriggers");
1195   if (entry) {
1196     fListOfCosmicTriggers = dynamic_cast<THashTable*>(entry->GetObject());
1197     entry->SetOwner(0);
1198     AliCDBManager::Instance()->UnloadFromCache("GRP/Calib/CosmicTriggers");
1199   }
1200
1201   if (!fListOfCosmicTriggers) {
1202     AliWarning("Can not get list of cosmic triggers from OCDB! Cosmic event specie will be effectively disabled!");
1203   }
1204
1205   return kTRUE;
1206
1207
1208 //_____________________________________________________________________________
1209 Bool_t AliReconstruction::LoadCDB()
1210 {
1211   AliCodeTimerAuto("");
1212
1213   AliCDBManager::Instance()->Get("GRP/CTP/Config");
1214
1215   TString detStr = fLoadCDB;
1216   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1217     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1218     AliCDBManager::Instance()->GetAll(Form("%s/Calib/*",fgkDetectorName[iDet]));
1219   }
1220   return kTRUE;
1221 }
1222 //_____________________________________________________________________________
1223 Bool_t AliReconstruction::LoadTriggerScalersCDB()
1224 {
1225   AliCodeTimerAuto("");
1226
1227   AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/CTP/Scalers");
1228
1229   if (entry) { 
1230    
1231        AliInfo("Found an AliTriggerRunScalers in GRP/CTP/Scalers, reading it");
1232        fRunScalers = dynamic_cast<AliTriggerRunScalers*> (entry->GetObject());
1233        entry->SetOwner(0);
1234        if (fRunScalers->CorrectScalersOverflow() == 0) AliInfo("32bit Trigger counters corrected for overflow");
1235
1236   }
1237   return kTRUE;
1238 }
1239 //_____________________________________________________________________________
1240 Bool_t AliReconstruction::Run(const char* input)
1241 {
1242   // Run Run Run
1243   AliCodeTimerAuto("");
1244
1245   InitRun(input);
1246   if (GetAbort() != TSelector::kContinue) return kFALSE;
1247
1248   TChain *chain = NULL;
1249   if (fRawReader && (chain = fRawReader->GetChain())) {
1250     // Proof mode
1251     if (gProof) {
1252       gProof->AddInput(this);
1253       if (!fESDOutput.IsValid()) {
1254         fESDOutput.SetProtocol("root",kTRUE);
1255         fESDOutput.SetHost(gSystem->HostName());
1256         fESDOutput.SetFile(Form("%s/AliESDs.root",gSystem->pwd()));
1257       }
1258       AliInfo(Form("Output file with ESDs is %s",fESDOutput.GetUrl()));
1259       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",fESDOutput.GetUrl()));
1260       gProof->SetParameter("PROOF_MaxSlavesPerNode", 9999);
1261       chain->SetProof();
1262       chain->Process("AliReconstruction");
1263     }
1264     else {
1265       chain->Process(this);
1266     }
1267   }
1268   else {
1269     Begin(NULL);
1270     if (GetAbort() != TSelector::kContinue) return kFALSE;
1271     SlaveBegin(NULL);
1272     if (GetAbort() != TSelector::kContinue) return kFALSE;
1273     //******* The loop over events
1274     AliInfo("Starting looping over events");
1275     Int_t iEvent = 0;
1276     while ((iEvent < fRunLoader->GetNumberOfEvents()) ||
1277            (fRawReader && fRawReader->NextEvent())) {
1278       if (!ProcessEvent(iEvent)) {
1279         Abort("ProcessEvent",TSelector::kAbortFile);
1280         return kFALSE;
1281       }
1282       iEvent++;
1283     }
1284     SlaveTerminate();
1285     if (GetAbort() != TSelector::kContinue) return kFALSE;
1286     Terminate();
1287     if (GetAbort() != TSelector::kContinue) return kFALSE;
1288   }
1289
1290   return kTRUE;
1291 }
1292
1293 //_____________________________________________________________________________
1294 void AliReconstruction::InitRawReader(const char* input)
1295 {
1296   AliCodeTimerAuto("");
1297
1298   // Init raw-reader and
1299   // set the input in case of raw data
1300   if (input) fRawInput = input;
1301   fRawReader = AliRawReader::Create(fRawInput.Data());
1302   if (!fRawReader)
1303     AliInfo("Reconstruction will run over digits");
1304
1305   if (!fEquipIdMap.IsNull() && fRawReader)
1306     fRawReader->LoadEquipmentIdsMap(fEquipIdMap);
1307
1308   if (!fUseHLTData.IsNull()) {
1309     // create the RawReaderHLT which performs redirection of HLT input data for
1310     // the specified detectors
1311     AliRawReader* pRawReader=AliRawHLTManager::CreateRawReaderHLT(fRawReader, fUseHLTData.Data());
1312     if (pRawReader) {
1313       fParentRawReader=fRawReader;
1314       fRawReader=pRawReader;
1315     } else {
1316       AliError(Form("can not create Raw Reader for HLT input %s", fUseHLTData.Data()));
1317     }
1318   }
1319   AliSysInfo::AddStamp("CreateRawReader");
1320 }
1321
1322 //_____________________________________________________________________________
1323 void AliReconstruction::InitRun(const char* input)
1324 {
1325   // Initialization of raw-reader,
1326   // run number, CDB etc.
1327   AliCodeTimerAuto("");
1328   AliSysInfo::AddStamp("Start");
1329
1330   // Initialize raw-reader if any
1331   InitRawReader(input);
1332
1333   // Initialize the CDB storage
1334   InitCDB();
1335
1336   // Set run number in CDBManager (if it is not already set by the user)
1337   if (!SetRunNumberFromData()) {
1338     Abort("SetRunNumberFromData", TSelector::kAbortProcess);
1339     return;
1340   }
1341
1342   // Set CDB lock: from now on it is forbidden to reset the run number
1343   // or the default storage or to activate any further storage!
1344   SetCDBLock();
1345   
1346 }
1347
1348 //_____________________________________________________________________________
1349 void AliReconstruction::Begin(TTree *)
1350 {
1351   // Initialize AlReconstruction before
1352   // going into the event loop
1353   // Should follow the TSelector convention
1354   // i.e. initialize only the object on the client side
1355   AliCodeTimerAuto("");
1356
1357   AliReconstruction *reco = NULL;
1358   if (fInput) {
1359     if ((reco = (AliReconstruction*)fInput->FindObject("AliReconstruction"))) {
1360       *this = *reco;
1361     }
1362     AliSysInfo::AddStamp("ReadInputInBegin");
1363   }
1364
1365   // Import ideal TGeo geometry and apply misalignment
1366   if (!gGeoManager) {
1367     TString geom(gSystem->DirName(fGAliceFileName));
1368     geom += "/geometry.root";
1369     AliGeomManager::LoadGeometry(geom.Data());
1370     if (!gGeoManager) {
1371       Abort("LoadGeometry", TSelector::kAbortProcess);
1372       return;
1373     }
1374     AliSysInfo::AddStamp("LoadGeom");
1375     TString detsToCheck=fRunLocalReconstruction;
1376     if(!AliGeomManager::CheckSymNamesLUT(detsToCheck.Data())) {
1377       Abort("CheckSymNamesLUT", TSelector::kAbortProcess);
1378       return;
1379     }
1380     AliSysInfo::AddStamp("CheckGeom");
1381   }
1382
1383   if (!MisalignGeometry(fLoadAlignData)) {
1384     Abort("MisalignGeometry", TSelector::kAbortProcess);
1385     return;
1386   }
1387   AliCDBManager::Instance()->UnloadFromCache("GRP/Geometry/Data");
1388   AliSysInfo::AddStamp("MisalignGeom");
1389
1390   if (!InitGRP()) {
1391     Abort("InitGRP", TSelector::kAbortProcess);
1392     return;
1393   }
1394   AliSysInfo::AddStamp("InitGRP");
1395
1396   if (!LoadCDB()) {
1397     Abort("LoadCDB", TSelector::kAbortProcess);
1398     return;
1399   }
1400   AliSysInfo::AddStamp("LoadCDB");
1401
1402   if (!LoadTriggerScalersCDB()) {
1403     Abort("LoadTriggerScalersCDB", TSelector::kAbortProcess);
1404     return;
1405   }
1406   AliSysInfo::AddStamp("LoadTriggerScalersCDB");
1407
1408
1409   // Read the reconstruction parameters from OCDB
1410   if (!InitRecoParams()) {
1411     AliWarning("Not all detectors have correct RecoParam objects initialized");
1412   }
1413   AliSysInfo::AddStamp("InitRecoParams");
1414
1415   if (fInput && gProof) {
1416     if (reco) *reco = *this;
1417
1418     gProof->AddInputData(gGeoManager,kTRUE);
1419     gGeoManager = NULL;
1420     gProof->AddInputData(const_cast<TMap*>(AliCDBManager::Instance()->GetEntryCache()),kTRUE);
1421     fInput->Add(new TParameter<Int_t>("RunNumber",AliCDBManager::Instance()->GetRun()));
1422     AliMagF *magFieldMap = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
1423     magFieldMap->SetName("MagneticFieldMap");
1424     gProof->AddInputData(magFieldMap,kTRUE);
1425   }
1426
1427 }
1428
1429 //_____________________________________________________________________________
1430 void AliReconstruction::SlaveBegin(TTree*)
1431 {
1432   // Initialization related to run-loader,
1433   // vertexer, trackers, recontructors
1434   // In proof mode it is executed on the slave
1435   AliCodeTimerAuto("");
1436
1437   TProofOutputFile *outProofFile = NULL;
1438   if (fInput) { 
1439     if (AliReconstruction *reco = (AliReconstruction*)fInput->FindObject("AliReconstruction")) {
1440       *this = *reco;
1441     }
1442     if (TGeoManager *tgeo = (TGeoManager*)fInput->FindObject("Geometry")) {
1443       gGeoManager = tgeo;
1444       AliGeomManager::SetGeometry(tgeo);
1445     }
1446     if (TMap *entryCache = (TMap*)fInput->FindObject("CDBEntryCache")) {
1447       Int_t runNumber = -1;
1448       if (TProof::GetParameter(fInput,"RunNumber",runNumber) == 0) {
1449         AliCDBManager *man = AliCDBManager::Instance(entryCache,runNumber);
1450         man->SetCacheFlag(kTRUE);
1451         man->SetLock(kTRUE);
1452         man->Print();
1453       }
1454     }
1455     if (AliMagF *map = (AliMagF*)fInput->FindObject("MagneticFieldMap")) {
1456       TGeoGlobalMagField::Instance()->SetField(map);
1457     }
1458     if (TNamed *outputFileName = (TNamed *) fInput->FindObject("PROOF_OUTPUTFILE")) {
1459       outProofFile = new TProofOutputFile(gSystem->BaseName(TUrl(outputFileName->GetTitle()).GetFile()));
1460       outProofFile->SetOutputFileName(outputFileName->GetTitle());
1461       fOutput->Add(outProofFile);
1462     }
1463     AliSysInfo::AddStamp("ReadInputInSlaveBegin");
1464   }
1465
1466   // get the run loader
1467   if (!InitRunLoader()) {
1468     Abort("InitRunLoader", TSelector::kAbortProcess);
1469     return;
1470   }
1471   AliSysInfo::AddStamp("LoadLoader");
1472  
1473   ftVertexer = new AliVertexerTracks(AliTracker::GetBz());
1474
1475   // get trackers
1476   if (!fRunTracking.IsNull() && !CreateTrackers(fRunTracking)) {
1477     Abort("CreateTrackers", TSelector::kAbortProcess);
1478     return;
1479   }      
1480   AliSysInfo::AddStamp("CreateTrackers");
1481
1482   // create the ESD output file and tree
1483   if (!outProofFile) {
1484     ffile = TFile::Open("AliESDs.root", "RECREATE");
1485     ffile->SetCompressionLevel(2);
1486     if (!ffile->IsOpen()) {
1487       Abort("OpenESDFile", TSelector::kAbortProcess);
1488       return;
1489     }
1490   }
1491   else {
1492     if (!(ffile = outProofFile->OpenFile("RECREATE"))) {
1493       Abort(Form("Problems opening output PROOF file: %s/%s",
1494                  outProofFile->GetDir(), outProofFile->GetFileName()),
1495             TSelector::kAbortProcess);
1496       return;
1497     }
1498   }
1499
1500   ftree = new TTree("esdTree", "Tree with ESD objects");
1501   fesd = new AliESDEvent();
1502   fesd->CreateStdContent();
1503
1504   fesd->WriteToTree(ftree);
1505   if (fWriteESDfriend) {
1506     // careful:
1507     // Since we add the branch manually we must 
1508     // book and add it after WriteToTree
1509     // otherwise it is created twice,
1510     // once via writetotree and once here.
1511     // The case for AliESDfriend is now 
1512     // caught also in AlIESDEvent::WriteToTree but 
1513     // be careful when changing the name (AliESDfriend is not 
1514     // a TNamed so we had to hardwire it)
1515     fesdf = new AliESDfriend();
1516     TBranch *br=ftree->Branch("ESDfriend.","AliESDfriend", &fesdf);
1517     br->SetFile("AliESDfriends.root");
1518     fesd->AddObject(fesdf);
1519   }
1520   ftree->GetUserInfo()->Add(fesd);
1521
1522   fhlttree = new TTree("HLTesdTree", "Tree with HLT ESD objects");
1523   fhltesd = new AliESDEvent();
1524   fhltesd->CreateStdContent();
1525
1526   // read the ESD template from CDB
1527   // HLT is allowed to put non-std content to its ESD, the non-std
1528   // objects need to be created before invocation of WriteToTree in
1529   // order to create all branches. Initialization is done from an
1530   // ESD layout template in CDB
1531   AliCDBManager* man = AliCDBManager::Instance();
1532   AliCDBPath hltESDConfigPath("HLT/ConfigHLT/esdLayout");
1533   AliCDBEntry* hltESDConfig=NULL;
1534   if (man->GetId(hltESDConfigPath)!=NULL &&
1535       (hltESDConfig=man->Get(hltESDConfigPath))!=NULL) {
1536     AliESDEvent* pESDLayout=dynamic_cast<AliESDEvent*>(hltESDConfig->GetObject());
1537     if (pESDLayout) {
1538       // init all internal variables from the list of objects
1539       pESDLayout->GetStdContent();
1540
1541       // copy content and create non-std objects
1542       *fhltesd=*pESDLayout;
1543       fhltesd->Reset();
1544     } else {
1545       AliError(Form("error setting hltEsd layout from %s: invalid object type",
1546                     hltESDConfigPath.GetPath().Data()));
1547     }
1548   }
1549
1550   fhltesd->WriteToTree(fhlttree);
1551   fhlttree->GetUserInfo()->Add(fhltesd);
1552
1553   ProcInfo_t procInfo;
1554   gSystem->GetProcInfo(&procInfo);
1555   AliInfo(Form("Current memory usage %d %d", procInfo.fMemResident, procInfo.fMemVirtual));
1556   
1557   //QA
1558   //Initialize the QA and start of cycle 
1559   if (fRunQA || fRunGlobalQA) 
1560     InitQA() ; 
1561
1562   //Initialize the Plane Efficiency framework
1563   if (fRunPlaneEff && !InitPlaneEff()) {
1564     Abort("InitPlaneEff", TSelector::kAbortProcess);
1565     return;
1566   }
1567
1568   if (strcmp(gProgName,"alieve") == 0)
1569     fRunAliEVE = InitAliEVE();
1570
1571   return;
1572 }
1573
1574 //_____________________________________________________________________________
1575 Bool_t AliReconstruction::Process(Long64_t entry)
1576 {
1577   // run the reconstruction over a single entry
1578   // from the chain with raw data
1579   AliCodeTimerAuto("");
1580
1581   TTree *currTree = fChain->GetTree();
1582   AliRawVEvent *event = NULL;
1583   currTree->SetBranchAddress("rawevent",&event);
1584   currTree->GetEntry(entry);
1585   fRawReader = new AliRawReaderRoot(event);
1586   fStatus = ProcessEvent(fRunLoader->GetNumberOfEvents());  
1587   delete fRawReader;
1588   fRawReader = NULL;
1589   delete event;
1590
1591   return fStatus;
1592 }
1593
1594 //_____________________________________________________________________________
1595 void AliReconstruction::Init(TTree *tree)
1596 {
1597   if (tree == 0) {
1598     AliError("The input tree is not found!");
1599     return;
1600   }
1601   fChain = tree;
1602 }
1603
1604 //_____________________________________________________________________________
1605 Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
1606 {
1607   // run the reconstruction over a single event
1608   // The event loop is steered in Run method
1609
1610   AliCodeTimerAuto("");
1611
1612   if (iEvent >= fRunLoader->GetNumberOfEvents()) {
1613     fRunLoader->SetEventNumber(iEvent);
1614     fRunLoader->GetHeader()->Reset(fRawReader->GetRunNumber(), 
1615                                    iEvent, iEvent);
1616     fRunLoader->TreeE()->Fill();
1617     if (fRawReader && fRawReader->UseAutoSaveESD())
1618       fRunLoader->TreeE()->AutoSave("SaveSelf");
1619   }
1620
1621   if ((iEvent < fFirstEvent) || ((fLastEvent >= 0) && (iEvent > fLastEvent))) {
1622     return kTRUE;
1623   }
1624
1625   AliInfo(Form("processing event %d", iEvent));
1626
1627   fRunLoader->GetEvent(iEvent);
1628
1629   // Fill Event-info object
1630   GetEventInfo();
1631   fRecoParam.SetEventSpecie(fRunInfo,fEventInfo,fListOfCosmicTriggers);
1632   AliInfo(Form("Current event specie: %s",fRecoParam.PrintEventSpecie()));
1633
1634   // Set the reco-params
1635   {
1636     TString detStr = fLoadCDB;
1637     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1638       if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1639       AliReconstructor *reconstructor = GetReconstructor(iDet);
1640       if (reconstructor && fRecoParam.GetDetRecoParamArray(iDet)) {
1641         const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
1642         reconstructor->SetRecoParam(par);
1643         reconstructor->SetEventInfo(&fEventInfo);
1644         if (fRunQA) {
1645           AliQAManager::QAManager()->SetRecoParam(iDet, par) ; 
1646           AliQAManager::QAManager()->SetEventSpecie(AliRecoParam::Convert(par->GetEventSpecie())) ;
1647         }
1648       }
1649     }
1650   }
1651
1652     // QA on single raw 
1653   if (fRunQA) {
1654     AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
1655     AliQAManager::QAManager()->RunOneEvent(fRawReader) ;  
1656   }
1657     // local single event reconstruction
1658     if (!fRunLocalReconstruction.IsNull()) {
1659       TString detectors=fRunLocalReconstruction;
1660       // run HLT event reconstruction first
1661       // ;-( IsSelected changes the string
1662       if (IsSelected("HLT", detectors) &&
1663           !RunLocalEventReconstruction("HLT")) {
1664         if (fStopOnError) {CleanUp(); return kFALSE;}
1665       }
1666       detectors=fRunLocalReconstruction;
1667       detectors.ReplaceAll("HLT", "");
1668       if (!RunLocalEventReconstruction(detectors)) {
1669         if (fStopOnError) {CleanUp(); return kFALSE;}
1670       }
1671     }
1672
1673     fesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
1674     fhltesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
1675     fesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
1676     fhltesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
1677     
1678     // Set magnetic field from the tracker
1679     fesd->SetMagneticField(AliTracker::GetBz());
1680     fhltesd->SetMagneticField(AliTracker::GetBz());
1681
1682     // Set most probable pt, for B=0 tracking
1683     // Get the global reco-params. They are atposition 16 inside the array of detectors in fRecoParam
1684     const AliGRPRecoParam *grpRecoParam = dynamic_cast<const AliGRPRecoParam*>(fRecoParam.GetDetRecoParam(kNDetectors));
1685     if (grpRecoParam) AliExternalTrackParam::SetMostProbablePt(grpRecoParam->GetMostProbablePt());
1686     
1687     // Fill raw-data error log into the ESD
1688     if (fRawReader) FillRawDataErrorLog(iEvent,fesd);
1689
1690     // vertex finder
1691     if (fRunVertexFinder) {
1692       if (!RunVertexFinder(fesd)) {
1693         if (fStopOnError) {CleanUp(); return kFALSE;}
1694       }
1695     }
1696
1697     // For Plane Efficiency: run the SPD trackleter
1698     if (fRunPlaneEff && fSPDTrackleter) {
1699       if (!RunSPDTrackleting(fesd)) {
1700         if (fStopOnError) {CleanUp(); return kFALSE;}
1701       }
1702     }
1703
1704     // Muon tracking
1705     if (!fRunTracking.IsNull()) {
1706       if (fRunMuonTracking) {
1707         if (!RunMuonTracking(fesd)) {
1708           if (fStopOnError) {CleanUp(); return kFALSE;}
1709         }
1710       }
1711     }
1712
1713     // barrel tracking
1714     if (!fRunTracking.IsNull()) {
1715       if (!RunTracking(fesd)) {
1716         if (fStopOnError) {CleanUp(); return kFALSE;}
1717       }
1718     }
1719
1720     // fill ESD
1721     if (!fFillESD.IsNull()) {
1722       TString detectors=fFillESD;
1723       // run HLT first and on hltesd
1724       // ;-( IsSelected changes the string
1725       if (IsSelected("HLT", detectors) &&
1726           !FillESD(fhltesd, "HLT")) {
1727         if (fStopOnError) {CleanUp(); return kFALSE;}
1728       }
1729       detectors=fFillESD;
1730       // Temporary fix to avoid problems with HLT that overwrites the offline ESDs
1731       if (detectors.Contains("ALL")) {
1732         detectors="";
1733         for (Int_t idet=0; idet<kNDetectors; ++idet){
1734           detectors += fgkDetectorName[idet];
1735           detectors += " ";
1736         }
1737       }
1738       detectors.ReplaceAll("HLT", "");
1739       if (!FillESD(fesd, detectors)) {
1740         if (fStopOnError) {CleanUp(); return kFALSE;}
1741       }
1742     }
1743   
1744     // fill Event header information from the RawEventHeader
1745     if (fRawReader){FillRawEventHeaderESD(fesd);}
1746
1747     // combined PID
1748     AliESDpid::MakePID(fesd);
1749
1750     if (fFillTriggerESD) {
1751       if (!FillTriggerESD(fesd)) {
1752         if (fStopOnError) {CleanUp(); return kFALSE;}
1753       }
1754     }
1755
1756     ffile->cd();
1757
1758     //
1759     // Propagate track to the beam pipe  (if not already done by ITS)
1760     //
1761     const Int_t ntracks = fesd->GetNumberOfTracks();
1762     const Double_t kBz = fesd->GetMagneticField();
1763     const Double_t kRadius  = 2.8; //something less than the beam pipe radius
1764
1765     TObjArray trkArray;
1766     UShort_t *selectedIdx=new UShort_t[ntracks];
1767
1768     for (Int_t itrack=0; itrack<ntracks; itrack++){
1769       const Double_t kMaxStep = 1;   //max step over the material
1770       Bool_t ok;
1771
1772       AliESDtrack *track = fesd->GetTrack(itrack);
1773       if (!track) continue;
1774
1775       AliExternalTrackParam *tpcTrack =
1776            (AliExternalTrackParam *)track->GetTPCInnerParam();
1777       ok = kFALSE;
1778       if (tpcTrack)
1779         ok = AliTracker::
1780           PropagateTrackTo(tpcTrack,kRadius,track->GetMass(),kMaxStep,kFALSE);
1781
1782       if (ok) {
1783         Int_t n=trkArray.GetEntriesFast();
1784         selectedIdx[n]=track->GetID();
1785         trkArray.AddLast(tpcTrack);
1786       }
1787
1788       //Tracks refitted by ITS should already be at the SPD vertex
1789       if (track->IsOn(AliESDtrack::kITSrefit)) continue;
1790
1791       AliTracker::
1792          PropagateTrackTo(track,kRadius,track->GetMass(),kMaxStep,kFALSE);
1793       track->RelateToVertex(fesd->GetPrimaryVertexSPD(), kBz, kVeryBig);
1794
1795     }
1796
1797     //
1798     // Improve the reconstructed primary vertex position using the tracks
1799     //
1800     Bool_t runVertexFinderTracks = fRunVertexFinderTracks;
1801     if(fesd->GetPrimaryVertexSPD()) {
1802       TString vtitle = fesd->GetPrimaryVertexSPD()->GetTitle();
1803       if(vtitle.Contains("cosmics")) {
1804         runVertexFinderTracks=kFALSE;
1805       }
1806     }
1807
1808     if (runVertexFinderTracks) {
1809        // TPC + ITS primary vertex
1810        ftVertexer->SetITSMode();
1811        ftVertexer->SetConstraintOff();
1812        // get cuts for vertexer from AliGRPRecoParam
1813        if (grpRecoParam) {
1814          Int_t nCutsVertexer = grpRecoParam->GetVertexerTracksNCuts();
1815          Double_t *cutsVertexer = new Double_t[nCutsVertexer];
1816          grpRecoParam->GetVertexerTracksCutsITS(cutsVertexer);
1817          ftVertexer->SetCuts(cutsVertexer);
1818          delete [] cutsVertexer; cutsVertexer = NULL; 
1819          if(fDiamondProfile && grpRecoParam->GetVertexerTracksConstraintITS())
1820            ftVertexer->SetVtxStart(fDiamondProfile);
1821        }
1822        AliESDVertex *pvtx=ftVertexer->FindPrimaryVertex(fesd);
1823        if (pvtx) {
1824           if (pvtx->GetStatus()) {
1825              fesd->SetPrimaryVertexTracks(pvtx);
1826              for (Int_t i=0; i<ntracks; i++) {
1827                  AliESDtrack *t = fesd->GetTrack(i);
1828                  t->RelateToVertex(pvtx, kBz, kVeryBig);
1829              } 
1830           }
1831        }
1832
1833        // TPC-only primary vertex
1834        ftVertexer->SetTPCMode();
1835        ftVertexer->SetConstraintOff();
1836        // get cuts for vertexer from AliGRPRecoParam
1837        if (grpRecoParam) {
1838          Int_t nCutsVertexer = grpRecoParam->GetVertexerTracksNCuts();
1839          Double_t *cutsVertexer = new Double_t[nCutsVertexer];
1840          grpRecoParam->GetVertexerTracksCutsTPC(cutsVertexer);
1841          ftVertexer->SetCuts(cutsVertexer);
1842          delete [] cutsVertexer; cutsVertexer = NULL; 
1843          if(fDiamondProfileTPC && grpRecoParam->GetVertexerTracksConstraintTPC())
1844            ftVertexer->SetVtxStart(fDiamondProfileTPC);
1845        }
1846        pvtx=ftVertexer->FindPrimaryVertex(&trkArray,selectedIdx);
1847        if (pvtx) {
1848           if (pvtx->GetStatus()) {
1849              fesd->SetPrimaryVertexTPC(pvtx);
1850              for (Int_t i=0; i<ntracks; i++) {
1851                  AliESDtrack *t = fesd->GetTrack(i);
1852                  t->RelateToVertexTPC(pvtx, kBz, kVeryBig);
1853              } 
1854           }
1855        }
1856
1857     }
1858     delete[] selectedIdx;
1859
1860     if(fDiamondProfile) fesd->SetDiamond(fDiamondProfile);
1861     
1862
1863     if (fRunV0Finder) {
1864        // V0 finding
1865        AliV0vertexer vtxer;
1866        vtxer.Tracks2V0vertices(fesd);
1867
1868        if (fRunCascadeFinder) {
1869           // Cascade finding
1870           AliCascadeVertexer cvtxer;
1871           cvtxer.V0sTracks2CascadeVertices(fesd);
1872        }
1873     }
1874  
1875     // write ESD
1876     if (fCleanESD) CleanESD(fesd);
1877
1878   if (fRunQA) {
1879     AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
1880     AliQAManager::QAManager()->RunOneEvent(fesd) ; 
1881   }
1882   if (fRunGlobalQA) {
1883     AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
1884       qadm->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
1885     if (qadm && fQATasks.Contains(Form("%d", AliQAv1::kESDS)))
1886       qadm->Exec(AliQAv1::kESDS, fesd);
1887   }
1888
1889     if (fWriteESDfriend) {
1890       //      fesdf->~AliESDfriend();
1891       //  new (fesdf) AliESDfriend(); // Reset...
1892       fesd->GetESDfriend(fesdf);
1893     }
1894     ftree->Fill();
1895
1896     // Auto-save the ESD tree in case of prompt reco @P2
1897     if (fRawReader && fRawReader->UseAutoSaveESD()) {
1898       ftree->AutoSave("SaveSelf");
1899       TFile *friendfile = (TFile *)(gROOT->GetListOfFiles()->FindObject("AliESDfriends.root"));
1900       if (friendfile) friendfile->Save();
1901     }
1902
1903     // write HLT ESD
1904     fhlttree->Fill();
1905
1906     // call AliEVE
1907     if (fRunAliEVE) RunAliEVE();
1908
1909     fesd->Reset();
1910     fhltesd->Reset();
1911     if (fWriteESDfriend) {
1912       fesdf->~AliESDfriend();
1913       new (fesdf) AliESDfriend(); // Reset...
1914     }
1915  
1916     ProcInfo_t procInfo;
1917     gSystem->GetProcInfo(&procInfo);
1918     AliInfo(Form("Event %d -> Current memory usage %d %d",iEvent, procInfo.fMemResident, procInfo.fMemVirtual));
1919   
1920     fEventInfo.Reset();
1921     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1922       if (fReconstructor[iDet]) {
1923         fReconstructor[iDet]->SetRecoParam(NULL);
1924         fReconstructor[iDet]->SetEventInfo(NULL);
1925       }
1926       if (fTracker[iDet]) fTracker[iDet]->SetEventInfo(NULL);
1927     }
1928         
1929   if (fRunQA || fRunGlobalQA) 
1930     AliQAManager::QAManager()->Increment() ; 
1931   
1932     return kTRUE;
1933 }
1934
1935 //_____________________________________________________________________________
1936 void AliReconstruction::SlaveTerminate()
1937 {
1938   // Finalize the run on the slave side
1939   // Called after the exit
1940   // from the event loop
1941   AliCodeTimerAuto("");
1942
1943   if (fIsNewRunLoader) { // galice.root didn't exist
1944     fRunLoader->WriteHeader("OVERWRITE");
1945     fRunLoader->CdGAFile();
1946     fRunLoader->Write(0, TObject::kOverwrite);
1947   }
1948
1949   const TMap *cdbMap = AliCDBManager::Instance()->GetStorageMap();       
1950   const TList *cdbList = AliCDBManager::Instance()->GetRetrievedIds();   
1951                  
1952    TMap *cdbMapCopy = new TMap(cdbMap->GetEntries());    
1953    cdbMapCopy->SetOwner(1);      
1954    cdbMapCopy->SetName("cdbMap");        
1955    TIter iter(cdbMap->GetTable());       
1956          
1957    TPair* pair = 0;      
1958    while((pair = dynamic_cast<TPair*> (iter.Next()))){   
1959          TObjString* keyStr = dynamic_cast<TObjString*> (pair->Key());   
1960          TObjString* valStr = dynamic_cast<TObjString*> (pair->Value());         
1961          cdbMapCopy->Add(new TObjString(keyStr->GetName()), new TObjString(valStr->GetName()));  
1962    }     
1963          
1964    TList *cdbListCopy = new TList();     
1965    cdbListCopy->SetOwner(1);     
1966    cdbListCopy->SetName("cdbList");      
1967          
1968    TIter iter2(cdbList);         
1969          
1970         AliCDBId* id=0;
1971         while((id = dynamic_cast<AliCDBId*> (iter2.Next()))){    
1972          cdbListCopy->Add(new TObjString(id->ToString().Data()));        
1973    }     
1974          
1975    ftree->GetUserInfo()->Add(cdbMapCopy);        
1976    ftree->GetUserInfo()->Add(cdbListCopy);
1977
1978
1979   ffile->cd();
1980
1981   if (fWriteESDfriend)
1982     ftree->SetBranchStatus("ESDfriend*",0);
1983   // we want to have only one tree version number
1984   ftree->Write(ftree->GetName(),TObject::kOverwrite);
1985   fhlttree->Write();
1986
1987 // Finish with Plane Efficiency evaluation: before of CleanUp !!!
1988   if (fRunPlaneEff && !FinishPlaneEff()) {
1989    AliWarning("Finish PlaneEff evaluation failed");
1990   }
1991
1992   // End of cycle for the in-loop  
1993   if (fRunQA) 
1994     AliQAManager::QAManager()->EndOfCycle() ;
1995   
1996   if (fRunGlobalQA) {
1997     AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
1998     if (qadm) {
1999       if (fQATasks.Contains(Form("%d", AliQAv1::kRECPOINTS))) 
2000         qadm->EndOfCycle(AliQAv1::kRECPOINTS);
2001       if (fQATasks.Contains(Form("%d", AliQAv1::kESDS))) 
2002         qadm->EndOfCycle(AliQAv1::kESDS);
2003       qadm->Finish();
2004     }
2005   }
2006
2007   if (fRunQA || fRunGlobalQA) {
2008     if (fInput) { 
2009       if (TNamed *outputFileName = (TNamed *) fInput->FindObject("PROOF_OUTPUTFILE")) {
2010         TString qaOutputFile = outputFileName->GetTitle();
2011         qaOutputFile.ReplaceAll(gSystem->BaseName(TUrl(outputFileName->GetTitle()).GetFile()),
2012                                 Form("Merged.%s.Data.root",AliQAv1::GetQADataFileName()));
2013         TProofOutputFile *qaProofFile = new TProofOutputFile(Form("Merged.%s.Data.root",AliQAv1::GetQADataFileName()));
2014         qaProofFile->SetOutputFileName(qaOutputFile.Data());
2015         fOutput->Add(qaProofFile);
2016         MergeQA(qaProofFile->GetFileName());
2017       }
2018     }
2019     else {
2020       MergeQA();
2021     }
2022   }
2023
2024   gROOT->cd();
2025   CleanUp();
2026 }
2027     
2028 //_____________________________________________________________________________
2029 void AliReconstruction::Terminate()
2030 {
2031   // Create tags for the events in the ESD tree (the ESD tree is always present)
2032   // In case of empty events the tags will contain dummy values
2033   AliCodeTimerAuto("");
2034
2035   // Do not call the ESD tag creator in case of PROOF-based reconstruction
2036   if (!fInput) {
2037     AliESDTagCreator *esdtagCreator = new AliESDTagCreator();
2038     esdtagCreator->CreateESDTags(fFirstEvent,fLastEvent,fGRPData, AliQAv1::Instance()->GetQA(), AliQAv1::Instance()->GetEventSpecies(), AliQAv1::kNDET, AliRecoParam::kNSpecies);
2039   }
2040
2041   // Cleanup of CDB manager: cache and active storages!
2042   AliCDBManager::Instance()->ClearCache();
2043 }
2044
2045 //_____________________________________________________________________________
2046 Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
2047 {
2048 // run the local reconstruction
2049
2050   static Int_t eventNr=0;
2051   AliCodeTimerAuto("")
2052
2053   TString detStr = detectors;
2054   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2055     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2056     AliReconstructor* reconstructor = GetReconstructor(iDet);
2057     if (!reconstructor) continue;
2058     AliLoader* loader = fLoader[iDet];
2059     // Matthias April 2008: temporary fix to run HLT reconstruction
2060     // although the HLT loader is missing
2061     if (strcmp(fgkDetectorName[iDet], "HLT")==0) {
2062       if (fRawReader) {
2063         reconstructor->Reconstruct(fRawReader, NULL);
2064       } else {
2065         TTree* dummy=NULL;
2066         reconstructor->Reconstruct(dummy, NULL);
2067       }
2068       continue;
2069     }
2070     if (!loader) {
2071       AliWarning(Form("No loader is defined for %s!",fgkDetectorName[iDet]));
2072       continue;
2073     }
2074     // conversion of digits
2075     if (fRawReader && reconstructor->HasDigitConversion()) {
2076       AliInfo(Form("converting raw data digits into root objects for %s", 
2077                    fgkDetectorName[iDet]));
2078 //      AliCodeTimerAuto(Form("converting raw data digits into root objects for %s", 
2079 //                            fgkDetectorName[iDet]));
2080       loader->LoadDigits("update");
2081       loader->CleanDigits();
2082       loader->MakeDigitsContainer();
2083       TTree* digitsTree = loader->TreeD();
2084       reconstructor->ConvertDigits(fRawReader, digitsTree);
2085       loader->WriteDigits("OVERWRITE");
2086       loader->UnloadDigits();
2087     }
2088     // local reconstruction
2089     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
2090     //AliCodeTimerAuto(Form("running reconstruction for %s", fgkDetectorName[iDet]));
2091     loader->LoadRecPoints("update");
2092     loader->CleanRecPoints();
2093     loader->MakeRecPointsContainer();
2094     TTree* clustersTree = loader->TreeR();
2095     if (fRawReader && !reconstructor->HasDigitConversion()) {
2096       reconstructor->Reconstruct(fRawReader, clustersTree);
2097     } else {
2098       loader->LoadDigits("read");
2099       TTree* digitsTree = loader->TreeD();
2100       if (!digitsTree) {
2101         AliError(Form("Can't get the %s digits tree", fgkDetectorName[iDet]));
2102         if (fStopOnError) return kFALSE;
2103       } else {
2104         reconstructor->Reconstruct(digitsTree, clustersTree);
2105         if (fRunQA) {
2106           AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2107           AliQAManager::QAManager()->RunOneEventInOneDetector(iDet, digitsTree) ; 
2108         }
2109       }
2110       loader->UnloadDigits();
2111     }
2112                 if (fRunQA) {
2113       AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2114                         AliQAManager::QAManager()->RunOneEventInOneDetector(iDet, clustersTree) ; 
2115     }
2116     loader->WriteRecPoints("OVERWRITE");
2117     loader->UnloadRecPoints();
2118     AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr), iDet,1,eventNr);
2119   }
2120   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2121     AliError(Form("the following detectors were not found: %s",
2122                   detStr.Data()));
2123     if (fStopOnError) return kFALSE;
2124   }
2125   eventNr++;
2126   return kTRUE;
2127 }
2128 //_____________________________________________________________________________
2129 Bool_t AliReconstruction::RunSPDTrackleting(AliESDEvent*& esd)
2130 {
2131 // run the SPD trackleting (for SPD efficiency purpouses)
2132
2133   AliCodeTimerAuto("")
2134
2135   Double_t vtxPos[3] = {0, 0, 0};
2136   Double_t vtxErr[3] = {0.0, 0.0, 0.0};
2137 /*
2138   TArrayF mcVertex(3);
2139   // if(MC)
2140   if (fRunLoader->GetHeader() && fRunLoader->GetHeader()->GenEventHeader()) {
2141     fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(mcVertex);
2142     for (Int_t i = 0; i < 3; i++) vtxPos[i] = mcVertex[i];
2143   }
2144 */
2145   const AliESDVertex *vertex = esd->GetVertex();
2146   if(!vertex){
2147     AliWarning("Vertex not found");
2148     return kFALSE;
2149   }
2150   vertex->GetXYZ(vtxPos);
2151   vertex->GetSigmaXYZ(vtxErr);
2152   if (fSPDTrackleter) {
2153     AliInfo("running the SPD Trackleter for Plane Efficiency Evaluation");
2154
2155     // load clusters
2156     fLoader[0]->LoadRecPoints("read");
2157     TTree* tree = fLoader[0]->TreeR();
2158     if (!tree) {
2159       AliError("Can't get the ITS cluster tree");
2160       return kFALSE;
2161     }
2162     fSPDTrackleter->LoadClusters(tree);
2163     fSPDTrackleter->SetVertex(vtxPos, vtxErr);
2164     // run trackleting
2165     if (fSPDTrackleter->Clusters2Tracks(esd) != 0) {
2166       AliError("AliITSTrackleterSPDEff Clusters2Tracks failed");
2167      // fLoader[0]->UnloadRecPoints();
2168       return kFALSE;
2169     }
2170 //fSPDTrackleter->UnloadRecPoints();
2171   } else {
2172     AliWarning("SPDTrackleter not available");
2173     return kFALSE;
2174   }
2175   return kTRUE;
2176 }
2177
2178 //_____________________________________________________________________________
2179 Bool_t AliReconstruction::RunVertexFinder(AliESDEvent*& esd)
2180 {
2181 // run the barrel tracking
2182
2183   AliCodeTimerAuto("")
2184
2185   AliVertexer *vertexer = CreateVertexer();
2186   if (!vertexer) return kFALSE;
2187
2188   AliInfo("running the ITS vertex finder");
2189   AliESDVertex* vertex = NULL;
2190   if (fLoader[0]) {
2191     fLoader[0]->LoadRecPoints();
2192     TTree* cltree = fLoader[0]->TreeR();
2193     if (cltree) {
2194       if(fDiamondProfileSPD) vertexer->SetVtxStart(fDiamondProfileSPD);
2195       vertex = vertexer->FindVertexForCurrentEvent(cltree);
2196     }
2197     else {
2198       AliError("Can't get the ITS cluster tree");
2199     }
2200     fLoader[0]->UnloadRecPoints();
2201   }
2202   else {
2203     AliError("Can't get the ITS loader");
2204   }
2205   if(!vertex){
2206     AliWarning("Vertex not found");
2207     vertex = new AliESDVertex();
2208     vertex->SetName("default");
2209   }
2210   else {
2211     vertex->SetName("reconstructed");
2212   }
2213
2214   Double_t vtxPos[3];
2215   Double_t vtxErr[3];
2216   vertex->GetXYZ(vtxPos);
2217   vertex->GetSigmaXYZ(vtxErr);
2218
2219   esd->SetPrimaryVertexSPD(vertex);
2220   AliESDVertex *vpileup = NULL;
2221   Int_t novertices = 0;
2222   vpileup = vertexer->GetAllVertices(novertices);
2223   if(novertices>1){
2224     for (Int_t kk=1; kk<novertices; kk++)esd->AddPileupVertexSPD(&vpileup[kk]);
2225   }
2226   // if SPD multiplicity has been determined, it is stored in the ESD
2227   AliMultiplicity *mult = vertexer->GetMultiplicity();
2228   if(mult)esd->SetMultiplicity(mult);
2229
2230   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2231     if (fTracker[iDet]) fTracker[iDet]->SetVertex(vtxPos, vtxErr);
2232   }  
2233   delete vertex;
2234
2235   delete vertexer;
2236
2237   return kTRUE;
2238 }
2239
2240 //_____________________________________________________________________________
2241 Bool_t AliReconstruction::RunHLTTracking(AliESDEvent*& esd)
2242 {
2243 // run the HLT barrel tracking
2244
2245   AliCodeTimerAuto("")
2246
2247   if (!fRunLoader) {
2248     AliError("Missing runLoader!");
2249     return kFALSE;
2250   }
2251
2252   AliInfo("running HLT tracking");
2253
2254   // Get a pointer to the HLT reconstructor
2255   AliReconstructor *reconstructor = GetReconstructor(kNDetectors-1);
2256   if (!reconstructor) return kFALSE;
2257
2258   // TPC + ITS
2259   for (Int_t iDet = 1; iDet >= 0; iDet--) {
2260     TString detName = fgkDetectorName[iDet];
2261     AliDebug(1, Form("%s HLT tracking", detName.Data()));
2262     reconstructor->SetOption(detName.Data());
2263     AliTracker *tracker = reconstructor->CreateTracker();
2264     if (!tracker) {
2265       AliWarning(Form("couldn't create a HLT tracker for %s", detName.Data()));
2266       if (fStopOnError) return kFALSE;
2267       continue;
2268     }
2269     Double_t vtxPos[3];
2270     Double_t vtxErr[3]={0.005,0.005,0.010};
2271     const AliESDVertex *vertex = esd->GetVertex();
2272     vertex->GetXYZ(vtxPos);
2273     tracker->SetVertex(vtxPos,vtxErr);
2274     if(iDet != 1) {
2275       fLoader[iDet]->LoadRecPoints("read");
2276       TTree* tree = fLoader[iDet]->TreeR();
2277       if (!tree) {
2278         AliError(Form("Can't get the %s cluster tree", detName.Data()));
2279         return kFALSE;
2280       }
2281       tracker->LoadClusters(tree);
2282     }
2283     if (tracker->Clusters2Tracks(esd) != 0) {
2284       AliError(Form("HLT %s Clusters2Tracks failed", fgkDetectorName[iDet]));
2285       return kFALSE;
2286     }
2287     if(iDet != 1) {
2288       tracker->UnloadClusters();
2289     }
2290     delete tracker;
2291   }
2292
2293   return kTRUE;
2294 }
2295
2296 //_____________________________________________________________________________
2297 Bool_t AliReconstruction::RunMuonTracking(AliESDEvent*& esd)
2298 {
2299 // run the muon spectrometer tracking
2300
2301   AliCodeTimerAuto("")
2302
2303   if (!fRunLoader) {
2304     AliError("Missing runLoader!");
2305     return kFALSE;
2306   }
2307   Int_t iDet = 7; // for MUON
2308
2309   AliInfo("is running...");
2310
2311   // Get a pointer to the MUON reconstructor
2312   AliReconstructor *reconstructor = GetReconstructor(iDet);
2313   if (!reconstructor) return kFALSE;
2314
2315   
2316   TString detName = fgkDetectorName[iDet];
2317   AliDebug(1, Form("%s tracking", detName.Data()));
2318   AliTracker *tracker =  reconstructor->CreateTracker();
2319   if (!tracker) {
2320     AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
2321     return kFALSE;
2322   }
2323      
2324   // read RecPoints
2325   fLoader[iDet]->LoadRecPoints("read");  
2326
2327   tracker->LoadClusters(fLoader[iDet]->TreeR());
2328   
2329   Int_t rv = tracker->Clusters2Tracks(esd);
2330   
2331   if ( rv )
2332   {
2333     AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
2334     return kFALSE;
2335   }
2336   
2337   fLoader[iDet]->UnloadRecPoints();
2338
2339   tracker->UnloadClusters();
2340   
2341   delete tracker;
2342   
2343   return kTRUE;
2344 }
2345
2346
2347 //_____________________________________________________________________________
2348 Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd)
2349 {
2350 // run the barrel tracking
2351   static Int_t eventNr=0;
2352   AliCodeTimerAuto("")
2353
2354   AliInfo("running tracking");
2355
2356   // Set the event info which is used
2357   // by the trackers in order to obtain
2358   // information about read-out detectors,
2359   // trigger etc.
2360   AliDebug(1, "Setting event info");
2361   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2362     if (!fTracker[iDet]) continue;
2363     fTracker[iDet]->SetEventInfo(&fEventInfo);
2364   }
2365
2366   //Fill the ESD with the T0 info (will be used by the TOF) 
2367   if (fReconstructor[11] && fLoader[11]) {
2368     fLoader[11]->LoadRecPoints("READ");
2369     TTree *treeR = fLoader[11]->TreeR();
2370     if (treeR) {
2371       GetReconstructor(11)->FillESD((TTree *)NULL,treeR,esd);
2372     }
2373   }
2374
2375   // pass 1: TPC + ITS inwards
2376   for (Int_t iDet = 1; iDet >= 0; iDet--) {
2377     if (!fTracker[iDet]) continue;
2378     AliDebug(1, Form("%s tracking", fgkDetectorName[iDet]));
2379
2380     // load clusters
2381     fLoader[iDet]->LoadRecPoints("read");
2382     AliSysInfo::AddStamp(Form("RLoadCluster%s_%d",fgkDetectorName[iDet],eventNr),iDet,1, eventNr);
2383     TTree* tree = fLoader[iDet]->TreeR();
2384     if (!tree) {
2385       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
2386       return kFALSE;
2387     }
2388     fTracker[iDet]->LoadClusters(tree);
2389     AliSysInfo::AddStamp(Form("TLoadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
2390     // run tracking
2391     if (fTracker[iDet]->Clusters2Tracks(esd) != 0) {
2392       AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
2393       return kFALSE;
2394     }
2395     // preliminary PID in TPC needed by the ITS tracker
2396     if (iDet == 1) {
2397       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
2398       AliESDpid::MakePID(esd);
2399     } 
2400     AliSysInfo::AddStamp(Form("Tracking0%s_%d",fgkDetectorName[iDet],eventNr), iDet,3,eventNr);
2401   }
2402
2403   // pass 2: ALL backwards
2404
2405   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2406     if (!fTracker[iDet]) continue;
2407     AliDebug(1, Form("%s back propagation", fgkDetectorName[iDet]));
2408
2409     // load clusters
2410     if (iDet > 1) {     // all except ITS, TPC
2411       TTree* tree = NULL;
2412       fLoader[iDet]->LoadRecPoints("read");
2413       AliSysInfo::AddStamp(Form("RLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,1, eventNr);
2414       tree = fLoader[iDet]->TreeR();
2415       if (!tree) {
2416         AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
2417         return kFALSE;
2418       }
2419       fTracker[iDet]->LoadClusters(tree); 
2420       AliSysInfo::AddStamp(Form("TLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
2421     }
2422
2423     // run tracking
2424     if (iDet>1) // start filling residuals for the "outer" detectors
2425       if (fRunGlobalQA) {
2426         AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
2427         TObjArray ** arr = AliTracker::GetResidualsArray() ; 
2428         if (arr) {
2429           AliRecoParam::EventSpecie_t es=fRecoParam.GetEventSpecie();
2430           TObjArray * elem = arr[AliRecoParam::AConvert(es)];
2431           if ( elem && (! elem->At(0)) ) {
2432             AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
2433             if (qadm) qadm->InitRecPointsForTracker() ; 
2434           }
2435         }
2436       }
2437     if (fTracker[iDet]->PropagateBack(esd) != 0) {
2438       AliError(Form("%s backward propagation failed", fgkDetectorName[iDet]));
2439       //      return kFALSE;
2440     }
2441
2442     // unload clusters
2443     if (iDet > 3) {     // all except ITS, TPC, TRD and TOF
2444       fTracker[iDet]->UnloadClusters();
2445       fLoader[iDet]->UnloadRecPoints();
2446     }
2447     // updated PID in TPC needed by the ITS tracker -MI
2448     if (iDet == 1) {
2449       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
2450       AliESDpid::MakePID(esd);
2451     }
2452     AliSysInfo::AddStamp(Form("Tracking1%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
2453   }
2454   //stop filling residuals for the "outer" detectors
2455   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
2456
2457   // pass 3: TRD + TPC + ITS refit inwards
2458
2459   for (Int_t iDet = 2; iDet >= 0; iDet--) {
2460     if (!fTracker[iDet]) continue;
2461     AliDebug(1, Form("%s inward refit", fgkDetectorName[iDet]));
2462
2463     // run tracking
2464     if (iDet<2) // start filling residuals for TPC and ITS
2465       if (fRunGlobalQA) {
2466         AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
2467         TObjArray ** arr = AliTracker::GetResidualsArray() ; 
2468         if (arr) {
2469           AliRecoParam::EventSpecie_t es=fRecoParam.GetEventSpecie();
2470           TObjArray * elem = arr[AliRecoParam::AConvert(es)];
2471           if ( elem && (! elem->At(0)) ) {
2472             AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
2473             if (qadm) qadm->InitRecPointsForTracker() ; 
2474           }
2475         }
2476       }
2477     
2478     if (fTracker[iDet]->RefitInward(esd) != 0) {
2479       AliError(Form("%s inward refit failed", fgkDetectorName[iDet]));
2480       //      return kFALSE;
2481     }
2482     // run postprocessing
2483     if (fTracker[iDet]->PostProcess(esd) != 0) {
2484       AliError(Form("%s postprocessing failed", fgkDetectorName[iDet]));
2485       //      return kFALSE;
2486     }
2487     AliSysInfo::AddStamp(Form("Tracking2%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
2488   }
2489
2490   // write space-points to the ESD in case alignment data output
2491   // is switched on
2492   if (fWriteAlignmentData)
2493     WriteAlignmentData(esd);
2494
2495   for (Int_t iDet = 3; iDet >= 0; iDet--) {
2496     if (!fTracker[iDet]) continue;
2497     // unload clusters
2498     fTracker[iDet]->UnloadClusters();
2499     AliSysInfo::AddStamp(Form("TUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,4, eventNr);
2500     fLoader[iDet]->UnloadRecPoints();
2501     AliSysInfo::AddStamp(Form("RUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,5, eventNr);
2502   }
2503   // stop filling residuals for TPC and ITS
2504   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
2505
2506   eventNr++;
2507   return kTRUE;
2508 }
2509
2510 //_____________________________________________________________________________
2511 Bool_t AliReconstruction::CleanESD(AliESDEvent *esd){
2512   //
2513   // Remove the data which are not needed for the physics analysis.
2514   //
2515
2516   Int_t nTracks=esd->GetNumberOfTracks();
2517   Int_t nV0s=esd->GetNumberOfV0s();
2518   AliInfo
2519   (Form("Number of ESD tracks and V0s before cleaning: %d %d",nTracks,nV0s));
2520
2521   Float_t cleanPars[]={fV0DCAmax,fV0CsPmin,fDmax,fZmax};
2522   Bool_t rc=esd->Clean(cleanPars);
2523
2524   nTracks=esd->GetNumberOfTracks();
2525   nV0s=esd->GetNumberOfV0s();
2526   AliInfo
2527   (Form("Number of ESD tracks and V0s after cleaning %d %d",nTracks,nV0s));
2528
2529   return rc;
2530 }
2531
2532 //_____________________________________________________________________________
2533 Bool_t AliReconstruction::FillESD(AliESDEvent*& esd, const TString& detectors)
2534 {
2535 // fill the event summary data
2536
2537   AliCodeTimerAuto("")
2538     static Int_t eventNr=0; 
2539   TString detStr = detectors;
2540   
2541   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2542   if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2543     AliReconstructor* reconstructor = GetReconstructor(iDet);
2544     if (!reconstructor) continue;
2545     AliDebug(1, Form("filling ESD for %s", fgkDetectorName[iDet]));
2546     TTree* clustersTree = NULL;
2547     if (fLoader[iDet]) {
2548       fLoader[iDet]->LoadRecPoints("read");
2549       clustersTree = fLoader[iDet]->TreeR();
2550       if (!clustersTree) {
2551         AliError(Form("Can't get the %s clusters tree", 
2552                       fgkDetectorName[iDet]));
2553         if (fStopOnError) return kFALSE;
2554       }
2555     }
2556     if (fRawReader && !reconstructor->HasDigitConversion()) {
2557       reconstructor->FillESD(fRawReader, clustersTree, esd);
2558     } else {
2559       TTree* digitsTree = NULL;
2560       if (fLoader[iDet]) {
2561         fLoader[iDet]->LoadDigits("read");
2562         digitsTree = fLoader[iDet]->TreeD();
2563         if (!digitsTree) {
2564           AliError(Form("Can't get the %s digits tree", 
2565                         fgkDetectorName[iDet]));
2566           if (fStopOnError) return kFALSE;
2567         }
2568       }
2569       reconstructor->FillESD(digitsTree, clustersTree, esd);
2570       if (fLoader[iDet]) fLoader[iDet]->UnloadDigits();
2571     }
2572     if (fLoader[iDet]) {
2573       fLoader[iDet]->UnloadRecPoints();
2574     }
2575   }
2576
2577   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2578     AliError(Form("the following detectors were not found: %s", 
2579                   detStr.Data()));
2580     if (fStopOnError) return kFALSE;
2581   }
2582   AliSysInfo::AddStamp(Form("FillESD%d",eventNr), 0,1, eventNr);
2583   eventNr++;
2584   return kTRUE;
2585 }
2586
2587 //_____________________________________________________________________________
2588 Bool_t AliReconstruction::FillTriggerESD(AliESDEvent*& esd)
2589 {
2590   // Reads the trigger decision which is
2591   // stored in Trigger.root file and fills
2592   // the corresponding esd entries
2593
2594   AliCodeTimerAuto("")
2595   
2596   AliInfo("Filling trigger information into the ESD");
2597
2598   if (fRawReader) {
2599     AliCTPRawStream input(fRawReader);
2600     if (!input.Next()) {
2601       AliWarning("No valid CTP (trigger) DDL raw data is found ! The trigger info is taken from the event header!");
2602     }
2603     else {
2604       if (esd->GetTriggerMask() != input.GetClassMask())
2605         AliError(Form("Invalid trigger pattern found in CTP raw-data: %llx %llx",
2606                       input.GetClassMask(),esd->GetTriggerMask()));
2607       if (esd->GetOrbitNumber() != input.GetOrbitID())
2608         AliError(Form("Invalid orbit id found in CTP raw-data: %x %x",
2609                       input.GetOrbitID(),esd->GetOrbitNumber()));
2610       if (esd->GetBunchCrossNumber() != input.GetBCID())
2611         AliError(Form("Invalid bunch-crossing id found in CTP raw-data: %x %x",
2612                       input.GetBCID(),esd->GetBunchCrossNumber()));
2613       AliESDHeader* esdheader = esd->GetHeader();
2614       esdheader->SetL0TriggerInputs(input.GetL0Inputs());
2615       esdheader->SetL1TriggerInputs(input.GetL1Inputs());
2616       esdheader->SetL2TriggerInputs(input.GetL2Inputs());
2617       // IR
2618       UInt_t orbit=input.GetOrbitID();
2619        for(Int_t i=0 ; i<input.GetNIRs() ; i++ )
2620           if(TMath::Abs(Int_t(orbit-(input.GetIR(i))->GetOrbit()))<=1){
2621              esdheader->AddTriggerIR(input.GetIR(i));
2622           }
2623     }
2624   }
2625   //Scalers
2626   //fRunScalers->Print();
2627   if(fRunScalers && fRunScalers->CheckRunScalers()){
2628      AliTimeStamp* timestamp = new AliTimeStamp(esd->GetOrbitNumber(), esd->GetPeriodNumber(), esd->GetBunchCrossNumber());
2629      //AliTimeStamp* timestamp = new AliTimeStamp(10308000, 0, (ULong64_t)486238);
2630      AliESDHeader* esdheader = fesd->GetHeader();
2631      for(Int_t i=0;i<50;i++){
2632           if((1<<i) & esd->GetTriggerMask()){
2633           AliTriggerScalersESD* scalesd = fRunScalers->GetScalersForEventClass( timestamp, i+1);
2634           if(scalesd)esdheader->SetTriggerScalersRecord(scalesd);
2635         }
2636      }
2637   }
2638   return kTRUE;
2639 }
2640 //_____________________________________________________________________________
2641 Bool_t AliReconstruction::FillRawEventHeaderESD(AliESDEvent*& esd)
2642 {
2643   // 
2644   // Filling information from RawReader Header
2645   // 
2646
2647   if (!fRawReader) return kFALSE;
2648
2649   AliInfo("Filling information from RawReader Header");
2650
2651   esd->SetBunchCrossNumber(fRawReader->GetBCID());
2652   esd->SetOrbitNumber(fRawReader->GetOrbitID());
2653   esd->SetPeriodNumber(fRawReader->GetPeriod());
2654
2655   esd->SetTimeStamp(fRawReader->GetTimestamp());  
2656   esd->SetEventType(fRawReader->GetType());
2657
2658   return kTRUE;
2659 }
2660
2661
2662 //_____________________________________________________________________________
2663 Bool_t AliReconstruction::IsSelected(TString detName, TString& detectors) const
2664 {
2665 // check whether detName is contained in detectors
2666 // if yes, it is removed from detectors
2667
2668   // check if all detectors are selected
2669   if ((detectors.CompareTo("ALL") == 0) ||
2670       detectors.BeginsWith("ALL ") ||
2671       detectors.EndsWith(" ALL") ||
2672       detectors.Contains(" ALL ")) {
2673     detectors = "ALL";
2674     return kTRUE;
2675   }
2676
2677   // search for the given detector
2678   Bool_t result = kFALSE;
2679   if ((detectors.CompareTo(detName) == 0) ||
2680       detectors.BeginsWith(detName+" ") ||
2681       detectors.EndsWith(" "+detName) ||
2682       detectors.Contains(" "+detName+" ")) {
2683     detectors.ReplaceAll(detName, "");
2684     result = kTRUE;
2685   }
2686
2687   // clean up the detectors string
2688   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
2689   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
2690   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
2691
2692   return result;
2693 }
2694
2695 //_____________________________________________________________________________
2696 Bool_t AliReconstruction::InitRunLoader()
2697 {
2698 // get or create the run loader
2699
2700   if (gAlice) delete gAlice;
2701   gAlice = NULL;
2702
2703   if (!gSystem->AccessPathName(fGAliceFileName.Data())) { // galice.root exists
2704     // load all base libraries to get the loader classes
2705     TString libs = gSystem->GetLibraries();
2706     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2707       TString detName = fgkDetectorName[iDet];
2708       if (detName == "HLT") continue;
2709       if (libs.Contains("lib" + detName + "base.so")) continue;
2710       gSystem->Load("lib" + detName + "base.so");
2711     }
2712     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data());
2713     if (!fRunLoader) {
2714       AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
2715       CleanUp();
2716       return kFALSE;
2717     }
2718
2719     fRunLoader->CdGAFile();
2720     fRunLoader->LoadgAlice();
2721
2722     //PH This is a temporary fix to give access to the kinematics
2723     //PH that is needed for the labels of ITS clusters
2724     fRunLoader->LoadHeader();
2725     fRunLoader->LoadKinematics();
2726
2727   } else {               // galice.root does not exist
2728     if (!fRawReader) {
2729       AliError(Form("the file %s does not exist", fGAliceFileName.Data()));
2730     }
2731     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data(),
2732                                     AliConfig::GetDefaultEventFolderName(),
2733                                     "recreate");
2734     if (!fRunLoader) {
2735       AliError(Form("could not create run loader in file %s", 
2736                     fGAliceFileName.Data()));
2737       CleanUp();
2738       return kFALSE;
2739     }
2740     fIsNewRunLoader = kTRUE;
2741     fRunLoader->MakeTree("E");
2742
2743     if (fNumberOfEventsPerFile > 0)
2744       fRunLoader->SetNumberOfEventsPerFile(fNumberOfEventsPerFile);
2745     else
2746       fRunLoader->SetNumberOfEventsPerFile((UInt_t)-1);
2747   }
2748
2749   return kTRUE;
2750 }
2751
2752 //_____________________________________________________________________________
2753 AliReconstructor* AliReconstruction::GetReconstructor(Int_t iDet)
2754 {
2755 // get the reconstructor object and the loader for a detector
2756
2757   if (fReconstructor[iDet]) {
2758     if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
2759       const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
2760       fReconstructor[iDet]->SetRecoParam(par);
2761       fReconstructor[iDet]->SetRunInfo(fRunInfo);
2762     }
2763     return fReconstructor[iDet];
2764   }
2765
2766   // load the reconstructor object
2767   TPluginManager* pluginManager = gROOT->GetPluginManager();
2768   TString detName = fgkDetectorName[iDet];
2769   TString recName = "Ali" + detName + "Reconstructor";
2770
2771   if (!fIsNewRunLoader && !fRunLoader->GetLoader(detName+"Loader") && (detName != "HLT")) return NULL;
2772
2773   AliReconstructor* reconstructor = NULL;
2774   // first check if a plugin is defined for the reconstructor
2775   TPluginHandler* pluginHandler = 
2776     pluginManager->FindHandler("AliReconstructor", detName);
2777   // if not, add a plugin for it
2778   if (!pluginHandler) {
2779     AliDebug(1, Form("defining plugin for %s", recName.Data()));
2780     TString libs = gSystem->GetLibraries();
2781     if (libs.Contains("lib" + detName + "base.so") ||
2782         (gSystem->Load("lib" + detName + "base.so") >= 0)) {
2783       pluginManager->AddHandler("AliReconstructor", detName, 
2784                                 recName, detName + "rec", recName + "()");
2785     } else {
2786       pluginManager->AddHandler("AliReconstructor", detName, 
2787                                 recName, detName, recName + "()");
2788     }
2789     pluginHandler = pluginManager->FindHandler("AliReconstructor", detName);
2790   }
2791   if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
2792     reconstructor = (AliReconstructor*) pluginHandler->ExecPlugin(0);
2793   }
2794   if (reconstructor) {
2795     TObject* obj = fOptions.FindObject(detName.Data());
2796     if (obj) reconstructor->SetOption(obj->GetTitle());
2797     reconstructor->Init();
2798     fReconstructor[iDet] = reconstructor;
2799   }
2800
2801   // get or create the loader
2802   if (detName != "HLT") {
2803     fLoader[iDet] = fRunLoader->GetLoader(detName + "Loader");
2804     if (!fLoader[iDet]) {
2805       AliConfig::Instance()
2806         ->CreateDetectorFolders(fRunLoader->GetEventFolder(), 
2807                                 detName, detName);
2808       // first check if a plugin is defined for the loader
2809       pluginHandler = 
2810         pluginManager->FindHandler("AliLoader", detName);
2811       // if not, add a plugin for it
2812       if (!pluginHandler) {
2813         TString loaderName = "Ali" + detName + "Loader";
2814         AliDebug(1, Form("defining plugin for %s", loaderName.Data()));
2815         pluginManager->AddHandler("AliLoader", detName, 
2816                                   loaderName, detName + "base", 
2817                                   loaderName + "(const char*, TFolder*)");
2818         pluginHandler = pluginManager->FindHandler("AliLoader", detName);
2819       }
2820       if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
2821         fLoader[iDet] = 
2822           (AliLoader*) pluginHandler->ExecPlugin(2, detName.Data(), 
2823                                                  fRunLoader->GetEventFolder());
2824       }
2825       if (!fLoader[iDet]) {   // use default loader
2826         fLoader[iDet] = new AliLoader(detName, fRunLoader->GetEventFolder());
2827       }
2828       if (!fLoader[iDet]) {
2829         AliWarning(Form("couldn't get loader for %s", detName.Data()));
2830         if (fStopOnError) return NULL;
2831       } else {
2832         fRunLoader->AddLoader(fLoader[iDet]);
2833         fRunLoader->CdGAFile();
2834         if (gFile && !gFile->IsWritable()) gFile->ReOpen("UPDATE");
2835         fRunLoader->Write(0, TObject::kOverwrite);
2836       }
2837     }
2838   }
2839       
2840   if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
2841     const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
2842     reconstructor->SetRecoParam(par);
2843     reconstructor->SetRunInfo(fRunInfo);
2844   }
2845   return reconstructor;
2846 }
2847
2848 //_____________________________________________________________________________
2849 AliVertexer* AliReconstruction::CreateVertexer()
2850 {
2851 // create the vertexer
2852 // Please note that the caller is the owner of the
2853 // vertexer
2854
2855   AliVertexer* vertexer = NULL;
2856   AliReconstructor* itsReconstructor = GetReconstructor(0);
2857   if (itsReconstructor && ((fRunLocalReconstruction.Contains("ITS")) || fRunTracking.Contains("ITS"))) {
2858     vertexer = itsReconstructor->CreateVertexer();
2859   }
2860   if (!vertexer) {
2861     AliWarning("couldn't create a vertexer for ITS");
2862   }
2863
2864   return vertexer;
2865 }
2866
2867 //_____________________________________________________________________________
2868 Bool_t AliReconstruction::CreateTrackers(const TString& detectors)
2869 {
2870 // create the trackers
2871         AliInfo("Creating trackers");
2872
2873   TString detStr = detectors;
2874   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2875     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2876     AliReconstructor* reconstructor = GetReconstructor(iDet);
2877     if (!reconstructor) continue;
2878     TString detName = fgkDetectorName[iDet];
2879     if (detName == "HLT") {
2880       fRunHLTTracking = kTRUE;
2881       continue;
2882     }
2883     if (detName == "MUON") {
2884       fRunMuonTracking = kTRUE;
2885       continue;
2886     }
2887
2888
2889     fTracker[iDet] = reconstructor->CreateTracker();
2890     if (!fTracker[iDet] && (iDet < 7)) {
2891       AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
2892       if (fStopOnError) return kFALSE;
2893     }
2894     AliSysInfo::AddStamp(Form("LTracker%s",fgkDetectorName[iDet]), iDet,0);
2895   }
2896
2897   return kTRUE;
2898 }
2899
2900 //_____________________________________________________________________________
2901 void AliReconstruction::CleanUp()
2902 {
2903 // delete trackers and the run loader and close and delete the file
2904
2905   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2906     delete fReconstructor[iDet];
2907     fReconstructor[iDet] = NULL;
2908     fLoader[iDet] = NULL;
2909     delete fTracker[iDet];
2910     fTracker[iDet] = NULL;
2911   }
2912   delete fRunInfo;
2913   fRunInfo = NULL;
2914
2915   delete fSPDTrackleter;
2916   fSPDTrackleter = NULL;
2917
2918   delete ftVertexer;
2919   ftVertexer = NULL;
2920   
2921   delete fRunLoader;
2922   fRunLoader = NULL;
2923   delete fRawReader;
2924   fRawReader = NULL;
2925   delete fParentRawReader;
2926   fParentRawReader=NULL;
2927
2928   if (ffile) {
2929     ffile->Close();
2930     delete ffile;
2931     ffile = NULL;
2932   }
2933
2934   if (AliQAManager::QAManager())
2935     AliQAManager::QAManager()->ShowQA() ; 
2936   AliQAManager::Destroy() ; 
2937   
2938   TGeoGlobalMagField::Instance()->SetField(NULL);
2939 }
2940
2941 void AliReconstruction::WriteAlignmentData(AliESDEvent* esd)
2942 {
2943   // Write space-points which are then used in the alignment procedures
2944   // For the moment only ITS, TPC, TRD and TOF
2945
2946   Int_t ntracks = esd->GetNumberOfTracks();
2947   for (Int_t itrack = 0; itrack < ntracks; itrack++)
2948     {
2949       AliESDtrack *track = esd->GetTrack(itrack);
2950       Int_t nsp = 0;
2951       Int_t idx[200];
2952       for (Int_t i=0; i<200; ++i) idx[i] = -1; //PH avoid uninitialized values
2953       for (Int_t iDet = 5; iDet >= 0; iDet--) {// TOF, TRD, TPC, ITS clusters
2954           nsp += track->GetNcls(iDet);
2955
2956           if (iDet==0) { // ITS "extra" clusters
2957              track->GetClusters(iDet,idx);
2958              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nsp++;
2959           }  
2960       }
2961
2962       if (nsp) {
2963         AliTrackPointArray *sp = new AliTrackPointArray(nsp);
2964         track->SetTrackPointArray(sp);
2965         Int_t isptrack = 0;
2966         for (Int_t iDet = 5; iDet >= 0; iDet--) {
2967           AliTracker *tracker = fTracker[iDet];
2968           if (!tracker) continue;
2969           Int_t nspdet = track->GetClusters(iDet,idx);
2970
2971           if (iDet==0) // ITS "extra" clusters             
2972              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nspdet++;
2973
2974           if (nspdet <= 0) continue;
2975           AliTrackPoint p;
2976           Int_t isp = 0;
2977           Int_t isp2 = 0;
2978           while (isp2 < nspdet) {
2979             Bool_t isvalid=kTRUE;
2980
2981             Int_t index=idx[isp++];
2982             if (index < 0) continue;
2983
2984             TString dets = fgkDetectorName[iDet];
2985             if ((fUseTrackingErrorsForAlignment.CompareTo(dets) == 0) ||
2986             fUseTrackingErrorsForAlignment.BeginsWith(dets+" ") ||
2987             fUseTrackingErrorsForAlignment.EndsWith(" "+dets) ||
2988             fUseTrackingErrorsForAlignment.Contains(" "+dets+" ")) {
2989               isvalid = tracker->GetTrackPointTrackingError(index,p,track);
2990             } else {
2991               isvalid = tracker->GetTrackPoint(index,p); 
2992             } 
2993             isp2++;
2994             if (!isvalid) continue;
2995             if (iDet==0 && (isp-1)>=6) p.SetExtra();
2996             sp->AddPoint(isptrack,&p); isptrack++;
2997           }
2998         }       
2999       }
3000     }
3001 }
3002
3003 //_____________________________________________________________________________
3004 void AliReconstruction::FillRawDataErrorLog(Int_t iEvent, AliESDEvent* esd)
3005 {
3006   // The method reads the raw-data error log
3007   // accumulated within the rawReader.
3008   // It extracts the raw-data errors related to
3009   // the current event and stores them into
3010   // a TClonesArray inside the esd object.
3011
3012   if (!fRawReader) return;
3013
3014   for(Int_t i = 0; i < fRawReader->GetNumberOfErrorLogs(); i++) {
3015
3016     AliRawDataErrorLog *log = fRawReader->GetErrorLog(i);
3017     if (!log) continue;
3018     if (iEvent != log->GetEventNumber()) continue;
3019
3020     esd->AddRawDataErrorLog(log);
3021   }
3022
3023 }
3024
3025 //_____________________________________________________________________________
3026 void AliReconstruction::CheckQA()
3027 {
3028 // check the QA of SIM for this run and remove the detectors 
3029 // with status Fatal
3030   
3031 //      TString newRunLocalReconstruction ; 
3032 //      TString newRunTracking ;
3033 //      TString newFillESD ;
3034 //       
3035 //      for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
3036 //              TString detName(AliQAv1::GetDetName(iDet)) ;
3037 //              AliQAv1 * qa = AliQAv1::Instance(AliQAv1::DETECTORINDEX_t(iDet)) ;       
3038 //      if ( qa->IsSet(AliQAv1::DETECTORINDEX_t(iDet), AliQAv1::kSIM, specie, AliQAv1::kFATAL)) {
3039 //        AliInfo(Form("QA status for %s %s in Hits and/or SDIGITS  and/or Digits was Fatal; No reconstruction performed", 
3040 //                   detName.Data(), AliRecoParam::GetEventSpecieName(es))) ;
3041 //                      } else {
3042 //                      if ( fRunLocalReconstruction.Contains(AliQAv1::GetDetName(iDet)) || 
3043 //                                      fRunLocalReconstruction.Contains("ALL") )  {
3044 //                              newRunLocalReconstruction += detName ; 
3045 //                              newRunLocalReconstruction += " " ;                      
3046 //                      }
3047 //                      if ( fRunTracking.Contains(AliQAv1::GetDetName(iDet)) || 
3048 //                                      fRunTracking.Contains("ALL") )  {
3049 //                              newRunTracking += detName ; 
3050 //                              newRunTracking += " " ;                         
3051 //                      }
3052 //                      if ( fFillESD.Contains(AliQAv1::GetDetName(iDet)) || 
3053 //                                      fFillESD.Contains("ALL") )  {
3054 //                              newFillESD += detName ; 
3055 //                              newFillESD += " " ;                     
3056 //                      }
3057 //              }
3058 //      }
3059 //      fRunLocalReconstruction = newRunLocalReconstruction ; 
3060 //      fRunTracking            = newRunTracking ; 
3061 //      fFillESD                = newFillESD ; 
3062 }
3063
3064 //_____________________________________________________________________________
3065 Int_t AliReconstruction::GetDetIndex(const char* detector)
3066 {
3067   // return the detector index corresponding to detector
3068   Int_t index = -1 ; 
3069   for (index = 0; index < kNDetectors ; index++) {
3070     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
3071         break ; 
3072   }     
3073   return index ; 
3074 }
3075 //_____________________________________________________________________________
3076 Bool_t AliReconstruction::FinishPlaneEff() {
3077  //
3078  // Here execute all the necessary operationis, at the end of the tracking phase,
3079  // in case that evaluation of PlaneEfficiencies was required for some detector.
3080  // E.g., write into a DataBase file the PlaneEfficiency which have been evaluated.
3081  //
3082  // This Preliminary version works only FOR ITS !!!!!
3083  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3084  //
3085  //  Input: none
3086  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3087  //
3088  Bool_t ret=kFALSE;
3089  //for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
3090  for (Int_t iDet = 0; iDet < 1; iDet++) { // for the time being only ITS
3091    //if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3092    if(fTracker[iDet] && fTracker[iDet]->GetPlaneEff()) {
3093       AliPlaneEff *planeeff=fTracker[iDet]->GetPlaneEff();
3094       TString name=planeeff->GetName();
3095       name+=".root";
3096       TFile* pefile = TFile::Open(name, "RECREATE");
3097       ret=(Bool_t)planeeff->Write();
3098       pefile->Close();
3099       if(planeeff->GetCreateHistos()) {
3100         TString hname=planeeff->GetName();
3101         hname+="Histo.root";
3102         ret*=planeeff->WriteHistosToFile(hname,"RECREATE");
3103       }
3104    }
3105    if(fSPDTrackleter) {
3106      AliPlaneEff *planeeff=fSPDTrackleter->GetPlaneEff();
3107       TString name="AliITSPlaneEffSPDtracklet.root";
3108       TFile* pefile = TFile::Open(name, "RECREATE");
3109       ret=(Bool_t)planeeff->Write();
3110       pefile->Close();
3111       AliESDEvent *dummy=NULL;
3112       ret=(Bool_t)fSPDTrackleter->PostProcess(dummy); // take care of writing other files
3113    }
3114  }
3115  return ret;
3116 }
3117 //_____________________________________________________________________________
3118 Bool_t AliReconstruction::InitPlaneEff() {
3119 //
3120  // Here execute all the necessary operations, before of the tracking phase,
3121  // for the evaluation of PlaneEfficiencies, in case required for some detectors.
3122  // E.g., read from a DataBase file a first evaluation of the PlaneEfficiency
3123  // which should be updated/recalculated.
3124  //
3125  // This Preliminary version will work only FOR ITS !!!!!
3126  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3127  //
3128  //  Input: none
3129  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3130  //
3131  AliWarning(Form("Implementation of this method not yet completed !! Method return kTRUE"));
3132
3133   fSPDTrackleter = NULL;
3134   AliReconstructor* itsReconstructor = GetReconstructor(0);
3135   if (itsReconstructor) {
3136     fSPDTrackleter = itsReconstructor->CreateTrackleter(); // this is NULL unless required in RecoParam
3137   }
3138   if (fSPDTrackleter) { 
3139     AliInfo("Trackleter for SPD has been created");
3140   }
3141
3142  return kTRUE;
3143 }
3144
3145 //_____________________________________________________________________________
3146 Bool_t AliReconstruction::InitAliEVE()
3147 {
3148   // This method should be called only in case 
3149   // AliReconstruction is run
3150   // within the alieve environment.
3151   // It will initialize AliEVE in a way
3152   // so that it can visualize event processed
3153   // by AliReconstruction.
3154   // The return flag shows whenever the
3155   // AliEVE initialization was successful or not.
3156
3157   TString macroStr;
3158   macroStr.Form("%s/EVE/macros/alieve_online.C",gSystem->ExpandPathName("$ALICE_ROOT"));
3159   AliInfo(Form("Loading AliEVE macro: %s",macroStr.Data()));
3160   if (gROOT->LoadMacro(macroStr.Data()) != 0) return kFALSE;
3161
3162   gROOT->ProcessLine("if (!AliEveEventManager::GetMaster()){new AliEveEventManager();AliEveEventManager::GetMaster()->AddNewEventCommand(\"alieve_online_on_new_event()\");gEve->AddEvent(AliEveEventManager::GetMaster());};");
3163   gROOT->ProcessLine("alieve_online_init()");
3164
3165   return kTRUE;
3166 }
3167   
3168 //_____________________________________________________________________________
3169 void AliReconstruction::RunAliEVE()
3170 {
3171   // Runs AliEVE visualisation of
3172   // the current event.
3173   // Should be executed only after
3174   // successful initialization of AliEVE.
3175
3176   AliInfo("Running AliEVE...");
3177   gROOT->ProcessLine(Form("AliEveEventManager::GetMaster()->SetEvent((AliRunLoader*)0x%lx,(AliRawReader*)0x%lx,(AliESDEvent*)0x%lx,(AliESDfriend*)0x%lx);",fRunLoader,fRawReader,fesd,fesdf));
3178   gSystem->Run();
3179 }
3180
3181 //_____________________________________________________________________________
3182 Bool_t AliReconstruction::SetRunQA(TString detAndAction) 
3183 {
3184         // Allows to run QA for a selected set of detectors
3185         // and a selected set of tasks among RAWS, DIGITSR, RECPOINTS and ESDS
3186         // all selected detectors run the same selected tasks
3187         
3188         if (!detAndAction.Contains(":")) {
3189                 AliError( Form("%s is a wrong syntax, use \"DetectorList:ActionList\" \n", detAndAction.Data()) ) ;
3190                 fRunQA = kFALSE ;
3191                 return kFALSE ;                 
3192         }
3193         Int_t colon = detAndAction.Index(":") ; 
3194         fQADetectors = detAndAction(0, colon) ; 
3195         if (fQADetectors.Contains("ALL") )
3196                 fQADetectors = fFillESD ; 
3197                 fQATasks   = detAndAction(colon+1, detAndAction.Sizeof() ) ; 
3198         if (fQATasks.Contains("ALL") ) {
3199                 fQATasks = Form("%d %d %d %d", AliQAv1::kRAWS, AliQAv1::kDIGITSR, AliQAv1::kRECPOINTS, AliQAv1::kESDS) ; 
3200         } else {
3201                 fQATasks.ToUpper() ; 
3202                 TString tempo("") ; 
3203                 if ( fQATasks.Contains("RAW") ) 
3204                         tempo = Form("%d ", AliQAv1::kRAWS) ; 
3205                 if ( fQATasks.Contains("DIGIT") ) 
3206                         tempo += Form("%d ", AliQAv1::kDIGITSR) ; 
3207                 if ( fQATasks.Contains("RECPOINT") ) 
3208                         tempo += Form("%d ", AliQAv1::kRECPOINTS) ; 
3209                 if ( fQATasks.Contains("ESD") ) 
3210                         tempo += Form("%d ", AliQAv1::kESDS) ; 
3211                 fQATasks = tempo ; 
3212                 if (fQATasks.IsNull()) {
3213                         AliInfo("No QA requested\n")  ;
3214                         fRunQA = kFALSE ;
3215                         return kTRUE ; 
3216                 }
3217         }       
3218         TString tempo(fQATasks) ; 
3219         tempo.ReplaceAll(Form("%d", AliQAv1::kRAWS), AliQAv1::GetTaskName(AliQAv1::kRAWS))      ;
3220         tempo.ReplaceAll(Form("%d", AliQAv1::kDIGITSR), AliQAv1::GetTaskName(AliQAv1::kDIGITSR)) ;      
3221         tempo.ReplaceAll(Form("%d", AliQAv1::kRECPOINTS), AliQAv1::GetTaskName(AliQAv1::kRECPOINTS)) ;  
3222         tempo.ReplaceAll(Form("%d", AliQAv1::kESDS), AliQAv1::GetTaskName(AliQAv1::kESDS)) ;    
3223         AliInfo( Form("QA will be done on \"%s\" for \"%s\"\n", fQADetectors.Data(), tempo.Data()) ) ;  
3224         fRunQA = kTRUE ;
3225         return kTRUE; 
3226
3227
3228 //_____________________________________________________________________________
3229 Bool_t AliReconstruction::InitRecoParams() 
3230 {
3231   // The method accesses OCDB and retrieves all
3232   // the available reco-param objects from there.
3233
3234   Bool_t isOK = kTRUE;
3235
3236   if (fRecoParam.GetDetRecoParamArray(kNDetectors)) {
3237     AliInfo("Using custom GRP reconstruction parameters");
3238   }
3239   else {
3240     AliInfo("Loading GRP reconstruction parameter objects");
3241
3242     AliCDBPath path("GRP","Calib","RecoParam");
3243     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
3244     if(!entry){ 
3245       AliWarning("Couldn't find GRP RecoParam entry in OCDB");
3246       isOK = kFALSE;
3247     }
3248     else {
3249       TObject *recoParamObj = entry->GetObject();
3250       if (dynamic_cast<TObjArray*>(recoParamObj)) {
3251         // GRP has a normal TobjArray of AliDetectorRecoParam objects
3252         // Registering them in AliRecoParam
3253         fRecoParam.AddDetRecoParamArray(kNDetectors,dynamic_cast<TObjArray*>(recoParamObj));
3254       }
3255       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
3256         // GRP has only onse set of reco parameters
3257         // Registering it in AliRecoParam
3258         AliInfo("Single set of GRP reconstruction parameters found");
3259         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
3260         fRecoParam.AddDetRecoParam(kNDetectors,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
3261       }
3262       else {
3263         AliError("No valid GRP RecoParam object found in the OCDB");
3264         isOK = kFALSE;
3265       }
3266       entry->SetOwner(0);
3267     }
3268   }
3269
3270   TString detStr = fLoadCDB;
3271   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3272
3273     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3274
3275     if (fRecoParam.GetDetRecoParamArray(iDet)) {
3276       AliInfo(Form("Using custom reconstruction parameters for detector %s",fgkDetectorName[iDet]));
3277       continue;
3278     }
3279
3280     AliInfo(Form("Loading reconstruction parameter objects for detector %s",fgkDetectorName[iDet]));
3281   
3282     AliCDBPath path(fgkDetectorName[iDet],"Calib","RecoParam");
3283     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
3284     if(!entry){ 
3285       AliWarning(Form("Couldn't find RecoParam entry in OCDB for detector %s",fgkDetectorName[iDet]));
3286       isOK = kFALSE;
3287     }
3288     else {
3289       TObject *recoParamObj = entry->GetObject();
3290       if (dynamic_cast<TObjArray*>(recoParamObj)) {
3291         // The detector has a normal TobjArray of AliDetectorRecoParam objects
3292         // Registering them in AliRecoParam
3293         fRecoParam.AddDetRecoParamArray(iDet,dynamic_cast<TObjArray*>(recoParamObj));
3294       }
3295       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
3296         // The detector has only onse set of reco parameters
3297         // Registering it in AliRecoParam
3298         AliInfo(Form("Single set of reconstruction parameters found for detector %s",fgkDetectorName[iDet]));
3299         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
3300         fRecoParam.AddDetRecoParam(iDet,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
3301       }
3302       else {
3303         AliError(Form("No valid RecoParam object found in the OCDB for detector %s",fgkDetectorName[iDet]));
3304         isOK = kFALSE;
3305       }
3306       entry->SetOwner(0);
3307       //      FIX ME: We have to disable the unloading of reco-param CDB
3308       //      entries because QA framework is using them. Has to be fix in
3309       //      a way that the QA takes the objects already constructed in
3310       //      this method.
3311       //      AliCDBManager::Instance()->UnloadFromCache(path.GetPath());
3312     }
3313   }
3314
3315   if (AliDebugLevel() > 0) fRecoParam.Print();
3316
3317   return isOK;
3318 }
3319
3320 //_____________________________________________________________________________
3321 Bool_t AliReconstruction::GetEventInfo() 
3322 {
3323   // Fill the event info object
3324   // ...
3325   AliCodeTimerAuto("")
3326
3327   AliCentralTrigger *aCTP = NULL;
3328   if (fRawReader) {
3329     fEventInfo.SetEventType(fRawReader->GetType());
3330
3331     ULong64_t mask = fRawReader->GetClassMask();
3332     fEventInfo.SetTriggerMask(mask);
3333     UInt_t clmask = fRawReader->GetDetectorPattern()[0];
3334     fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(clmask));
3335
3336     aCTP = new AliCentralTrigger();
3337     TString configstr("");
3338     if (!aCTP->LoadConfiguration(configstr)) { // Load CTP config from OCDB
3339       AliError("No trigger configuration found in OCDB! The trigger configuration information will not be used!");
3340       delete aCTP;
3341       return kFALSE;
3342     }
3343     aCTP->SetClassMask(mask);
3344     aCTP->SetClusterMask(clmask);
3345   }
3346   else {
3347     fEventInfo.SetEventType(AliRawEventHeaderBase::kPhysicsEvent);
3348
3349     if (fRunLoader && (!fRunLoader->LoadTrigger())) {
3350       aCTP = fRunLoader->GetTrigger();
3351       fEventInfo.SetTriggerMask(aCTP->GetClassMask());
3352       // get inputs from actp - just get
3353       AliESDHeader* esdheader = fesd->GetHeader();
3354       esdheader->SetL0TriggerInputs(aCTP->GetL0TriggerInputs());
3355       esdheader->SetL1TriggerInputs(aCTP->GetL1TriggerInputs());
3356       esdheader->SetL2TriggerInputs(aCTP->GetL2TriggerInputs());
3357       fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(aCTP->GetClusterMask()));
3358     }
3359     else {
3360       AliWarning("No trigger can be loaded! The trigger information will not be used!");
3361       return kFALSE;
3362     }
3363   }
3364
3365   AliTriggerConfiguration *config = aCTP->GetConfiguration();
3366   if (!config) {
3367     AliError("No trigger configuration has been found! The trigger configuration information will not be used!");
3368     if (fRawReader) delete aCTP;
3369     return kFALSE;
3370   }
3371
3372   UChar_t clustmask = 0;
3373   TString trclasses;
3374   ULong64_t trmask = fEventInfo.GetTriggerMask();
3375   const TObjArray& classesArray = config->GetClasses();
3376   Int_t nclasses = classesArray.GetEntriesFast();
3377   for( Int_t iclass=0; iclass < nclasses; iclass++ ) {
3378     AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At(iclass);
3379     if (trclass) {
3380       Int_t trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
3381       fesd->SetTriggerClass(trclass->GetName(),trindex);
3382       if (fRawReader) fRawReader->LoadTriggerClass(trclass->GetName(),trindex);
3383       if (trmask & (1ull << trindex)) {
3384         trclasses += " ";
3385         trclasses += trclass->GetName();
3386         trclasses += " ";
3387         clustmask |= trclass->GetCluster()->GetClusterMask();
3388       }
3389     }
3390   }
3391   fEventInfo.SetTriggerClasses(trclasses);
3392
3393   // Set the information in ESD
3394   fesd->SetTriggerMask(trmask);
3395   fesd->SetTriggerCluster(clustmask);
3396
3397   if (!aCTP->CheckTriggeredDetectors()) {
3398     if (fRawReader) delete aCTP;
3399     return kFALSE;
3400   }    
3401
3402   if (fRawReader) delete aCTP;
3403
3404   // We have to fill also the HLT decision here!!
3405   // ...
3406
3407   return kTRUE;
3408 }
3409
3410 const char *AliReconstruction::MatchDetectorList(const char *detectorList, UInt_t detectorMask)
3411 {
3412   // Match the detector list found in the rec.C or the default 'ALL'
3413   // to the list found in the GRP (stored there by the shuttle PP which
3414   // gets the information from ECS)
3415   static TString resultList;
3416   TString detList = detectorList;
3417
3418   resultList = "";
3419
3420   for(Int_t iDet = 0; iDet < (AliDAQ::kNDetectors-1); iDet++) {
3421     if ((detectorMask >> iDet) & 0x1) {
3422       TString det = AliDAQ::OfflineModuleName(iDet);
3423       if ((detList.CompareTo("ALL") == 0) ||
3424           ((detList.BeginsWith("ALL ") ||
3425             detList.EndsWith(" ALL") ||
3426             detList.Contains(" ALL ")) &&
3427            !(detList.BeginsWith("-"+det+" ") ||
3428              detList.EndsWith(" -"+det) ||
3429              detList.Contains(" -"+det+" "))) ||
3430           (detList.CompareTo(det) == 0) ||
3431           detList.BeginsWith(det+" ") ||
3432           detList.EndsWith(" "+det) ||
3433           detList.Contains( " "+det+" " )) {
3434         if (!resultList.EndsWith(det + " ")) {
3435           resultList += det;
3436           resultList += " ";
3437         }
3438       }        
3439     }
3440   }
3441
3442   // HLT
3443   if ((detectorMask >> AliDAQ::kHLTId) & 0x1) {
3444     TString hltDet = AliDAQ::OfflineModuleName(AliDAQ::kNDetectors-1);
3445     if ((detList.CompareTo("ALL") == 0) ||
3446         ((detList.BeginsWith("ALL ") ||
3447           detList.EndsWith(" ALL") ||
3448           detList.Contains(" ALL ")) &&
3449          !(detList.BeginsWith("-"+hltDet+" ") ||