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