]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/STEER/AliReconstruction.cxx
MFT clean-up (Antonio)
[u/mrichter/AliRoot.git] / STEER / STEER / AliReconstruction.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* $Id: AliReconstruction.cxx 63911 2013-08-19 16:46:41Z hristov $ */
17
18 ///////////////////////////////////////////////////////////////////////////////
19 //                                                                           //
20 // class for running the reconstruction                                      //
21 //                                                                           //
22 // Clusters and tracks are created for all detectors and all events by       //
23 // typing:                                                                   //
24 //                                                                           //
25 //   AliReconstruction rec;                                                  //
26 //   rec.Run();                                                              //
27 //                                                                           //
28 // The Run method returns kTRUE in case of successful execution.             //
29 //                                                                           //
30 // If the input to the reconstruction are not simulated digits but raw data, //
31 // this can be specified by an argument of the Run method or by the method   //
32 //                                                                           //
33 //   rec.SetInput("...");                                                    //
34 //                                                                           //
35 // The input formats and the corresponding argument are:                     //
36 // - DDL raw data files: directory name, ends with "/"                       //
37 // - raw data root file: root file name, extension ".root"                   //
38 // - raw data DATE file: DATE file name, any other non-empty string          //
39 // - MC root files     : empty string, default                               //
40 //                                                                           //
41 // By default all events are reconstructed. The reconstruction can be        //
42 // limited to a range of events by giving the index of the first and the     //
43 // last event as an argument to the Run method or by calling                 //
44 //                                                                           //
45 //   rec.SetEventRange(..., ...);                                            //
46 //                                                                           //
47 // The index -1 (default) can be used for the last event to indicate no      //
48 // upper limit of the event range.                                           //
49 //                                                                           //
50 // In case of raw-data reconstruction the user can modify the default        //
51 // number of events per digits/clusters/tracks file. In case the option      //
52 // is not used the number is set 1. In case the user provides 0, than        //
53 // the number of events is equal to the number of events inside the          //
54 // raw-data file (i.e. one digits/clusters/tracks file):                     //
55 //                                                                           //
56 //   rec.SetNumberOfEventsPerFile(...);                                      //
57 //                                                                           //
58 //                                                                           //
59 // The name of the galice file can be changed from the default               //
60 // "galice.root" by passing it as argument to the AliReconstruction          //
61 // constructor or by                                                         //
62 //                                                                           //
63 //   rec.SetGAliceFile("...");                                               //
64 //                                                                           //
65 // The local reconstruction can be switched on or off for individual         //
66 // detectors by                                                              //
67 //                                                                           //
68 //   rec.SetRunLocalReconstruction("...");                                   //
69 //                                                                           //
70 // The argument is a (case sensitive) string with the names of the           //
71 // detectors separated by a space. The special string "ALL" selects all      //
72 // available detectors. This is the default.                                 //
73 //                                                                           //
74 // The reconstruction of the primary vertex position can be switched off by  //
75 //                                                                           //
76 //   rec.SetRunVertexFinder(kFALSE);                                         //
77 //                                                                           //
78 // The tracking and the creation of ESD tracks can be switched on for        //
79 // selected detectors by                                                     //
80 //                                                                           //
81 //   rec.SetRunTracking("...");                                              //
82 //                                                                           //
83 // Uniform/nonuniform field tracking switches (default: uniform field)       //
84 //                                                                           //
85 //   rec.SetUniformFieldTracking(); ( rec.SetUniformFieldTracking(kFALSE); ) //
86 //                                                                           //
87 // The filling of additional ESD information can be steered by               //
88 //                                                                           //
89 //   rec.SetFillESD("...");                                                  //
90 //                                                                           //
91 // Again, for both methods the string specifies the list of detectors.       //
92 // The default is "ALL".                                                     //
93 //                                                                           //
94 // The call of the shortcut method                                           //
95 //                                                                           //
96 //   rec.SetRunReconstruction("...");                                        //
97 //                                                                           //
98 // is equivalent to calling SetRunLocalReconstruction, SetRunTracking and    //
99 // SetFillESD with the same detector selecting string as argument.           //
100 //                                                                           //
101 // The reconstruction requires digits or raw data as input. For the creation //
102 // of digits and raw data have a look at the class AliSimulation.            //
103 //                                                                           //
104 // The input data of a detector can be replaced by the corresponding HLT     //
105 // data by calling (usual detector string)                                   //
106 // SetUseHLTData("...");                                                     //
107 //                                                                           //
108 //                                                                           //
109 ///////////////////////////////////////////////////////////////////////////////
110
111 #include <TArrayD.h>
112 #include <TArrayF.h>
113 #include <TArrayS.h>
114 #include <TChain.h>
115 #include <TFile.h>
116 #include <TGeoGlobalMagField.h>
117 #include <TGeoManager.h>
118 #include <TList.h>
119 #include <TLorentzVector.h>
120 #include <TMap.h>
121 #include <TObjArray.h>
122 #include <TPRegexp.h>
123 #include <TParameter.h>
124 #include <TPluginManager.h>
125 #include <TProof.h>
126 #include <TProofOutputFile.h>
127 #include <TROOT.h>
128 #include <TSystem.h>
129 #include <THashTable.h>
130 #include <TGrid.h>
131 #include <TMessage.h>
132 #include <TUrl.h>
133 #include <TRandom.h>
134 #include <THashList.h>
135
136 #include "AliAlignObj.h"
137 #include "AliAnalysisManager.h"
138 #include "AliAnalysisDataContainer.h"
139 #include "AliCDBEntry.h"
140 #include "AliCDBManager.h"
141 #include "AliCDBStorage.h"
142 #include "AliCTPRawStream.h"
143 #include "AliCascadeVertexer.h"
144 #include "AliCentralTrigger.h"
145 #include "AliCodeTimer.h"
146 #include "AliDAQ.h"
147 #include "AliDetectorRecoParam.h"
148 #include "AliESDCaloCells.h"
149 #include "AliESDCaloCluster.h"
150 #include "AliESDEvent.h"
151 #include "AliESDMuonTrack.h"
152 #include "AliESDPmdTrack.h"
153 #include "AliESDTagCreator.h"
154 #include "AliESDVertex.h"
155 #include "AliESDcascade.h"
156 #include "AliESDfriend.h"
157 #include "AliESDkink.h"
158 #include "AliESDpid.h"
159 #include "AliESDtrack.h"
160 #include "AliESDtrack.h"
161 #include "AliEventInfo.h"
162 #include "AliGRPObject.h"
163 #include "AliGRPRecoParam.h"
164 #include "AliGenEventHeader.h"
165 #include "AliGeomManager.h"
166 #include "AliGlobalQADataMaker.h" 
167 #include "AliHeader.h"
168 #include "AliLog.h"
169 #include "AliMagF.h"
170 #include "AliMultiplicity.h"
171 #include "AliPID.h"
172 #include "AliPlaneEff.h"
173 #include "AliQAv1.h"
174 #include "AliQADataMakerRec.h" 
175 #include "AliQAManager.h"
176 #include "AliRawVEvent.h"
177 #include "AliRawEventHeaderBase.h"
178 #include "AliRawHLTManager.h"
179 #include "AliRawReaderDate.h"
180 #include "AliRawReaderFile.h"
181 #include "AliRawReaderRoot.h"
182 #include "AliRecoInputHandler.h"
183 #include "AliReconstruction.h"
184 #include "AliReconstructor.h"
185 #include "AliRun.h"
186 #include "AliRunInfo.h"
187 #include "AliRunLoader.h"
188 #include "AliSysInfo.h" // memory snapshots
189 #include "AliTrackPointArray.h"
190 #include "AliTracker.h"
191 #include "AliTriggerClass.h"
192 #include "AliTriggerCluster.h"
193 #include "AliTriggerIR.h"
194 #include "AliTriggerConfiguration.h"
195 #include "AliV0vertexer.h"
196 #include "AliVertexer.h"
197 #include "AliTrackleter.h"
198 #include "AliVertexerTracks.h"
199 #include "AliTriggerRunScalers.h"
200 #include "AliCTPTimeParams.h" 
201 #include "AliESDHLTDecision.h"
202 #include "AliTriggerInput.h"
203 #include "AliLHCData.h"
204 #include "ARVersion.h"
205 #include <RVersion.h>
206 #include <unistd.h>
207 #include <sys/resource.h>
208 ClassImp(AliReconstruction)
209
210 using std::endl;
211
212 //_____________________________________________________________________________
213 const char* AliReconstruction::fgkStopEvFName = "_stopEvent_";
214 const char* AliReconstruction::fgkDetectorName[AliReconstruction::kNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "ACORDE","AD","MFT", "HLT"};
215
216 //_____________________________________________________________________________
217 AliReconstruction::AliReconstruction(const char* gAliceFilename) :
218   TSelector(),
219   fRunVertexFinder(kTRUE),
220   fRunVertexFinderTracks(kTRUE),
221   fRunMuonTracking(kFALSE),
222   fRunV0Finder(kTRUE),
223   fRunCascadeFinder(kTRUE),
224   fRunMultFinder(kTRUE),
225   fStopOnError(kTRUE),
226   fStopOnMissingTriggerFile(kTRUE),
227   fWriteAlignmentData(kFALSE),
228   fWriteESDfriend(kFALSE),
229   fFillTriggerESD(kTRUE),
230
231   fCleanESD(kTRUE),
232   fV0DCAmax(3.),
233   fV0CsPmin(0.),
234   fDmax(50.),
235   fZmax(50.),
236
237   fRunLocalReconstruction("ALL"),
238   fRunTracking("ALL"),
239   fFillESD("ALL"),
240   fDeleteRecPoints(""),
241   fDeleteDigits(""),
242   fLoadCDB(""),
243   fUseTrackingErrorsForAlignment(""),
244   fGAliceFileName(gAliceFilename),
245   fRawInput(""),
246   fESDOutput(""),
247   fProofOutputFileName(""),
248   fProofOutputLocation(""),
249   fProofOutputDataset(kFALSE),
250   fProofOutputArchive(""),
251   fEquipIdMap(""),
252   fFirstEvent(0),
253   fLastEvent(-1),
254   fNumberOfEventsPerFile((UInt_t)-1),
255   fFractionFriends(0.04),
256   fOptions(),
257   fLoadAlignFromCDB(kTRUE),
258   fLoadAlignData("ALL"),
259   fUseHLTData(),
260   fRunInfo(NULL),
261   fEventInfo(),
262   fRunScalers(NULL),
263   fCTPTimeParams(NULL),  
264   fCTPTimeAlign(NULL),  
265
266   fRunLoader(NULL),
267   fRawReader(NULL),
268   fParentRawReader(NULL),
269
270   fRecoParam(),
271
272   fSPDTrackleter(NULL),
273
274   fDiamondProfileSPD(NULL),
275   fDiamondProfile(NULL),
276   fDiamondProfileTPC(NULL),
277   fListOfCosmicTriggers(NULL),
278   
279   fGRPData(NULL),
280
281   fAlignObjArray(NULL),
282   fCDBUri(),
283   fQARefUri(),
284   fSpecCDBUri(), 
285   fInitCDBCalled(kFALSE),
286   fCDBSnapshotMode(kFALSE),
287   fSetRunNumberFromDataCalled(kFALSE),
288   fQADetectors("ALL"), 
289   fQATasks("ALL"), 
290   fRunQA(kTRUE),  
291   fRunGlobalQA(kTRUE),
292   fSameQACycle(kFALSE),
293   fInitQACalled(kFALSE), 
294   fWriteQAExpertData(kTRUE), 
295   fRunPlaneEff(kFALSE),
296
297   fESDpid(NULL),
298
299   fesd(NULL),
300   fhltesd(NULL),
301   fesdf(NULL),
302   ffile(NULL),
303   ffileF(NULL),
304   ftree(NULL),
305   ftreeF(NULL),
306   fhlttree(NULL),
307   ftVertexer(NULL),
308   fIsNewRunLoader(kFALSE),
309   fRunAliEVE(kFALSE),
310   fChain(NULL),
311   fNall(0),
312   fNspecie(0),
313   fSspecie(0),
314   fNhighPt(0),
315   fShighPt(0),
316   //
317   fTreeBuffSize(30000000),
318   fMemCountESD(0),
319   fMemCountESDF(0),
320   fMemCountESDHLT(0),
321   //
322   fUpgradeModule(""),
323   fAnalysisMacro(),
324   fAnalysis(0),
325   fRecoHandler(0),
326   fDeclTriggerClasses(""),
327   fStopped(kFALSE),
328   fMaxRSS(0),
329   fMaxVMEM(0)
330 {
331 // create reconstruction object with default parameters
332   gGeoManager = NULL;
333   
334   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
335     fReconstructor[iDet] = NULL;
336     fUpgradeMask[iDet]=kFALSE;
337     fLoader[iDet] = NULL;
338     fTracker[iDet] = NULL;
339   }
340   for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
341     fQACycles[iDet] = 999999 ;
342     fQAWriteExpert[iDet] = kFALSE ; 
343   }
344   fBeamInt[0][0]=fBeamInt[0][1]=fBeamInt[1][0]=fBeamInt[1][1] = -1;
345
346   AliPID pid;
347 }
348
349 //_____________________________________________________________________________
350 AliReconstruction::AliReconstruction(const AliReconstruction& rec) :
351   TSelector(),
352   fRunVertexFinder(rec.fRunVertexFinder),
353   fRunVertexFinderTracks(rec.fRunVertexFinderTracks),
354   fRunMuonTracking(rec.fRunMuonTracking),
355   fRunV0Finder(rec.fRunV0Finder),
356   fRunCascadeFinder(rec.fRunCascadeFinder),
357   fRunMultFinder(rec.fRunMultFinder),
358   fStopOnError(rec.fStopOnError),
359   fStopOnMissingTriggerFile(rec.fStopOnMissingTriggerFile),
360   fWriteAlignmentData(rec.fWriteAlignmentData),
361   fWriteESDfriend(rec.fWriteESDfriend),
362   fFillTriggerESD(rec.fFillTriggerESD),
363
364   fCleanESD(rec.fCleanESD),
365   fV0DCAmax(rec.fV0DCAmax),
366   fV0CsPmin(rec.fV0CsPmin),
367   fDmax(rec.fDmax),
368   fZmax(rec.fZmax),
369
370   fRunLocalReconstruction(rec.fRunLocalReconstruction),
371   fRunTracking(rec.fRunTracking),
372   fFillESD(rec.fFillESD),
373   fDeleteRecPoints(""),
374   fDeleteDigits(""),
375   fLoadCDB(rec.fLoadCDB),
376   fUseTrackingErrorsForAlignment(rec.fUseTrackingErrorsForAlignment),
377   fGAliceFileName(rec.fGAliceFileName),
378   fRawInput(rec.fRawInput),
379   fESDOutput(rec.fESDOutput),
380   fProofOutputFileName(rec.fProofOutputFileName),
381   fProofOutputLocation(rec.fProofOutputLocation),
382   fProofOutputDataset(rec.fProofOutputDataset),
383   fProofOutputArchive(rec.fProofOutputArchive),
384   fEquipIdMap(rec.fEquipIdMap),
385   fFirstEvent(rec.fFirstEvent),
386   fLastEvent(rec.fLastEvent),
387   fNumberOfEventsPerFile(rec.fNumberOfEventsPerFile),
388   fFractionFriends(rec.fFractionFriends),
389   fOptions(),
390   fLoadAlignFromCDB(rec.fLoadAlignFromCDB),
391   fLoadAlignData(rec.fLoadAlignData),
392   fUseHLTData(rec.fUseHLTData),
393   fRunInfo(NULL),
394   fEventInfo(),
395   fRunScalers(NULL),
396   fCTPTimeParams(NULL),
397   fCTPTimeAlign(NULL),
398
399   fRunLoader(NULL),
400   fRawReader(NULL),
401   fParentRawReader(NULL),
402
403   fRecoParam(rec.fRecoParam),
404
405   fSPDTrackleter(NULL),
406
407   fDiamondProfileSPD(rec.fDiamondProfileSPD),
408   fDiamondProfile(rec.fDiamondProfile),
409   fDiamondProfileTPC(rec.fDiamondProfileTPC),
410   fListOfCosmicTriggers(NULL),
411   
412   fGRPData(NULL),
413
414   fAlignObjArray(rec.fAlignObjArray),
415   fCDBUri(rec.fCDBUri),
416   fQARefUri(rec.fQARefUri),
417   fSpecCDBUri(), 
418   fInitCDBCalled(rec.fInitCDBCalled),
419   fCDBSnapshotMode(rec.fCDBSnapshotMode),
420   fSetRunNumberFromDataCalled(rec.fSetRunNumberFromDataCalled),
421   fQADetectors(rec.fQADetectors), 
422   fQATasks(rec.fQATasks), 
423   fRunQA(rec.fRunQA),  
424   fRunGlobalQA(rec.fRunGlobalQA),
425   fSameQACycle(rec.fSameQACycle),
426   fInitQACalled(rec.fInitQACalled),
427   fWriteQAExpertData(rec.fWriteQAExpertData), 
428   fRunPlaneEff(rec.fRunPlaneEff),
429
430   fESDpid(NULL),
431
432   fesd(NULL),
433   fhltesd(NULL),
434   fesdf(NULL),
435   ffile(NULL),
436   ffileF(NULL),
437   ftree(NULL),
438   ftreeF(NULL),
439   fhlttree(NULL),
440   ftVertexer(NULL),
441   fIsNewRunLoader(rec.fIsNewRunLoader),
442   fRunAliEVE(kFALSE),
443   fChain(NULL),
444   fNall(0),
445   fNspecie(0),
446   fSspecie(0),
447   fNhighPt(0),
448   fShighPt(0),
449   //
450   fTreeBuffSize(rec.fTreeBuffSize),
451   fMemCountESD(0),
452   fMemCountESDF(0),
453   fMemCountESDHLT(0),
454   //
455   fUpgradeModule(""),
456   fAnalysisMacro(rec.fAnalysisMacro),
457   fAnalysis(0),
458   fRecoHandler(0),
459   fDeclTriggerClasses(rec.fDeclTriggerClasses),
460   fStopped(kFALSE),
461   fMaxRSS(0),
462   fMaxVMEM(0)
463 {
464 // copy constructor
465
466   for (Int_t i = 0; i < rec.fOptions.GetEntriesFast(); i++) {
467     if (rec.fOptions[i]) fOptions.Add(rec.fOptions[i]->Clone());
468   }
469   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
470     fReconstructor[iDet] = NULL;
471     fUpgradeMask[iDet] = kFALSE;
472     fLoader[iDet] = NULL;
473     fTracker[iDet] = NULL;
474   }  
475   
476   for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
477     fQACycles[iDet] = rec.fQACycles[iDet];
478     fQAWriteExpert[iDet] = rec.fQAWriteExpert[iDet] ; 
479   }
480
481   for (Int_t i = 0; i < rec.fSpecCDBUri.GetEntriesFast(); i++) {
482     if (rec.fSpecCDBUri[i]) fSpecCDBUri.Add(rec.fSpecCDBUri[i]->Clone());
483   }
484
485   for (int i=2;i--;) for (int j=2;j--;) fBeamInt[i][j] = rec.fBeamInt[i][j];
486
487 }
488
489 //_____________________________________________________________________________
490 AliReconstruction& AliReconstruction::operator = (const AliReconstruction& rec)
491 {
492 // assignment operator
493 // Used in PROOF mode
494 // Be very careful while modifing it!
495 // Simple rules to follow:
496 // for persistent data members - use their assignment operators
497 // for non-persistent ones - do nothing or take the default values from constructor
498 // TSelector members should not be touched
499   if(&rec == this) return *this;
500
501   fRunVertexFinder       = rec.fRunVertexFinder;
502   fRunVertexFinderTracks = rec.fRunVertexFinderTracks;
503   fRunMuonTracking       = rec.fRunMuonTracking;
504   fRunV0Finder           = rec.fRunV0Finder;
505   fRunCascadeFinder      = rec.fRunCascadeFinder;
506   fRunMultFinder         = rec.fRunMultFinder;
507   fStopOnError           = rec.fStopOnError;
508   fStopOnMissingTriggerFile = rec.fStopOnMissingTriggerFile;
509   fWriteAlignmentData    = rec.fWriteAlignmentData;
510   fWriteESDfriend        = rec.fWriteESDfriend;
511   fFillTriggerESD        = rec.fFillTriggerESD;
512
513   fCleanESD  = rec.fCleanESD;
514   fV0DCAmax  = rec.fV0DCAmax;
515   fV0CsPmin  = rec.fV0CsPmin;
516   fDmax      = rec.fDmax;
517   fZmax      = rec.fZmax;
518
519   fRunLocalReconstruction        = rec.fRunLocalReconstruction;
520   fRunTracking                   = rec.fRunTracking;
521   fFillESD                       = rec.fFillESD;
522   fDeleteRecPoints               = rec.fDeleteRecPoints;
523   fDeleteDigits                  = rec.fDeleteDigits;
524   fLoadCDB                       = rec.fLoadCDB;
525   fUseTrackingErrorsForAlignment = rec.fUseTrackingErrorsForAlignment;
526   fGAliceFileName                = rec.fGAliceFileName;
527   fRawInput                      = rec.fRawInput;
528   fESDOutput                     = rec.fESDOutput;
529   fProofOutputFileName           = rec.fProofOutputFileName;
530   fProofOutputLocation           = rec.fProofOutputLocation;
531   fProofOutputDataset            = rec.fProofOutputDataset;
532   fProofOutputArchive            = rec.fProofOutputArchive;
533   fEquipIdMap                    = rec.fEquipIdMap;
534   fFirstEvent                    = rec.fFirstEvent;
535   fLastEvent                     = rec.fLastEvent;
536   fNumberOfEventsPerFile         = rec.fNumberOfEventsPerFile;
537   fFractionFriends               = rec.fFractionFriends;
538
539   for (Int_t i = 0; i < rec.fOptions.GetEntriesFast(); i++) {
540     if (rec.fOptions[i]) fOptions.Add(rec.fOptions[i]->Clone());
541   }
542
543   fLoadAlignFromCDB              = rec.fLoadAlignFromCDB;
544   fLoadAlignData                 = rec.fLoadAlignData;
545   fUseHLTData                    = rec.fUseHLTData;
546
547   delete fRunInfo; fRunInfo = NULL;
548   if (rec.fRunInfo) fRunInfo = new AliRunInfo(*rec.fRunInfo);
549
550   fEventInfo                     = rec.fEventInfo;
551
552   delete fRunScalers; fRunScalers = NULL;
553   if (rec.fRunScalers) fRunScalers = new AliTriggerRunScalers(*rec.fRunScalers); 
554
555   delete fCTPTimeParams; fCTPTimeParams = NULL;
556   if (rec.fCTPTimeParams) fCTPTimeParams = new AliCTPTimeParams(*rec.fCTPTimeParams);
557   delete fCTPTimeAlign; fCTPTimeAlign = NULL;
558   if (rec.fCTPTimeAlign) fCTPTimeAlign = new AliCTPTimeParams(*rec.fCTPTimeAlign);
559
560   fRunLoader       = NULL;
561   fRawReader       = NULL;
562   fParentRawReader = NULL;
563
564   fRecoParam = rec.fRecoParam;
565
566   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
567     fUpgradeMask[iDet] = kFALSE;
568     delete fReconstructor[iDet]; fReconstructor[iDet] = NULL;
569     delete fLoader[iDet]; fLoader[iDet] = NULL;
570     delete fTracker[iDet]; fTracker[iDet] = NULL;
571   }
572   
573   for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
574     fQACycles[iDet] = rec.fQACycles[iDet];
575     fQAWriteExpert[iDet] = rec.fQAWriteExpert[iDet] ;
576   } 
577
578   delete fSPDTrackleter; fSPDTrackleter = NULL;
579     
580   delete fDiamondProfileSPD; fDiamondProfileSPD = NULL;
581   if (rec.fDiamondProfileSPD) fDiamondProfileSPD = new AliESDVertex(*rec.fDiamondProfileSPD);
582   delete fDiamondProfile; fDiamondProfile = NULL;
583   if (rec.fDiamondProfile) fDiamondProfile = new AliESDVertex(*rec.fDiamondProfile);
584   delete fDiamondProfileTPC; fDiamondProfileTPC = NULL;
585   if (rec.fDiamondProfileTPC) fDiamondProfileTPC = new AliESDVertex(*rec.fDiamondProfileTPC);
586
587   delete fListOfCosmicTriggers; fListOfCosmicTriggers = NULL;
588   if (rec.fListOfCosmicTriggers) fListOfCosmicTriggers = (THashTable*)((rec.fListOfCosmicTriggers)->Clone());
589
590   delete fGRPData; fGRPData = NULL;
591   //  if (rec.fGRPData) fGRPData = (TMap*)((rec.fGRPData)->Clone());
592   if (rec.fGRPData) fGRPData = (AliGRPObject*)((rec.fGRPData)->Clone());
593
594   delete fAlignObjArray; fAlignObjArray = NULL;
595
596   fCDBUri        = "";
597   fQARefUri      = rec.fQARefUri;
598   fSpecCDBUri.Delete();
599   fInitCDBCalled               = rec.fInitCDBCalled;
600   fCDBSnapshotMode             = rec.fCDBSnapshotMode;
601   fSetRunNumberFromDataCalled  = rec.fSetRunNumberFromDataCalled;
602   fQADetectors                 = rec.fQADetectors;
603   fQATasks                     = rec.fQATasks; 
604   fRunQA                       = rec.fRunQA;  
605   fRunGlobalQA                 = rec.fRunGlobalQA;
606   fSameQACycle                 = rec.fSameQACycle;
607   fInitQACalled                = rec.fInitQACalled;
608   fWriteQAExpertData           = rec.fWriteQAExpertData;
609   fRunPlaneEff                 = rec.fRunPlaneEff;
610   for (int i=2;i--;) for (int j=2;j--;) fBeamInt[i][j] = rec.fBeamInt[i][j];
611   fESDpid  = NULL;
612   fesd     = NULL;
613   fhltesd  = NULL;
614   fesdf    = NULL;
615   ffile    = NULL;
616   ffileF   = NULL;
617   ftree    = NULL;
618   ftreeF   = NULL;
619   fhlttree = NULL;
620   ftVertexer = NULL;
621   fIsNewRunLoader = rec.fIsNewRunLoader;
622   fRunAliEVE = kFALSE;
623   fChain = NULL;
624   fNall = 0;
625   fNspecie = 0;
626   fSspecie = 0;
627   fNhighPt = 0;
628   fShighPt = 0;
629   //
630   fTreeBuffSize = rec.fTreeBuffSize;
631   fMemCountESD = 0;
632   fMemCountESDF = 0;
633   fMemCountESDHLT = 0;
634   //
635   fUpgradeModule="";
636   fAnalysisMacro = rec.fAnalysisMacro;
637   fAnalysis = 0;
638   fRecoHandler = 0;
639   fDeclTriggerClasses = rec.fDeclTriggerClasses;
640
641   return *this;
642 }
643
644 //_____________________________________________________________________________
645 AliReconstruction::~AliReconstruction()
646 {
647 // clean up
648
649   CleanUp();
650   if (fListOfCosmicTriggers) {
651     fListOfCosmicTriggers->Delete();
652     delete fListOfCosmicTriggers;
653   }
654   delete fGRPData;
655   delete fRunScalers;
656   delete fCTPTimeParams;
657   delete fCTPTimeAlign;
658   fOptions.Delete();
659   if (fAlignObjArray) {
660     fAlignObjArray->Delete();
661     delete fAlignObjArray;
662   }
663   fSpecCDBUri.Delete();
664
665   AliCodeTimer::Instance()->Print();
666 }
667
668 //_____________________________________________________________________________
669 void AliReconstruction::InitQA()
670 {
671   //Initialize the QA and start of cycle 
672   AliCodeTimerAuto("",0);
673   
674   if (fInitQACalled) return;
675   fInitQACalled = kTRUE;
676   
677   if (fGRPData) AliQADataMaker::SetCloningRequest( fGRPData->GetQATrigClasses(), fGRPData->GetQACloningRequest());
678
679
680   AliQAManager * qam = AliQAManager::QAManager(AliQAv1::kRECMODE) ; 
681   qam->SetSaveData(kTRUE); 
682   qam->SetCycleLength(AliQAv1::kITS, 5) ; 
683   if (fWriteQAExpertData)
684     qam->SetWriteExpert() ; 
685  
686   if (qam->IsDefaultStorageSet()) {
687     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
688     AliWarning("Default QA reference storage has been already set !");
689     AliWarning(Form("Ignoring the default storage declared in AliReconstruction: %s",fQARefUri.Data()));
690     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
691     fQARefUri = qam->GetDefaultStorage()->GetURI();
692   } else {
693     if (fQARefUri.Length() > 0) {
694         AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
695         AliDebug(2, Form("Default QA reference storage is set to: %s", fQARefUri.Data()));
696         AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
697       } else {
698         fQARefUri="local://$ALICE_ROOT/QAref";
699         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
700         AliWarning("Default QA refeference storage not yet set !!!!");
701         AliWarning(Form("Setting it now to: %s", fQARefUri.Data()));
702         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
703                 
704       }
705     qam->SetDefaultStorage(fQARefUri);
706   }
707   
708   if (fRunQA) {
709   qam->SetActiveDetectors(fQADetectors) ;
710   qam->SetActiveOnlineDetectors(fRunInfo->GetActiveDetectors());
711     
712   for (Int_t det = 0 ; det < AliQAv1::kNDET ; det++) {
713     qam->SetCycleLength(AliQAv1::DETECTORINDEX_t(det), fQACycles[det]) ;  
714     qam->SetWriteExpert(AliQAv1::DETECTORINDEX_t(det)) ;
715   }
716   if (!fRawReader && !fInput && IsInTasks(AliQAv1::kRAWS))
717     fQATasks.ReplaceAll(Form("%d",AliQAv1::kRAWS), "") ;
718   qam->SetTasks(fQATasks) ; 
719   qam->InitQADataMaker(AliCDBManager::Instance()->GetRun()) ; 
720   }
721   if (fRunGlobalQA) {
722     Bool_t sameCycle = kFALSE ;
723     AliQADataMaker *qadm = qam->GetQADataMaker(AliQAv1::kGLOBAL);
724     AliInfo(Form("Initializing the global QA data maker"));
725     if (IsInTasks(AliQAv1::kRECPOINTS)) {
726       qadm->StartOfCycle(AliQAv1::kRECPOINTS, AliCDBManager::Instance()->GetRun(), sameCycle) ; 
727       TObjArray **arr=qadm->Init(AliQAv1::kRECPOINTS);
728       AliTracker::SetResidualsArray(arr);
729       sameCycle = kTRUE ; 
730     }
731     if (IsInTasks(AliQAv1::kESDS)) {
732       qadm->StartOfCycle(AliQAv1::kESDS, AliCDBManager::Instance()->GetRun(), sameCycle) ; 
733       qadm->Init(AliQAv1::kESDS);
734     }
735   }
736     AliSysInfo::AddStamp("InitQA") ; 
737 }
738
739 //_____________________________________________________________________________
740 void AliReconstruction::MergeQA(const char *fileName)
741 {
742   //Initialize the QA and start of cycle 
743   AliCodeTimerAuto("",0) ;
744   AliQAManager::QAManager()->Merge(AliCDBManager::Instance()->GetRun(),fileName) ; 
745   AliSysInfo::AddStamp("MergeQA") ; 
746 }
747   
748 //_____________________________________________________________________________
749 void AliReconstruction::InitCDB()
750 {
751 // activate a default CDB storage
752 // First check if we have any CDB storage set, because it is used 
753 // to retrieve the calibration and alignment constants
754   AliCodeTimerAuto("",0);
755
756   if (fInitCDBCalled) return;
757   fInitCDBCalled = kTRUE;
758
759   AliCDBManager* man = AliCDBManager::Instance();
760   if (man->IsDefaultStorageSet())
761   {
762     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
763     AliWarning("Default CDB storage has been already set !");
764     AliWarning(Form("Ignoring the default storage declared in AliReconstruction: %s",fCDBUri.Data()));
765     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
766     fCDBUri = man->GetDefaultStorage()->GetURI();
767   }
768   else {
769     if (fCDBUri.Length() > 0) 
770     {
771         AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
772         AliDebug(2, Form("Default CDB storage is set to: %s", fCDBUri.Data()));
773         AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
774         man->SetDefaultStorage(fCDBUri);
775     } 
776     else if (!man->GetRaw()){
777         fCDBUri="local://$ALICE_ROOT/OCDB";
778         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
779         AliWarning("Default CDB storage not yet set !!!!");
780         AliWarning(Form("Setting it now to: %s", fCDBUri.Data()));
781         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
782         man->SetDefaultStorage(fCDBUri);
783     }
784     else {    
785         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
786         AliWarning("Default storage will be set after setting the Run Number!!!");
787         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");                    
788     }
789   }
790
791   // Now activate the detector specific CDB storage locations
792   for (Int_t i = 0; i < fSpecCDBUri.GetEntriesFast(); i++) {
793     TObject* obj = fSpecCDBUri[i];
794     if (!obj) continue;
795     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
796     AliDebug(2, Form("Specific CDB storage for %s is set to: %s",obj->GetName(),obj->GetTitle()));
797     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
798     man->SetSpecificStorage(obj->GetName(), obj->GetTitle());
799   }
800   AliSysInfo::AddStamp("InitCDB");
801 }
802
803 //_____________________________________________________________________________
804 void AliReconstruction::SetCDBSnapshotMode(const char* snapshotFileName) {
805     fCDBSnapshotMode = kTRUE;
806     AliCDBManager::Instance()->SetSnapshotMode(snapshotFileName);
807 }
808
809 //_____________________________________________________________________________
810 void AliReconstruction::SetDefaultStorage(const char* uri) {
811 // Store the desired default CDB storage location
812 // Activate it later within the Run() method
813
814   fCDBUri = uri;
815
816 }
817
818 //_____________________________________________________________________________
819 void AliReconstruction::SetQARefDefaultStorage(const char* uri) {
820   // Store the desired default CDB storage location
821   // Activate it later within the Run() method
822   
823   fQARefUri = uri;
824   AliQAv1::SetQARefStorage(fQARefUri.Data()) ;
825   
826 }
827 //_____________________________________________________________________________
828 void AliReconstruction::SetSpecificStorage(const char* calibType, const char* uri) {
829 // Store a detector-specific CDB storage location
830 // Activate it later within the Run() method
831
832   AliCDBPath aPath(calibType);
833   if(!aPath.IsValid()){
834         // if calibType is not wildcard but it is a valid detector, add "/*" to make it a valid path
835         for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
836                 if(!strcmp(calibType, fgkDetectorName[iDet])) {
837                         aPath.SetPath(Form("%s/*", calibType));
838                         AliInfo(Form("Path for specific storage set to %s", aPath.GetPath().Data()));
839                         break;
840                 }
841         }
842         if(!aPath.IsValid()){
843                 AliError(Form("Not a valid path or detector: %s", calibType));
844                 return;
845         }
846   }
847
848 //  // check that calibType refers to a "valid" detector name
849 //  Bool_t isDetector = kFALSE;
850 //  for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
851 //    TString detName = fgkDetectorName[iDet];
852 //    if(aPath.GetLevel0() == detName) {
853 //      isDetector = kTRUE;
854 //      break;
855 //    }
856 //  }
857 //
858 //  if(!isDetector) {
859 //      AliError(Form("Not a valid detector: %s", aPath.GetLevel0().Data()));
860 //      return;
861 //  }
862
863   TObject* obj = fSpecCDBUri.FindObject(aPath.GetPath().Data());
864   if (obj) fSpecCDBUri.Remove(obj);
865   fSpecCDBUri.Add(new TNamed(aPath.GetPath().Data(), uri));
866
867 }
868
869 //_____________________________________________________________________________
870 Bool_t AliReconstruction::SetRunNumberFromData()
871 {
872   // The method is called in Run() in order
873   // to set a correct run number.
874   // In case of raw data reconstruction the
875   // run number is taken from the raw data header
876
877   if (fSetRunNumberFromDataCalled) return kTRUE;
878   fSetRunNumberFromDataCalled = kTRUE;
879   
880   AliCDBManager* man = AliCDBManager::Instance();
881  
882   if(fRawReader) {
883     if(fRawReader->NextEvent()) {
884       if(man->GetRun() > 0) {
885         AliWarning("Run number is taken from raw-event header! Ignoring settings in AliCDBManager!");
886       } 
887       man->SetRun(fRawReader->GetRunNumber());
888       GetEventInfo();
889       fRawReader->RewindEvents();
890     }
891     else {
892       if(man->GetRun() > 0) {
893         AliWarning("No raw-data events are found ! Using settings in AliCDBManager !");
894       }
895       else {
896         AliWarning("Neither raw events nor settings in AliCDBManager are found !");
897         return kFALSE;
898       }
899     }
900   }
901   else {
902     AliRunLoader *rl = AliRunLoader::Open(fGAliceFileName.Data());
903     if (!rl) {
904       AliError(Form("No run loader found in file %s", fGAliceFileName.Data()));
905       return kFALSE;
906     }
907     else {
908       rl->LoadHeader();
909       // read run number from gAlice
910       if(rl->GetHeader()) {
911         man->SetRun(rl->GetHeader()->GetRun());
912         rl->UnloadHeader();
913         delete rl;
914       }
915       else {
916         AliError("Neither run-loader header nor RawReader objects are found !");
917         delete rl;
918         return kFALSE;
919       }
920     }
921   }
922
923   man->Print();  
924   
925   return kTRUE;
926 }
927
928 //_____________________________________________________________________________
929 void AliReconstruction::SetCDBLock() {
930   // Set CDB lock: from now on it is forbidden to reset the run number
931   // or the default storage or to activate any further storage!
932   
933   AliCDBManager::Instance()->SetLock(1);
934 }
935
936 //_____________________________________________________________________________
937 void AliReconstruction::MatchUpgradeDetector() {
938   // Translates detector name in a boolean.
939   // The boolean is used in GetReconstructor to load the 
940   // upgrade reconstructor instead of the standard one.
941    for(Int_t iDet = 0; iDet < kNDetectors; iDet++) {
942     if(fUpgradeModule.Contains(fgkDetectorName[iDet])) fUpgradeMask[iDet]=kTRUE;
943    }
944 }
945 //_____________________________________________________________________________
946 Bool_t AliReconstruction::MisalignGeometry(const TString& detectors)
947 {
948   // Read the alignment objects from CDB.
949   // Each detector is supposed to have the
950   // alignment objects in DET/Align/Data CDB path.
951   // All the detector objects are then collected,
952   // sorted by geometry level (starting from ALIC) and
953   // then applied to the TGeo geometry.
954   // Finally an overlaps check is performed.
955
956   // Load alignment data from CDB and fill fAlignObjArray 
957   if(fLoadAlignFromCDB){
958         
959     TString detStr = detectors;
960     TString loadAlObjsListOfDets = "";
961     
962     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
963       if(!IsSelected(fgkDetectorName[iDet], detStr)) continue;
964       if(!strcmp(fgkDetectorName[iDet],"HLT")) continue;
965       
966       if(AliGeomManager::GetNalignable(fgkDetectorName[iDet]) != 0)
967       {
968         loadAlObjsListOfDets += fgkDetectorName[iDet];
969         loadAlObjsListOfDets += " ";
970       }
971     } // end loop over detectors
972     
973     if(AliGeomManager::GetNalignable("GRP") != 0)
974       loadAlObjsListOfDets.Prepend("GRP "); //add alignment objects for non-sensitive modules
975     AliGeomManager::ApplyAlignObjsFromCDB(loadAlObjsListOfDets.Data());
976   }else{
977     // Check if the array with alignment objects was
978     // provided by the user. If yes, apply the objects
979     // to the present TGeo geometry
980     if (fAlignObjArray) {
981       if (gGeoManager && gGeoManager->IsClosed()) {
982         if (AliGeomManager::ApplyAlignObjsToGeom(*fAlignObjArray) == kFALSE) {
983           AliError("The misalignment of one or more volumes failed!"
984                    "Compare the list of simulated detectors and the list of detector alignment data!");
985           return kFALSE;
986         }
987       }
988       else {
989         AliError("Can't apply the misalignment! gGeoManager doesn't exist or it is still opened!");
990         return kFALSE;
991       }
992     }
993   }
994   
995   if (fAlignObjArray) {
996     fAlignObjArray->Delete();
997     delete fAlignObjArray; fAlignObjArray=NULL;
998   }
999
1000   return kTRUE;
1001 }
1002
1003 //_____________________________________________________________________________
1004 void AliReconstruction::SetGAliceFile(const char* fileName)
1005 {
1006 // set the name of the galice file
1007
1008   fGAliceFileName = fileName;
1009 }
1010
1011 //_____________________________________________________________________________
1012 void AliReconstruction::SetInput(const char* input) 
1013 {
1014   // In case the input string starts with 'mem://', we run in an online mode
1015   // and AliRawReaderDateOnline object is created. In all other cases a raw-data
1016   // file is assumed. One can give as an input:
1017   // mem://: - events taken from DAQ monitoring libs online
1018   //  or
1019   // mem://<filename> - emulation of the above mode (via DATE monitoring libs)
1020   if (input) fRawInput = input;
1021 }
1022
1023 //_____________________________________________________________________________
1024 void AliReconstruction::SetOutput(const char* output) 
1025 {
1026   // Set the output ESD filename
1027   // 'output' is a normalt ROOT url
1028   // The method is used in case of raw-data reco with PROOF
1029   if (output) fESDOutput = output;
1030 }
1031
1032 //_____________________________________________________________________________
1033 void AliReconstruction::SetOption(const char* detector, const char* option)
1034 {
1035 // set options for the reconstruction of a detector
1036
1037   TObject* obj = fOptions.FindObject(detector);
1038   if (obj) fOptions.Remove(obj);
1039   fOptions.Add(new TNamed(detector, option));
1040 }
1041
1042 //_____________________________________________________________________________
1043 void AliReconstruction::SetRecoParam(const char* detector, AliDetectorRecoParam *par)
1044 {
1045   // Set custom reconstruction parameters for a given detector
1046   // Single set of parameters for all the events
1047
1048   // First check if the reco-params are global
1049   if(!strcmp(detector, "GRP")) {
1050     par->SetAsDefault();
1051     fRecoParam.AddDetRecoParam(kNDetectors,par);
1052     return;
1053   }
1054
1055   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1056     if(!strcmp(detector, fgkDetectorName[iDet])) {
1057       par->SetAsDefault();
1058       fRecoParam.AddDetRecoParam(iDet,par);
1059       break;
1060     }
1061   }
1062
1063 }
1064
1065 //_____________________________________________________________________________
1066 Bool_t AliReconstruction::InitGRP() {
1067   //------------------------------------
1068   // Initialization of the GRP entry 
1069   //------------------------------------
1070   AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/GRP/Data");
1071
1072   if (entry) {
1073
1074     TMap* m = dynamic_cast<TMap*>(entry->GetObject());  // old GRP entry
1075
1076     if (m) {
1077        AliInfo("Found a TMap in GRP/GRP/Data, converting it into an AliGRPObject");
1078        m->Print();
1079        fGRPData = new AliGRPObject();
1080        fGRPData->ReadValuesFromMap(m);
1081     }
1082
1083     else {
1084        AliInfo("Found an AliGRPObject in GRP/GRP/Data, reading it");
1085        fGRPData = dynamic_cast<AliGRPObject*>(entry->GetObject());  // new GRP entry
1086        entry->SetOwner(0);
1087     }
1088
1089     //    FIX ME: The unloading of GRP entry is temporarily disabled
1090     //    because ZDC and VZERO are using it in order to initialize
1091     //    their reconstructor objects. In the future one has to think
1092     //    of propagating AliRunInfo to the reconstructors.
1093     //    AliCDBManager::Instance()->UnloadFromCache("GRP/GRP/Data");
1094   }
1095
1096   if (!fGRPData) {
1097      AliError("No GRP entry found in OCDB!");
1098      return kFALSE;
1099   }
1100
1101   TString lhcState = fGRPData->GetLHCState();
1102   if (lhcState==AliGRPObject::GetInvalidString()) {
1103     AliError("GRP/GRP/Data entry:  missing value for the LHC state ! Using UNKNOWN");
1104     lhcState = "UNKNOWN";
1105   }
1106
1107   TString beamType = fGRPData->GetBeamType();
1108   if (beamType==AliGRPObject::GetInvalidString()) {
1109     AliError("GRP/GRP/Data entry:  missing value for the beam type ! Using UNKNOWN");
1110     beamType = "UNKNOWN";
1111   }
1112
1113   Float_t beamEnergy = fGRPData->GetBeamEnergy();
1114   if (beamEnergy==AliGRPObject::GetInvalidFloat()) {
1115     AliError("GRP/GRP/Data entry:  missing value for the beam energy ! Using 0");
1116     beamEnergy = 0;
1117   }
1118
1119   TString runType = fGRPData->GetRunType();
1120   if (runType==AliGRPObject::GetInvalidString()) {
1121     AliError("GRP/GRP/Data entry:  missing value for the run type ! Using UNKNOWN");
1122     runType = "UNKNOWN";
1123   }
1124
1125   Int_t activeDetectors = fGRPData->GetDetectorMask();
1126   if (activeDetectors==AliGRPObject::GetInvalidUInt()) {
1127     AliError("GRP/GRP/Data entry:  missing value for the detector mask ! Using 1074790399");
1128     activeDetectors = 1074790399;
1129   }
1130   AliDebug(1, Form("activeDetectors = %d", activeDetectors));
1131
1132   fRunInfo = new AliRunInfo(lhcState, beamType, beamEnergy, runType, activeDetectors);
1133   fRunInfo->Dump();
1134
1135
1136   // Process the list of active detectors
1137   if (activeDetectors) {
1138     UInt_t detMask = activeDetectors;
1139     AliDebug(1, Form("Detector List = %s", fRunLocalReconstruction.Data()));
1140     fRunLocalReconstruction = MatchDetectorList(fRunLocalReconstruction,detMask);
1141     AliDebug(1, Form("Detector List = %s", fRunLocalReconstruction.Data()));
1142     fRunTracking = MatchDetectorList(fRunTracking,detMask);
1143     fFillESD = MatchDetectorList(fFillESD,detMask);
1144     fQADetectors = MatchDetectorList(fQADetectors,detMask);
1145     AliInfo(Form("fQADetectors=%s",fQADetectors.Data()));
1146     fDeleteRecPoints = MatchDetectorList(fDeleteRecPoints,detMask);
1147     fDeleteDigits    = MatchDetectorList(fDeleteDigits,detMask);
1148     fLoadCDB.Form("%s %s %s %s",
1149                   fRunLocalReconstruction.Data(),
1150                   fRunTracking.Data(),
1151                   fFillESD.Data(),
1152                   fQADetectors.Data());
1153     fLoadCDB = MatchDetectorList(fLoadCDB,detMask);
1154     if (!((detMask >> AliDAQ::DetectorID("ITSSPD")) & 0x1) &&
1155         !((detMask >> AliDAQ::DetectorID("ITSSDD")) & 0x1) &&
1156         !((detMask >> AliDAQ::DetectorID("ITSSSD")) & 0x1) ) {
1157       // switch off the vertexer
1158       AliInfo("SPD,SDD,SSD is not in the list of active detectors. Vertexer and Trackleter are switched off.");
1159       fRunVertexFinder = kFALSE;
1160       fRunMultFinder = kFALSE;
1161     }
1162     if (!((detMask >> AliDAQ::DetectorID("TRG")) & 0x1)) {
1163       // switch off the reading of CTP raw-data payload
1164       if (fFillTriggerESD) {
1165         AliInfo("CTP is not in the list of active detectors. CTP data reading switched off.");
1166         fFillTriggerESD = kFALSE;
1167       }
1168     }
1169   }
1170
1171   AliInfo("===================================================================================");
1172   AliInfo(Form("Running local reconstruction for detectors: %s",fRunLocalReconstruction.Data()));
1173   AliInfo(Form("Running tracking for detectors: %s",fRunTracking.Data()));
1174   AliInfo(Form("Filling ESD for detectors: %s",fFillESD.Data()));
1175   AliInfo(Form("Quality assurance is active for detectors: %s",fQADetectors.Data()));
1176   AliInfo(Form("CDB and reconstruction parameters are loaded for detectors: %s",fLoadCDB.Data()));
1177   AliInfo("===================================================================================");
1178
1179   //*** Dealing with the magnetic field map
1180   if ( TGeoGlobalMagField::Instance()->IsLocked() ) {
1181     if (TGeoGlobalMagField::Instance()->GetField()->TestBit(AliMagF::kOverrideGRP)) {
1182       AliInfo("ExpertMode!!! GRP information will be ignored !");
1183       AliInfo("ExpertMode!!! Running with the externally locked B field !");
1184     }
1185     else {
1186       AliInfo("Destroying existing B field instance!");
1187       delete TGeoGlobalMagField::Instance();
1188     }    
1189   }
1190   if ( !TGeoGlobalMagField::Instance()->IsLocked() ) {
1191     // Construct the field map out of the information retrieved from GRP.
1192     Bool_t ok = kTRUE;
1193     // L3
1194     Float_t l3Current = fGRPData->GetL3Current((AliGRPObject::Stats)0);
1195     if (l3Current == AliGRPObject::GetInvalidFloat()) {
1196       AliError("GRP/GRP/Data entry:  missing value for the L3 current !");
1197       ok = kFALSE;
1198     }
1199     
1200     Char_t l3Polarity = fGRPData->GetL3Polarity();
1201     if (l3Polarity == AliGRPObject::GetInvalidChar()) {
1202       AliError("GRP/GRP/Data entry:  missing value for the L3 polarity !");
1203       ok = kFALSE;
1204     }
1205
1206     // Dipole
1207     Float_t diCurrent = fGRPData->GetDipoleCurrent((AliGRPObject::Stats)0);
1208     if (diCurrent == AliGRPObject::GetInvalidFloat()) {
1209       AliError("GRP/GRP/Data entry:  missing value for the dipole current !");
1210       ok = kFALSE;
1211     }
1212
1213     Char_t diPolarity = fGRPData->GetDipolePolarity();
1214     if (diPolarity == AliGRPObject::GetInvalidChar()) {
1215       AliError("GRP/GRP/Data entry:  missing value for the dipole polarity !");
1216       ok = kFALSE;
1217     }
1218
1219     // read special bits for the polarity convention and map type
1220     Int_t  polConvention = fGRPData->IsPolarityConventionLHC() ? AliMagF::kConvLHC : AliMagF::kConvDCS2008;
1221     Bool_t uniformB = fGRPData->IsUniformBMap();
1222
1223     if (ok) { 
1224       AliMagF* fld = AliMagF::CreateFieldMap(TMath::Abs(l3Current) * (l3Polarity ? -1:1), 
1225                                              TMath::Abs(diCurrent) * (diPolarity ? -1:1), 
1226                                              polConvention,uniformB,beamEnergy, beamType.Data());
1227       if (fld) {
1228         TGeoGlobalMagField::Instance()->SetField( fld );
1229         TGeoGlobalMagField::Instance()->Lock();
1230         AliInfo("Running with the B field constructed out of GRP !");
1231       }
1232       else AliFatal("Failed to create a B field map !");
1233     }
1234     else AliFatal("B field is neither set nor constructed from GRP ! Exitig...");
1235   }
1236   
1237   //*** Get the diamond profiles from OCDB
1238   entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexSPD");
1239   if (entry) {
1240     fDiamondProfileSPD = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1241   } else {
1242      AliError("No SPD diamond profile found in OCDB!");
1243   }
1244
1245   entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertex");
1246   if (entry) {
1247     fDiamondProfile = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1248   } else {
1249      AliError("No diamond profile found in OCDB!");
1250   }
1251
1252   entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexTPC");
1253   if (entry) {
1254     fDiamondProfileTPC = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1255   } else {
1256      AliError("No TPC diamond profile found in OCDB!");
1257   }
1258
1259   entry = AliCDBManager::Instance()->Get("GRP/Calib/CosmicTriggers");
1260   if (entry) {
1261     fListOfCosmicTriggers = dynamic_cast<THashTable*>(entry->GetObject());
1262     entry->SetOwner(0);
1263   }
1264
1265   if (!fListOfCosmicTriggers) {
1266     AliWarning("Can not get list of cosmic triggers from OCDB! Cosmic event specie will be effectively disabled!");
1267   }
1268
1269   return kTRUE;
1270
1271
1272 //_____________________________________________________________________________
1273 Bool_t AliReconstruction::LoadCDB()
1274 {
1275   // Load CDB entries for all active detectors.
1276   // By default we load all the entries in <det>/Calib
1277   // folder.
1278
1279   AliCodeTimerAuto("",0);
1280
1281   AliCDBManager::Instance()->Get("GRP/CTP/Config");
1282
1283   AliCDBManager::Instance()->Get("GRP/Calib/LHCClockPhase");
1284
1285   TString detStr = fLoadCDB;
1286   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1287     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1288     AliCDBManager::Instance()->GetAll(Form("%s/Calib/*",fgkDetectorName[iDet]));
1289     AliCDBManager::Instance()->GetAll(Form("%s/Trigger/*",fgkDetectorName[iDet]));
1290   }
1291
1292   // Temporary fix - one has to define the correct policy in order
1293   // to load the trigger OCDB entries only for the detectors that
1294   // in the trigger or that are needed in order to put correct
1295   // information in ESD
1296   AliCDBManager::Instance()->GetAll("TRIGGER/*/*");
1297   AliCDBManager::Instance()->GetAll("HLT/*/*");
1298
1299   return kTRUE;
1300 }
1301 //_____________________________________________________________________________
1302 Bool_t AliReconstruction::LoadTriggerScalersCDB()
1303 {
1304   // Load CTP scalers from OCDB.
1305   // The scalers are checked for consistency.
1306
1307   AliCodeTimerAuto("",0);
1308
1309   AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/CTP/Scalers");
1310
1311   if (entry) { 
1312    
1313        AliInfo("Found an AliTriggerRunScalers in GRP/CTP/Scalers, reading it");
1314        fRunScalers = dynamic_cast<AliTriggerRunScalers*> (entry->GetObject());
1315        entry->SetOwner(0);
1316        if (fRunScalers && (fRunScalers->CorrectScalersOverflow() == 0)) AliInfo("32bit Trigger counters corrected for overflow");
1317
1318   }
1319   return kTRUE;
1320 }
1321 //_____________________________________________________________________________
1322 Bool_t AliReconstruction::LoadCTPTimeParamsCDB()
1323 {
1324   // Load CTP timing information (alignment)
1325   // from OCDB.
1326
1327   AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/CTP/CTPtiming");
1328   if (!entry) return kFALSE;
1329
1330   AliInfo("Found an AliCTPTimeParams in GRP/CTP/CTPtiming, reading it");
1331   fCTPTimeParams = dynamic_cast<AliCTPTimeParams*> (entry->GetObject());
1332   entry->SetOwner(0);
1333
1334   AliCDBEntry* entry2 = AliCDBManager::Instance()->Get("GRP/CTP/TimeAlign");
1335   if (!entry2) return kFALSE;
1336
1337   AliInfo("Found an AliCTPTimeParams in GRP/CTP/TimeAlign, reading it");
1338   fCTPTimeAlign = dynamic_cast<AliCTPTimeParams*> (entry2->GetObject());
1339   entry2->SetOwner(0);
1340
1341   return kTRUE;
1342 }
1343
1344 //_____________________________________________________________________________
1345 Bool_t AliReconstruction::ReadIntensityInfoCDB()
1346 {
1347   // Load LHC DIP data
1348   AliCDBEntry* entry    = AliCDBManager::Instance()->Get("GRP/GRP/LHCData");
1349   AliCDBEntry* entryCTP = AliCDBManager::Instance()->Get("GRP/CTP/Config");
1350   //
1351   if (!entry || !entryCTP) {
1352     AliError(Form("Failed to extract CDB objects GRP/GRP/LHCData: %p or GRP/CTP/Config: %p",entry,entryCTP));
1353     return kFALSE;
1354   }
1355   // extract BC masks
1356   enum {kA,kB,kC,kE,kNMasks};
1357   AliTriggerConfiguration* conf = (AliTriggerConfiguration*)entryCTP->GetObject();
1358   const TObjArray& clArr = conf->GetClasses();
1359   TObjArray masks(kNMasks);
1360   TIter next(&clArr);
1361   AliTriggerClass* trClass = 0;
1362   int nFound = 0;
1363   masks.SetOwner(kFALSE);
1364   //
1365   while ( (trClass=(AliTriggerClass*)next()) ) {
1366     TString trName = trClass->GetName();
1367     int ind = trName.Index("-"); // prefix in front of A,B,C,E
1368     if (ind<1) continue;   // anomaly
1369     //
1370     trName = trName.Data() + ind;
1371     AliTriggerBCMask* bcMask = trClass->GetBCMask();
1372     if (!bcMask) continue;
1373     UInt_t which = 0;
1374     if      (trName.BeginsWith("-A-"))  which |= 0x1<<kA;
1375     else if (trName.BeginsWith("-B-"))  which |= 0x1<<kB;
1376     else if (trName.BeginsWith("-C-"))  which |= 0x1<<kC;
1377     else if (trName.BeginsWith("-E-"))  which |= 0x1<<kE;
1378     else if (trName.BeginsWith("-AC-")) which |= (0x1<<kA) | (0x1<<kC);
1379     else if (trName.BeginsWith("-CA-")) which |= (0x1<<kA) | (0x1<<kC);
1380     else { AliWarning(Form("Unknown trigger type %s\n",trClass->GetName())); continue;}
1381     //
1382     for (int ip=kNMasks;ip--;) {
1383       if ( !(which&(0x1<<ip)) || masks[ip] ) continue; // does not match or already done
1384       masks[ip] = (TObject*)bcMask;
1385       nFound++;
1386     }
1387     if (nFound==kNMasks) break;
1388   }  
1389   //  
1390   AliInfo("Reading mean bunch intensities from GRP/GRP/LHCData");
1391   AliLHCData* dipData = dynamic_cast<AliLHCData*> (entry->GetObject());
1392   //
1393   for (int ib=2;ib--;) {
1394     double intI,intNI;
1395     if (dipData && (dipData->GetMeanIntensity(ib,intI,intNI,&masks)>=0)) {
1396       fBeamInt[ib][0] = intI;
1397       fBeamInt[ib][1] = intNI;  
1398       AliInfo(Form("Mean intensity for beam %d: Interacting:%.2e Non-Interacting:%.2e",ib,intI,intNI));
1399     }
1400   }
1401   return kTRUE;
1402   //
1403 }
1404
1405
1406 //_____________________________________________________________________________
1407 Bool_t AliReconstruction::Run(const char* input)
1408 {
1409   // Run Run Run
1410   AliCodeTimerAuto("",0);
1411
1412   InitRun(input);
1413   if (GetAbort() != TSelector::kContinue) return kFALSE;
1414
1415   TChain *chain = NULL;
1416   if (fRawReader && (chain = fRawReader->GetChain())) {
1417     Long64_t nEntries = (fLastEvent < 0) ? (TChain::kBigNumber) : (fLastEvent - fFirstEvent + 1);
1418     // Proof mode
1419     if (gProof) {
1420       // Temporary fix for long raw-data runs (until socket timeout handling in PROOF is revised)
1421       gProof->Exec("gEnv->SetValue(\"Proof.SocketActivityTimeout\",-1)", kTRUE);
1422
1423       if (gGrid)
1424         gProof->Exec("TGrid::Connect(\"alien://\")",kTRUE);
1425
1426       TMessage::EnableSchemaEvolutionForAll(kTRUE);
1427       gProof->Exec("TMessage::EnableSchemaEvolutionForAll(kTRUE)",kTRUE);
1428
1429       gProof->AddInput(this);
1430
1431       if (!ParseOutput()) return kFALSE;
1432
1433       gProof->SetParameter("PROOF_MaxSlavesPerNode", 9999);
1434       chain->SetProof();
1435       chain->Process("AliReconstruction","",nEntries,fFirstEvent);
1436     }
1437     else {
1438       chain->Process(this,"",nEntries,fFirstEvent);
1439     }
1440   }
1441   else {
1442     Begin(NULL);
1443     if (GetAbort() != TSelector::kContinue) return kFALSE;
1444     SlaveBegin(NULL);
1445     if (GetAbort() != TSelector::kContinue) return kFALSE;
1446     //******* The loop over events
1447     AliInfo("Starting looping over events");
1448     Int_t iEvent = 0;
1449     while ((iEvent < fRunLoader->GetNumberOfEvents()) ||
1450            (fRawReader && fRawReader->NextEvent())) {
1451       //
1452       // check if process has enough resources 
1453       if (!HasEnoughResources(iEvent)) break;
1454       if (!ProcessEvent(iEvent)) {
1455         Abort("ProcessEvent",TSelector::kAbortFile);
1456         return kFALSE;
1457       }
1458       CleanProcessedEvent();
1459       iEvent++;
1460     }
1461     if (!iEvent) AliWarning("No events passed trigger selection");
1462     SlaveTerminate();
1463     if (GetAbort() != TSelector::kContinue) return kFALSE;
1464     Terminate();
1465     if (GetAbort() != TSelector::kContinue) return kFALSE;
1466   }
1467
1468   return kTRUE;
1469 }
1470
1471 //_____________________________________________________________________________
1472 void AliReconstruction::InitRawReader(const char* input)
1473 {
1474   // Init raw-reader and
1475   // set the input in case of raw data
1476
1477   AliCodeTimerAuto("",0);
1478
1479   if (input) fRawInput = input;
1480   fRawReader = AliRawReader::Create(fRawInput.Data());
1481   if (!fRawReader) {
1482     if (fRawInput.IsNull()) {
1483       AliInfo("Reconstruction will run over digits");
1484     }
1485     else {
1486       AliFatal("Can not create raw-data reader ! Exiting..."); 
1487     }
1488   }
1489
1490   if (!fEquipIdMap.IsNull() && fRawReader)
1491     fRawReader->LoadEquipmentIdsMap(fEquipIdMap);
1492
1493   if (!fUseHLTData.IsNull()) {
1494     // create the RawReaderHLT which performs redirection of HLT input data for
1495     // the specified detectors
1496     AliRawReader* pRawReader=AliRawHLTManager::CreateRawReaderHLT(fRawReader, fUseHLTData.Data());
1497     if (pRawReader) {
1498       fParentRawReader=fRawReader;
1499       fRawReader=pRawReader;
1500     } else {
1501       AliError(Form("can not create Raw Reader for HLT input %s", fUseHLTData.Data()));
1502     }
1503   }
1504   AliSysInfo::AddStamp("CreateRawReader");
1505 }
1506
1507 //_____________________________________________________________________________
1508 void AliReconstruction::InitRun(const char* input)
1509 {
1510   // Initialization of raw-reader,
1511   // run number, CDB etc.
1512   AliCodeTimerAuto("",0);
1513   AliSysInfo::AddStamp("Start");
1514
1515   // Initialize raw-reader if any
1516   InitRawReader(input);
1517
1518   // Initialize the CDB storage
1519   InitCDB();
1520
1521   // Set run number in CDBManager (if it is not already set by the user)
1522   if (!SetRunNumberFromData()) {
1523     Abort("SetRunNumberFromData", TSelector::kAbortProcess);
1524     return;
1525   }
1526
1527   // Set CDB lock: from now on it is forbidden to reset the run number
1528   // or the default storage or to activate any further storage!
1529   SetCDBLock();
1530   
1531 }
1532
1533 //_____________________________________________________________________________
1534 void AliReconstruction::Begin(TTree *)
1535 {
1536   // Initialize AlReconstruction before
1537   // going into the event loop
1538   // Should follow the TSelector convention
1539   // i.e. initialize only the object on the client side
1540   AliCodeTimerAuto("",0);
1541
1542   AliReconstruction *reco = NULL;
1543   if (fInput) {
1544     if ((reco = (AliReconstruction*)fInput->FindObject("AliReconstruction"))) {
1545       *this = *reco;
1546     }
1547     AliSysInfo::AddStamp("ReadInputInBegin");
1548   }
1549
1550   // Import ideal TGeo geometry and apply misalignment
1551   if (!AliGeomManager::GetGeometry()) {
1552     TString geom(gSystem->DirName(fGAliceFileName));
1553     geom += "/geometry.root";
1554     AliGeomManager::LoadGeometry(geom.Data());
1555     if (!gGeoManager) {
1556       Abort("LoadGeometry", TSelector::kAbortProcess);
1557       return;
1558     }
1559     AliSysInfo::AddStamp("LoadGeom");
1560     TString detsToCheck=fRunLocalReconstruction;
1561     if(!AliGeomManager::CheckSymNamesLUT(detsToCheck.Data())) {
1562       Abort("CheckSymNamesLUT", TSelector::kAbortProcess);
1563       return;
1564     }
1565     AliSysInfo::AddStamp("CheckGeom");
1566   }
1567
1568   Bool_t toCDBSnapshot=kFALSE;
1569   TString snapshotFileOut(""); // we could use fSnapshotFileName if we are not interested
1570   // in reading from and writing to a snapshot file at the same time
1571   if(TString(getenv("OCDB_SNAPSHOT_CREATE")) == TString("kTRUE")){
1572       toCDBSnapshot=kTRUE;
1573       //fFromCDBSnapshot=kFALSE;
1574       TString snapshotFile(getenv("OCDB_SNAPSHOT_FILENAME"));
1575       if(!(snapshotFile.IsNull() || snapshotFile.IsWhitespace()))
1576           snapshotFileOut = snapshotFile;
1577       else
1578           snapshotFileOut="OCDB.root";
1579   }
1580
1581   if (!MisalignGeometry(fLoadAlignData)) {
1582     Abort("MisalignGeometry", TSelector::kAbortProcess);
1583     return;
1584   }
1585
1586   const TMap* cdbCache = AliCDBManager::Instance()->GetEntryCache();
1587   if(cdbCache->Contains("GRP/Geometry/Data"))
1588           AliCDBManager::Instance()->UnloadFromCache("GRP/Geometry/Data");
1589   if(!toCDBSnapshot) AliCDBManager::Instance()->UnloadFromCache("*/Align/*");
1590   AliSysInfo::AddStamp("MisalignGeom");
1591
1592   if (!InitGRP()) {
1593     Abort("InitGRP", TSelector::kAbortProcess);
1594     return;
1595   }
1596   AliSysInfo::AddStamp("InitGRP");
1597   if(!toCDBSnapshot)
1598       if(cdbCache->Contains("GRP/Calib/CosmicTriggers"))
1599           AliCDBManager::Instance()->UnloadFromCache("GRP/Calib/CosmicTriggers");
1600
1601   if(!fCDBSnapshotMode || toCDBSnapshot){
1602       if (!LoadCDB()) {
1603           Abort("LoadCDB", TSelector::kAbortProcess);
1604           return;
1605       }
1606       AliSysInfo::AddStamp("LoadCDB"); 
1607   }
1608
1609   if (!LoadTriggerScalersCDB()) {
1610     Abort("LoadTriggerScalersCDB", TSelector::kAbortProcess);
1611     return;
1612   }
1613   AliSysInfo::AddStamp("LoadTriggerScalersCDB");
1614
1615   if (!LoadCTPTimeParamsCDB()) {
1616     Abort("LoadCTPTimeParamsCDB", TSelector::kAbortProcess);
1617     return;
1618   }
1619   AliSysInfo::AddStamp("LoadCTPTimeParamsCDB");
1620
1621   if (!ReadIntensityInfoCDB()) {
1622     Abort("ReadIntensityInfoCDB", TSelector::kAbortProcess);
1623     return;
1624   }
1625   AliSysInfo::AddStamp("ReadIntensityInfoCDB");
1626
1627   // Read the reconstruction parameters from OCDB
1628   if (!InitRecoParams()) {
1629     AliWarning("Not all detectors have correct RecoParam objects initialized");
1630   }
1631   AliSysInfo::AddStamp("InitRecoParams");
1632
1633   if(toCDBSnapshot)
1634   {
1635       AliCDBManager::Instance()->DumpToSnapshotFile(snapshotFileOut.Data(),kFALSE);
1636       AliCDBManager::Instance()->UnloadFromCache("*/Align/*");
1637       if(cdbCache->Contains("GRP/Calib/CosmicTriggers"))
1638           AliCDBManager::Instance()->UnloadFromCache("GRP/Calib/CosmicTriggers");
1639   }
1640
1641   if (fInput && gProof) {
1642     if (reco) *reco = *this;
1643
1644     gGeoManager->SetName("Geometry");
1645     gProof->AddInputData(gGeoManager,kTRUE);
1646     gGeoManager = NULL;
1647     gProof->AddInputData(const_cast<TMap*>(AliCDBManager::Instance()->GetEntryCache()),kTRUE);
1648     fInput->Add(new TParameter<Int_t>("RunNumber",AliCDBManager::Instance()->GetRun()));
1649     AliMagF *magFieldMap = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
1650     magFieldMap->SetName("MagneticFieldMap");
1651     gProof->AddInputData(magFieldMap,kTRUE);
1652     if (fAnalysis) {
1653       fAnalysis->SetName("Analysis");
1654       gProof->AddInputData(fAnalysis,kTRUE);
1655     }  
1656   }
1657
1658 }
1659
1660 //_____________________________________________________________________________
1661 void AliReconstruction::SlaveBegin(TTree*)
1662 {
1663   // Initialization related to run-loader,
1664   // vertexer, trackers, recontructors
1665   // In proof mode it is executed on the slave
1666   AliCodeTimerAuto("",0);
1667
1668   TProofOutputFile *outProofFile = NULL;
1669   if (fInput) {
1670     if (AliDebugLevel() > 0) fInput->Print();
1671     if (AliDebugLevel() > 10) fInput->Dump();
1672     if (AliReconstruction *reco = (AliReconstruction*)fInput->FindObject("AliReconstruction")) {
1673       *this = *reco;
1674     }
1675     if (TGeoManager *tgeo = (TGeoManager*)fInput->FindObject("Geometry")) {
1676       gGeoManager = tgeo;
1677       AliGeomManager::SetGeometry(tgeo);
1678     }
1679     if (TMap *entryCache = (TMap*)fInput->FindObject("CDBEntryCache")) {
1680       Int_t runNumber = -1;
1681       if (TProof::GetParameter(fInput,"RunNumber",runNumber) == 0) {
1682         AliCDBManager *man = AliCDBManager::Instance(entryCache,runNumber);
1683         man->SetCacheFlag(kTRUE);
1684         man->SetLock(kTRUE);
1685         man->Print();
1686       }
1687     }
1688     if (AliMagF *map = (AliMagF*)fInput->FindObject("MagneticFieldMap")) {
1689       AliMagF *newMap = new AliMagF(*map);
1690       if (!newMap->LoadParameterization()) {
1691         Abort("AliMagF::LoadParameterization", TSelector::kAbortProcess);
1692         return;
1693       }
1694       TGeoGlobalMagField::Instance()->SetField(newMap);
1695       TGeoGlobalMagField::Instance()->Lock();
1696     }
1697     if (!fAnalysis) {
1698        // Attempt to get the analysis manager from the input list
1699        fAnalysis = (AliAnalysisManager*)fInput->FindObject("Analysis");
1700        if (fAnalysis) AliInfo("==== Analysis manager retrieved from input list ====");
1701     }   
1702     if (TNamed *outputFileName = (TNamed*)fInput->FindObject("PROOF_OUTPUTFILE"))
1703       fProofOutputFileName = outputFileName->GetTitle();
1704     if (TNamed *outputLocation = (TNamed*)fInput->FindObject("PROOF_OUTPUTFILE_LOCATION"))
1705       fProofOutputLocation = outputLocation->GetTitle();
1706     if (fInput->FindObject("PROOF_OUTPUTFILE_DATASET"))
1707       fProofOutputDataset = kTRUE;
1708     if (TNamed *archiveList = (TNamed*)fInput->FindObject("PROOF_OUTPUTFILE_ARCHIVE"))
1709       fProofOutputArchive = archiveList->GetTitle();
1710     if (!fProofOutputFileName.IsNull() &&
1711         !fProofOutputLocation.IsNull() &&
1712         fProofOutputArchive.IsNull()) {
1713       if (!fProofOutputDataset) {
1714         outProofFile = new TProofOutputFile(fProofOutputFileName.Data(),"M");
1715         outProofFile->SetOutputFileName(Form("%s%s",fProofOutputLocation.Data(),fProofOutputFileName.Data()));
1716       }
1717       else {
1718         outProofFile = new TProofOutputFile(fProofOutputFileName.Data(),"DROV",fProofOutputLocation.Data());
1719       }
1720       if (AliDebugLevel() > 0) outProofFile->Dump();
1721       fOutput->Add(outProofFile);
1722     }
1723     AliSysInfo::AddStamp("ReadInputInSlaveBegin");
1724   }
1725   // Check if analysis was requested in the reconstruction event loop
1726   if (!fAnalysis) {
1727     // Attempt to connect in-memory singleton
1728     fAnalysis = AliAnalysisManager::GetAnalysisManager();
1729     if (fAnalysis) AliInfo(Form("==== Analysis manager <%s> found in memory ====", fAnalysis->GetName()));
1730     // Check if an analysis macro was specified
1731     if (!fAnalysis && !fAnalysisMacro.IsNull()) {
1732       // Run specified analysis macro
1733       gROOT->ProcessLine(Form(".x %s",fAnalysisMacro.Data()));
1734       fAnalysis = AliAnalysisManager::GetAnalysisManager();
1735       if (!fAnalysis) AliError(Form("No analysis manager produced by analysis macro %s", fAnalysisMacro.Data()));
1736       else AliInfo(Form("==== Analysis manager <%s> produced by analysis macro <%s> ====", 
1737                         fAnalysis->GetName(), fAnalysisMacro.Data()));
1738     }
1739   }
1740   
1741   // get the run loader
1742   if (!InitRunLoader()) {
1743     Abort("InitRunLoader", TSelector::kAbortProcess);
1744     return;
1745   }
1746   AliSysInfo::AddStamp("LoadLoader");
1747  
1748   ftVertexer = new AliVertexerTracks(AliTracker::GetBz());
1749
1750   // get trackers
1751   if (!fRunTracking.IsNull() && !CreateTrackers(fRunTracking)) {
1752     Abort("CreateTrackers", TSelector::kAbortProcess);
1753     return;
1754   }      
1755   AliSysInfo::AddStamp("CreateTrackers");
1756
1757   // create the ESD output file and tree
1758   if (!outProofFile) {
1759     ffile = TFile::Open("AliESDs.root", "RECREATE");
1760     ffile->SetCompressionLevel(2);
1761     if (!ffile->IsOpen()) {
1762       Abort("OpenESDFile", TSelector::kAbortProcess);
1763       return;
1764     }
1765   }
1766   else {
1767     AliInfo(Form("Opening output PROOF file: %s/%s",
1768                  outProofFile->GetDir(), outProofFile->GetFileName()));
1769     if (!(ffile = outProofFile->OpenFile("RECREATE"))) {
1770       Abort(Form("Problems opening output PROOF file: %s/%s",
1771                  outProofFile->GetDir(), outProofFile->GetFileName()),
1772             TSelector::kAbortProcess);
1773       return;
1774     }
1775   }
1776
1777   ftree = new TTree("esdTree", "Tree with ESD objects");
1778   fesd = new AliESDEvent();
1779   fesd->CreateStdContent();
1780   // add a so far non-std object to the ESD, this will
1781   // become part of the std content
1782   fesd->AddObject(new AliESDHLTDecision);
1783
1784   fesd->WriteToTree(ftree);
1785   if (fWriteESDfriend) {
1786     ffileF = TFile::Open("AliESDfriends.root", "RECREATE");
1787     ftreeF = new TTree("esdFriendTree", "Tree with ESD Friend objects");
1788     fesdf  = new AliESDfriend();
1789     ftreeF->Branch("ESDfriend.","AliESDfriend", &fesdf);
1790     fesd->AddObject(fesdf);
1791     ffile->cd();
1792   }
1793   ftree->GetUserInfo()->Add(fesd);
1794
1795   fhlttree = new TTree("HLTesdTree", "Tree with HLT ESD objects");
1796   fhltesd = new AliESDEvent();
1797   fhltesd->CreateStdContent();
1798   // read the ESD template from CDB
1799   // HLT is allowed to put non-std content to its ESD, the non-std
1800   // objects need to be created before invocation of WriteToTree in
1801   // order to create all branches. Initialization is done from an
1802   // ESD layout template in CDB
1803   AliCDBManager* man = AliCDBManager::Instance();
1804   AliCDBEntry* hltESDConfig = man->Get("HLT/Calib/esdLayout");
1805   if(!hltESDConfig){
1806       AliError(Form("Error getting \"HLT/Calib/esdLayout\""));
1807       return;
1808   }
1809   AliESDEvent* pESDLayout=dynamic_cast<AliESDEvent*>(hltESDConfig->GetObject());
1810   if (pESDLayout) {
1811       // init all internal variables from the list of objects
1812       pESDLayout->GetStdContent();
1813
1814       // copy content and create non-std objects
1815       *fhltesd=*pESDLayout;
1816       fhltesd->Reset();
1817   } else {
1818       AliError(Form("error setting hltEsd layout from \"HLT/Calib/esdLayout\": invalid object type"));
1819   }
1820
1821   fhltesd->WriteToTree(fhlttree);
1822   fhlttree->GetUserInfo()->Add(fhltesd);
1823
1824   ProcInfo_t procInfo;
1825   gSystem->GetProcInfo(&procInfo);
1826   AliInfo(Form("Current memory usage %ld %ld", procInfo.fMemResident, procInfo.fMemVirtual));
1827   
1828   // PID
1829   fESDpid = new AliESDpid();
1830
1831   //QA
1832   //Initialize the QA and start of cycle 
1833   if (fRunQA || fRunGlobalQA) 
1834     InitQA() ; 
1835
1836   //Initialize the Plane Efficiency framework
1837   if (fRunPlaneEff && !InitPlaneEff()) {
1838     Abort("InitPlaneEff", TSelector::kAbortProcess);
1839     return;
1840   }
1841
1842   if (strcmp(gProgName,"alieve") == 0)
1843     fRunAliEVE = InitAliEVE();
1844   // If we have an analysis manager, connect the AliRecoInputHandler here  
1845   if (fAnalysis) {
1846     if (!dynamic_cast<AliRecoInputHandler*>(fAnalysis->GetInputEventHandler())) {
1847        AliError("Analysis manager used in reconstruction should use AliRecoInputHandler - \
1848                  \n  ->Replacing with AliRecoInputHandler instance.");
1849        delete fAnalysis->GetInputEventHandler();
1850     }
1851     // Set the event and other data pointers
1852     fRecoHandler = new AliRecoInputHandler();
1853 //    fRecoHandler->Init(ftree, "LOCAL");
1854     fRecoHandler->SetEvent(fesd);
1855     fRecoHandler->SetESDfriend(fesdf);
1856     fRecoHandler->SetHLTEvent(fhltesd);
1857     fRecoHandler->SetHLTTree(fhlttree);
1858     fAnalysis->SetInputEventHandler(fRecoHandler);
1859     // Enter external loop mode
1860     fAnalysis->SetExternalLoop(kTRUE);
1861     // Initialize analysis
1862     fAnalysis->SlaveBegin(ftree);
1863     fAnalysis->StartAnalysis("local", (TTree*)0);
1864     // Connect ESD tree with the input container
1865     fAnalysis->GetCommonInputContainer()->SetData(ftree);
1866   }  
1867   return;
1868 }
1869
1870 //_____________________________________________________________________________
1871 Bool_t AliReconstruction::Process(Long64_t entry)
1872 {
1873   // run the reconstruction over a single entry
1874   // from the chain with raw data
1875   AliCodeTimerAuto("",0);
1876
1877   TTree *currTree = fChain->GetTree();
1878   AliRawVEvent *event = NULL;
1879   currTree->SetBranchAddress("rawevent",&event);
1880   currTree->GetEntry(entry);
1881   fRawReader = new AliRawReaderRoot(event);
1882   // check if process has enough resources 
1883   if (!HasEnoughResources(entry)) return kFALSE;
1884   fStatus = ProcessEvent(fRunLoader->GetNumberOfEvents());
1885   delete fRawReader;
1886   fRawReader = NULL;
1887   delete event;
1888
1889   return fStatus;
1890 }
1891
1892 //_____________________________________________________________________________
1893 void AliReconstruction::Init(TTree *tree)
1894 {
1895   // Implementation of TSelector::Init()
1896   // method
1897   if (tree == 0) {
1898     AliError("The input tree is not found!");
1899     return;
1900   }
1901   fChain = tree;
1902 }
1903
1904 //_____________________________________________________________________________
1905 Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
1906 {
1907   // run the reconstruction over a single event
1908   // The event loop is steered in Run method
1909
1910
1911   static Long_t oldMres=0;
1912   static Long_t oldMvir=0;
1913   static Float_t oldCPU=0;
1914   static Long_t aveDMres=0;
1915   static Long_t aveDMvir=0;
1916   static Float_t aveDCPU=0;
1917
1918   AliCodeTimerAuto("",0);
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(fESDpid);
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,*fESDpid)) {
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->GetMassForTracking(),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->GetMassForTracking(),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,fESDpid);
2307
2308     // combined PID
2309     //    fESDpid->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.MakePIDForTracking(esd);
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.MakePIDForTracking(esd);
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   delete fESDpid;
3563   fESDpid = NULL;
3564
3565   if (ffile) {
3566     ffile->Close();
3567     delete ffile;
3568     ffile = NULL;
3569   }
3570
3571   if (AliQAManager::QAManager())
3572     AliQAManager::QAManager()->ShowQA() ; 
3573   //  AliQAManager::Destroy() ;
3574   delete fAnalysis; 
3575   fAnalysis = NULL;
3576 }
3577
3578 void AliReconstruction::WriteAlignmentData(AliESDEvent* esd)
3579 {
3580   // Write space-points which are then used in the alignment procedures
3581   // For the moment only ITS, TPC, TRD and TOF
3582
3583   Int_t ntracks = esd->GetNumberOfTracks();
3584   for (Int_t itrack = 0; itrack < ntracks; itrack++)
3585     {
3586       AliESDtrack *track = esd->GetTrack(itrack);
3587       Int_t nsp = 0;
3588       Int_t idx[200];
3589       for (Int_t i=0; i<200; ++i) idx[i] = -1; //PH avoid uninitialized values
3590       for (Int_t iDet = 5; iDet >= 0; iDet--) {// TOF, TRD, TPC, ITS clusters
3591           nsp += (iDet==GetDetIndex("TRD")) ? track->GetTRDntracklets():track->GetNcls(iDet);
3592
3593           if (iDet==GetDetIndex("ITS")) { // ITS "extra" clusters
3594              track->GetClusters(iDet,idx);
3595              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nsp++;
3596           }  
3597       }
3598
3599       if (nsp) {
3600         AliTrackPointArray *sp = new AliTrackPointArray(nsp);
3601         track->SetTrackPointArray(sp);
3602         Int_t isptrack = 0;
3603         for (Int_t iDet = 5; iDet >= 0; iDet--) {
3604           AliTracker *tracker = fTracker[iDet];
3605           if (!tracker) continue;
3606           Int_t nspdet = (iDet==GetDetIndex("TRD")) ? track->GetTRDtracklets(idx):track->GetClusters(iDet,idx);
3607
3608           if (iDet==GetDetIndex("ITS")) // ITS "extra" clusters             
3609              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nspdet++;
3610
3611           if (nspdet <= 0) continue;
3612           AliTrackPoint p;
3613           Int_t isp = 0;
3614           Int_t isp2 = 0;
3615           while (isp2 < nspdet) {
3616             Bool_t isvalid=kTRUE;
3617
3618             Int_t index=idx[isp++];
3619             if (index < 0) continue;
3620
3621             TString dets = fgkDetectorName[iDet];
3622             if ((fUseTrackingErrorsForAlignment.CompareTo(dets) == 0) ||
3623             fUseTrackingErrorsForAlignment.BeginsWith(dets+" ") ||
3624             fUseTrackingErrorsForAlignment.EndsWith(" "+dets) ||
3625             fUseTrackingErrorsForAlignment.Contains(" "+dets+" ")) {
3626               isvalid = tracker->GetTrackPointTrackingError(index,p,track);
3627             } else {
3628               isvalid = tracker->GetTrackPoint(index,p); 
3629             } 
3630             isp2++;
3631             if (!isvalid) continue;
3632             if (iDet==GetDetIndex("ITS") && (isp-1)>=6) p.SetExtra();
3633             sp->AddPoint(isptrack,&p); isptrack++;
3634           }
3635         }       
3636       }
3637     }
3638 }
3639
3640 //_____________________________________________________________________________
3641 void AliReconstruction::FillRawDataErrorLog(Int_t iEvent, AliESDEvent* esd)
3642 {
3643   // The method reads the raw-data error log
3644   // accumulated within the rawReader.
3645   // It extracts the raw-data errors related to
3646   // the current event and stores them into
3647   // a TClonesArray inside the esd object.
3648
3649   if (!fRawReader) return;
3650
3651   for(Int_t i = 0; i < fRawReader->GetNumberOfErrorLogs(); i++) {
3652
3653     AliRawDataErrorLog *log = fRawReader->GetErrorLog(i);
3654     if (!log) continue;
3655     if (iEvent != log->GetEventNumber()) continue;
3656
3657     esd->AddRawDataErrorLog(log);
3658   }
3659
3660 }
3661
3662 //_____________________________________________________________________________
3663 // void AliReconstruction::CheckQA()
3664 // {
3665 // check the QA of SIM for this run and remove the detectors 
3666 // with status Fatal
3667   
3668 //      TString newRunLocalReconstruction ; 
3669 //      TString newRunTracking ;
3670 //      TString newFillESD ;
3671 //       
3672 //      for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
3673 //              TString detName(AliQAv1::GetDetName(iDet)) ;
3674 //              AliQAv1 * qa = AliQAv1::Instance(AliQAv1::DETECTORINDEX_t(iDet)) ;       
3675 //      if ( qa->IsSet(AliQAv1::DETECTORINDEX_t(iDet), AliQAv1::kSIM, specie, AliQAv1::kFATAL)) {
3676 //        AliInfo(Form("QA status for %s %s in Hits and/or SDIGITS  and/or Digits was Fatal; No reconstruction performed", 
3677 //                   detName.Data(), AliRecoParam::GetEventSpecieName(es))) ;
3678 //                      } else {
3679 //                      if ( fRunLocalReconstruction.Contains(AliQAv1::GetDetName(iDet)) || 
3680 //                                      fRunLocalReconstruction.Contains("ALL") )  {
3681 //                              newRunLocalReconstruction += detName ; 
3682 //                              newRunLocalReconstruction += " " ;                      
3683 //                      }
3684 //                      if ( fRunTracking.Contains(AliQAv1::GetDetName(iDet)) || 
3685 //                                      fRunTracking.Contains("ALL") )  {
3686 //                              newRunTracking += detName ; 
3687 //                              newRunTracking += " " ;                         
3688 //                      }
3689 //                      if ( fFillESD.Contains(AliQAv1::GetDetName(iDet)) || 
3690 //                                      fFillESD.Contains("ALL") )  {
3691 //                              newFillESD += detName ; 
3692 //                              newFillESD += " " ;                     
3693 //                      }
3694 //              }
3695 //      }
3696 //      fRunLocalReconstruction = newRunLocalReconstruction ; 
3697 //      fRunTracking            = newRunTracking ; 
3698 //      fFillESD                = newFillESD ; 
3699 // }
3700
3701 //_____________________________________________________________________________
3702 Int_t AliReconstruction::GetDetIndex(const char* detector)
3703 {
3704   // return the detector index corresponding to detector
3705   Int_t index = -1 ; 
3706   for (index = 0; index < kNDetectors ; index++) {
3707     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
3708         break ; 
3709   }     
3710   return index ; 
3711 }
3712 //_____________________________________________________________________________
3713 Bool_t AliReconstruction::FinishPlaneEff() {
3714  //
3715  // Here execute all the necessary operationis, at the end of the tracking phase,
3716  // in case that evaluation of PlaneEfficiencies was required for some detector.
3717  // E.g., write into a DataBase file the PlaneEfficiency which have been evaluated.
3718  //
3719  // This Preliminary version works only FOR ITS !!!!!
3720  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3721  //
3722  //  Input: none
3723  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3724  //
3725  Bool_t ret=kFALSE;
3726  TString detStr = fLoadCDB;
3727  //for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
3728  for (Int_t iDet = 0; iDet < 1; iDet++) { // for the time being only ITS
3729    if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3730    if(fTracker[iDet] && fTracker[iDet]->GetPlaneEff()) {
3731       AliPlaneEff *planeeff=fTracker[iDet]->GetPlaneEff();
3732       TString name=planeeff->GetName();
3733       name+=".root";
3734       TFile* pefile = TFile::Open(name, "RECREATE");
3735       ret=(Bool_t)planeeff->Write();
3736       pefile->Close();
3737       if(planeeff->GetCreateHistos()) {
3738         TString hname=planeeff->GetName();
3739         hname+="Histo.root";
3740         ret*=planeeff->WriteHistosToFile(hname,"RECREATE");
3741       }
3742    }
3743    if(fSPDTrackleter) {
3744      AliPlaneEff *planeeff=fSPDTrackleter->GetPlaneEff();
3745       TString name="AliITSPlaneEffSPDtracklet.root";
3746       TFile* pefile = TFile::Open(name, "RECREATE");
3747       ret=(Bool_t)planeeff->Write();
3748       pefile->Close();
3749       AliESDEvent *dummy=NULL;
3750       ret=(Bool_t)fSPDTrackleter->PostProcess(dummy); // take care of writing other files
3751    }
3752  }
3753  return ret;
3754 }
3755 //_____________________________________________________________________________
3756 Bool_t AliReconstruction::InitPlaneEff() {
3757 //
3758  // Here execute all the necessary operations, before of the tracking phase,
3759  // for the evaluation of PlaneEfficiencies, in case required for some detectors.
3760  // E.g., read from a DataBase file a first evaluation of the PlaneEfficiency
3761  // which should be updated/recalculated.
3762  //
3763  // This Preliminary version will work only FOR ITS !!!!!
3764  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3765  //
3766  //  Input: none
3767  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3768  //
3769
3770   fSPDTrackleter = NULL;
3771   TString detStr = fLoadCDB;
3772   if (IsSelected(fgkDetectorName[0], detStr)) {
3773     AliReconstructor* itsReconstructor = GetReconstructor(0);
3774     if (itsReconstructor) {
3775       fSPDTrackleter = itsReconstructor->CreateTrackleter(); // this is NULL unless required in RecoParam
3776     }
3777     if (fSPDTrackleter) {
3778       AliInfo("Trackleter for SPD has been created");
3779     }
3780   }
3781  return kTRUE;
3782 }
3783
3784 //_____________________________________________________________________________
3785 Bool_t AliReconstruction::InitAliEVE()
3786 {
3787   // This method should be called only in case 
3788   // AliReconstruction is run
3789   // within the alieve environment.
3790   // It will initialize AliEVE in a way
3791   // so that it can visualize event processed
3792   // by AliReconstruction.
3793   // The return flag shows whenever the
3794   // AliEVE initialization was successful or not.
3795
3796   TString macroStr(getenv("ALIEVE_ONLINE_MACRO"));
3797
3798   if (macroStr.IsNull())
3799     macroStr.Form("%s/EVE/macros/alieve_online.C",gSystem->ExpandPathName("$ALICE_ROOT"));
3800
3801   AliInfo(Form("Loading AliEVE macro: %s",macroStr.Data()));
3802
3803   if (gROOT->LoadMacro(macroStr.Data()) != 0) return kFALSE;
3804
3805   gROOT->ProcessLine("if (!AliEveEventManager::GetMaster()){new AliEveEventManager();AliEveEventManager::GetMaster()->AddNewEventCommand(\"alieve_online_on_new_event()\");gEve->AddEvent(AliEveEventManager::GetMaster());};");
3806   gROOT->ProcessLine("alieve_online_init()");
3807
3808   return kTRUE;
3809 }
3810   
3811 //_____________________________________________________________________________
3812 void AliReconstruction::RunAliEVE()
3813 {
3814   // Runs AliEVE visualisation of
3815   // the current event.
3816   // Should be executed only after
3817   // successful initialization of AliEVE.
3818
3819   AliInfo("Running AliEVE...");
3820   gROOT->ProcessLine(Form("AliEveEventManager::GetMaster()->SetEvent((AliRunLoader*)%p,(AliRawReader*)%p,(AliESDEvent*)%p,(AliESDfriend*)%p);",fRunLoader,fRawReader,fesd,fesdf));
3821   gSystem->Run();
3822 }
3823
3824 //_____________________________________________________________________________
3825 Bool_t AliReconstruction::SetRunQA(TString detAndAction) 
3826 {
3827         // Allows to run QA for a selected set of detectors
3828         // and a selected set of tasks among RAWS, DIGITSR, RECPOINTS and ESDS
3829         // all selected detectors run the same selected tasks
3830         
3831         if (!detAndAction.Contains(":")) {
3832                 AliError( Form("%s is a wrong syntax, use \"DetectorList:ActionList\" \n", detAndAction.Data()) ) ;
3833                 fRunQA = kFALSE ;
3834                 return kFALSE ;                 
3835         }
3836         Int_t colon = detAndAction.Index(":") ; 
3837         fQADetectors = detAndAction(0, colon) ; 
3838         fQATasks   = detAndAction(colon+1, detAndAction.Sizeof() ) ; 
3839         if (fQATasks.Contains("ALL") ) {
3840                 fQATasks = Form("%d %d %d %d", AliQAv1::kRAWS, AliQAv1::kDIGITSR, AliQAv1::kRECPOINTS, AliQAv1::kESDS) ; 
3841         } else {
3842                 fQATasks.ToUpper() ; 
3843                 TString tempo("") ; 
3844                 if ( fQATasks.Contains("RAW") ) 
3845                         tempo = Form("%d ", AliQAv1::kRAWS) ; 
3846                 if ( fQATasks.Contains("DIGIT") ) 
3847                         tempo += Form("%d ", AliQAv1::kDIGITSR) ; 
3848                 if ( fQATasks.Contains("RECPOINT") ) 
3849                         tempo += Form("%d ", AliQAv1::kRECPOINTS) ; 
3850                 if ( fQATasks.Contains("ESD") ) 
3851                         tempo += Form("%d ", AliQAv1::kESDS) ; 
3852                 fQATasks = tempo ; 
3853                 if (fQATasks.IsNull()) {
3854                         AliInfo("No QA requested\n")  ;
3855                         fRunQA = kFALSE ;
3856                         return kTRUE ; 
3857                 }
3858         }       
3859         TString tempo(fQATasks) ; 
3860         tempo.ReplaceAll(Form("%d", AliQAv1::kRAWS), AliQAv1::GetTaskName(AliQAv1::kRAWS))      ;
3861         tempo.ReplaceAll(Form("%d", AliQAv1::kDIGITSR), AliQAv1::GetTaskName(AliQAv1::kDIGITSR)) ;      
3862         tempo.ReplaceAll(Form("%d", AliQAv1::kRECPOINTS), AliQAv1::GetTaskName(AliQAv1::kRECPOINTS)) ;  
3863         tempo.ReplaceAll(Form("%d", AliQAv1::kESDS), AliQAv1::GetTaskName(AliQAv1::kESDS)) ;    
3864         AliInfo( Form("QA will be done on \"%s\" for \"%s\"\n", fQADetectors.Data(), tempo.Data()) ) ;  
3865         fRunQA = kTRUE ;
3866         return kTRUE; 
3867
3868
3869 //_____________________________________________________________________________
3870 Bool_t AliReconstruction::InitRecoParams() 
3871 {
3872   // The method accesses OCDB and retrieves all
3873   // the available reco-param objects from there.
3874
3875   Bool_t isOK = kTRUE;
3876
3877   if (fRecoParam.GetDetRecoParamArray(kNDetectors)) {
3878     AliInfo("Using custom GRP reconstruction parameters");
3879   }
3880   else {
3881     AliInfo("Loading GRP reconstruction parameter objects");
3882
3883     AliCDBPath path("GRP","Calib","RecoParam");
3884     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
3885     if(!entry){ 
3886       AliWarning("Couldn't find GRP RecoParam entry in OCDB");
3887       isOK = kFALSE;
3888     }
3889     else {
3890       TObject *recoParamObj = entry->GetObject();
3891       if (dynamic_cast<TObjArray*>(recoParamObj)) {
3892         // GRP has a normal TobjArray of AliDetectorRecoParam objects
3893         // Registering them in AliRecoParam
3894         fRecoParam.AddDetRecoParamArray(kNDetectors,dynamic_cast<TObjArray*>(recoParamObj));
3895       }
3896       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
3897         // GRP has only onse set of reco parameters
3898         // Registering it in AliRecoParam
3899         AliInfo("Single set of GRP reconstruction parameters found");
3900         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
3901         fRecoParam.AddDetRecoParam(kNDetectors,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
3902       }
3903       else {
3904         AliError("No valid GRP RecoParam object found in the OCDB");
3905         isOK = kFALSE;
3906       }
3907       entry->SetOwner(0);
3908     }
3909   }
3910
3911   TString detStr = fLoadCDB;
3912   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3913
3914     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3915
3916     if (fRecoParam.GetDetRecoParamArray(iDet)) {
3917       AliInfo(Form("Using custom reconstruction parameters for detector %s",fgkDetectorName[iDet]));
3918       continue;
3919     }
3920
3921     AliInfo(Form("Loading reconstruction parameter objects for detector %s",fgkDetectorName[iDet]));
3922   
3923     AliCDBPath path(fgkDetectorName[iDet],"Calib","RecoParam");
3924     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
3925     if(!entry){ 
3926       AliWarning(Form("Couldn't find RecoParam entry in OCDB for detector %s",fgkDetectorName[iDet]));
3927       isOK = kFALSE;
3928     }
3929     else {
3930       TObject *recoParamObj = entry->GetObject();
3931       if (dynamic_cast<TObjArray*>(recoParamObj)) {
3932         // The detector has a normal TobjArray of AliDetectorRecoParam objects
3933         // Registering them in AliRecoParam
3934         fRecoParam.AddDetRecoParamArray(iDet,dynamic_cast<TObjArray*>(recoParamObj));
3935       }
3936       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
3937         // The detector has only onse set of reco parameters
3938         // Registering it in AliRecoParam
3939         AliInfo(Form("Single set of reconstruction parameters found for detector %s",fgkDetectorName[iDet]));
3940         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
3941         fRecoParam.AddDetRecoParam(iDet,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
3942       }
3943       else {
3944         AliError(Form("No valid RecoParam object found in the OCDB for detector %s",fgkDetectorName[iDet]));
3945         isOK = kFALSE;
3946       }
3947       entry->SetOwner(0);
3948       //      FIX ME: We have to disable the unloading of reco-param CDB
3949       //      entries because QA framework is using them. Has to be fix in
3950       //      a way that the QA takes the objects already constructed in
3951       //      this method.
3952       //      AliCDBManager::Instance()->UnloadFromCache(path.GetPath());
3953     }
3954   }
3955
3956   if (AliDebugLevel() > 0) fRecoParam.Print();
3957
3958   return isOK;
3959 }
3960
3961 //_____________________________________________________________________________
3962 Bool_t AliReconstruction::GetEventInfo() 
3963 {
3964   // Fill the event info object
3965   // ...
3966   AliCodeTimerAuto("",0)
3967
3968   AliCentralTrigger *aCTP = NULL;
3969   if (fRawReader) {
3970     fEventInfo.SetEventType(fRawReader->GetType());
3971
3972     ULong64_t mask = fRawReader->GetClassMask();
3973     fEventInfo.SetTriggerMask(mask);
3974     UInt_t clmask = fRawReader->GetDetectorPattern()[0];
3975     fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(clmask));
3976
3977     aCTP = new AliCentralTrigger();
3978     TString configstr("");
3979     if (!aCTP->LoadConfiguration(configstr)) { // Load CTP config from OCDB
3980       AliError("No trigger configuration found in OCDB! The trigger configuration information will not be used!");
3981       delete aCTP;
3982       return kFALSE;
3983     }
3984     aCTP->SetClassMask(mask);
3985     aCTP->SetClusterMask(clmask);
3986
3987     if (fRunLoader) {
3988       AliCentralTrigger* rlCTP = fRunLoader->GetTrigger();
3989       if (rlCTP) {
3990         rlCTP->SetClassMask(mask);
3991         rlCTP->SetClusterMask(clmask);
3992       }
3993     }
3994   }
3995   else {
3996     fEventInfo.SetEventType(AliRawEventHeaderBase::kPhysicsEvent);
3997
3998     if (fRunLoader && (!fRunLoader->LoadTrigger())) {
3999       aCTP = fRunLoader->GetTrigger();
4000       fEventInfo.SetTriggerMask(aCTP->GetClassMask());
4001       // get inputs from actp - just get
4002       AliESDHeader* esdheader = fesd->GetHeader();
4003       esdheader->SetL0TriggerInputs(aCTP->GetL0TriggerInputs());
4004       esdheader->SetL1TriggerInputs(aCTP->GetL1TriggerInputs());
4005       esdheader->SetL2TriggerInputs(aCTP->GetL2TriggerInputs());
4006       fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(aCTP->GetClusterMask()));
4007     }
4008     else {
4009       if (fStopOnMissingTriggerFile) AliFatal("No trigger can be loaded! Stopping reconstruction!");
4010       AliWarning("No trigger can be loaded! The trigger information will not be used!");
4011       return kFALSE;
4012     }
4013   }
4014
4015   AliTriggerConfiguration *config = aCTP->GetConfiguration();
4016   if (!config) {
4017     AliError("No trigger configuration has been found! The trigger configuration information will not be used!");
4018     if (fRawReader) delete aCTP;
4019     return kFALSE;
4020   }
4021
4022   // Load trigger aliases and declare the trigger classes included in aliases
4023   //PH Why do we do it in each event and not only once in the beginning of the chunk??
4024   //PH Temporary fix for #99725: AliReconstruction::GetEventInfo bug
4025   fDeclTriggerClasses.Clear();
4026   AliCDBEntry * entry = AliCDBManager::Instance()->Get("GRP/CTP/Aliases");
4027   if (entry) {
4028     THashList * lst = dynamic_cast<THashList*>(entry->GetObject());
4029     if (lst) {
4030       lst->Sort(kSortDescending); // to avoid problems with substrungs
4031       if (fRawReader) fRawReader->LoadTriggerAlias(lst);
4032       // Now declare all the triggers present in the aliases
4033       TIter iter(lst);
4034       TNamed *nmd = 0;
4035       while((nmd = dynamic_cast<TNamed*>(iter.Next()))){
4036         fDeclTriggerClasses += " ";
4037         fDeclTriggerClasses += nmd->GetName();
4038       }
4039     }
4040     else {
4041       AliError("Cannot cast the object with trigger aliases to THashList!");
4042     }
4043   }
4044   else {
4045     AliError("No OCDB ebtry for the trigger aliases!");
4046   }
4047   // Load trigger classes for this run
4048   UChar_t clustmask = 0;
4049   TString trclasses;
4050   ULong64_t trmask = fEventInfo.GetTriggerMask();
4051   const TObjArray& classesArray = config->GetClasses();
4052   Int_t nclasses = classesArray.GetEntriesFast();
4053   for( Int_t iclass=0; iclass < nclasses; iclass++ ) {
4054     AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At(iclass);
4055     if (trclass && trclass->GetMask()>0) {
4056       Int_t trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
4057       if (fesd) fesd->SetTriggerClass(trclass->GetName(),trindex);
4058       if (fRawReader) fRawReader->LoadTriggerClass(trclass->GetName(),trindex);
4059       if (trmask & (1ull << trindex)) {
4060         trclasses += " ";
4061         trclasses += trclass->GetName();
4062         trclasses += " ";
4063         clustmask |= trclass->GetCluster()->GetClusterMask();
4064       }
4065     }
4066   }
4067   fEventInfo.SetTriggerClasses(trclasses);
4068   // Now put the declared trigger classes (not present in the run)
4069   // to 0/false in the event selection
4070   if (!fDeclTriggerClasses.IsNull()) {
4071     TObjArray *tokens = fDeclTriggerClasses.Tokenize(" ");
4072     Int_t ntokens = tokens->GetEntriesFast();
4073     for (Int_t itoken = 0; itoken < ntokens; ++itoken) {
4074       if (fRawReader) fRawReader->LoadTriggerClass((((TObjString*)tokens->At(itoken))->String()).Data(),-1);
4075     }
4076     delete tokens;
4077   }
4078
4079   // Write names of active trigger inputs in ESD Header
4080   const TObjArray& inputsArray = config->GetInputs(); 
4081   Int_t ninputs = inputsArray.GetEntriesFast();
4082   for( Int_t iinput=0; iinput < ninputs; iinput++ ) {
4083     AliTriggerInput* trginput = (AliTriggerInput*)inputsArray.At(iinput);
4084     if (trginput && trginput->GetMask()>0) {
4085       Int_t inputIndex = (Int_t)TMath::Nint(TMath::Log2(trginput->GetMask()));
4086       AliESDHeader* headeresd = 0x0;
4087       if (fesd) headeresd = fesd->GetHeader();
4088       if (headeresd) {
4089         Int_t trglevel = (Int_t)trginput->GetLevel();
4090         if (trglevel == 0) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex);
4091         if (trglevel == 1) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex+24);
4092         if (trglevel == 2) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex+48);
4093       }
4094     }
4095   }
4096
4097   // Set the information in ESD
4098   if (fesd) {
4099     fesd->SetTriggerMask(trmask);
4100     fesd->SetTriggerCluster(clustmask);
4101   }
4102
4103   if (!aCTP->CheckTriggeredDetectors()) {
4104     if (fRawReader) delete aCTP;
4105     return kFALSE;
4106   }    
4107
4108   if (fRawReader) delete aCTP;
4109
4110   // We have to fill also the HLT decision here!!
4111   // ...
4112
4113   return kTRUE;
4114 }
4115
4116 const char *AliReconstruction::MatchDetectorList(const char *detectorList, UInt_t detectorMask)
4117 {
4118   // Match the detector list found in the rec.C or the default 'ALL'
4119   // to the list found in the GRP (stored there by the shuttle PP which
4120   // gets the information from ECS)
4121   static TString resultList;
4122   TString detList = detectorList;
4123
4124   resultList = "";
4125
4126   for(Int_t iDet = 0; iDet < (AliDAQ::kNDetectors-1); iDet++) {
4127     if ((detectorMask >> iDet) & 0x1) {
4128       TString det = AliDAQ::OfflineModuleName(iDet);
4129       if ((detList.CompareTo("ALL") == 0) ||
4130           ((detList.BeginsWith("ALL ") ||
4131             detList.EndsWith(" ALL") ||
4132             detList.Contains(" ALL ")) &&
4133            !(detList.BeginsWith("-"+det+" ") ||
4134              detList.EndsWith(" -"+det) ||
4135              detList.Contains(" -"+det+" "))) ||
4136           (detList.CompareTo(det) == 0) ||
4137           detList.BeginsWith(det+" ") ||
4138           detList.EndsWith(" "+det) ||
4139           detList.Contains( " "+det+" " )) {
4140         if (!resultList.EndsWith(det + " ")) {
4141           resultList += det;
4142           resultList += " ";
4143         }
4144       }        
4145     }
4146   }
4147
4148   // HLT
4149   if ((detectorMask >> AliDAQ::kHLTId) & 0x1) {
4150     TString hltDet = AliDAQ::OfflineModuleName(AliDAQ::kNDetectors-1);
4151     if ((detList.CompareTo("ALL") == 0) ||
4152         ((detList.BeginsWith("ALL ") ||
4153           detList.EndsWith(" ALL") ||
4154           detList.Contains(" ALL ")) &&
4155          !(detList.BeginsWith("-"+hltDet+" ") ||
4156            detList.EndsWith(" -"+hltDet) ||
4157            detList.Contains(" -"+hltDet+" "))) ||
4158         (detList.CompareTo(hltDet) == 0) ||
4159         detList.BeginsWith(hltDet+" ") ||
4160         detList.EndsWith(" "+hltDet) ||
4161         detList.Contains( " "+hltDet+" " )) {
4162       resultList += hltDet;
4163     }
4164   }
4165
4166   return resultList.Data();
4167
4168 }
4169
4170 //______________________________________________________________________________
4171 void AliReconstruction::Abort(const char *method, EAbort what)
4172 {
4173   // Abort processing. If what = kAbortProcess, the Process() loop will be
4174   // aborted. If what = kAbortFile, the current file in a chain will be
4175   // aborted and the processing will continue with the next file, if there
4176   // is no next file then Process() will be aborted. Abort() can also  be
4177   // called from Begin(), SlaveBegin(), Init() and Notify(). After abort
4178   // the SlaveTerminate() and Terminate() are always called. The abort flag
4179   // can be checked in these methods using GetAbort().
4180   //
4181   // The method is overwritten in AliReconstruction for better handling of
4182   // reco specific errors 
4183
4184   if (!fStopOnError) return;
4185
4186   CleanUp();
4187
4188   TString whyMess = method;
4189   whyMess += " failed! Aborting...";
4190
4191   AliError(whyMess.Data());
4192
4193   fAbort = what;
4194   TString mess = "Abort";
4195   if (fAbort == kAbortProcess)
4196     mess = "AbortProcess";
4197   else if (fAbort == kAbortFile)
4198     mess = "AbortFile";
4199
4200   Info(mess.Data(), "%s", whyMess.Data());
4201 }
4202
4203 //______________________________________________________________________________
4204 Bool_t AliReconstruction::ProcessEvent(void* event)
4205 {
4206   // Method that is used in case the event loop
4207   // is steered from outside, for example by AMORE
4208   // 'event' is a pointer to the DATE event in the memory
4209
4210   if (fRawReader) delete fRawReader;
4211   fRawReader = new AliRawReaderDate(event);
4212   fStatus = ProcessEvent(fRunLoader->GetNumberOfEvents());  
4213   delete fRawReader;
4214   fRawReader = NULL;
4215
4216   return fStatus;
4217 }
4218
4219 //______________________________________________________________________________
4220 Bool_t AliReconstruction::ParseOutput()
4221 {
4222   // The method parses the output file
4223   // location string in order to steer
4224   // properly the selector
4225
4226   TPMERegexp re1("(\\w+\\.zip#\\w+\\.root):([,*\\w+\\.root,*]+)@dataset://(\\w++)");
4227   TPMERegexp re2("(\\w+\\.root)?@?dataset://(\\w++)");
4228
4229   if (re1.Match(fESDOutput) == 4) {
4230     // root archive with output files stored and regustered
4231     // in proof dataset
4232     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",re1[1].Data()));
4233     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",re1[3].Data()));
4234     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_DATASET",""));
4235     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_ARCHIVE",re1[2].Data()));
4236     AliInfo(Form("%s files will be stored within %s in dataset %s",
4237                  re1[2].Data(),
4238                  re1[1].Data(),
4239                  re1[3].Data()));
4240   }
4241   else if (re2.Match(fESDOutput) == 3) {
4242     // output file stored and registered
4243     // in proof dataset
4244     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",(re2[1].IsNull()) ? "AliESDs.root" : re2[1].Data()));
4245     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",re2[2].Data()));
4246     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_DATASET",""));
4247     AliInfo(Form("%s will be stored in dataset %s",
4248                  (re2[1].IsNull()) ? "AliESDs.root" : re2[1].Data(),
4249                  re2[2].Data()));
4250   }
4251   else {
4252     if (fESDOutput.IsNull()) {
4253       // Output location not given.
4254       // Assuming xrootd has been already started and
4255       // the output file has to be sent back
4256       // to the client machine
4257       TString esdUrl(Form("root://%s/%s/",
4258                           TUrl(gSystem->HostName()).GetHostFQDN(),
4259                           gSystem->pwd()));
4260       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE","AliESDs.root"));
4261       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",esdUrl.Data()));
4262       AliInfo(Form("AliESDs.root will be stored in %s",
4263                    esdUrl.Data()));
4264     }
4265     else {
4266       // User specified an output location.
4267       // Ones has just to parse it here
4268       TUrl outputUrl(fESDOutput.Data());
4269       TString outputFile(gSystem->BaseName(outputUrl.GetFile()));
4270       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",outputFile.IsNull() ? "AliESDs.root" : outputFile.Data()));
4271       TString outputLocation(outputUrl.GetUrl());
4272       outputLocation.ReplaceAll(outputFile.Data(),"");
4273       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",outputLocation.Data()));
4274       AliInfo(Form("%s will be stored in %s",
4275                    outputFile.IsNull() ? "AliESDs.root" : outputFile.Data(),
4276                    outputLocation.Data()));
4277     }
4278   }
4279
4280   return kTRUE;
4281 }
4282
4283 //______________________________________________________________________________
4284 Bool_t AliReconstruction::IsHighPt() const {
4285   // Selection of events containing "high" pT tracks
4286   // If at least one track is found within 1.5 and 100 GeV (pT)
4287   // that was reconstructed by both ITS and TPC, the event is accepted
4288
4289   // Track cuts
4290   const Double_t pTmin = 1.5;
4291   const Double_t pTmax = 100;
4292   ULong_t mask = 0;
4293   mask |= (AliESDtrack::kITSrefit);
4294   mask |= (AliESDtrack::kTPCrefit);
4295   const Double_t pTminCosmic = 5.;
4296   const Double_t pTmaxCosmic = 100;
4297   ULong_t maskCosmic = 0;
4298   Int_t cosmicCount=0;
4299   maskCosmic |= (AliESDtrack::kTPCrefit);
4300
4301   Bool_t isOK = kFALSE;
4302
4303   if (fesd && fesd->GetEventType()==AliRawEventHeaderBase::kPhysicsEvent) {
4304     // Check if this ia a physics event (code 7)
4305     Int_t ntrk = fesd->GetNumberOfTracks();
4306     for (Int_t itrk=0; itrk<ntrk; ++itrk) {
4307           
4308       AliESDtrack * trk = fesd->GetTrack(itrk);
4309       if (trk 
4310           && trk->Pt() > pTmin 
4311           && trk->Pt() < pTmax
4312           && (trk->GetStatus() & mask) == mask ) {
4313         
4314         isOK = kTRUE;
4315         break;
4316       }
4317       if (trk 
4318           && trk->GetInnerParam()
4319           && trk->GetInnerParam()->Pt() > pTminCosmic 
4320           && trk->GetInnerParam()->Pt() < pTmaxCosmic
4321           && (trk->GetStatus() & maskCosmic) == maskCosmic ) {
4322         
4323         cosmicCount++;
4324         break;
4325       }
4326     }
4327     if (cosmicCount>1) isOK=kTRUE;
4328   }
4329   return isOK;
4330 }
4331
4332 //______________________________________________________________________________
4333 Bool_t AliReconstruction::IsCosmicOrCalibSpecie() const {
4334   // Select cosmic or calibration events
4335
4336   Bool_t isOK = kFALSE;
4337
4338   if (fesd && fesd->GetEventType()==AliRawEventHeaderBase::kPhysicsEvent) {
4339       // Check if this ia a physics event (code 7)
4340       
4341       UInt_t specie = fesd->GetEventSpecie();
4342       if (specie==AliRecoParam::kCosmic || specie==AliRecoParam::kCalib) {
4343         isOK = kTRUE;
4344       }
4345   }
4346   return isOK;
4347 }
4348
4349 //______________________________________________________________________________
4350 void AliReconstruction::WriteESDfriend() {
4351   // Fill the ESD friend in the tree. The required fraction of ESD friends is stored
4352   // in fFractionFriends. We select events where we store the ESD friends according
4353   // to the following algorithm:
4354   // 1. Store all Cosmic or Calibration events within the required fraction
4355   // 2. Sample "high Pt" events within the remaining fraction after step 1.
4356   // 3. Sample randomly events if we still have remaining slot
4357
4358   fNall++;
4359   Bool_t isSelected = kFALSE;
4360   //
4361   // Store all friends for B field OFF 
4362   if (TMath::Abs(AliTrackerBase::GetBz())<0.5) isSelected=kTRUE;
4363
4364   if (IsCosmicOrCalibSpecie()) { // Selection of calib or cosmic events
4365     fNspecie++;
4366
4367     isSelected = kTRUE;
4368     fSspecie++;
4369   }
4370   
4371   Double_t remainingFraction = fFractionFriends;
4372   remainingFraction -= ((Double_t)(fSspecie)/(Double_t)(fNall));
4373   
4374   if (IsHighPt())  { // Selection of "high Pt" events
4375     fNhighPt++;
4376     Double_t curentHighPtFraction = ((Double_t)(fNhighPt+1))/((Double_t)(fNall+1));
4377     // "Bayesian" estimate supposing that without events all the events are of the required type
4378     
4379     if (!isSelected) {
4380       Double_t rnd = gRandom->Rndm()*curentHighPtFraction;
4381       if (rnd<remainingFraction) {
4382         isSelected = kTRUE;
4383         fShighPt++;
4384       }
4385     }
4386   }
4387   remainingFraction -= ((Double_t)(fShighPt)/(Double_t)(fNall));
4388   
4389   // Random selection to fill the remaining fraction (if any)
4390   if (!isSelected) {
4391     Double_t rnd = gRandom->Rndm();
4392     if (rnd<remainingFraction) {        
4393       isSelected = kTRUE;
4394     }
4395   }
4396   
4397   if (!isSelected) {
4398     fesdf->~AliESDfriend();
4399     new (fesdf) AliESDfriend(); // Reset...
4400     fesdf->SetSkipBit(kTRUE);
4401   }
4402   //
4403   Long64_t nbf = ftreeF->Fill();
4404   if (fTreeBuffSize>0 && ftreeF->GetAutoFlush()<0 && (fMemCountESDF += nbf)>fTreeBuffSize ) { // default limit is still not reached
4405     nbf = ftreeF->GetZipBytes();
4406     if (nbf>0) nbf = -nbf;
4407     else       nbf = ftreeF->GetEntries();
4408     ftreeF->SetAutoFlush(nbf);
4409     AliInfo(Form("Calling ftreeF->SetAutoFlush(%lld) | W:%lld T:%lld Z:%lld",
4410                  nbf,fMemCountESDF,ftreeF->GetTotBytes(),ftreeF->GetZipBytes()));        
4411   }
4412   
4413 }
4414
4415 //_________________________________________________________________
4416 void AliReconstruction::DeleteDigits(const TString& detectors)
4417 {
4418   // delete requested digit files produced at current event
4419   static int iEvent = 0;
4420   if (detectors.IsNull()) return;
4421   TString detStr = detectors;
4422   AliInfo(Form("Deleting Digits: %s",detectors.Data()));
4423
4424   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
4425     if(!IsSelected(fgkDetectorName[iDet], detStr)) continue;
4426     unlink(Form("%s.Digits.root",fgkDetectorName[iDet]));
4427   }
4428   AliSysInfo::AddStamp(Form("DelDigits_%d",iEvent), 0,0,iEvent);
4429   iEvent++;
4430 }
4431
4432 //_________________________________________________________________
4433 void AliReconstruction::DeleteRecPoints(const TString& detectors)
4434 {
4435   // delete requested recpoint files produced at current event
4436   static int iEvent = 0;
4437   if (detectors.IsNull()) return;
4438   TString detStr = detectors;
4439   AliInfo(Form("Deleting Recpoints: %s",detectors.Data()));
4440   //
4441   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
4442     if(!IsSelected(fgkDetectorName[iDet], detStr)) continue;
4443     unlink(Form("%s.RecPoints.root",fgkDetectorName[iDet]));
4444   }
4445   AliSysInfo::AddStamp(Form("DelRecPoints_%d",iEvent), 0,0,iEvent);
4446   iEvent++;
4447 }
4448
4449 //_________________________________________________________________
4450 void AliReconstruction::SetStopOnResourcesExcess(Int_t vRSS,Int_t vVMEM)
4451 {
4452   // require checking the resources left and stopping on excess
4453   // if 0  : no check is done
4454   // if >0 : stop reconstruction if exceeds this value
4455   // if <0 : use as margin to system limits
4456   //
4457   const int kKB2MB = 1024;
4458   const int kInfMem = 9999999;
4459   //
4460   struct rlimit r;
4461   int pgSize = getpagesize();
4462   //
4463   if (vRSS>0) {
4464     fMaxRSS = vRSS;
4465     AliInfo(Form("Setting max. RSS usage to user value %d MB",fMaxRSS));
4466   }
4467   else if (vRSS<0) {
4468     getrlimit(RLIMIT_RSS,&r);
4469     fMaxRSS = r.rlim_max==RLIM_INFINITY ? kInfMem : int(r.rlim_max*pgSize/kKB2MB/kKB2MB) + vRSS;
4470     AliInfo(Form("Setting max. RSS usage to system hard limit %d%s MB (%d margin)",fMaxRSS,r.rlim_max==RLIM_INFINITY ? "(inf)":"",-vRSS));
4471   }
4472   else {AliInfo("No check on RSS memory usage will be applied");}
4473   //
4474   if (vVMEM>0) {
4475     fMaxVMEM = vVMEM;
4476     AliInfo(Form("Setting max. VMEM usage to user value %d MB",fMaxVMEM));
4477   }
4478   else if (vVMEM<0) {
4479     getrlimit(RLIMIT_AS,&r);
4480     fMaxVMEM = r.rlim_max==RLIM_INFINITY ? kInfMem : int(r.rlim_max*pgSize/kKB2MB/kKB2MB) + vVMEM;
4481     AliInfo(Form("Setting max. VMEM usage to system hard limit %d%s MB (%d margin)",fMaxVMEM,r.rlim_max==RLIM_INFINITY ? "(inf)":"",-vVMEM));
4482   }
4483   else {AliInfo("No check on RSS memory usage will be applied");}
4484   //  
4485 }
4486
4487 //_________________________________________________________________
4488 Bool_t AliReconstruction::HasEnoughResources(int ev)
4489 {
4490   // check if process consumed more than allowed resources
4491   const int kKB2MB = 1024;
4492   Bool_t res = kTRUE;
4493   if (!fMaxRSS && !fMaxVMEM) return res;
4494   //
4495   ProcInfo_t procInfo;
4496   gSystem->GetProcInfo(&procInfo);
4497   if (procInfo.fMemResident/kKB2MB > fMaxRSS)  res = kFALSE;
4498   if (procInfo.fMemVirtual/kKB2MB  > fMaxVMEM) res = kFALSE;  
4499   //
4500   if (!res) {
4501     AliInfo(Form("Job exceeded allowed limits: RSS:%d (%d) VMEM:%d (%d), will stop",
4502                  int(procInfo.fMemResident/kKB2MB),fMaxRSS,
4503                  int(procInfo.fMemVirtual/kKB2MB) ,fMaxVMEM));
4504     //
4505     unlink(Form("%s",fgkStopEvFName));
4506     ofstream outfile(fgkStopEvFName);
4507     outfile << ev << std::endl;
4508     outfile.close();
4509     fStopped = kTRUE;
4510   }
4511   return res;
4512 }
4513
4514 Bool_t AliReconstruction::HasNextEventAfter(Int_t eventId)
4515 {
4516          return ( (eventId < fRunLoader->GetNumberOfEvents()) ||
4517            (fRawReader && fRawReader->NextEvent()) );
4518 }