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