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