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