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