]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliReconstruction.cxx
Moving from ESDfriends to friends (A.Morsch)
[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("esdTree", "Tree with ESD Friend objects");
1512     fesdf  = new AliESDfriend();
1513     TBranch *br=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            ftVertexer->SetVtxStart(fDiamondProfile);
1874        }
1875        AliESDVertex *pvtx=ftVertexer->FindPrimaryVertex(fesd);
1876        if (pvtx) {
1877           if (pvtx->GetStatus()) {
1878              fesd->SetPrimaryVertexTracks(pvtx);
1879              for (Int_t i=0; i<ntracks; i++) {
1880                  AliESDtrack *t = fesd->GetTrack(i);
1881                  Double_t x[3]; t->GetXYZ(x);
1882                  Double_t b[3]; AliTracker::GetBxByBz(x,b);
1883                  t->RelateToVertexBxByBz(pvtx, b, kVeryBig);
1884              } 
1885           }
1886           delete pvtx; pvtx=NULL;
1887        }
1888
1889        // TPC-only primary vertex
1890        ftVertexer->SetTPCMode();
1891        ftVertexer->SetConstraintOff();
1892        // get cuts for vertexer from AliGRPRecoParam
1893        if (grpRecoParam) {
1894          Int_t nCutsVertexer = grpRecoParam->GetVertexerTracksNCuts();
1895          Double_t *cutsVertexer = new Double_t[nCutsVertexer];
1896          grpRecoParam->GetVertexerTracksCutsTPC(cutsVertexer);
1897          ftVertexer->SetCuts(cutsVertexer);
1898          delete [] cutsVertexer; cutsVertexer = NULL; 
1899          if(fDiamondProfileTPC && grpRecoParam->GetVertexerTracksConstraintTPC())
1900            ftVertexer->SetVtxStart(fDiamondProfileTPC);
1901        }
1902        pvtx=ftVertexer->FindPrimaryVertex(&trkArray,selectedIdx);
1903        if (pvtx) {
1904           if (pvtx->GetStatus()) {
1905              fesd->SetPrimaryVertexTPC(pvtx);
1906              for (Int_t i=0; i<ntracks; i++) {
1907                  AliESDtrack *t = fesd->GetTrack(i);
1908                  Double_t x[3]; t->GetXYZ(x);
1909                  Double_t b[3]; AliTracker::GetBxByBz(x,b);
1910                  t->RelateToVertexTPCBxByBz(pvtx, b, kVeryBig);
1911              } 
1912           }
1913           delete pvtx; pvtx=NULL;
1914        }
1915
1916     }
1917     delete[] selectedIdx;
1918
1919     if(fDiamondProfile) fesd->SetDiamond(fDiamondProfile);
1920     
1921
1922     if (fRunV0Finder) {
1923        // V0 finding
1924        AliV0vertexer vtxer;
1925        vtxer.Tracks2V0vertices(fesd);
1926
1927        if (fRunCascadeFinder) {
1928           // Cascade finding
1929           AliCascadeVertexer cvtxer;
1930           cvtxer.V0sTracks2CascadeVertices(fesd);
1931        }
1932     }
1933  
1934     // write ESD
1935     if (fCleanESD) CleanESD(fesd);
1936
1937   if (fRunQA && IsInTasks(AliQAv1::kESDS)) {
1938     AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
1939     AliQAManager::QAManager()->RunOneEvent(fesd, fhltesd) ; 
1940   }
1941   if (fRunGlobalQA) {
1942     AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
1943       qadm->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
1944     if (qadm && IsInTasks(AliQAv1::kESDS))
1945       qadm->Exec(AliQAv1::kESDS, fesd);
1946   }
1947
1948   // copy HLT decision from HLTesd to esd
1949   // the most relevant information is stored in a reduced container in the esd,
1950   // while the full information can be found in the HLTesd
1951   TObject* pHLTSrc=fhltesd->FindListObject(AliESDHLTDecision::Name());
1952   TObject* pHLTTgt=fesd->FindListObject(AliESDHLTDecision::Name());
1953   if (pHLTSrc && pHLTTgt) {
1954     pHLTSrc->Copy(*pHLTTgt);
1955   }
1956
1957     if (fWriteESDfriend) 
1958       fesd->GetESDfriend(fesdf);
1959
1960     ftree->Fill();
1961     if (fWriteESDfriend) ftreeF->Fill();
1962
1963     // Auto-save the ESD tree in case of prompt reco @P2
1964     if (fRawReader && fRawReader->UseAutoSaveESD()) {
1965       ftree->AutoSave("SaveSelf");
1966       if (fWriteESDfriend) ftreeF->AutoSave("SaveSelf");
1967       TFile *friendfile = (TFile *)(gROOT->GetListOfFiles()->FindObject("AliESDfriends.root"));
1968       if (friendfile) friendfile->Save();
1969     }
1970
1971     // write HLT ESD
1972     fhlttree->Fill();
1973
1974     // call AliEVE
1975     if (fRunAliEVE) RunAliEVE();
1976
1977     fesd->Reset();
1978     fhltesd->Reset();
1979     if (fWriteESDfriend) {
1980       fesdf->~AliESDfriend();
1981       new (fesdf) AliESDfriend(); // Reset...
1982     }
1983  
1984     gSystem->GetProcInfo(&procInfo);
1985     Long_t dMres=(procInfo.fMemResident-oldMres)/1024;
1986     Long_t dMvir=(procInfo.fMemVirtual-oldMvir)/1024;
1987     Float_t dCPU=procInfo.fCpuUser+procInfo.fCpuSys-oldCPU;
1988     aveDMres+=(dMres-aveDMres)/(iEvent-fFirstEvent+1);
1989     aveDMvir+=(dMvir-aveDMvir)/(iEvent-fFirstEvent+1);
1990     aveDCPU+=(dCPU-aveDCPU)/(iEvent-fFirstEvent+1);
1991     AliInfo(Form("======================= End Event %d: Res %d(%3d <%3d>) Vir %d(%3d <%3d>) CPU %5.2f <%5.2f> ===================",
1992                  iEvent, procInfo.fMemResident/1024, dMres, aveDMres, procInfo.fMemVirtual/1024, dMvir, aveDMvir, dCPU, aveDCPU));
1993     oldMres=procInfo.fMemResident;
1994     oldMvir=procInfo.fMemVirtual;
1995     oldCPU=procInfo.fCpuUser+procInfo.fCpuSys;
1996   
1997     fEventInfo.Reset();
1998     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1999       if (fReconstructor[iDet]) {
2000         fReconstructor[iDet]->SetRecoParam(NULL);
2001         fReconstructor[iDet]->SetEventInfo(NULL);
2002       }
2003       if (fTracker[iDet]) fTracker[iDet]->SetEventInfo(NULL);
2004     }
2005         
2006   if (fRunQA || fRunGlobalQA) 
2007     AliQAManager::QAManager()->Increment() ; 
2008   
2009     return kTRUE;
2010 }
2011
2012 //_____________________________________________________________________________
2013 void AliReconstruction::SlaveTerminate()
2014 {
2015   // Finalize the run on the slave side
2016   // Called after the exit
2017   // from the event loop
2018   AliCodeTimerAuto("",0);
2019
2020   if (fIsNewRunLoader) { // galice.root didn't exist
2021     fRunLoader->WriteHeader("OVERWRITE");
2022     fRunLoader->CdGAFile();
2023     fRunLoader->Write(0, TObject::kOverwrite);
2024   }
2025
2026   const TMap *cdbMap = AliCDBManager::Instance()->GetStorageMap();       
2027   const TList *cdbList = AliCDBManager::Instance()->GetRetrievedIds();   
2028                  
2029    TMap *cdbMapCopy = new TMap(cdbMap->GetEntries());    
2030    cdbMapCopy->SetOwner(1);      
2031    cdbMapCopy->SetName("cdbMap");        
2032    TIter iter(cdbMap->GetTable());       
2033          
2034    TPair* pair = 0;      
2035    while((pair = dynamic_cast<TPair*> (iter.Next()))){   
2036          TObjString* keyStr = dynamic_cast<TObjString*> (pair->Key());   
2037          TObjString* valStr = dynamic_cast<TObjString*> (pair->Value());         
2038          cdbMapCopy->Add(new TObjString(keyStr->GetName()), new TObjString(valStr->GetName()));  
2039    }     
2040          
2041    TList *cdbListCopy = new TList();     
2042    cdbListCopy->SetOwner(1);     
2043    cdbListCopy->SetName("cdbList");      
2044          
2045    TIter iter2(cdbList);         
2046          
2047         AliCDBId* id=0;
2048         while((id = dynamic_cast<AliCDBId*> (iter2.Next()))){    
2049          cdbListCopy->Add(new TObjString(id->ToString().Data()));        
2050    }     
2051          
2052    ftree->GetUserInfo()->Add(cdbMapCopy);        
2053    ftree->GetUserInfo()->Add(cdbListCopy);
2054
2055
2056   ffile->cd();
2057
2058   // we want to have only one tree version number
2059   ftree->Write(ftree->GetName(),TObject::kOverwrite);
2060   fhlttree->Write(fhlttree->GetName(),TObject::kOverwrite);
2061
2062   if (fWriteESDfriend) {
2063     ffileF->cd();
2064     ftreeF->Write(ftreeF->GetName(),TObject::kOverwrite);
2065   }
2066
2067 // Finish with Plane Efficiency evaluation: before of CleanUp !!!
2068   if (fRunPlaneEff && !FinishPlaneEff()) {
2069    AliWarning("Finish PlaneEff evaluation failed");
2070   }
2071
2072   // End of cycle for the in-loop  
2073
2074   if (fRunQA || fRunGlobalQA) {
2075     AliQAManager::QAManager()->EndOfCycle() ;
2076     if (fInput &&
2077         !fProofOutputLocation.IsNull() &&
2078         fProofOutputArchive.IsNull() &&
2079         !fProofOutputDataset) {
2080       TString qaOutputFile(Form("%sMerged.%s.Data.root",
2081                                 fProofOutputLocation.Data(),
2082                                 AliQAv1::GetQADataFileName()));
2083       TProofOutputFile *qaProofFile = new TProofOutputFile(Form("Merged.%s.Data.root",
2084                                                                 AliQAv1::GetQADataFileName()));
2085       qaProofFile->SetOutputFileName(qaOutputFile.Data());
2086       if (AliDebugLevel() > 0) qaProofFile->Dump();
2087       fOutput->Add(qaProofFile);
2088       MergeQA(qaProofFile->GetFileName());
2089     }
2090     else {
2091       MergeQA();
2092     }
2093   }
2094
2095   gROOT->cd();
2096   CleanUp();
2097
2098   if (fInput) {
2099     if (!fProofOutputFileName.IsNull() &&
2100         !fProofOutputLocation.IsNull() &&
2101         fProofOutputDataset &&
2102         !fProofOutputArchive.IsNull()) {
2103       TProofOutputFile *zipProofFile = new TProofOutputFile(fProofOutputFileName.Data(),
2104                                                             "DROV",
2105                                                             fProofOutputLocation.Data());
2106       if (AliDebugLevel() > 0) zipProofFile->Dump();
2107       fOutput->Add(zipProofFile);
2108       TString fileList(fProofOutputArchive.Data());
2109       fileList.ReplaceAll(","," ");
2110       TString command;
2111 #if ROOT_SVN_REVISION >= 30174
2112       command.Form("zip -n root %s/%s %s",zipProofFile->GetDir(kTRUE),zipProofFile->GetFileName(),fileList.Data());
2113 #else
2114       command.Form("zip -n root %s/%s %s",zipProofFile->GetDir(),zipProofFile->GetFileName(),fileList.Data());
2115 #endif
2116       AliInfo(Form("Executing: %s",command.Data()));
2117       gSystem->Exec(command.Data());
2118     }
2119   }
2120 }
2121     
2122 //_____________________________________________________________________________
2123 void AliReconstruction::Terminate()
2124 {
2125   // Create tags for the events in the ESD tree (the ESD tree is always present)
2126   // In case of empty events the tags will contain dummy values
2127   AliCodeTimerAuto("",0);
2128
2129   // Do not call the ESD tag creator in case of PROOF-based reconstruction
2130   if (!fInput) {
2131     AliESDTagCreator *esdtagCreator = new AliESDTagCreator();
2132     esdtagCreator->CreateESDTags(fFirstEvent,fLastEvent,fGRPData, AliQAv1::Instance()->GetQA(), AliQAv1::Instance()->GetEventSpecies(), AliQAv1::kNDET, AliRecoParam::kNSpecies);
2133     delete esdtagCreator;
2134   }
2135
2136   // Cleanup of CDB manager: cache and active storages!
2137   AliCDBManager::Instance()->ClearCache();
2138 }
2139
2140 //_____________________________________________________________________________
2141 Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
2142 {
2143 // run the local reconstruction
2144
2145   static Int_t eventNr=0;
2146   AliCodeTimerAuto("",0)
2147
2148   TString detStr = detectors;
2149   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2150     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2151     AliReconstructor* reconstructor = GetReconstructor(iDet);
2152     if (!reconstructor) continue;
2153     AliLoader* loader = fLoader[iDet];
2154     // Matthias April 2008: temporary fix to run HLT reconstruction
2155     // although the HLT loader is missing
2156     if (strcmp(fgkDetectorName[iDet], "HLT")==0) {
2157       if (fRawReader) {
2158         reconstructor->Reconstruct(fRawReader, NULL);
2159       } else {
2160         TTree* dummy=NULL;
2161         reconstructor->Reconstruct(dummy, NULL);
2162       }
2163       continue;
2164     }
2165     if (!loader) {
2166       AliWarning(Form("No loader is defined for %s!",fgkDetectorName[iDet]));
2167       continue;
2168     }
2169     // conversion of digits
2170     if (fRawReader && reconstructor->HasDigitConversion()) {
2171       AliInfo(Form("converting raw data digits into root objects for %s", 
2172                    fgkDetectorName[iDet]));
2173 //      AliCodeTimerAuto(Form("converting raw data digits into root objects for %s", 
2174 //                            fgkDetectorName[iDet]),0);
2175       loader->LoadDigits("update");
2176       loader->CleanDigits();
2177       loader->MakeDigitsContainer();
2178       TTree* digitsTree = loader->TreeD();
2179       reconstructor->ConvertDigits(fRawReader, digitsTree);
2180       loader->WriteDigits("OVERWRITE");
2181       loader->UnloadDigits();
2182     }
2183     // local reconstruction
2184     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
2185     //AliCodeTimerAuto(Form("running reconstruction for %s", fgkDetectorName[iDet]),0);
2186     loader->LoadRecPoints("update");
2187     loader->CleanRecPoints();
2188     loader->MakeRecPointsContainer();
2189     TTree* clustersTree = loader->TreeR();
2190     if (fRawReader && !reconstructor->HasDigitConversion()) {
2191       reconstructor->Reconstruct(fRawReader, clustersTree);
2192     } else {
2193       loader->LoadDigits("read");
2194       TTree* digitsTree = loader->TreeD();
2195       if (!digitsTree) {
2196         AliError(Form("Can't get the %s digits tree", fgkDetectorName[iDet]));
2197         if (fStopOnError) 
2198           return kFALSE;
2199       } else {
2200         reconstructor->Reconstruct(digitsTree, clustersTree);
2201         if (fRunQA && IsInTasks(AliQAv1::kDIGITSR)) {
2202           AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2203           AliQAManager::QAManager()->RunOneEventInOneDetector(iDet, digitsTree) ; 
2204         }
2205       }
2206       loader->UnloadDigits();
2207     }
2208                 if (fRunQA && IsInTasks(AliQAv1::kRECPOINTS)) {
2209       AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2210                         AliQAManager::QAManager()->RunOneEventInOneDetector(iDet, clustersTree) ; 
2211     }
2212     loader->WriteRecPoints("OVERWRITE");
2213     loader->UnloadRecPoints();
2214     AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr), iDet,1,eventNr);
2215   }
2216   IsSelected("CTP", detStr);
2217   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2218     AliError(Form("the following detectors were not found: %s",
2219                   detStr.Data()));
2220     if (fStopOnError) 
2221       return kFALSE;
2222   }
2223   eventNr++;
2224   return kTRUE;
2225 }
2226 //_____________________________________________________________________________
2227 Bool_t AliReconstruction::RunSPDTrackleting(AliESDEvent*& esd)
2228 {
2229 // run the SPD trackleting (for SPD efficiency purpouses)
2230
2231   AliCodeTimerAuto("",0)
2232
2233   Double_t vtxPos[3] = {0, 0, 0};
2234   Double_t vtxErr[3] = {0.0, 0.0, 0.0};
2235 /*
2236   TArrayF mcVertex(3);
2237   // if(MC)
2238   if (fRunLoader->GetHeader() && fRunLoader->GetHeader()->GenEventHeader()) {
2239     fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(mcVertex);
2240     for (Int_t i = 0; i < 3; i++) vtxPos[i] = mcVertex[i];
2241   }
2242 */
2243   const AliESDVertex *vertex = esd->GetVertex();
2244   if(!vertex){
2245     AliWarning("Vertex not found");
2246     return kFALSE;
2247   }
2248   vertex->GetXYZ(vtxPos);
2249   vertex->GetSigmaXYZ(vtxErr);
2250   if (fSPDTrackleter) {
2251     AliInfo("running the SPD Trackleter for Plane Efficiency Evaluation");
2252
2253     // load clusters
2254     fLoader[0]->LoadRecPoints("read");
2255     TTree* tree = fLoader[0]->TreeR();
2256     if (!tree) {
2257       AliError("Can't get the ITS cluster tree");
2258       return kFALSE;
2259     }
2260     fSPDTrackleter->LoadClusters(tree);
2261     fSPDTrackleter->SetVertex(vtxPos, vtxErr);
2262     // run trackleting
2263     if (fSPDTrackleter->Clusters2Tracks(esd) != 0) {
2264       AliWarning("AliITSTrackleterSPDEff Clusters2Tracks failed");
2265      // fLoader[0]->UnloadRecPoints();
2266       return kFALSE;
2267     }
2268 //fSPDTrackleter->UnloadRecPoints();
2269   } else {
2270     AliWarning("SPDTrackleter not available");
2271     return kFALSE;
2272   }
2273   return kTRUE;
2274 }
2275
2276 //_____________________________________________________________________________
2277 Bool_t AliReconstruction::RunVertexFinder(AliESDEvent*& esd)
2278 {
2279 // run the barrel tracking
2280
2281   AliCodeTimerAuto("",0)
2282
2283   AliVertexer *vertexer = CreateVertexer();
2284   if (!vertexer) return kFALSE;
2285
2286   AliInfo("running the ITS vertex finder");
2287   AliESDVertex* vertex = NULL;
2288   if (fLoader[0]) {
2289     fLoader[0]->LoadRecPoints();
2290     TTree* cltree = fLoader[0]->TreeR();
2291     if (cltree) {
2292       if(fDiamondProfileSPD) vertexer->SetVtxStart(fDiamondProfileSPD);
2293       vertex = vertexer->FindVertexForCurrentEvent(cltree);
2294     }
2295     else {
2296       AliError("Can't get the ITS cluster tree");
2297     }
2298     fLoader[0]->UnloadRecPoints();
2299   }
2300   else {
2301     AliError("Can't get the ITS loader");
2302   }
2303   if(!vertex){
2304     AliWarning("Vertex not found");
2305     vertex = new AliESDVertex();
2306     vertex->SetName("default");
2307   }
2308   else {
2309     vertex->SetName("reconstructed");
2310   }
2311
2312   Double_t vtxPos[3];
2313   Double_t vtxErr[3];
2314   vertex->GetXYZ(vtxPos);
2315   vertex->GetSigmaXYZ(vtxErr);
2316
2317   esd->SetPrimaryVertexSPD(vertex);
2318   AliESDVertex *vpileup = NULL;
2319   Int_t novertices = 0;
2320   vpileup = vertexer->GetAllVertices(novertices);
2321   if(novertices>1){
2322     for (Int_t kk=1; kk<novertices; kk++)esd->AddPileupVertexSPD(&vpileup[kk]);
2323   }
2324   // if SPD multiplicity has been determined, it is stored in the ESD
2325   AliMultiplicity *mult = vertexer->GetMultiplicity();
2326   if(mult)esd->SetMultiplicity(mult);
2327
2328   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2329     if (fTracker[iDet]) fTracker[iDet]->SetVertex(vtxPos, vtxErr);
2330   }  
2331   delete vertex;
2332
2333   delete vertexer;
2334
2335   return kTRUE;
2336 }
2337
2338 //_____________________________________________________________________________
2339 Bool_t AliReconstruction::RunHLTTracking(AliESDEvent*& esd)
2340 {
2341 // run the HLT barrel tracking
2342
2343   AliCodeTimerAuto("",0)
2344
2345   if (!fRunLoader) {
2346     AliError("Missing runLoader!");
2347     return kFALSE;
2348   }
2349
2350   AliInfo("running HLT tracking");
2351
2352   // Get a pointer to the HLT reconstructor
2353   AliReconstructor *reconstructor = GetReconstructor(kNDetectors-1);
2354   if (!reconstructor) return kFALSE;
2355
2356   // TPC + ITS
2357   for (Int_t iDet = 1; iDet >= 0; iDet--) {
2358     TString detName = fgkDetectorName[iDet];
2359     AliDebug(1, Form("%s HLT tracking", detName.Data()));
2360     reconstructor->SetOption(detName.Data());
2361     AliTracker *tracker = reconstructor->CreateTracker();
2362     if (!tracker) {
2363       AliWarning(Form("couldn't create a HLT tracker for %s", detName.Data()));
2364       if (fStopOnError) return kFALSE;
2365       continue;
2366     }
2367     Double_t vtxPos[3];
2368     Double_t vtxErr[3]={0.005,0.005,0.010};
2369     const AliESDVertex *vertex = esd->GetVertex();
2370     vertex->GetXYZ(vtxPos);
2371     tracker->SetVertex(vtxPos,vtxErr);
2372     if(iDet != 1) {
2373       fLoader[iDet]->LoadRecPoints("read");
2374       TTree* tree = fLoader[iDet]->TreeR();
2375       if (!tree) {
2376         AliError(Form("Can't get the %s cluster tree", detName.Data()));
2377         return kFALSE;
2378       }
2379       tracker->LoadClusters(tree);
2380     }
2381     if (tracker->Clusters2Tracks(esd) != 0) {
2382       AliError(Form("HLT %s Clusters2Tracks failed", fgkDetectorName[iDet]));
2383       return kFALSE;
2384     }
2385     if(iDet != 1) {
2386       tracker->UnloadClusters();
2387     }
2388     delete tracker;
2389   }
2390
2391   return kTRUE;
2392 }
2393
2394 //_____________________________________________________________________________
2395 Bool_t AliReconstruction::RunMuonTracking(AliESDEvent*& esd)
2396 {
2397 // run the muon spectrometer tracking
2398
2399   AliCodeTimerAuto("",0)
2400
2401   if (!fRunLoader) {
2402     AliError("Missing runLoader!");
2403     return kFALSE;
2404   }
2405   Int_t iDet = 7; // for MUON
2406
2407   AliInfo("is running...");
2408
2409   // Get a pointer to the MUON reconstructor
2410   AliReconstructor *reconstructor = GetReconstructor(iDet);
2411   if (!reconstructor) return kFALSE;
2412
2413   
2414   TString detName = fgkDetectorName[iDet];
2415   AliDebug(1, Form("%s tracking", detName.Data()));
2416   AliTracker *tracker =  reconstructor->CreateTracker();
2417   if (!tracker) {
2418     AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
2419     return kFALSE;
2420   }
2421      
2422   // read RecPoints
2423   fLoader[iDet]->LoadRecPoints("read");  
2424
2425   tracker->LoadClusters(fLoader[iDet]->TreeR());
2426   
2427   Int_t rv = tracker->Clusters2Tracks(esd);
2428   
2429   fLoader[iDet]->UnloadRecPoints();
2430
2431   tracker->UnloadClusters();
2432   
2433   delete tracker;
2434   
2435   if ( rv )
2436   {
2437     AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
2438     return kFALSE;
2439   }
2440   
2441   return kTRUE;
2442 }
2443
2444
2445 //_____________________________________________________________________________
2446 Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd,AliESDpid &PID)
2447 {
2448 // run the barrel tracking
2449   static Int_t eventNr=0;
2450   AliCodeTimerAuto("",0)
2451
2452   AliInfo("running tracking");
2453
2454   // Set the event info which is used
2455   // by the trackers in order to obtain
2456   // information about read-out detectors,
2457   // trigger etc.
2458   AliDebug(1, "Setting event info");
2459   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2460     if (!fTracker[iDet]) continue;
2461     fTracker[iDet]->SetEventInfo(&fEventInfo);
2462   }
2463
2464   //Fill the ESD with the T0 info (will be used by the TOF) 
2465   if (fReconstructor[11] && fLoader[11]) {
2466     fLoader[11]->LoadRecPoints("READ");
2467     TTree *treeR = fLoader[11]->TreeR();
2468     if (treeR) {
2469       GetReconstructor(11)->FillESD((TTree *)NULL,treeR,esd);
2470     }
2471   }
2472
2473   // pass 1: TPC + ITS inwards
2474   for (Int_t iDet = 1; iDet >= 0; iDet--) {
2475     if (!fTracker[iDet]) continue;
2476     AliDebug(1, Form("%s tracking", fgkDetectorName[iDet]));
2477
2478     // load clusters
2479     fLoader[iDet]->LoadRecPoints("read");
2480     AliSysInfo::AddStamp(Form("RLoadCluster%s_%d",fgkDetectorName[iDet],eventNr),iDet,1, eventNr);
2481     TTree* tree = fLoader[iDet]->TreeR();
2482     if (!tree) {
2483       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
2484       return kFALSE;
2485     }
2486     fTracker[iDet]->LoadClusters(tree);
2487     AliSysInfo::AddStamp(Form("TLoadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
2488     // run tracking
2489     if (fTracker[iDet]->Clusters2Tracks(esd) != 0) {
2490       AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
2491       return kFALSE;
2492     }
2493     // preliminary PID in TPC needed by the ITS tracker
2494     if (iDet == 1) {
2495       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
2496       PID.MakePID(esd,kTRUE);
2497     } 
2498     AliSysInfo::AddStamp(Form("Tracking0%s_%d",fgkDetectorName[iDet],eventNr), iDet,3,eventNr);
2499   }
2500
2501   // pass 2: ALL backwards
2502
2503   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2504     if (!fTracker[iDet]) continue;
2505     AliDebug(1, Form("%s back propagation", fgkDetectorName[iDet]));
2506
2507     // load clusters
2508     if (iDet > 1) {     // all except ITS, TPC
2509       TTree* tree = NULL;
2510       fLoader[iDet]->LoadRecPoints("read");
2511       AliSysInfo::AddStamp(Form("RLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,1, eventNr);
2512       tree = fLoader[iDet]->TreeR();
2513       if (!tree) {
2514         AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
2515         return kFALSE;
2516       }
2517       fTracker[iDet]->LoadClusters(tree); 
2518       AliSysInfo::AddStamp(Form("TLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
2519     }
2520
2521     // run tracking
2522     if (iDet>1) // start filling residuals for the "outer" detectors
2523       if (fRunGlobalQA) {
2524         AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
2525         TObjArray ** arr = AliTracker::GetResidualsArray() ; 
2526         if (arr) {
2527           AliRecoParam::EventSpecie_t es=fRecoParam.GetEventSpecie();
2528           TObjArray * elem = arr[AliRecoParam::AConvert(es)];
2529           if ( elem && (! elem->At(0)) ) {
2530             AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
2531             if (qadm) qadm->InitRecPointsForTracker() ; 
2532           }
2533         }
2534       }
2535     if (fTracker[iDet]->PropagateBack(esd) != 0) {
2536       AliError(Form("%s backward propagation failed", fgkDetectorName[iDet]));
2537       //      return kFALSE;
2538     }
2539
2540     // unload clusters
2541     if (iDet > 3) {     // all except ITS, TPC, TRD and TOF
2542       fTracker[iDet]->UnloadClusters();
2543       fLoader[iDet]->UnloadRecPoints();
2544     }
2545     // updated PID in TPC needed by the ITS tracker -MI
2546     if (iDet == 1) {
2547       //GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
2548       //AliESDpid::MakePID(esd);
2549       PID.MakePID(esd,kTRUE);
2550     }
2551     AliSysInfo::AddStamp(Form("Tracking1%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
2552   }
2553   //stop filling residuals for the "outer" detectors
2554   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
2555
2556   // pass 3: TRD + TPC + ITS refit inwards
2557
2558   for (Int_t iDet = 2; iDet >= 0; iDet--) {
2559     if (!fTracker[iDet]) continue;
2560     AliDebug(1, Form("%s inward refit", fgkDetectorName[iDet]));
2561
2562     // run tracking
2563     if (iDet<2) // start filling residuals for TPC and ITS
2564       if (fRunGlobalQA) {
2565         AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
2566         TObjArray ** arr = AliTracker::GetResidualsArray() ; 
2567         if (arr) {
2568           AliRecoParam::EventSpecie_t es=fRecoParam.GetEventSpecie();
2569           TObjArray * elem = arr[AliRecoParam::AConvert(es)];
2570           if ( elem && (! elem->At(0)) ) {
2571             AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
2572             if (qadm) qadm->InitRecPointsForTracker() ; 
2573           }
2574         }
2575       }
2576     
2577     if (fTracker[iDet]->RefitInward(esd) != 0) {
2578       AliError(Form("%s inward refit failed", fgkDetectorName[iDet]));
2579       //      return kFALSE;
2580     }
2581     // run postprocessing
2582     if (fTracker[iDet]->PostProcess(esd) != 0) {
2583       AliError(Form("%s postprocessing failed", fgkDetectorName[iDet]));
2584       //      return kFALSE;
2585     }
2586     AliSysInfo::AddStamp(Form("Tracking2%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
2587   }
2588
2589   // write space-points to the ESD in case alignment data output
2590   // is switched on
2591   if (fWriteAlignmentData)
2592     WriteAlignmentData(esd);
2593
2594   for (Int_t iDet = 3; iDet >= 0; iDet--) {
2595     if (!fTracker[iDet]) continue;
2596     // unload clusters
2597     fTracker[iDet]->UnloadClusters();
2598     AliSysInfo::AddStamp(Form("TUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,4, eventNr);
2599     fLoader[iDet]->UnloadRecPoints();
2600     AliSysInfo::AddStamp(Form("RUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,5, eventNr);
2601   }
2602   // stop filling residuals for TPC and ITS
2603   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
2604
2605   eventNr++;
2606   return kTRUE;
2607 }
2608
2609 //_____________________________________________________________________________
2610 Bool_t AliReconstruction::CleanESD(AliESDEvent *esd){
2611   //
2612   // Remove the data which are not needed for the physics analysis.
2613   //
2614
2615   Int_t nTracks=esd->GetNumberOfTracks();
2616   Int_t nV0s=esd->GetNumberOfV0s();
2617   AliInfo
2618   (Form("Number of ESD tracks and V0s before cleaning: %d %d",nTracks,nV0s));
2619
2620   Float_t cleanPars[]={fV0DCAmax,fV0CsPmin,fDmax,fZmax};
2621   Bool_t rc=esd->Clean(cleanPars);
2622
2623   nTracks=esd->GetNumberOfTracks();
2624   nV0s=esd->GetNumberOfV0s();
2625   AliInfo
2626   (Form("Number of ESD tracks and V0s after cleaning %d %d",nTracks,nV0s));
2627
2628   return rc;
2629 }
2630
2631 //_____________________________________________________________________________
2632 Bool_t AliReconstruction::FillESD(AliESDEvent*& esd, const TString& detectors)
2633 {
2634 // fill the event summary data
2635
2636   AliCodeTimerAuto("",0)
2637     static Int_t eventNr=0; 
2638   TString detStr = detectors;
2639   
2640   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2641   if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2642     AliReconstructor* reconstructor = GetReconstructor(iDet);
2643     if (!reconstructor) continue;
2644     AliDebug(1, Form("filling ESD for %s", fgkDetectorName[iDet]));
2645     TTree* clustersTree = NULL;
2646     if (fLoader[iDet]) {
2647       fLoader[iDet]->LoadRecPoints("read");
2648       clustersTree = fLoader[iDet]->TreeR();
2649       if (!clustersTree) {
2650         AliError(Form("Can't get the %s clusters tree", 
2651                       fgkDetectorName[iDet]));
2652         if (fStopOnError) return kFALSE;
2653       }
2654     }
2655     if (fRawReader && !reconstructor->HasDigitConversion()) {
2656       reconstructor->FillESD(fRawReader, clustersTree, esd);
2657     } else {
2658       TTree* digitsTree = NULL;
2659       if (fLoader[iDet]) {
2660         fLoader[iDet]->LoadDigits("read");
2661         digitsTree = fLoader[iDet]->TreeD();
2662         if (!digitsTree) {
2663           AliError(Form("Can't get the %s digits tree", 
2664                         fgkDetectorName[iDet]));
2665           if (fStopOnError) return kFALSE;
2666         }
2667       }
2668       reconstructor->FillESD(digitsTree, clustersTree, esd);
2669       if (fLoader[iDet]) fLoader[iDet]->UnloadDigits();
2670     }
2671     if (fLoader[iDet]) {
2672       fLoader[iDet]->UnloadRecPoints();
2673     }
2674   }
2675   
2676   IsSelected("CTP", detStr);
2677   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2678     AliError(Form("the following detectors were not found: %s", 
2679                   detStr.Data()));
2680     if (fStopOnError) return kFALSE;
2681   }
2682   AliSysInfo::AddStamp(Form("FillESD%d",eventNr), 0,1, eventNr);
2683   eventNr++;
2684   return kTRUE;
2685 }
2686
2687 //_____________________________________________________________________________
2688 Bool_t AliReconstruction::FillTriggerESD(AliESDEvent*& esd)
2689 {
2690   // Reads the trigger decision which is
2691   // stored in Trigger.root file and fills
2692   // the corresponding esd entries
2693
2694   AliCodeTimerAuto("",0)
2695   
2696   AliInfo("Filling trigger information into the ESD");
2697
2698   if (fRawReader) {
2699     AliCTPRawStream input(fRawReader);
2700     if (!input.Next()) {
2701       AliWarning("No valid CTP (trigger) DDL raw data is found ! The trigger info is taken from the event header!");
2702     }
2703     else {
2704       if (esd->GetTriggerMask() != input.GetClassMask())
2705         AliError(Form("Invalid trigger pattern found in CTP raw-data: %llx %llx",
2706                       input.GetClassMask(),esd->GetTriggerMask()));
2707       if (esd->GetOrbitNumber() != input.GetOrbitID())
2708         AliError(Form("Invalid orbit id found in CTP raw-data: %x %x",
2709                       input.GetOrbitID(),esd->GetOrbitNumber()));
2710       if (esd->GetBunchCrossNumber() != input.GetBCID())
2711         AliError(Form("Invalid bunch-crossing id found in CTP raw-data: %x %x",
2712                       input.GetBCID(),esd->GetBunchCrossNumber()));
2713       AliESDHeader* esdheader = esd->GetHeader();
2714       esdheader->SetL0TriggerInputs(input.GetL0Inputs());
2715       esdheader->SetL1TriggerInputs(input.GetL1Inputs());
2716       esdheader->SetL2TriggerInputs(input.GetL2Inputs());
2717       // IR
2718       UInt_t orbit=input.GetOrbitID();
2719        for(Int_t i=0 ; i<input.GetNIRs() ; i++ )
2720           if(TMath::Abs(Int_t(orbit-(input.GetIR(i))->GetOrbit()))<=1){
2721              esdheader->AddTriggerIR(input.GetIR(i));
2722           }
2723     }
2724   }
2725   return kTRUE;
2726 }
2727 //_____________________________________________________________________________
2728 Bool_t AliReconstruction::FillTriggerScalers(AliESDEvent*& esd)
2729 {
2730   //Scalers
2731   //fRunScalers->Print();
2732   if(fRunScalers && fRunScalers->CheckRunScalers()){
2733      AliTimeStamp* timestamp = new AliTimeStamp(esd->GetOrbitNumber(), esd->GetPeriodNumber(), esd->GetBunchCrossNumber());
2734      //AliTimeStamp* timestamp = new AliTimeStamp(10308000, 0, (ULong64_t)486238);
2735      AliESDHeader* esdheader = fesd->GetHeader();
2736      for(Int_t i=0;i<50;i++){
2737           if((1ull<<i) & esd->GetTriggerMask()){
2738           AliTriggerScalersESD* scalesd = fRunScalers->GetScalersForEventClass( timestamp, i+1);
2739           if(scalesd)esdheader->SetTriggerScalersRecord(scalesd);
2740         }
2741      }
2742   }
2743   return kTRUE;
2744 }
2745 //_____________________________________________________________________________
2746 Bool_t AliReconstruction::FillRawEventHeaderESD(AliESDEvent*& esd)
2747 {
2748   // 
2749   // Filling information from RawReader Header
2750   // 
2751
2752   if (!fRawReader) return kFALSE;
2753
2754   AliInfo("Filling information from RawReader Header");
2755
2756   esd->SetBunchCrossNumber(fRawReader->GetBCID());
2757   esd->SetOrbitNumber(fRawReader->GetOrbitID());
2758   esd->SetPeriodNumber(fRawReader->GetPeriod());
2759
2760   esd->SetTimeStamp(fRawReader->GetTimestamp());  
2761   esd->SetEventType(fRawReader->GetType());
2762
2763   return kTRUE;
2764 }
2765
2766
2767 //_____________________________________________________________________________
2768 Bool_t AliReconstruction::IsSelected(TString detName, TString& detectors) const
2769 {
2770 // check whether detName is contained in detectors
2771 // if yes, it is removed from detectors
2772
2773   // check if all detectors are selected
2774   if ((detectors.CompareTo("ALL") == 0) ||
2775       detectors.BeginsWith("ALL ") ||
2776       detectors.EndsWith(" ALL") ||
2777       detectors.Contains(" ALL ")) {
2778     detectors = "ALL";
2779     return kTRUE;
2780   }
2781
2782   // search for the given detector
2783   Bool_t result = kFALSE;
2784   if ((detectors.CompareTo(detName) == 0) ||
2785       detectors.BeginsWith(detName+" ") ||
2786       detectors.EndsWith(" "+detName) ||
2787       detectors.Contains(" "+detName+" ")) {
2788     detectors.ReplaceAll(detName, "");
2789     result = kTRUE;
2790   }
2791
2792   // clean up the detectors string
2793   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
2794   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
2795   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
2796
2797   return result;
2798 }
2799
2800 //_____________________________________________________________________________
2801 Bool_t AliReconstruction::InitRunLoader()
2802 {
2803 // get or create the run loader
2804
2805   if (gAlice) delete gAlice;
2806   gAlice = NULL;
2807
2808   TFile *gafile = TFile::Open(fGAliceFileName.Data());
2809   //  if (!gSystem->AccessPathName(fGAliceFileName.Data())) { // galice.root exists
2810   if (gafile) { // galice.root exists
2811     gafile->Close();
2812     delete gafile;
2813
2814     // load all base libraries to get the loader classes
2815     TString libs = gSystem->GetLibraries();
2816     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2817       TString detName = fgkDetectorName[iDet];
2818       if (detName == "HLT") continue;
2819       if (libs.Contains("lib" + detName + "base.so")) continue;
2820       gSystem->Load("lib" + detName + "base.so");
2821     }
2822     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data());
2823     if (!fRunLoader) {
2824       AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
2825       CleanUp();
2826       return kFALSE;
2827     }
2828
2829     fRunLoader->CdGAFile();
2830     fRunLoader->LoadgAlice();
2831
2832     //PH This is a temporary fix to give access to the kinematics
2833     //PH that is needed for the labels of ITS clusters
2834     fRunLoader->LoadHeader();
2835     fRunLoader->LoadKinematics();
2836
2837   } else {               // galice.root does not exist
2838     if (!fRawReader) {
2839       AliError(Form("the file %s does not exist", fGAliceFileName.Data()));
2840     }
2841     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data(),
2842                                     AliConfig::GetDefaultEventFolderName(),
2843                                     "recreate");
2844     if (!fRunLoader) {
2845       AliError(Form("could not create run loader in file %s", 
2846                     fGAliceFileName.Data()));
2847       CleanUp();
2848       return kFALSE;
2849     }
2850     fIsNewRunLoader = kTRUE;
2851     fRunLoader->MakeTree("E");
2852
2853     if (fNumberOfEventsPerFile > 0)
2854       fRunLoader->SetNumberOfEventsPerFile(fNumberOfEventsPerFile);
2855     else
2856       fRunLoader->SetNumberOfEventsPerFile((UInt_t)-1);
2857   }
2858
2859   return kTRUE;
2860 }
2861
2862 //_____________________________________________________________________________
2863 AliReconstructor* AliReconstruction::GetReconstructor(Int_t iDet)
2864 {
2865 // get the reconstructor object and the loader for a detector
2866
2867   if (fReconstructor[iDet]) {
2868     if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
2869       const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
2870       fReconstructor[iDet]->SetRecoParam(par);
2871       fReconstructor[iDet]->SetRunInfo(fRunInfo);
2872     }
2873     return fReconstructor[iDet];
2874   }
2875
2876   // load the reconstructor object
2877   TPluginManager* pluginManager = gROOT->GetPluginManager();
2878   TString detName = fgkDetectorName[iDet];
2879   TString recName = "Ali" + detName + "Reconstructor";
2880
2881   if (!fIsNewRunLoader && !fRunLoader->GetLoader(detName+"Loader") && (detName != "HLT")) return NULL;
2882
2883   AliReconstructor* reconstructor = NULL;
2884   // first check if a plugin is defined for the reconstructor
2885   TPluginHandler* pluginHandler = 
2886     pluginManager->FindHandler("AliReconstructor", detName);
2887   // if not, add a plugin for it
2888   if (!pluginHandler) {
2889     AliDebug(1, Form("defining plugin for %s", recName.Data()));
2890     TString libs = gSystem->GetLibraries();
2891     if (libs.Contains("lib" + detName + "base.so") ||
2892         (gSystem->Load("lib" + detName + "base.so") >= 0)) {
2893       pluginManager->AddHandler("AliReconstructor", detName, 
2894                                 recName, detName + "rec", recName + "()");
2895     } else {
2896       pluginManager->AddHandler("AliReconstructor", detName, 
2897                                 recName, detName, recName + "()");
2898     }
2899     pluginHandler = pluginManager->FindHandler("AliReconstructor", detName);
2900   }
2901   if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
2902     reconstructor = (AliReconstructor*) pluginHandler->ExecPlugin(0);
2903   }
2904   if (reconstructor) {
2905     TObject* obj = fOptions.FindObject(detName.Data());
2906     if (obj) reconstructor->SetOption(obj->GetTitle());
2907     reconstructor->SetRunInfo(fRunInfo);
2908     reconstructor->Init();
2909     fReconstructor[iDet] = reconstructor;
2910   }
2911
2912   // get or create the loader
2913   if (detName != "HLT") {
2914     fLoader[iDet] = fRunLoader->GetLoader(detName + "Loader");
2915     if (!fLoader[iDet]) {
2916       AliConfig::Instance()
2917         ->CreateDetectorFolders(fRunLoader->GetEventFolder(), 
2918                                 detName, detName);
2919       // first check if a plugin is defined for the loader
2920       pluginHandler = 
2921         pluginManager->FindHandler("AliLoader", detName);
2922       // if not, add a plugin for it
2923       if (!pluginHandler) {
2924         TString loaderName = "Ali" + detName + "Loader";
2925         AliDebug(1, Form("defining plugin for %s", loaderName.Data()));
2926         pluginManager->AddHandler("AliLoader", detName, 
2927                                   loaderName, detName + "base", 
2928                                   loaderName + "(const char*, TFolder*)");
2929         pluginHandler = pluginManager->FindHandler("AliLoader", detName);
2930       }
2931       if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
2932         fLoader[iDet] = 
2933           (AliLoader*) pluginHandler->ExecPlugin(2, detName.Data(), 
2934                                                  fRunLoader->GetEventFolder());
2935       }
2936       if (!fLoader[iDet]) {   // use default loader
2937         fLoader[iDet] = new AliLoader(detName, fRunLoader->GetEventFolder());
2938       }
2939       if (!fLoader[iDet]) {
2940         AliWarning(Form("couldn't get loader for %s", detName.Data()));
2941         if (fStopOnError) return NULL;
2942       } else {
2943         fRunLoader->AddLoader(fLoader[iDet]);
2944         fRunLoader->CdGAFile();
2945         if (gFile && !gFile->IsWritable()) gFile->ReOpen("UPDATE");
2946         fRunLoader->Write(0, TObject::kOverwrite);
2947       }
2948     }
2949   }
2950       
2951   if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
2952     const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
2953     reconstructor->SetRecoParam(par);
2954     reconstructor->SetRunInfo(fRunInfo);
2955   }
2956   return reconstructor;
2957 }
2958
2959 //_____________________________________________________________________________
2960 AliVertexer* AliReconstruction::CreateVertexer()
2961 {
2962 // create the vertexer
2963 // Please note that the caller is the owner of the
2964 // vertexer
2965
2966   AliVertexer* vertexer = NULL;
2967   AliReconstructor* itsReconstructor = GetReconstructor(0);
2968   if (itsReconstructor && ((fRunLocalReconstruction.Contains("ITS")) || fRunTracking.Contains("ITS"))) {
2969     vertexer = itsReconstructor->CreateVertexer();
2970   }
2971   if (!vertexer) {
2972     AliWarning("couldn't create a vertexer for ITS");
2973   }
2974
2975   return vertexer;
2976 }
2977
2978 //_____________________________________________________________________________
2979 Bool_t AliReconstruction::CreateTrackers(const TString& detectors)
2980 {
2981 // create the trackers
2982         AliInfo("Creating trackers");
2983
2984   TString detStr = detectors;
2985   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2986     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2987     AliReconstructor* reconstructor = GetReconstructor(iDet);
2988     if (!reconstructor) continue;
2989     TString detName = fgkDetectorName[iDet];
2990     if (detName == "HLT") {
2991       fRunHLTTracking = kTRUE;
2992       continue;
2993     }
2994     if (detName == "MUON") {
2995       fRunMuonTracking = kTRUE;
2996       continue;
2997     }
2998
2999
3000     fTracker[iDet] = reconstructor->CreateTracker();
3001     if (!fTracker[iDet] && (iDet < 7)) {
3002       AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
3003       if (fStopOnError) return kFALSE;
3004     }
3005     AliSysInfo::AddStamp(Form("LTracker%s",fgkDetectorName[iDet]), iDet,0);
3006   }
3007
3008   return kTRUE;
3009 }
3010
3011 //_____________________________________________________________________________
3012 void AliReconstruction::CleanUp()
3013 {
3014 // delete trackers and the run loader and close and delete the file
3015
3016   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3017     delete fReconstructor[iDet];
3018     fReconstructor[iDet] = NULL;
3019     fLoader[iDet] = NULL;
3020     delete fTracker[iDet];
3021     fTracker[iDet] = NULL;
3022   }
3023   delete fRunInfo;
3024   fRunInfo = NULL;
3025
3026   delete fSPDTrackleter;
3027   fSPDTrackleter = NULL;
3028
3029   delete ftVertexer;
3030   ftVertexer = NULL;
3031   
3032   delete fRunLoader;
3033   fRunLoader = NULL;
3034   delete fRawReader;
3035   fRawReader = NULL;
3036   delete fParentRawReader;
3037   fParentRawReader=NULL;
3038
3039   if (ffile) {
3040     ffile->Close();
3041     delete ffile;
3042     ffile = NULL;
3043   }
3044
3045   if (AliQAManager::QAManager())
3046     AliQAManager::QAManager()->ShowQA() ; 
3047   AliQAManager::Destroy() ; 
3048   
3049 }
3050
3051 void AliReconstruction::WriteAlignmentData(AliESDEvent* esd)
3052 {
3053   // Write space-points which are then used in the alignment procedures
3054   // For the moment only ITS, TPC, TRD and TOF
3055
3056   Int_t ntracks = esd->GetNumberOfTracks();
3057   for (Int_t itrack = 0; itrack < ntracks; itrack++)
3058     {
3059       AliESDtrack *track = esd->GetTrack(itrack);
3060       Int_t nsp = 0;
3061       Int_t idx[200];
3062       for (Int_t i=0; i<200; ++i) idx[i] = -1; //PH avoid uninitialized values
3063       for (Int_t iDet = 5; iDet >= 0; iDet--) {// TOF, TRD, TPC, ITS clusters
3064           nsp += (iDet==GetDetIndex("TRD")) ? track->GetTRDntracklets():track->GetNcls(iDet);
3065
3066           if (iDet==GetDetIndex("ITS")) { // ITS "extra" clusters
3067              track->GetClusters(iDet,idx);
3068              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nsp++;
3069           }  
3070       }
3071
3072       if (nsp) {
3073         AliTrackPointArray *sp = new AliTrackPointArray(nsp);
3074         track->SetTrackPointArray(sp);
3075         Int_t isptrack = 0;
3076         for (Int_t iDet = 5; iDet >= 0; iDet--) {
3077           AliTracker *tracker = fTracker[iDet];
3078           if (!tracker) continue;
3079           Int_t nspdet = (iDet==GetDetIndex("TRD")) ? track->GetTRDtracklets(idx):track->GetClusters(iDet,idx);
3080
3081           if (iDet==GetDetIndex("ITS")) // ITS "extra" clusters             
3082              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nspdet++;
3083
3084           if (nspdet <= 0) continue;
3085           AliTrackPoint p;
3086           Int_t isp = 0;
3087           Int_t isp2 = 0;
3088           while (isp2 < nspdet) {
3089             Bool_t isvalid=kTRUE;
3090
3091             Int_t index=idx[isp++];
3092             if (index < 0) continue;
3093
3094             TString dets = fgkDetectorName[iDet];
3095             if ((fUseTrackingErrorsForAlignment.CompareTo(dets) == 0) ||
3096             fUseTrackingErrorsForAlignment.BeginsWith(dets+" ") ||
3097             fUseTrackingErrorsForAlignment.EndsWith(" "+dets) ||
3098             fUseTrackingErrorsForAlignment.Contains(" "+dets+" ")) {
3099               isvalid = tracker->GetTrackPointTrackingError(index,p,track);
3100             } else {
3101               isvalid = tracker->GetTrackPoint(index,p); 
3102             } 
3103             isp2++;
3104             if (!isvalid) continue;
3105             if (iDet==GetDetIndex("ITS") && (isp-1)>=6) p.SetExtra();
3106             sp->AddPoint(isptrack,&p); isptrack++;
3107           }
3108         }       
3109       }
3110     }
3111 }
3112
3113 //_____________________________________________________________________________
3114 void AliReconstruction::FillRawDataErrorLog(Int_t iEvent, AliESDEvent* esd)
3115 {
3116   // The method reads the raw-data error log
3117   // accumulated within the rawReader.
3118   // It extracts the raw-data errors related to
3119   // the current event and stores them into
3120   // a TClonesArray inside the esd object.
3121
3122   if (!fRawReader) return;
3123
3124   for(Int_t i = 0; i < fRawReader->GetNumberOfErrorLogs(); i++) {
3125
3126     AliRawDataErrorLog *log = fRawReader->GetErrorLog(i);
3127     if (!log) continue;
3128     if (iEvent != log->GetEventNumber()) continue;
3129
3130     esd->AddRawDataErrorLog(log);
3131   }
3132
3133 }
3134
3135 //_____________________________________________________________________________
3136 void AliReconstruction::CheckQA()
3137 {
3138 // check the QA of SIM for this run and remove the detectors 
3139 // with status Fatal
3140   
3141 //      TString newRunLocalReconstruction ; 
3142 //      TString newRunTracking ;
3143 //      TString newFillESD ;
3144 //       
3145 //      for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
3146 //              TString detName(AliQAv1::GetDetName(iDet)) ;
3147 //              AliQAv1 * qa = AliQAv1::Instance(AliQAv1::DETECTORINDEX_t(iDet)) ;       
3148 //      if ( qa->IsSet(AliQAv1::DETECTORINDEX_t(iDet), AliQAv1::kSIM, specie, AliQAv1::kFATAL)) {
3149 //        AliInfo(Form("QA status for %s %s in Hits and/or SDIGITS  and/or Digits was Fatal; No reconstruction performed", 
3150 //                   detName.Data(), AliRecoParam::GetEventSpecieName(es))) ;
3151 //                      } else {
3152 //                      if ( fRunLocalReconstruction.Contains(AliQAv1::GetDetName(iDet)) || 
3153 //                                      fRunLocalReconstruction.Contains("ALL") )  {
3154 //                              newRunLocalReconstruction += detName ; 
3155 //                              newRunLocalReconstruction += " " ;                      
3156 //                      }
3157 //                      if ( fRunTracking.Contains(AliQAv1::GetDetName(iDet)) || 
3158 //                                      fRunTracking.Contains("ALL") )  {
3159 //                              newRunTracking += detName ; 
3160 //                              newRunTracking += " " ;                         
3161 //                      }
3162 //                      if ( fFillESD.Contains(AliQAv1::GetDetName(iDet)) || 
3163 //                                      fFillESD.Contains("ALL") )  {
3164 //                              newFillESD += detName ; 
3165 //                              newFillESD += " " ;                     
3166 //                      }
3167 //              }
3168 //      }
3169 //      fRunLocalReconstruction = newRunLocalReconstruction ; 
3170 //      fRunTracking            = newRunTracking ; 
3171 //      fFillESD                = newFillESD ; 
3172 }
3173
3174 //_____________________________________________________________________________
3175 Int_t AliReconstruction::GetDetIndex(const char* detector)
3176 {
3177   // return the detector index corresponding to detector
3178   Int_t index = -1 ; 
3179   for (index = 0; index < kNDetectors ; index++) {
3180     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
3181         break ; 
3182   }     
3183   return index ; 
3184 }
3185 //_____________________________________________________________________________
3186 Bool_t AliReconstruction::FinishPlaneEff() {
3187  //
3188  // Here execute all the necessary operationis, at the end of the tracking phase,
3189  // in case that evaluation of PlaneEfficiencies was required for some detector.
3190  // E.g., write into a DataBase file the PlaneEfficiency which have been evaluated.
3191  //
3192  // This Preliminary version works only FOR ITS !!!!!
3193  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3194  //
3195  //  Input: none
3196  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3197  //
3198  Bool_t ret=kFALSE;
3199  TString detStr = fLoadCDB;
3200  //for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
3201  for (Int_t iDet = 0; iDet < 1; iDet++) { // for the time being only ITS
3202    if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3203    if(fTracker[iDet] && fTracker[iDet]->GetPlaneEff()) {
3204       AliPlaneEff *planeeff=fTracker[iDet]->GetPlaneEff();
3205       TString name=planeeff->GetName();
3206       name+=".root";
3207       TFile* pefile = TFile::Open(name, "RECREATE");
3208       ret=(Bool_t)planeeff->Write();
3209       pefile->Close();
3210       if(planeeff->GetCreateHistos()) {
3211         TString hname=planeeff->GetName();
3212         hname+="Histo.root";
3213         ret*=planeeff->WriteHistosToFile(hname,"RECREATE");
3214       }
3215    }
3216    if(fSPDTrackleter) {
3217      AliPlaneEff *planeeff=fSPDTrackleter->GetPlaneEff();
3218       TString name="AliITSPlaneEffSPDtracklet.root";
3219       TFile* pefile = TFile::Open(name, "RECREATE");
3220       ret=(Bool_t)planeeff->Write();
3221       pefile->Close();
3222       AliESDEvent *dummy=NULL;
3223       ret=(Bool_t)fSPDTrackleter->PostProcess(dummy); // take care of writing other files
3224    }
3225  }
3226  return ret;
3227 }
3228 //_____________________________________________________________________________
3229 Bool_t AliReconstruction::InitPlaneEff() {
3230 //
3231  // Here execute all the necessary operations, before of the tracking phase,
3232  // for the evaluation of PlaneEfficiencies, in case required for some detectors.
3233  // E.g., read from a DataBase file a first evaluation of the PlaneEfficiency
3234  // which should be updated/recalculated.
3235  //
3236  // This Preliminary version will work only FOR ITS !!!!!
3237  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3238  //
3239  //  Input: none
3240  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3241  //
3242  AliWarning(Form("Implementation of this method not yet completed !! Method return kTRUE"));
3243
3244   fSPDTrackleter = NULL;
3245   TString detStr = fLoadCDB;
3246   if (IsSelected(fgkDetectorName[0], detStr)) {
3247     AliReconstructor* itsReconstructor = GetReconstructor(0);
3248     if (itsReconstructor) {
3249       fSPDTrackleter = itsReconstructor->CreateTrackleter(); // this is NULL unless required in RecoParam
3250     }
3251     if (fSPDTrackleter) {
3252       AliInfo("Trackleter for SPD has been created");
3253     }
3254   }
3255  return kTRUE;
3256 }
3257
3258 //_____________________________________________________________________________
3259 Bool_t AliReconstruction::InitAliEVE()
3260 {
3261   // This method should be called only in case 
3262   // AliReconstruction is run
3263   // within the alieve environment.
3264   // It will initialize AliEVE in a way
3265   // so that it can visualize event processed
3266   // by AliReconstruction.
3267   // The return flag shows whenever the
3268   // AliEVE initialization was successful or not.
3269
3270   TString macroStr;
3271   macroStr.Form("%s/EVE/macros/alieve_online.C",gSystem->ExpandPathName("$ALICE_ROOT"));
3272   AliInfo(Form("Loading AliEVE macro: %s",macroStr.Data()));
3273   if (gROOT->LoadMacro(macroStr.Data()) != 0) return kFALSE;
3274
3275   gROOT->ProcessLine("if (!AliEveEventManager::GetMaster()){new AliEveEventManager();AliEveEventManager::GetMaster()->AddNewEventCommand(\"alieve_online_on_new_event()\");gEve->AddEvent(AliEveEventManager::GetMaster());};");
3276   gROOT->ProcessLine("alieve_online_init()");
3277
3278   return kTRUE;
3279 }
3280   
3281 //_____________________________________________________________________________
3282 void AliReconstruction::RunAliEVE()
3283 {
3284   // Runs AliEVE visualisation of
3285   // the current event.
3286   // Should be executed only after
3287   // successful initialization of AliEVE.
3288
3289   AliInfo("Running AliEVE...");
3290   gROOT->ProcessLine(Form("AliEveEventManager::GetMaster()->SetEvent((AliRunLoader*)0x%lx,(AliRawReader*)0x%lx,(AliESDEvent*)0x%lx,(AliESDfriend*)0x%lx);",fRunLoader,fRawReader,fesd,fesdf));
3291   gSystem->Run();
3292 }
3293
3294 //_____________________________________________________________________________
3295 Bool_t AliReconstruction::SetRunQA(TString detAndAction) 
3296 {
3297         // Allows to run QA for a selected set of detectors
3298         // and a selected set of tasks among RAWS, DIGITSR, RECPOINTS and ESDS
3299         // all selected detectors run the same selected tasks
3300         
3301         if (!detAndAction.Contains(":")) {
3302                 AliError( Form("%s is a wrong syntax, use \"DetectorList:ActionList\" \n", detAndAction.Data()) ) ;
3303                 fRunQA = kFALSE ;
3304                 return kFALSE ;                 
3305         }
3306         Int_t colon = detAndAction.Index(":") ; 
3307         fQADetectors = detAndAction(0, colon) ; 
3308         fQATasks   = detAndAction(colon+1, detAndAction.Sizeof() ) ; 
3309         if (fQATasks.Contains("ALL") ) {
3310                 fQATasks = Form("%d %d %d %d", AliQAv1::kRAWS, AliQAv1::kDIGITSR, AliQAv1::kRECPOINTS, AliQAv1::kESDS) ; 
3311         } else {
3312                 fQATasks.ToUpper() ; 
3313                 TString tempo("") ; 
3314                 if ( fQATasks.Contains("RAW") ) 
3315                         tempo = Form("%d ", AliQAv1::kRAWS) ; 
3316                 if ( fQATasks.Contains("DIGIT") ) 
3317                         tempo += Form("%d ", AliQAv1::kDIGITSR) ; 
3318                 if ( fQATasks.Contains("RECPOINT") ) 
3319                         tempo += Form("%d ", AliQAv1::kRECPOINTS) ; 
3320                 if ( fQATasks.Contains("ESD") ) 
3321                         tempo += Form("%d ", AliQAv1::kESDS) ; 
3322                 fQATasks = tempo ; 
3323                 if (fQATasks.IsNull()) {
3324                         AliInfo("No QA requested\n")  ;
3325                         fRunQA = kFALSE ;
3326                         return kTRUE ; 
3327                 }
3328         }       
3329         TString tempo(fQATasks) ; 
3330         tempo.ReplaceAll(Form("%d", AliQAv1::kRAWS), AliQAv1::GetTaskName(AliQAv1::kRAWS))      ;
3331         tempo.ReplaceAll(Form("%d", AliQAv1::kDIGITSR), AliQAv1::GetTaskName(AliQAv1::kDIGITSR)) ;      
3332         tempo.ReplaceAll(Form("%d", AliQAv1::kRECPOINTS), AliQAv1::GetTaskName(AliQAv1::kRECPOINTS)) ;  
3333         tempo.ReplaceAll(Form("%d", AliQAv1::kESDS), AliQAv1::GetTaskName(AliQAv1::kESDS)) ;    
3334         AliInfo( Form("QA will be done on \"%s\" for \"%s\"\n", fQADetectors.Data(), tempo.Data()) ) ;  
3335         fRunQA = kTRUE ;
3336         return kTRUE; 
3337
3338
3339 //_____________________________________________________________________________
3340 Bool_t AliReconstruction::InitRecoParams() 
3341 {
3342   // The method accesses OCDB and retrieves all
3343   // the available reco-param objects from there.
3344
3345   Bool_t isOK = kTRUE;
3346
3347   if (fRecoParam.GetDetRecoParamArray(kNDetectors)) {
3348     AliInfo("Using custom GRP reconstruction parameters");
3349   }
3350   else {
3351     AliInfo("Loading GRP reconstruction parameter objects");
3352
3353     AliCDBPath path("GRP","Calib","RecoParam");
3354     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
3355     if(!entry){ 
3356       AliWarning("Couldn't find GRP RecoParam entry in OCDB");
3357       isOK = kFALSE;
3358     }
3359     else {
3360       TObject *recoParamObj = entry->GetObject();
3361       if (dynamic_cast<TObjArray*>(recoParamObj)) {
3362         // GRP has a normal TobjArray of AliDetectorRecoParam objects
3363         // Registering them in AliRecoParam
3364         fRecoParam.AddDetRecoParamArray(kNDetectors,dynamic_cast<TObjArray*>(recoParamObj));
3365       }
3366       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
3367         // GRP has only onse set of reco parameters
3368         // Registering it in AliRecoParam
3369         AliInfo("Single set of GRP reconstruction parameters found");
3370         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
3371         fRecoParam.AddDetRecoParam(kNDetectors,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
3372       }
3373       else {
3374         AliError("No valid GRP RecoParam object found in the OCDB");
3375         isOK = kFALSE;
3376       }
3377       entry->SetOwner(0);
3378     }
3379   }
3380
3381   TString detStr = fLoadCDB;
3382   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3383
3384     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3385
3386     if (fRecoParam.GetDetRecoParamArray(iDet)) {
3387       AliInfo(Form("Using custom reconstruction parameters for detector %s",fgkDetectorName[iDet]));
3388       continue;
3389     }
3390
3391     AliInfo(Form("Loading reconstruction parameter objects for detector %s",fgkDetectorName[iDet]));
3392   
3393     AliCDBPath path(fgkDetectorName[iDet],"Calib","RecoParam");
3394     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
3395     if(!entry){ 
3396       AliWarning(Form("Couldn't find RecoParam entry in OCDB for detector %s",fgkDetectorName[iDet]));
3397       isOK = kFALSE;
3398     }
3399     else {
3400       TObject *recoParamObj = entry->GetObject();
3401       if (dynamic_cast<TObjArray*>(recoParamObj)) {
3402         // The detector has a normal TobjArray of AliDetectorRecoParam objects
3403         // Registering them in AliRecoParam
3404         fRecoParam.AddDetRecoParamArray(iDet,dynamic_cast<TObjArray*>(recoParamObj));
3405       }
3406       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
3407         // The detector has only onse set of reco parameters
3408         // Registering it in AliRecoParam
3409         AliInfo(Form("Single set of reconstruction parameters found for detector %s",fgkDetectorName[iDet]));
3410         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
3411         fRecoParam.AddDetRecoParam(iDet,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
3412       }
3413       else {
3414         AliError(Form("No valid RecoParam object found in the OCDB for detector %s",fgkDetectorName[iDet]));
3415         isOK = kFALSE;
3416       }
3417       entry->SetOwner(0);
3418       //      FIX ME: We have to disable the unloading of reco-param CDB
3419       //      entries because QA framework is using them. Has to be fix in
3420       //      a way that the QA takes the objects already constructed in
3421       //      this method.
3422       //      AliCDBManager::Instance()->UnloadFromCache(path.GetPath());
3423     }
3424   }
3425
3426   if (AliDebugLevel() > 0) fRecoParam.Print();
3427
3428   return isOK;
3429 }
3430
3431 //_____________________________________________________________________________
3432 Bool_t AliReconstruction::GetEventInfo() 
3433 {
3434   // Fill the event info object
3435   // ...
3436   AliCodeTimerAuto("",0)
3437
3438   AliCentralTrigger *aCTP = NULL;
3439   if (fRawReader) {
3440     fEventInfo.SetEventType(fRawReader->GetType());
3441
3442     ULong64_t mask = fRawReader->GetClassMask();
3443     fEventInfo.SetTriggerMask(mask);
3444     UInt_t clmask = fRawReader->GetDetectorPattern()[0];
3445     fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(clmask));
3446
3447     aCTP = new AliCentralTrigger();
3448     TString configstr("");
3449     if (!aCTP->LoadConfiguration(configstr)) { // Load CTP config from OCDB
3450       AliError("No trigger configuration found in OCDB! The trigger configuration information will not be used!");
3451       delete aCTP;
3452       return kFALSE;
3453     }
3454     aCTP->SetClassMask(mask);
3455     aCTP->SetClusterMask(clmask);
3456   }
3457   else {
3458     fEventInfo.SetEventType(AliRawEventHeaderBase::kPhysicsEvent);
3459
3460     if (fRunLoader && (!fRunLoader->LoadTrigger())) {
3461       aCTP = fRunLoader->GetTrigger();
3462       fEventInfo.SetTriggerMask(aCTP->GetClassMask());
3463       // get inputs from actp - just get
3464       AliESDHeader* esdheader = fesd->GetHeader();
3465       esdheader->SetL0TriggerInputs(aCTP->GetL0TriggerInputs());
3466       esdheader->SetL1TriggerInputs(aCTP->GetL1TriggerInputs());
3467       esdheader->SetL2TriggerInputs(aCTP->GetL2TriggerInputs());
3468       fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(aCTP->GetClusterMask()));
3469     }
3470     else {
3471       AliWarning("No trigger can be loaded! The trigger information will not be used!");
3472       return kFALSE;
3473     }
3474   }
3475
3476   AliTriggerConfiguration *config = aCTP->GetConfiguration();
3477   if (!config) {
3478     AliError("No trigger configuration has been found! The trigger configuration information will not be used!");
3479     if (fRawReader) delete aCTP;
3480     return kFALSE;
3481   }
3482
3483   UChar_t clustmask = 0;
3484   TString trclasses;
3485   ULong64_t trmask = fEventInfo.GetTriggerMask();
3486   const TObjArray& classesArray = config->GetClasses();
3487   Int_t nclasses = classesArray.GetEntriesFast();
3488   for( Int_t iclass=0; iclass < nclasses; iclass++ ) {
3489     AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At(iclass);
3490     if (trclass) {
3491       Int_t trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
3492       fesd->SetTriggerClass(trclass->GetName(),trindex);
3493       if (fRawReader) fRawReader->LoadTriggerClass(trclass->GetName(),trindex);
3494       if (trmask & (1ull << trindex)) {
3495         trclasses += " ";
3496         trclasses += trclass->GetName();
3497         trclasses += " ";
3498         clustmask |= trclass->GetCluster()->GetClusterMask();
3499       }
3500     }
3501   }
3502   fEventInfo.SetTriggerClasses(trclasses);
3503
3504   // Write names of active trigger inputs in ESD Header
3505   const TObjArray& inputsArray = config->GetInputs(); 
3506   Int_t ninputs = inputsArray.GetEntriesFast();
3507   for( Int_t iinput=0; iinput < ninputs; iinput++ ) {
3508     AliTriggerInput* trginput = (AliTriggerInput*)inputsArray.At(iinput);
3509     if (trginput) {
3510       Int_t inputIndex = (Int_t)TMath::Nint(TMath::Log2(trginput->GetMask()));
3511       AliESDHeader* headeresd = fesd->GetHeader();
3512       Int_t trglevel = (Int_t)trginput->GetLevel();
3513       if (trglevel == 0) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex);
3514       if (trglevel == 1) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex+24);
3515       if (trglevel == 2) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex+48);
3516     }
3517   }
3518
3519   // Set the information in ESD
3520   fesd->SetTriggerMask(trmask);
3521   fesd->SetTriggerCluster(clustmask);
3522
3523   if (!aCTP->CheckTriggeredDetectors()) {
3524     if (fRawReader) delete aCTP;
3525     return kFALSE;
3526   }    
3527
3528   if (fRawReader) delete aCTP;
3529
3530   // We have to fill also the HLT decision here!!
3531   // ...
3532
3533   return kTRUE;
3534 }
3535
3536 const char *AliReconstruction::MatchDetectorList(const char *detectorList, UInt_t detectorMask)
3537 {
3538   // Match the detector list found in the rec.C or the default 'ALL'
3539   // to the list found in the GRP (stored there by the shuttle PP which
3540   // gets the information from ECS)
3541   static TString resultList;
3542   TString detList = detectorList;
3543
3544   resultList = "";
3545
3546   for(Int_t iDet = 0; iDet < (AliDAQ::kNDetectors-1); iDet++) {
3547     if ((detectorMask >> iDet) & 0x1) {
3548       TString det = AliDAQ::OfflineModuleName(iDet);
3549       if ((detList.CompareTo("ALL") == 0) ||
3550           ((detList.BeginsWith("ALL ") ||
3551             detList.EndsWith(" ALL") ||
3552             detList.Contains(" ALL ")) &&
3553            !(detList.BeginsWith("-"+det+" ") ||
3554              detList.EndsWith(" -"+det) ||
3555              detList.Contains(" -"+det+" "))) ||
3556           (detList.CompareTo(det) == 0) ||
3557           detList.BeginsWith(det+" ") ||
3558           detList.EndsWith(" "+det) ||
3559           detList.Contains( " "+det+" " )) {
3560         if (!resultList.EndsWith(det + " ")) {
3561           resultList += det;
3562           resultList += " ";
3563         }
3564       }        
3565     }
3566   }
3567
3568   // HLT
3569   if ((detectorMask >> AliDAQ::kHLTId) & 0x1) {
3570     TString hltDet = AliDAQ::OfflineModuleName(AliDAQ::kNDetectors-1);
3571     if ((detList.CompareTo("ALL") == 0) ||
3572         ((detList.BeginsWith("ALL ") ||
3573           detList.EndsWith(" ALL") ||
3574           detList.Contains(" ALL ")) &&
3575          !(detList.BeginsWith("-"+hltDet+" ") ||
3576            detList.EndsWith(" -"+hltDet) ||
3577            detList.Contains(" -"+hltDet+" "))) ||
3578         (detList.CompareTo(hltDet) == 0) ||
3579         detList.BeginsWith(hltDet+" ") ||
3580         detList.EndsWith(" "+hltDet) ||
3581         detList.Contains( " "+hltDet+" " )) {
3582       resultList += hltDet;
3583     }
3584   }
3585
3586   return resultList.Data();
3587
3588 }
3589
3590 //______________________________________________________________________________
3591 void AliReconstruction::Abort(const char *method, EAbort what)
3592 {
3593   // Abort processing. If what = kAbortProcess, the Process() loop will be
3594   // aborted. If what = kAbortFile, the current file in a chain will be
3595   // aborted and the processing will continue with the next file, if there
3596   // is no next file then Process() will be aborted. Abort() can also  be
3597   // called from Begin(), SlaveBegin(), Init() and Notify(). After abort
3598   // the SlaveTerminate() and Terminate() are always called. The abort flag
3599   // can be checked in these methods using GetAbort().
3600   //
3601   // The method is overwritten in AliReconstruction for better handling of
3602   // reco specific errors 
3603
3604   if (!fStopOnError) return;
3605
3606   CleanUp();
3607
3608   TString whyMess = method;
3609   whyMess += " failed! Aborting...";
3610
3611   AliError(whyMess.Data());
3612
3613   fAbort = what;
3614   TString mess = "Abort";
3615   if (fAbort == kAbortProcess)
3616     mess = "AbortProcess";
3617   else if (fAbort == kAbortFile)
3618     mess = "AbortFile";
3619
3620   Info(mess, whyMess.Data());
3621 }
3622
3623 //______________________________________________________________________________
3624 Bool_t AliReconstruction::ProcessEvent(void* event)
3625 {
3626   // Method that is used in case the event loop
3627   // is steered from outside, for example by AMORE
3628   // 'event' is a pointer to the DATE event in the memory
3629
3630   if (fRawReader) delete fRawReader;
3631   fRawReader = new AliRawReaderDate(event);
3632   fStatus = ProcessEvent(fRunLoader->GetNumberOfEvents());  
3633   delete fRawReader;
3634   fRawReader = NULL;
3635
3636   return fStatus;
3637 }
3638
3639 //______________________________________________________________________________
3640 Bool_t AliReconstruction::ParseOutput()
3641 {
3642   // The method parses the output file
3643   // location string in order to steer
3644   // properly the selector
3645
3646   TPMERegexp re1("(\\w+\\.zip#\\w+\\.root):([,*\\w+\\.root,*]+)@dataset://(\\w++)");
3647   TPMERegexp re2("(\\w+\\.root)?@?dataset://(\\w++)");
3648
3649   if (re1.Match(fESDOutput) == 4) {
3650     // root archive with output files stored and regustered
3651     // in proof dataset
3652     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",re1[1].Data()));
3653     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",re1[3].Data()));
3654     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_DATASET",""));
3655     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_ARCHIVE",re1[2].Data()));
3656     AliInfo(Form("%s files will be stored within %s in dataset %s",
3657                  re1[2].Data(),
3658                  re1[1].Data(),
3659                  re1[3].Data()));
3660   }
3661   else if (re2.Match(fESDOutput) == 3) {
3662     // output file stored and registered
3663     // in proof dataset
3664     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",(re2[1].IsNull()) ? "AliESDs.root" : re2[1].Data()));
3665     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",re2[2].Data()));
3666     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_DATASET",""));
3667     AliInfo(Form("%s will be stored in dataset %s",
3668                  (re2[1].IsNull()) ? "AliESDs.root" : re2[1].Data(),
3669                  re2[2].Data()));
3670   }
3671   else {
3672     if (fESDOutput.IsNull()) {
3673       // Output location not given.
3674       // Assuming xrootd has been already started and
3675       // the output file has to be sent back
3676       // to the client machine
3677       TString esdUrl(Form("root://%s/%s/",
3678                           TUrl(gSystem->HostName()).GetHostFQDN(),
3679                           gSystem->pwd()));
3680       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE","AliESDs.root"));
3681       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",esdUrl.Data()));
3682       AliInfo(Form("AliESDs.root will be stored in %s",
3683                    esdUrl.Data()));
3684     }
3685     else {
3686       // User specified an output location.
3687       // Ones has just to parse it here
3688       TUrl outputUrl(fESDOutput.Data());
3689       TString outputFile(gSystem->BaseName(outputUrl.GetFile()));
3690       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",outputFile.IsNull() ? "AliESDs.root" : outputFile.Data()));
3691       TString outputLocation(outputUrl.GetUrl());
3692       outputLocation.ReplaceAll(outputFile.Data(),"");
3693       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",outputLocation.Data()));
3694       AliInfo(Form("%s will be stored in %s",
3695                    outputFile.IsNull() ? "AliESDs.root" : outputFile.Data(),
3696                    outputLocation.Data()));
3697     }
3698   }
3699
3700   return kTRUE;
3701 }