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