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