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