]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/STEER/AliReconstruction.cxx
788752e420cf872911a7f0b7ab6e12035f553ede
[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   AliSysInfo::AddStamp(Form("StartEv_%d",iEvent), 0,0,iEvent);
1863
1864   if (iEvent >= fRunLoader->GetNumberOfEvents()) {
1865     fRunLoader->SetEventNumber(iEvent);
1866     if (fRawReader)
1867       fRunLoader->GetHeader()->Reset(fRawReader->GetRunNumber(), 
1868                                      iEvent, iEvent);
1869     fRunLoader->TreeE()->Fill();
1870
1871     if (fRawReader && fRawReader->UseAutoSaveESD())
1872       fRunLoader->TreeE()->AutoSave("SaveSelf");
1873   }
1874
1875   if ((iEvent < fFirstEvent) || ((fLastEvent >= 0) && (iEvent > fLastEvent))) {
1876     return kTRUE;
1877   }
1878
1879
1880   fRunLoader->GetEvent(iEvent);
1881
1882   // Fill Event-info object
1883   GetEventInfo();
1884   fRecoParam.SetEventSpecie(fRunInfo,fEventInfo,fListOfCosmicTriggers);
1885   
1886   ProcInfo_t procInfo;
1887   if(iEvent==fFirstEvent) {
1888     gSystem->GetProcInfo(&procInfo);
1889     oldMres=procInfo.fMemResident;
1890     oldMvir=procInfo.fMemVirtual;
1891     oldCPU=procInfo.fCpuUser+procInfo.fCpuSys;
1892   }
1893   AliInfo(Form("================================= Processing event %d of type %-10s ==================================", iEvent,fRecoParam.PrintEventSpecie()));
1894
1895   AliSysInfo::AddStamp(Form("StartReco_%d",iEvent), 0,0,iEvent);
1896
1897   // Set the reco-params
1898   {
1899     TString detStr = fLoadCDB;
1900     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1901       if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1902       AliReconstructor *reconstructor = GetReconstructor(iDet);
1903       if (reconstructor && fRecoParam.GetDetRecoParamArray(iDet)) {
1904         const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
1905         reconstructor->SetRecoParam(par);
1906         reconstructor->GetPidSettings(&pid);
1907         reconstructor->SetEventInfo(&fEventInfo);
1908         if (fRunQA) {
1909           AliQAManager::QAManager()->SetEventInfo(&fEventInfo) ;
1910           AliQAManager::QAManager()->SetRecoParam(iDet, par) ; 
1911           if (par) AliQAManager::QAManager()->SetEventSpecie(AliRecoParam::Convert(par->GetEventSpecie())) ;
1912         }
1913       }
1914     }
1915     //
1916     if (fRunQA || fRunGlobalQA) AliQADataMaker::SetEventTrigClasses(fEventInfo.GetTriggerClasses()); // RS: select which histo clones are to be filled
1917     //
1918     if (fRunQA) {
1919       const AliDetectorRecoParam *grppar = fRecoParam.GetDetRecoParam(kNDetectors);
1920       AliQAManager::QAManager()->SetRecoParam(AliQAv1::kGLOBAL, grppar) ; 
1921       AliQAManager::QAManager()->SetEventSpecie(AliRecoParam::Convert(grppar->GetEventSpecie())) ;
1922     }
1923   }
1924
1925     // QA on single raw 
1926   if (fRunQA && IsInTasks(AliQAv1::kRAWS)) {
1927     AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
1928     AliQAManager::QAManager()->RunOneEvent(fRawReader) ;  
1929     AliSysInfo::AddStamp(Form("RawQA_%d",iEvent), 0,0,iEvent);
1930   }
1931     // local single event reconstruction
1932     if (!fRunLocalReconstruction.IsNull()) {
1933       TString detectors=fRunLocalReconstruction;
1934       // run HLT event reconstruction first
1935       // ;-( IsSelected changes the string
1936       if (IsSelected("HLT", detectors) &&
1937           !RunLocalEventReconstruction("HLT")) {
1938         if (fStopOnError) {CleanUp(); return kFALSE;}
1939       }
1940       detectors=fRunLocalReconstruction;
1941       detectors.ReplaceAll("HLT", "");
1942       if (!RunLocalEventReconstruction(detectors)) {
1943         if (fStopOnError) {
1944           CleanUp(); 
1945           return kFALSE;
1946         }
1947       }
1948     }
1949
1950   
1951     // fill Event header information from the RawEventHeader
1952     if (fRawReader){FillRawEventHeaderESD(fesd);}
1953     if (fRawReader){FillRawEventHeaderESD(fhltesd);}
1954
1955     fesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
1956     fhltesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
1957     
1958     ((AliESDRun*)fesd->GetESDRun())->SetDetectorsInDAQ(fRunInfo->GetDetectorMask());
1959     ((AliESDRun*)fhltesd->GetESDRun())->SetDetectorsInDAQ(fRunInfo->GetDetectorMask());
1960     ((AliESDRun*)fesd->GetESDRun())->SetDetectorsInReco(AliDAQ::DetectorPatternOffline(fFillESD.Data()));
1961     ((AliESDRun*)fhltesd->GetESDRun())->SetDetectorsInReco(AliDAQ::DetectorPatternOffline(fFillESD.Data()));
1962
1963     fesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
1964     fhltesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
1965
1966     fesd->SetEventSpecie(fRecoParam.GetEventSpecie());
1967     fhltesd->SetEventSpecie(fRecoParam.GetEventSpecie());
1968     
1969     // Set magnetic field from the tracker
1970     fesd->SetMagneticField(AliTracker::GetBz());
1971     fhltesd->SetMagneticField(AliTracker::GetBz());
1972     //
1973     AliESDRun *esdRun,*esdRunH;
1974     esdRun  = (AliESDRun*)fesd->GetESDRun();
1975     esdRunH = (AliESDRun*)fhltesd->GetESDRun();
1976     esdRun->SetBeamEnergyIsSqrtSHalfGeV();
1977     esdRunH->SetBeamEnergyIsSqrtSHalfGeV();
1978     //
1979     for (int ib=2;ib--;) for (int it=2;it--;) {
1980         esdRun->SetMeanIntensity(ib,it, fBeamInt[ib][it]); 
1981         esdRunH->SetMeanIntensity(ib,it, fBeamInt[ib][it]); 
1982       }
1983     //
1984     fesd->SetBeamEnergy(fGRPData->GetBeamEnergy());
1985     fesd->SetBeamType(fGRPData->GetBeamType().Data());
1986     fesd->SetBeamParticle(fGRPData->GetSingleBeamType(0).Atoi(),0);
1987     fesd->SetBeamParticle(fGRPData->GetSingleBeamType(1).Atoi(),1);
1988     fhltesd->SetBeamEnergy(fGRPData->GetBeamEnergy());
1989     fhltesd->SetBeamType(fGRPData->GetBeamType().Data());
1990     fhltesd->SetBeamParticle(fGRPData->GetSingleBeamType(0).Atoi(),0);
1991     fhltesd->SetBeamParticle(fGRPData->GetSingleBeamType(1).Atoi(),1);
1992     //
1993     AliMagF* fld = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
1994     if (fld) { // set info needed for field initialization
1995       fesd->SetCurrentL3(fld->GetCurrentSol());
1996       fesd->SetCurrentDip(fld->GetCurrentDip());
1997       fesd->SetUniformBMap(fld->IsUniform());
1998       fesd->SetBInfoStored();
1999       //
2000       fhltesd->SetCurrentL3(fld->GetCurrentSol());
2001       fhltesd->SetCurrentDip(fld->GetCurrentDip());
2002       fhltesd->SetUniformBMap(fld->IsUniform());
2003       fhltesd->SetBInfoStored();
2004     }
2005     //
2006     // Set most probable pt, for B=0 tracking
2007     // Get the global reco-params. They are atposition 16 inside the array of detectors in fRecoParam
2008     const AliGRPRecoParam *grpRecoParam = dynamic_cast<const AliGRPRecoParam*>(fRecoParam.GetDetRecoParam(kNDetectors));
2009     if (grpRecoParam) AliExternalTrackParam::SetMostProbablePt(grpRecoParam->GetMostProbablePt());
2010     
2011     // Fill raw-data error log into the ESD
2012     if (fRawReader) FillRawDataErrorLog(iEvent,fesd);
2013
2014     AliSysInfo::AddStamp(Form("FillHeadErrs_%d",iEvent), 0,0,iEvent);
2015
2016     // vertex finder
2017     if (fRunVertexFinder) {
2018       if (!RunVertexFinder(fesd)) {
2019         if (fStopOnError) {CleanUp(); return kFALSE;}
2020       }
2021       AliSysInfo::AddStamp(Form("VtxFinder_%d",iEvent), 0,0,iEvent);
2022     }
2023
2024     // For Plane Efficiency: run the SPD trackleter
2025     if (fRunPlaneEff && fSPDTrackleter) {
2026       if (!RunSPDTrackleting(fesd)) {
2027         if (fStopOnError) {CleanUp(); return kFALSE;}
2028       }
2029       AliSysInfo::AddStamp(Form("TrackletEff_%d",iEvent), 0,0,iEvent);
2030     }
2031
2032     // Muon tracking
2033     if (!fRunTracking.IsNull()) {
2034       if (fRunMuonTracking) {
2035         if (!RunMuonTracking(fesd)) {
2036           if (fStopOnError) {CleanUp(); return kFALSE;}
2037         }
2038       }
2039       AliSysInfo::AddStamp(Form("TrackingMUON_%d",iEvent), 0,0,iEvent);      
2040     }
2041
2042     // barrel tracking
2043     if (!fRunTracking.IsNull()) {
2044       if (!RunTracking(fesd,pid)) {
2045         if (fStopOnError) {CleanUp(); return kFALSE;}
2046       }
2047     }
2048
2049     // fill ESD
2050     if (!fFillESD.IsNull()) {
2051       TString detectors=fFillESD;
2052       // run HLT first and on hltesd
2053       // ;-( IsSelected changes the string
2054       if (IsSelected("HLT", detectors) &&
2055           !FillESD(fhltesd, "HLT")) {
2056         if (fStopOnError) {CleanUp(); return kFALSE;}
2057       }
2058       detectors=fFillESD;
2059       // Temporary fix to avoid problems with HLT that overwrites the offline ESDs
2060       if (detectors.Contains("ALL")) {
2061         detectors="";
2062         for (Int_t idet=0; idet<kNDetectors; ++idet){
2063           detectors += fgkDetectorName[idet];
2064           detectors += " ";
2065         }
2066       }
2067       detectors.ReplaceAll("HLT", "");
2068       if (!FillESD(fesd, detectors)) {
2069         if (fStopOnError) {CleanUp(); return kFALSE;}
2070       }
2071     }
2072     
2073
2074     ffile->cd();
2075
2076     //
2077     // Propagate track to the beam pipe  (if not already done by ITS)
2078     //
2079     const Int_t ntracks = fesd->GetNumberOfTracks();
2080     const Double_t kRadius  = 2.8; //something less than the beam pipe radius
2081
2082     TObjArray trkArray;
2083     UShort_t *selectedIdx=new UShort_t[ntracks];
2084
2085     for (Int_t itrack=0; itrack<ntracks; itrack++){
2086       const Double_t kMaxStep = 1;   //max step over the material
2087       Bool_t ok;
2088
2089       AliESDtrack *track = fesd->GetTrack(itrack);
2090       if (!track) continue;
2091
2092       AliExternalTrackParam *tpcTrack =
2093            (AliExternalTrackParam *)track->GetTPCInnerParam();
2094       ok = kFALSE;
2095       if (tpcTrack)
2096         ok = AliTracker::
2097           PropagateTrackToBxByBz(tpcTrack,kRadius,track->GetMass(),kMaxStep,kFALSE);
2098
2099       if (ok) {
2100         Int_t n=trkArray.GetEntriesFast();
2101         selectedIdx[n]=track->GetID();
2102         trkArray.AddLast(tpcTrack);
2103       }
2104
2105       //Tracks refitted by ITS should already be at the SPD vertex
2106       if (track->IsOn(AliESDtrack::kITSrefit)) continue;
2107
2108       AliTracker::
2109          PropagateTrackToBxByBz(track,kRadius,track->GetMass(),kMaxStep,kFALSE);
2110       Double_t x[3]; track->GetXYZ(x);
2111       Double_t b[3]; AliTracker::GetBxByBz(x,b);
2112       track->RelateToVertexBxByBz(fesd->GetPrimaryVertexSPD(), b, kVeryBig);
2113
2114     }
2115     AliSysInfo::AddStamp(Form("RelToSPDVtx_%d",iEvent), 0,0,iEvent);      
2116     //
2117     // Improve the reconstructed primary vertex position using the tracks
2118     //
2119     Bool_t runVertexFinderTracks = fRunVertexFinderTracks;
2120     if(fesd->GetPrimaryVertexSPD()) {
2121       TString vtitle = fesd->GetPrimaryVertexSPD()->GetTitle();
2122       if(vtitle.Contains("cosmics")) {
2123         runVertexFinderTracks=kFALSE;
2124       }
2125     }
2126
2127     if (runVertexFinderTracks) {
2128        // TPC + ITS primary vertex
2129        ftVertexer->SetITSMode();
2130        ftVertexer->SetConstraintOff();
2131        // get cuts for vertexer from AliGRPRecoParam
2132        Bool_t constrSPD=kFALSE;
2133        if (grpRecoParam) {
2134          Int_t nCutsVertexer = grpRecoParam->GetVertexerTracksNCuts();
2135          Double_t *cutsVertexer = new Double_t[nCutsVertexer];
2136          grpRecoParam->GetVertexerTracksCutsITS(cutsVertexer,nCutsVertexer);
2137          ftVertexer->SetCuts(cutsVertexer,nCutsVertexer);
2138          delete [] cutsVertexer; cutsVertexer = NULL; 
2139          if(grpRecoParam->GetVertexerTracksConstraintITS()) { 
2140            if(fDiamondProfile && fDiamondProfile->GetXRes()<kRadius){
2141              ftVertexer->SetVtxStart(fDiamondProfile); // apply constraint only if sigmax is smaller than the beam pipe radius 
2142            }else{
2143              if(fDiamondProfileSPD && fDiamondProfileSPD->GetXRes()<kRadius){
2144                ftVertexer->SetVtxStart(fDiamondProfileSPD);
2145                constrSPD=kTRUE;
2146              }
2147            }
2148          } 
2149        }
2150        AliESDVertex *pvtx=ftVertexer->FindPrimaryVertex(fesd);
2151        if (pvtx) {
2152          if(constrSPD){
2153            TString title=pvtx->GetTitle();
2154            title.Append("SPD");
2155            pvtx->SetTitle(title);
2156          }
2157           if (pvtx->GetStatus()) {
2158              fesd->SetPrimaryVertexTracks(pvtx);
2159              for (Int_t i=0; i<ntracks; i++) {
2160                  AliESDtrack *t = fesd->GetTrack(i);
2161                  Double_t x[3]; t->GetXYZ(x);
2162                  Double_t b[3]; AliTracker::GetBxByBz(x,b);
2163                  t->RelateToVertexBxByBz(pvtx, b, kVeryBig);
2164              } 
2165           }
2166           delete pvtx; pvtx=NULL;
2167        }
2168        AliSysInfo::AddStamp(Form("VtxTrk_%d",iEvent), 0,0,iEvent);      
2169
2170        // TPC-only primary vertex
2171        ftVertexer->SetTPCMode();
2172        ftVertexer->SetConstraintOff();
2173        // get cuts for vertexer from AliGRPRecoParam
2174        if (grpRecoParam) {
2175          Int_t nCutsVertexer = grpRecoParam->GetVertexerTracksNCuts();
2176          Double_t *cutsVertexer = new Double_t[nCutsVertexer];
2177          grpRecoParam->GetVertexerTracksCutsTPC(cutsVertexer,nCutsVertexer);
2178          ftVertexer->SetCuts(cutsVertexer,nCutsVertexer);
2179          delete [] cutsVertexer; cutsVertexer = NULL; 
2180          if(fDiamondProfileTPC && grpRecoParam->GetVertexerTracksConstraintTPC()) { 
2181            if(fDiamondProfileTPC->GetXRes()<kRadius) ftVertexer->SetVtxStart(fDiamondProfileTPC); // apply constraint only if sigmax is smaller than the beam pipe radius 
2182          } 
2183        }
2184        pvtx=ftVertexer->FindPrimaryVertex(&trkArray,selectedIdx);
2185        if (pvtx) {
2186           if (pvtx->GetStatus()) {
2187              fesd->SetPrimaryVertexTPC(pvtx);
2188              for (Int_t i=0; i<ntracks; i++) {
2189                  AliESDtrack *t = fesd->GetTrack(i);
2190                  Double_t x[3]; t->GetXYZ(x);
2191                  Double_t b[3]; AliTracker::GetBxByBz(x,b);
2192                  t->RelateToVertexTPCBxByBz(pvtx, b, kVeryBig);
2193              } 
2194           }
2195           delete pvtx; pvtx=NULL;
2196        }
2197        AliSysInfo::AddStamp(Form("VtxTPC_%d",iEvent), 0,0,iEvent);      
2198
2199     }
2200     delete[] selectedIdx;
2201
2202     if(fDiamondProfile && fDiamondProfile->GetXRes()<kRadius) fesd->SetDiamond(fDiamondProfile);
2203     else fesd->SetDiamond(fDiamondProfileSPD);
2204
2205     if (fRunV0Finder) {
2206        // V0 finding
2207        AliV0vertexer vtxer;
2208        // get cuts for V0vertexer from AliGRPRecoParam
2209        if (grpRecoParam) {
2210          Int_t nCutsV0vertexer = grpRecoParam->GetVertexerV0NCuts();
2211          Double_t *cutsV0vertexer = new Double_t[nCutsV0vertexer];
2212          grpRecoParam->GetVertexerV0Cuts(cutsV0vertexer);
2213          vtxer.SetCuts(cutsV0vertexer);
2214          delete [] cutsV0vertexer; cutsV0vertexer = NULL; 
2215        }
2216        vtxer.Tracks2V0vertices(fesd);
2217        AliSysInfo::AddStamp(Form("V0Finder_%d",iEvent), 0,0,iEvent); 
2218
2219        if (fRunCascadeFinder) {
2220           // Cascade finding
2221           AliCascadeVertexer cvtxer;
2222           // get cuts for CascadeVertexer from AliGRPRecoParam
2223           if (grpRecoParam) {
2224             Int_t nCutsCascadeVertexer = grpRecoParam->GetVertexerCascadeNCuts();
2225             Double_t *cutsCascadeVertexer = new Double_t[nCutsCascadeVertexer];
2226             grpRecoParam->GetVertexerCascadeCuts(cutsCascadeVertexer);
2227             cvtxer.SetCuts(cutsCascadeVertexer);
2228             delete [] cutsCascadeVertexer; cutsCascadeVertexer = NULL; 
2229           }
2230           cvtxer.V0sTracks2CascadeVertices(fesd);
2231           AliSysInfo::AddStamp(Form("CascadeFinder_%d",iEvent), 0,0,iEvent); 
2232        }
2233     }
2234
2235     // AdC+FN
2236     if (fReconstructor[3])
2237       GetReconstructor(3)->FillEventTimeWithTOF(fesd,&pid);
2238
2239     // combined PID
2240     pid.MakePID(fesd);
2241
2242     if (fFillTriggerESD) {
2243       if (!FillTriggerESD(fesd)) {
2244         if (fStopOnError) {CleanUp(); return kFALSE;}
2245       }
2246     }
2247     // Always fill scalers
2248     if (!FillTriggerScalers(fesd)) {
2249        if (fStopOnError) {CleanUp(); return kFALSE;}
2250     }
2251
2252     AliSysInfo::AddStamp(Form("FillVaria_%d",iEvent), 0,0,iEvent); 
2253
2254     // write ESD
2255     if (fCleanESD) {
2256       CleanESD(fesd);
2257       AliSysInfo::AddStamp(Form("CleanESD_%d",iEvent), 0,0,iEvent); 
2258     }
2259     // 
2260     // RS run updated trackleter: since we want to mark the clusters used by tracks and also mark the 
2261     // tracks interpreted as primary, this step should be done in the very end, when full 
2262     // ESD info is available (particulalry, V0s)
2263     // vertex finder
2264     if (fRunMultFinder) {
2265       if (!RunMultFinder(fesd)) {
2266         if (fStopOnError) {CleanUp(); return kFALSE;}
2267       }
2268       AliSysInfo::AddStamp(Form("MultFinder_%d",iEvent), 0,0,iEvent); 
2269     }
2270
2271   if (fRunQA && IsInTasks(AliQAv1::kESDS)) {
2272     AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2273     AliQAManager::QAManager()->RunOneEvent(fesd, fhltesd) ; 
2274     AliSysInfo::AddStamp(Form("RunQA_%d",iEvent), 0,0,iEvent); 
2275   }
2276   if (fRunGlobalQA) {
2277     AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
2278     if (qadm)
2279       qadm->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2280     if (qadm && IsInTasks(AliQAv1::kESDS))
2281       qadm->Exec(AliQAv1::kESDS, fesd);
2282     AliSysInfo::AddStamp(Form("RunGlobQA_%d",iEvent), 0,0,iEvent);     
2283   }
2284
2285   // copy HLT decision from HLTesd to esd
2286   // the most relevant information is stored in a reduced container in the esd,
2287   // while the full information can be found in the HLTesd
2288   TObject* pHLTSrc=fhltesd->FindListObject(AliESDHLTDecision::Name());
2289   TObject* pHLTTgt=fesd->FindListObject(AliESDHLTDecision::Name());
2290   if (pHLTSrc && pHLTTgt) {
2291     pHLTSrc->Copy(*pHLTTgt);
2292   }
2293   //
2294   // Perform analysis of this event if requested
2295   // RS: Should be done before WriteESDfriend, since the latter may clean the esdfriend
2296   if (fAnalysis) {
2297     fRecoHandler->BeginEvent(iEvent);
2298     fAnalysis->ExecAnalysis();
2299     fRecoHandler->FinishEvent();
2300     AliSysInfo::AddStamp(Form("Analysis_%d",iEvent), 0,0,iEvent);     
2301   }  
2302   //
2303     if (fWriteESDfriend) 
2304       fesd->GetESDfriend(fesdf);
2305
2306     ftree->Fill();
2307     if (fWriteESDfriend) {
2308       WriteESDfriend();
2309     }
2310     // Auto-save the ESD tree in case of prompt reco @P2
2311     if (fRawReader && fRawReader->UseAutoSaveESD()) {
2312       ftree->AutoSave("SaveSelf");
2313       if (fWriteESDfriend) ftreeF->AutoSave("SaveSelf");
2314     }
2315
2316     // write HLT ESD
2317     fhlttree->Fill();
2318
2319     AliSysInfo::AddStamp(Form("WriteESDs_%d",iEvent), 0,0,iEvent);     
2320
2321     // call AliEVE
2322     if (fRunAliEVE) RunAliEVE();
2323     //
2324     fesd->Reset();
2325     fhltesd->Reset();
2326     if (fWriteESDfriend) {
2327       fesdf->~AliESDfriend();
2328       new (fesdf) AliESDfriend(); // Reset...
2329     }
2330  
2331     gSystem->GetProcInfo(&procInfo);
2332     Long_t dMres=(procInfo.fMemResident-oldMres)/1024;
2333     Long_t dMvir=(procInfo.fMemVirtual-oldMvir)/1024;
2334     Float_t dCPU=procInfo.fCpuUser+procInfo.fCpuSys-oldCPU;
2335     aveDMres+=(dMres-aveDMres)/(iEvent-fFirstEvent+1);
2336     aveDMvir+=(dMvir-aveDMvir)/(iEvent-fFirstEvent+1);
2337     aveDCPU+=(dCPU-aveDCPU)/(iEvent-fFirstEvent+1);
2338     AliInfo(Form("======================= End Event %d: Res %ld(%3ld <%3ld>) Vir %ld(%3ld <%3ld>) CPU %5.2f <%5.2f> ===================",
2339                  iEvent, procInfo.fMemResident/1024, dMres, aveDMres, procInfo.fMemVirtual/1024, dMvir, aveDMvir, dCPU, aveDCPU));
2340     oldMres=procInfo.fMemResident;
2341     oldMvir=procInfo.fMemVirtual;
2342     oldCPU=procInfo.fCpuUser+procInfo.fCpuSys;
2343   
2344     fEventInfo.Reset();
2345     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2346       if (fReconstructor[iDet]) {
2347         fReconstructor[iDet]->SetRecoParam(NULL);
2348         fReconstructor[iDet]->SetEventInfo(NULL);
2349       }
2350       if (fTracker[iDet]) fTracker[iDet]->SetEventInfo(NULL);
2351     }
2352         
2353   if (fRunQA || fRunGlobalQA) 
2354     AliQAManager::QAManager()->Increment() ; 
2355
2356     return kTRUE;
2357 }
2358
2359 //_____________________________________________________________________________
2360 void AliReconstruction::SlaveTerminate()
2361 {
2362   // Finalize the run on the slave side
2363   // Called after the exit
2364   // from the event loop
2365   AliCodeTimerAuto("",0);
2366   // If analysis was done during reconstruction, we need to call SlaveTerminate for it
2367   if (fAnalysis) {
2368      fAnalysis->PackOutput(fOutput);
2369      fAnalysis->SetSkipTerminate(kTRUE);
2370      fAnalysis->Terminate();
2371   }   
2372
2373   if (fIsNewRunLoader) { // galice.root didn't exist
2374     fRunLoader->WriteHeader("OVERWRITE");
2375     fRunLoader->WriteTrigger("OVERWRITE");
2376     fRunLoader->CdGAFile();
2377     fRunLoader->Write(0, TObject::kOverwrite);
2378   }
2379
2380   const TMap *cdbMap = AliCDBManager::Instance()->GetStorageMap();       
2381   const TList *cdbList = AliCDBManager::Instance()->GetRetrievedIds();   
2382                  
2383    TMap *cdbMapCopy = new TMap(cdbMap->GetEntries());    
2384    cdbMapCopy->SetOwner(1);      
2385    cdbMapCopy->SetName("cdbMap");        
2386    TIter iter(cdbMap->GetTable());       
2387          
2388    TPair* pair = 0;      
2389    while((pair = dynamic_cast<TPair*> (iter.Next()))){   
2390          TObjString* keyStr = dynamic_cast<TObjString*> (pair->Key());   
2391          TObjString* valStr = dynamic_cast<TObjString*> (pair->Value());
2392          if (keyStr && valStr)
2393            cdbMapCopy->Add(new TObjString(keyStr->GetName()), new TObjString(valStr->GetName()));        
2394    }     
2395          
2396    TList *cdbListCopy = new TList();     
2397    cdbListCopy->SetOwner(1);     
2398    cdbListCopy->SetName("cdbList");      
2399          
2400    TIter iter2(cdbList);         
2401          
2402         AliCDBId* id=0;
2403         while((id = dynamic_cast<AliCDBId*> (iter2.Next()))){    
2404          cdbListCopy->Add(new TObjString(id->ToString().Data()));        
2405    }     
2406          
2407    ftree->GetUserInfo()->Add(cdbMapCopy);        
2408    ftree->GetUserInfo()->Add(cdbListCopy);
2409
2410    // Add the AliRoot version that created this file
2411    TString sVersion("aliroot ");
2412    sVersion += ALIROOT_SVN_BRANCH;
2413    sVersion += ":";
2414    sVersion += ALIROOT_SVN_REVISION;
2415    sVersion += "; root ";
2416    sVersion += ROOT_SVN_BRANCH;
2417    sVersion += ":";
2418    sVersion += ROOT_SVN_REVISION;
2419    sVersion += "; metadata ";
2420    sVersion += gSystem->Getenv("PRODUCTION_METADATA");
2421                     
2422
2423    TNamed * alirootVersion = new TNamed("alirootVersion",sVersion.Data());
2424    ftree->GetUserInfo()->Add(alirootVersion); // The list becomes owner of alirootVersion
2425
2426   ffile->cd();
2427
2428   // we want to have only one tree version number
2429   ftree->Write(ftree->GetName(),TObject::kOverwrite);
2430   fhlttree->Write(fhlttree->GetName(),TObject::kOverwrite);
2431
2432   if (fWriteESDfriend) {
2433     ffileF->cd();
2434     ftreeF->Write(ftreeF->GetName(),TObject::kOverwrite);
2435   }
2436
2437 // Finish with Plane Efficiency evaluation: before of CleanUp !!!
2438   if (fRunPlaneEff && !FinishPlaneEff()) {
2439    AliWarning("Finish PlaneEff evaluation failed");
2440   }
2441
2442   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2443     if (fReconstructor[iDet]) fReconstructor[iDet]->Terminate();
2444   }
2445   // End of cycle for the in-loop  
2446
2447   if (fRunQA || fRunGlobalQA) {
2448     AliQAManager::QAManager()->EndOfCycle() ;
2449     if (fInput &&
2450         !fProofOutputLocation.IsNull() &&
2451         fProofOutputArchive.IsNull() &&
2452         !fProofOutputDataset) {
2453       TString qaOutputFile(Form("%sMerged.%s.Data.root",
2454                                 fProofOutputLocation.Data(),
2455                                 AliQAv1::GetQADataFileName()));
2456       TProofOutputFile *qaProofFile = new TProofOutputFile(Form("Merged.%s.Data.root",
2457                                                                 AliQAv1::GetQADataFileName()));
2458       qaProofFile->SetOutputFileName(qaOutputFile.Data());
2459       if (AliDebugLevel() > 0) qaProofFile->Dump();
2460       fOutput->Add(qaProofFile);
2461       MergeQA(qaProofFile->GetFileName());
2462     }
2463     else {
2464       MergeQA();
2465     }
2466   }
2467
2468   gROOT->cd();
2469   CleanUp();
2470
2471   if (fInput) {
2472     if (!fProofOutputFileName.IsNull() &&
2473         !fProofOutputLocation.IsNull() &&
2474         fProofOutputDataset &&
2475         !fProofOutputArchive.IsNull()) {
2476       TProofOutputFile *zipProofFile = new TProofOutputFile(fProofOutputFileName.Data(),
2477                                                             "DROV",
2478                                                             fProofOutputLocation.Data());
2479       if (AliDebugLevel() > 0) zipProofFile->Dump();
2480       fOutput->Add(zipProofFile);
2481       TString fileList(fProofOutputArchive.Data());
2482       fileList.ReplaceAll(","," ");
2483       TString command;
2484 #if ROOT_SVN_REVISION >= 30174
2485       command.Form("zip -n root %s/%s %s",zipProofFile->GetDir(kTRUE),zipProofFile->GetFileName(),fileList.Data());
2486 #else
2487       command.Form("zip -n root %s/%s %s",zipProofFile->GetDir(),zipProofFile->GetFileName(),fileList.Data());
2488 #endif
2489       AliInfo(Form("Executing: %s",command.Data()));
2490       gSystem->Exec(command.Data());
2491     }
2492   }
2493 }
2494     
2495 //_____________________________________________________________________________
2496 void AliReconstruction::Terminate()
2497 {
2498   // Create tags for the events in the ESD tree (the ESD tree is always present)
2499   // In case of empty events the tags will contain dummy values
2500   AliCodeTimerAuto("",0);
2501
2502   // Do not call the ESD tag creator in case of PROOF-based reconstruction
2503   if (!fInput) {
2504     AliESDTagCreator *esdtagCreator = new AliESDTagCreator();
2505     esdtagCreator->CreateESDTags(fFirstEvent,fLastEvent,fGRPData, AliQAv1::Instance()->GetQA(), AliQAv1::Instance()->GetEventSpecies(), AliQAv1::kNDET, AliRecoParam::kNSpecies);
2506     delete esdtagCreator;
2507   }
2508
2509   // Cleanup of CDB manager: cache and active storages!
2510   AliCDBManager::Instance()->ClearCache();
2511 }
2512
2513 //_____________________________________________________________________________
2514 Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
2515 {
2516 // run the local reconstruction
2517
2518   static Int_t eventNr=0;
2519   AliCodeTimerAuto("",0)
2520
2521   TString detStr = detectors;
2522   // execute HLT reconstruction first since other detector reconstruction
2523   // might depend on HLT data
2524   // key 'HLT' is removed from detStr by IsSelected
2525   if (!IsSelected("HLT", detStr)) {
2526     AliReconstructor* reconstructor = GetReconstructor(kNDetectors-1);
2527     if (reconstructor) {
2528       // there is no AliLoader for HLT, see
2529       // https://savannah.cern.ch/bugs/?35473
2530       AliInfo("running reconstruction for HLT");
2531       if (fRawReader) {
2532         AliInfo("reconstructor->Reconstruct(fRawReader, NULL)");
2533         reconstructor->Reconstruct(fRawReader, NULL);
2534       } 
2535       else {
2536         AliInfo("reconstructor->Reconstruct(dummy, NULL)");
2537         TTree* dummy=NULL;
2538         reconstructor->Reconstruct(dummy, NULL);
2539       }
2540     }
2541     AliSysInfo::AddStamp(Form("LRecHLT_%d",eventNr), -1,1,eventNr);
2542   }
2543
2544   AliInfo(Form("kNDetectors = %d",kNDetectors));
2545
2546   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2547     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2548     AliDebug(1, Form("Detector: %s", fgkDetectorName[iDet]));
2549     AliReconstructor* reconstructor = GetReconstructor(iDet);
2550     if (!reconstructor) continue;
2551     AliLoader* loader = fLoader[iDet];
2552     if (!loader) {
2553       AliWarning(Form("No loader is defined for %s!",fgkDetectorName[iDet]));
2554       continue;
2555     }
2556     // conversion of digits
2557     if (fRawReader && reconstructor->HasDigitConversion()) {
2558       AliInfo(Form("converting raw data digits into root objects for %s", 
2559                    fgkDetectorName[iDet]));
2560 //      AliCodeTimerAuto(Form("converting raw data digits into root objects for %s", 
2561 //                            fgkDetectorName[iDet]),0);
2562       loader->LoadDigits("update");
2563       loader->CleanDigits();
2564       loader->MakeDigitsContainer();
2565       TTree* digitsTree = loader->TreeD();
2566       reconstructor->ConvertDigits(fRawReader, digitsTree);
2567       loader->WriteDigits("OVERWRITE");
2568       loader->UnloadDigits();
2569     }
2570     // local reconstruction
2571     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
2572     //AliCodeTimerAuto(Form("running reconstruction for %s", fgkDetectorName[iDet]),0);
2573     AliDebug(1, "Loading Rec Points");
2574     loader->LoadRecPoints("update");
2575     AliDebug(1, "Cleaning Rec Points");
2576     loader->CleanRecPoints();
2577     AliDebug(1, "Making Rec Points Container");
2578     loader->MakeRecPointsContainer();
2579     TTree* clustersTree = loader->TreeR();
2580     if (fRawReader && !reconstructor->HasDigitConversion()) {
2581       reconstructor->Reconstruct(fRawReader, clustersTree);
2582     } 
2583     else {
2584       AliDebug(1, "Loading Digits");
2585       loader->LoadDigits("read");
2586       TTree* digitsTree = loader->TreeD();
2587       AliDebug(1, Form("Digits Tree = %p",digitsTree));
2588       if (!digitsTree) {
2589         AliError(Form("Can't get the %s digits tree", fgkDetectorName[iDet]));
2590         if (fStopOnError) 
2591           return kFALSE;
2592       } 
2593       else {
2594         AliDebug(1, "Digits -> Clusters");
2595         reconstructor->Reconstruct(digitsTree, clustersTree);
2596         if (fRunQA && IsInTasks(AliQAv1::kDIGITSR)) {
2597           AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2598           AliQAManager::QAManager()->RunOneEventInOneDetector(iDet, digitsTree) ; 
2599         }
2600       }
2601       loader->UnloadDigits();
2602     }
2603     if (fRunQA && IsInTasks(AliQAv1::kRECPOINTS)) {
2604       AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2605       AliQAManager::QAManager()->RunOneEventInOneDetector(iDet, clustersTree) ; 
2606     }
2607     loader->WriteRecPoints("OVERWRITE");
2608     loader->UnloadRecPoints();
2609     AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr), iDet,1,eventNr);
2610   }
2611   if (!IsSelected("CTP", detStr)) AliDebug(10,"No CTP");
2612   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2613     AliError(Form("the following detectors were not found: %s",
2614                   detStr.Data()));
2615     if (fStopOnError) 
2616       return kFALSE;
2617   }
2618   eventNr++;
2619   return kTRUE;
2620 }
2621 //_____________________________________________________________________________
2622 Bool_t AliReconstruction::RunSPDTrackleting(AliESDEvent*& esd)
2623 {
2624 // run the SPD trackleting (for SPD efficiency purpouses)
2625
2626   AliCodeTimerAuto("",0)
2627
2628   Double_t vtxPos[3] = {0, 0, 0};
2629   Double_t vtxErr[3] = {0.0, 0.0, 0.0};
2630 /*
2631   TArrayF m
2632 /
2633 cVertex(3);
2634   // if(MC)
2635   if (fRunLoader->GetHeader() && fRunLoader->GetHeader()->GenEventHeader()) {
2636     fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(mcVertex);
2637     for (Int_t i = 0; i < 3; i++) vtxPos[i] = mcVertex[i];
2638   }
2639 */
2640   const AliESDVertex *vertex = esd->GetVertex();
2641   if(!vertex){
2642     AliWarning("Vertex not found");
2643     return kFALSE;
2644   }
2645   vertex->GetXYZ(vtxPos);
2646   vertex->GetSigmaXYZ(vtxErr);
2647   if (fSPDTrackleter) {
2648     AliInfo("running the SPD Trackleter for Plane Efficiency Evaluation");
2649
2650     // load clusters
2651     fLoader[0]->LoadRecPoints("read");
2652     TTree* tree = fLoader[0]->TreeR();
2653     if (!tree) {
2654       AliError("Can't get the ITS cluster tree");
2655       return kFALSE;
2656     }
2657     fSPDTrackleter->LoadClusters(tree);
2658     fSPDTrackleter->SetVertex(vtxPos, vtxErr);
2659     // run trackleting
2660     if (fSPDTrackleter->Clusters2Tracks(esd) != 0) {
2661       AliWarning("AliITSTrackleterSPDEff Clusters2Tracks failed");
2662      // fLoader[0]->UnloadRecPoints();
2663       return kFALSE;
2664     }
2665 //fSPDTrackleter->UnloadRecPoints();
2666   } else {
2667     AliWarning("SPDTrackleter not available");
2668     return kFALSE;
2669   }
2670   return kTRUE;
2671 }
2672
2673 //_____________________________________________________________________________
2674 Bool_t AliReconstruction::RunVertexFinder(AliESDEvent*& esd)
2675 {
2676 // run the barrel tracking
2677
2678   AliCodeTimerAuto("",0)
2679
2680   AliVertexer *vertexer = CreateVertexer();
2681   if (!vertexer) return kFALSE;
2682
2683   AliInfo(Form("running the ITS vertex finder: %s",vertexer->ClassName()));
2684   AliESDVertex* vertex = NULL;
2685   if (fLoader[0]) {
2686     fLoader[0]->LoadRecPoints();
2687     TTree* cltree = fLoader[0]->TreeR();
2688     if (cltree) {
2689       if(fDiamondProfileSPD) vertexer->SetVtxStart(fDiamondProfileSPD);
2690       vertex = vertexer->FindVertexForCurrentEvent(cltree);
2691     }
2692     else {
2693       AliError("Can't get the ITS cluster tree");
2694     }
2695     fLoader[0]->UnloadRecPoints();
2696   }
2697   else {
2698     AliError("Can't get the ITS loader");
2699   }
2700   if(!vertex){
2701     AliWarning("Vertex not found");
2702     vertex = new AliESDVertex();
2703     vertex->SetName("default");
2704   }
2705   else {
2706     vertex->SetName("reconstructed");
2707   }
2708
2709   Double_t vtxPos[3];
2710   Double_t vtxErr[3];
2711   vertex->GetXYZ(vtxPos);
2712   vertex->GetSigmaXYZ(vtxErr);
2713
2714   esd->SetPrimaryVertexSPD(vertex);
2715   AliESDVertex *vpileup = NULL;
2716   Int_t novertices = 0;
2717   vpileup = vertexer->GetAllVertices(novertices);
2718   if(novertices>1){
2719     for (Int_t kk=1; kk<novertices; kk++)esd->AddPileupVertexSPD(&vpileup[kk]);
2720   }
2721   /*
2722   // if SPD multiplicity has been determined, it is stored in the ESD
2723   AliMultiplicity *mult = vertexer->GetMultiplicity();
2724   if(mult)esd->SetMultiplicity(mult);
2725   */
2726   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2727     if (fTracker[iDet]) fTracker[iDet]->SetVertex(vtxPos, vtxErr);
2728   }  
2729   delete vertex;
2730
2731   delete vertexer;
2732
2733   return kTRUE;
2734 }
2735
2736 //_____________________________________________________________________________
2737 Bool_t AliReconstruction::RunMultFinder(AliESDEvent*& esd)
2738 {
2739   // run the trackleter for multiplicity study
2740
2741   AliCodeTimerAuto("",0)
2742
2743   AliTrackleter *trackleter = CreateMultFinder();
2744   if (!trackleter) return kFALSE;
2745
2746   AliInfo(Form("running the ITS multiplicity finder: %s",trackleter->ClassName()));
2747
2748   if (fLoader[0]) {
2749     fLoader[0]->LoadRecPoints();
2750     TTree* cltree = fLoader[0]->TreeR();
2751     if (cltree) {
2752       trackleter->Reconstruct(esd,cltree);
2753       AliMultiplicity *mult = trackleter->GetMultiplicity();
2754       if(mult) esd->SetMultiplicity(mult);
2755     }
2756     else {
2757       AliError("Can't get the ITS cluster tree");
2758     }
2759     fLoader[0]->UnloadRecPoints();
2760   }
2761   else {
2762     AliError("Can't get the ITS loader");
2763   }
2764
2765   delete trackleter;
2766
2767   return kTRUE;
2768 }
2769
2770 //_____________________________________________________________________________
2771 Bool_t AliReconstruction::RunHLTTracking(AliESDEvent*& esd)
2772 {
2773 // run the HLT barrel tracking
2774
2775   AliCodeTimerAuto("",0)
2776
2777   if (!fRunLoader) {
2778     AliError("Missing runLoader!");
2779     return kFALSE;
2780   }
2781
2782   AliInfo("running HLT tracking");
2783
2784   // Get a pointer to the HLT reconstructor
2785   AliReconstructor *reconstructor = GetReconstructor(kNDetectors-1);
2786   if (!reconstructor) return kFALSE;
2787
2788   // TPC + ITS
2789   for (Int_t iDet = 1; iDet >= 0; iDet--) {
2790     TString detName = fgkDetectorName[iDet];
2791     AliDebug(1, Form("%s HLT tracking", detName.Data()));
2792     reconstructor->SetOption(detName.Data());
2793     AliTracker *tracker = reconstructor->CreateTracker();
2794     if (!tracker) {
2795       AliWarning(Form("couldn't create a HLT tracker for %s", detName.Data()));
2796       if (fStopOnError) return kFALSE;
2797       continue;
2798     }
2799     Double_t vtxPos[3];
2800     Double_t vtxErr[3]={0.005,0.005,0.010};
2801     const AliESDVertex *vertex = esd->GetVertex();
2802     vertex->GetXYZ(vtxPos);
2803     tracker->SetVertex(vtxPos,vtxErr);
2804     if(iDet != 1) {
2805       fLoader[iDet]->LoadRecPoints("read");
2806       TTree* tree = fLoader[iDet]->TreeR();
2807       if (!tree) {
2808         AliError(Form("Can't get the %s cluster tree", detName.Data()));
2809         return kFALSE;
2810       }
2811       tracker->LoadClusters(tree);
2812     }
2813     if (tracker->Clusters2Tracks(esd) != 0) {
2814       AliError(Form("HLT %s Clusters2Tracks failed", fgkDetectorName[iDet]));
2815       return kFALSE;
2816     }
2817     if(iDet != 1) {
2818       tracker->UnloadClusters();
2819     }
2820     delete tracker;
2821   }
2822
2823   return kTRUE;
2824 }
2825
2826 //_____________________________________________________________________________
2827 Bool_t AliReconstruction::RunMuonTracking(AliESDEvent*& esd)
2828 {
2829 // run the muon spectrometer tracking
2830
2831   AliCodeTimerAuto("",0)
2832
2833   if (!fRunLoader) {
2834     AliError("Missing runLoader!");
2835     return kFALSE;
2836   }
2837   Int_t iDet =  GetDetIndex("MUON"); // for MUON
2838
2839   // Get a pointer to the MUON reconstructor
2840   AliReconstructor *reconstructor = GetReconstructor(iDet);
2841   if (!reconstructor) return kFALSE;
2842
2843   
2844   TString detName = fgkDetectorName[iDet];
2845   AliDebug(1, Form("%s tracking", detName.Data()));
2846   AliTracker *tracker =  reconstructor->CreateTracker();
2847   if (!tracker) {
2848     AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
2849     return kFALSE;
2850   }
2851      
2852   // read RecPoints
2853   fLoader[iDet]->LoadRecPoints("read");  
2854
2855   tracker->LoadClusters(fLoader[iDet]->TreeR());
2856   
2857   Int_t rv = tracker->Clusters2Tracks(esd);
2858   
2859   fLoader[iDet]->UnloadRecPoints();
2860
2861   tracker->UnloadClusters();
2862   
2863   if ( rv )
2864   {
2865     AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
2866     return kFALSE;
2867   }
2868   
2869   return kTRUE;
2870 }
2871
2872
2873 //_____________________________________________________________________________
2874 Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd,AliESDpid &PID)
2875 {
2876 // run the barrel tracking
2877   static Int_t eventNr=0;
2878   AliCodeTimerAuto("",0)
2879
2880   AliInfo("running tracking");
2881
2882   // Set the event info which is used
2883   // by the trackers in order to obtain
2884   // information about read-out detectors,
2885   // trigger etc.
2886   AliDebug(1, "Setting event info");
2887   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2888     if (!fTracker[iDet]) continue;
2889     fTracker[iDet]->SetEventInfo(&fEventInfo);
2890   }
2891
2892   //Fill the ESD with the T0 info (will be used by the TOF) 
2893   if (fReconstructor[11] && fLoader[11]) {
2894     fLoader[11]->LoadRecPoints("READ");
2895     TTree *treeR = fLoader[11]->TreeR();
2896     if (treeR) {
2897       GetReconstructor(11)->FillESD((TTree *)NULL,treeR,esd);
2898     }
2899   }
2900
2901   // pass 1: TPC + ITS inwards
2902   for (Int_t iDet = 1; iDet >= 0; iDet--) {
2903     if (!fTracker[iDet]) continue;
2904     AliDebug(1, Form("%s tracking", fgkDetectorName[iDet]));
2905
2906     // load clusters
2907     fLoader[iDet]->LoadRecPoints("read");
2908     AliSysInfo::AddStamp(Form("RLoadCluster%s_%d",fgkDetectorName[iDet],eventNr),iDet,1, eventNr);
2909     TTree* tree = fLoader[iDet]->TreeR();
2910     if (!tree) {
2911       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
2912       return kFALSE;
2913     }
2914     fTracker[iDet]->LoadClusters(tree);
2915     AliSysInfo::AddStamp(Form("TLoadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
2916     // run tracking
2917     if (fTracker[iDet]->Clusters2Tracks(esd) != 0) {
2918       AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
2919       return kFALSE;
2920     }
2921     AliSysInfo::AddStamp(Form("Tracking0%s_%d",fgkDetectorName[iDet],eventNr), iDet,3,eventNr);
2922     // preliminary PID in TPC needed by the ITS tracker
2923     if (iDet == 1) {
2924       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
2925       PID.MakePID(esd,kTRUE);
2926       AliSysInfo::AddStamp(Form("MakePID0%s_%d",fgkDetectorName[iDet],eventNr), iDet,4,eventNr);
2927     } 
2928   }
2929
2930   // pass 2: ALL backwards
2931
2932   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2933     if (!fTracker[iDet]) continue;
2934     AliDebug(1, Form("%s back propagation", fgkDetectorName[iDet]));
2935
2936     // load clusters
2937     if (iDet > 1) {     // all except ITS, TPC
2938       TTree* tree = NULL;
2939       fLoader[iDet]->LoadRecPoints("read");
2940       AliSysInfo::AddStamp(Form("RLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,1, eventNr);
2941       tree = fLoader[iDet]->TreeR();
2942       if (!tree) {
2943         AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
2944         return kFALSE;
2945       }
2946       fTracker[iDet]->LoadClusters(tree); 
2947       AliSysInfo::AddStamp(Form("TLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
2948     }
2949
2950     // run tracking
2951     if (iDet>1) // start filling residuals for the "outer" detectors
2952       if (fRunGlobalQA) {
2953         AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
2954         TObjArray ** arr = AliTracker::GetResidualsArray() ; 
2955         if (arr) {
2956           AliRecoParam::EventSpecie_t es=fRecoParam.GetEventSpecie();
2957           TObjArray * elem = arr[AliRecoParam::AConvert(es)];
2958           if ( elem && (! elem->At(0)) ) {
2959             AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
2960             if (qadm) qadm->InitRecPointsForTracker() ; 
2961           }
2962         }
2963         //      AliSysInfo::AddStamp(Form("QAInitResid%s_%d",fgkDetectorName[iDet],eventNr), iDet,0, eventNr);
2964       }
2965     if (fTracker[iDet]->PropagateBack(esd) != 0) {
2966       AliError(Form("%s backward propagation failed", fgkDetectorName[iDet]));
2967       //      return kFALSE;
2968     }
2969     AliSysInfo::AddStamp(Form("Tracking1%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
2970
2971     // unload clusters
2972     if (iDet > 3) {     // all except ITS, TPC, TRD and TOF
2973       fTracker[iDet]->UnloadClusters();
2974       fLoader[iDet]->UnloadRecPoints();
2975     }
2976     // updated PID in TPC needed by the ITS tracker -MI
2977     if (iDet == 1) {
2978       //GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
2979       //AliESDpid::MakePID(esd);
2980       PID.MakePID(esd,kTRUE);
2981       AliSysInfo::AddStamp(Form("MakePID1%s_%d",fgkDetectorName[iDet],eventNr), iDet,4,eventNr);
2982     }
2983
2984   }
2985   //stop filling residuals for the "outer" detectors
2986   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
2987
2988   // pass 3: TRD + TPC + ITS refit inwards
2989
2990   for (Int_t iDet = 2; iDet >= 0; iDet--) {
2991     if (!fTracker[iDet]) continue;
2992     AliDebug(1, Form("%s inward refit", fgkDetectorName[iDet]));
2993
2994     // run tracking
2995     if (iDet<2) // start filling residuals for TPC and ITS
2996       if (fRunGlobalQA) {
2997         AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
2998         TObjArray ** arr = AliTracker::GetResidualsArray() ; 
2999         if (arr) {
3000           AliRecoParam::EventSpecie_t es=fRecoParam.GetEventSpecie();
3001           TObjArray * elem = arr[AliRecoParam::AConvert(es)];
3002           if ( elem && (! elem->At(0)) ) {
3003             AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
3004             if (qadm) qadm->InitRecPointsForTracker() ; 
3005           }
3006         }
3007       }
3008     
3009     if (fTracker[iDet]->RefitInward(esd) != 0) {
3010       AliError(Form("%s inward refit failed", fgkDetectorName[iDet]));
3011       //      return kFALSE;
3012     }
3013     // run postprocessing
3014     if (fTracker[iDet]->PostProcess(esd) != 0) {
3015       AliError(Form("%s postprocessing failed", fgkDetectorName[iDet]));
3016       //      return kFALSE;
3017     }
3018     AliSysInfo::AddStamp(Form("Tracking2%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
3019   }
3020
3021   // write space-points to the ESD in case alignment data output
3022   // is switched on
3023   if (fWriteAlignmentData) {
3024     WriteAlignmentData(esd);
3025     AliSysInfo::AddStamp(Form("WrtAlignData_%d",eventNr), 0,0, eventNr);
3026   }
3027   
3028   for (Int_t iDet = 3; iDet >= 0; iDet--) {
3029     if (!fTracker[iDet]) continue;
3030     // unload clusters
3031     fTracker[iDet]->UnloadClusters();
3032     AliSysInfo::AddStamp(Form("TUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,4, eventNr);
3033     fLoader[iDet]->UnloadRecPoints();
3034     AliSysInfo::AddStamp(Form("RUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,5, eventNr);
3035   }
3036   // stop filling residuals for TPC and ITS
3037   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
3038
3039   eventNr++;
3040   return kTRUE;
3041 }
3042
3043 //_____________________________________________________________________________
3044 Bool_t AliReconstruction::CleanESD(AliESDEvent *esd){
3045   //
3046   // Remove the data which are not needed for the physics analysis.
3047   //
3048
3049   Int_t nTracks=esd->GetNumberOfTracks();
3050   Int_t nV0s=esd->GetNumberOfV0s();
3051   AliInfo
3052   (Form("Number of ESD tracks and V0s before cleaning: %d %d",nTracks,nV0s));
3053
3054   Float_t cleanPars[]={fV0DCAmax,fV0CsPmin,fDmax,fZmax};
3055   Bool_t rc=esd->Clean(cleanPars);
3056
3057   nTracks=esd->GetNumberOfTracks();
3058   nV0s=esd->GetNumberOfV0s();
3059   AliInfo
3060   (Form("Number of ESD tracks and V0s after cleaning %d %d",nTracks,nV0s));
3061
3062   return rc;
3063 }
3064
3065 //_____________________________________________________________________________
3066 Bool_t AliReconstruction::FillESD(AliESDEvent*& esd, const TString& detectors)
3067 {
3068 // fill the event summary data
3069
3070   AliCodeTimerAuto("",0)
3071     static Int_t eventNr=0; 
3072   TString detStr = detectors;
3073   
3074   AliSysInfo::AddStamp(Form("FillESDb%d",eventNr), -19,-19, eventNr);
3075   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3076   if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3077     AliReconstructor* reconstructor = GetReconstructor(iDet);
3078     if (!reconstructor) continue;
3079     AliDebug(1, Form("filling ESD for %s", fgkDetectorName[iDet]));
3080     TTree* clustersTree = NULL;
3081     if (fLoader[iDet]) {
3082       fLoader[iDet]->LoadRecPoints("read");
3083       clustersTree = fLoader[iDet]->TreeR();
3084       if (!clustersTree) {
3085         AliError(Form("Can't get the %s clusters tree", 
3086                       fgkDetectorName[iDet]));
3087         if (fStopOnError) return kFALSE;
3088       }
3089     }
3090     if (fRawReader && !reconstructor->HasDigitConversion()) {
3091       reconstructor->FillESD(fRawReader, clustersTree, esd);
3092     } else {
3093       TTree* digitsTree = NULL;
3094       if (fLoader[iDet]) {
3095         fLoader[iDet]->LoadDigits("read");
3096         digitsTree = fLoader[iDet]->TreeD();
3097         if (!digitsTree) {
3098           AliError(Form("Can't get the %s digits tree", 
3099                         fgkDetectorName[iDet]));
3100           if (fStopOnError) return kFALSE;
3101         }
3102       }
3103       reconstructor->FillESD(digitsTree, clustersTree, esd);
3104       if (fLoader[iDet]) fLoader[iDet]->UnloadDigits();
3105     }
3106     if (fLoader[iDet]) {
3107       fLoader[iDet]->UnloadRecPoints();
3108     }
3109   }
3110   
3111   if (!IsSelected("CTP", detStr)) AliDebug(10,"No CTP");
3112   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
3113     AliError(Form("the following detectors were not found: %s", 
3114                   detStr.Data()));
3115     if (fStopOnError) return kFALSE;
3116   }
3117   AliSysInfo::AddStamp(Form("FillESDe%d",eventNr), -20,-20, eventNr);
3118   eventNr++;
3119   return kTRUE;
3120 }
3121
3122 //_____________________________________________________________________________
3123 Bool_t AliReconstruction::FillTriggerESD(AliESDEvent*& esd)
3124 {
3125   // Reads the trigger decision which is
3126   // stored in Trigger.root file and fills
3127   // the corresponding esd entries
3128
3129   AliCodeTimerAuto("",0)
3130   
3131   AliInfo("Filling trigger information into the ESD");
3132
3133   if (fRawReader) {
3134     AliCTPRawStream input(fRawReader);
3135     if (!input.Next()) {
3136       AliWarning("No valid CTP (trigger) DDL raw data is found ! The trigger info is taken from the event header!");
3137     }
3138     else {
3139       if (esd->GetTriggerMask() != input.GetClassMask())
3140         AliError(Form("Invalid trigger pattern found in CTP raw-data: %llx %llx",
3141                       input.GetClassMask(),esd->GetTriggerMask()));
3142       if (esd->GetOrbitNumber() != input.GetOrbitID())
3143         AliError(Form("Invalid orbit id found in CTP raw-data: %x %x",
3144                       input.GetOrbitID(),esd->GetOrbitNumber()));
3145       if (esd->GetBunchCrossNumber() != input.GetBCID())
3146         AliError(Form("Invalid bunch-crossing id found in CTP raw-data: %x %x",
3147                       input.GetBCID(),esd->GetBunchCrossNumber()));
3148       AliESDHeader* esdheader = esd->GetHeader();
3149       esdheader->SetL0TriggerInputs(input.GetL0Inputs());
3150       esdheader->SetL1TriggerInputs(input.GetL1Inputs());
3151       esdheader->SetL2TriggerInputs(input.GetL2Inputs());
3152       // IR
3153       //      UInt_t orbit=input.GetOrbitID();
3154       for(Int_t i=0 ; i<input.GetNIRs() ; i++ ) {
3155         esdheader->AddTriggerIR(input.GetIR(i));
3156       }
3157        AliCentralTrigger* rlCTP = fRunLoader->GetTrigger();
3158        rlCTP->SetL0TriggerInputs(input.GetL0Inputs());
3159        rlCTP->SetL1TriggerInputs(input.GetL1Inputs());
3160        rlCTP->SetL2TriggerInputs(input.GetL2Inputs());
3161     }
3162     if (fIsNewRunLoader) fRunLoader->TreeCT()->Fill();
3163   }
3164   return kTRUE;
3165 }
3166 //_____________________________________________________________________________
3167 Bool_t AliReconstruction::FillTriggerScalers(AliESDEvent*& esd)
3168 {
3169   //Scalers
3170   //fRunScalers->Print();
3171   if(fRunScalers && fRunScalers->CheckRunScalers()){
3172      AliTimeStamp* timestamp = new AliTimeStamp(esd->GetOrbitNumber(), esd->GetPeriodNumber(), esd->GetBunchCrossNumber());
3173      //AliTimeStamp* timestamp = new AliTimeStamp(10308000, 0, (ULong64_t)486238);
3174      AliESDHeader* esdheader = fesd->GetHeader();
3175      for(Int_t i=0;i<50;i++){
3176           if((1ull<<i) & esd->GetTriggerMask()){
3177           AliTriggerScalersESD* scalesd = fRunScalers->GetScalersForEventClass( timestamp, i+1);
3178           if(scalesd)esdheader->SetTriggerScalersRecord(scalesd);
3179         }
3180      }
3181      const AliTriggerScalersRecordESD* scalrecEvent = fRunScalers->GetScalersDeltaForEvent( timestamp);
3182      const AliTriggerScalersRecordESD* scalrecRun = fRunScalers->GetScalersDeltaForRun();
3183      if (scalrecEvent) esdheader->SetTriggerScalersDeltaEvent(scalrecEvent);
3184      if (scalrecRun) esdheader->SetTriggerScalersDeltaRun(scalrecRun);
3185   }
3186   return kTRUE;
3187 }
3188 //_____________________________________________________________________________
3189 Bool_t AliReconstruction::FillRawEventHeaderESD(AliESDEvent*& esd)
3190 {
3191   // 
3192   // Filling information from RawReader Header
3193   // 
3194
3195   if (!fRawReader) return kFALSE;
3196
3197   AliInfo("Filling information from RawReader Header");
3198
3199   esd->SetBunchCrossNumber(fRawReader->GetBCID());
3200   esd->SetOrbitNumber(fRawReader->GetOrbitID());
3201   esd->SetPeriodNumber(fRawReader->GetPeriod());
3202
3203   esd->SetTimeStamp(fRawReader->GetTimestamp());  
3204   esd->SetEventType(fRawReader->GetType());
3205
3206   return kTRUE;
3207 }
3208
3209
3210 //_____________________________________________________________________________
3211 Bool_t AliReconstruction::IsSelected(TString detName, TString& detectors) const
3212 {
3213 // check whether detName is contained in detectors
3214 // if yes, it is removed from detectors
3215
3216   // check if all detectors are selected
3217   if ((detectors.CompareTo("ALL") == 0) ||
3218       detectors.BeginsWith("ALL ") ||
3219       detectors.EndsWith(" ALL") ||
3220       detectors.Contains(" ALL ")) {
3221     detectors = "ALL";
3222     return kTRUE;
3223   }
3224
3225   // search for the given detector
3226   Bool_t result = kFALSE;
3227   if ((detectors.CompareTo(detName) == 0) ||
3228       detectors.BeginsWith(detName+" ") ||
3229       detectors.EndsWith(" "+detName) ||
3230       detectors.Contains(" "+detName+" ")) {
3231     detectors.ReplaceAll(detName, "");
3232     result = kTRUE;
3233   }
3234
3235   // clean up the detectors string
3236   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
3237   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
3238   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
3239
3240   return result;
3241 }
3242
3243 //_____________________________________________________________________________
3244 Bool_t AliReconstruction::InitRunLoader()
3245 {
3246 // get or create the run loader
3247
3248   if (gAlice) delete gAlice;
3249   gAlice = NULL;
3250
3251   TFile *gafile = TFile::Open(fGAliceFileName.Data());
3252   //  if (!gSystem->AccessPathName(fGAliceFileName.Data())) { // galice.root exists
3253   if (gafile) { // galice.root exists
3254     gafile->Close();
3255     delete gafile;
3256
3257     // load all base libraries to get the loader classes
3258     TString libs = gSystem->GetLibraries();
3259     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3260       TString detName = fgkDetectorName[iDet];
3261       if (detName == "HLT") continue;
3262       if (libs.Contains("lib" + detName + "base.so")) continue;
3263       gSystem->Load("lib" + detName + "base.so");
3264     }
3265     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data());
3266     if (!fRunLoader) {
3267       AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
3268       CleanUp();
3269       return kFALSE;
3270     }
3271
3272     fRunLoader->CdGAFile();
3273     fRunLoader->LoadgAlice();
3274
3275     //PH This is a temporary fix to give access to the kinematics
3276     //PH that is needed for the labels of ITS clusters
3277     fRunLoader->LoadHeader();
3278     fRunLoader->LoadKinematics();
3279
3280   } else {               // galice.root does not exist
3281     if (!fRawReader) {
3282       AliError(Form("the file %s does not exist", fGAliceFileName.Data()));
3283     }
3284     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data(),
3285                                     AliConfig::GetDefaultEventFolderName(),
3286                                     "recreate");
3287     if (!fRunLoader) {
3288       AliError(Form("could not create run loader in file %s", 
3289                     fGAliceFileName.Data()));
3290       CleanUp();
3291       return kFALSE;
3292     }
3293     fIsNewRunLoader = kTRUE;
3294     fRunLoader->MakeTree("E");
3295     fRunLoader->MakeTree("GG");
3296
3297     if (fNumberOfEventsPerFile > 0)
3298       fRunLoader->SetNumberOfEventsPerFile(fNumberOfEventsPerFile);
3299     else
3300       fRunLoader->SetNumberOfEventsPerFile((UInt_t)-1);
3301   }
3302
3303   return kTRUE;
3304 }
3305
3306 //_____________________________________________________________________________
3307 AliReconstructor* AliReconstruction::GetReconstructor(Int_t iDet)
3308 {
3309 // get the reconstructor object and the loader for a detector
3310
3311   if (fReconstructor[iDet]) {
3312     if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
3313       const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
3314       fReconstructor[iDet]->SetRecoParam(par);
3315       fReconstructor[iDet]->SetRunInfo(fRunInfo);
3316     }
3317     return fReconstructor[iDet];
3318   }
3319
3320   // load the reconstructor object
3321   TPluginManager* pluginManager = gROOT->GetPluginManager();
3322   TString detName = fgkDetectorName[iDet];
3323   TString recName = "Ali" + detName + "Reconstructor";
3324
3325   if (!fIsNewRunLoader && !fRunLoader->GetLoader(detName+"Loader") && (detName != "HLT")) return NULL;
3326
3327   AliReconstructor* reconstructor = NULL;
3328   // first check if a plugin is defined for the reconstructor
3329   TPluginHandler* pluginHandler = 
3330     pluginManager->FindHandler("AliReconstructor", detName);
3331   // if not, add a plugin for it
3332   if (!pluginHandler) {
3333     AliDebug(1, Form("defining plugin for %s", recName.Data()));
3334     TString libs = gSystem->GetLibraries();
3335     if (libs.Contains("lib" + detName + "base.so") ||
3336         (gSystem->Load("lib" + detName + "base.so") >= 0)) {
3337       pluginManager->AddHandler("AliReconstructor", detName, 
3338                                 recName, detName + "rec", recName + "()");
3339     } else {
3340       pluginManager->AddHandler("AliReconstructor", detName, 
3341                                 recName, detName, recName + "()");
3342     }
3343     pluginHandler = pluginManager->FindHandler("AliReconstructor", detName);
3344   }
3345   if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
3346     reconstructor = (AliReconstructor*) pluginHandler->ExecPlugin(0);
3347   }
3348
3349    // check if the upgrade reconstructor should be used instead of the standard one
3350   if(fUpgradeMask[iDet]) {
3351     if(reconstructor) delete reconstructor;
3352     TClass *cl = new TClass(Form("Ali%sUpgradeReconstructor",fgkDetectorName[iDet]));
3353     reconstructor = (AliReconstructor*)(cl->New());
3354    }
3355
3356   if (reconstructor) {
3357     TObject* obj = fOptions.FindObject(detName.Data());
3358     if (obj) reconstructor->SetOption(obj->GetTitle());
3359     reconstructor->SetRunInfo(fRunInfo);
3360     reconstructor->Init();
3361     fReconstructor[iDet] = reconstructor;
3362   }
3363
3364   // get or create the loader
3365   if (detName != "HLT") {
3366     fLoader[iDet] = fRunLoader->GetLoader(detName + "Loader");
3367     if (!fLoader[iDet]) {
3368       AliConfig::Instance()
3369         ->CreateDetectorFolders(fRunLoader->GetEventFolder(), 
3370                                 detName, detName);
3371       // first check if a plugin is defined for the loader
3372       pluginHandler = 
3373         pluginManager->FindHandler("AliLoader", detName);
3374       // if not, add a plugin for it
3375       if (!pluginHandler) {
3376         TString loaderName = "Ali" + detName + "Loader";
3377         AliDebug(1, Form("defining plugin for %s", loaderName.Data()));
3378         pluginManager->AddHandler("AliLoader", detName, 
3379                                   loaderName, detName + "base", 
3380                                   loaderName + "(const char*, TFolder*)");
3381         pluginHandler = pluginManager->FindHandler("AliLoader", detName);
3382       }
3383       if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
3384         fLoader[iDet] = 
3385           (AliLoader*) pluginHandler->ExecPlugin(2, detName.Data(), 
3386                                                  fRunLoader->GetEventFolder());
3387       }
3388       if (!fLoader[iDet]) {   // use default loader
3389         fLoader[iDet] = new AliLoader(detName, fRunLoader->GetEventFolder());
3390       }
3391       if (!fLoader[iDet]) {
3392         AliWarning(Form("couldn't get loader for %s", detName.Data()));
3393         if (fStopOnError) return NULL;
3394       } else {
3395         fRunLoader->AddLoader(fLoader[iDet]);
3396         fRunLoader->CdGAFile();
3397         if (gFile && !gFile->IsWritable()) gFile->ReOpen("UPDATE");
3398         fRunLoader->Write(0, TObject::kOverwrite);
3399       }
3400     }
3401   }
3402       
3403   if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
3404     const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
3405     if (reconstructor) {
3406       reconstructor->SetRecoParam(par);
3407       reconstructor->SetRunInfo(fRunInfo);
3408     }
3409   }
3410   return reconstructor;
3411 }
3412
3413 //_____________________________________________________________________________
3414 AliVertexer* AliReconstruction::CreateVertexer()
3415 {
3416 // create the vertexer
3417 // Please note that the caller is the owner of the
3418 // vertexer
3419
3420   AliVertexer* vertexer = NULL;
3421   AliReconstructor* itsReconstructor = GetReconstructor(0);
3422   if (itsReconstructor && ((fRunLocalReconstruction.Contains("ITS")) || 
3423                            fRunTracking.Contains("ITS") || fFillESD.Contains("ITS") )) {
3424     vertexer = itsReconstructor->CreateVertexer();
3425   }
3426   if (!vertexer) {
3427     AliWarning("couldn't create a vertexer for ITS");
3428   }
3429
3430   return vertexer;
3431 }
3432
3433 //_____________________________________________________________________________
3434 AliTrackleter* AliReconstruction::CreateMultFinder()
3435 {
3436 // create the ITS trackleter for mult. estimation
3437 // Please note that the caller is the owner of the
3438 // trackleter
3439
3440   AliTrackleter* trackleter = NULL;
3441   AliReconstructor* itsReconstructor = GetReconstructor(0);
3442   if (itsReconstructor && ((fRunLocalReconstruction.Contains("ITS")) || 
3443                            fRunTracking.Contains("ITS") || fFillESD.Contains("ITS") )) {
3444     trackleter = itsReconstructor->CreateMultFinder();
3445   }
3446   else {
3447     AliWarning("ITS is not in reconstruction, switching off RunMultFinder");
3448     fRunMultFinder = kFALSE;
3449   }
3450
3451   return trackleter;
3452 }
3453
3454 //_____________________________________________________________________________
3455 Bool_t AliReconstruction::CreateTrackers(const TString& detectors)
3456 {
3457 // create the trackers
3458         AliInfo("Creating trackers");
3459
3460   TString detStr = detectors;
3461   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3462     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3463     AliReconstructor* reconstructor = GetReconstructor(iDet);
3464     if (!reconstructor) continue;
3465     TString detName = fgkDetectorName[iDet];
3466     if (detName == "HLT") {
3467       fRunHLTTracking = kTRUE;
3468       continue;
3469     }
3470     if (detName == "MUON") {
3471       fRunMuonTracking = kTRUE;
3472       continue;
3473     }
3474
3475     fTracker[iDet] = reconstructor->CreateTracker();
3476     if (!fTracker[iDet] && (iDet < 7)) {
3477       AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
3478       if (fStopOnError) return kFALSE;
3479     }
3480     AliSysInfo::AddStamp(Form("LTracker%s",fgkDetectorName[iDet]), iDet,0);
3481   }
3482
3483   return kTRUE;
3484 }
3485
3486 //_____________________________________________________________________________
3487 void AliReconstruction::CleanUp()
3488 {
3489 // delete trackers and the run loader and close and delete the file
3490 /*
3491   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3492     delete fReconstructor[iDet];
3493     fReconstructor[iDet] = NULL;
3494     fLoader[iDet] = NULL;
3495     delete fTracker[iDet];
3496     fTracker[iDet] = NULL;
3497   }
3498 */
3499
3500   delete fRunInfo;
3501   fRunInfo = NULL;
3502
3503   delete fSPDTrackleter;
3504   fSPDTrackleter = NULL;
3505
3506   delete ftVertexer;
3507   ftVertexer = NULL;
3508   
3509   delete fRunLoader;
3510   fRunLoader = NULL;
3511   delete fRawReader;
3512   fRawReader = NULL;
3513   delete fParentRawReader;
3514   fParentRawReader=NULL;
3515
3516   if (ffile) {
3517     ffile->Close();
3518     delete ffile;
3519     ffile = NULL;
3520   }
3521
3522   if (AliQAManager::QAManager())
3523     AliQAManager::QAManager()->ShowQA() ; 
3524   //  AliQAManager::Destroy() ;
3525   delete fAnalysis; 
3526   fAnalysis = NULL;
3527 }
3528
3529 void AliReconstruction::WriteAlignmentData(AliESDEvent* esd)
3530 {
3531   // Write space-points which are then used in the alignment procedures
3532   // For the moment only ITS, TPC, TRD and TOF
3533
3534   Int_t ntracks = esd->GetNumberOfTracks();
3535   for (Int_t itrack = 0; itrack < ntracks; itrack++)
3536     {
3537       AliESDtrack *track = esd->GetTrack(itrack);
3538       Int_t nsp = 0;
3539       Int_t idx[200];
3540       for (Int_t i=0; i<200; ++i) idx[i] = -1; //PH avoid uninitialized values
3541       for (Int_t iDet = 5; iDet >= 0; iDet--) {// TOF, TRD, TPC, ITS clusters
3542           nsp += (iDet==GetDetIndex("TRD")) ? track->GetTRDntracklets():track->GetNcls(iDet);
3543
3544           if (iDet==GetDetIndex("ITS")) { // ITS "extra" clusters
3545              track->GetClusters(iDet,idx);
3546              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nsp++;
3547           }  
3548       }
3549
3550       if (nsp) {
3551         AliTrackPointArray *sp = new AliTrackPointArray(nsp);
3552         track->SetTrackPointArray(sp);
3553         Int_t isptrack = 0;
3554         for (Int_t iDet = 5; iDet >= 0; iDet--) {
3555           AliTracker *tracker = fTracker[iDet];
3556           if (!tracker) continue;
3557           Int_t nspdet = (iDet==GetDetIndex("TRD")) ? track->GetTRDtracklets(idx):track->GetClusters(iDet,idx);
3558
3559           if (iDet==GetDetIndex("ITS")) // ITS "extra" clusters             
3560              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nspdet++;
3561
3562           if (nspdet <= 0) continue;
3563           AliTrackPoint p;
3564           Int_t isp = 0;
3565           Int_t isp2 = 0;
3566           while (isp2 < nspdet) {
3567             Bool_t isvalid=kTRUE;
3568
3569             Int_t index=idx[isp++];
3570             if (index < 0) continue;
3571
3572             TString dets = fgkDetectorName[iDet];
3573             if ((fUseTrackingErrorsForAlignment.CompareTo(dets) == 0) ||
3574             fUseTrackingErrorsForAlignment.BeginsWith(dets+" ") ||
3575             fUseTrackingErrorsForAlignment.EndsWith(" "+dets) ||
3576             fUseTrackingErrorsForAlignment.Contains(" "+dets+" ")) {
3577               isvalid = tracker->GetTrackPointTrackingError(index,p,track);
3578             } else {
3579               isvalid = tracker->GetTrackPoint(index,p); 
3580             } 
3581             isp2++;
3582             if (!isvalid) continue;
3583             if (iDet==GetDetIndex("ITS") && (isp-1)>=6) p.SetExtra();
3584             sp->AddPoint(isptrack,&p); isptrack++;
3585           }
3586         }       
3587       }
3588     }
3589 }
3590
3591 //_____________________________________________________________________________
3592 void AliReconstruction::FillRawDataErrorLog(Int_t iEvent, AliESDEvent* esd)
3593 {
3594   // The method reads the raw-data error log
3595   // accumulated within the rawReader.
3596   // It extracts the raw-data errors related to
3597   // the current event and stores them into
3598   // a TClonesArray inside the esd object.
3599
3600   if (!fRawReader) return;
3601
3602   for(Int_t i = 0; i < fRawReader->GetNumberOfErrorLogs(); i++) {
3603
3604     AliRawDataErrorLog *log = fRawReader->GetErrorLog(i);
3605     if (!log) continue;
3606     if (iEvent != log->GetEventNumber()) continue;
3607
3608     esd->AddRawDataErrorLog(log);
3609   }
3610
3611 }
3612
3613 //_____________________________________________________________________________
3614 // void AliReconstruction::CheckQA()
3615 // {
3616 // check the QA of SIM for this run and remove the detectors 
3617 // with status Fatal
3618   
3619 //      TString newRunLocalReconstruction ; 
3620 //      TString newRunTracking ;
3621 //      TString newFillESD ;
3622 //       
3623 //      for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
3624 //              TString detName(AliQAv1::GetDetName(iDet)) ;
3625 //              AliQAv1 * qa = AliQAv1::Instance(AliQAv1::DETECTORINDEX_t(iDet)) ;       
3626 //      if ( qa->IsSet(AliQAv1::DETECTORINDEX_t(iDet), AliQAv1::kSIM, specie, AliQAv1::kFATAL)) {
3627 //        AliInfo(Form("QA status for %s %s in Hits and/or SDIGITS  and/or Digits was Fatal; No reconstruction performed", 
3628 //                   detName.Data(), AliRecoParam::GetEventSpecieName(es))) ;
3629 //                      } else {
3630 //                      if ( fRunLocalReconstruction.Contains(AliQAv1::GetDetName(iDet)) || 
3631 //                                      fRunLocalReconstruction.Contains("ALL") )  {
3632 //                              newRunLocalReconstruction += detName ; 
3633 //                              newRunLocalReconstruction += " " ;                      
3634 //                      }
3635 //                      if ( fRunTracking.Contains(AliQAv1::GetDetName(iDet)) || 
3636 //                                      fRunTracking.Contains("ALL") )  {
3637 //                              newRunTracking += detName ; 
3638 //                              newRunTracking += " " ;                         
3639 //                      }
3640 //                      if ( fFillESD.Contains(AliQAv1::GetDetName(iDet)) || 
3641 //                                      fFillESD.Contains("ALL") )  {
3642 //                              newFillESD += detName ; 
3643 //                              newFillESD += " " ;                     
3644 //                      }
3645 //              }
3646 //      }
3647 //      fRunLocalReconstruction = newRunLocalReconstruction ; 
3648 //      fRunTracking            = newRunTracking ; 
3649 //      fFillESD                = newFillESD ; 
3650 // }
3651
3652 //_____________________________________________________________________________
3653 Int_t AliReconstruction::GetDetIndex(const char* detector)
3654 {
3655   // return the detector index corresponding to detector
3656   Int_t index = -1 ; 
3657   for (index = 0; index < kNDetectors ; index++) {
3658     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
3659         break ; 
3660   }     
3661   return index ; 
3662 }
3663 //_____________________________________________________________________________
3664 Bool_t AliReconstruction::FinishPlaneEff() {
3665  //
3666  // Here execute all the necessary operationis, at the end of the tracking phase,
3667  // in case that evaluation of PlaneEfficiencies was required for some detector.
3668  // E.g., write into a DataBase file the PlaneEfficiency which have been evaluated.
3669  //
3670  // This Preliminary version works only FOR ITS !!!!!
3671  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3672  //
3673  //  Input: none
3674  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3675  //
3676  Bool_t ret=kFALSE;
3677  TString detStr = fLoadCDB;
3678  //for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
3679  for (Int_t iDet = 0; iDet < 1; iDet++) { // for the time being only ITS
3680    if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3681    if(fTracker[iDet] && fTracker[iDet]->GetPlaneEff()) {
3682       AliPlaneEff *planeeff=fTracker[iDet]->GetPlaneEff();
3683       TString name=planeeff->GetName();
3684       name+=".root";
3685       TFile* pefile = TFile::Open(name, "RECREATE");
3686       ret=(Bool_t)planeeff->Write();
3687       pefile->Close();
3688       if(planeeff->GetCreateHistos()) {
3689         TString hname=planeeff->GetName();
3690         hname+="Histo.root";
3691         ret*=planeeff->WriteHistosToFile(hname,"RECREATE");
3692       }
3693    }
3694    if(fSPDTrackleter) {
3695      AliPlaneEff *planeeff=fSPDTrackleter->GetPlaneEff();
3696       TString name="AliITSPlaneEffSPDtracklet.root";
3697       TFile* pefile = TFile::Open(name, "RECREATE");
3698       ret=(Bool_t)planeeff->Write();
3699       pefile->Close();
3700       AliESDEvent *dummy=NULL;
3701       ret=(Bool_t)fSPDTrackleter->PostProcess(dummy); // take care of writing other files
3702    }
3703  }
3704  return ret;
3705 }
3706 //_____________________________________________________________________________
3707 Bool_t AliReconstruction::InitPlaneEff() {
3708 //
3709  // Here execute all the necessary operations, before of the tracking phase,
3710  // for the evaluation of PlaneEfficiencies, in case required for some detectors.
3711  // E.g., read from a DataBase file a first evaluation of the PlaneEfficiency
3712  // which should be updated/recalculated.
3713  //
3714  // This Preliminary version will work only FOR ITS !!!!!
3715  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3716  //
3717  //  Input: none
3718  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3719  //
3720
3721   fSPDTrackleter = NULL;
3722   TString detStr = fLoadCDB;
3723   if (IsSelected(fgkDetectorName[0], detStr)) {
3724     AliReconstructor* itsReconstructor = GetReconstructor(0);
3725     if (itsReconstructor) {
3726       fSPDTrackleter = itsReconstructor->CreateTrackleter(); // this is NULL unless required in RecoParam
3727     }
3728     if (fSPDTrackleter) {
3729       AliInfo("Trackleter for SPD has been created");
3730     }
3731   }
3732  return kTRUE;
3733 }
3734
3735 //_____________________________________________________________________________
3736 Bool_t AliReconstruction::InitAliEVE()
3737 {
3738   // This method should be called only in case 
3739   // AliReconstruction is run
3740   // within the alieve environment.
3741   // It will initialize AliEVE in a way
3742   // so that it can visualize event processed
3743   // by AliReconstruction.
3744   // The return flag shows whenever the
3745   // AliEVE initialization was successful or not.
3746
3747   TString macroStr(gSystem->Getenv("ALIEVE_ONLINE_MACRO"));
3748
3749   if (macroStr.IsNull())
3750     macroStr.Form("%s/EVE/macros/alieve_online.C",gSystem->ExpandPathName("$ALICE_ROOT"));
3751
3752   AliInfo(Form("Loading AliEVE macro: %s",macroStr.Data()));
3753
3754   if (gROOT->LoadMacro(macroStr.Data()) != 0) return kFALSE;
3755
3756   gROOT->ProcessLine("if (!AliEveEventManager::GetMaster()){new AliEveEventManager();AliEveEventManager::GetMaster()->AddNewEventCommand(\"alieve_online_on_new_event()\");gEve->AddEvent(AliEveEventManager::GetMaster());};");
3757   gROOT->ProcessLine("alieve_online_init()");
3758
3759   return kTRUE;
3760 }
3761   
3762 //_____________________________________________________________________________
3763 void AliReconstruction::RunAliEVE()
3764 {
3765   // Runs AliEVE visualisation of
3766   // the current event.
3767   // Should be executed only after
3768   // successful initialization of AliEVE.
3769
3770   AliInfo("Running AliEVE...");
3771   gROOT->ProcessLine(Form("AliEveEventManager::GetMaster()->SetEvent((AliRunLoader*)%p,(AliRawReader*)%p,(AliESDEvent*)%p,(AliESDfriend*)%p);",fRunLoader,fRawReader,fesd,fesdf));
3772   gSystem->Run();
3773 }
3774
3775 //_____________________________________________________________________________
3776 Bool_t AliReconstruction::SetRunQA(TString detAndAction) 
3777 {
3778         // Allows to run QA for a selected set of detectors
3779         // and a selected set of tasks among RAWS, DIGITSR, RECPOINTS and ESDS
3780         // all selected detectors run the same selected tasks
3781         
3782         if (!detAndAction.Contains(":")) {
3783                 AliError( Form("%s is a wrong syntax, use \"DetectorList:ActionList\" \n", detAndAction.Data()) ) ;
3784                 fRunQA = kFALSE ;
3785                 return kFALSE ;                 
3786         }
3787         Int_t colon = detAndAction.Index(":") ; 
3788         fQADetectors = detAndAction(0, colon) ; 
3789         fQATasks   = detAndAction(colon+1, detAndAction.Sizeof() ) ; 
3790         if (fQATasks.Contains("ALL") ) {
3791                 fQATasks = Form("%d %d %d %d", AliQAv1::kRAWS, AliQAv1::kDIGITSR, AliQAv1::kRECPOINTS, AliQAv1::kESDS) ; 
3792         } else {
3793                 fQATasks.ToUpper() ; 
3794                 TString tempo("") ; 
3795                 if ( fQATasks.Contains("RAW") ) 
3796                         tempo = Form("%d ", AliQAv1::kRAWS) ; 
3797                 if ( fQATasks.Contains("DIGIT") ) 
3798                         tempo += Form("%d ", AliQAv1::kDIGITSR) ; 
3799                 if ( fQATasks.Contains("RECPOINT") ) 
3800                         tempo += Form("%d ", AliQAv1::kRECPOINTS) ; 
3801                 if ( fQATasks.Contains("ESD") ) 
3802                         tempo += Form("%d ", AliQAv1::kESDS) ; 
3803                 fQATasks = tempo ; 
3804                 if (fQATasks.IsNull()) {
3805                         AliInfo("No QA requested\n")  ;
3806                         fRunQA = kFALSE ;
3807                         return kTRUE ; 
3808                 }
3809         }       
3810         TString tempo(fQATasks) ; 
3811         tempo.ReplaceAll(Form("%d", AliQAv1::kRAWS), AliQAv1::GetTaskName(AliQAv1::kRAWS))      ;
3812         tempo.ReplaceAll(Form("%d", AliQAv1::kDIGITSR), AliQAv1::GetTaskName(AliQAv1::kDIGITSR)) ;      
3813         tempo.ReplaceAll(Form("%d", AliQAv1::kRECPOINTS), AliQAv1::GetTaskName(AliQAv1::kRECPOINTS)) ;  
3814         tempo.ReplaceAll(Form("%d", AliQAv1::kESDS), AliQAv1::GetTaskName(AliQAv1::kESDS)) ;    
3815         AliInfo( Form("QA will be done on \"%s\" for \"%s\"\n", fQADetectors.Data(), tempo.Data()) ) ;  
3816         fRunQA = kTRUE ;
3817         return kTRUE; 
3818
3819
3820 //_____________________________________________________________________________
3821 Bool_t AliReconstruction::InitRecoParams() 
3822 {
3823   // The method accesses OCDB and retrieves all
3824   // the available reco-param objects from there.
3825
3826   Bool_t isOK = kTRUE;
3827
3828   if (fRecoParam.GetDetRecoParamArray(kNDetectors)) {
3829     AliInfo("Using custom GRP reconstruction parameters");
3830   }
3831   else {
3832     AliInfo("Loading GRP reconstruction parameter objects");
3833
3834     AliCDBPath path("GRP","Calib","RecoParam");
3835     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
3836     if(!entry){ 
3837       AliWarning("Couldn't find GRP RecoParam entry in OCDB");
3838       isOK = kFALSE;
3839     }
3840     else {
3841       TObject *recoParamObj = entry->GetObject();
3842       if (dynamic_cast<TObjArray*>(recoParamObj)) {
3843         // GRP has a normal TobjArray of AliDetectorRecoParam objects
3844         // Registering them in AliRecoParam
3845         fRecoParam.AddDetRecoParamArray(kNDetectors,dynamic_cast<TObjArray*>(recoParamObj));
3846       }
3847       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
3848         // GRP has only onse set of reco parameters
3849         // Registering it in AliRecoParam
3850         AliInfo("Single set of GRP reconstruction parameters found");
3851         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
3852         fRecoParam.AddDetRecoParam(kNDetectors,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
3853       }
3854       else {
3855         AliError("No valid GRP RecoParam object found in the OCDB");
3856         isOK = kFALSE;
3857       }
3858       entry->SetOwner(0);
3859     }
3860   }
3861
3862   TString detStr = fLoadCDB;
3863   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3864
3865     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3866
3867     if (fRecoParam.GetDetRecoParamArray(iDet)) {
3868       AliInfo(Form("Using custom reconstruction parameters for detector %s",fgkDetectorName[iDet]));
3869       continue;
3870     }
3871
3872     AliInfo(Form("Loading reconstruction parameter objects for detector %s",fgkDetectorName[iDet]));
3873   
3874     AliCDBPath path(fgkDetectorName[iDet],"Calib","RecoParam");
3875     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
3876     if(!entry){ 
3877       AliWarning(Form("Couldn't find RecoParam entry in OCDB for detector %s",fgkDetectorName[iDet]));
3878       isOK = kFALSE;
3879     }
3880     else {
3881       TObject *recoParamObj = entry->GetObject();
3882       if (dynamic_cast<TObjArray*>(recoParamObj)) {
3883         // The detector has a normal TobjArray of AliDetectorRecoParam objects
3884         // Registering them in AliRecoParam
3885         fRecoParam.AddDetRecoParamArray(iDet,dynamic_cast<TObjArray*>(recoParamObj));
3886       }
3887       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
3888         // The detector has only onse set of reco parameters
3889         // Registering it in AliRecoParam
3890         AliInfo(Form("Single set of reconstruction parameters found for detector %s",fgkDetectorName[iDet]));
3891         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
3892         fRecoParam.AddDetRecoParam(iDet,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
3893       }
3894       else {
3895         AliError(Form("No valid RecoParam object found in the OCDB for detector %s",fgkDetectorName[iDet]));
3896         isOK = kFALSE;
3897       }
3898       entry->SetOwner(0);
3899       //      FIX ME: We have to disable the unloading of reco-param CDB
3900       //      entries because QA framework is using them. Has to be fix in
3901       //      a way that the QA takes the objects already constructed in
3902       //      this method.
3903       //      AliCDBManager::Instance()->UnloadFromCache(path.GetPath());
3904     }
3905   }
3906
3907   if (AliDebugLevel() > 0) fRecoParam.Print();
3908
3909   return isOK;
3910 }
3911
3912 //_____________________________________________________________________________
3913 Bool_t AliReconstruction::GetEventInfo() 
3914 {
3915   // Fill the event info object
3916   // ...
3917   AliCodeTimerAuto("",0)
3918
3919   AliCentralTrigger *aCTP = NULL;
3920   if (fRawReader) {
3921     fEventInfo.SetEventType(fRawReader->GetType());
3922
3923     ULong64_t mask = fRawReader->GetClassMask();
3924     fEventInfo.SetTriggerMask(mask);
3925     UInt_t clmask = fRawReader->GetDetectorPattern()[0];
3926     fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(clmask));
3927
3928     aCTP = new AliCentralTrigger();
3929     TString configstr("");
3930     if (!aCTP->LoadConfiguration(configstr)) { // Load CTP config from OCDB
3931       AliError("No trigger configuration found in OCDB! The trigger configuration information will not be used!");
3932       delete aCTP;
3933       return kFALSE;
3934     }
3935     aCTP->SetClassMask(mask);
3936     aCTP->SetClusterMask(clmask);
3937
3938     AliCentralTrigger* rlCTP = fRunLoader->GetTrigger();
3939     rlCTP->SetClassMask(mask);
3940     rlCTP->SetClusterMask(clmask);
3941   }
3942   else {
3943     fEventInfo.SetEventType(AliRawEventHeaderBase::kPhysicsEvent);
3944
3945     if (fRunLoader && (!fRunLoader->LoadTrigger())) {
3946       aCTP = fRunLoader->GetTrigger();
3947       fEventInfo.SetTriggerMask(aCTP->GetClassMask());
3948       // get inputs from actp - just get
3949       AliESDHeader* esdheader = fesd->GetHeader();
3950       esdheader->SetL0TriggerInputs(aCTP->GetL0TriggerInputs());
3951       esdheader->SetL1TriggerInputs(aCTP->GetL1TriggerInputs());
3952       esdheader->SetL2TriggerInputs(aCTP->GetL2TriggerInputs());
3953       fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(aCTP->GetClusterMask()));
3954     }
3955     else {
3956       AliWarning("No trigger can be loaded! The trigger information will not be used!");
3957       return kFALSE;
3958     }
3959   }
3960
3961   AliTriggerConfiguration *config = aCTP->GetConfiguration();
3962   if (!config) {
3963     AliError("No trigger configuration has been found! The trigger configuration information will not be used!");
3964     if (fRawReader) delete aCTP;
3965     return kFALSE;
3966   }
3967
3968   UChar_t clustmask = 0;
3969   TString trclasses;
3970   ULong64_t trmask = fEventInfo.GetTriggerMask();
3971   const TObjArray& classesArray = config->GetClasses();
3972   Int_t nclasses = classesArray.GetEntriesFast();
3973   for( Int_t iclass=0; iclass < nclasses; iclass++ ) {
3974     AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At(iclass);
3975     if (trclass && trclass->GetMask()>0) {
3976       Int_t trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
3977       fesd->SetTriggerClass(trclass->GetName(),trindex);
3978       if (fRawReader) fRawReader->LoadTriggerClass(trclass->GetName(),trindex);
3979       if (trmask & (1ull << trindex)) {
3980         trclasses += " ";
3981         trclasses += trclass->GetName();
3982         trclasses += " ";
3983         clustmask |= trclass->GetCluster()->GetClusterMask();
3984       }
3985     }
3986   }
3987   fEventInfo.SetTriggerClasses(trclasses);
3988   // Now put the declared trigger classes (not present in the run)
3989   // to 0/false in the event selection
3990   if (!fDeclTriggerClasses.IsNull()) {
3991     TObjArray *tokens = fDeclTriggerClasses.Tokenize(" ");
3992     Int_t ntokens = tokens->GetEntriesFast();
3993     for (Int_t itoken = 0; itoken < ntokens; ++itoken) {
3994       if (fRawReader) fRawReader->LoadTriggerClass((((TObjString*)tokens->At(itoken))->String()).Data(),-1);
3995     }
3996     delete tokens;
3997   }
3998
3999   // Write names of active trigger inputs in ESD Header
4000   const TObjArray& inputsArray = config->GetInputs(); 
4001   Int_t ninputs = inputsArray.GetEntriesFast();
4002   for( Int_t iinput=0; iinput < ninputs; iinput++ ) {
4003     AliTriggerInput* trginput = (AliTriggerInput*)inputsArray.At(iinput);
4004     if (trginput && trginput->GetMask()>0) {
4005       Int_t inputIndex = (Int_t)TMath::Nint(TMath::Log2(trginput->GetMask()));
4006       AliESDHeader* headeresd = fesd->GetHeader();
4007       Int_t trglevel = (Int_t)trginput->GetLevel();
4008       if (trglevel == 0) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex);
4009       if (trglevel == 1) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex+24);
4010       if (trglevel == 2) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex+48);
4011     }
4012   }
4013
4014   // Set the information in ESD
4015   fesd->SetTriggerMask(trmask);
4016   fesd->SetTriggerCluster(clustmask);
4017
4018   if (!aCTP->CheckTriggeredDetectors()) {
4019     if (fRawReader) delete aCTP;
4020     return kFALSE;
4021   }    
4022
4023   if (fRawReader) delete aCTP;
4024
4025   // We have to fill also the HLT decision here!!
4026   // ...
4027
4028   return kTRUE;
4029 }
4030
4031 const char *AliReconstruction::MatchDetectorList(const char *detectorList, UInt_t detectorMask)
4032 {
4033   // Match the detector list found in the rec.C or the default 'ALL'
4034   // to the list found in the GRP (stored there by the shuttle PP which
4035   // gets the information from ECS)
4036   static TString resultList;
4037   TString detList = detectorList;
4038
4039   resultList = "";
4040
4041   for(Int_t iDet = 0; iDet < (AliDAQ::kNDetectors-1); iDet++) {
4042     if ((detectorMask >> iDet) & 0x1) {
4043       TString det = AliDAQ::OfflineModuleName(iDet);
4044       if ((detList.CompareTo("ALL") == 0) ||
4045           ((detList.BeginsWith("ALL ") ||
4046             detList.EndsWith(" ALL") ||
4047             detList.Contains(" ALL ")) &&
4048            !(detList.BeginsWith("-"+det+" ") ||
4049              detList.EndsWith(" -"+det) ||
4050              detList.Contains(" -"+det+" "))) ||
4051           (detList.CompareTo(det) == 0) ||
4052           detList.BeginsWith(det+" ") ||
4053           detList.EndsWith(" "+det) ||
4054           detList.Contains( " "+det+" " )) {
4055         if (!resultList.EndsWith(det + " ")) {
4056           resultList += det;
4057           resultList += " ";
4058         }
4059       }        
4060     }
4061   }
4062
4063   // HLT
4064   if ((detectorMask >> AliDAQ::kHLTId) & 0x1) {
4065     TString hltDet = AliDAQ::OfflineModuleName(AliDAQ::kNDetectors-1);
4066     if ((detList.CompareTo("ALL") == 0) ||
4067         ((detList.BeginsWith("ALL ") ||
4068           detList.EndsWith(" ALL") ||
4069           detList.Contains(" ALL ")) &&
4070          !(detList.BeginsWith("-"+hltDet+" ") ||
4071            detList.EndsWith(" -"+hltDet) ||
4072            detList.Contains(" -"+hltDet+" "))) ||
4073         (detList.CompareTo(hltDet) == 0) ||
4074         detList.BeginsWith(hltDet+" ") ||
4075         detList.EndsWith(" "+hltDet) ||
4076         detList.Contains( " "+hltDet+" " )) {
4077       resultList += hltDet;
4078     }
4079   }
4080
4081   return resultList.Data();
4082
4083 }
4084
4085 //______________________________________________________________________________
4086 void AliReconstruction::Abort(const char *method, EAbort what)
4087 {
4088   // Abort processing. If what = kAbortProcess, the Process() loop will be
4089   // aborted. If what = kAbortFile, the current file in a chain will be
4090   // aborted and the processing will continue with the next file, if there
4091   // is no next file then Process() will be aborted. Abort() can also  be
4092   // called from Begin(), SlaveBegin(), Init() and Notify(). After abort
4093   // the SlaveTerminate() and Terminate() are always called. The abort flag
4094   // can be checked in these methods using GetAbort().
4095   //
4096   // The method is overwritten in AliReconstruction for better handling of
4097   // reco specific errors 
4098
4099   if (!fStopOnError) return;
4100
4101   CleanUp();
4102
4103   TString whyMess = method;
4104   whyMess += " failed! Aborting...";
4105
4106   AliError(whyMess.Data());
4107
4108   fAbort = what;
4109   TString mess = "Abort";
4110   if (fAbort == kAbortProcess)
4111     mess = "AbortProcess";
4112   else if (fAbort == kAbortFile)
4113     mess = "AbortFile";
4114
4115   Info(mess.Data(), "%s", whyMess.Data());
4116 }
4117
4118 //______________________________________________________________________________
4119 Bool_t AliReconstruction::ProcessEvent(void* event)
4120 {
4121   // Method that is used in case the event loop
4122   // is steered from outside, for example by AMORE
4123   // 'event' is a pointer to the DATE event in the memory
4124
4125   if (fRawReader) delete fRawReader;
4126   fRawReader = new AliRawReaderDate(event);
4127   fStatus = ProcessEvent(fRunLoader->GetNumberOfEvents());  
4128   delete fRawReader;
4129   fRawReader = NULL;
4130
4131   return fStatus;
4132 }
4133
4134 //______________________________________________________________________________
4135 Bool_t AliReconstruction::ParseOutput()
4136 {
4137   // The method parses the output file
4138   // location string in order to steer
4139   // properly the selector
4140
4141   TPMERegexp re1("(\\w+\\.zip#\\w+\\.root):([,*\\w+\\.root,*]+)@dataset://(\\w++)");
4142   TPMERegexp re2("(\\w+\\.root)?@?dataset://(\\w++)");
4143
4144   if (re1.Match(fESDOutput) == 4) {
4145     // root archive with output files stored and regustered
4146     // in proof dataset
4147     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",re1[1].Data()));
4148     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",re1[3].Data()));
4149     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_DATASET",""));
4150     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_ARCHIVE",re1[2].Data()));
4151     AliInfo(Form("%s files will be stored within %s in dataset %s",
4152                  re1[2].Data(),
4153                  re1[1].Data(),
4154                  re1[3].Data()));
4155   }
4156   else if (re2.Match(fESDOutput) == 3) {
4157     // output file stored and registered
4158     // in proof dataset
4159     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",(re2[1].IsNull()) ? "AliESDs.root" : re2[1].Data()));
4160     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",re2[2].Data()));
4161     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_DATASET",""));
4162     AliInfo(Form("%s will be stored in dataset %s",
4163                  (re2[1].IsNull()) ? "AliESDs.root" : re2[1].Data(),
4164                  re2[2].Data()));
4165   }
4166   else {
4167     if (fESDOutput.IsNull()) {
4168       // Output location not given.
4169       // Assuming xrootd has been already started and
4170       // the output file has to be sent back
4171       // to the client machine
4172       TString esdUrl(Form("root://%s/%s/",
4173                           TUrl(gSystem->HostName()).GetHostFQDN(),
4174                           gSystem->pwd()));
4175       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE","AliESDs.root"));
4176       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",esdUrl.Data()));
4177       AliInfo(Form("AliESDs.root will be stored in %s",
4178                    esdUrl.Data()));
4179     }
4180     else {
4181       // User specified an output location.
4182       // Ones has just to parse it here
4183       TUrl outputUrl(fESDOutput.Data());
4184       TString outputFile(gSystem->BaseName(outputUrl.GetFile()));
4185       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",outputFile.IsNull() ? "AliESDs.root" : outputFile.Data()));
4186       TString outputLocation(outputUrl.GetUrl());
4187       outputLocation.ReplaceAll(outputFile.Data(),"");
4188       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",outputLocation.Data()));
4189       AliInfo(Form("%s will be stored in %s",
4190                    outputFile.IsNull() ? "AliESDs.root" : outputFile.Data(),
4191                    outputLocation.Data()));
4192     }
4193   }
4194
4195   return kTRUE;
4196 }
4197
4198 //______________________________________________________________________________
4199 Bool_t AliReconstruction::IsHighPt() const {
4200   // Selection of events containing "high" pT tracks
4201   // If at least one track is found within 1.5 and 100 GeV (pT)
4202   // that was reconstructed by both ITS and TPC, the event is accepted
4203
4204   // Track cuts
4205   const Double_t pTmin = 1.5;
4206   const Double_t pTmax = 100;
4207   ULong_t mask = 0;
4208   mask |= (AliESDtrack::kITSrefit);
4209   mask |= (AliESDtrack::kTPCrefit);
4210   const Double_t pTminCosmic = 5.;
4211   const Double_t pTmaxCosmic = 100;
4212   ULong_t maskCosmic = 0;
4213   Int_t cosmicCount=0;
4214   maskCosmic |= (AliESDtrack::kTPCrefit);
4215
4216   Bool_t isOK = kFALSE;
4217
4218   if (fesd && fesd->GetEventType()==AliRawEventHeaderBase::kPhysicsEvent) {
4219     // Check if this ia a physics event (code 7)
4220     Int_t ntrk = fesd->GetNumberOfTracks();
4221     for (Int_t itrk=0; itrk<ntrk; ++itrk) {
4222           
4223       AliESDtrack * trk = fesd->GetTrack(itrk);
4224       if (trk 
4225           && trk->Pt() > pTmin 
4226           && trk->Pt() < pTmax
4227           && (trk->GetStatus() & mask) == mask ) {
4228         
4229         isOK = kTRUE;
4230         break;
4231       }
4232       if (trk 
4233           && trk->GetInnerParam()
4234           && trk->GetInnerParam()->Pt() > pTminCosmic 
4235           && trk->GetInnerParam()->Pt() < pTmaxCosmic
4236           && (trk->GetStatus() & maskCosmic) == maskCosmic ) {
4237         
4238         cosmicCount++;
4239         break;
4240       }
4241     }
4242     if (cosmicCount>1) isOK=kTRUE;
4243   }
4244   return isOK;
4245 }
4246
4247 //______________________________________________________________________________
4248 Bool_t AliReconstruction::IsCosmicOrCalibSpecie() const {
4249   // Select cosmic or calibration events
4250
4251   Bool_t isOK = kFALSE;
4252
4253   if (fesd && fesd->GetEventType()==AliRawEventHeaderBase::kPhysicsEvent) {
4254       // Check if this ia a physics event (code 7)
4255       
4256       UInt_t specie = fesd->GetEventSpecie();
4257       if (specie==AliRecoParam::kCosmic || specie==AliRecoParam::kCalib) {
4258         isOK = kTRUE;
4259       }
4260   }
4261   return isOK;
4262 }
4263
4264 //______________________________________________________________________________
4265 void AliReconstruction::WriteESDfriend() {
4266   // Fill the ESD friend in the tree. The required fraction of ESD friends is stored
4267   // in fFractionFriends. We select events where we store the ESD friends according
4268   // to the following algorithm:
4269   // 1. Store all Cosmic or Calibration events within the required fraction
4270   // 2. Sample "high Pt" events within the remaining fraction after step 1.
4271   // 3. Sample randomly events if we still have remaining slot
4272
4273   fNall++;
4274   Bool_t isSelected = kFALSE;
4275   //
4276   // Store all friends for B field OFF 
4277   if (TMath::Abs(AliTrackerBase::GetBz())<0.5) isSelected=kTRUE;
4278
4279   if (IsCosmicOrCalibSpecie()) { // Selection of calib or cosmic events
4280     fNspecie++;
4281
4282     isSelected = kTRUE;
4283     fSspecie++;
4284   }
4285   
4286   Double_t remainingFraction = fFractionFriends;
4287   remainingFraction -= ((Double_t)(fSspecie)/(Double_t)(fNall));
4288   
4289   if (IsHighPt())  { // Selection of "high Pt" events
4290     fNhighPt++;
4291     Double_t curentHighPtFraction = ((Double_t)(fNhighPt+1))/((Double_t)(fNall+1));
4292     // "Bayesian" estimate supposing that without events all the events are of the required type
4293     
4294     if (!isSelected) {
4295       Double_t rnd = gRandom->Rndm()*curentHighPtFraction;
4296       if (rnd<remainingFraction) {
4297         isSelected = kTRUE;
4298         fShighPt++;
4299       }
4300     }
4301   }
4302   remainingFraction -= ((Double_t)(fShighPt)/(Double_t)(fNall));
4303   
4304   // Random selection to fill the remaining fraction (if any)
4305   if (!isSelected) {
4306     Double_t rnd = gRandom->Rndm();
4307     if (rnd<remainingFraction) {        
4308       isSelected = kTRUE;
4309     }
4310   }
4311   
4312   if (!isSelected) {
4313     fesdf->~AliESDfriend();
4314     new (fesdf) AliESDfriend(); // Reset...
4315     fesdf->SetSkipBit(kTRUE);
4316   }
4317   
4318   ftreeF->Fill();
4319 }