]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliReconstruction.cxx
Coverity fixes
[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 && (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 && (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        // get cuts for V0vertexer from AliGRPRecoParam
2042        if (grpRecoParam) {
2043          Int_t nCutsV0vertexer = grpRecoParam->GetVertexerV0NCuts();
2044          Double_t *cutsV0vertexer = new Double_t[nCutsV0vertexer];
2045          grpRecoParam->GetVertexerV0Cuts(cutsV0vertexer);
2046          vtxer.SetCuts(cutsV0vertexer);
2047          delete [] cutsV0vertexer; cutsV0vertexer = NULL; 
2048        }
2049        vtxer.Tracks2V0vertices(fesd);
2050
2051        if (fRunCascadeFinder) {
2052           // Cascade finding
2053           AliCascadeVertexer cvtxer;
2054           // get cuts for CascadeVertexer from AliGRPRecoParam
2055           if (grpRecoParam) {
2056             Int_t nCutsCascadeVertexer = grpRecoParam->GetVertexerCascadeNCuts();
2057             Double_t *cutsCascadeVertexer = new Double_t[nCutsCascadeVertexer];
2058             grpRecoParam->GetVertexerCascadeCuts(cutsCascadeVertexer);
2059             cvtxer.SetCuts(cutsCascadeVertexer);
2060             delete [] cutsCascadeVertexer; cutsCascadeVertexer = NULL; 
2061           }
2062           cvtxer.V0sTracks2CascadeVertices(fesd);
2063        }
2064     }
2065
2066     // write ESD
2067     if (fCleanESD) CleanESD(fesd);
2068     // 
2069     // RS run updated trackleter: since we want to mark the clusters used by tracks and also mark the 
2070     // tracks interpreted as primary, this step should be done in the very end, when full 
2071     // ESD info is available (particulalry, V0s)
2072     // vertex finder
2073     if (fRunMultFinder) {
2074       if (!RunMultFinder(fesd)) {
2075         if (fStopOnError) {CleanUp(); return kFALSE;}
2076       }
2077     }
2078
2079   if (fRunQA && IsInTasks(AliQAv1::kESDS)) {
2080     AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2081     AliQAManager::QAManager()->RunOneEvent(fesd, fhltesd) ; 
2082   }
2083   if (fRunGlobalQA) {
2084     AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
2085       qadm->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2086     if (qadm && IsInTasks(AliQAv1::kESDS))
2087       qadm->Exec(AliQAv1::kESDS, fesd);
2088   }
2089
2090   // copy HLT decision from HLTesd to esd
2091   // the most relevant information is stored in a reduced container in the esd,
2092   // while the full information can be found in the HLTesd
2093   TObject* pHLTSrc=fhltesd->FindListObject(AliESDHLTDecision::Name());
2094   TObject* pHLTTgt=fesd->FindListObject(AliESDHLTDecision::Name());
2095   if (pHLTSrc && pHLTTgt) {
2096     pHLTSrc->Copy(*pHLTTgt);
2097   }
2098
2099     if (fWriteESDfriend) 
2100       fesd->GetESDfriend(fesdf);
2101
2102     ftree->Fill();
2103     if (fWriteESDfriend) {
2104       WriteESDfriend();
2105     }
2106
2107     // Auto-save the ESD tree in case of prompt reco @P2
2108     if (fRawReader && fRawReader->UseAutoSaveESD()) {
2109       ftree->AutoSave("SaveSelf");
2110       if (fWriteESDfriend) ftreeF->AutoSave("SaveSelf");
2111     }
2112
2113     // write HLT ESD
2114     fhlttree->Fill();
2115
2116     // call AliEVE
2117     if (fRunAliEVE) RunAliEVE();
2118
2119     fesd->Reset();
2120     fhltesd->Reset();
2121     if (fWriteESDfriend) {
2122       fesdf->~AliESDfriend();
2123       new (fesdf) AliESDfriend(); // Reset...
2124     }
2125  
2126     gSystem->GetProcInfo(&procInfo);
2127     Long_t dMres=(procInfo.fMemResident-oldMres)/1024;
2128     Long_t dMvir=(procInfo.fMemVirtual-oldMvir)/1024;
2129     Float_t dCPU=procInfo.fCpuUser+procInfo.fCpuSys-oldCPU;
2130     aveDMres+=(dMres-aveDMres)/(iEvent-fFirstEvent+1);
2131     aveDMvir+=(dMvir-aveDMvir)/(iEvent-fFirstEvent+1);
2132     aveDCPU+=(dCPU-aveDCPU)/(iEvent-fFirstEvent+1);
2133     AliInfo(Form("======================= End Event %d: Res %ld(%3ld <%3ld>) Vir %ld(%3ld <%3ld>) CPU %5.2f <%5.2f> ===================",
2134                  iEvent, procInfo.fMemResident/1024, dMres, aveDMres, procInfo.fMemVirtual/1024, dMvir, aveDMvir, dCPU, aveDCPU));
2135     oldMres=procInfo.fMemResident;
2136     oldMvir=procInfo.fMemVirtual;
2137     oldCPU=procInfo.fCpuUser+procInfo.fCpuSys;
2138   
2139     fEventInfo.Reset();
2140     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2141       if (fReconstructor[iDet]) {
2142         fReconstructor[iDet]->SetRecoParam(NULL);
2143         fReconstructor[iDet]->SetEventInfo(NULL);
2144       }
2145       if (fTracker[iDet]) fTracker[iDet]->SetEventInfo(NULL);
2146     }
2147         
2148   if (fRunQA || fRunGlobalQA) 
2149     AliQAManager::QAManager()->Increment() ; 
2150   
2151     return kTRUE;
2152 }
2153
2154 //_____________________________________________________________________________
2155 void AliReconstruction::SlaveTerminate()
2156 {
2157   // Finalize the run on the slave side
2158   // Called after the exit
2159   // from the event loop
2160   AliCodeTimerAuto("",0);
2161
2162   if (fIsNewRunLoader) { // galice.root didn't exist
2163     fRunLoader->WriteHeader("OVERWRITE");
2164     fRunLoader->CdGAFile();
2165     fRunLoader->Write(0, TObject::kOverwrite);
2166   }
2167
2168   const TMap *cdbMap = AliCDBManager::Instance()->GetStorageMap();       
2169   const TList *cdbList = AliCDBManager::Instance()->GetRetrievedIds();   
2170                  
2171    TMap *cdbMapCopy = new TMap(cdbMap->GetEntries());    
2172    cdbMapCopy->SetOwner(1);      
2173    cdbMapCopy->SetName("cdbMap");        
2174    TIter iter(cdbMap->GetTable());       
2175          
2176    TPair* pair = 0;      
2177    while((pair = dynamic_cast<TPair*> (iter.Next()))){   
2178          TObjString* keyStr = dynamic_cast<TObjString*> (pair->Key());   
2179          TObjString* valStr = dynamic_cast<TObjString*> (pair->Value());
2180          if (keyStr && valStr)
2181            cdbMapCopy->Add(new TObjString(keyStr->GetName()), new TObjString(valStr->GetName()));        
2182    }     
2183          
2184    TList *cdbListCopy = new TList();     
2185    cdbListCopy->SetOwner(1);     
2186    cdbListCopy->SetName("cdbList");      
2187          
2188    TIter iter2(cdbList);         
2189          
2190         AliCDBId* id=0;
2191         while((id = dynamic_cast<AliCDBId*> (iter2.Next()))){    
2192          cdbListCopy->Add(new TObjString(id->ToString().Data()));        
2193    }     
2194          
2195    ftree->GetUserInfo()->Add(cdbMapCopy);        
2196    ftree->GetUserInfo()->Add(cdbListCopy);
2197
2198
2199   ffile->cd();
2200
2201   // we want to have only one tree version number
2202   ftree->Write(ftree->GetName(),TObject::kOverwrite);
2203   fhlttree->Write(fhlttree->GetName(),TObject::kOverwrite);
2204
2205   if (fWriteESDfriend) {
2206     ffileF->cd();
2207     ftreeF->Write(ftreeF->GetName(),TObject::kOverwrite);
2208   }
2209
2210 // Finish with Plane Efficiency evaluation: before of CleanUp !!!
2211   if (fRunPlaneEff && !FinishPlaneEff()) {
2212    AliWarning("Finish PlaneEff evaluation failed");
2213   }
2214
2215   // End of cycle for the in-loop  
2216
2217   if (fRunQA || fRunGlobalQA) {
2218     AliQAManager::QAManager()->EndOfCycle() ;
2219     if (fInput &&
2220         !fProofOutputLocation.IsNull() &&
2221         fProofOutputArchive.IsNull() &&
2222         !fProofOutputDataset) {
2223       TString qaOutputFile(Form("%sMerged.%s.Data.root",
2224                                 fProofOutputLocation.Data(),
2225                                 AliQAv1::GetQADataFileName()));
2226       TProofOutputFile *qaProofFile = new TProofOutputFile(Form("Merged.%s.Data.root",
2227                                                                 AliQAv1::GetQADataFileName()));
2228       qaProofFile->SetOutputFileName(qaOutputFile.Data());
2229       if (AliDebugLevel() > 0) qaProofFile->Dump();
2230       fOutput->Add(qaProofFile);
2231       MergeQA(qaProofFile->GetFileName());
2232     }
2233     else {
2234       MergeQA();
2235     }
2236   }
2237
2238   gROOT->cd();
2239   CleanUp();
2240
2241   if (fInput) {
2242     if (!fProofOutputFileName.IsNull() &&
2243         !fProofOutputLocation.IsNull() &&
2244         fProofOutputDataset &&
2245         !fProofOutputArchive.IsNull()) {
2246       TProofOutputFile *zipProofFile = new TProofOutputFile(fProofOutputFileName.Data(),
2247                                                             "DROV",
2248                                                             fProofOutputLocation.Data());
2249       if (AliDebugLevel() > 0) zipProofFile->Dump();
2250       fOutput->Add(zipProofFile);
2251       TString fileList(fProofOutputArchive.Data());
2252       fileList.ReplaceAll(","," ");
2253       TString command;
2254 #if ROOT_SVN_REVISION >= 30174
2255       command.Form("zip -n root %s/%s %s",zipProofFile->GetDir(kTRUE),zipProofFile->GetFileName(),fileList.Data());
2256 #else
2257       command.Form("zip -n root %s/%s %s",zipProofFile->GetDir(),zipProofFile->GetFileName(),fileList.Data());
2258 #endif
2259       AliInfo(Form("Executing: %s",command.Data()));
2260       gSystem->Exec(command.Data());
2261     }
2262   }
2263 }
2264     
2265 //_____________________________________________________________________________
2266 void AliReconstruction::Terminate()
2267 {
2268   // Create tags for the events in the ESD tree (the ESD tree is always present)
2269   // In case of empty events the tags will contain dummy values
2270   AliCodeTimerAuto("",0);
2271
2272   // Do not call the ESD tag creator in case of PROOF-based reconstruction
2273   if (!fInput) {
2274     AliESDTagCreator *esdtagCreator = new AliESDTagCreator();
2275     esdtagCreator->CreateESDTags(fFirstEvent,fLastEvent,fGRPData, AliQAv1::Instance()->GetQA(), AliQAv1::Instance()->GetEventSpecies(), AliQAv1::kNDET, AliRecoParam::kNSpecies);
2276     delete esdtagCreator;
2277   }
2278
2279   // Cleanup of CDB manager: cache and active storages!
2280   AliCDBManager::Instance()->ClearCache();
2281 }
2282
2283 //_____________________________________________________________________________
2284 Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
2285 {
2286 // run the local reconstruction
2287
2288   static Int_t eventNr=0;
2289   AliCodeTimerAuto("",0)
2290
2291   TString detStr = detectors;
2292   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2293     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2294     AliReconstructor* reconstructor = GetReconstructor(iDet);
2295     if (!reconstructor) continue;
2296     AliLoader* loader = fLoader[iDet];
2297     // Matthias April 2008: temporary fix to run HLT reconstruction
2298     // although the HLT loader is missing
2299     if (strcmp(fgkDetectorName[iDet], "HLT")==0) {
2300       if (fRawReader) {
2301         reconstructor->Reconstruct(fRawReader, NULL);
2302       } else {
2303         TTree* dummy=NULL;
2304         reconstructor->Reconstruct(dummy, NULL);
2305       }
2306       continue;
2307     }
2308     if (!loader) {
2309       AliWarning(Form("No loader is defined for %s!",fgkDetectorName[iDet]));
2310       continue;
2311     }
2312     // conversion of digits
2313     if (fRawReader && reconstructor->HasDigitConversion()) {
2314       AliInfo(Form("converting raw data digits into root objects for %s", 
2315                    fgkDetectorName[iDet]));
2316 //      AliCodeTimerAuto(Form("converting raw data digits into root objects for %s", 
2317 //                            fgkDetectorName[iDet]),0);
2318       loader->LoadDigits("update");
2319       loader->CleanDigits();
2320       loader->MakeDigitsContainer();
2321       TTree* digitsTree = loader->TreeD();
2322       reconstructor->ConvertDigits(fRawReader, digitsTree);
2323       loader->WriteDigits("OVERWRITE");
2324       loader->UnloadDigits();
2325     }
2326     // local reconstruction
2327     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
2328     //AliCodeTimerAuto(Form("running reconstruction for %s", fgkDetectorName[iDet]),0);
2329     loader->LoadRecPoints("update");
2330     loader->CleanRecPoints();
2331     loader->MakeRecPointsContainer();
2332     TTree* clustersTree = loader->TreeR();
2333     if (fRawReader && !reconstructor->HasDigitConversion()) {
2334       reconstructor->Reconstruct(fRawReader, clustersTree);
2335     } else {
2336       loader->LoadDigits("read");
2337       TTree* digitsTree = loader->TreeD();
2338       if (!digitsTree) {
2339         AliError(Form("Can't get the %s digits tree", fgkDetectorName[iDet]));
2340         if (fStopOnError) 
2341           return kFALSE;
2342       } else {
2343         reconstructor->Reconstruct(digitsTree, clustersTree);
2344         if (fRunQA && IsInTasks(AliQAv1::kDIGITSR)) {
2345           AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2346           AliQAManager::QAManager()->RunOneEventInOneDetector(iDet, digitsTree) ; 
2347         }
2348       }
2349       loader->UnloadDigits();
2350     }
2351                 if (fRunQA && IsInTasks(AliQAv1::kRECPOINTS)) {
2352       AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2353                         AliQAManager::QAManager()->RunOneEventInOneDetector(iDet, clustersTree) ; 
2354     }
2355     loader->WriteRecPoints("OVERWRITE");
2356     loader->UnloadRecPoints();
2357     AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr), iDet,1,eventNr);
2358   }
2359   if (!IsSelected("CTP", detStr)) AliDebug(10,"No CTP");
2360   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2361     AliError(Form("the following detectors were not found: %s",
2362                   detStr.Data()));
2363     if (fStopOnError) 
2364       return kFALSE;
2365   }
2366   eventNr++;
2367   return kTRUE;
2368 }
2369 //_____________________________________________________________________________
2370 Bool_t AliReconstruction::RunSPDTrackleting(AliESDEvent*& esd)
2371 {
2372 // run the SPD trackleting (for SPD efficiency purpouses)
2373
2374   AliCodeTimerAuto("",0)
2375
2376   Double_t vtxPos[3] = {0, 0, 0};
2377   Double_t vtxErr[3] = {0.0, 0.0, 0.0};
2378 /*
2379   TArrayF mcVertex(3);
2380   // if(MC)
2381   if (fRunLoader->GetHeader() && fRunLoader->GetHeader()->GenEventHeader()) {
2382     fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(mcVertex);
2383     for (Int_t i = 0; i < 3; i++) vtxPos[i] = mcVertex[i];
2384   }
2385 */
2386   const AliESDVertex *vertex = esd->GetVertex();
2387   if(!vertex){
2388     AliWarning("Vertex not found");
2389     return kFALSE;
2390   }
2391   vertex->GetXYZ(vtxPos);
2392   vertex->GetSigmaXYZ(vtxErr);
2393   if (fSPDTrackleter) {
2394     AliInfo("running the SPD Trackleter for Plane Efficiency Evaluation");
2395
2396     // load clusters
2397     fLoader[0]->LoadRecPoints("read");
2398     TTree* tree = fLoader[0]->TreeR();
2399     if (!tree) {
2400       AliError("Can't get the ITS cluster tree");
2401       return kFALSE;
2402     }
2403     fSPDTrackleter->LoadClusters(tree);
2404     fSPDTrackleter->SetVertex(vtxPos, vtxErr);
2405     // run trackleting
2406     if (fSPDTrackleter->Clusters2Tracks(esd) != 0) {
2407       AliWarning("AliITSTrackleterSPDEff Clusters2Tracks failed");
2408      // fLoader[0]->UnloadRecPoints();
2409       return kFALSE;
2410     }
2411 //fSPDTrackleter->UnloadRecPoints();
2412   } else {
2413     AliWarning("SPDTrackleter not available");
2414     return kFALSE;
2415   }
2416   return kTRUE;
2417 }
2418
2419 //_____________________________________________________________________________
2420 Bool_t AliReconstruction::RunVertexFinder(AliESDEvent*& esd)
2421 {
2422 // run the barrel tracking
2423
2424   AliCodeTimerAuto("",0)
2425
2426   AliVertexer *vertexer = CreateVertexer();
2427   if (!vertexer) return kFALSE;
2428
2429   AliInfo(Form("running the ITS vertex finder: %s",vertexer->ClassName()));
2430   AliESDVertex* vertex = NULL;
2431   if (fLoader[0]) {
2432     fLoader[0]->LoadRecPoints();
2433     TTree* cltree = fLoader[0]->TreeR();
2434     if (cltree) {
2435       if(fDiamondProfileSPD) vertexer->SetVtxStart(fDiamondProfileSPD);
2436       vertex = vertexer->FindVertexForCurrentEvent(cltree);
2437     }
2438     else {
2439       AliError("Can't get the ITS cluster tree");
2440     }
2441     fLoader[0]->UnloadRecPoints();
2442   }
2443   else {
2444     AliError("Can't get the ITS loader");
2445   }
2446   if(!vertex){
2447     AliWarning("Vertex not found");
2448     vertex = new AliESDVertex();
2449     vertex->SetName("default");
2450   }
2451   else {
2452     vertex->SetName("reconstructed");
2453   }
2454
2455   Double_t vtxPos[3];
2456   Double_t vtxErr[3];
2457   vertex->GetXYZ(vtxPos);
2458   vertex->GetSigmaXYZ(vtxErr);
2459
2460   esd->SetPrimaryVertexSPD(vertex);
2461   AliESDVertex *vpileup = NULL;
2462   Int_t novertices = 0;
2463   vpileup = vertexer->GetAllVertices(novertices);
2464   if(novertices>1){
2465     for (Int_t kk=1; kk<novertices; kk++)esd->AddPileupVertexSPD(&vpileup[kk]);
2466   }
2467   /*
2468   // if SPD multiplicity has been determined, it is stored in the ESD
2469   AliMultiplicity *mult = vertexer->GetMultiplicity();
2470   if(mult)esd->SetMultiplicity(mult);
2471   */
2472   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2473     if (fTracker[iDet]) fTracker[iDet]->SetVertex(vtxPos, vtxErr);
2474   }  
2475   delete vertex;
2476
2477   delete vertexer;
2478
2479   return kTRUE;
2480 }
2481
2482 //_____________________________________________________________________________
2483 Bool_t AliReconstruction::RunMultFinder(AliESDEvent*& esd)
2484 {
2485   // run the trackleter for multiplicity study
2486
2487   AliCodeTimerAuto("",0)
2488
2489   AliTrackleter *trackleter = CreateMultFinder();
2490   if (!trackleter) return kFALSE;
2491
2492   AliInfo(Form("running the ITS multiplicity finder: %s",trackleter->ClassName()));
2493
2494   if (fLoader[0]) {
2495     fLoader[0]->LoadRecPoints();
2496     TTree* cltree = fLoader[0]->TreeR();
2497     if (cltree) {
2498       trackleter->Reconstruct(esd,cltree);
2499       AliMultiplicity *mult = trackleter->GetMultiplicity();
2500       if(mult) esd->SetMultiplicity(mult);
2501     }
2502     else {
2503       AliError("Can't get the ITS cluster tree");
2504     }
2505     fLoader[0]->UnloadRecPoints();
2506   }
2507   else {
2508     AliError("Can't get the ITS loader");
2509   }
2510
2511   delete trackleter;
2512
2513   return kTRUE;
2514 }
2515
2516 //_____________________________________________________________________________
2517 Bool_t AliReconstruction::RunHLTTracking(AliESDEvent*& esd)
2518 {
2519 // run the HLT barrel tracking
2520
2521   AliCodeTimerAuto("",0)
2522
2523   if (!fRunLoader) {
2524     AliError("Missing runLoader!");
2525     return kFALSE;
2526   }
2527
2528   AliInfo("running HLT tracking");
2529
2530   // Get a pointer to the HLT reconstructor
2531   AliReconstructor *reconstructor = GetReconstructor(kNDetectors-1);
2532   if (!reconstructor) return kFALSE;
2533
2534   // TPC + ITS
2535   for (Int_t iDet = 1; iDet >= 0; iDet--) {
2536     TString detName = fgkDetectorName[iDet];
2537     AliDebug(1, Form("%s HLT tracking", detName.Data()));
2538     reconstructor->SetOption(detName.Data());
2539     AliTracker *tracker = reconstructor->CreateTracker();
2540     if (!tracker) {
2541       AliWarning(Form("couldn't create a HLT tracker for %s", detName.Data()));
2542       if (fStopOnError) return kFALSE;
2543       continue;
2544     }
2545     Double_t vtxPos[3];
2546     Double_t vtxErr[3]={0.005,0.005,0.010};
2547     const AliESDVertex *vertex = esd->GetVertex();
2548     vertex->GetXYZ(vtxPos);
2549     tracker->SetVertex(vtxPos,vtxErr);
2550     if(iDet != 1) {
2551       fLoader[iDet]->LoadRecPoints("read");
2552       TTree* tree = fLoader[iDet]->TreeR();
2553       if (!tree) {
2554         AliError(Form("Can't get the %s cluster tree", detName.Data()));
2555         return kFALSE;
2556       }
2557       tracker->LoadClusters(tree);
2558     }
2559     if (tracker->Clusters2Tracks(esd) != 0) {
2560       AliError(Form("HLT %s Clusters2Tracks failed", fgkDetectorName[iDet]));
2561       return kFALSE;
2562     }
2563     if(iDet != 1) {
2564       tracker->UnloadClusters();
2565     }
2566     delete tracker;
2567   }
2568
2569   return kTRUE;
2570 }
2571
2572 //_____________________________________________________________________________
2573 Bool_t AliReconstruction::RunMuonTracking(AliESDEvent*& esd)
2574 {
2575 // run the muon spectrometer tracking
2576
2577   AliCodeTimerAuto("",0)
2578
2579   if (!fRunLoader) {
2580     AliError("Missing runLoader!");
2581     return kFALSE;
2582   }
2583   Int_t iDet = 7; // for MUON
2584
2585   AliInfo("is running...");
2586
2587   // Get a pointer to the MUON reconstructor
2588   AliReconstructor *reconstructor = GetReconstructor(iDet);
2589   if (!reconstructor) return kFALSE;
2590
2591   
2592   TString detName = fgkDetectorName[iDet];
2593   AliDebug(1, Form("%s tracking", detName.Data()));
2594   AliTracker *tracker =  reconstructor->CreateTracker();
2595   if (!tracker) {
2596     AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
2597     return kFALSE;
2598   }
2599      
2600   // read RecPoints
2601   fLoader[iDet]->LoadRecPoints("read");  
2602
2603   tracker->LoadClusters(fLoader[iDet]->TreeR());
2604   
2605   Int_t rv = tracker->Clusters2Tracks(esd);
2606   
2607   fLoader[iDet]->UnloadRecPoints();
2608
2609   tracker->UnloadClusters();
2610   
2611   delete tracker;
2612   
2613   if ( rv )
2614   {
2615     AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
2616     return kFALSE;
2617   }
2618   
2619   return kTRUE;
2620 }
2621
2622
2623 //_____________________________________________________________________________
2624 Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd,AliESDpid &PID)
2625 {
2626 // run the barrel tracking
2627   static Int_t eventNr=0;
2628   AliCodeTimerAuto("",0)
2629
2630   AliInfo("running tracking");
2631
2632   // Set the event info which is used
2633   // by the trackers in order to obtain
2634   // information about read-out detectors,
2635   // trigger etc.
2636   AliDebug(1, "Setting event info");
2637   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2638     if (!fTracker[iDet]) continue;
2639     fTracker[iDet]->SetEventInfo(&fEventInfo);
2640   }
2641
2642   //Fill the ESD with the T0 info (will be used by the TOF) 
2643   if (fReconstructor[11] && fLoader[11]) {
2644     fLoader[11]->LoadRecPoints("READ");
2645     TTree *treeR = fLoader[11]->TreeR();
2646     if (treeR) {
2647       GetReconstructor(11)->FillESD((TTree *)NULL,treeR,esd);
2648     }
2649   }
2650
2651   // pass 1: TPC + ITS inwards
2652   for (Int_t iDet = 1; iDet >= 0; iDet--) {
2653     if (!fTracker[iDet]) continue;
2654     AliDebug(1, Form("%s tracking", fgkDetectorName[iDet]));
2655
2656     // load clusters
2657     fLoader[iDet]->LoadRecPoints("read");
2658     AliSysInfo::AddStamp(Form("RLoadCluster%s_%d",fgkDetectorName[iDet],eventNr),iDet,1, eventNr);
2659     TTree* tree = fLoader[iDet]->TreeR();
2660     if (!tree) {
2661       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
2662       return kFALSE;
2663     }
2664     fTracker[iDet]->LoadClusters(tree);
2665     AliSysInfo::AddStamp(Form("TLoadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
2666     // run tracking
2667     if (fTracker[iDet]->Clusters2Tracks(esd) != 0) {
2668       AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
2669       return kFALSE;
2670     }
2671     // preliminary PID in TPC needed by the ITS tracker
2672     if (iDet == 1) {
2673       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
2674       PID.MakePID(esd,kTRUE);
2675     } 
2676     AliSysInfo::AddStamp(Form("Tracking0%s_%d",fgkDetectorName[iDet],eventNr), iDet,3,eventNr);
2677   }
2678
2679   // pass 2: ALL backwards
2680
2681   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2682     if (!fTracker[iDet]) continue;
2683     AliDebug(1, Form("%s back propagation", fgkDetectorName[iDet]));
2684
2685     // load clusters
2686     if (iDet > 1) {     // all except ITS, TPC
2687       TTree* tree = NULL;
2688       fLoader[iDet]->LoadRecPoints("read");
2689       AliSysInfo::AddStamp(Form("RLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,1, eventNr);
2690       tree = fLoader[iDet]->TreeR();
2691       if (!tree) {
2692         AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
2693         return kFALSE;
2694       }
2695       fTracker[iDet]->LoadClusters(tree); 
2696       AliSysInfo::AddStamp(Form("TLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
2697     }
2698
2699     // run tracking
2700     if (iDet>1) // start filling residuals for the "outer" detectors
2701       if (fRunGlobalQA) {
2702         AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
2703         TObjArray ** arr = AliTracker::GetResidualsArray() ; 
2704         if (arr) {
2705           AliRecoParam::EventSpecie_t es=fRecoParam.GetEventSpecie();
2706           TObjArray * elem = arr[AliRecoParam::AConvert(es)];
2707           if ( elem && (! elem->At(0)) ) {
2708             AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
2709             if (qadm) qadm->InitRecPointsForTracker() ; 
2710           }
2711         }
2712       }
2713     if (fTracker[iDet]->PropagateBack(esd) != 0) {
2714       AliError(Form("%s backward propagation failed", fgkDetectorName[iDet]));
2715       //      return kFALSE;
2716     }
2717
2718     // unload clusters
2719     if (iDet > 3) {     // all except ITS, TPC, TRD and TOF
2720       fTracker[iDet]->UnloadClusters();
2721       fLoader[iDet]->UnloadRecPoints();
2722     }
2723     // updated PID in TPC needed by the ITS tracker -MI
2724     if (iDet == 1) {
2725       //GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
2726       //AliESDpid::MakePID(esd);
2727       PID.MakePID(esd,kTRUE);
2728     }
2729     AliSysInfo::AddStamp(Form("Tracking1%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
2730   }
2731   //stop filling residuals for the "outer" detectors
2732   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
2733
2734   // pass 3: TRD + TPC + ITS refit inwards
2735
2736   for (Int_t iDet = 2; iDet >= 0; iDet--) {
2737     if (!fTracker[iDet]) continue;
2738     AliDebug(1, Form("%s inward refit", fgkDetectorName[iDet]));
2739
2740     // run tracking
2741     if (iDet<2) // start filling residuals for TPC and ITS
2742       if (fRunGlobalQA) {
2743         AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
2744         TObjArray ** arr = AliTracker::GetResidualsArray() ; 
2745         if (arr) {
2746           AliRecoParam::EventSpecie_t es=fRecoParam.GetEventSpecie();
2747           TObjArray * elem = arr[AliRecoParam::AConvert(es)];
2748           if ( elem && (! elem->At(0)) ) {
2749             AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
2750             if (qadm) qadm->InitRecPointsForTracker() ; 
2751           }
2752         }
2753       }
2754     
2755     if (fTracker[iDet]->RefitInward(esd) != 0) {
2756       AliError(Form("%s inward refit failed", fgkDetectorName[iDet]));
2757       //      return kFALSE;
2758     }
2759     // run postprocessing
2760     if (fTracker[iDet]->PostProcess(esd) != 0) {
2761       AliError(Form("%s postprocessing failed", fgkDetectorName[iDet]));
2762       //      return kFALSE;
2763     }
2764     AliSysInfo::AddStamp(Form("Tracking2%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
2765   }
2766
2767   // write space-points to the ESD in case alignment data output
2768   // is switched on
2769   if (fWriteAlignmentData)
2770     WriteAlignmentData(esd);
2771
2772   for (Int_t iDet = 3; iDet >= 0; iDet--) {
2773     if (!fTracker[iDet]) continue;
2774     // unload clusters
2775     fTracker[iDet]->UnloadClusters();
2776     AliSysInfo::AddStamp(Form("TUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,4, eventNr);
2777     fLoader[iDet]->UnloadRecPoints();
2778     AliSysInfo::AddStamp(Form("RUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,5, eventNr);
2779   }
2780   // stop filling residuals for TPC and ITS
2781   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
2782
2783   eventNr++;
2784   return kTRUE;
2785 }
2786
2787 //_____________________________________________________________________________
2788 Bool_t AliReconstruction::CleanESD(AliESDEvent *esd){
2789   //
2790   // Remove the data which are not needed for the physics analysis.
2791   //
2792
2793   Int_t nTracks=esd->GetNumberOfTracks();
2794   Int_t nV0s=esd->GetNumberOfV0s();
2795   AliInfo
2796   (Form("Number of ESD tracks and V0s before cleaning: %d %d",nTracks,nV0s));
2797
2798   Float_t cleanPars[]={fV0DCAmax,fV0CsPmin,fDmax,fZmax};
2799   Bool_t rc=esd->Clean(cleanPars);
2800
2801   nTracks=esd->GetNumberOfTracks();
2802   nV0s=esd->GetNumberOfV0s();
2803   AliInfo
2804   (Form("Number of ESD tracks and V0s after cleaning %d %d",nTracks,nV0s));
2805
2806   return rc;
2807 }
2808
2809 //_____________________________________________________________________________
2810 Bool_t AliReconstruction::FillESD(AliESDEvent*& esd, const TString& detectors)
2811 {
2812 // fill the event summary data
2813
2814   AliCodeTimerAuto("",0)
2815     static Int_t eventNr=0; 
2816   TString detStr = detectors;
2817   
2818   AliSysInfo::AddStamp(Form("FillESDb%d",eventNr), -19,-19, eventNr);
2819   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2820   if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2821     AliReconstructor* reconstructor = GetReconstructor(iDet);
2822     if (!reconstructor) continue;
2823     AliDebug(1, Form("filling ESD for %s", fgkDetectorName[iDet]));
2824     TTree* clustersTree = NULL;
2825     if (fLoader[iDet]) {
2826       fLoader[iDet]->LoadRecPoints("read");
2827       clustersTree = fLoader[iDet]->TreeR();
2828       if (!clustersTree) {
2829         AliError(Form("Can't get the %s clusters tree", 
2830                       fgkDetectorName[iDet]));
2831         if (fStopOnError) return kFALSE;
2832       }
2833     }
2834     if (fRawReader && !reconstructor->HasDigitConversion()) {
2835       reconstructor->FillESD(fRawReader, clustersTree, esd);
2836     } else {
2837       TTree* digitsTree = NULL;
2838       if (fLoader[iDet]) {
2839         fLoader[iDet]->LoadDigits("read");
2840         digitsTree = fLoader[iDet]->TreeD();
2841         if (!digitsTree) {
2842           AliError(Form("Can't get the %s digits tree", 
2843                         fgkDetectorName[iDet]));
2844           if (fStopOnError) return kFALSE;
2845         }
2846       }
2847       reconstructor->FillESD(digitsTree, clustersTree, esd);
2848       if (fLoader[iDet]) fLoader[iDet]->UnloadDigits();
2849     }
2850     if (fLoader[iDet]) {
2851       fLoader[iDet]->UnloadRecPoints();
2852     }
2853   }
2854   
2855   if (!IsSelected("CTP", detStr)) AliDebug(10,"No CTP");
2856   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2857     AliError(Form("the following detectors were not found: %s", 
2858                   detStr.Data()));
2859     if (fStopOnError) return kFALSE;
2860   }
2861   AliSysInfo::AddStamp(Form("FillESDe%d",eventNr), -20,-20, eventNr);
2862   eventNr++;
2863   return kTRUE;
2864 }
2865
2866 //_____________________________________________________________________________
2867 Bool_t AliReconstruction::FillTriggerESD(AliESDEvent*& esd)
2868 {
2869   // Reads the trigger decision which is
2870   // stored in Trigger.root file and fills
2871   // the corresponding esd entries
2872
2873   AliCodeTimerAuto("",0)
2874   
2875   AliInfo("Filling trigger information into the ESD");
2876
2877   if (fRawReader) {
2878     AliCTPRawStream input(fRawReader);
2879     if (!input.Next()) {
2880       AliWarning("No valid CTP (trigger) DDL raw data is found ! The trigger info is taken from the event header!");
2881     }
2882     else {
2883       if (esd->GetTriggerMask() != input.GetClassMask())
2884         AliError(Form("Invalid trigger pattern found in CTP raw-data: %llx %llx",
2885                       input.GetClassMask(),esd->GetTriggerMask()));
2886       if (esd->GetOrbitNumber() != input.GetOrbitID())
2887         AliError(Form("Invalid orbit id found in CTP raw-data: %x %x",
2888                       input.GetOrbitID(),esd->GetOrbitNumber()));
2889       if (esd->GetBunchCrossNumber() != input.GetBCID())
2890         AliError(Form("Invalid bunch-crossing id found in CTP raw-data: %x %x",
2891                       input.GetBCID(),esd->GetBunchCrossNumber()));
2892       AliESDHeader* esdheader = esd->GetHeader();
2893       esdheader->SetL0TriggerInputs(input.GetL0Inputs());
2894       esdheader->SetL1TriggerInputs(input.GetL1Inputs());
2895       esdheader->SetL2TriggerInputs(input.GetL2Inputs());
2896       // IR
2897       UInt_t orbit=input.GetOrbitID();
2898        for(Int_t i=0 ; i<input.GetNIRs() ; i++ )
2899           if(TMath::Abs(Int_t(orbit-(input.GetIR(i))->GetOrbit()))<=1){
2900              esdheader->AddTriggerIR(input.GetIR(i));
2901           }
2902     }
2903   }
2904   return kTRUE;
2905 }
2906 //_____________________________________________________________________________
2907 Bool_t AliReconstruction::FillTriggerScalers(AliESDEvent*& esd)
2908 {
2909   //Scalers
2910   //fRunScalers->Print();
2911   if(fRunScalers && fRunScalers->CheckRunScalers()){
2912      AliTimeStamp* timestamp = new AliTimeStamp(esd->GetOrbitNumber(), esd->GetPeriodNumber(), esd->GetBunchCrossNumber());
2913      //AliTimeStamp* timestamp = new AliTimeStamp(10308000, 0, (ULong64_t)486238);
2914      AliESDHeader* esdheader = fesd->GetHeader();
2915      for(Int_t i=0;i<50;i++){
2916           if((1ull<<i) & esd->GetTriggerMask()){
2917           AliTriggerScalersESD* scalesd = fRunScalers->GetScalersForEventClass( timestamp, i+1);
2918           if(scalesd)esdheader->SetTriggerScalersRecord(scalesd);
2919         }
2920      }
2921   }
2922   return kTRUE;
2923 }
2924 //_____________________________________________________________________________
2925 Bool_t AliReconstruction::FillRawEventHeaderESD(AliESDEvent*& esd)
2926 {
2927   // 
2928   // Filling information from RawReader Header
2929   // 
2930
2931   if (!fRawReader) return kFALSE;
2932
2933   AliInfo("Filling information from RawReader Header");
2934
2935   esd->SetBunchCrossNumber(fRawReader->GetBCID());
2936   esd->SetOrbitNumber(fRawReader->GetOrbitID());
2937   esd->SetPeriodNumber(fRawReader->GetPeriod());
2938
2939   esd->SetTimeStamp(fRawReader->GetTimestamp());  
2940   esd->SetEventType(fRawReader->GetType());
2941
2942   return kTRUE;
2943 }
2944
2945
2946 //_____________________________________________________________________________
2947 Bool_t AliReconstruction::IsSelected(TString detName, TString& detectors) const
2948 {
2949 // check whether detName is contained in detectors
2950 // if yes, it is removed from detectors
2951
2952   // check if all detectors are selected
2953   if ((detectors.CompareTo("ALL") == 0) ||
2954       detectors.BeginsWith("ALL ") ||
2955       detectors.EndsWith(" ALL") ||
2956       detectors.Contains(" ALL ")) {
2957     detectors = "ALL";
2958     return kTRUE;
2959   }
2960
2961   // search for the given detector
2962   Bool_t result = kFALSE;
2963   if ((detectors.CompareTo(detName) == 0) ||
2964       detectors.BeginsWith(detName+" ") ||
2965       detectors.EndsWith(" "+detName) ||
2966       detectors.Contains(" "+detName+" ")) {
2967     detectors.ReplaceAll(detName, "");
2968     result = kTRUE;
2969   }
2970
2971   // clean up the detectors string
2972   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
2973   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
2974   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
2975
2976   return result;
2977 }
2978
2979 //_____________________________________________________________________________
2980 Bool_t AliReconstruction::InitRunLoader()
2981 {
2982 // get or create the run loader
2983
2984   if (gAlice) delete gAlice;
2985   gAlice = NULL;
2986
2987   TFile *gafile = TFile::Open(fGAliceFileName.Data());
2988   //  if (!gSystem->AccessPathName(fGAliceFileName.Data())) { // galice.root exists
2989   if (gafile) { // galice.root exists
2990     gafile->Close();
2991     delete gafile;
2992
2993     // load all base libraries to get the loader classes
2994     TString libs = gSystem->GetLibraries();
2995     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2996       TString detName = fgkDetectorName[iDet];
2997       if (detName == "HLT") continue;
2998       if (libs.Contains("lib" + detName + "base.so")) continue;
2999       gSystem->Load("lib" + detName + "base.so");
3000     }
3001     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data());
3002     if (!fRunLoader) {
3003       AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
3004       CleanUp();
3005       return kFALSE;
3006     }
3007
3008     fRunLoader->CdGAFile();
3009     fRunLoader->LoadgAlice();
3010
3011     //PH This is a temporary fix to give access to the kinematics
3012     //PH that is needed for the labels of ITS clusters
3013     fRunLoader->LoadHeader();
3014     fRunLoader->LoadKinematics();
3015
3016   } else {               // galice.root does not exist
3017     if (!fRawReader) {
3018       AliError(Form("the file %s does not exist", fGAliceFileName.Data()));
3019     }
3020     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data(),
3021                                     AliConfig::GetDefaultEventFolderName(),
3022                                     "recreate");
3023     if (!fRunLoader) {
3024       AliError(Form("could not create run loader in file %s", 
3025                     fGAliceFileName.Data()));
3026       CleanUp();
3027       return kFALSE;
3028     }
3029     fIsNewRunLoader = kTRUE;
3030     fRunLoader->MakeTree("E");
3031
3032     if (fNumberOfEventsPerFile > 0)
3033       fRunLoader->SetNumberOfEventsPerFile(fNumberOfEventsPerFile);
3034     else
3035       fRunLoader->SetNumberOfEventsPerFile((UInt_t)-1);
3036   }
3037
3038   return kTRUE;
3039 }
3040
3041 //_____________________________________________________________________________
3042 AliReconstructor* AliReconstruction::GetReconstructor(Int_t iDet)
3043 {
3044 // get the reconstructor object and the loader for a detector
3045
3046   if (fReconstructor[iDet]) {
3047     if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
3048       const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
3049       fReconstructor[iDet]->SetRecoParam(par);
3050       fReconstructor[iDet]->SetRunInfo(fRunInfo);
3051     }
3052     return fReconstructor[iDet];
3053   }
3054
3055   // load the reconstructor object
3056   TPluginManager* pluginManager = gROOT->GetPluginManager();
3057   TString detName = fgkDetectorName[iDet];
3058   TString recName = "Ali" + detName + "Reconstructor";
3059
3060   if (!fIsNewRunLoader && !fRunLoader->GetLoader(detName+"Loader") && (detName != "HLT")) return NULL;
3061
3062   AliReconstructor* reconstructor = NULL;
3063   // first check if a plugin is defined for the reconstructor
3064   TPluginHandler* pluginHandler = 
3065     pluginManager->FindHandler("AliReconstructor", detName);
3066   // if not, add a plugin for it
3067   if (!pluginHandler) {
3068     AliDebug(1, Form("defining plugin for %s", recName.Data()));
3069     TString libs = gSystem->GetLibraries();
3070     if (libs.Contains("lib" + detName + "base.so") ||
3071         (gSystem->Load("lib" + detName + "base.so") >= 0)) {
3072       pluginManager->AddHandler("AliReconstructor", detName, 
3073                                 recName, detName + "rec", recName + "()");
3074     } else {
3075       pluginManager->AddHandler("AliReconstructor", detName, 
3076                                 recName, detName, recName + "()");
3077     }
3078     pluginHandler = pluginManager->FindHandler("AliReconstructor", detName);
3079   }
3080   if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
3081     reconstructor = (AliReconstructor*) pluginHandler->ExecPlugin(0);
3082   }
3083   if (reconstructor) {
3084     TObject* obj = fOptions.FindObject(detName.Data());
3085     if (obj) reconstructor->SetOption(obj->GetTitle());
3086     reconstructor->SetRunInfo(fRunInfo);
3087     reconstructor->Init();
3088     fReconstructor[iDet] = reconstructor;
3089   }
3090
3091   // get or create the loader
3092   if (detName != "HLT") {
3093     fLoader[iDet] = fRunLoader->GetLoader(detName + "Loader");
3094     if (!fLoader[iDet]) {
3095       AliConfig::Instance()
3096         ->CreateDetectorFolders(fRunLoader->GetEventFolder(), 
3097                                 detName, detName);
3098       // first check if a plugin is defined for the loader
3099       pluginHandler = 
3100         pluginManager->FindHandler("AliLoader", detName);
3101       // if not, add a plugin for it
3102       if (!pluginHandler) {
3103         TString loaderName = "Ali" + detName + "Loader";
3104         AliDebug(1, Form("defining plugin for %s", loaderName.Data()));
3105         pluginManager->AddHandler("AliLoader", detName, 
3106                                   loaderName, detName + "base", 
3107                                   loaderName + "(const char*, TFolder*)");
3108         pluginHandler = pluginManager->FindHandler("AliLoader", detName);
3109       }
3110       if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
3111         fLoader[iDet] = 
3112           (AliLoader*) pluginHandler->ExecPlugin(2, detName.Data(), 
3113                                                  fRunLoader->GetEventFolder());
3114       }
3115       if (!fLoader[iDet]) {   // use default loader
3116         fLoader[iDet] = new AliLoader(detName, fRunLoader->GetEventFolder());
3117       }
3118       if (!fLoader[iDet]) {
3119         AliWarning(Form("couldn't get loader for %s", detName.Data()));
3120         if (fStopOnError) return NULL;
3121       } else {
3122         fRunLoader->AddLoader(fLoader[iDet]);
3123         fRunLoader->CdGAFile();
3124         if (gFile && !gFile->IsWritable()) gFile->ReOpen("UPDATE");
3125         fRunLoader->Write(0, TObject::kOverwrite);
3126       }
3127     }
3128   }
3129       
3130   if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
3131     const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
3132     if (reconstructor) {
3133       reconstructor->SetRecoParam(par);
3134       reconstructor->SetRunInfo(fRunInfo);
3135     }
3136   }
3137   return reconstructor;
3138 }
3139
3140 //_____________________________________________________________________________
3141 AliVertexer* AliReconstruction::CreateVertexer()
3142 {
3143 // create the vertexer
3144 // Please note that the caller is the owner of the
3145 // vertexer
3146
3147   AliVertexer* vertexer = NULL;
3148   AliReconstructor* itsReconstructor = GetReconstructor(0);
3149   if (itsReconstructor && ((fRunLocalReconstruction.Contains("ITS")) || 
3150                            fRunTracking.Contains("ITS") || fFillESD.Contains("ITS") )) {
3151     vertexer = itsReconstructor->CreateVertexer();
3152   }
3153   if (!vertexer) {
3154     AliWarning("couldn't create a vertexer for ITS");
3155   }
3156
3157   return vertexer;
3158 }
3159
3160 //_____________________________________________________________________________
3161 AliTrackleter* AliReconstruction::CreateMultFinder()
3162 {
3163 // create the ITS trackleter for mult. estimation
3164 // Please note that the caller is the owner of the
3165 // trackleter
3166
3167   AliTrackleter* trackleter = NULL;
3168   AliReconstructor* itsReconstructor = GetReconstructor(0);
3169   if (itsReconstructor && ((fRunLocalReconstruction.Contains("ITS")) || 
3170                            fRunTracking.Contains("ITS") || fFillESD.Contains("ITS") )) {
3171     trackleter = itsReconstructor->CreateMultFinder();
3172   }
3173   else {
3174     AliWarning("ITS is not in reconstruction, switching off RunMultFinder");
3175     fRunMultFinder = kFALSE;
3176   }
3177
3178   return trackleter;
3179 }
3180
3181 //_____________________________________________________________________________
3182 Bool_t AliReconstruction::CreateTrackers(const TString& detectors)
3183 {
3184 // create the trackers
3185         AliInfo("Creating trackers");
3186
3187   TString detStr = detectors;
3188   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3189     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3190     AliReconstructor* reconstructor = GetReconstructor(iDet);
3191     if (!reconstructor) continue;
3192     TString detName = fgkDetectorName[iDet];
3193     if (detName == "HLT") {
3194       fRunHLTTracking = kTRUE;
3195       continue;
3196     }
3197     if (detName == "MUON") {
3198       fRunMuonTracking = kTRUE;
3199       continue;
3200     }
3201
3202     fTracker[iDet] = reconstructor->CreateTracker();
3203     if (!fTracker[iDet] && (iDet < 7)) {
3204       AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
3205       if (fStopOnError) return kFALSE;
3206     }
3207     AliSysInfo::AddStamp(Form("LTracker%s",fgkDetectorName[iDet]), iDet,0);
3208   }
3209
3210   return kTRUE;
3211 }
3212
3213 //_____________________________________________________________________________
3214 void AliReconstruction::CleanUp()
3215 {
3216 // delete trackers and the run loader and close and delete the file
3217
3218   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3219     delete fReconstructor[iDet];
3220     fReconstructor[iDet] = NULL;
3221     fLoader[iDet] = NULL;
3222     delete fTracker[iDet];
3223     fTracker[iDet] = NULL;
3224   }
3225   delete fRunInfo;
3226   fRunInfo = NULL;
3227
3228   delete fSPDTrackleter;
3229   fSPDTrackleter = NULL;
3230
3231   delete ftVertexer;
3232   ftVertexer = NULL;
3233   
3234   delete fRunLoader;
3235   fRunLoader = NULL;
3236   delete fRawReader;
3237   fRawReader = NULL;
3238   delete fParentRawReader;
3239   fParentRawReader=NULL;
3240
3241   if (ffile) {
3242     ffile->Close();
3243     delete ffile;
3244     ffile = NULL;
3245   }
3246
3247   if (AliQAManager::QAManager())
3248     AliQAManager::QAManager()->ShowQA() ; 
3249   AliQAManager::Destroy() ; 
3250   
3251 }
3252
3253 void AliReconstruction::WriteAlignmentData(AliESDEvent* esd)
3254 {
3255   // Write space-points which are then used in the alignment procedures
3256   // For the moment only ITS, TPC, TRD and TOF
3257
3258   Int_t ntracks = esd->GetNumberOfTracks();
3259   for (Int_t itrack = 0; itrack < ntracks; itrack++)
3260     {
3261       AliESDtrack *track = esd->GetTrack(itrack);
3262       Int_t nsp = 0;
3263       Int_t idx[200];
3264       for (Int_t i=0; i<200; ++i) idx[i] = -1; //PH avoid uninitialized values
3265       for (Int_t iDet = 5; iDet >= 0; iDet--) {// TOF, TRD, TPC, ITS clusters
3266           nsp += (iDet==GetDetIndex("TRD")) ? track->GetTRDntracklets():track->GetNcls(iDet);
3267
3268           if (iDet==GetDetIndex("ITS")) { // ITS "extra" clusters
3269              track->GetClusters(iDet,idx);
3270              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nsp++;
3271           }  
3272       }
3273
3274       if (nsp) {
3275         AliTrackPointArray *sp = new AliTrackPointArray(nsp);
3276         track->SetTrackPointArray(sp);
3277         Int_t isptrack = 0;
3278         for (Int_t iDet = 5; iDet >= 0; iDet--) {
3279           AliTracker *tracker = fTracker[iDet];
3280           if (!tracker) continue;
3281           Int_t nspdet = (iDet==GetDetIndex("TRD")) ? track->GetTRDtracklets(idx):track->GetClusters(iDet,idx);
3282
3283           if (iDet==GetDetIndex("ITS")) // ITS "extra" clusters             
3284              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nspdet++;
3285
3286           if (nspdet <= 0) continue;
3287           AliTrackPoint p;
3288           Int_t isp = 0;
3289           Int_t isp2 = 0;
3290           while (isp2 < nspdet) {
3291             Bool_t isvalid=kTRUE;
3292
3293             Int_t index=idx[isp++];
3294             if (index < 0) continue;
3295
3296             TString dets = fgkDetectorName[iDet];
3297             if ((fUseTrackingErrorsForAlignment.CompareTo(dets) == 0) ||
3298             fUseTrackingErrorsForAlignment.BeginsWith(dets+" ") ||
3299             fUseTrackingErrorsForAlignment.EndsWith(" "+dets) ||
3300             fUseTrackingErrorsForAlignment.Contains(" "+dets+" ")) {
3301               isvalid = tracker->GetTrackPointTrackingError(index,p,track);
3302             } else {
3303               isvalid = tracker->GetTrackPoint(index,p); 
3304             } 
3305             isp2++;
3306             if (!isvalid) continue;
3307             if (iDet==GetDetIndex("ITS") && (isp-1)>=6) p.SetExtra();
3308             sp->AddPoint(isptrack,&p); isptrack++;
3309           }
3310         }       
3311       }
3312     }
3313 }
3314
3315 //_____________________________________________________________________________
3316 void AliReconstruction::FillRawDataErrorLog(Int_t iEvent, AliESDEvent* esd)
3317 {
3318   // The method reads the raw-data error log
3319   // accumulated within the rawReader.
3320   // It extracts the raw-data errors related to
3321   // the current event and stores them into
3322   // a TClonesArray inside the esd object.
3323
3324   if (!fRawReader) return;
3325
3326   for(Int_t i = 0; i < fRawReader->GetNumberOfErrorLogs(); i++) {
3327
3328     AliRawDataErrorLog *log = fRawReader->GetErrorLog(i);
3329     if (!log) continue;
3330     if (iEvent != log->GetEventNumber()) continue;
3331
3332     esd->AddRawDataErrorLog(log);
3333   }
3334
3335 }
3336
3337 //_____________________________________________________________________________
3338 // void AliReconstruction::CheckQA()
3339 // {
3340 // check the QA of SIM for this run and remove the detectors 
3341 // with status Fatal
3342   
3343 //      TString newRunLocalReconstruction ; 
3344 //      TString newRunTracking ;
3345 //      TString newFillESD ;
3346 //       
3347 //      for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
3348 //              TString detName(AliQAv1::GetDetName(iDet)) ;
3349 //              AliQAv1 * qa = AliQAv1::Instance(AliQAv1::DETECTORINDEX_t(iDet)) ;       
3350 //      if ( qa->IsSet(AliQAv1::DETECTORINDEX_t(iDet), AliQAv1::kSIM, specie, AliQAv1::kFATAL)) {
3351 //        AliInfo(Form("QA status for %s %s in Hits and/or SDIGITS  and/or Digits was Fatal; No reconstruction performed", 
3352 //                   detName.Data(), AliRecoParam::GetEventSpecieName(es))) ;
3353 //                      } else {
3354 //                      if ( fRunLocalReconstruction.Contains(AliQAv1::GetDetName(iDet)) || 
3355 //                                      fRunLocalReconstruction.Contains("ALL") )  {
3356 //                              newRunLocalReconstruction += detName ; 
3357 //                              newRunLocalReconstruction += " " ;                      
3358 //                      }
3359 //                      if ( fRunTracking.Contains(AliQAv1::GetDetName(iDet)) || 
3360 //                                      fRunTracking.Contains("ALL") )  {
3361 //                              newRunTracking += detName ; 
3362 //                              newRunTracking += " " ;                         
3363 //                      }
3364 //                      if ( fFillESD.Contains(AliQAv1::GetDetName(iDet)) || 
3365 //                                      fFillESD.Contains("ALL") )  {
3366 //                              newFillESD += detName ; 
3367 //                              newFillESD += " " ;                     
3368 //                      }
3369 //              }
3370 //      }
3371 //      fRunLocalReconstruction = newRunLocalReconstruction ; 
3372 //      fRunTracking            = newRunTracking ; 
3373 //      fFillESD                = newFillESD ; 
3374 // }
3375
3376 //_____________________________________________________________________________
3377 Int_t AliReconstruction::GetDetIndex(const char* detector)
3378 {
3379   // return the detector index corresponding to detector
3380   Int_t index = -1 ; 
3381   for (index = 0; index < kNDetectors ; index++) {
3382     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
3383         break ; 
3384   }     
3385   return index ; 
3386 }
3387 //_____________________________________________________________________________
3388 Bool_t AliReconstruction::FinishPlaneEff() {
3389  //
3390  // Here execute all the necessary operationis, at the end of the tracking phase,
3391  // in case that evaluation of PlaneEfficiencies was required for some detector.
3392  // E.g., write into a DataBase file the PlaneEfficiency which have been evaluated.
3393  //
3394  // This Preliminary version works only FOR ITS !!!!!
3395  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3396  //
3397  //  Input: none
3398  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3399  //
3400  Bool_t ret=kFALSE;
3401  TString detStr = fLoadCDB;
3402  //for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
3403  for (Int_t iDet = 0; iDet < 1; iDet++) { // for the time being only ITS
3404    if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3405    if(fTracker[iDet] && fTracker[iDet]->GetPlaneEff()) {
3406       AliPlaneEff *planeeff=fTracker[iDet]->GetPlaneEff();
3407       TString name=planeeff->GetName();
3408       name+=".root";
3409       TFile* pefile = TFile::Open(name, "RECREATE");
3410       ret=(Bool_t)planeeff->Write();
3411       pefile->Close();
3412       if(planeeff->GetCreateHistos()) {
3413         TString hname=planeeff->GetName();
3414         hname+="Histo.root";
3415         ret*=planeeff->WriteHistosToFile(hname,"RECREATE");
3416       }
3417    }
3418    if(fSPDTrackleter) {
3419      AliPlaneEff *planeeff=fSPDTrackleter->GetPlaneEff();
3420       TString name="AliITSPlaneEffSPDtracklet.root";
3421       TFile* pefile = TFile::Open(name, "RECREATE");
3422       ret=(Bool_t)planeeff->Write();
3423       pefile->Close();
3424       AliESDEvent *dummy=NULL;
3425       ret=(Bool_t)fSPDTrackleter->PostProcess(dummy); // take care of writing other files
3426    }
3427  }
3428  return ret;
3429 }
3430 //_____________________________________________________________________________
3431 Bool_t AliReconstruction::InitPlaneEff() {
3432 //
3433  // Here execute all the necessary operations, before of the tracking phase,
3434  // for the evaluation of PlaneEfficiencies, in case required for some detectors.
3435  // E.g., read from a DataBase file a first evaluation of the PlaneEfficiency
3436  // which should be updated/recalculated.
3437  //
3438  // This Preliminary version will work only FOR ITS !!!!!
3439  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3440  //
3441  //  Input: none
3442  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3443  //
3444
3445   fSPDTrackleter = NULL;
3446   TString detStr = fLoadCDB;
3447   if (IsSelected(fgkDetectorName[0], detStr)) {
3448     AliReconstructor* itsReconstructor = GetReconstructor(0);
3449     if (itsReconstructor) {
3450       fSPDTrackleter = itsReconstructor->CreateTrackleter(); // this is NULL unless required in RecoParam
3451     }
3452     if (fSPDTrackleter) {
3453       AliInfo("Trackleter for SPD has been created");
3454     }
3455   }
3456  return kTRUE;
3457 }
3458
3459 //_____________________________________________________________________________
3460 Bool_t AliReconstruction::InitAliEVE()
3461 {
3462   // This method should be called only in case 
3463   // AliReconstruction is run
3464   // within the alieve environment.
3465   // It will initialize AliEVE in a way
3466   // so that it can visualize event processed
3467   // by AliReconstruction.
3468   // The return flag shows whenever the
3469   // AliEVE initialization was successful or not.
3470
3471   TString macroStr(gSystem->Getenv("ALIEVE_ONLINE_MACRO"));
3472
3473   if (macroStr.IsNull())
3474     macroStr.Form("%s/EVE/macros/alieve_online.C",gSystem->ExpandPathName("$ALICE_ROOT"));
3475
3476   AliInfo(Form("Loading AliEVE macro: %s",macroStr.Data()));
3477
3478   if (gROOT->LoadMacro(macroStr.Data()) != 0) return kFALSE;
3479
3480   gROOT->ProcessLine("if (!AliEveEventManager::GetMaster()){new AliEveEventManager();AliEveEventManager::GetMaster()->AddNewEventCommand(\"alieve_online_on_new_event()\");gEve->AddEvent(AliEveEventManager::GetMaster());};");
3481   gROOT->ProcessLine("alieve_online_init()");
3482
3483   return kTRUE;
3484 }
3485   
3486 //_____________________________________________________________________________
3487 void AliReconstruction::RunAliEVE()
3488 {
3489   // Runs AliEVE visualisation of
3490   // the current event.
3491   // Should be executed only after
3492   // successful initialization of AliEVE.
3493
3494   AliInfo("Running AliEVE...");
3495   gROOT->ProcessLine(Form("AliEveEventManager::GetMaster()->SetEvent((AliRunLoader*)%p,(AliRawReader*)%p,(AliESDEvent*)%p,(AliESDfriend*)%p);",fRunLoader,fRawReader,fesd,fesdf));
3496   gSystem->Run();
3497 }
3498
3499 //_____________________________________________________________________________
3500 Bool_t AliReconstruction::SetRunQA(TString detAndAction) 
3501 {
3502         // Allows to run QA for a selected set of detectors
3503         // and a selected set of tasks among RAWS, DIGITSR, RECPOINTS and ESDS
3504         // all selected detectors run the same selected tasks
3505         
3506         if (!detAndAction.Contains(":")) {
3507                 AliError( Form("%s is a wrong syntax, use \"DetectorList:ActionList\" \n", detAndAction.Data()) ) ;
3508                 fRunQA = kFALSE ;
3509                 return kFALSE ;                 
3510         }
3511         Int_t colon = detAndAction.Index(":") ; 
3512         fQADetectors = detAndAction(0, colon) ; 
3513         fQATasks   = detAndAction(colon+1, detAndAction.Sizeof() ) ; 
3514         if (fQATasks.Contains("ALL") ) {
3515                 fQATasks = Form("%d %d %d %d", AliQAv1::kRAWS, AliQAv1::kDIGITSR, AliQAv1::kRECPOINTS, AliQAv1::kESDS) ; 
3516         } else {
3517                 fQATasks.ToUpper() ; 
3518                 TString tempo("") ; 
3519                 if ( fQATasks.Contains("RAW") ) 
3520                         tempo = Form("%d ", AliQAv1::kRAWS) ; 
3521                 if ( fQATasks.Contains("DIGIT") ) 
3522                         tempo += Form("%d ", AliQAv1::kDIGITSR) ; 
3523                 if ( fQATasks.Contains("RECPOINT") ) 
3524                         tempo += Form("%d ", AliQAv1::kRECPOINTS) ; 
3525                 if ( fQATasks.Contains("ESD") ) 
3526                         tempo += Form("%d ", AliQAv1::kESDS) ; 
3527                 fQATasks = tempo ; 
3528                 if (fQATasks.IsNull()) {
3529                         AliInfo("No QA requested\n")  ;
3530                         fRunQA = kFALSE ;
3531                         return kTRUE ; 
3532                 }
3533         }       
3534         TString tempo(fQATasks) ; 
3535         tempo.ReplaceAll(Form("%d", AliQAv1::kRAWS), AliQAv1::GetTaskName(AliQAv1::kRAWS))      ;
3536         tempo.ReplaceAll(Form("%d", AliQAv1::kDIGITSR), AliQAv1::GetTaskName(AliQAv1::kDIGITSR)) ;      
3537         tempo.ReplaceAll(Form("%d", AliQAv1::kRECPOINTS), AliQAv1::GetTaskName(AliQAv1::kRECPOINTS)) ;  
3538         tempo.ReplaceAll(Form("%d", AliQAv1::kESDS), AliQAv1::GetTaskName(AliQAv1::kESDS)) ;    
3539         AliInfo( Form("QA will be done on \"%s\" for \"%s\"\n", fQADetectors.Data(), tempo.Data()) ) ;  
3540         fRunQA = kTRUE ;
3541         return kTRUE; 
3542
3543
3544 //_____________________________________________________________________________
3545 Bool_t AliReconstruction::InitRecoParams() 
3546 {
3547   // The method accesses OCDB and retrieves all
3548   // the available reco-param objects from there.
3549
3550   Bool_t isOK = kTRUE;
3551
3552   if (fRecoParam.GetDetRecoParamArray(kNDetectors)) {
3553     AliInfo("Using custom GRP reconstruction parameters");
3554   }
3555   else {
3556     AliInfo("Loading GRP reconstruction parameter objects");
3557
3558     AliCDBPath path("GRP","Calib","RecoParam");
3559     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
3560     if(!entry){ 
3561       AliWarning("Couldn't find GRP RecoParam entry in OCDB");
3562       isOK = kFALSE;
3563     }
3564     else {
3565       TObject *recoParamObj = entry->GetObject();
3566       if (dynamic_cast<TObjArray*>(recoParamObj)) {
3567         // GRP has a normal TobjArray of AliDetectorRecoParam objects
3568         // Registering them in AliRecoParam
3569         fRecoParam.AddDetRecoParamArray(kNDetectors,dynamic_cast<TObjArray*>(recoParamObj));
3570       }
3571       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
3572         // GRP has only onse set of reco parameters
3573         // Registering it in AliRecoParam
3574         AliInfo("Single set of GRP reconstruction parameters found");
3575         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
3576         fRecoParam.AddDetRecoParam(kNDetectors,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
3577       }
3578       else {
3579         AliError("No valid GRP RecoParam object found in the OCDB");
3580         isOK = kFALSE;
3581       }
3582       entry->SetOwner(0);
3583     }
3584   }
3585
3586   TString detStr = fLoadCDB;
3587   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3588
3589     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3590
3591     if (fRecoParam.GetDetRecoParamArray(iDet)) {
3592       AliInfo(Form("Using custom reconstruction parameters for detector %s",fgkDetectorName[iDet]));
3593       continue;
3594     }
3595
3596     AliInfo(Form("Loading reconstruction parameter objects for detector %s",fgkDetectorName[iDet]));
3597   
3598     AliCDBPath path(fgkDetectorName[iDet],"Calib","RecoParam");
3599     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
3600     if(!entry){ 
3601       AliWarning(Form("Couldn't find RecoParam entry in OCDB for detector %s",fgkDetectorName[iDet]));
3602       isOK = kFALSE;
3603     }
3604     else {
3605       TObject *recoParamObj = entry->GetObject();
3606       if (dynamic_cast<TObjArray*>(recoParamObj)) {
3607         // The detector has a normal TobjArray of AliDetectorRecoParam objects
3608         // Registering them in AliRecoParam
3609         fRecoParam.AddDetRecoParamArray(iDet,dynamic_cast<TObjArray*>(recoParamObj));
3610       }
3611       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
3612         // The detector has only onse set of reco parameters
3613         // Registering it in AliRecoParam
3614         AliInfo(Form("Single set of reconstruction parameters found for detector %s",fgkDetectorName[iDet]));
3615         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
3616         fRecoParam.AddDetRecoParam(iDet,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
3617       }
3618       else {
3619         AliError(Form("No valid RecoParam object found in the OCDB for detector %s",fgkDetectorName[iDet]));
3620         isOK = kFALSE;
3621       }
3622       entry->SetOwner(0);
3623       //      FIX ME: We have to disable the unloading of reco-param CDB
3624       //      entries because QA framework is using them. Has to be fix in
3625       //      a way that the QA takes the objects already constructed in
3626       //      this method.
3627       //      AliCDBManager::Instance()->UnloadFromCache(path.GetPath());
3628     }
3629   }
3630
3631   if (AliDebugLevel() > 0) fRecoParam.Print();
3632
3633   return isOK;
3634 }
3635
3636 //_____________________________________________________________________________
3637 Bool_t AliReconstruction::GetEventInfo() 
3638 {
3639   // Fill the event info object
3640   // ...
3641   AliCodeTimerAuto("",0)
3642
3643   AliCentralTrigger *aCTP = NULL;
3644   if (fRawReader) {
3645     fEventInfo.SetEventType(fRawReader->GetType());
3646
3647     ULong64_t mask = fRawReader->GetClassMask();
3648     fEventInfo.SetTriggerMask(mask);
3649     UInt_t clmask = fRawReader->GetDetectorPattern()[0];
3650     fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(clmask));
3651
3652     aCTP = new AliCentralTrigger();
3653     TString configstr("");
3654     if (!aCTP->LoadConfiguration(configstr)) { // Load CTP config from OCDB
3655       AliError("No trigger configuration found in OCDB! The trigger configuration information will not be used!");
3656       delete aCTP;
3657       return kFALSE;
3658     }
3659     aCTP->SetClassMask(mask);
3660     aCTP->SetClusterMask(clmask);
3661   }
3662   else {
3663     fEventInfo.SetEventType(AliRawEventHeaderBase::kPhysicsEvent);
3664
3665     if (fRunLoader && (!fRunLoader->LoadTrigger())) {
3666       aCTP = fRunLoader->GetTrigger();
3667       fEventInfo.SetTriggerMask(aCTP->GetClassMask());
3668       // get inputs from actp - just get
3669       AliESDHeader* esdheader = fesd->GetHeader();
3670       esdheader->SetL0TriggerInputs(aCTP->GetL0TriggerInputs());
3671       esdheader->SetL1TriggerInputs(aCTP->GetL1TriggerInputs());
3672       esdheader->SetL2TriggerInputs(aCTP->GetL2TriggerInputs());
3673       fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(aCTP->GetClusterMask()));
3674     }
3675     else {
3676       AliWarning("No trigger can be loaded! The trigger information will not be used!");
3677       return kFALSE;
3678     }
3679   }
3680
3681   AliTriggerConfiguration *config = aCTP->GetConfiguration();
3682   if (!config) {
3683     AliError("No trigger configuration has been found! The trigger configuration information will not be used!");
3684     if (fRawReader) delete aCTP;
3685     return kFALSE;
3686   }
3687
3688   UChar_t clustmask = 0;
3689   TString trclasses;
3690   ULong64_t trmask = fEventInfo.GetTriggerMask();
3691   const TObjArray& classesArray = config->GetClasses();
3692   Int_t nclasses = classesArray.GetEntriesFast();
3693   for( Int_t iclass=0; iclass < nclasses; iclass++ ) {
3694     AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At(iclass);
3695     if (trclass && trclass->GetMask()>0) {
3696       Int_t trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
3697       fesd->SetTriggerClass(trclass->GetName(),trindex);
3698       if (fRawReader) fRawReader->LoadTriggerClass(trclass->GetName(),trindex);
3699       if (trmask & (1ull << trindex)) {
3700         trclasses += " ";
3701         trclasses += trclass->GetName();
3702         trclasses += " ";
3703         clustmask |= trclass->GetCluster()->GetClusterMask();
3704       }
3705     }
3706   }
3707   fEventInfo.SetTriggerClasses(trclasses);
3708
3709   // Write names of active trigger inputs in ESD Header
3710   const TObjArray& inputsArray = config->GetInputs(); 
3711   Int_t ninputs = inputsArray.GetEntriesFast();
3712   for( Int_t iinput=0; iinput < ninputs; iinput++ ) {
3713     AliTriggerInput* trginput = (AliTriggerInput*)inputsArray.At(iinput);
3714     if (trginput && trginput->GetMask()>0) {
3715       Int_t inputIndex = (Int_t)TMath::Nint(TMath::Log2(trginput->GetMask()));
3716       AliESDHeader* headeresd = fesd->GetHeader();
3717       Int_t trglevel = (Int_t)trginput->GetLevel();
3718       if (trglevel == 0) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex);
3719       if (trglevel == 1) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex+24);
3720       if (trglevel == 2) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex+48);
3721     }
3722   }
3723
3724   // Set the information in ESD
3725   fesd->SetTriggerMask(trmask);
3726   fesd->SetTriggerCluster(clustmask);
3727
3728   if (!aCTP->CheckTriggeredDetectors()) {
3729     if (fRawReader) delete aCTP;
3730     return kFALSE;
3731   }    
3732
3733   if (fRawReader) delete aCTP;
3734
3735   // We have to fill also the HLT decision here!!
3736   // ...
3737
3738   return kTRUE;
3739 }
3740
3741 const char *AliReconstruction::MatchDetectorList(const char *detectorList, UInt_t detectorMask)
3742 {
3743   // Match the detector list found in the rec.C or the default 'ALL'
3744   // to the list found in the GRP (stored there by the shuttle PP which
3745   // gets the information from ECS)
3746   static TString resultList;
3747   TString detList = detectorList;
3748
3749   resultList = "";
3750
3751   for(Int_t iDet = 0; iDet < (AliDAQ::kNDetectors-1); iDet++) {
3752     if ((detectorMask >> iDet) & 0x1) {
3753       TString det = AliDAQ::OfflineModuleName(iDet);
3754       if ((detList.CompareTo("ALL") == 0) ||
3755           ((detList.BeginsWith("ALL ") ||
3756             detList.EndsWith(" ALL") ||
3757             detList.Contains(" ALL ")) &&
3758            !(detList.BeginsWith("-"+det+" ") ||
3759              detList.EndsWith(" -"+det) ||
3760              detList.Contains(" -"+det+" "))) ||
3761           (detList.CompareTo(det) == 0) ||
3762           detList.BeginsWith(det+" ") ||
3763           detList.EndsWith(" "+det) ||
3764           detList.Contains( " "+det+" " )) {
3765         if (!resultList.EndsWith(det + " ")) {
3766           resultList += det;
3767           resultList += " ";
3768         }
3769       }        
3770     }
3771   }
3772
3773   // HLT
3774   if ((detectorMask >> AliDAQ::kHLTId) & 0x1) {
3775     TString hltDet = AliDAQ::OfflineModuleName(AliDAQ::kNDetectors-1);
3776     if ((detList.CompareTo("ALL") == 0) ||
3777         ((detList.BeginsWith("ALL ") ||
3778           detList.EndsWith(" ALL") ||
3779           detList.Contains(" ALL ")) &&
3780          !(detList.BeginsWith("-"+hltDet+" ") ||
3781            detList.EndsWith(" -"+hltDet) ||
3782            detList.Contains(" -"+hltDet+" "))) ||
3783         (detList.CompareTo(hltDet) == 0) ||
3784         detList.BeginsWith(hltDet+" ") ||
3785         detList.EndsWith(" "+hltDet) ||
3786         detList.Contains( " "+hltDet+" " )) {
3787       resultList += hltDet;
3788     }
3789   }
3790
3791   return resultList.Data();
3792
3793 }
3794
3795 //______________________________________________________________________________
3796 void AliReconstruction::Abort(const char *method, EAbort what)
3797 {
3798   // Abort processing. If what = kAbortProcess, the Process() loop will be
3799   // aborted. If what = kAbortFile, the current file in a chain will be
3800   // aborted and the processing will continue with the next file, if there
3801   // is no next file then Process() will be aborted. Abort() can also  be
3802   // called from Begin(), SlaveBegin(), Init() and Notify(). After abort
3803   // the SlaveTerminate() and Terminate() are always called. The abort flag
3804   // can be checked in these methods using GetAbort().
3805   //
3806   // The method is overwritten in AliReconstruction for better handling of
3807   // reco specific errors 
3808
3809   if (!fStopOnError) return;
3810
3811   CleanUp();
3812
3813   TString whyMess = method;
3814   whyMess += " failed! Aborting...";
3815
3816   AliError(whyMess.Data());
3817
3818   fAbort = what;
3819   TString mess = "Abort";
3820   if (fAbort == kAbortProcess)
3821     mess = "AbortProcess";
3822   else if (fAbort == kAbortFile)
3823     mess = "AbortFile";
3824
3825   Info(mess, whyMess.Data());
3826 }
3827
3828 //______________________________________________________________________________
3829 Bool_t AliReconstruction::ProcessEvent(void* event)
3830 {
3831   // Method that is used in case the event loop
3832   // is steered from outside, for example by AMORE
3833   // 'event' is a pointer to the DATE event in the memory
3834
3835   if (fRawReader) delete fRawReader;
3836   fRawReader = new AliRawReaderDate(event);
3837   fStatus = ProcessEvent(fRunLoader->GetNumberOfEvents());  
3838   delete fRawReader;
3839   fRawReader = NULL;
3840
3841   return fStatus;
3842 }
3843
3844 //______________________________________________________________________________
3845 Bool_t AliReconstruction::ParseOutput()
3846 {
3847   // The method parses the output file
3848   // location string in order to steer
3849   // properly the selector
3850
3851   TPMERegexp re1("(\\w+\\.zip#\\w+\\.root):([,*\\w+\\.root,*]+)@dataset://(\\w++)");
3852   TPMERegexp re2("(\\w+\\.root)?@?dataset://(\\w++)");
3853
3854   if (re1.Match(fESDOutput) == 4) {
3855     // root archive with output files stored and regustered
3856     // in proof dataset
3857     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",re1[1].Data()));
3858     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",re1[3].Data()));
3859     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_DATASET",""));
3860     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_ARCHIVE",re1[2].Data()));
3861     AliInfo(Form("%s files will be stored within %s in dataset %s",
3862                  re1[2].Data(),
3863                  re1[1].Data(),
3864                  re1[3].Data()));
3865   }
3866   else if (re2.Match(fESDOutput) == 3) {
3867     // output file stored and registered
3868     // in proof dataset
3869     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",(re2[1].IsNull()) ? "AliESDs.root" : re2[1].Data()));
3870     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",re2[2].Data()));
3871     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_DATASET",""));
3872     AliInfo(Form("%s will be stored in dataset %s",
3873                  (re2[1].IsNull()) ? "AliESDs.root" : re2[1].Data(),
3874                  re2[2].Data()));
3875   }
3876   else {
3877     if (fESDOutput.IsNull()) {
3878       // Output location not given.
3879       // Assuming xrootd has been already started and
3880       // the output file has to be sent back
3881       // to the client machine
3882       TString esdUrl(Form("root://%s/%s/",
3883                           TUrl(gSystem->HostName()).GetHostFQDN(),
3884                           gSystem->pwd()));
3885       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE","AliESDs.root"));
3886       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",esdUrl.Data()));
3887       AliInfo(Form("AliESDs.root will be stored in %s",
3888                    esdUrl.Data()));
3889     }
3890     else {
3891       // User specified an output location.
3892       // Ones has just to parse it here
3893       TUrl outputUrl(fESDOutput.Data());
3894       TString outputFile(gSystem->BaseName(outputUrl.GetFile()));
3895       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",outputFile.IsNull() ? "AliESDs.root" : outputFile.Data()));
3896       TString outputLocation(outputUrl.GetUrl());
3897       outputLocation.ReplaceAll(outputFile.Data(),"");
3898       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",outputLocation.Data()));
3899       AliInfo(Form("%s will be stored in %s",
3900                    outputFile.IsNull() ? "AliESDs.root" : outputFile.Data(),
3901                    outputLocation.Data()));
3902     }
3903   }
3904
3905   return kTRUE;
3906 }
3907
3908 //______________________________________________________________________________
3909 Bool_t AliReconstruction::IsHighPt() const {
3910   // Selection of events containing "high" pT tracks
3911   // If at least one track is found within 1.5 and 100 GeV (pT)
3912   // that was reconstructed by both ITS and TPC, the event is accepted
3913
3914   // Track cuts
3915
3916   const Double_t pTmin = 1.5;
3917   const Double_t pTmax = 100;
3918   ULong_t mask = 0;
3919   mask |= (AliESDtrack::kITSrefit);
3920   mask |= (AliESDtrack::kTPCrefit);
3921
3922   Bool_t isOK = kFALSE;
3923
3924   if (fesd && fesd->GetEventType()==AliRawEventHeaderBase::kPhysicsEvent) {
3925     // Check if this ia a physics event (code 7)
3926     Int_t ntrk = fesd->GetNumberOfTracks();
3927     for (Int_t itrk=0; itrk<ntrk; ++itrk) {
3928           
3929       AliESDtrack * trk = fesd->GetTrack(itrk);
3930       if (trk 
3931           && trk->Pt() > pTmin 
3932           && trk->Pt() < pTmax
3933           && (trk->GetStatus() & mask) == mask ) {
3934         
3935         isOK = kTRUE;
3936         break;
3937       }
3938     }
3939   }
3940   return isOK;
3941 }
3942
3943 //______________________________________________________________________________
3944 Bool_t AliReconstruction::IsCosmicOrCalibSpecie() const {
3945   // Select cosmic or calibration events
3946
3947   Bool_t isOK = kFALSE;
3948
3949   if (fesd && fesd->GetEventType()==AliRawEventHeaderBase::kPhysicsEvent) {
3950       // Check if this ia a physics event (code 7)
3951       
3952       UInt_t specie = fesd->GetEventSpecie();
3953       if (specie==AliRecoParam::kCosmic || specie==AliRecoParam::kCalib) {
3954         isOK = kTRUE;
3955       }
3956   }
3957   return isOK;
3958 }
3959
3960 //______________________________________________________________________________
3961 void AliReconstruction::WriteESDfriend() {
3962   // Fill the ESD friend in the tree. The required fraction of ESD friends is stored
3963   // in fFractionFriends. We select events where we store the ESD friends according
3964   // to the following algorithm:
3965   // 1. Store all Cosmic or Calibration events within the required fraction
3966   // 2. Sample "high Pt" events within the remaining fraction after step 1.
3967   // 3. Sample randomly events if we still have remaining slot
3968
3969   fNall++;
3970
3971   Bool_t isSelected = kFALSE;
3972
3973   if (IsCosmicOrCalibSpecie()) { // Selection of calib or cosmic events
3974     fNspecie++;
3975     Double_t curentSpecieFraction = ((Double_t)(fNspecie+1))/((Double_t)(fNall+1)); 
3976     // "Bayesian" estimate supposing that without events all the events are of the required type
3977     
3978     Double_t rnd = gRandom->Rndm()*curentSpecieFraction;
3979     if (rnd<fFractionFriends) {
3980       isSelected = kTRUE;
3981       fSspecie++;
3982     }
3983   }
3984   
3985   Double_t remainingFraction = fFractionFriends;
3986   remainingFraction -= ((Double_t)(fSspecie)/(Double_t)(fNall));
3987   
3988   if (IsHighPt())  { // Selection of "high Pt" events
3989     fNhighPt++;
3990     Double_t curentHighPtFraction = ((Double_t)(fNhighPt+1))/((Double_t)(fNall+1));
3991     // "Bayesian" estimate supposing that without events all the events are of the required type
3992     
3993     if (!isSelected) {
3994       Double_t rnd = gRandom->Rndm()*curentHighPtFraction;
3995       if (rnd<remainingFraction) {
3996         isSelected = kTRUE;
3997         fShighPt++;
3998       }
3999     }
4000   }
4001   remainingFraction -= ((Double_t)(fShighPt)/(Double_t)(fNall));
4002   
4003   // Random selection to fill the remaining fraction (if any)
4004   if (!isSelected) {
4005     Double_t rnd = gRandom->Rndm();
4006     if (rnd<remainingFraction) {        
4007       isSelected = kTRUE;
4008     }
4009   }
4010   
4011   if (!isSelected) {
4012     fesdf->~AliESDfriend();
4013     new (fesdf) AliESDfriend(); // Reset...
4014     fesdf->SetSkipBit(kTRUE);
4015   }
4016   
4017   ftreeF->Fill();
4018 }