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