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