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