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