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