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