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