]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliReconstruction.cxx
3f369ebe0ae434ec2cbfa6cb3ff39d1a1efee2ce
[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   AliCDBManager::Instance()->Get("GRP/Calib/LHCClockPhase");
1175
1176   TString detStr = fLoadCDB;
1177   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1178     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1179     AliCDBManager::Instance()->GetAll(Form("%s/Calib/*",fgkDetectorName[iDet]));
1180   }
1181
1182   // Temporary fix - one has to define the correct policy in order
1183   // to load the trigger OCDB entries only for the detectors that
1184   // in the trigger or that are needed in order to put correct
1185   // information in ESD
1186   AliCDBManager::Instance()->GetAll("TRIGGER/*/*");
1187
1188   return kTRUE;
1189 }
1190 //_____________________________________________________________________________
1191 Bool_t AliReconstruction::LoadTriggerScalersCDB()
1192 {
1193   // Load CTP scalers from OCDB.
1194   // The scalers are checked for consistency.
1195
1196   AliCodeTimerAuto("",0);
1197
1198   AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/CTP/Scalers");
1199
1200   if (entry) { 
1201    
1202        AliInfo("Found an AliTriggerRunScalers in GRP/CTP/Scalers, reading it");
1203        fRunScalers = dynamic_cast<AliTriggerRunScalers*> (entry->GetObject());
1204        entry->SetOwner(0);
1205        if (fRunScalers->CorrectScalersOverflow() == 0) AliInfo("32bit Trigger counters corrected for overflow");
1206
1207   }
1208   return kTRUE;
1209 }
1210 //_____________________________________________________________________________
1211 Bool_t AliReconstruction::LoadCTPTimeParamsCDB()
1212 {
1213   // Load CTP timing information (alignment)
1214   // from OCDB.
1215
1216   AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/CTP/CTPtiming");
1217   if (!entry) return kFALSE;
1218
1219   AliInfo("Found an AliCTPTimeParams in GRP/CTP/CTPtiming, reading it");
1220   fCTPTimeParams = dynamic_cast<AliCTPTimeParams*> (entry->GetObject());
1221   entry->SetOwner(0);
1222
1223   AliCDBEntry* entry2 = AliCDBManager::Instance()->Get("GRP/CTP/TimeAlign");
1224   if (!entry2) return kFALSE;
1225
1226   AliInfo("Found an AliCTPTimeParams in GRP/CTP/TimeAlign, reading it");
1227   fCTPTimeAlign = dynamic_cast<AliCTPTimeParams*> (entry2->GetObject());
1228   entry2->SetOwner(0);
1229
1230   return kTRUE;
1231 }
1232
1233 //_____________________________________________________________________________
1234 Bool_t AliReconstruction::ReadIntensityInfoCDB()
1235 {
1236   // Load LHC DIP data
1237   AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/GRP/LHCData");
1238
1239   if (entry) { 
1240     AliInfo("Found an AliLHCData in GRP/GRP/LHCData, reading it");
1241     AliLHCData* dipData = dynamic_cast<AliLHCData*> (entry->GetObject());
1242     for (int ib=2;ib--;) {
1243       double intI,intNI;
1244       if (dipData->GetMeanIntensity(ib,intI,intNI)>=0) {
1245         fBeamInt[ib][0] = intI;
1246         fBeamInt[ib][1] = intNI;        
1247       }
1248     }
1249     return kTRUE;
1250   }
1251   return kFALSE;
1252 }
1253
1254
1255 //_____________________________________________________________________________
1256 Bool_t AliReconstruction::Run(const char* input)
1257 {
1258   // Run Run Run
1259   AliCodeTimerAuto("",0);
1260
1261   InitRun(input);
1262   if (GetAbort() != TSelector::kContinue) return kFALSE;
1263
1264   TChain *chain = NULL;
1265   if (fRawReader && (chain = fRawReader->GetChain())) {
1266     Long64_t nEntries = (fLastEvent < 0) ? (TChain::kBigNumber) : (fLastEvent - fFirstEvent + 1);
1267     // Proof mode
1268     if (gProof) {
1269       // Temporary fix for long raw-data runs (until socket timeout handling in PROOF is revised)
1270       gProof->Exec("gEnv->SetValue(\"Proof.SocketActivityTimeout\",-1)", kTRUE);
1271
1272       if (gGrid)
1273         gProof->Exec("TGrid::Connect(\"alien://\")",kTRUE);
1274
1275       TMessage::EnableSchemaEvolutionForAll(kTRUE);
1276       gProof->Exec("TMessage::EnableSchemaEvolutionForAll(kTRUE)",kTRUE);
1277
1278       gProof->AddInput(this);
1279
1280       if (!ParseOutput()) return kFALSE;
1281
1282       gProof->SetParameter("PROOF_MaxSlavesPerNode", 9999);
1283       chain->SetProof();
1284       chain->Process("AliReconstruction","",nEntries,fFirstEvent);
1285     }
1286     else {
1287       chain->Process(this,"",nEntries,fFirstEvent);
1288     }
1289   }
1290   else {
1291     Begin(NULL);
1292     if (GetAbort() != TSelector::kContinue) return kFALSE;
1293     SlaveBegin(NULL);
1294     if (GetAbort() != TSelector::kContinue) return kFALSE;
1295     //******* The loop over events
1296     AliInfo("Starting looping over events");
1297     Int_t iEvent = 0;
1298     while ((iEvent < fRunLoader->GetNumberOfEvents()) ||
1299            (fRawReader && fRawReader->NextEvent())) {
1300       if (!ProcessEvent(iEvent)) {
1301         Abort("ProcessEvent",TSelector::kAbortFile);
1302         return kFALSE;
1303       }
1304       iEvent++;
1305     }
1306     SlaveTerminate();
1307     if (GetAbort() != TSelector::kContinue) return kFALSE;
1308     Terminate();
1309     if (GetAbort() != TSelector::kContinue) return kFALSE;
1310   }
1311
1312   return kTRUE;
1313 }
1314
1315 //_____________________________________________________________________________
1316 void AliReconstruction::InitRawReader(const char* input)
1317 {
1318   // Init raw-reader and
1319   // set the input in case of raw data
1320
1321   AliCodeTimerAuto("",0);
1322
1323   if (input) fRawInput = input;
1324   fRawReader = AliRawReader::Create(fRawInput.Data());
1325   if (!fRawReader) {
1326     if (fRawInput.IsNull()) {
1327       AliInfo("Reconstruction will run over digits");
1328     }
1329     else {
1330       AliFatal("Can not create raw-data reader ! Exiting..."); 
1331     }
1332   }
1333
1334   if (!fEquipIdMap.IsNull() && fRawReader)
1335     fRawReader->LoadEquipmentIdsMap(fEquipIdMap);
1336
1337   if (!fUseHLTData.IsNull()) {
1338     // create the RawReaderHLT which performs redirection of HLT input data for
1339     // the specified detectors
1340     AliRawReader* pRawReader=AliRawHLTManager::CreateRawReaderHLT(fRawReader, fUseHLTData.Data());
1341     if (pRawReader) {
1342       fParentRawReader=fRawReader;
1343       fRawReader=pRawReader;
1344     } else {
1345       AliError(Form("can not create Raw Reader for HLT input %s", fUseHLTData.Data()));
1346     }
1347   }
1348   AliSysInfo::AddStamp("CreateRawReader");
1349 }
1350
1351 //_____________________________________________________________________________
1352 void AliReconstruction::InitRun(const char* input)
1353 {
1354   // Initialization of raw-reader,
1355   // run number, CDB etc.
1356   AliCodeTimerAuto("",0);
1357   AliSysInfo::AddStamp("Start");
1358
1359   // Initialize raw-reader if any
1360   InitRawReader(input);
1361
1362   // Initialize the CDB storage
1363   InitCDB();
1364
1365   // Set run number in CDBManager (if it is not already set by the user)
1366   if (!SetRunNumberFromData()) {
1367     Abort("SetRunNumberFromData", TSelector::kAbortProcess);
1368     return;
1369   }
1370
1371   // Set CDB lock: from now on it is forbidden to reset the run number
1372   // or the default storage or to activate any further storage!
1373   SetCDBLock();
1374   
1375 }
1376
1377 //_____________________________________________________________________________
1378 void AliReconstruction::Begin(TTree *)
1379 {
1380   // Initialize AlReconstruction before
1381   // going into the event loop
1382   // Should follow the TSelector convention
1383   // i.e. initialize only the object on the client side
1384   AliCodeTimerAuto("",0);
1385
1386   AliReconstruction *reco = NULL;
1387   if (fInput) {
1388     if ((reco = (AliReconstruction*)fInput->FindObject("AliReconstruction"))) {
1389       *this = *reco;
1390     }
1391     AliSysInfo::AddStamp("ReadInputInBegin");
1392   }
1393
1394   // Import ideal TGeo geometry and apply misalignment
1395   if (!gGeoManager) {
1396     TString geom(gSystem->DirName(fGAliceFileName));
1397     geom += "/geometry.root";
1398     AliGeomManager::LoadGeometry(geom.Data());
1399     if (!gGeoManager) {
1400       Abort("LoadGeometry", TSelector::kAbortProcess);
1401       return;
1402     }
1403     AliSysInfo::AddStamp("LoadGeom");
1404     TString detsToCheck=fRunLocalReconstruction;
1405     if(!AliGeomManager::CheckSymNamesLUT(detsToCheck.Data())) {
1406       Abort("CheckSymNamesLUT", TSelector::kAbortProcess);
1407       return;
1408     }
1409     AliSysInfo::AddStamp("CheckGeom");
1410   }
1411
1412   if (!MisalignGeometry(fLoadAlignData)) {
1413     Abort("MisalignGeometry", TSelector::kAbortProcess);
1414     return;
1415   }
1416   AliCDBManager::Instance()->UnloadFromCache("GRP/Geometry/Data");
1417   AliSysInfo::AddStamp("MisalignGeom");
1418
1419   if (!InitGRP()) {
1420     Abort("InitGRP", TSelector::kAbortProcess);
1421     return;
1422   }
1423   AliSysInfo::AddStamp("InitGRP");
1424
1425   if (!LoadCDB()) {
1426     Abort("LoadCDB", TSelector::kAbortProcess);
1427     return;
1428   }
1429   AliSysInfo::AddStamp("LoadCDB");
1430
1431   if (!LoadTriggerScalersCDB()) {
1432     Abort("LoadTriggerScalersCDB", TSelector::kAbortProcess);
1433     return;
1434   }
1435   AliSysInfo::AddStamp("LoadTriggerScalersCDB");
1436
1437   if (!LoadCTPTimeParamsCDB()) {
1438     Abort("LoadCTPTimeParamsCDB", TSelector::kAbortProcess);
1439     return;
1440   }
1441   AliSysInfo::AddStamp("LoadCTPTimeParamsCDB");
1442
1443   if (!ReadIntensityInfoCDB()) {
1444     Abort("ReadIntensityInfoCDB", TSelector::kAbortProcess);
1445     return;
1446   }
1447   AliSysInfo::AddStamp("ReadIntensityInfoCDB");
1448
1449   // Read the reconstruction parameters from OCDB
1450   if (!InitRecoParams()) {
1451     AliWarning("Not all detectors have correct RecoParam objects initialized");
1452   }
1453   AliSysInfo::AddStamp("InitRecoParams");
1454
1455   if (fInput && gProof) {
1456     if (reco) *reco = *this;
1457
1458     gGeoManager->SetName("Geometry");
1459     gProof->AddInputData(gGeoManager,kTRUE);
1460     gGeoManager = NULL;
1461     gProof->AddInputData(const_cast<TMap*>(AliCDBManager::Instance()->GetEntryCache()),kTRUE);
1462     fInput->Add(new TParameter<Int_t>("RunNumber",AliCDBManager::Instance()->GetRun()));
1463     AliMagF *magFieldMap = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
1464     magFieldMap->SetName("MagneticFieldMap");
1465     gProof->AddInputData(magFieldMap,kTRUE);
1466   }
1467
1468 }
1469
1470 //_____________________________________________________________________________
1471 void AliReconstruction::SlaveBegin(TTree*)
1472 {
1473   // Initialization related to run-loader,
1474   // vertexer, trackers, recontructors
1475   // In proof mode it is executed on the slave
1476   AliCodeTimerAuto("",0);
1477
1478   TProofOutputFile *outProofFile = NULL;
1479   if (fInput) {
1480     if (AliDebugLevel() > 0) fInput->Print();
1481     if (AliDebugLevel() > 10) fInput->Dump();
1482     if (AliReconstruction *reco = (AliReconstruction*)fInput->FindObject("AliReconstruction")) {
1483       *this = *reco;
1484     }
1485     if (TGeoManager *tgeo = (TGeoManager*)fInput->FindObject("Geometry")) {
1486       gGeoManager = tgeo;
1487       AliGeomManager::SetGeometry(tgeo);
1488     }
1489     if (TMap *entryCache = (TMap*)fInput->FindObject("CDBEntryCache")) {
1490       Int_t runNumber = -1;
1491       if (TProof::GetParameter(fInput,"RunNumber",runNumber) == 0) {
1492         AliCDBManager *man = AliCDBManager::Instance(entryCache,runNumber);
1493         man->SetCacheFlag(kTRUE);
1494         man->SetLock(kTRUE);
1495         man->Print();
1496       }
1497     }
1498     if (AliMagF *map = (AliMagF*)fInput->FindObject("MagneticFieldMap")) {
1499       AliMagF *newMap = new AliMagF(*map);
1500       if (!newMap->LoadParameterization()) {
1501         Abort("AliMagF::LoadParameterization", TSelector::kAbortProcess);
1502         return;
1503       }
1504       TGeoGlobalMagField::Instance()->SetField(newMap);
1505       TGeoGlobalMagField::Instance()->Lock();
1506     }
1507     if (TNamed *outputFileName = (TNamed*)fInput->FindObject("PROOF_OUTPUTFILE"))
1508       fProofOutputFileName = outputFileName->GetTitle();
1509     if (TNamed *outputLocation = (TNamed*)fInput->FindObject("PROOF_OUTPUTFILE_LOCATION"))
1510       fProofOutputLocation = outputLocation->GetTitle();
1511     if (fInput->FindObject("PROOF_OUTPUTFILE_DATASET"))
1512       fProofOutputDataset = kTRUE;
1513     if (TNamed *archiveList = (TNamed*)fInput->FindObject("PROOF_OUTPUTFILE_ARCHIVE"))
1514       fProofOutputArchive = archiveList->GetTitle();
1515     if (!fProofOutputFileName.IsNull() &&
1516         !fProofOutputLocation.IsNull() &&
1517         fProofOutputArchive.IsNull()) {
1518       if (!fProofOutputDataset) {
1519         outProofFile = new TProofOutputFile(fProofOutputFileName.Data(),"M");
1520         outProofFile->SetOutputFileName(Form("%s%s",fProofOutputLocation.Data(),fProofOutputFileName.Data()));
1521       }
1522       else {
1523         outProofFile = new TProofOutputFile(fProofOutputFileName.Data(),"DROV",fProofOutputLocation.Data());
1524       }
1525       if (AliDebugLevel() > 0) outProofFile->Dump();
1526       fOutput->Add(outProofFile);
1527     }
1528     AliSysInfo::AddStamp("ReadInputInSlaveBegin");
1529   }
1530
1531   // get the run loader
1532   if (!InitRunLoader()) {
1533     Abort("InitRunLoader", TSelector::kAbortProcess);
1534     return;
1535   }
1536   AliSysInfo::AddStamp("LoadLoader");
1537  
1538   ftVertexer = new AliVertexerTracks(AliTracker::GetBz());
1539
1540   // get trackers
1541   if (!fRunTracking.IsNull() && !CreateTrackers(fRunTracking)) {
1542     Abort("CreateTrackers", TSelector::kAbortProcess);
1543     return;
1544   }      
1545   AliSysInfo::AddStamp("CreateTrackers");
1546
1547   // create the ESD output file and tree
1548   if (!outProofFile) {
1549     ffile = TFile::Open("AliESDs.root", "RECREATE");
1550     ffile->SetCompressionLevel(2);
1551     if (!ffile->IsOpen()) {
1552       Abort("OpenESDFile", TSelector::kAbortProcess);
1553       return;
1554     }
1555   }
1556   else {
1557     AliInfo(Form("Opening output PROOF file: %s/%s",
1558                  outProofFile->GetDir(), outProofFile->GetFileName()));
1559     if (!(ffile = outProofFile->OpenFile("RECREATE"))) {
1560       Abort(Form("Problems opening output PROOF file: %s/%s",
1561                  outProofFile->GetDir(), outProofFile->GetFileName()),
1562             TSelector::kAbortProcess);
1563       return;
1564     }
1565   }
1566
1567   ftree = new TTree("esdTree", "Tree with ESD objects");
1568   fesd = new AliESDEvent();
1569   fesd->CreateStdContent();
1570   // add a so far non-std object to the ESD, this will
1571   // become part of the std content
1572   fesd->AddObject(new AliESDHLTDecision);
1573
1574   fesd->WriteToTree(ftree);
1575   if (fWriteESDfriend) {
1576     ffileF = TFile::Open("AliESDfriends.root", "RECREATE");
1577     ftreeF = new TTree("esdFriendTree", "Tree with ESD Friend objects");
1578     fesdf  = new AliESDfriend();
1579     ftreeF->Branch("ESDfriend.","AliESDfriend", &fesdf);
1580     fesd->AddObject(fesdf);
1581     ffile->cd();
1582   }
1583   ftree->GetUserInfo()->Add(fesd);
1584
1585   fhlttree = new TTree("HLTesdTree", "Tree with HLT ESD objects");
1586   fhltesd = new AliESDEvent();
1587   fhltesd->CreateStdContent();
1588   // read the ESD template from CDB
1589   // HLT is allowed to put non-std content to its ESD, the non-std
1590   // objects need to be created before invocation of WriteToTree in
1591   // order to create all branches. Initialization is done from an
1592   // ESD layout template in CDB
1593   AliCDBManager* man = AliCDBManager::Instance();
1594   AliCDBPath hltESDConfigPath("HLT/ConfigHLT/esdLayout");
1595   AliCDBEntry* hltESDConfig=NULL;
1596   if (man->GetId(hltESDConfigPath)!=NULL &&
1597       (hltESDConfig=man->Get(hltESDConfigPath))!=NULL) {
1598     AliESDEvent* pESDLayout=dynamic_cast<AliESDEvent*>(hltESDConfig->GetObject());
1599     if (pESDLayout) {
1600       // init all internal variables from the list of objects
1601       pESDLayout->GetStdContent();
1602
1603       // copy content and create non-std objects
1604       *fhltesd=*pESDLayout;
1605       fhltesd->Reset();
1606     } else {
1607       AliError(Form("error setting hltEsd layout from %s: invalid object type",
1608                     hltESDConfigPath.GetPath().Data()));
1609     }
1610   }
1611
1612   fhltesd->WriteToTree(fhlttree);
1613   fhlttree->GetUserInfo()->Add(fhltesd);
1614
1615   ProcInfo_t procInfo;
1616   gSystem->GetProcInfo(&procInfo);
1617   AliInfo(Form("Current memory usage %ld %ld", procInfo.fMemResident, procInfo.fMemVirtual));
1618   
1619   //QA
1620   //Initialize the QA and start of cycle 
1621   if (fRunQA || fRunGlobalQA) 
1622     InitQA() ; 
1623
1624   //Initialize the Plane Efficiency framework
1625   if (fRunPlaneEff && !InitPlaneEff()) {
1626     Abort("InitPlaneEff", TSelector::kAbortProcess);
1627     return;
1628   }
1629
1630   if (strcmp(gProgName,"alieve") == 0)
1631     fRunAliEVE = InitAliEVE();
1632
1633   return;
1634 }
1635
1636 //_____________________________________________________________________________
1637 Bool_t AliReconstruction::Process(Long64_t entry)
1638 {
1639   // run the reconstruction over a single entry
1640   // from the chain with raw data
1641   AliCodeTimerAuto("",0);
1642
1643   TTree *currTree = fChain->GetTree();
1644   AliRawVEvent *event = NULL;
1645   currTree->SetBranchAddress("rawevent",&event);
1646   currTree->GetEntry(entry);
1647   fRawReader = new AliRawReaderRoot(event);
1648   fStatus = ProcessEvent(fRunLoader->GetNumberOfEvents());  
1649   delete fRawReader;
1650   fRawReader = NULL;
1651   delete event;
1652
1653   return fStatus;
1654 }
1655
1656 //_____________________________________________________________________________
1657 void AliReconstruction::Init(TTree *tree)
1658 {
1659   // Implementation of TSelector::Init()
1660   // method
1661   if (tree == 0) {
1662     AliError("The input tree is not found!");
1663     return;
1664   }
1665   fChain = tree;
1666 }
1667
1668 //_____________________________________________________________________________
1669 Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
1670 {
1671   // run the reconstruction over a single event
1672   // The event loop is steered in Run method
1673
1674
1675   static Long_t oldMres=0;
1676   static Long_t oldMvir=0;
1677   static Float_t oldCPU=0;
1678   static Long_t aveDMres=0;
1679   static Long_t aveDMvir=0;
1680   static Float_t aveDCPU=0;
1681
1682   AliCodeTimerAuto("",0);
1683
1684   AliESDpid pid;
1685
1686   if (iEvent >= fRunLoader->GetNumberOfEvents()) {
1687     fRunLoader->SetEventNumber(iEvent);
1688     fRunLoader->GetHeader()->Reset(fRawReader->GetRunNumber(), 
1689                                    iEvent, iEvent);
1690     fRunLoader->TreeE()->Fill();
1691     if (fRawReader && fRawReader->UseAutoSaveESD())
1692       fRunLoader->TreeE()->AutoSave("SaveSelf");
1693   }
1694
1695   if ((iEvent < fFirstEvent) || ((fLastEvent >= 0) && (iEvent > fLastEvent))) {
1696     return kTRUE;
1697   }
1698
1699
1700   fRunLoader->GetEvent(iEvent);
1701
1702   // Fill Event-info object
1703   GetEventInfo();
1704   fRecoParam.SetEventSpecie(fRunInfo,fEventInfo,fListOfCosmicTriggers);
1705   
1706   ProcInfo_t procInfo;
1707   if(iEvent==fFirstEvent) {
1708     gSystem->GetProcInfo(&procInfo);
1709     oldMres=procInfo.fMemResident;
1710     oldMvir=procInfo.fMemVirtual;
1711     oldCPU=procInfo.fCpuUser+procInfo.fCpuSys;
1712   }
1713   AliInfo(Form("================================= Processing event %d of type %-10s ==================================", iEvent,fRecoParam.PrintEventSpecie()));
1714
1715   // Set the reco-params
1716   {
1717     TString detStr = fLoadCDB;
1718     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1719       if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1720       AliReconstructor *reconstructor = GetReconstructor(iDet);
1721       if (reconstructor && fRecoParam.GetDetRecoParamArray(iDet)) {
1722         const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
1723         reconstructor->SetRecoParam(par);
1724         reconstructor->GetPidSettings(&pid);
1725         reconstructor->SetEventInfo(&fEventInfo);
1726         if (fRunQA) {
1727           AliQAManager::QAManager()->SetRecoParam(iDet, par) ; 
1728           if (par) AliQAManager::QAManager()->SetEventSpecie(AliRecoParam::Convert(par->GetEventSpecie())) ;
1729         }
1730       }
1731     }
1732     if (fRunQA) {
1733       const AliDetectorRecoParam *grppar = fRecoParam.GetDetRecoParam(kNDetectors);
1734       AliQAManager::QAManager()->SetRecoParam(AliQAv1::kGLOBAL, grppar) ; 
1735       AliQAManager::QAManager()->SetEventSpecie(AliRecoParam::Convert(grppar->GetEventSpecie())) ;
1736     }
1737   }
1738
1739     // QA on single raw 
1740   if (fRunQA && IsInTasks(AliQAv1::kRAWS)) {
1741     AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
1742     AliQAManager::QAManager()->RunOneEvent(fRawReader) ;  
1743   }
1744     // local single event reconstruction
1745     if (!fRunLocalReconstruction.IsNull()) {
1746       TString detectors=fRunLocalReconstruction;
1747       // run HLT event reconstruction first
1748       // ;-( IsSelected changes the string
1749       if (IsSelected("HLT", detectors) &&
1750           !RunLocalEventReconstruction("HLT")) {
1751         if (fStopOnError) {CleanUp(); return kFALSE;}
1752       }
1753       detectors=fRunLocalReconstruction;
1754       detectors.ReplaceAll("HLT", "");
1755       if (!RunLocalEventReconstruction(detectors)) {
1756         if (fStopOnError) {
1757           CleanUp(); 
1758           return kFALSE;
1759         }
1760       }
1761     }
1762
1763   
1764     // fill Event header information from the RawEventHeader
1765     if (fRawReader){FillRawEventHeaderESD(fesd);}
1766     if (fRawReader){FillRawEventHeaderESD(fhltesd);}
1767
1768     fesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
1769     fhltesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
1770     
1771     ((AliESDRun*)fesd->GetESDRun())->SetDetectorsInDAQ(fRunInfo->GetDetectorMask());
1772     ((AliESDRun*)fhltesd->GetESDRun())->SetDetectorsInDAQ(fRunInfo->GetDetectorMask());
1773     ((AliESDRun*)fesd->GetESDRun())->SetDetectorsInReco(AliDAQ::DetectorPatternOffline(fFillESD.Data()));
1774     ((AliESDRun*)fhltesd->GetESDRun())->SetDetectorsInReco(AliDAQ::DetectorPatternOffline(fFillESD.Data()));
1775
1776     fesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
1777     fhltesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
1778
1779     fesd->SetEventSpecie(fRecoParam.GetEventSpecie());
1780     fhltesd->SetEventSpecie(fRecoParam.GetEventSpecie());
1781     
1782     // Set magnetic field from the tracker
1783     fesd->SetMagneticField(AliTracker::GetBz());
1784     fhltesd->SetMagneticField(AliTracker::GetBz());
1785     //
1786     AliESDRun *esdRun,*esdRunH;
1787     esdRun  = (AliESDRun*)fesd->GetESDRun();
1788     esdRunH = (AliESDRun*)fhltesd->GetESDRun();
1789     esdRun->SetBeamEnergyIsSqrtSHalfGeV();
1790     esdRunH->SetBeamEnergyIsSqrtSHalfGeV();
1791     //
1792     for (int ib=2;ib--;) for (int it=2;it--;) {
1793         esdRun->SetMeanIntensity(ib,it, fBeamInt[ib][it]); 
1794         esdRunH->SetMeanIntensity(ib,it, fBeamInt[ib][it]); 
1795       }
1796     //
1797     AliMagF* fld = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
1798     if (fld) { // set info needed for field initialization
1799       fesd->SetCurrentL3(fld->GetCurrentSol());
1800       fesd->SetCurrentDip(fld->GetCurrentDip());
1801       fesd->SetBeamEnergy(fld->GetBeamEnergy());
1802       fesd->SetBeamType(fld->GetBeamTypeText());
1803       fesd->SetUniformBMap(fld->IsUniform());
1804       fesd->SetBInfoStored();
1805       //
1806       fhltesd->SetCurrentL3(fld->GetCurrentSol());
1807       fhltesd->SetCurrentDip(fld->GetCurrentDip());
1808       fhltesd->SetBeamEnergy(fld->GetBeamEnergy());
1809       fhltesd->SetBeamType(fld->GetBeamTypeText());
1810       fhltesd->SetUniformBMap(fld->IsUniform());
1811       fhltesd->SetBInfoStored();
1812     }
1813     //
1814     // Set most probable pt, for B=0 tracking
1815     // Get the global reco-params. They are atposition 16 inside the array of detectors in fRecoParam
1816     const AliGRPRecoParam *grpRecoParam = dynamic_cast<const AliGRPRecoParam*>(fRecoParam.GetDetRecoParam(kNDetectors));
1817     if (grpRecoParam) AliExternalTrackParam::SetMostProbablePt(grpRecoParam->GetMostProbablePt());
1818     
1819     // Fill raw-data error log into the ESD
1820     if (fRawReader) FillRawDataErrorLog(iEvent,fesd);
1821
1822     // vertex finder
1823     if (fRunVertexFinder) {
1824       if (!RunVertexFinder(fesd)) {
1825         if (fStopOnError) {CleanUp(); return kFALSE;}
1826       }
1827     }
1828
1829     // For Plane Efficiency: run the SPD trackleter
1830     if (fRunPlaneEff && fSPDTrackleter) {
1831       if (!RunSPDTrackleting(fesd)) {
1832         if (fStopOnError) {CleanUp(); return kFALSE;}
1833       }
1834     }
1835
1836     // Muon tracking
1837     if (!fRunTracking.IsNull()) {
1838       if (fRunMuonTracking) {
1839         if (!RunMuonTracking(fesd)) {
1840           if (fStopOnError) {CleanUp(); return kFALSE;}
1841         }
1842       }
1843     }
1844
1845     // barrel tracking
1846     if (!fRunTracking.IsNull()) {
1847       if (!RunTracking(fesd,pid)) {
1848         if (fStopOnError) {CleanUp(); return kFALSE;}
1849       }
1850     }
1851
1852     // fill ESD
1853     if (!fFillESD.IsNull()) {
1854       TString detectors=fFillESD;
1855       // run HLT first and on hltesd
1856       // ;-( IsSelected changes the string
1857       if (IsSelected("HLT", detectors) &&
1858           !FillESD(fhltesd, "HLT")) {
1859         if (fStopOnError) {CleanUp(); return kFALSE;}
1860       }
1861       detectors=fFillESD;
1862       // Temporary fix to avoid problems with HLT that overwrites the offline ESDs
1863       if (detectors.Contains("ALL")) {
1864         detectors="";
1865         for (Int_t idet=0; idet<kNDetectors; ++idet){
1866           detectors += fgkDetectorName[idet];
1867           detectors += " ";
1868         }
1869       }
1870       detectors.ReplaceAll("HLT", "");
1871       if (!FillESD(fesd, detectors)) {
1872         if (fStopOnError) {CleanUp(); return kFALSE;}
1873       }
1874     }
1875  
1876     // combined PID
1877     pid.MakePID(fesd);
1878
1879     if (fFillTriggerESD) {
1880       if (!FillTriggerESD(fesd)) {
1881         if (fStopOnError) {CleanUp(); return kFALSE;}
1882       }
1883     }
1884     // Always fill scalers
1885     if (!FillTriggerScalers(fesd)) {
1886        if (fStopOnError) {CleanUp(); return kFALSE;}
1887     }
1888     
1889
1890     ffile->cd();
1891
1892     //
1893     // Propagate track to the beam pipe  (if not already done by ITS)
1894     //
1895     const Int_t ntracks = fesd->GetNumberOfTracks();
1896     const Double_t kRadius  = 2.8; //something less than the beam pipe radius
1897
1898     TObjArray trkArray;
1899     UShort_t *selectedIdx=new UShort_t[ntracks];
1900
1901     for (Int_t itrack=0; itrack<ntracks; itrack++){
1902       const Double_t kMaxStep = 1;   //max step over the material
1903       Bool_t ok;
1904
1905       AliESDtrack *track = fesd->GetTrack(itrack);
1906       if (!track) continue;
1907
1908       AliExternalTrackParam *tpcTrack =
1909            (AliExternalTrackParam *)track->GetTPCInnerParam();
1910       ok = kFALSE;
1911       if (tpcTrack)
1912         ok = AliTracker::
1913           PropagateTrackToBxByBz(tpcTrack,kRadius,track->GetMass(),kMaxStep,kFALSE);
1914
1915       if (ok) {
1916         Int_t n=trkArray.GetEntriesFast();
1917         selectedIdx[n]=track->GetID();
1918         trkArray.AddLast(tpcTrack);
1919       }
1920
1921       //Tracks refitted by ITS should already be at the SPD vertex
1922       if (track->IsOn(AliESDtrack::kITSrefit)) continue;
1923
1924       AliTracker::
1925          PropagateTrackToBxByBz(track,kRadius,track->GetMass(),kMaxStep,kFALSE);
1926       Double_t x[3]; track->GetXYZ(x);
1927       Double_t b[3]; AliTracker::GetBxByBz(x,b);
1928       track->RelateToVertexBxByBz(fesd->GetPrimaryVertexSPD(), b, kVeryBig);
1929
1930     }
1931
1932     //
1933     // Improve the reconstructed primary vertex position using the tracks
1934     //
1935     Bool_t runVertexFinderTracks = fRunVertexFinderTracks;
1936     if(fesd->GetPrimaryVertexSPD()) {
1937       TString vtitle = fesd->GetPrimaryVertexSPD()->GetTitle();
1938       if(vtitle.Contains("cosmics")) {
1939         runVertexFinderTracks=kFALSE;
1940       }
1941     }
1942
1943     if (runVertexFinderTracks) {
1944        // TPC + ITS primary vertex
1945        ftVertexer->SetITSMode();
1946        ftVertexer->SetConstraintOff();
1947        // get cuts for vertexer from AliGRPRecoParam
1948        Bool_t constrSPD=kFALSE;
1949        if (grpRecoParam) {
1950          Int_t nCutsVertexer = grpRecoParam->GetVertexerTracksNCuts();
1951          Double_t *cutsVertexer = new Double_t[nCutsVertexer];
1952          grpRecoParam->GetVertexerTracksCutsITS(cutsVertexer);
1953          ftVertexer->SetCuts(cutsVertexer);
1954          delete [] cutsVertexer; cutsVertexer = NULL; 
1955          if(grpRecoParam->GetVertexerTracksConstraintITS()) { 
1956            if(fDiamondProfile && fDiamondProfile->GetXRes()<kRadius){
1957              ftVertexer->SetVtxStart(fDiamondProfile); // apply constraint only if sigmax is smaller than the beam pipe radius 
1958            }else{
1959              if(fDiamondProfileSPD && fDiamondProfileSPD->GetXRes()<kRadius){
1960                ftVertexer->SetVtxStart(fDiamondProfileSPD);
1961                constrSPD=kTRUE;
1962              }
1963            }
1964          } 
1965        }
1966        AliESDVertex *pvtx=ftVertexer->FindPrimaryVertex(fesd);
1967        if (pvtx) {
1968          if(constrSPD){
1969            TString title=pvtx->GetTitle();
1970            title.Append("SPD");
1971            pvtx->SetTitle(title);
1972          }
1973           if (pvtx->GetStatus()) {
1974              fesd->SetPrimaryVertexTracks(pvtx);
1975              for (Int_t i=0; i<ntracks; i++) {
1976                  AliESDtrack *t = fesd->GetTrack(i);
1977                  Double_t x[3]; t->GetXYZ(x);
1978                  Double_t b[3]; AliTracker::GetBxByBz(x,b);
1979                  t->RelateToVertexBxByBz(pvtx, b, kVeryBig);
1980              } 
1981           }
1982           delete pvtx; pvtx=NULL;
1983        }
1984
1985        // TPC-only primary vertex
1986        ftVertexer->SetTPCMode();
1987        ftVertexer->SetConstraintOff();
1988        // get cuts for vertexer from AliGRPRecoParam
1989        if (grpRecoParam) {
1990          Int_t nCutsVertexer = grpRecoParam->GetVertexerTracksNCuts();
1991          Double_t *cutsVertexer = new Double_t[nCutsVertexer];
1992          grpRecoParam->GetVertexerTracksCutsTPC(cutsVertexer);
1993          ftVertexer->SetCuts(cutsVertexer);
1994          delete [] cutsVertexer; cutsVertexer = NULL; 
1995          if(fDiamondProfileTPC && grpRecoParam->GetVertexerTracksConstraintTPC()) { 
1996            if(fDiamondProfileTPC->GetXRes()<kRadius) ftVertexer->SetVtxStart(fDiamondProfileTPC); // apply constraint only if sigmax is smaller than the beam pipe radius 
1997          } 
1998        }
1999        pvtx=ftVertexer->FindPrimaryVertex(&trkArray,selectedIdx);
2000        if (pvtx) {
2001           if (pvtx->GetStatus()) {
2002              fesd->SetPrimaryVertexTPC(pvtx);
2003              for (Int_t i=0; i<ntracks; i++) {
2004                  AliESDtrack *t = fesd->GetTrack(i);
2005                  Double_t x[3]; t->GetXYZ(x);
2006                  Double_t b[3]; AliTracker::GetBxByBz(x,b);
2007                  t->RelateToVertexTPCBxByBz(pvtx, b, kVeryBig);
2008              } 
2009           }
2010           delete pvtx; pvtx=NULL;
2011        }
2012
2013     }
2014     delete[] selectedIdx;
2015
2016     if(fDiamondProfile && fDiamondProfile->GetXRes()<kRadius) fesd->SetDiamond(fDiamondProfile);
2017     else fesd->SetDiamond(fDiamondProfileSPD);
2018
2019     if (fRunV0Finder) {
2020        // V0 finding
2021        AliV0vertexer vtxer;
2022        vtxer.Tracks2V0vertices(fesd);
2023
2024        if (fRunCascadeFinder) {
2025           // Cascade finding
2026           AliCascadeVertexer cvtxer;
2027           cvtxer.V0sTracks2CascadeVertices(fesd);
2028        }
2029     }
2030
2031     // write ESD
2032     if (fCleanESD) CleanESD(fesd);
2033     // 
2034     // RS run updated trackleter: since we want to mark the clusters used by tracks and also mark the 
2035     // tracks interpreted as primary, this step should be done in the very end, when full 
2036     // ESD info is available (particulalry, V0s)
2037     // vertex finder
2038     if (fRunMultFinder) {
2039       if (!RunMultFinder(fesd)) {
2040         if (fStopOnError) {CleanUp(); return kFALSE;}
2041       }
2042     }
2043
2044   if (fRunQA && IsInTasks(AliQAv1::kESDS)) {
2045     AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2046     AliQAManager::QAManager()->RunOneEvent(fesd, fhltesd) ; 
2047   }
2048   if (fRunGlobalQA) {
2049     AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
2050       qadm->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2051     if (qadm && IsInTasks(AliQAv1::kESDS))
2052       qadm->Exec(AliQAv1::kESDS, fesd);
2053   }
2054
2055   // copy HLT decision from HLTesd to esd
2056   // the most relevant information is stored in a reduced container in the esd,
2057   // while the full information can be found in the HLTesd
2058   TObject* pHLTSrc=fhltesd->FindListObject(AliESDHLTDecision::Name());
2059   TObject* pHLTTgt=fesd->FindListObject(AliESDHLTDecision::Name());
2060   if (pHLTSrc && pHLTTgt) {
2061     pHLTSrc->Copy(*pHLTTgt);
2062   }
2063
2064     if (fWriteESDfriend) 
2065       fesd->GetESDfriend(fesdf);
2066
2067     ftree->Fill();
2068     if (fWriteESDfriend) {
2069       // Sampling
2070       Double_t rnd = gRandom->Rndm();
2071       if (fFractionFriends < rnd) {
2072         fesdf->~AliESDfriend();
2073         new (fesdf) AliESDfriend(); // Reset...
2074         fesdf->SetSkipBit(kTRUE);
2075       }
2076
2077       ftreeF->Fill();
2078     }
2079
2080     // Auto-save the ESD tree in case of prompt reco @P2
2081     if (fRawReader && fRawReader->UseAutoSaveESD()) {
2082       ftree->AutoSave("SaveSelf");
2083       if (fWriteESDfriend) ftreeF->AutoSave("SaveSelf");
2084       TFile *friendfile = (TFile *)(gROOT->GetListOfFiles()->FindObject("AliESDfriends.root"));
2085       if (friendfile) friendfile->Save();
2086     }
2087
2088     // write HLT ESD
2089     fhlttree->Fill();
2090
2091     // call AliEVE
2092     if (fRunAliEVE) RunAliEVE();
2093
2094     fesd->Reset();
2095     fhltesd->Reset();
2096     if (fWriteESDfriend) {
2097       fesdf->~AliESDfriend();
2098       new (fesdf) AliESDfriend(); // Reset...
2099     }
2100  
2101     gSystem->GetProcInfo(&procInfo);
2102     Long_t dMres=(procInfo.fMemResident-oldMres)/1024;
2103     Long_t dMvir=(procInfo.fMemVirtual-oldMvir)/1024;
2104     Float_t dCPU=procInfo.fCpuUser+procInfo.fCpuSys-oldCPU;
2105     aveDMres+=(dMres-aveDMres)/(iEvent-fFirstEvent+1);
2106     aveDMvir+=(dMvir-aveDMvir)/(iEvent-fFirstEvent+1);
2107     aveDCPU+=(dCPU-aveDCPU)/(iEvent-fFirstEvent+1);
2108     AliInfo(Form("======================= End Event %d: Res %ld(%3ld <%3ld>) Vir %ld(%3ld <%3ld>) CPU %5.2f <%5.2f> ===================",
2109                  iEvent, procInfo.fMemResident/1024, dMres, aveDMres, procInfo.fMemVirtual/1024, dMvir, aveDMvir, dCPU, aveDCPU));
2110     oldMres=procInfo.fMemResident;
2111     oldMvir=procInfo.fMemVirtual;
2112     oldCPU=procInfo.fCpuUser+procInfo.fCpuSys;
2113   
2114     fEventInfo.Reset();
2115     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2116       if (fReconstructor[iDet]) {
2117         fReconstructor[iDet]->SetRecoParam(NULL);
2118         fReconstructor[iDet]->SetEventInfo(NULL);
2119       }
2120       if (fTracker[iDet]) fTracker[iDet]->SetEventInfo(NULL);
2121     }
2122         
2123   if (fRunQA || fRunGlobalQA) 
2124     AliQAManager::QAManager()->Increment() ; 
2125   
2126     return kTRUE;
2127 }
2128
2129 //_____________________________________________________________________________
2130 void AliReconstruction::SlaveTerminate()
2131 {
2132   // Finalize the run on the slave side
2133   // Called after the exit
2134   // from the event loop
2135   AliCodeTimerAuto("",0);
2136
2137   if (fIsNewRunLoader) { // galice.root didn't exist
2138     fRunLoader->WriteHeader("OVERWRITE");
2139     fRunLoader->CdGAFile();
2140     fRunLoader->Write(0, TObject::kOverwrite);
2141   }
2142
2143   const TMap *cdbMap = AliCDBManager::Instance()->GetStorageMap();       
2144   const TList *cdbList = AliCDBManager::Instance()->GetRetrievedIds();   
2145                  
2146    TMap *cdbMapCopy = new TMap(cdbMap->GetEntries());    
2147    cdbMapCopy->SetOwner(1);      
2148    cdbMapCopy->SetName("cdbMap");        
2149    TIter iter(cdbMap->GetTable());       
2150          
2151    TPair* pair = 0;      
2152    while((pair = dynamic_cast<TPair*> (iter.Next()))){   
2153          TObjString* keyStr = dynamic_cast<TObjString*> (pair->Key());   
2154          TObjString* valStr = dynamic_cast<TObjString*> (pair->Value());         
2155          cdbMapCopy->Add(new TObjString(keyStr->GetName()), new TObjString(valStr->GetName()));  
2156    }     
2157          
2158    TList *cdbListCopy = new TList();     
2159    cdbListCopy->SetOwner(1);     
2160    cdbListCopy->SetName("cdbList");      
2161          
2162    TIter iter2(cdbList);         
2163          
2164         AliCDBId* id=0;
2165         while((id = dynamic_cast<AliCDBId*> (iter2.Next()))){    
2166          cdbListCopy->Add(new TObjString(id->ToString().Data()));        
2167    }     
2168          
2169    ftree->GetUserInfo()->Add(cdbMapCopy);        
2170    ftree->GetUserInfo()->Add(cdbListCopy);
2171
2172
2173   ffile->cd();
2174
2175   // we want to have only one tree version number
2176   ftree->Write(ftree->GetName(),TObject::kOverwrite);
2177   fhlttree->Write(fhlttree->GetName(),TObject::kOverwrite);
2178
2179   if (fWriteESDfriend) {
2180     ffileF->cd();
2181     ftreeF->Write(ftreeF->GetName(),TObject::kOverwrite);
2182   }
2183
2184 // Finish with Plane Efficiency evaluation: before of CleanUp !!!
2185   if (fRunPlaneEff && !FinishPlaneEff()) {
2186    AliWarning("Finish PlaneEff evaluation failed");
2187   }
2188
2189   // End of cycle for the in-loop  
2190
2191   if (fRunQA || fRunGlobalQA) {
2192     AliQAManager::QAManager()->EndOfCycle() ;
2193     if (fInput &&
2194         !fProofOutputLocation.IsNull() &&
2195         fProofOutputArchive.IsNull() &&
2196         !fProofOutputDataset) {
2197       TString qaOutputFile(Form("%sMerged.%s.Data.root",
2198                                 fProofOutputLocation.Data(),
2199                                 AliQAv1::GetQADataFileName()));
2200       TProofOutputFile *qaProofFile = new TProofOutputFile(Form("Merged.%s.Data.root",
2201                                                                 AliQAv1::GetQADataFileName()));
2202       qaProofFile->SetOutputFileName(qaOutputFile.Data());
2203       if (AliDebugLevel() > 0) qaProofFile->Dump();
2204       fOutput->Add(qaProofFile);
2205       MergeQA(qaProofFile->GetFileName());
2206     }
2207     else {
2208       MergeQA();
2209     }
2210   }
2211
2212   gROOT->cd();
2213   CleanUp();
2214
2215   if (fInput) {
2216     if (!fProofOutputFileName.IsNull() &&
2217         !fProofOutputLocation.IsNull() &&
2218         fProofOutputDataset &&
2219         !fProofOutputArchive.IsNull()) {
2220       TProofOutputFile *zipProofFile = new TProofOutputFile(fProofOutputFileName.Data(),
2221                                                             "DROV",
2222                                                             fProofOutputLocation.Data());
2223       if (AliDebugLevel() > 0) zipProofFile->Dump();
2224       fOutput->Add(zipProofFile);
2225       TString fileList(fProofOutputArchive.Data());
2226       fileList.ReplaceAll(","," ");
2227       TString command;
2228 #if ROOT_SVN_REVISION >= 30174
2229       command.Form("zip -n root %s/%s %s",zipProofFile->GetDir(kTRUE),zipProofFile->GetFileName(),fileList.Data());
2230 #else
2231       command.Form("zip -n root %s/%s %s",zipProofFile->GetDir(),zipProofFile->GetFileName(),fileList.Data());
2232 #endif
2233       AliInfo(Form("Executing: %s",command.Data()));
2234       gSystem->Exec(command.Data());
2235     }
2236   }
2237 }
2238     
2239 //_____________________________________________________________________________
2240 void AliReconstruction::Terminate()
2241 {
2242   // Create tags for the events in the ESD tree (the ESD tree is always present)
2243   // In case of empty events the tags will contain dummy values
2244   AliCodeTimerAuto("",0);
2245
2246   // Do not call the ESD tag creator in case of PROOF-based reconstruction
2247   if (!fInput) {
2248     AliESDTagCreator *esdtagCreator = new AliESDTagCreator();
2249     esdtagCreator->CreateESDTags(fFirstEvent,fLastEvent,fGRPData, AliQAv1::Instance()->GetQA(), AliQAv1::Instance()->GetEventSpecies(), AliQAv1::kNDET, AliRecoParam::kNSpecies);
2250     delete esdtagCreator;
2251   }
2252
2253   // Cleanup of CDB manager: cache and active storages!
2254   AliCDBManager::Instance()->ClearCache();
2255 }
2256
2257 //_____________________________________________________________________________
2258 Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
2259 {
2260 // run the local reconstruction
2261
2262   static Int_t eventNr=0;
2263   AliCodeTimerAuto("",0)
2264
2265   TString detStr = detectors;
2266   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2267     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2268     AliReconstructor* reconstructor = GetReconstructor(iDet);
2269     if (!reconstructor) continue;
2270     AliLoader* loader = fLoader[iDet];
2271     // Matthias April 2008: temporary fix to run HLT reconstruction
2272     // although the HLT loader is missing
2273     if (strcmp(fgkDetectorName[iDet], "HLT")==0) {
2274       if (fRawReader) {
2275         reconstructor->Reconstruct(fRawReader, NULL);
2276       } else {
2277         TTree* dummy=NULL;
2278         reconstructor->Reconstruct(dummy, NULL);
2279       }
2280       continue;
2281     }
2282     if (!loader) {
2283       AliWarning(Form("No loader is defined for %s!",fgkDetectorName[iDet]));
2284       continue;
2285     }
2286     // conversion of digits
2287     if (fRawReader && reconstructor->HasDigitConversion()) {
2288       AliInfo(Form("converting raw data digits into root objects for %s", 
2289                    fgkDetectorName[iDet]));
2290 //      AliCodeTimerAuto(Form("converting raw data digits into root objects for %s", 
2291 //                            fgkDetectorName[iDet]),0);
2292       loader->LoadDigits("update");
2293       loader->CleanDigits();
2294       loader->MakeDigitsContainer();
2295       TTree* digitsTree = loader->TreeD();
2296       reconstructor->ConvertDigits(fRawReader, digitsTree);
2297       loader->WriteDigits("OVERWRITE");
2298       loader->UnloadDigits();
2299     }
2300     // local reconstruction
2301     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
2302     //AliCodeTimerAuto(Form("running reconstruction for %s", fgkDetectorName[iDet]),0);
2303     loader->LoadRecPoints("update");
2304     loader->CleanRecPoints();
2305     loader->MakeRecPointsContainer();
2306     TTree* clustersTree = loader->TreeR();
2307     if (fRawReader && !reconstructor->HasDigitConversion()) {
2308       reconstructor->Reconstruct(fRawReader, clustersTree);
2309     } else {
2310       loader->LoadDigits("read");
2311       TTree* digitsTree = loader->TreeD();
2312       if (!digitsTree) {
2313         AliError(Form("Can't get the %s digits tree", fgkDetectorName[iDet]));
2314         if (fStopOnError) 
2315           return kFALSE;
2316       } else {
2317         reconstructor->Reconstruct(digitsTree, clustersTree);
2318         if (fRunQA && IsInTasks(AliQAv1::kDIGITSR)) {
2319           AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2320           AliQAManager::QAManager()->RunOneEventInOneDetector(iDet, digitsTree) ; 
2321         }
2322       }
2323       loader->UnloadDigits();
2324     }
2325                 if (fRunQA && IsInTasks(AliQAv1::kRECPOINTS)) {
2326       AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2327                         AliQAManager::QAManager()->RunOneEventInOneDetector(iDet, clustersTree) ; 
2328     }
2329     loader->WriteRecPoints("OVERWRITE");
2330     loader->UnloadRecPoints();
2331     AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr), iDet,1,eventNr);
2332   }
2333   IsSelected("CTP", detStr);
2334   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2335     AliError(Form("the following detectors were not found: %s",
2336                   detStr.Data()));
2337     if (fStopOnError) 
2338       return kFALSE;
2339   }
2340   eventNr++;
2341   return kTRUE;
2342 }
2343 //_____________________________________________________________________________
2344 Bool_t AliReconstruction::RunSPDTrackleting(AliESDEvent*& esd)
2345 {
2346 // run the SPD trackleting (for SPD efficiency purpouses)
2347
2348   AliCodeTimerAuto("",0)
2349
2350   Double_t vtxPos[3] = {0, 0, 0};
2351   Double_t vtxErr[3] = {0.0, 0.0, 0.0};
2352 /*
2353   TArrayF mcVertex(3);
2354   // if(MC)
2355   if (fRunLoader->GetHeader() && fRunLoader->GetHeader()->GenEventHeader()) {
2356     fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(mcVertex);
2357     for (Int_t i = 0; i < 3; i++) vtxPos[i] = mcVertex[i];
2358   }
2359 */
2360   const AliESDVertex *vertex = esd->GetVertex();
2361   if(!vertex){
2362     AliWarning("Vertex not found");
2363     return kFALSE;
2364   }
2365   vertex->GetXYZ(vtxPos);
2366   vertex->GetSigmaXYZ(vtxErr);
2367   if (fSPDTrackleter) {
2368     AliInfo("running the SPD Trackleter for Plane Efficiency Evaluation");
2369
2370     // load clusters
2371     fLoader[0]->LoadRecPoints("read");
2372     TTree* tree = fLoader[0]->TreeR();
2373     if (!tree) {
2374       AliError("Can't get the ITS cluster tree");
2375       return kFALSE;
2376     }
2377     fSPDTrackleter->LoadClusters(tree);
2378     fSPDTrackleter->SetVertex(vtxPos, vtxErr);
2379     // run trackleting
2380     if (fSPDTrackleter->Clusters2Tracks(esd) != 0) {
2381       AliWarning("AliITSTrackleterSPDEff Clusters2Tracks failed");
2382      // fLoader[0]->UnloadRecPoints();
2383       return kFALSE;
2384     }
2385 //fSPDTrackleter->UnloadRecPoints();
2386   } else {
2387     AliWarning("SPDTrackleter not available");
2388     return kFALSE;
2389   }
2390   return kTRUE;
2391 }
2392
2393 //_____________________________________________________________________________
2394 Bool_t AliReconstruction::RunVertexFinder(AliESDEvent*& esd)
2395 {
2396 // run the barrel tracking
2397
2398   AliCodeTimerAuto("",0)
2399
2400   AliVertexer *vertexer = CreateVertexer();
2401   if (!vertexer) return kFALSE;
2402
2403   AliInfo(Form("running the ITS vertex finder: %s",vertexer->ClassName()));
2404   AliESDVertex* vertex = NULL;
2405   if (fLoader[0]) {
2406     fLoader[0]->LoadRecPoints();
2407     TTree* cltree = fLoader[0]->TreeR();
2408     if (cltree) {
2409       if(fDiamondProfileSPD) vertexer->SetVtxStart(fDiamondProfileSPD);
2410       vertex = vertexer->FindVertexForCurrentEvent(cltree);
2411     }
2412     else {
2413       AliError("Can't get the ITS cluster tree");
2414     }
2415     fLoader[0]->UnloadRecPoints();
2416   }
2417   else {
2418     AliError("Can't get the ITS loader");
2419   }
2420   if(!vertex){
2421     AliWarning("Vertex not found");
2422     vertex = new AliESDVertex();
2423     vertex->SetName("default");
2424   }
2425   else {
2426     vertex->SetName("reconstructed");
2427   }
2428
2429   Double_t vtxPos[3];
2430   Double_t vtxErr[3];
2431   vertex->GetXYZ(vtxPos);
2432   vertex->GetSigmaXYZ(vtxErr);
2433
2434   esd->SetPrimaryVertexSPD(vertex);
2435   AliESDVertex *vpileup = NULL;
2436   Int_t novertices = 0;
2437   vpileup = vertexer->GetAllVertices(novertices);
2438   if(novertices>1){
2439     for (Int_t kk=1; kk<novertices; kk++)esd->AddPileupVertexSPD(&vpileup[kk]);
2440   }
2441   /*
2442   // if SPD multiplicity has been determined, it is stored in the ESD
2443   AliMultiplicity *mult = vertexer->GetMultiplicity();
2444   if(mult)esd->SetMultiplicity(mult);
2445   */
2446   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2447     if (fTracker[iDet]) fTracker[iDet]->SetVertex(vtxPos, vtxErr);
2448   }  
2449   delete vertex;
2450
2451   delete vertexer;
2452
2453   return kTRUE;
2454 }
2455
2456 //_____________________________________________________________________________
2457 Bool_t AliReconstruction::RunMultFinder(AliESDEvent*& esd)
2458 {
2459   // run the trackleter for multiplicity study
2460
2461   AliCodeTimerAuto("",0)
2462
2463   AliTrackleter *trackleter = CreateMultFinder();
2464   if (!trackleter) return kFALSE;
2465
2466   AliInfo(Form("running the ITS multiplicity finder: %s",trackleter->ClassName()));
2467
2468   if (fLoader[0]) {
2469     fLoader[0]->LoadRecPoints();
2470     TTree* cltree = fLoader[0]->TreeR();
2471     if (cltree) {
2472       trackleter->Reconstruct(esd,cltree);
2473       AliMultiplicity *mult = trackleter->GetMultiplicity();
2474       if(mult) esd->SetMultiplicity(mult);
2475     }
2476     else {
2477       AliError("Can't get the ITS cluster tree");
2478     }
2479     fLoader[0]->UnloadRecPoints();
2480   }
2481   else {
2482     AliError("Can't get the ITS loader");
2483   }
2484
2485   delete trackleter;
2486
2487   return kTRUE;
2488 }
2489
2490 //_____________________________________________________________________________
2491 Bool_t AliReconstruction::RunHLTTracking(AliESDEvent*& esd)
2492 {
2493 // run the HLT barrel tracking
2494
2495   AliCodeTimerAuto("",0)
2496
2497   if (!fRunLoader) {
2498     AliError("Missing runLoader!");
2499     return kFALSE;
2500   }
2501
2502   AliInfo("running HLT tracking");
2503
2504   // Get a pointer to the HLT reconstructor
2505   AliReconstructor *reconstructor = GetReconstructor(kNDetectors-1);
2506   if (!reconstructor) return kFALSE;
2507
2508   // TPC + ITS
2509   for (Int_t iDet = 1; iDet >= 0; iDet--) {
2510     TString detName = fgkDetectorName[iDet];
2511     AliDebug(1, Form("%s HLT tracking", detName.Data()));
2512     reconstructor->SetOption(detName.Data());
2513     AliTracker *tracker = reconstructor->CreateTracker();
2514     if (!tracker) {
2515       AliWarning(Form("couldn't create a HLT tracker for %s", detName.Data()));
2516       if (fStopOnError) return kFALSE;
2517       continue;
2518     }
2519     Double_t vtxPos[3];
2520     Double_t vtxErr[3]={0.005,0.005,0.010};
2521     const AliESDVertex *vertex = esd->GetVertex();
2522     vertex->GetXYZ(vtxPos);
2523     tracker->SetVertex(vtxPos,vtxErr);
2524     if(iDet != 1) {
2525       fLoader[iDet]->LoadRecPoints("read");
2526       TTree* tree = fLoader[iDet]->TreeR();
2527       if (!tree) {
2528         AliError(Form("Can't get the %s cluster tree", detName.Data()));
2529         return kFALSE;
2530       }
2531       tracker->LoadClusters(tree);
2532     }
2533     if (tracker->Clusters2Tracks(esd) != 0) {
2534       AliError(Form("HLT %s Clusters2Tracks failed", fgkDetectorName[iDet]));
2535       return kFALSE;
2536     }
2537     if(iDet != 1) {
2538       tracker->UnloadClusters();
2539     }
2540     delete tracker;
2541   }
2542
2543   return kTRUE;
2544 }
2545
2546 //_____________________________________________________________________________
2547 Bool_t AliReconstruction::RunMuonTracking(AliESDEvent*& esd)
2548 {
2549 // run the muon spectrometer tracking
2550
2551   AliCodeTimerAuto("",0)
2552
2553   if (!fRunLoader) {
2554     AliError("Missing runLoader!");
2555     return kFALSE;
2556   }
2557   Int_t iDet = 7; // for MUON
2558
2559   AliInfo("is running...");
2560
2561   // Get a pointer to the MUON reconstructor
2562   AliReconstructor *reconstructor = GetReconstructor(iDet);
2563   if (!reconstructor) return kFALSE;
2564
2565   
2566   TString detName = fgkDetectorName[iDet];
2567   AliDebug(1, Form("%s tracking", detName.Data()));
2568   AliTracker *tracker =  reconstructor->CreateTracker();
2569   if (!tracker) {
2570     AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
2571     return kFALSE;
2572   }
2573      
2574   // read RecPoints
2575   fLoader[iDet]->LoadRecPoints("read");  
2576
2577   tracker->LoadClusters(fLoader[iDet]->TreeR());
2578   
2579   Int_t rv = tracker->Clusters2Tracks(esd);
2580   
2581   fLoader[iDet]->UnloadRecPoints();
2582
2583   tracker->UnloadClusters();
2584   
2585   delete tracker;
2586   
2587   if ( rv )
2588   {
2589     AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
2590     return kFALSE;
2591   }
2592   
2593   return kTRUE;
2594 }
2595
2596
2597 //_____________________________________________________________________________
2598 Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd,AliESDpid &PID)
2599 {
2600 // run the barrel tracking
2601   static Int_t eventNr=0;
2602   AliCodeTimerAuto("",0)
2603
2604   AliInfo("running tracking");
2605
2606   // Set the event info which is used
2607   // by the trackers in order to obtain
2608   // information about read-out detectors,
2609   // trigger etc.
2610   AliDebug(1, "Setting event info");
2611   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2612     if (!fTracker[iDet]) continue;
2613     fTracker[iDet]->SetEventInfo(&fEventInfo);
2614   }
2615
2616   //Fill the ESD with the T0 info (will be used by the TOF) 
2617   if (fReconstructor[11] && fLoader[11]) {
2618     fLoader[11]->LoadRecPoints("READ");
2619     TTree *treeR = fLoader[11]->TreeR();
2620     if (treeR) {
2621       GetReconstructor(11)->FillESD((TTree *)NULL,treeR,esd);
2622     }
2623   }
2624
2625   // pass 1: TPC + ITS inwards
2626   for (Int_t iDet = 1; iDet >= 0; iDet--) {
2627     if (!fTracker[iDet]) continue;
2628     AliDebug(1, Form("%s tracking", fgkDetectorName[iDet]));
2629
2630     // load clusters
2631     fLoader[iDet]->LoadRecPoints("read");
2632     AliSysInfo::AddStamp(Form("RLoadCluster%s_%d",fgkDetectorName[iDet],eventNr),iDet,1, eventNr);
2633     TTree* tree = fLoader[iDet]->TreeR();
2634     if (!tree) {
2635       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
2636       return kFALSE;
2637     }
2638     fTracker[iDet]->LoadClusters(tree);
2639     AliSysInfo::AddStamp(Form("TLoadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
2640     // run tracking
2641     if (fTracker[iDet]->Clusters2Tracks(esd) != 0) {
2642       AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
2643       return kFALSE;
2644     }
2645     // preliminary PID in TPC needed by the ITS tracker
2646     if (iDet == 1) {
2647       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
2648       PID.MakePID(esd,kTRUE);
2649     } 
2650     AliSysInfo::AddStamp(Form("Tracking0%s_%d",fgkDetectorName[iDet],eventNr), iDet,3,eventNr);
2651   }
2652
2653   // pass 2: ALL backwards
2654
2655   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2656     if (!fTracker[iDet]) continue;
2657     AliDebug(1, Form("%s back propagation", fgkDetectorName[iDet]));
2658
2659     // load clusters
2660     if (iDet > 1) {     // all except ITS, TPC
2661       TTree* tree = NULL;
2662       fLoader[iDet]->LoadRecPoints("read");
2663       AliSysInfo::AddStamp(Form("RLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,1, eventNr);
2664       tree = fLoader[iDet]->TreeR();
2665       if (!tree) {
2666         AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
2667         return kFALSE;
2668       }
2669       fTracker[iDet]->LoadClusters(tree); 
2670       AliSysInfo::AddStamp(Form("TLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
2671     }
2672
2673     // run tracking
2674     if (iDet>1) // start filling residuals for the "outer" detectors
2675       if (fRunGlobalQA) {
2676         AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
2677         TObjArray ** arr = AliTracker::GetResidualsArray() ; 
2678         if (arr) {
2679           AliRecoParam::EventSpecie_t es=fRecoParam.GetEventSpecie();
2680           TObjArray * elem = arr[AliRecoParam::AConvert(es)];
2681           if ( elem && (! elem->At(0)) ) {
2682             AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
2683             if (qadm) qadm->InitRecPointsForTracker() ; 
2684           }
2685         }
2686       }
2687     if (fTracker[iDet]->PropagateBack(esd) != 0) {
2688       AliError(Form("%s backward propagation failed", fgkDetectorName[iDet]));
2689       //      return kFALSE;
2690     }
2691
2692     // unload clusters
2693     if (iDet > 3) {     // all except ITS, TPC, TRD and TOF
2694       fTracker[iDet]->UnloadClusters();
2695       fLoader[iDet]->UnloadRecPoints();
2696     }
2697     // updated PID in TPC needed by the ITS tracker -MI
2698     if (iDet == 1) {
2699       //GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
2700       //AliESDpid::MakePID(esd);
2701       PID.MakePID(esd,kTRUE);
2702     }
2703     AliSysInfo::AddStamp(Form("Tracking1%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
2704   }
2705   //stop filling residuals for the "outer" detectors
2706   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
2707
2708   // pass 3: TRD + TPC + ITS refit inwards
2709
2710   for (Int_t iDet = 2; iDet >= 0; iDet--) {
2711     if (!fTracker[iDet]) continue;
2712     AliDebug(1, Form("%s inward refit", fgkDetectorName[iDet]));
2713
2714     // run tracking
2715     if (iDet<2) // start filling residuals for TPC and ITS
2716       if (fRunGlobalQA) {
2717         AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
2718         TObjArray ** arr = AliTracker::GetResidualsArray() ; 
2719         if (arr) {
2720           AliRecoParam::EventSpecie_t es=fRecoParam.GetEventSpecie();
2721           TObjArray * elem = arr[AliRecoParam::AConvert(es)];
2722           if ( elem && (! elem->At(0)) ) {
2723             AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
2724             if (qadm) qadm->InitRecPointsForTracker() ; 
2725           }
2726         }
2727       }
2728     
2729     if (fTracker[iDet]->RefitInward(esd) != 0) {
2730       AliError(Form("%s inward refit failed", fgkDetectorName[iDet]));
2731       //      return kFALSE;
2732     }
2733     // run postprocessing
2734     if (fTracker[iDet]->PostProcess(esd) != 0) {
2735       AliError(Form("%s postprocessing failed", fgkDetectorName[iDet]));
2736       //      return kFALSE;
2737     }
2738     AliSysInfo::AddStamp(Form("Tracking2%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
2739   }
2740
2741   // write space-points to the ESD in case alignment data output
2742   // is switched on
2743   if (fWriteAlignmentData)
2744     WriteAlignmentData(esd);
2745
2746   for (Int_t iDet = 3; iDet >= 0; iDet--) {
2747     if (!fTracker[iDet]) continue;
2748     // unload clusters
2749     fTracker[iDet]->UnloadClusters();
2750     AliSysInfo::AddStamp(Form("TUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,4, eventNr);
2751     fLoader[iDet]->UnloadRecPoints();
2752     AliSysInfo::AddStamp(Form("RUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,5, eventNr);
2753   }
2754   // stop filling residuals for TPC and ITS
2755   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
2756
2757   eventNr++;
2758   return kTRUE;
2759 }
2760
2761 //_____________________________________________________________________________
2762 Bool_t AliReconstruction::CleanESD(AliESDEvent *esd){
2763   //
2764   // Remove the data which are not needed for the physics analysis.
2765   //
2766
2767   Int_t nTracks=esd->GetNumberOfTracks();
2768   Int_t nV0s=esd->GetNumberOfV0s();
2769   AliInfo
2770   (Form("Number of ESD tracks and V0s before cleaning: %d %d",nTracks,nV0s));
2771
2772   Float_t cleanPars[]={fV0DCAmax,fV0CsPmin,fDmax,fZmax};
2773   Bool_t rc=esd->Clean(cleanPars);
2774
2775   nTracks=esd->GetNumberOfTracks();
2776   nV0s=esd->GetNumberOfV0s();
2777   AliInfo
2778   (Form("Number of ESD tracks and V0s after cleaning %d %d",nTracks,nV0s));
2779
2780   return rc;
2781 }
2782
2783 //_____________________________________________________________________________
2784 Bool_t AliReconstruction::FillESD(AliESDEvent*& esd, const TString& detectors)
2785 {
2786 // fill the event summary data
2787
2788   AliCodeTimerAuto("",0)
2789     static Int_t eventNr=0; 
2790   TString detStr = detectors;
2791   
2792   AliSysInfo::AddStamp(Form("FillESDb%d",eventNr), -19,-19, eventNr);
2793   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2794   if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2795     AliReconstructor* reconstructor = GetReconstructor(iDet);
2796     if (!reconstructor) continue;
2797     AliDebug(1, Form("filling ESD for %s", fgkDetectorName[iDet]));
2798     TTree* clustersTree = NULL;
2799     if (fLoader[iDet]) {
2800       fLoader[iDet]->LoadRecPoints("read");
2801       clustersTree = fLoader[iDet]->TreeR();
2802       if (!clustersTree) {
2803         AliError(Form("Can't get the %s clusters tree", 
2804                       fgkDetectorName[iDet]));
2805         if (fStopOnError) return kFALSE;
2806       }
2807     }
2808     if (fRawReader && !reconstructor->HasDigitConversion()) {
2809       reconstructor->FillESD(fRawReader, clustersTree, esd);
2810     } else {
2811       TTree* digitsTree = NULL;
2812       if (fLoader[iDet]) {
2813         fLoader[iDet]->LoadDigits("read");
2814         digitsTree = fLoader[iDet]->TreeD();
2815         if (!digitsTree) {
2816           AliError(Form("Can't get the %s digits tree", 
2817                         fgkDetectorName[iDet]));
2818           if (fStopOnError) return kFALSE;
2819         }
2820       }
2821       reconstructor->FillESD(digitsTree, clustersTree, esd);
2822       if (fLoader[iDet]) fLoader[iDet]->UnloadDigits();
2823     }
2824     if (fLoader[iDet]) {
2825       fLoader[iDet]->UnloadRecPoints();
2826     }
2827   }
2828   
2829   IsSelected("CTP", detStr);
2830   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2831     AliError(Form("the following detectors were not found: %s", 
2832                   detStr.Data()));
2833     if (fStopOnError) return kFALSE;
2834   }
2835   AliSysInfo::AddStamp(Form("FillESDe%d",eventNr), -20,-20, eventNr);
2836   eventNr++;
2837   return kTRUE;
2838 }
2839
2840 //_____________________________________________________________________________
2841 Bool_t AliReconstruction::FillTriggerESD(AliESDEvent*& esd)
2842 {
2843   // Reads the trigger decision which is
2844   // stored in Trigger.root file and fills
2845   // the corresponding esd entries
2846
2847   AliCodeTimerAuto("",0)
2848   
2849   AliInfo("Filling trigger information into the ESD");
2850
2851   if (fRawReader) {
2852     AliCTPRawStream input(fRawReader);
2853     if (!input.Next()) {
2854       AliWarning("No valid CTP (trigger) DDL raw data is found ! The trigger info is taken from the event header!");
2855     }
2856     else {
2857       if (esd->GetTriggerMask() != input.GetClassMask())
2858         AliError(Form("Invalid trigger pattern found in CTP raw-data: %llx %llx",
2859                       input.GetClassMask(),esd->GetTriggerMask()));
2860       if (esd->GetOrbitNumber() != input.GetOrbitID())
2861         AliError(Form("Invalid orbit id found in CTP raw-data: %x %x",
2862                       input.GetOrbitID(),esd->GetOrbitNumber()));
2863       if (esd->GetBunchCrossNumber() != input.GetBCID())
2864         AliError(Form("Invalid bunch-crossing id found in CTP raw-data: %x %x",
2865                       input.GetBCID(),esd->GetBunchCrossNumber()));
2866       AliESDHeader* esdheader = esd->GetHeader();
2867       esdheader->SetL0TriggerInputs(input.GetL0Inputs());
2868       esdheader->SetL1TriggerInputs(input.GetL1Inputs());
2869       esdheader->SetL2TriggerInputs(input.GetL2Inputs());
2870       // IR
2871       UInt_t orbit=input.GetOrbitID();
2872        for(Int_t i=0 ; i<input.GetNIRs() ; i++ )
2873           if(TMath::Abs(Int_t(orbit-(input.GetIR(i))->GetOrbit()))<=1){
2874              esdheader->AddTriggerIR(input.GetIR(i));
2875           }
2876     }
2877   }
2878   return kTRUE;
2879 }
2880 //_____________________________________________________________________________
2881 Bool_t AliReconstruction::FillTriggerScalers(AliESDEvent*& esd)
2882 {
2883   //Scalers
2884   //fRunScalers->Print();
2885   if(fRunScalers && fRunScalers->CheckRunScalers()){
2886      AliTimeStamp* timestamp = new AliTimeStamp(esd->GetOrbitNumber(), esd->GetPeriodNumber(), esd->GetBunchCrossNumber());
2887      //AliTimeStamp* timestamp = new AliTimeStamp(10308000, 0, (ULong64_t)486238);
2888      AliESDHeader* esdheader = fesd->GetHeader();
2889      for(Int_t i=0;i<50;i++){
2890           if((1ull<<i) & esd->GetTriggerMask()){
2891           AliTriggerScalersESD* scalesd = fRunScalers->GetScalersForEventClass( timestamp, i+1);
2892           if(scalesd)esdheader->SetTriggerScalersRecord(scalesd);
2893         }
2894      }
2895   }
2896   return kTRUE;
2897 }
2898 //_____________________________________________________________________________
2899 Bool_t AliReconstruction::FillRawEventHeaderESD(AliESDEvent*& esd)
2900 {
2901   // 
2902   // Filling information from RawReader Header
2903   // 
2904
2905   if (!fRawReader) return kFALSE;
2906
2907   AliInfo("Filling information from RawReader Header");
2908
2909   esd->SetBunchCrossNumber(fRawReader->GetBCID());
2910   esd->SetOrbitNumber(fRawReader->GetOrbitID());
2911   esd->SetPeriodNumber(fRawReader->GetPeriod());
2912
2913   esd->SetTimeStamp(fRawReader->GetTimestamp());  
2914   esd->SetEventType(fRawReader->GetType());
2915
2916   return kTRUE;
2917 }
2918
2919
2920 //_____________________________________________________________________________
2921 Bool_t AliReconstruction::IsSelected(TString detName, TString& detectors) const
2922 {
2923 // check whether detName is contained in detectors
2924 // if yes, it is removed from detectors
2925
2926   // check if all detectors are selected
2927   if ((detectors.CompareTo("ALL") == 0) ||
2928       detectors.BeginsWith("ALL ") ||
2929       detectors.EndsWith(" ALL") ||
2930       detectors.Contains(" ALL ")) {
2931     detectors = "ALL";
2932     return kTRUE;
2933   }
2934
2935   // search for the given detector
2936   Bool_t result = kFALSE;
2937   if ((detectors.CompareTo(detName) == 0) ||
2938       detectors.BeginsWith(detName+" ") ||
2939       detectors.EndsWith(" "+detName) ||
2940       detectors.Contains(" "+detName+" ")) {
2941     detectors.ReplaceAll(detName, "");
2942     result = kTRUE;
2943   }
2944
2945   // clean up the detectors string
2946   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
2947   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
2948   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
2949
2950   return result;
2951 }
2952
2953 //_____________________________________________________________________________
2954 Bool_t AliReconstruction::InitRunLoader()
2955 {
2956 // get or create the run loader
2957
2958   if (gAlice) delete gAlice;
2959   gAlice = NULL;
2960
2961   TFile *gafile = TFile::Open(fGAliceFileName.Data());
2962   //  if (!gSystem->AccessPathName(fGAliceFileName.Data())) { // galice.root exists
2963   if (gafile) { // galice.root exists
2964     gafile->Close();
2965     delete gafile;
2966
2967     // load all base libraries to get the loader classes
2968     TString libs = gSystem->GetLibraries();
2969     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2970       TString detName = fgkDetectorName[iDet];
2971       if (detName == "HLT") continue;
2972       if (libs.Contains("lib" + detName + "base.so")) continue;
2973       gSystem->Load("lib" + detName + "base.so");
2974     }
2975     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data());
2976     if (!fRunLoader) {
2977       AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
2978       CleanUp();
2979       return kFALSE;
2980     }
2981
2982     fRunLoader->CdGAFile();
2983     fRunLoader->LoadgAlice();
2984
2985     //PH This is a temporary fix to give access to the kinematics
2986     //PH that is needed for the labels of ITS clusters
2987     fRunLoader->LoadHeader();
2988     fRunLoader->LoadKinematics();
2989
2990   } else {               // galice.root does not exist
2991     if (!fRawReader) {
2992       AliError(Form("the file %s does not exist", fGAliceFileName.Data()));
2993     }
2994     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data(),
2995                                     AliConfig::GetDefaultEventFolderName(),
2996                                     "recreate");
2997     if (!fRunLoader) {
2998       AliError(Form("could not create run loader in file %s", 
2999                     fGAliceFileName.Data()));
3000       CleanUp();
3001       return kFALSE;
3002     }
3003     fIsNewRunLoader = kTRUE;
3004     fRunLoader->MakeTree("E");
3005
3006     if (fNumberOfEventsPerFile > 0)
3007       fRunLoader->SetNumberOfEventsPerFile(fNumberOfEventsPerFile);
3008     else
3009       fRunLoader->SetNumberOfEventsPerFile((UInt_t)-1);
3010   }
3011
3012   return kTRUE;
3013 }
3014
3015 //_____________________________________________________________________________
3016 AliReconstructor* AliReconstruction::GetReconstructor(Int_t iDet)
3017 {
3018 // get the reconstructor object and the loader for a detector
3019
3020   if (fReconstructor[iDet]) {
3021     if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
3022       const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
3023       fReconstructor[iDet]->SetRecoParam(par);
3024       fReconstructor[iDet]->SetRunInfo(fRunInfo);
3025     }
3026     return fReconstructor[iDet];
3027   }
3028
3029   // load the reconstructor object
3030   TPluginManager* pluginManager = gROOT->GetPluginManager();
3031   TString detName = fgkDetectorName[iDet];
3032   TString recName = "Ali" + detName + "Reconstructor";
3033
3034   if (!fIsNewRunLoader && !fRunLoader->GetLoader(detName+"Loader") && (detName != "HLT")) return NULL;
3035
3036   AliReconstructor* reconstructor = NULL;
3037   // first check if a plugin is defined for the reconstructor
3038   TPluginHandler* pluginHandler = 
3039     pluginManager->FindHandler("AliReconstructor", detName);
3040   // if not, add a plugin for it
3041   if (!pluginHandler) {
3042     AliDebug(1, Form("defining plugin for %s", recName.Data()));
3043     TString libs = gSystem->GetLibraries();
3044     if (libs.Contains("lib" + detName + "base.so") ||
3045         (gSystem->Load("lib" + detName + "base.so") >= 0)) {
3046       pluginManager->AddHandler("AliReconstructor", detName, 
3047                                 recName, detName + "rec", recName + "()");
3048     } else {
3049       pluginManager->AddHandler("AliReconstructor", detName, 
3050                                 recName, detName, recName + "()");
3051     }
3052     pluginHandler = pluginManager->FindHandler("AliReconstructor", detName);
3053   }
3054   if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
3055     reconstructor = (AliReconstructor*) pluginHandler->ExecPlugin(0);
3056   }
3057   if (reconstructor) {
3058     TObject* obj = fOptions.FindObject(detName.Data());
3059     if (obj) reconstructor->SetOption(obj->GetTitle());
3060     reconstructor->SetRunInfo(fRunInfo);
3061     reconstructor->Init();
3062     fReconstructor[iDet] = reconstructor;
3063   }
3064
3065   // get or create the loader
3066   if (detName != "HLT") {
3067     fLoader[iDet] = fRunLoader->GetLoader(detName + "Loader");
3068     if (!fLoader[iDet]) {
3069       AliConfig::Instance()
3070         ->CreateDetectorFolders(fRunLoader->GetEventFolder(), 
3071                                 detName, detName);
3072       // first check if a plugin is defined for the loader
3073       pluginHandler = 
3074         pluginManager->FindHandler("AliLoader", detName);
3075       // if not, add a plugin for it
3076       if (!pluginHandler) {
3077         TString loaderName = "Ali" + detName + "Loader";
3078         AliDebug(1, Form("defining plugin for %s", loaderName.Data()));
3079         pluginManager->AddHandler("AliLoader", detName, 
3080                                   loaderName, detName + "base", 
3081                                   loaderName + "(const char*, TFolder*)");
3082         pluginHandler = pluginManager->FindHandler("AliLoader", detName);
3083       }
3084       if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
3085         fLoader[iDet] = 
3086           (AliLoader*) pluginHandler->ExecPlugin(2, detName.Data(), 
3087                                                  fRunLoader->GetEventFolder());
3088       }
3089       if (!fLoader[iDet]) {   // use default loader
3090         fLoader[iDet] = new AliLoader(detName, fRunLoader->GetEventFolder());
3091       }
3092       if (!fLoader[iDet]) {
3093         AliWarning(Form("couldn't get loader for %s", detName.Data()));
3094         if (fStopOnError) return NULL;
3095       } else {
3096         fRunLoader->AddLoader(fLoader[iDet]);
3097         fRunLoader->CdGAFile();
3098         if (gFile && !gFile->IsWritable()) gFile->ReOpen("UPDATE");
3099         fRunLoader->Write(0, TObject::kOverwrite);
3100       }
3101     }
3102   }
3103       
3104   if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
3105     const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
3106     reconstructor->SetRecoParam(par);
3107     reconstructor->SetRunInfo(fRunInfo);
3108   }
3109   return reconstructor;
3110 }
3111
3112 //_____________________________________________________________________________
3113 AliVertexer* AliReconstruction::CreateVertexer()
3114 {
3115 // create the vertexer
3116 // Please note that the caller is the owner of the
3117 // vertexer
3118
3119   AliVertexer* vertexer = NULL;
3120   AliReconstructor* itsReconstructor = GetReconstructor(0);
3121   if (itsReconstructor && ((fRunLocalReconstruction.Contains("ITS")) || 
3122                            fRunTracking.Contains("ITS") || fFillESD.Contains("ITS") )) {
3123     vertexer = itsReconstructor->CreateVertexer();
3124   }
3125   if (!vertexer) {
3126     AliWarning("couldn't create a vertexer for ITS");
3127   }
3128
3129   return vertexer;
3130 }
3131
3132 //_____________________________________________________________________________
3133 AliTrackleter* AliReconstruction::CreateMultFinder()
3134 {
3135 // create the ITS trackleter for mult. estimation
3136 // Please note that the caller is the owner of the
3137 // trackleter
3138
3139   AliTrackleter* trackleter = NULL;
3140   AliReconstructor* itsReconstructor = GetReconstructor(0);
3141   if (itsReconstructor && ((fRunLocalReconstruction.Contains("ITS")) || 
3142                            fRunTracking.Contains("ITS") || fFillESD.Contains("ITS") )) {
3143     trackleter = itsReconstructor->CreateMultFinder();
3144   }
3145   else {
3146     AliWarning("ITS is not in reconstruction, switching off RunMultFinder");
3147     fRunMultFinder = kFALSE;
3148   }
3149
3150   return trackleter;
3151 }
3152
3153 //_____________________________________________________________________________
3154 Bool_t AliReconstruction::CreateTrackers(const TString& detectors)
3155 {
3156 // create the trackers
3157         AliInfo("Creating trackers");
3158
3159   TString detStr = detectors;
3160   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3161     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3162     AliReconstructor* reconstructor = GetReconstructor(iDet);
3163     if (!reconstructor) continue;
3164     TString detName = fgkDetectorName[iDet];
3165     if (detName == "HLT") {
3166       fRunHLTTracking = kTRUE;
3167       continue;
3168     }
3169     if (detName == "MUON") {
3170       fRunMuonTracking = kTRUE;
3171       continue;
3172     }
3173
3174     fTracker[iDet] = reconstructor->CreateTracker();
3175     if (!fTracker[iDet] && (iDet < 7)) {
3176       AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
3177       if (fStopOnError) return kFALSE;
3178     }
3179     AliSysInfo::AddStamp(Form("LTracker%s",fgkDetectorName[iDet]), iDet,0);
3180   }
3181
3182   return kTRUE;
3183 }
3184
3185 //_____________________________________________________________________________
3186 void AliReconstruction::CleanUp()
3187 {
3188 // delete trackers and the run loader and close and delete the file
3189
3190   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3191     delete fReconstructor[iDet];
3192     fReconstructor[iDet] = NULL;
3193     fLoader[iDet] = NULL;
3194     delete fTracker[iDet];
3195     fTracker[iDet] = NULL;
3196   }
3197   delete fRunInfo;
3198   fRunInfo = NULL;
3199
3200   delete fSPDTrackleter;
3201   fSPDTrackleter = NULL;
3202
3203   delete ftVertexer;
3204   ftVertexer = NULL;
3205   
3206   delete fRunLoader;
3207   fRunLoader = NULL;
3208   delete fRawReader;
3209   fRawReader = NULL;
3210   delete fParentRawReader;
3211   fParentRawReader=NULL;
3212
3213   if (ffile) {
3214     ffile->Close();
3215     delete ffile;
3216     ffile = NULL;
3217   }
3218
3219   if (AliQAManager::QAManager())
3220     AliQAManager::QAManager()->ShowQA() ; 
3221   AliQAManager::Destroy() ; 
3222   
3223 }
3224
3225 void AliReconstruction::WriteAlignmentData(AliESDEvent* esd)
3226 {
3227   // Write space-points which are then used in the alignment procedures
3228   // For the moment only ITS, TPC, TRD and TOF
3229
3230   Int_t ntracks = esd->GetNumberOfTracks();
3231   for (Int_t itrack = 0; itrack < ntracks; itrack++)
3232     {
3233       AliESDtrack *track = esd->GetTrack(itrack);
3234       Int_t nsp = 0;
3235       Int_t idx[200];
3236       for (Int_t i=0; i<200; ++i) idx[i] = -1; //PH avoid uninitialized values
3237       for (Int_t iDet = 5; iDet >= 0; iDet--) {// TOF, TRD, TPC, ITS clusters
3238           nsp += (iDet==GetDetIndex("TRD")) ? track->GetTRDntracklets():track->GetNcls(iDet);
3239
3240           if (iDet==GetDetIndex("ITS")) { // ITS "extra" clusters
3241              track->GetClusters(iDet,idx);
3242              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nsp++;
3243           }  
3244       }
3245
3246       if (nsp) {
3247         AliTrackPointArray *sp = new AliTrackPointArray(nsp);
3248         track->SetTrackPointArray(sp);
3249         Int_t isptrack = 0;
3250         for (Int_t iDet = 5; iDet >= 0; iDet--) {
3251           AliTracker *tracker = fTracker[iDet];
3252           if (!tracker) continue;
3253           Int_t nspdet = (iDet==GetDetIndex("TRD")) ? track->GetTRDtracklets(idx):track->GetClusters(iDet,idx);
3254
3255           if (iDet==GetDetIndex("ITS")) // ITS "extra" clusters             
3256              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nspdet++;
3257
3258           if (nspdet <= 0) continue;
3259           AliTrackPoint p;
3260           Int_t isp = 0;
3261           Int_t isp2 = 0;
3262           while (isp2 < nspdet) {
3263             Bool_t isvalid=kTRUE;
3264
3265             Int_t index=idx[isp++];
3266             if (index < 0) continue;
3267
3268             TString dets = fgkDetectorName[iDet];
3269             if ((fUseTrackingErrorsForAlignment.CompareTo(dets) == 0) ||
3270             fUseTrackingErrorsForAlignment.BeginsWith(dets+" ") ||
3271             fUseTrackingErrorsForAlignment.EndsWith(" "+dets) ||
3272             fUseTrackingErrorsForAlignment.Contains(" "+dets+" ")) {
3273               isvalid = tracker->GetTrackPointTrackingError(index,p,track);
3274             } else {
3275               isvalid = tracker->GetTrackPoint(index,p); 
3276             } 
3277             isp2++;
3278             if (!isvalid) continue;
3279             if (iDet==GetDetIndex("ITS") && (isp-1)>=6) p.SetExtra();
3280             sp->AddPoint(isptrack,&p); isptrack++;
3281           }
3282         }       
3283       }
3284     }
3285 }
3286
3287 //_____________________________________________________________________________
3288 void AliReconstruction::FillRawDataErrorLog(Int_t iEvent, AliESDEvent* esd)
3289 {
3290   // The method reads the raw-data error log
3291   // accumulated within the rawReader.
3292   // It extracts the raw-data errors related to
3293   // the current event and stores them into
3294   // a TClonesArray inside the esd object.
3295
3296   if (!fRawReader) return;
3297
3298   for(Int_t i = 0; i < fRawReader->GetNumberOfErrorLogs(); i++) {
3299
3300     AliRawDataErrorLog *log = fRawReader->GetErrorLog(i);
3301     if (!log) continue;
3302     if (iEvent != log->GetEventNumber()) continue;
3303
3304     esd->AddRawDataErrorLog(log);
3305   }
3306
3307 }
3308
3309 //_____________________________________________________________________________
3310 // void AliReconstruction::CheckQA()
3311 // {
3312 // check the QA of SIM for this run and remove the detectors 
3313 // with status Fatal
3314   
3315 //      TString newRunLocalReconstruction ; 
3316 //      TString newRunTracking ;
3317 //      TString newFillESD ;
3318 //       
3319 //      for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
3320 //              TString detName(AliQAv1::GetDetName(iDet)) ;
3321 //              AliQAv1 * qa = AliQAv1::Instance(AliQAv1::DETECTORINDEX_t(iDet)) ;       
3322 //      if ( qa->IsSet(AliQAv1::DETECTORINDEX_t(iDet), AliQAv1::kSIM, specie, AliQAv1::kFATAL)) {
3323 //        AliInfo(Form("QA status for %s %s in Hits and/or SDIGITS  and/or Digits was Fatal; No reconstruction performed", 
3324 //                   detName.Data(), AliRecoParam::GetEventSpecieName(es))) ;
3325 //                      } else {
3326 //                      if ( fRunLocalReconstruction.Contains(AliQAv1::GetDetName(iDet)) || 
3327 //                                      fRunLocalReconstruction.Contains("ALL") )  {
3328 //                              newRunLocalReconstruction += detName ; 
3329 //                              newRunLocalReconstruction += " " ;                      
3330 //                      }
3331 //                      if ( fRunTracking.Contains(AliQAv1::GetDetName(iDet)) || 
3332 //                                      fRunTracking.Contains("ALL") )  {
3333 //                              newRunTracking += detName ; 
3334 //                              newRunTracking += " " ;                         
3335 //                      }
3336 //                      if ( fFillESD.Contains(AliQAv1::GetDetName(iDet)) || 
3337 //                                      fFillESD.Contains("ALL") )  {
3338 //                              newFillESD += detName ; 
3339 //                              newFillESD += " " ;                     
3340 //                      }
3341 //              }
3342 //      }
3343 //      fRunLocalReconstruction = newRunLocalReconstruction ; 
3344 //      fRunTracking            = newRunTracking ; 
3345 //      fFillESD                = newFillESD ; 
3346 // }
3347
3348 //_____________________________________________________________________________
3349 Int_t AliReconstruction::GetDetIndex(const char* detector)
3350 {
3351   // return the detector index corresponding to detector
3352   Int_t index = -1 ; 
3353   for (index = 0; index < kNDetectors ; index++) {
3354     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
3355         break ; 
3356   }     
3357   return index ; 
3358 }
3359 //_____________________________________________________________________________
3360 Bool_t AliReconstruction::FinishPlaneEff() {
3361  //
3362  // Here execute all the necessary operationis, at the end of the tracking phase,
3363  // in case that evaluation of PlaneEfficiencies was required for some detector.
3364  // E.g., write into a DataBase file the PlaneEfficiency which have been evaluated.
3365  //
3366  // This Preliminary version works only FOR ITS !!!!!
3367  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3368  //
3369  //  Input: none
3370  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3371  //
3372  Bool_t ret=kFALSE;
3373  TString detStr = fLoadCDB;
3374  //for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
3375  for (Int_t iDet = 0; iDet < 1; iDet++) { // for the time being only ITS
3376    if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3377    if(fTracker[iDet] && fTracker[iDet]->GetPlaneEff()) {
3378       AliPlaneEff *planeeff=fTracker[iDet]->GetPlaneEff();
3379       TString name=planeeff->GetName();
3380       name+=".root";
3381       TFile* pefile = TFile::Open(name, "RECREATE");
3382       ret=(Bool_t)planeeff->Write();
3383       pefile->Close();
3384       if(planeeff->GetCreateHistos()) {
3385         TString hname=planeeff->GetName();
3386         hname+="Histo.root";
3387         ret*=planeeff->WriteHistosToFile(hname,"RECREATE");
3388       }
3389    }
3390    if(fSPDTrackleter) {
3391      AliPlaneEff *planeeff=fSPDTrackleter->GetPlaneEff();
3392       TString name="AliITSPlaneEffSPDtracklet.root";
3393       TFile* pefile = TFile::Open(name, "RECREATE");
3394       ret=(Bool_t)planeeff->Write();
3395       pefile->Close();
3396       AliESDEvent *dummy=NULL;
3397       ret=(Bool_t)fSPDTrackleter->PostProcess(dummy); // take care of writing other files
3398    }
3399  }
3400  return ret;
3401 }
3402 //_____________________________________________________________________________
3403 Bool_t AliReconstruction::InitPlaneEff() {
3404 //
3405  // Here execute all the necessary operations, before of the tracking phase,
3406  // for the evaluation of PlaneEfficiencies, in case required for some detectors.
3407  // E.g., read from a DataBase file a first evaluation of the PlaneEfficiency
3408  // which should be updated/recalculated.
3409  //
3410  // This Preliminary version will work only FOR ITS !!!!!
3411  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3412  //
3413  //  Input: none
3414  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3415  //
3416
3417   fSPDTrackleter = NULL;
3418   TString detStr = fLoadCDB;
3419   if (IsSelected(fgkDetectorName[0], detStr)) {
3420     AliReconstructor* itsReconstructor = GetReconstructor(0);
3421     if (itsReconstructor) {
3422       fSPDTrackleter = itsReconstructor->CreateTrackleter(); // this is NULL unless required in RecoParam
3423     }
3424     if (fSPDTrackleter) {
3425       AliInfo("Trackleter for SPD has been created");
3426     }
3427   }
3428  return kTRUE;
3429 }
3430
3431 //_____________________________________________________________________________
3432 Bool_t AliReconstruction::InitAliEVE()
3433 {
3434   // This method should be called only in case 
3435   // AliReconstruction is run
3436   // within the alieve environment.
3437   // It will initialize AliEVE in a way
3438   // so that it can visualize event processed
3439   // by AliReconstruction.
3440   // The return flag shows whenever the
3441   // AliEVE initialization was successful or not.
3442
3443   TString macroStr;
3444   macroStr.Form("%s/EVE/macros/alieve_online.C",gSystem->ExpandPathName("$ALICE_ROOT"));
3445   AliInfo(Form("Loading AliEVE macro: %s",macroStr.Data()));
3446   if (gROOT->LoadMacro(macroStr.Data()) != 0) return kFALSE;
3447
3448   gROOT->ProcessLine("if (!AliEveEventManager::GetMaster()){new AliEveEventManager();AliEveEventManager::GetMaster()->AddNewEventCommand(\"alieve_online_on_new_event()\");gEve->AddEvent(AliEveEventManager::GetMaster());};");
3449   gROOT->ProcessLine("alieve_online_init()");
3450
3451   return kTRUE;
3452 }
3453   
3454 //_____________________________________________________________________________
3455 void AliReconstruction::RunAliEVE()
3456 {
3457   // Runs AliEVE visualisation of
3458   // the current event.
3459   // Should be executed only after
3460   // successful initialization of AliEVE.
3461
3462   AliInfo("Running AliEVE...");
3463   gROOT->ProcessLine(Form("AliEveEventManager::GetMaster()->SetEvent((AliRunLoader*)0x%p,(AliRawReader*)0x%p,(AliESDEvent*)0x%p,(AliESDfriend*)0x%p);",fRunLoader,fRawReader,fesd,fesdf));
3464   gSystem->Run();
3465 }
3466
3467 //_____________________________________________________________________________
3468 Bool_t AliReconstruction::SetRunQA(TString detAndAction) 
3469 {
3470         // Allows to run QA for a selected set of detectors
3471         // and a selected set of tasks among RAWS, DIGITSR, RECPOINTS and ESDS
3472         // all selected detectors run the same selected tasks
3473         
3474         if (!detAndAction.Contains(":")) {
3475                 AliError( Form("%s is a wrong syntax, use \"DetectorList:ActionList\" \n", detAndAction.Data()) ) ;
3476                 fRunQA = kFALSE ;
3477                 return kFALSE ;                 
3478         }
3479         Int_t colon = detAndAction.Index(":") ; 
3480         fQADetectors = detAndAction(0, colon) ; 
3481         fQATasks   = detAndAction(colon+1, detAndAction.Sizeof() ) ; 
3482         if (fQATasks.Contains("ALL") ) {
3483                 fQATasks = Form("%d %d %d %d", AliQAv1::kRAWS, AliQAv1::kDIGITSR, AliQAv1::kRECPOINTS, AliQAv1::kESDS) ; 
3484         } else {
3485                 fQATasks.ToUpper() ; 
3486                 TString tempo("") ; 
3487                 if ( fQATasks.Contains("RAW") ) 
3488                         tempo = Form("%d ", AliQAv1::kRAWS) ; 
3489                 if ( fQATasks.Contains("DIGIT") ) 
3490                         tempo += Form("%d ", AliQAv1::kDIGITSR) ; 
3491                 if ( fQATasks.Contains("RECPOINT") ) 
3492                         tempo += Form("%d ", AliQAv1::kRECPOINTS) ; 
3493                 if ( fQATasks.Contains("ESD") ) 
3494                         tempo += Form("%d ", AliQAv1::kESDS) ; 
3495                 fQATasks = tempo ; 
3496                 if (fQATasks.IsNull()) {
3497                         AliInfo("No QA requested\n")  ;
3498                         fRunQA = kFALSE ;
3499                         return kTRUE ; 
3500                 }
3501         }       
3502         TString tempo(fQATasks) ; 
3503         tempo.ReplaceAll(Form("%d", AliQAv1::kRAWS), AliQAv1::GetTaskName(AliQAv1::kRAWS))      ;
3504         tempo.ReplaceAll(Form("%d", AliQAv1::kDIGITSR), AliQAv1::GetTaskName(AliQAv1::kDIGITSR)) ;      
3505         tempo.ReplaceAll(Form("%d", AliQAv1::kRECPOINTS), AliQAv1::GetTaskName(AliQAv1::kRECPOINTS)) ;  
3506         tempo.ReplaceAll(Form("%d", AliQAv1::kESDS), AliQAv1::GetTaskName(AliQAv1::kESDS)) ;    
3507         AliInfo( Form("QA will be done on \"%s\" for \"%s\"\n", fQADetectors.Data(), tempo.Data()) ) ;  
3508         fRunQA = kTRUE ;
3509         return kTRUE; 
3510
3511
3512 //_____________________________________________________________________________
3513 Bool_t AliReconstruction::InitRecoParams() 
3514 {
3515   // The method accesses OCDB and retrieves all
3516   // the available reco-param objects from there.
3517
3518   Bool_t isOK = kTRUE;
3519
3520   if (fRecoParam.GetDetRecoParamArray(kNDetectors)) {
3521     AliInfo("Using custom GRP reconstruction parameters");
3522   }
3523   else {
3524     AliInfo("Loading GRP reconstruction parameter objects");
3525
3526     AliCDBPath path("GRP","Calib","RecoParam");
3527     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
3528     if(!entry){ 
3529       AliWarning("Couldn't find GRP RecoParam entry in OCDB");
3530       isOK = kFALSE;
3531     }
3532     else {
3533       TObject *recoParamObj = entry->GetObject();
3534       if (dynamic_cast<TObjArray*>(recoParamObj)) {
3535         // GRP has a normal TobjArray of AliDetectorRecoParam objects
3536         // Registering them in AliRecoParam
3537         fRecoParam.AddDetRecoParamArray(kNDetectors,dynamic_cast<TObjArray*>(recoParamObj));
3538       }
3539       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
3540         // GRP has only onse set of reco parameters
3541         // Registering it in AliRecoParam
3542         AliInfo("Single set of GRP reconstruction parameters found");
3543         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
3544         fRecoParam.AddDetRecoParam(kNDetectors,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
3545       }
3546       else {
3547         AliError("No valid GRP RecoParam object found in the OCDB");
3548         isOK = kFALSE;
3549       }
3550       entry->SetOwner(0);
3551     }
3552   }
3553
3554   TString detStr = fLoadCDB;
3555   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3556
3557     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3558
3559     if (fRecoParam.GetDetRecoParamArray(iDet)) {
3560       AliInfo(Form("Using custom reconstruction parameters for detector %s",fgkDetectorName[iDet]));
3561       continue;
3562     }
3563
3564     AliInfo(Form("Loading reconstruction parameter objects for detector %s",fgkDetectorName[iDet]));
3565   
3566     AliCDBPath path(fgkDetectorName[iDet],"Calib","RecoParam");
3567     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
3568     if(!entry){ 
3569       AliWarning(Form("Couldn't find RecoParam entry in OCDB for detector %s",fgkDetectorName[iDet]));
3570       isOK = kFALSE;
3571     }
3572     else {
3573       TObject *recoParamObj = entry->GetObject();
3574       if (dynamic_cast<TObjArray*>(recoParamObj)) {
3575         // The detector has a normal TobjArray of AliDetectorRecoParam objects
3576         // Registering them in AliRecoParam
3577         fRecoParam.AddDetRecoParamArray(iDet,dynamic_cast<TObjArray*>(recoParamObj));
3578       }
3579       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
3580         // The detector has only onse set of reco parameters
3581         // Registering it in AliRecoParam
3582         AliInfo(Form("Single set of reconstruction parameters found for detector %s",fgkDetectorName[iDet]));
3583         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
3584         fRecoParam.AddDetRecoParam(iDet,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
3585       }
3586       else {
3587         AliError(Form("No valid RecoParam object found in the OCDB for detector %s",fgkDetectorName[iDet]));
3588         isOK = kFALSE;
3589       }
3590       entry->SetOwner(0);
3591       //      FIX ME: We have to disable the unloading of reco-param CDB
3592       //      entries because QA framework is using them. Has to be fix in
3593       //      a way that the QA takes the objects already constructed in
3594       //      this method.
3595       //      AliCDBManager::Instance()->UnloadFromCache(path.GetPath());
3596     }
3597   }
3598
3599   if (AliDebugLevel() > 0) fRecoParam.Print();
3600
3601   return isOK;
3602 }
3603
3604 //_____________________________________________________________________________
3605 Bool_t AliReconstruction::GetEventInfo() 
3606 {
3607   // Fill the event info object
3608   // ...
3609   AliCodeTimerAuto("",0)
3610
3611   AliCentralTrigger *aCTP = NULL;
3612   if (fRawReader) {
3613     fEventInfo.SetEventType(fRawReader->GetType());
3614
3615     ULong64_t mask = fRawReader->GetClassMask();
3616     fEventInfo.SetTriggerMask(mask);
3617     UInt_t clmask = fRawReader->GetDetectorPattern()[0];
3618     fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(clmask));
3619
3620     aCTP = new AliCentralTrigger();
3621     TString configstr("");
3622     if (!aCTP->LoadConfiguration(configstr)) { // Load CTP config from OCDB
3623       AliError("No trigger configuration found in OCDB! The trigger configuration information will not be used!");
3624       delete aCTP;
3625       return kFALSE;
3626     }
3627     aCTP->SetClassMask(mask);
3628     aCTP->SetClusterMask(clmask);
3629   }
3630   else {
3631     fEventInfo.SetEventType(AliRawEventHeaderBase::kPhysicsEvent);
3632
3633     if (fRunLoader && (!fRunLoader->LoadTrigger())) {
3634       aCTP = fRunLoader->GetTrigger();
3635       fEventInfo.SetTriggerMask(aCTP->GetClassMask());
3636       // get inputs from actp - just get
3637       AliESDHeader* esdheader = fesd->GetHeader();
3638       esdheader->SetL0TriggerInputs(aCTP->GetL0TriggerInputs());
3639       esdheader->SetL1TriggerInputs(aCTP->GetL1TriggerInputs());
3640       esdheader->SetL2TriggerInputs(aCTP->GetL2TriggerInputs());
3641       fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(aCTP->GetClusterMask()));
3642     }
3643     else {
3644       AliWarning("No trigger can be loaded! The trigger information will not be used!");
3645       return kFALSE;
3646     }
3647   }
3648
3649   AliTriggerConfiguration *config = aCTP->GetConfiguration();
3650   if (!config) {
3651     AliError("No trigger configuration has been found! The trigger configuration information will not be used!");
3652     if (fRawReader) delete aCTP;
3653     return kFALSE;
3654   }
3655
3656   UChar_t clustmask = 0;
3657   TString trclasses;
3658   ULong64_t trmask = fEventInfo.GetTriggerMask();
3659   const TObjArray& classesArray = config->GetClasses();
3660   Int_t nclasses = classesArray.GetEntriesFast();
3661   for( Int_t iclass=0; iclass < nclasses; iclass++ ) {
3662     AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At(iclass);
3663     if (trclass && trclass->GetMask()>0) {
3664       Int_t trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
3665       fesd->SetTriggerClass(trclass->GetName(),trindex);
3666       if (fRawReader) fRawReader->LoadTriggerClass(trclass->GetName(),trindex);
3667       if (trmask & (1ull << trindex)) {
3668         trclasses += " ";
3669         trclasses += trclass->GetName();
3670         trclasses += " ";
3671         clustmask |= trclass->GetCluster()->GetClusterMask();
3672       }
3673     }
3674   }
3675   fEventInfo.SetTriggerClasses(trclasses);
3676
3677   // Write names of active trigger inputs in ESD Header
3678   const TObjArray& inputsArray = config->GetInputs(); 
3679   Int_t ninputs = inputsArray.GetEntriesFast();
3680   for( Int_t iinput=0; iinput < ninputs; iinput++ ) {
3681     AliTriggerInput* trginput = (AliTriggerInput*)inputsArray.At(iinput);
3682     if (trginput && trginput->GetMask()>0) {
3683       Int_t inputIndex = (Int_t)TMath::Nint(TMath::Log2(trginput->GetMask()));
3684       AliESDHeader* headeresd = fesd->GetHeader();
3685       Int_t trglevel = (Int_t)trginput->GetLevel();
3686       if (trglevel == 0) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex);
3687       if (trglevel == 1) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex+24);
3688       if (trglevel == 2) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex+48);
3689     }
3690   }
3691
3692   // Set the information in ESD
3693   fesd->SetTriggerMask(trmask);
3694   fesd->SetTriggerCluster(clustmask);
3695
3696   if (!aCTP->CheckTriggeredDetectors()) {
3697     if (fRawReader) delete aCTP;
3698     return kFALSE;
3699   }    
3700
3701   if (fRawReader) delete aCTP;
3702
3703   // We have to fill also the HLT decision here!!
3704   // ...
3705
3706   return kTRUE;
3707 }
3708
3709 const char *AliReconstruction::MatchDetectorList(const char *detectorList, UInt_t detectorMask)
3710 {
3711   // Match the detector list found in the rec.C or the default 'ALL'
3712   // to the list found in the GRP (stored there by the shuttle PP which
3713   // gets the information from ECS)
3714   static TString resultList;
3715   TString detList = detectorList;
3716
3717   resultList = "";
3718
3719   for(Int_t iDet = 0; iDet < (AliDAQ::kNDetectors-1); iDet++) {
3720     if ((detectorMask >> iDet) & 0x1) {
3721       TString det = AliDAQ::OfflineModuleName(iDet);
3722       if ((detList.CompareTo("ALL") == 0) ||
3723           ((detList.BeginsWith("ALL ") ||
3724             detList.EndsWith(" ALL") ||
3725             detList.Contains(" ALL ")) &&
3726            !(detList.BeginsWith("-"+det+" ") ||
3727              detList.EndsWith(" -"+det) ||
3728              detList.Contains(" -"+det+" "))) ||
3729           (detList.CompareTo(det) == 0) ||
3730           detList.BeginsWith(det+" ") ||
3731           detList.EndsWith(" "+det) ||
3732           detList.Contains( " "+det+" " )) {
3733         if (!resultList.EndsWith(det + " ")) {
3734           resultList += det;
3735           resultList += " ";
3736         }
3737       }        
3738     }
3739   }
3740
3741   // HLT
3742   if ((detectorMask >> AliDAQ::kHLTId) & 0x1) {
3743     TString hltDet = AliDAQ::OfflineModuleName(AliDAQ::kNDetectors-1);
3744     if ((detList.CompareTo("ALL") == 0) ||
3745         ((detList.BeginsWith("ALL ") ||
3746           detList.EndsWith(" ALL") ||
3747           detList.Contains(" ALL ")) &&
3748          !(detList.BeginsWith("-"+hltDet+" ") ||
3749            detList.EndsWith(" -"+hltDet) ||
3750            detList.Contains(" -"+hltDet+" "))) ||
3751         (detList.CompareTo(hltDet) == 0) ||
3752         detList.BeginsWith(hltDet+" ") ||
3753         detList.EndsWith(" "+hltDet) ||
3754         detList.Contains( " "+hltDet+" " )) {
3755       resultList += hltDet;
3756     }
3757   }
3758
3759   return resultList.Data();
3760
3761 }
3762
3763 //______________________________________________________________________________
3764 void AliReconstruction::Abort(const char *method, EAbort what)
3765 {
3766   // Abort processing. If what = kAbortProcess, the Process() loop will be
3767   // aborted. If what = kAbortFile, the current file in a chain will be
3768   // aborted and the processing will continue with the next file, if there
3769   // is no next file then Process() will be aborted. Abort() can also  be
3770   // called from Begin(), SlaveBegin(), Init() and Notify(). After abort
3771   // the SlaveTerminate() and Terminate() are always called. The abort flag
3772   // can be checked in these methods using GetAbort().
3773   //
3774   // The method is overwritten in AliReconstruction for better handling of
3775   // reco specific errors 
3776
3777   if (!fStopOnError) return;
3778
3779   CleanUp();
3780
3781   TString whyMess = method;
3782   whyMess += " failed! Aborting...";
3783
3784   AliError(whyMess.Data());
3785
3786   fAbort = what;
3787   TString mess = "Abort";
3788   if (fAbort == kAbortProcess)
3789     mess = "AbortProcess";
3790   else if (fAbort == kAbortFile)
3791     mess = "AbortFile";
3792
3793   Info(mess, whyMess.Data());
3794 }
3795
3796 //______________________________________________________________________________
3797 Bool_t AliReconstruction::ProcessEvent(void* event)
3798 {
3799   // Method that is used in case the event loop
3800   // is steered from outside, for example by AMORE
3801   // 'event' is a pointer to the DATE event in the memory
3802
3803   if (fRawReader) delete fRawReader;
3804   fRawReader = new AliRawReaderDate(event);
3805   fStatus = ProcessEvent(fRunLoader->GetNumberOfEvents());  
3806   delete fRawReader;
3807   fRawReader = NULL;
3808
3809   return fStatus;
3810 }
3811
3812 //______________________________________________________________________________
3813 Bool_t AliReconstruction::ParseOutput()
3814 {
3815   // The method parses the output file
3816   // location string in order to steer
3817   // properly the selector
3818
3819   TPMERegexp re1("(\\w+\\.zip#\\w+\\.root):([,*\\w+\\.root,*]+)@dataset://(\\w++)");
3820   TPMERegexp re2("(\\w+\\.root)?@?dataset://(\\w++)");
3821
3822   if (re1.Match(fESDOutput) == 4) {
3823     // root archive with output files stored and regustered
3824     // in proof dataset
3825     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",re1[1].Data()));
3826     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",re1[3].Data()));
3827     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_DATASET",""));
3828     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_ARCHIVE",re1[2].Data()));
3829     AliInfo(Form("%s files will be stored within %s in dataset %s",
3830                  re1[2].Data(),
3831                  re1[1].Data(),
3832                  re1[3].Data()));
3833   }
3834   else if (re2.Match(fESDOutput) == 3) {
3835     // output file stored and registered
3836     // in proof dataset
3837     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",(re2[1].IsNull()) ? "AliESDs.root" : re2[1].Data()));
3838     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",re2[2].Data()));
3839     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_DATASET",""));
3840     AliInfo(Form("%s will be stored in dataset %s",
3841                  (re2[1].IsNull()) ? "AliESDs.root" : re2[1].Data(),
3842                  re2[2].Data()));
3843   }
3844   else {
3845     if (fESDOutput.IsNull()) {
3846       // Output location not given.
3847       // Assuming xrootd has been already started and
3848       // the output file has to be sent back
3849       // to the client machine
3850       TString esdUrl(Form("root://%s/%s/",
3851                           TUrl(gSystem->HostName()).GetHostFQDN(),
3852                           gSystem->pwd()));
3853       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE","AliESDs.root"));
3854       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",esdUrl.Data()));
3855       AliInfo(Form("AliESDs.root will be stored in %s",
3856                    esdUrl.Data()));
3857     }
3858     else {
3859       // User specified an output location.
3860       // Ones has just to parse it here
3861       TUrl outputUrl(fESDOutput.Data());
3862       TString outputFile(gSystem->BaseName(outputUrl.GetFile()));
3863       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",outputFile.IsNull() ? "AliESDs.root" : outputFile.Data()));
3864       TString outputLocation(outputUrl.GetUrl());
3865       outputLocation.ReplaceAll(outputFile.Data(),"");
3866       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",outputLocation.Data()));
3867       AliInfo(Form("%s will be stored in %s",
3868                    outputFile.IsNull() ? "AliESDs.root" : outputFile.Data(),
3869                    outputLocation.Data()));
3870     }
3871   }
3872
3873   return kTRUE;
3874 }