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