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