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