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