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