]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliReconstruction.cxx
Fixes in order to have the merged QA data file as an output from PROOF-based reco...
[u/mrichter/AliRoot.git] / 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
130 #include "AliAlignObj.h"
131 #include "AliCDBEntry.h"
132 #include "AliCDBManager.h"
133 #include "AliCDBStorage.h"
134 #include "AliCTPRawStream.h"
135 #include "AliCascadeVertexer.h"
136 #include "AliCentralTrigger.h"
137 #include "AliCodeTimer.h"
138 #include "AliDAQ.h"
139 #include "AliDetectorRecoParam.h"
140 #include "AliESDCaloCells.h"
141 #include "AliESDCaloCluster.h"
142 #include "AliESDEvent.h"
143 #include "AliESDMuonTrack.h"
144 #include "AliESDPmdTrack.h"
145 #include "AliESDTagCreator.h"
146 #include "AliESDVertex.h"
147 #include "AliESDcascade.h"
148 #include "AliESDfriend.h"
149 #include "AliESDkink.h"
150 #include "AliESDpid.h"
151 #include "AliESDtrack.h"
152 #include "AliESDtrack.h"
153 #include "AliEventInfo.h"
154 #include "AliGRPObject.h"
155 #include "AliGRPRecoParam.h"
156 #include "AliGenEventHeader.h"
157 #include "AliGeomManager.h"
158 #include "AliGlobalQADataMaker.h" 
159 #include "AliHeader.h"
160 #include "AliLog.h"
161 #include "AliMagF.h"
162 #include "AliMultiplicity.h"
163 #include "AliPID.h"
164 #include "AliPlaneEff.h"
165 #include "AliQAv1.h"
166 #include "AliQADataMakerRec.h" 
167 #include "AliQAManager.h"
168 #include "AliRawVEvent.h"
169 #include "AliRawEventHeaderBase.h"
170 #include "AliRawHLTManager.h"
171 #include "AliRawReaderDate.h"
172 #include "AliRawReaderFile.h"
173 #include "AliRawReaderRoot.h"
174 #include "AliReconstruction.h"
175 #include "AliReconstructor.h"
176 #include "AliRun.h"
177 #include "AliRunInfo.h"
178 #include "AliRunLoader.h"
179 #include "AliSysInfo.h" // memory snapshots
180 #include "AliTrackPointArray.h"
181 #include "AliTracker.h"
182 #include "AliTriggerClass.h"
183 #include "AliTriggerCluster.h"
184 #include "AliTriggerConfiguration.h"
185 #include "AliV0vertexer.h"
186 #include "AliVertexer.h"
187 #include "AliVertexerTracks.h"
188
189 ClassImp(AliReconstruction)
190
191 //_____________________________________________________________________________
192 const char* AliReconstruction::fgkDetectorName[AliReconstruction::kNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT"};
193
194 //_____________________________________________________________________________
195 AliReconstruction::AliReconstruction(const char* gAliceFilename) :
196   TSelector(),
197   fUniformField(kFALSE),
198   fRunVertexFinder(kTRUE),
199   fRunVertexFinderTracks(kTRUE),
200   fRunHLTTracking(kFALSE),
201   fRunMuonTracking(kFALSE),
202   fRunV0Finder(kTRUE),
203   fRunCascadeFinder(kTRUE),
204   fStopOnError(kFALSE),
205   fWriteAlignmentData(kFALSE),
206   fWriteESDfriend(kFALSE),
207   fFillTriggerESD(kTRUE),
208
209   fCleanESD(kTRUE),
210   fV0DCAmax(3.),
211   fV0CsPmin(0.),
212   fDmax(50.),
213   fZmax(50.),
214
215   fRunLocalReconstruction("ALL"),
216   fRunTracking("ALL"),
217   fFillESD("ALL"),
218   fLoadCDB(""),
219   fUseTrackingErrorsForAlignment(""),
220   fGAliceFileName(gAliceFilename),
221   fRawInput(""),
222   fESDOutput(""),
223   fEquipIdMap(""),
224   fFirstEvent(0),
225   fLastEvent(-1),
226   fNumberOfEventsPerFile((UInt_t)-1),
227   fOptions(),
228   fLoadAlignFromCDB(kTRUE),
229   fLoadAlignData("ALL"),
230   fUseHLTData(),
231   fRunInfo(NULL),
232   fEventInfo(),
233
234   fRunLoader(NULL),
235   fRawReader(NULL),
236   fParentRawReader(NULL),
237
238   fRecoParam(),
239
240   fSPDTrackleter(NULL),
241
242   fDiamondProfileSPD(NULL),
243   fDiamondProfile(NULL),
244   fDiamondProfileTPC(NULL),
245   
246   fGRPData(NULL),
247
248   fAlignObjArray(NULL),
249   fCDBUri(),
250   fQARefUri(),
251   fSpecCDBUri(), 
252   fInitCDBCalled(kFALSE),
253   fSetRunNumberFromDataCalled(kFALSE),
254   fQADetectors("ALL"), 
255   fQAManager(NULL),  
256   fQATasks("ALL"), 
257   fRunQA(kTRUE),  
258   fRunGlobalQA(kTRUE),
259   fSameQACycle(kFALSE),
260   fInitQACalled(kFALSE), 
261   fWriteQAExpertData(kTRUE), 
262   fRunPlaneEff(kFALSE),
263
264   fesd(NULL),
265   fhltesd(NULL),
266   fesdf(NULL),
267   ffile(NULL),
268   ftree(NULL),
269   fhlttree(NULL),
270   ftVertexer(NULL),
271   fIsNewRunLoader(kFALSE),
272   fRunAliEVE(kFALSE),
273   fChain(NULL)
274 {
275 // create reconstruction object with default parameters
276   gGeoManager = NULL;
277   
278   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
279     fReconstructor[iDet] = NULL;
280     fLoader[iDet] = NULL;
281     fTracker[iDet] = NULL;
282   }
283   for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
284     fQACycles[iDet] = 999999 ;
285     fQAWriteExpert[iDet] = kFALSE ; 
286   }
287     
288   AliPID pid;
289 }
290
291 //_____________________________________________________________________________
292 AliReconstruction::AliReconstruction(const AliReconstruction& rec) :
293   TSelector(),
294   fUniformField(rec.fUniformField),
295   fRunVertexFinder(rec.fRunVertexFinder),
296   fRunVertexFinderTracks(rec.fRunVertexFinderTracks),
297   fRunHLTTracking(rec.fRunHLTTracking),
298   fRunMuonTracking(rec.fRunMuonTracking),
299   fRunV0Finder(rec.fRunV0Finder),
300   fRunCascadeFinder(rec.fRunCascadeFinder),
301   fStopOnError(rec.fStopOnError),
302   fWriteAlignmentData(rec.fWriteAlignmentData),
303   fWriteESDfriend(rec.fWriteESDfriend),
304   fFillTriggerESD(rec.fFillTriggerESD),
305
306   fCleanESD(rec.fCleanESD),
307   fV0DCAmax(rec.fV0DCAmax),
308   fV0CsPmin(rec.fV0CsPmin),
309   fDmax(rec.fDmax),
310   fZmax(rec.fZmax),
311
312   fRunLocalReconstruction(rec.fRunLocalReconstruction),
313   fRunTracking(rec.fRunTracking),
314   fFillESD(rec.fFillESD),
315   fLoadCDB(rec.fLoadCDB),
316   fUseTrackingErrorsForAlignment(rec.fUseTrackingErrorsForAlignment),
317   fGAliceFileName(rec.fGAliceFileName),
318   fRawInput(rec.fRawInput),
319   fESDOutput(rec.fESDOutput),
320   fEquipIdMap(rec.fEquipIdMap),
321   fFirstEvent(rec.fFirstEvent),
322   fLastEvent(rec.fLastEvent),
323   fNumberOfEventsPerFile(rec.fNumberOfEventsPerFile),
324   fOptions(),
325   fLoadAlignFromCDB(rec.fLoadAlignFromCDB),
326   fLoadAlignData(rec.fLoadAlignData),
327   fUseHLTData(rec.fUseHLTData),
328   fRunInfo(NULL),
329   fEventInfo(),
330
331   fRunLoader(NULL),
332   fRawReader(NULL),
333   fParentRawReader(NULL),
334
335   fRecoParam(rec.fRecoParam),
336
337   fSPDTrackleter(NULL),
338
339   fDiamondProfileSPD(rec.fDiamondProfileSPD),
340   fDiamondProfile(rec.fDiamondProfile),
341   fDiamondProfileTPC(rec.fDiamondProfileTPC),
342   
343   fGRPData(NULL),
344
345   fAlignObjArray(rec.fAlignObjArray),
346   fCDBUri(rec.fCDBUri),
347   fQARefUri(rec.fQARefUri),
348   fSpecCDBUri(), 
349   fInitCDBCalled(rec.fInitCDBCalled),
350   fSetRunNumberFromDataCalled(rec.fSetRunNumberFromDataCalled),
351   fQADetectors(rec.fQADetectors), 
352   fQAManager(NULL),  
353   fQATasks(rec.fQATasks), 
354   fRunQA(rec.fRunQA),  
355   fRunGlobalQA(rec.fRunGlobalQA),
356   fSameQACycle(rec.fSameQACycle),
357   fInitQACalled(rec.fInitQACalled),
358   fWriteQAExpertData(rec.fWriteQAExpertData), 
359   fRunPlaneEff(rec.fRunPlaneEff),
360
361   fesd(NULL),
362   fhltesd(NULL),
363   fesdf(NULL),
364   ffile(NULL),
365   ftree(NULL),
366   fhlttree(NULL),
367   ftVertexer(NULL),
368   fIsNewRunLoader(rec.fIsNewRunLoader),
369   fRunAliEVE(kFALSE),
370   fChain(NULL)
371 {
372 // copy constructor
373
374   for (Int_t i = 0; i < rec.fOptions.GetEntriesFast(); i++) {
375     if (rec.fOptions[i]) fOptions.Add(rec.fOptions[i]->Clone());
376   }
377   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
378     fReconstructor[iDet] = NULL;
379     fLoader[iDet] = NULL;
380     fTracker[iDet] = NULL;
381   }  
382   
383   for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
384     fQACycles[iDet] = rec.fQACycles[iDet];
385     fQAWriteExpert[iDet] = rec.fQAWriteExpert[iDet] ; 
386   }
387
388   for (Int_t i = 0; i < rec.fSpecCDBUri.GetEntriesFast(); i++) {
389     if (rec.fSpecCDBUri[i]) fSpecCDBUri.Add(rec.fSpecCDBUri[i]->Clone());
390   }
391 }
392
393 //_____________________________________________________________________________
394 AliReconstruction& AliReconstruction::operator = (const AliReconstruction& rec)
395 {
396 // assignment operator
397 // Used in PROOF mode
398 // Be very careful while modifing it!
399 // Simple rules to follow:
400 // for persistent data members - use their assignment operators
401 // for non-persistent ones - do nothing or take the default values from constructor
402 // TSelector members should not be touched
403   if(&rec == this) return *this;
404
405   fUniformField          = rec.fUniformField;
406   fRunVertexFinder       = rec.fRunVertexFinder;
407   fRunVertexFinderTracks = rec.fRunVertexFinderTracks;
408   fRunHLTTracking        = rec.fRunHLTTracking;
409   fRunMuonTracking       = rec.fRunMuonTracking;
410   fRunV0Finder           = rec.fRunV0Finder;
411   fRunCascadeFinder      = rec.fRunCascadeFinder;
412   fStopOnError           = rec.fStopOnError;
413   fWriteAlignmentData    = rec.fWriteAlignmentData;
414   fWriteESDfriend        = rec.fWriteESDfriend;
415   fFillTriggerESD        = rec.fFillTriggerESD;
416
417   fCleanESD  = rec.fCleanESD;
418   fV0DCAmax  = rec.fV0DCAmax;
419   fV0CsPmin  = rec.fV0CsPmin;
420   fDmax      = rec.fDmax;
421   fZmax      = rec.fZmax;
422
423   fRunLocalReconstruction        = rec.fRunLocalReconstruction;
424   fRunTracking                   = rec.fRunTracking;
425   fFillESD                       = rec.fFillESD;
426   fLoadCDB                       = rec.fLoadCDB;
427   fUseTrackingErrorsForAlignment = rec.fUseTrackingErrorsForAlignment;
428   fGAliceFileName                = rec.fGAliceFileName;
429   fRawInput                      = rec.fRawInput;
430   fESDOutput                     = rec.fESDOutput;
431   fEquipIdMap                    = rec.fEquipIdMap;
432   fFirstEvent                    = rec.fFirstEvent;
433   fLastEvent                     = rec.fLastEvent;
434   fNumberOfEventsPerFile         = rec.fNumberOfEventsPerFile;
435
436   for (Int_t i = 0; i < rec.fOptions.GetEntriesFast(); i++) {
437     if (rec.fOptions[i]) fOptions.Add(rec.fOptions[i]->Clone());
438   }
439
440   fLoadAlignFromCDB              = rec.fLoadAlignFromCDB;
441   fLoadAlignData                 = rec.fLoadAlignData;
442   fUseHLTData                    = rec.fUseHLTData;
443
444   delete fRunInfo; fRunInfo = NULL;
445   if (rec.fRunInfo) fRunInfo = new AliRunInfo(*rec.fRunInfo);
446
447   fEventInfo                     = rec.fEventInfo;
448
449   fRunLoader       = NULL;
450   fRawReader       = NULL;
451   fParentRawReader = NULL;
452
453   fRecoParam = rec.fRecoParam;
454
455   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
456     delete fReconstructor[iDet]; fReconstructor[iDet] = NULL;
457     delete fLoader[iDet]; fLoader[iDet] = NULL;
458     delete fTracker[iDet]; fTracker[iDet] = NULL;
459   }
460   
461   for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
462     fQACycles[iDet] = rec.fQACycles[iDet];
463     fQAWriteExpert[iDet] = rec.fQAWriteExpert[iDet] ;
464   } 
465
466   delete fSPDTrackleter; fSPDTrackleter = NULL;
467     
468   delete fDiamondProfileSPD; fDiamondProfileSPD = NULL;
469   if (rec.fDiamondProfileSPD) fDiamondProfileSPD = new AliESDVertex(*rec.fDiamondProfileSPD);
470   delete fDiamondProfile; fDiamondProfile = NULL;
471   if (rec.fDiamondProfile) fDiamondProfile = new AliESDVertex(*rec.fDiamondProfile);
472   delete fDiamondProfileTPC; fDiamondProfileTPC = NULL;
473   if (rec.fDiamondProfileTPC) fDiamondProfileTPC = new AliESDVertex(*rec.fDiamondProfileTPC);
474
475   delete fGRPData; fGRPData = NULL;
476   //  if (rec.fGRPData) fGRPData = (TMap*)((rec.fGRPData)->Clone());
477   if (rec.fGRPData) fGRPData = (AliGRPObject*)((rec.fGRPData)->Clone());
478
479   delete fAlignObjArray; fAlignObjArray = NULL;
480
481   fCDBUri        = "";
482   fQARefUri      = rec.fQARefUri;
483   fSpecCDBUri.Delete();
484   fInitCDBCalled               = rec.fInitCDBCalled;
485   fSetRunNumberFromDataCalled  = rec.fSetRunNumberFromDataCalled;
486   fQADetectors                 = rec.fQADetectors;
487   fQAManager                     = NULL;  
488   fQATasks                     = rec.fQATasks; 
489   fRunQA                       = rec.fRunQA;  
490   fRunGlobalQA                 = rec.fRunGlobalQA;
491   fSameQACycle                 = rec.fSameQACycle;
492   fInitQACalled                = rec.fInitQACalled;
493   fWriteQAExpertData           = rec.fWriteQAExpertData;
494   fRunPlaneEff                 = rec.fRunPlaneEff;
495
496   fesd     = NULL;
497   fhltesd  = NULL;
498   fesdf    = NULL;
499   ffile    = NULL;
500   ftree    = NULL;
501   fhlttree = NULL;
502   ftVertexer = NULL;
503   fIsNewRunLoader = rec.fIsNewRunLoader;
504   fRunAliEVE = kFALSE;
505   fChain = NULL;
506
507   return *this;
508 }
509
510 //_____________________________________________________________________________
511 AliReconstruction::~AliReconstruction()
512 {
513 // clean up
514
515   CleanUp();
516   delete fGRPData;
517   fOptions.Delete();
518   if (fAlignObjArray) {
519     fAlignObjArray->Delete();
520     delete fAlignObjArray;
521   }
522   fSpecCDBUri.Delete();
523   delete fQAManager;
524   AliCodeTimer::Instance()->Print();
525 }
526
527 //_____________________________________________________________________________
528 void AliReconstruction::InitQA()
529 {
530   //Initialize the QA and start of cycle 
531   AliCodeTimerAuto("");
532   
533   if (fInitQACalled) return;
534   fInitQACalled = kTRUE;
535   
536   fQAManager = AliQAManager::QAManager("rec") ; 
537   if (fWriteQAExpertData)
538     fQAManager->SetWriteExpert() ; 
539  
540   if (fQAManager->IsDefaultStorageSet()) {
541     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
542     AliWarning("Default QA reference storage has been already set !");
543     AliWarning(Form("Ignoring the default storage declared in AliReconstruction: %s",fQARefUri.Data()));
544     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
545     fQARefUri = fQAManager->GetDefaultStorage()->GetURI();
546   } else {
547     if (fQARefUri.Length() > 0) {
548         AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
549         AliDebug(2, Form("Default QA reference storage is set to: %s", fQARefUri.Data()));
550         AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
551       } else {
552         fQARefUri="local://$ALICE_ROOT/QAref";
553         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
554         AliWarning("Default QA refeference storage not yet set !!!!");
555         AliWarning(Form("Setting it now to: %s", fQARefUri.Data()));
556         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
557                 
558       }
559     fQAManager->SetDefaultStorage(fQARefUri);
560   }
561   
562   if (fRunQA) {
563   fQAManager->SetActiveDetectors(fQADetectors) ; 
564   for (Int_t det = 0 ; det < AliQAv1::kNDET ; det++) {
565     fQAManager->SetCycleLength(AliQAv1::DETECTORINDEX_t(det), fQACycles[det]) ;  
566     fQAManager->SetWriteExpert(AliQAv1::DETECTORINDEX_t(det)) ;
567   }
568   if (!fRawReader && !fInput && fQATasks.Contains(AliQAv1::kRAWS))
569     fQATasks.ReplaceAll(Form("%d",AliQAv1::kRAWS), "") ;
570   fQAManager->SetTasks(fQATasks) ; 
571   fQAManager->InitQADataMaker(AliCDBManager::Instance()->GetRun()) ; 
572   }
573   if (fRunGlobalQA) {
574     Bool_t sameCycle = kFALSE ;
575     AliQADataMaker *qadm = fQAManager->GetQADataMaker(AliQAv1::kGLOBAL);
576     AliInfo(Form("Initializing the global QA data maker"));
577     if (fQATasks.Contains(Form("%d", AliQAv1::kRECPOINTS))) {
578       qadm->StartOfCycle(AliQAv1::kRECPOINTS, AliCDBManager::Instance()->GetRun(), sameCycle) ; 
579       TObjArray **arr=qadm->Init(AliQAv1::kRECPOINTS);
580       AliTracker::SetResidualsArray(arr);
581       sameCycle = kTRUE ; 
582     }
583     if (fQATasks.Contains(Form("%d", AliQAv1::kESDS))) {
584       qadm->StartOfCycle(AliQAv1::kESDS, AliCDBManager::Instance()->GetRun(), sameCycle) ; 
585       qadm->Init(AliQAv1::kESDS);
586     }
587   }
588     AliSysInfo::AddStamp("InitQA") ; 
589 }
590
591 //_____________________________________________________________________________
592 void AliReconstruction::MergeQA(const char *fileName)
593 {
594   //Initialize the QA and start of cycle 
595   AliCodeTimerAuto("") ;
596   if ( ! fQAManager ) {
597     AliFatal("Hum... this should not happen") ; 
598   } else { 
599    fQAManager->Merge(AliCDBManager::Instance()->GetRun(),fileName) ; 
600   }
601   AliSysInfo::AddStamp("MergeQA") ; 
602 }
603   
604 //_____________________________________________________________________________
605 void AliReconstruction::InitCDB()
606 {
607 // activate a default CDB storage
608 // First check if we have any CDB storage set, because it is used 
609 // to retrieve the calibration and alignment constants
610   AliCodeTimerAuto("");
611
612   if (fInitCDBCalled) return;
613   fInitCDBCalled = kTRUE;
614
615   AliCDBManager* man = AliCDBManager::Instance();
616   if (man->IsDefaultStorageSet())
617   {
618     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
619     AliWarning("Default CDB storage has been already set !");
620     AliWarning(Form("Ignoring the default storage declared in AliReconstruction: %s",fCDBUri.Data()));
621     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
622     fCDBUri = man->GetDefaultStorage()->GetURI();
623   }
624   else {
625     if (fCDBUri.Length() > 0) 
626     {
627         AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
628         AliDebug(2, Form("Default CDB storage is set to: %s", fCDBUri.Data()));
629         AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
630     } else {
631         fCDBUri="local://$ALICE_ROOT/OCDB";
632         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
633         AliWarning("Default CDB storage not yet set !!!!");
634         AliWarning(Form("Setting it now to: %s", fCDBUri.Data()));
635         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
636                 
637     }
638     man->SetDefaultStorage(fCDBUri);
639   }
640
641   // Now activate the detector specific CDB storage locations
642   for (Int_t i = 0; i < fSpecCDBUri.GetEntriesFast(); i++) {
643     TObject* obj = fSpecCDBUri[i];
644     if (!obj) continue;
645     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
646     AliDebug(2, Form("Specific CDB storage for %s is set to: %s",obj->GetName(),obj->GetTitle()));
647     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
648     man->SetSpecificStorage(obj->GetName(), obj->GetTitle());
649   }
650   AliSysInfo::AddStamp("InitCDB");
651 }
652
653 //_____________________________________________________________________________
654 void AliReconstruction::SetDefaultStorage(const char* uri) {
655 // Store the desired default CDB storage location
656 // Activate it later within the Run() method
657
658   fCDBUri = uri;
659
660 }
661
662 //_____________________________________________________________________________
663 void AliReconstruction::SetQARefDefaultStorage(const char* uri) {
664   // Store the desired default CDB storage location
665   // Activate it later within the Run() method
666   
667   fQARefUri = uri;
668   AliQAv1::SetQARefStorage(fQARefUri.Data()) ;
669   
670 }
671 //_____________________________________________________________________________
672 void AliReconstruction::SetSpecificStorage(const char* calibType, const char* uri) {
673 // Store a detector-specific CDB storage location
674 // Activate it later within the Run() method
675
676   AliCDBPath aPath(calibType);
677   if(!aPath.IsValid()){
678         // if calibType is not wildcard but it is a valid detector, add "/*" to make it a valid path
679         for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
680                 if(!strcmp(calibType, fgkDetectorName[iDet])) {
681                         aPath.SetPath(Form("%s/*", calibType));
682                         AliInfo(Form("Path for specific storage set to %s", aPath.GetPath().Data()));
683                         break;
684                 }
685         }
686         if(!aPath.IsValid()){
687                 AliError(Form("Not a valid path or detector: %s", calibType));
688                 return;
689         }
690   }
691
692 //  // check that calibType refers to a "valid" detector name
693 //  Bool_t isDetector = kFALSE;
694 //  for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
695 //    TString detName = fgkDetectorName[iDet];
696 //    if(aPath.GetLevel0() == detName) {
697 //      isDetector = kTRUE;
698 //      break;
699 //    }
700 //  }
701 //
702 //  if(!isDetector) {
703 //      AliError(Form("Not a valid detector: %s", aPath.GetLevel0().Data()));
704 //      return;
705 //  }
706
707   TObject* obj = fSpecCDBUri.FindObject(aPath.GetPath().Data());
708   if (obj) fSpecCDBUri.Remove(obj);
709   fSpecCDBUri.Add(new TNamed(aPath.GetPath().Data(), uri));
710
711 }
712
713 //_____________________________________________________________________________
714 Bool_t AliReconstruction::SetRunNumberFromData()
715 {
716   // The method is called in Run() in order
717   // to set a correct run number.
718   // In case of raw data reconstruction the
719   // run number is taken from the raw data header
720
721   if (fSetRunNumberFromDataCalled) return kTRUE;
722   fSetRunNumberFromDataCalled = kTRUE;
723   
724   AliCDBManager* man = AliCDBManager::Instance();
725  
726   if(fRawReader) {
727     if(fRawReader->NextEvent()) {
728       if(man->GetRun() > 0) {
729         AliWarning("Run number is taken from raw-event header! Ignoring settings in AliCDBManager!");
730       } 
731       man->SetRun(fRawReader->GetRunNumber());
732       fRawReader->RewindEvents();
733     }
734     else {
735       if(man->GetRun() > 0) {
736         AliWarning("No raw-data events are found ! Using settings in AliCDBManager !");
737       }
738       else {
739         AliWarning("Neither raw events nor settings in AliCDBManager are found !");
740         return kFALSE;
741       }
742     }
743   }
744   else {
745     AliRunLoader *rl = AliRunLoader::Open(fGAliceFileName.Data());
746     if (!rl) {
747       AliError(Form("No run loader found in file %s", fGAliceFileName.Data()));
748       return kFALSE;
749     }
750     else {
751       rl->LoadHeader();
752       // read run number from gAlice
753       if(rl->GetHeader()) {
754         man->SetRun(rl->GetHeader()->GetRun());
755         rl->UnloadHeader();
756         delete rl;
757       }
758       else {
759         AliError("Neither run-loader header nor RawReader objects are found !");
760         delete rl;
761         return kFALSE;
762       }
763     }
764   }
765
766   man->Print();  
767   
768   return kTRUE;
769 }
770
771 //_____________________________________________________________________________
772 void AliReconstruction::SetCDBLock() {
773   // Set CDB lock: from now on it is forbidden to reset the run number
774   // or the default storage or to activate any further storage!
775   
776   AliCDBManager::Instance()->SetLock(1);
777 }
778
779 //_____________________________________________________________________________
780 Bool_t AliReconstruction::MisalignGeometry(const TString& detectors)
781 {
782   // Read the alignment objects from CDB.
783   // Each detector is supposed to have the
784   // alignment objects in DET/Align/Data CDB path.
785   // All the detector objects are then collected,
786   // sorted by geometry level (starting from ALIC) and
787   // then applied to the TGeo geometry.
788   // Finally an overlaps check is performed.
789
790   // Load alignment data from CDB and fill fAlignObjArray 
791   if(fLoadAlignFromCDB){
792         
793     TString detStr = detectors;
794     TString loadAlObjsListOfDets = "";
795     
796     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
797       if(!IsSelected(fgkDetectorName[iDet], detStr)) continue;
798       if(!strcmp(fgkDetectorName[iDet],"HLT")) continue;
799       
800       if(AliGeomManager::GetNalignable(fgkDetectorName[iDet]) != 0)
801       {
802         loadAlObjsListOfDets += fgkDetectorName[iDet];
803         loadAlObjsListOfDets += " ";
804       }
805     } // end loop over detectors
806     
807     if(AliGeomManager::GetNalignable("GRP") != 0)
808       loadAlObjsListOfDets.Prepend("GRP "); //add alignment objects for non-sensitive modules
809     AliGeomManager::ApplyAlignObjsFromCDB(loadAlObjsListOfDets.Data());
810     AliCDBManager::Instance()->UnloadFromCache("*/Align/*");
811   }else{
812     // Check if the array with alignment objects was
813     // provided by the user. If yes, apply the objects
814     // to the present TGeo geometry
815     if (fAlignObjArray) {
816       if (gGeoManager && gGeoManager->IsClosed()) {
817         if (AliGeomManager::ApplyAlignObjsToGeom(*fAlignObjArray) == kFALSE) {
818           AliError("The misalignment of one or more volumes failed!"
819                    "Compare the list of simulated detectors and the list of detector alignment data!");
820           return kFALSE;
821         }
822       }
823       else {
824         AliError("Can't apply the misalignment! gGeoManager doesn't exist or it is still opened!");
825         return kFALSE;
826       }
827     }
828   }
829   
830   if (fAlignObjArray) {
831     fAlignObjArray->Delete();
832     delete fAlignObjArray; fAlignObjArray=NULL;
833   }
834
835   return kTRUE;
836 }
837
838 //_____________________________________________________________________________
839 void AliReconstruction::SetGAliceFile(const char* fileName)
840 {
841 // set the name of the galice file
842
843   fGAliceFileName = fileName;
844 }
845
846 //_____________________________________________________________________________
847 void AliReconstruction::SetInput(const char* input) 
848 {
849   // In case the input string starts with 'mem://', we run in an online mode
850   // and AliRawReaderDateOnline object is created. In all other cases a raw-data
851   // file is assumed. One can give as an input:
852   // mem://: - events taken from DAQ monitoring libs online
853   //  or
854   // mem://<filename> - emulation of the above mode (via DATE monitoring libs)
855   if (input) fRawInput = input;
856 }
857
858 //_____________________________________________________________________________
859 void AliReconstruction::SetOutput(const char* output) 
860 {
861   // Set the output ESD filename
862   // 'output' is a normalt ROOT url
863   // The method is used in case of raw-data reco with PROOF
864   if (output) fESDOutput.SetUrl(output);
865 }
866
867 //_____________________________________________________________________________
868 void AliReconstruction::SetOption(const char* detector, const char* option)
869 {
870 // set options for the reconstruction of a detector
871
872   TObject* obj = fOptions.FindObject(detector);
873   if (obj) fOptions.Remove(obj);
874   fOptions.Add(new TNamed(detector, option));
875 }
876
877 //_____________________________________________________________________________
878 void AliReconstruction::SetRecoParam(const char* detector, AliDetectorRecoParam *par)
879 {
880   // Set custom reconstruction parameters for a given detector
881   // Single set of parameters for all the events
882
883   // First check if the reco-params are global
884   if(!strcmp(detector, "GRP")) {
885     par->SetAsDefault();
886     fRecoParam.AddDetRecoParam(kNDetectors,par);
887     return;
888   }
889
890   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
891     if(!strcmp(detector, fgkDetectorName[iDet])) {
892       par->SetAsDefault();
893       fRecoParam.AddDetRecoParam(iDet,par);
894       break;
895     }
896   }
897
898 }
899
900 //_____________________________________________________________________________
901 Bool_t AliReconstruction::SetFieldMap(Float_t l3Cur, Float_t diCur, Float_t l3Pol, 
902                                       Float_t diPol, Float_t beamenergy, 
903                                       const Char_t *beamtype, const Char_t *path) 
904 {
905   //------------------------------------------------
906   // The magnetic field map, defined externally...
907   // L3 current 30000 A  -> 0.5 T
908   // L3 current 12000 A  -> 0.2 T
909   // dipole current 6000 A
910   // The polarities must be the same
911   //------------------------------------------------
912   const Float_t l3NominalCurrent1=30000.; // (A)
913   const Float_t l3NominalCurrent2=12000.; // (A)
914   const Float_t diNominalCurrent =6000. ; // (A)
915
916   const Float_t tolerance=0.03; // relative current tolerance
917   const Float_t zero=77.;       // "zero" current (A)
918   //
919   TString s=(l3Pol < 0) ? "L3: -" : "L3: +";
920   //
921   AliMagF::BMap_t map = AliMagF::k5kG;
922   //
923   double fcL3,fcDip;
924   //
925   l3Cur = TMath::Abs(l3Cur);
926   if (TMath::Abs(l3Cur-l3NominalCurrent1)/l3NominalCurrent1 < tolerance) {
927     fcL3 = l3Cur/l3NominalCurrent1;
928     map  = AliMagF::k5kG;
929     s   += "0.5 T;  ";
930   } else if (TMath::Abs(l3Cur-l3NominalCurrent2)/l3NominalCurrent2 < tolerance) {
931     fcL3 = l3Cur/l3NominalCurrent2;
932     map  = AliMagF::k2kG;
933     s   += "0.2 T;  ";
934   } else if (l3Cur <= zero) {
935     fcL3 = 0;
936     map  = AliMagF::k5kGUniform;
937     s   += "0.0 T;  ";
938     fUniformField=kTRUE;        // track with the uniform (zero) B field
939   } else {
940     AliError(Form("Wrong L3 current (%f A)!",l3Cur));
941     return kFALSE;
942   }
943   //
944   diCur = TMath::Abs(diCur);
945   if (TMath::Abs(diCur-diNominalCurrent)/diNominalCurrent < tolerance) {
946     // 3% current tolerance...
947     fcDip = diCur/diNominalCurrent;
948     s    += "Dipole ON";
949   } else if (diCur <= zero) { // some small current..
950     fcDip = 0.;
951     s    += "Dipole OFF";
952   } else {
953     AliError(Form("Wrong dipole current (%f A)!",diCur));
954     return kFALSE;
955   }
956   //
957   if (l3Pol!=diPol && (map==AliMagF::k5kG || map==AliMagF::k2kG) && fcDip!=0) {
958     AliError("L3 and Dipole polarities must be the same");
959     return kFALSE;
960   }
961   //
962   if (l3Pol<0) fcL3  = -fcL3;
963   if (diPol<0) fcDip = -fcDip;
964   //
965   AliMagF::BeamType_t btype = AliMagF::kNoBeamField;
966   TString btypestr = beamtype;
967   btypestr.ToLower();
968   TPRegexp protonBeam("(proton|p)\\s*-?\\s*\\1");
969   TPRegexp ionBeam("(lead|pb|ion|a)\\s*-?\\s*\\1");
970   if (btypestr.Contains(ionBeam)) btype = AliMagF::kBeamTypeAA;
971   else if (btypestr.Contains(protonBeam)) btype = AliMagF::kBeamTypepp;
972   else {
973     AliInfo(Form("Cannot determine the beam type from %s, assume no LHC magnet field",beamtype));
974   }
975   
976   AliMagF* fld = new AliMagF("MagneticFieldMap", s.Data(), 2, fcL3, fcDip, 10., map, path, 
977                              btype,beamenergy);
978   TGeoGlobalMagField::Instance()->SetField( fld );
979   TGeoGlobalMagField::Instance()->Lock();
980   //
981   return kTRUE;
982 }
983
984
985 Bool_t AliReconstruction::InitGRP() {
986   //------------------------------------
987   // Initialization of the GRP entry 
988   //------------------------------------
989   AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/GRP/Data");
990
991   if (entry) {
992
993     TMap* m = dynamic_cast<TMap*>(entry->GetObject());  // old GRP entry
994
995     if (m) {
996        AliInfo("Found a TMap in GRP/GRP/Data, converting it into an AliGRPObject");
997        m->Print();
998        fGRPData = new AliGRPObject();
999        fGRPData->ReadValuesFromMap(m);
1000     }
1001
1002     else {
1003        AliInfo("Found an AliGRPObject in GRP/GRP/Data, reading it");
1004        fGRPData = dynamic_cast<AliGRPObject*>(entry->GetObject());  // new GRP entry
1005        entry->SetOwner(0);
1006     }
1007
1008     AliCDBManager::Instance()->UnloadFromCache("GRP/GRP/Data");
1009   }
1010
1011   if (!fGRPData) {
1012      AliError("No GRP entry found in OCDB!");
1013      return kFALSE;
1014   }
1015
1016   TString lhcState = fGRPData->GetLHCState();
1017   if (lhcState==AliGRPObject::GetInvalidString()) {
1018     AliError("GRP/GRP/Data entry:  missing value for the LHC state ! Using UNKNOWN");
1019     lhcState = "UNKNOWN";
1020   }
1021
1022   TString beamType = fGRPData->GetBeamType();
1023   if (beamType==AliGRPObject::GetInvalidString()) {
1024     AliError("GRP/GRP/Data entry:  missing value for the beam type ! Using UNKNOWN");
1025     beamType = "UNKNOWN";
1026   }
1027
1028   Float_t beamEnergy = fGRPData->GetBeamEnergy();
1029   if (beamEnergy==AliGRPObject::GetInvalidFloat()) {
1030     AliError("GRP/GRP/Data entry:  missing value for the beam energy ! Using 0");
1031     beamEnergy = 0;
1032   }
1033   // energy is provided in MeV*120
1034   beamEnergy /= 120E3;
1035
1036   TString runType = fGRPData->GetRunType();
1037   if (runType==AliGRPObject::GetInvalidString()) {
1038     AliError("GRP/GRP/Data entry:  missing value for the run type ! Using UNKNOWN");
1039     runType = "UNKNOWN";
1040   }
1041
1042   Int_t activeDetectors = fGRPData->GetDetectorMask();
1043   if (activeDetectors==AliGRPObject::GetInvalidUInt()) {
1044     AliError("GRP/GRP/Data entry:  missing value for the detector mask ! Using 1074790399");
1045     activeDetectors = 1074790399;
1046   }
1047
1048   fRunInfo = new AliRunInfo(lhcState, beamType, beamEnergy, runType, activeDetectors);
1049   fRunInfo->Dump();
1050
1051
1052   // Process the list of active detectors
1053   if (activeDetectors) {
1054     UInt_t detMask = activeDetectors;
1055     fRunLocalReconstruction = MatchDetectorList(fRunLocalReconstruction,detMask);
1056     fRunTracking = MatchDetectorList(fRunTracking,detMask);
1057     fFillESD = MatchDetectorList(fFillESD,detMask);
1058     fQADetectors = MatchDetectorList(fQADetectors,detMask);
1059     fLoadCDB.Form("%s %s %s %s",
1060                   fRunLocalReconstruction.Data(),
1061                   fRunTracking.Data(),
1062                   fFillESD.Data(),
1063                   fQADetectors.Data());
1064     fLoadCDB = MatchDetectorList(fLoadCDB,detMask);
1065     if (!((detMask >> AliDAQ::DetectorID("ITSSPD")) & 0x1)) {
1066       // switch off the vertexer
1067       AliInfo("SPD is not in the list of active detectors. Vertexer switched off.");
1068       fRunVertexFinder = kFALSE;
1069     }
1070     if (!((detMask >> AliDAQ::DetectorID("TRG")) & 0x1)) {
1071       // switch off the reading of CTP raw-data payload
1072       if (fFillTriggerESD) {
1073         AliInfo("CTP is not in the list of active detectors. CTP data reading switched off.");
1074         fFillTriggerESD = kFALSE;
1075       }
1076     }
1077   }
1078
1079   AliInfo("===================================================================================");
1080   AliInfo(Form("Running local reconstruction for detectors: %s",fRunLocalReconstruction.Data()));
1081   AliInfo(Form("Running tracking for detectors: %s",fRunTracking.Data()));
1082   AliInfo(Form("Filling ESD for detectors: %s",fFillESD.Data()));
1083   AliInfo(Form("Quality assurance is active for detectors: %s",fQADetectors.Data()));
1084   AliInfo(Form("CDB and reconstruction parameters are loaded for detectors: %s",fLoadCDB.Data()));
1085   AliInfo("===================================================================================");
1086
1087   //*** Dealing with the magnetic field map
1088   if ( TGeoGlobalMagField::Instance()->IsLocked() ) {AliInfo("Running with the externally locked B field !");}
1089   else {
1090     // Construct the field map out of the information retrieved from GRP.
1091     Bool_t ok = kTRUE;
1092     // L3
1093     Float_t l3Current = fGRPData->GetL3Current((AliGRPObject::Stats)0);
1094     if (l3Current == AliGRPObject::GetInvalidFloat()) {
1095       AliError("GRP/GRP/Data entry:  missing value for the L3 current !");
1096       ok = kFALSE;
1097     }
1098     
1099     Char_t l3Polarity = fGRPData->GetL3Polarity();
1100     if (l3Polarity == AliGRPObject::GetInvalidChar()) {
1101       AliError("GRP/GRP/Data entry:  missing value for the L3 polarity !");
1102       ok = kFALSE;
1103     }
1104
1105     // Dipole
1106     Float_t diCurrent = fGRPData->GetDipoleCurrent((AliGRPObject::Stats)0);
1107     if (diCurrent == AliGRPObject::GetInvalidFloat()) {
1108       AliError("GRP/GRP/Data entry:  missing value for the dipole current !");
1109       ok = kFALSE;
1110     }
1111
1112     Char_t diPolarity = fGRPData->GetDipolePolarity();
1113     if (diPolarity == AliGRPObject::GetInvalidChar()) {
1114       AliError("GRP/GRP/Data entry:  missing value for the dipole polarity !");
1115       ok = kFALSE;
1116     }
1117
1118     /*
1119     TObjString *l3Current=
1120        dynamic_cast<TObjString*>(fGRPData->GetValue("fL3Current"));
1121     if (!l3Current) {
1122       AliError("GRP/GRP/Data entry:  missing value for the L3 current !");
1123       ok = kFALSE;
1124     }
1125     TObjString *l3Polarity=
1126        dynamic_cast<TObjString*>(fGRPData->GetValue("fL3Polarity"));
1127     if (!l3Polarity) {
1128       AliError("GRP/GRP/Data entry:  missing value for the L3 polarity !");
1129       ok = kFALSE;
1130     }
1131     
1132     // Dipole
1133     TObjString *diCurrent=
1134        dynamic_cast<TObjString*>(fGRPData->GetValue("fDipoleCurrent"));
1135     if (!diCurrent) {
1136       AliError("GRP/GRP/Data entry:  missing value for the dipole current !");
1137       ok = kFALSE;
1138     }
1139     TObjString *diPolarity=
1140        dynamic_cast<TObjString*>(fGRPData->GetValue("fDipolePolarity"));
1141     if (!diPolarity) {
1142       AliError("GRP/GRP/Data entry:  missing value for the dipole polarity !");
1143       ok = kFALSE;
1144     }
1145     */
1146
1147     if (ok) { 
1148       if ( !SetFieldMap(l3Current, diCurrent, l3Polarity ? -1:1, diPolarity ? -1:1) )
1149         AliFatal("Failed to creat a B field map ! Exiting...");
1150       AliInfo("Running with the B field constructed out of GRP !");
1151     }
1152     else AliFatal("B field is neither set nor constructed from GRP ! Exitig...");
1153     
1154   }
1155   
1156   //*** Get the diamond profiles from OCDB
1157   entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexSPD");
1158   if (entry) {
1159     fDiamondProfileSPD = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1160   } else {
1161      AliError("No SPD diamond profile found in OCDB!");
1162   }
1163
1164   entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertex");
1165   if (entry) {
1166     fDiamondProfile = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1167   } else {
1168      AliError("No diamond profile found in OCDB!");
1169   }
1170
1171   entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexTPC");
1172   if (entry) {
1173     fDiamondProfileTPC = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1174   } else {
1175      AliError("No TPC diamond profile found in OCDB!");
1176   }
1177
1178   return kTRUE;
1179
1180
1181 //_____________________________________________________________________________
1182 Bool_t AliReconstruction::LoadCDB()
1183 {
1184   AliCodeTimerAuto("");
1185
1186   AliCDBManager::Instance()->Get("GRP/CTP/Config");
1187
1188   TString detStr = fLoadCDB;
1189   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1190     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1191     AliCDBManager::Instance()->GetAll(Form("%s/Calib/*",fgkDetectorName[iDet]));
1192   }
1193   return kTRUE;
1194 }
1195
1196 //_____________________________________________________________________________
1197 Bool_t AliReconstruction::Run(const char* input)
1198 {
1199   // Run Run Run
1200   AliCodeTimerAuto("");
1201
1202   InitRun(input);
1203   if (GetAbort() != TSelector::kContinue) return kFALSE;
1204
1205   TChain *chain = NULL;
1206   if (fRawReader && (chain = fRawReader->GetChain())) {
1207     // Proof mode
1208     if (gProof) {
1209       gProof->AddInput(this);
1210       if (!fESDOutput.IsValid()) {
1211         fESDOutput.SetProtocol("root",kTRUE);
1212         fESDOutput.SetHost(gSystem->HostName());
1213         fESDOutput.SetFile(Form("%s/AliESDs.root",gSystem->pwd()));
1214       }
1215       AliInfo(Form("Output file with ESDs is %s",fESDOutput.GetUrl()));
1216       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",fESDOutput.GetUrl()));
1217       gProof->SetParameter("PROOF_MaxSlavesPerNode", 9999);
1218       chain->SetProof();
1219       chain->Process("AliReconstruction");
1220     }
1221     else {
1222       chain->Process(this);
1223     }
1224   }
1225   else {
1226     Begin(NULL);
1227     if (GetAbort() != TSelector::kContinue) return kFALSE;
1228     SlaveBegin(NULL);
1229     if (GetAbort() != TSelector::kContinue) return kFALSE;
1230     //******* The loop over events
1231     AliInfo("Starting looping over events");
1232     Int_t iEvent = 0;
1233     while ((iEvent < fRunLoader->GetNumberOfEvents()) ||
1234            (fRawReader && fRawReader->NextEvent())) {
1235       if (!ProcessEvent(iEvent)) {
1236         Abort("ProcessEvent",TSelector::kAbortFile);
1237         return kFALSE;
1238       }
1239       iEvent++;
1240     }
1241     SlaveTerminate();
1242     if (GetAbort() != TSelector::kContinue) return kFALSE;
1243     Terminate();
1244     if (GetAbort() != TSelector::kContinue) return kFALSE;
1245   }
1246
1247   return kTRUE;
1248 }
1249
1250 //_____________________________________________________________________________
1251 void AliReconstruction::InitRawReader(const char* input)
1252 {
1253   AliCodeTimerAuto("");
1254
1255   // Init raw-reader and
1256   // set the input in case of raw data
1257   if (input) fRawInput = input;
1258   fRawReader = AliRawReader::Create(fRawInput.Data());
1259   if (!fRawReader)
1260     AliInfo("Reconstruction will run over digits");
1261
1262   if (!fEquipIdMap.IsNull() && fRawReader)
1263     fRawReader->LoadEquipmentIdsMap(fEquipIdMap);
1264
1265   if (!fUseHLTData.IsNull()) {
1266     // create the RawReaderHLT which performs redirection of HLT input data for
1267     // the specified detectors
1268     AliRawReader* pRawReader=AliRawHLTManager::CreateRawReaderHLT(fRawReader, fUseHLTData.Data());
1269     if (pRawReader) {
1270       fParentRawReader=fRawReader;
1271       fRawReader=pRawReader;
1272     } else {
1273       AliError(Form("can not create Raw Reader for HLT input %s", fUseHLTData.Data()));
1274     }
1275   }
1276   AliSysInfo::AddStamp("CreateRawReader");
1277 }
1278
1279 //_____________________________________________________________________________
1280 void AliReconstruction::InitRun(const char* input)
1281 {
1282   // Initialization of raw-reader,
1283   // run number, CDB etc.
1284   AliCodeTimerAuto("");
1285   AliSysInfo::AddStamp("Start");
1286
1287   // Initialize raw-reader if any
1288   InitRawReader(input);
1289
1290   // Initialize the CDB storage
1291   InitCDB();
1292
1293   // Set run number in CDBManager (if it is not already set by the user)
1294   if (!SetRunNumberFromData()) {
1295     Abort("SetRunNumberFromData", TSelector::kAbortProcess);
1296     return;
1297   }
1298
1299   // Set CDB lock: from now on it is forbidden to reset the run number
1300   // or the default storage or to activate any further storage!
1301   SetCDBLock();
1302   
1303 }
1304
1305 //_____________________________________________________________________________
1306 void AliReconstruction::Begin(TTree *)
1307 {
1308   // Initialize AlReconstruction before
1309   // going into the event loop
1310   // Should follow the TSelector convention
1311   // i.e. initialize only the object on the client side
1312   AliCodeTimerAuto("");
1313
1314   AliReconstruction *reco = NULL;
1315   if (fInput) {
1316     if ((reco = (AliReconstruction*)fInput->FindObject("AliReconstruction"))) {
1317       *this = *reco;
1318     }
1319     AliSysInfo::AddStamp("ReadInputInBegin");
1320   }
1321
1322   // Import ideal TGeo geometry and apply misalignment
1323   if (!gGeoManager) {
1324     TString geom(gSystem->DirName(fGAliceFileName));
1325     geom += "/geometry.root";
1326     AliGeomManager::LoadGeometry(geom.Data());
1327     if (!gGeoManager) {
1328       Abort("LoadGeometry", TSelector::kAbortProcess);
1329       return;
1330     }
1331     AliSysInfo::AddStamp("LoadGeom");
1332     TString detsToCheck=fRunLocalReconstruction;
1333     if(!AliGeomManager::CheckSymNamesLUT(detsToCheck.Data())) {
1334       Abort("CheckSymNamesLUT", TSelector::kAbortProcess);
1335       return;
1336     }
1337     AliSysInfo::AddStamp("CheckGeom");
1338   }
1339
1340   if (!MisalignGeometry(fLoadAlignData)) {
1341     Abort("MisalignGeometry", TSelector::kAbortProcess);
1342     return;
1343   }
1344   AliCDBManager::Instance()->UnloadFromCache("GRP/Geometry/Data");
1345   AliSysInfo::AddStamp("MisalignGeom");
1346
1347   if (!InitGRP()) {
1348     Abort("InitGRP", TSelector::kAbortProcess);
1349     return;
1350   }
1351   AliSysInfo::AddStamp("InitGRP");
1352
1353   if (!LoadCDB()) {
1354     Abort("LoadCDB", TSelector::kAbortProcess);
1355     return;
1356   }
1357   AliSysInfo::AddStamp("LoadCDB");
1358
1359   // Read the reconstruction parameters from OCDB
1360   if (!InitRecoParams()) {
1361     AliWarning("Not all detectors have correct RecoParam objects initialized");
1362   }
1363   AliSysInfo::AddStamp("InitRecoParams");
1364
1365   if (fInput && gProof) {
1366     if (reco) *reco = *this;
1367
1368     gProof->AddInputData(gGeoManager,kTRUE);
1369     gGeoManager = NULL;
1370     gProof->AddInputData(const_cast<TMap*>(AliCDBManager::Instance()->GetEntryCache()),kTRUE);
1371     fInput->Add(new TParameter<Int_t>("RunNumber",AliCDBManager::Instance()->GetRun()));
1372     AliMagF *magFieldMap = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
1373     magFieldMap->SetName("MagneticFieldMap");
1374     gProof->AddInputData(magFieldMap,kTRUE);
1375   }
1376
1377 }
1378
1379 //_____________________________________________________________________________
1380 void AliReconstruction::SlaveBegin(TTree*)
1381 {
1382   // Initialization related to run-loader,
1383   // vertexer, trackers, recontructors
1384   // In proof mode it is executed on the slave
1385   AliCodeTimerAuto("");
1386
1387   TProofOutputFile *outProofFile = NULL;
1388   if (fInput) { 
1389     if (AliReconstruction *reco = (AliReconstruction*)fInput->FindObject("AliReconstruction")) {
1390       *this = *reco;
1391     }
1392     if (TGeoManager *tgeo = (TGeoManager*)fInput->FindObject("Geometry")) {
1393       gGeoManager = tgeo;
1394       AliGeomManager::SetGeometry(tgeo);
1395     }
1396     if (TMap *entryCache = (TMap*)fInput->FindObject("CDBEntryCache")) {
1397       Int_t runNumber = -1;
1398       if (TProof::GetParameter(fInput,"RunNumber",runNumber) == 0) {
1399         AliCDBManager *man = AliCDBManager::Instance(entryCache,runNumber);
1400         man->SetCacheFlag(kTRUE);
1401         man->SetLock(kTRUE);
1402         man->Print();
1403       }
1404     }
1405     if (AliMagF *map = (AliMagF*)fInput->FindObject("MagneticFieldMap")) {
1406       TGeoGlobalMagField::Instance()->SetField(map);
1407     }
1408     if (TNamed *outputFileName = (TNamed *) fInput->FindObject("PROOF_OUTPUTFILE")) {
1409       outProofFile = new TProofOutputFile(gSystem->BaseName(TUrl(outputFileName->GetTitle()).GetFile()));
1410       outProofFile->SetOutputFileName(outputFileName->GetTitle());
1411       fOutput->Add(outProofFile);
1412     }
1413     AliSysInfo::AddStamp("ReadInputInSlaveBegin");
1414   }
1415
1416   // get the run loader
1417   if (!InitRunLoader()) {
1418     Abort("InitRunLoader", TSelector::kAbortProcess);
1419     return;
1420   }
1421   AliSysInfo::AddStamp("LoadLoader");
1422  
1423   ftVertexer = new AliVertexerTracks(AliTracker::GetBz());
1424
1425   // get trackers
1426   if (!fRunTracking.IsNull() && !CreateTrackers(fRunTracking)) {
1427     Abort("CreateTrackers", TSelector::kAbortProcess);
1428     return;
1429   }      
1430   AliSysInfo::AddStamp("CreateTrackers");
1431
1432   // create the ESD output file and tree
1433   if (!outProofFile) {
1434     ffile = TFile::Open("AliESDs.root", "RECREATE");
1435     ffile->SetCompressionLevel(2);
1436     if (!ffile->IsOpen()) {
1437       Abort("OpenESDFile", TSelector::kAbortProcess);
1438       return;
1439     }
1440   }
1441   else {
1442     if (!(ffile = outProofFile->OpenFile("RECREATE"))) {
1443       Abort(Form("Problems opening output PROOF file: %s/%s",
1444                  outProofFile->GetDir(), outProofFile->GetFileName()),
1445             TSelector::kAbortProcess);
1446       return;
1447     }
1448   }
1449
1450   ftree = new TTree("esdTree", "Tree with ESD objects");
1451   fesd = new AliESDEvent();
1452   fesd->CreateStdContent();
1453
1454   fesd->WriteToTree(ftree);
1455   if (fWriteESDfriend) {
1456     // careful:
1457     // Since we add the branch manually we must 
1458     // book and add it after WriteToTree
1459     // otherwise it is created twice,
1460     // once via writetotree and once here.
1461     // The case for AliESDfriend is now 
1462     // caught also in AlIESDEvent::WriteToTree but 
1463     // be careful when changing the name (AliESDfriend is not 
1464     // a TNamed so we had to hardwire it)
1465     fesdf = new AliESDfriend();
1466     TBranch *br=ftree->Branch("ESDfriend.","AliESDfriend", &fesdf);
1467     br->SetFile("AliESDfriends.root");
1468     fesd->AddObject(fesdf);
1469   }
1470   ftree->GetUserInfo()->Add(fesd);
1471
1472   fhlttree = new TTree("HLTesdTree", "Tree with HLT ESD objects");
1473   fhltesd = new AliESDEvent();
1474   fhltesd->CreateStdContent();
1475
1476   // read the ESD template from CDB
1477   // HLT is allowed to put non-std content to its ESD, the non-std
1478   // objects need to be created before invocation of WriteToTree in
1479   // order to create all branches. Initialization is done from an
1480   // ESD layout template in CDB
1481   AliCDBManager* man = AliCDBManager::Instance();
1482   AliCDBPath hltESDConfigPath("HLT/ConfigHLT/esdLayout");
1483   AliCDBEntry* hltESDConfig=NULL;
1484   if (man->GetId(hltESDConfigPath)!=NULL &&
1485       (hltESDConfig=man->Get(hltESDConfigPath))!=NULL) {
1486     AliESDEvent* pESDLayout=dynamic_cast<AliESDEvent*>(hltESDConfig->GetObject());
1487     if (pESDLayout) {
1488       // init all internal variables from the list of objects
1489       pESDLayout->GetStdContent();
1490
1491       // copy content and create non-std objects
1492       *fhltesd=*pESDLayout;
1493       fhltesd->Reset();
1494     } else {
1495       AliError(Form("error setting hltEsd layout from %s: invalid object type",
1496                     hltESDConfigPath.GetPath().Data()));
1497     }
1498   }
1499
1500   fhltesd->WriteToTree(fhlttree);
1501   fhlttree->GetUserInfo()->Add(fhltesd);
1502
1503   ProcInfo_t procInfo;
1504   gSystem->GetProcInfo(&procInfo);
1505   AliInfo(Form("Current memory usage %d %d", procInfo.fMemResident, procInfo.fMemVirtual));
1506   
1507   //QA
1508   //Initialize the QA and start of cycle 
1509   if (fRunQA || fRunGlobalQA) 
1510     InitQA() ; 
1511
1512   //Initialize the Plane Efficiency framework
1513   if (fRunPlaneEff && !InitPlaneEff()) {
1514     Abort("InitPlaneEff", TSelector::kAbortProcess);
1515     return;
1516   }
1517
1518   if (strcmp(gProgName,"alieve") == 0)
1519     fRunAliEVE = InitAliEVE();
1520
1521   return;
1522 }
1523
1524 //_____________________________________________________________________________
1525 Bool_t AliReconstruction::Process(Long64_t entry)
1526 {
1527   // run the reconstruction over a single entry
1528   // from the chain with raw data
1529   AliCodeTimerAuto("");
1530
1531   TTree *currTree = fChain->GetTree();
1532   AliRawVEvent *event = NULL;
1533   currTree->SetBranchAddress("rawevent",&event);
1534   currTree->GetEntry(entry);
1535   fRawReader = new AliRawReaderRoot(event);
1536   fStatus = ProcessEvent(fRunLoader->GetNumberOfEvents());  
1537   delete fRawReader;
1538   fRawReader = NULL;
1539   delete event;
1540
1541   return fStatus;
1542 }
1543
1544 //_____________________________________________________________________________
1545 void AliReconstruction::Init(TTree *tree)
1546 {
1547   if (tree == 0) {
1548     AliError("The input tree is not found!");
1549     return;
1550   }
1551   fChain = tree;
1552 }
1553
1554 //_____________________________________________________________________________
1555 Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
1556 {
1557   // run the reconstruction over a single event
1558   // The event loop is steered in Run method
1559
1560   AliCodeTimerAuto("");
1561
1562   if (iEvent >= fRunLoader->GetNumberOfEvents()) {
1563     fRunLoader->SetEventNumber(iEvent);
1564     fRunLoader->GetHeader()->Reset(fRawReader->GetRunNumber(), 
1565                                    iEvent, iEvent);
1566     fRunLoader->TreeE()->Fill();
1567     if (fRawReader && fRawReader->UseAutoSaveESD())
1568       fRunLoader->TreeE()->AutoSave("SaveSelf");
1569   }
1570
1571   if ((iEvent < fFirstEvent) || ((fLastEvent >= 0) && (iEvent > fLastEvent))) {
1572     return kTRUE;
1573   }
1574
1575   AliInfo(Form("processing event %d", iEvent));
1576
1577   fRunLoader->GetEvent(iEvent);
1578
1579   // Fill Event-info object
1580   GetEventInfo();
1581   fRecoParam.SetEventSpecie(fRunInfo,fEventInfo);
1582   AliInfo(Form("Current event specie: %s",fRecoParam.PrintEventSpecie()));
1583
1584   // Set the reco-params
1585   {
1586     TString detStr = fLoadCDB;
1587     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1588       if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1589       AliReconstructor *reconstructor = GetReconstructor(iDet);
1590       if (reconstructor && fRecoParam.GetDetRecoParamArray(iDet)) {
1591         const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
1592         reconstructor->SetRecoParam(par);
1593         if (fRunQA) {
1594           fQAManager->SetRecoParam(iDet, par) ; 
1595         }
1596       }
1597     }
1598   }
1599
1600     // QA on single raw 
1601   if (fRunQA) {
1602     fQAManager->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
1603     fQAManager->RunOneEvent(fRawReader) ;  
1604   }
1605     // local single event reconstruction
1606     if (!fRunLocalReconstruction.IsNull()) {
1607       TString detectors=fRunLocalReconstruction;
1608       // run HLT event reconstruction first
1609       // ;-( IsSelected changes the string
1610       if (IsSelected("HLT", detectors) &&
1611           !RunLocalEventReconstruction("HLT")) {
1612         if (fStopOnError) {CleanUp(); return kFALSE;}
1613       }
1614       detectors=fRunLocalReconstruction;
1615       detectors.ReplaceAll("HLT", "");
1616       if (!RunLocalEventReconstruction(detectors)) {
1617         if (fStopOnError) {CleanUp(); return kFALSE;}
1618       }
1619     }
1620
1621     fesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
1622     fhltesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
1623     fesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
1624     fhltesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
1625     
1626     // Set magnetic field from the tracker
1627     fesd->SetMagneticField(AliTracker::GetBz());
1628     fhltesd->SetMagneticField(AliTracker::GetBz());
1629
1630     // Set most probable pt, for B=0 tracking
1631     // Get the global reco-params. They are atposition 16 inside the array of detectors in fRecoParam
1632     const AliGRPRecoParam *grpRecoParam = dynamic_cast<const AliGRPRecoParam*>(fRecoParam.GetDetRecoParam(kNDetectors));
1633     if (grpRecoParam) AliExternalTrackParam::SetMostProbablePt(grpRecoParam->GetMostProbablePt());
1634     
1635     // Fill raw-data error log into the ESD
1636     if (fRawReader) FillRawDataErrorLog(iEvent,fesd);
1637
1638     // vertex finder
1639     if (fRunVertexFinder) {
1640       if (!RunVertexFinder(fesd)) {
1641         if (fStopOnError) {CleanUp(); return kFALSE;}
1642       }
1643     }
1644
1645     // For Plane Efficiency: run the SPD trackleter
1646     if (fRunPlaneEff && fSPDTrackleter) {
1647       if (!RunSPDTrackleting(fesd)) {
1648         if (fStopOnError) {CleanUp(); return kFALSE;}
1649       }
1650     }
1651
1652     // Muon tracking
1653     if (!fRunTracking.IsNull()) {
1654       if (fRunMuonTracking) {
1655         if (!RunMuonTracking(fesd)) {
1656           if (fStopOnError) {CleanUp(); return kFALSE;}
1657         }
1658       }
1659     }
1660
1661     // barrel tracking
1662     if (!fRunTracking.IsNull()) {
1663       if (!RunTracking(fesd)) {
1664         if (fStopOnError) {CleanUp(); return kFALSE;}
1665       }
1666     }
1667
1668     // fill ESD
1669     if (!fFillESD.IsNull()) {
1670       TString detectors=fFillESD;
1671       // run HLT first and on hltesd
1672       // ;-( IsSelected changes the string
1673       if (IsSelected("HLT", detectors) &&
1674           !FillESD(fhltesd, "HLT")) {
1675         if (fStopOnError) {CleanUp(); return kFALSE;}
1676       }
1677       detectors=fFillESD;
1678       // Temporary fix to avoid problems with HLT that overwrites the offline ESDs
1679       if (detectors.Contains("ALL")) {
1680         detectors="";
1681         for (Int_t idet=0; idet<kNDetectors; ++idet){
1682           detectors += fgkDetectorName[idet];
1683           detectors += " ";
1684         }
1685       }
1686       detectors.ReplaceAll("HLT", "");
1687       if (!FillESD(fesd, detectors)) {
1688         if (fStopOnError) {CleanUp(); return kFALSE;}
1689       }
1690     }
1691   
1692     // fill Event header information from the RawEventHeader
1693     if (fRawReader){FillRawEventHeaderESD(fesd);}
1694
1695     // combined PID
1696     AliESDpid::MakePID(fesd);
1697
1698     if (fFillTriggerESD) {
1699       if (!FillTriggerESD(fesd)) {
1700         if (fStopOnError) {CleanUp(); return kFALSE;}
1701       }
1702     }
1703
1704     ffile->cd();
1705
1706     //
1707     // Propagate track to the beam pipe  (if not already done by ITS)
1708     //
1709     const Int_t ntracks = fesd->GetNumberOfTracks();
1710     const Double_t kBz = fesd->GetMagneticField();
1711     const Double_t kRadius  = 2.8; //something less than the beam pipe radius
1712
1713     TObjArray trkArray;
1714     UShort_t *selectedIdx=new UShort_t[ntracks];
1715
1716     for (Int_t itrack=0; itrack<ntracks; itrack++){
1717       const Double_t kMaxStep = 1;   //max step over the material
1718       Bool_t ok;
1719
1720       AliESDtrack *track = fesd->GetTrack(itrack);
1721       if (!track) continue;
1722
1723       AliExternalTrackParam *tpcTrack =
1724            (AliExternalTrackParam *)track->GetTPCInnerParam();
1725       ok = kFALSE;
1726       if (tpcTrack)
1727         ok = AliTracker::
1728           PropagateTrackTo(tpcTrack,kRadius,track->GetMass(),kMaxStep,kFALSE);
1729
1730       if (ok) {
1731         Int_t n=trkArray.GetEntriesFast();
1732         selectedIdx[n]=track->GetID();
1733         trkArray.AddLast(tpcTrack);
1734       }
1735
1736       //Tracks refitted by ITS should already be at the SPD vertex
1737       if (track->IsOn(AliESDtrack::kITSrefit)) continue;
1738
1739       AliTracker::
1740          PropagateTrackTo(track,kRadius,track->GetMass(),kMaxStep,kFALSE);
1741       track->RelateToVertex(fesd->GetPrimaryVertexSPD(), kBz, kVeryBig);
1742
1743     }
1744
1745     //
1746     // Improve the reconstructed primary vertex position using the tracks
1747     //
1748     Bool_t runVertexFinderTracks = fRunVertexFinderTracks;
1749     if(fesd->GetPrimaryVertexSPD()) {
1750       TString vtitle = fesd->GetPrimaryVertexSPD()->GetTitle();
1751       if(vtitle.Contains("cosmics")) {
1752         runVertexFinderTracks=kFALSE;
1753       }
1754     }
1755
1756     if (runVertexFinderTracks) {
1757        // TPC + ITS primary vertex
1758        ftVertexer->SetITSMode();
1759        ftVertexer->SetConstraintOff();
1760        // get cuts for vertexer from AliGRPRecoParam
1761        if (grpRecoParam) {
1762          Int_t nCutsVertexer = grpRecoParam->GetVertexerTracksNCuts();
1763          Double_t *cutsVertexer = new Double_t[nCutsVertexer];
1764          grpRecoParam->GetVertexerTracksCutsITS(cutsVertexer);
1765          ftVertexer->SetCuts(cutsVertexer);
1766          delete [] cutsVertexer; cutsVertexer = NULL; 
1767          if(fDiamondProfile && grpRecoParam->GetVertexerTracksConstraintITS())
1768            ftVertexer->SetVtxStart(fDiamondProfile);
1769        }
1770        AliESDVertex *pvtx=ftVertexer->FindPrimaryVertex(fesd);
1771        if (pvtx) {
1772           if (pvtx->GetStatus()) {
1773              fesd->SetPrimaryVertexTracks(pvtx);
1774              for (Int_t i=0; i<ntracks; i++) {
1775                  AliESDtrack *t = fesd->GetTrack(i);
1776                  t->RelateToVertex(pvtx, kBz, kVeryBig);
1777              } 
1778           }
1779        }
1780
1781        // TPC-only primary vertex
1782        ftVertexer->SetTPCMode();
1783        ftVertexer->SetConstraintOff();
1784        // get cuts for vertexer from AliGRPRecoParam
1785        if (grpRecoParam) {
1786          Int_t nCutsVertexer = grpRecoParam->GetVertexerTracksNCuts();
1787          Double_t *cutsVertexer = new Double_t[nCutsVertexer];
1788          grpRecoParam->GetVertexerTracksCutsTPC(cutsVertexer);
1789          ftVertexer->SetCuts(cutsVertexer);
1790          delete [] cutsVertexer; cutsVertexer = NULL; 
1791          if(fDiamondProfileTPC && grpRecoParam->GetVertexerTracksConstraintTPC())
1792            ftVertexer->SetVtxStart(fDiamondProfileTPC);
1793        }
1794        pvtx=ftVertexer->FindPrimaryVertex(&trkArray,selectedIdx);
1795        if (pvtx) {
1796           if (pvtx->GetStatus()) {
1797              fesd->SetPrimaryVertexTPC(pvtx);
1798              for (Int_t i=0; i<ntracks; i++) {
1799                  AliESDtrack *t = fesd->GetTrack(i);
1800                  t->RelateToVertexTPC(pvtx, kBz, kVeryBig);
1801              } 
1802           }
1803        }
1804
1805     }
1806     delete[] selectedIdx;
1807
1808     if(fDiamondProfile) fesd->SetDiamond(fDiamondProfile);
1809     
1810
1811     if (fRunV0Finder) {
1812        // V0 finding
1813        AliV0vertexer vtxer;
1814        vtxer.Tracks2V0vertices(fesd);
1815
1816        if (fRunCascadeFinder) {
1817           // Cascade finding
1818           AliCascadeVertexer cvtxer;
1819           cvtxer.V0sTracks2CascadeVertices(fesd);
1820        }
1821     }
1822  
1823     // write ESD
1824     if (fCleanESD) CleanESD(fesd);
1825
1826   if (fRunQA) {
1827     fQAManager->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
1828     fQAManager->RunOneEvent(fesd) ; 
1829   }
1830   if (fRunGlobalQA) {
1831       AliQADataMaker *qadm = fQAManager->GetQADataMaker(AliQAv1::kGLOBAL);
1832       qadm->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
1833     if (qadm && fQATasks.Contains(Form("%d", AliQAv1::kESDS)))
1834       qadm->Exec(AliQAv1::kESDS, fesd);
1835   }
1836
1837     if (fWriteESDfriend) {
1838       //      fesdf->~AliESDfriend();
1839       //  new (fesdf) AliESDfriend(); // Reset...
1840       fesd->GetESDfriend(fesdf);
1841     }
1842     ftree->Fill();
1843
1844     // Auto-save the ESD tree in case of prompt reco @P2
1845     if (fRawReader && fRawReader->UseAutoSaveESD()) {
1846       ftree->AutoSave("SaveSelf");
1847       TFile *friendfile = (TFile *)(gROOT->GetListOfFiles()->FindObject("AliESDfriends.root"));
1848       if (friendfile) friendfile->Save();
1849     }
1850
1851     // write HLT ESD
1852     fhlttree->Fill();
1853
1854     // call AliEVE
1855     if (fRunAliEVE) RunAliEVE();
1856
1857     fesd->Reset();
1858     fhltesd->Reset();
1859     if (fWriteESDfriend) {
1860       fesdf->~AliESDfriend();
1861       new (fesdf) AliESDfriend(); // Reset...
1862     }
1863  
1864     ProcInfo_t procInfo;
1865     gSystem->GetProcInfo(&procInfo);
1866     AliInfo(Form("Event %d -> Current memory usage %d %d",iEvent, procInfo.fMemResident, procInfo.fMemVirtual));
1867   
1868     fEventInfo.Reset();
1869     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1870       if (fReconstructor[iDet])
1871         fReconstructor[iDet]->SetRecoParam(NULL);
1872     }
1873         
1874   if (fRunQA || fRunGlobalQA) 
1875       fQAManager->Increment() ; 
1876   
1877     return kTRUE;
1878 }
1879
1880 //_____________________________________________________________________________
1881 void AliReconstruction::SlaveTerminate()
1882 {
1883   // Finalize the run on the slave side
1884   // Called after the exit
1885   // from the event loop
1886   AliCodeTimerAuto("");
1887
1888   if (fIsNewRunLoader) { // galice.root didn't exist
1889     fRunLoader->WriteHeader("OVERWRITE");
1890     fRunLoader->CdGAFile();
1891     fRunLoader->Write(0, TObject::kOverwrite);
1892   }
1893
1894   const TMap *cdbMap = AliCDBManager::Instance()->GetStorageMap();       
1895   const TList *cdbList = AliCDBManager::Instance()->GetRetrievedIds();   
1896                  
1897    TMap *cdbMapCopy = new TMap(cdbMap->GetEntries());    
1898    cdbMapCopy->SetOwner(1);      
1899    cdbMapCopy->SetName("cdbMap");        
1900    TIter iter(cdbMap->GetTable());       
1901          
1902    TPair* pair = 0;      
1903    while((pair = dynamic_cast<TPair*> (iter.Next()))){   
1904          TObjString* keyStr = dynamic_cast<TObjString*> (pair->Key());   
1905          TObjString* valStr = dynamic_cast<TObjString*> (pair->Value());         
1906          cdbMapCopy->Add(new TObjString(keyStr->GetName()), new TObjString(valStr->GetName()));  
1907    }     
1908          
1909    TList *cdbListCopy = new TList();     
1910    cdbListCopy->SetOwner(1);     
1911    cdbListCopy->SetName("cdbList");      
1912          
1913    TIter iter2(cdbList);         
1914          
1915         AliCDBId* id=0;
1916         while((id = dynamic_cast<AliCDBId*> (iter2.Next()))){    
1917          cdbListCopy->Add(new TObjString(id->ToString().Data()));        
1918    }     
1919          
1920    ftree->GetUserInfo()->Add(cdbMapCopy);        
1921    ftree->GetUserInfo()->Add(cdbListCopy);
1922
1923
1924   ffile->cd();
1925
1926   if (fWriteESDfriend)
1927     ftree->SetBranchStatus("ESDfriend*",0);
1928   // we want to have only one tree version number
1929   ftree->Write(ftree->GetName(),TObject::kOverwrite);
1930   fhlttree->Write();
1931
1932 // Finish with Plane Efficiency evaluation: before of CleanUp !!!
1933   if (fRunPlaneEff && !FinishPlaneEff()) {
1934    AliWarning("Finish PlaneEff evaluation failed");
1935   }
1936
1937   // End of cycle for the in-loop  
1938   if (fRunQA) 
1939     fQAManager->EndOfCycle() ;
1940   
1941   if (fRunGlobalQA) {
1942     AliQADataMaker *qadm = fQAManager->GetQADataMaker(AliQAv1::kGLOBAL);
1943     if (qadm) {
1944       if (fQATasks.Contains(Form("%d", AliQAv1::kRECPOINTS))) 
1945         qadm->EndOfCycle(AliQAv1::kRECPOINTS);
1946       if (fQATasks.Contains(Form("%d", AliQAv1::kESDS))) 
1947         qadm->EndOfCycle(AliQAv1::kESDS);
1948       qadm->Finish();
1949     }
1950   }
1951
1952   if (fRunQA || fRunGlobalQA) {
1953     if (fInput) { 
1954       if (TNamed *outputFileName = (TNamed *) fInput->FindObject("PROOF_OUTPUTFILE")) {
1955         TString qaOutputFile = outputFileName->GetTitle();
1956         qaOutputFile.ReplaceAll(gSystem->BaseName(TUrl(outputFileName->GetTitle()).GetFile()),
1957                                 Form("Merged.%s.Data.root",AliQAv1::GetQADataFileName()));
1958         TProofOutputFile *qaProofFile = new TProofOutputFile(Form("Merged.%s.Data.root",AliQAv1::GetQADataFileName()));
1959         qaProofFile->SetOutputFileName(qaOutputFile.Data());
1960         fOutput->Add(qaProofFile);
1961         MergeQA(qaProofFile->GetFileName());
1962       }
1963     }
1964     else {
1965       MergeQA();
1966     }
1967   }
1968
1969   gROOT->cd();
1970   CleanUp();
1971 }
1972     
1973 //_____________________________________________________________________________
1974 void AliReconstruction::Terminate()
1975 {
1976   // Create tags for the events in the ESD tree (the ESD tree is always present)
1977   // In case of empty events the tags will contain dummy values
1978   AliCodeTimerAuto("");
1979
1980   AliESDTagCreator *esdtagCreator = new AliESDTagCreator();
1981   esdtagCreator->CreateESDTags(fFirstEvent,fLastEvent,fGRPData, AliQAv1::Instance()->GetQA(), AliQAv1::Instance()->GetEventSpecies(), AliQAv1::kNDET, AliRecoParam::kNSpecies);
1982
1983   // Cleanup of CDB manager: cache and active storages!
1984   AliCDBManager::Instance()->ClearCache();
1985 }
1986
1987 //_____________________________________________________________________________
1988 Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
1989 {
1990 // run the local reconstruction
1991
1992   static Int_t eventNr=0;
1993   AliCodeTimerAuto("")
1994
1995   TString detStr = detectors;
1996   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1997     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1998     AliReconstructor* reconstructor = GetReconstructor(iDet);
1999     if (!reconstructor) continue;
2000     AliLoader* loader = fLoader[iDet];
2001     // Matthias April 2008: temporary fix to run HLT reconstruction
2002     // although the HLT loader is missing
2003     if (strcmp(fgkDetectorName[iDet], "HLT")==0) {
2004       if (fRawReader) {
2005         reconstructor->Reconstruct(fRawReader, NULL);
2006       } else {
2007         TTree* dummy=NULL;
2008         reconstructor->Reconstruct(dummy, NULL);
2009       }
2010       continue;
2011     }
2012     if (!loader) {
2013       AliWarning(Form("No loader is defined for %s!",fgkDetectorName[iDet]));
2014       continue;
2015     }
2016     // conversion of digits
2017     if (fRawReader && reconstructor->HasDigitConversion()) {
2018       AliInfo(Form("converting raw data digits into root objects for %s", 
2019                    fgkDetectorName[iDet]));
2020 //      AliCodeTimerAuto(Form("converting raw data digits into root objects for %s", 
2021 //                            fgkDetectorName[iDet]));
2022       loader->LoadDigits("update");
2023       loader->CleanDigits();
2024       loader->MakeDigitsContainer();
2025       TTree* digitsTree = loader->TreeD();
2026       reconstructor->ConvertDigits(fRawReader, digitsTree);
2027       loader->WriteDigits("OVERWRITE");
2028       loader->UnloadDigits();
2029     }
2030     // local reconstruction
2031     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
2032     //AliCodeTimerAuto(Form("running reconstruction for %s", fgkDetectorName[iDet]));
2033     loader->LoadRecPoints("update");
2034     loader->CleanRecPoints();
2035     loader->MakeRecPointsContainer();
2036     TTree* clustersTree = loader->TreeR();
2037     if (fRawReader && !reconstructor->HasDigitConversion()) {
2038       reconstructor->Reconstruct(fRawReader, clustersTree);
2039     } else {
2040       loader->LoadDigits("read");
2041       TTree* digitsTree = loader->TreeD();
2042       if (!digitsTree) {
2043         AliError(Form("Can't get the %s digits tree", fgkDetectorName[iDet]));
2044         if (fStopOnError) return kFALSE;
2045       } else {
2046         reconstructor->Reconstruct(digitsTree, clustersTree);
2047         if (fRunQA) {
2048           fQAManager->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2049           fQAManager->RunOneEventInOneDetector(iDet, digitsTree) ; 
2050         }
2051       }
2052       loader->UnloadDigits();
2053     }
2054
2055                 TString detQAStr(fQADetectors) ; 
2056                 if (fRunQA) {
2057       fQAManager->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2058                         fQAManager->RunOneEventInOneDetector(iDet, clustersTree) ; 
2059     }
2060         loader->WriteRecPoints("OVERWRITE");
2061         loader->UnloadRecPoints();
2062         AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr), iDet,1,eventNr);
2063   }
2064   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2065     AliError(Form("the following detectors were not found: %s",
2066                   detStr.Data()));
2067     if (fStopOnError) return kFALSE;
2068   }
2069   eventNr++;
2070   return kTRUE;
2071 }
2072 //_____________________________________________________________________________
2073 Bool_t AliReconstruction::RunSPDTrackleting(AliESDEvent*& esd)
2074 {
2075 // run the SPD trackleting (for SPD efficiency purpouses)
2076
2077   AliCodeTimerAuto("")
2078
2079   Double_t vtxPos[3] = {0, 0, 0};
2080   Double_t vtxErr[3] = {0.0, 0.0, 0.0};
2081 /*
2082   TArrayF mcVertex(3);
2083   // if(MC)
2084   if (fRunLoader->GetHeader() && fRunLoader->GetHeader()->GenEventHeader()) {
2085     fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(mcVertex);
2086     for (Int_t i = 0; i < 3; i++) vtxPos[i] = mcVertex[i];
2087   }
2088 */
2089   const AliESDVertex *vertex = esd->GetVertex();
2090   if(!vertex){
2091     AliWarning("Vertex not found");
2092     return kFALSE;
2093   }
2094   vertex->GetXYZ(vtxPos);
2095   vertex->GetSigmaXYZ(vtxErr);
2096   if (fSPDTrackleter) {
2097     AliInfo("running the SPD Trackleter for Plane Efficiency Evaluation");
2098
2099     // load clusters
2100     fLoader[0]->LoadRecPoints("read");
2101     TTree* tree = fLoader[0]->TreeR();
2102     if (!tree) {
2103       AliError("Can't get the ITS cluster tree");
2104       return kFALSE;
2105     }
2106     fSPDTrackleter->LoadClusters(tree);
2107     fSPDTrackleter->SetVertex(vtxPos, vtxErr);
2108     // run trackleting
2109     if (fSPDTrackleter->Clusters2Tracks(esd) != 0) {
2110       AliError("AliITSTrackleterSPDEff Clusters2Tracks failed");
2111      // fLoader[0]->UnloadRecPoints();
2112       return kFALSE;
2113     }
2114 //fSPDTrackleter->UnloadRecPoints();
2115   } else {
2116     AliWarning("SPDTrackleter not available");
2117     return kFALSE;
2118   }
2119   return kTRUE;
2120 }
2121
2122 //_____________________________________________________________________________
2123 Bool_t AliReconstruction::RunVertexFinder(AliESDEvent*& esd)
2124 {
2125 // run the barrel tracking
2126
2127   AliCodeTimerAuto("")
2128
2129   AliVertexer *vertexer = CreateVertexer();
2130   if (!vertexer) return kFALSE;
2131
2132   AliInfo("running the ITS vertex finder");
2133   AliESDVertex* vertex = NULL;
2134   if (fLoader[0]) {
2135     fLoader[0]->LoadRecPoints();
2136     TTree* cltree = fLoader[0]->TreeR();
2137     if (cltree) {
2138       if(fDiamondProfileSPD) vertexer->SetVtxStart(fDiamondProfileSPD);
2139       vertex = vertexer->FindVertexForCurrentEvent(cltree);
2140     }
2141     else {
2142       AliError("Can't get the ITS cluster tree");
2143     }
2144     fLoader[0]->UnloadRecPoints();
2145   }
2146   else {
2147     AliError("Can't get the ITS loader");
2148   }
2149   if(!vertex){
2150     AliWarning("Vertex not found");
2151     vertex = new AliESDVertex();
2152     vertex->SetName("default");
2153   }
2154   else {
2155     vertex->SetName("reconstructed");
2156   }
2157
2158   Double_t vtxPos[3];
2159   Double_t vtxErr[3];
2160   vertex->GetXYZ(vtxPos);
2161   vertex->GetSigmaXYZ(vtxErr);
2162
2163   esd->SetPrimaryVertexSPD(vertex);
2164   AliESDVertex *vpileup = NULL;
2165   Int_t novertices = 0;
2166   vpileup = vertexer->GetAllVertices(novertices);
2167   if(novertices>1){
2168     for (Int_t kk=1; kk<novertices; kk++)esd->AddPileupVertexSPD(&vpileup[kk]);
2169   }
2170   // if SPD multiplicity has been determined, it is stored in the ESD
2171   AliMultiplicity *mult = vertexer->GetMultiplicity();
2172   if(mult)esd->SetMultiplicity(mult);
2173
2174   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2175     if (fTracker[iDet]) fTracker[iDet]->SetVertex(vtxPos, vtxErr);
2176   }  
2177   delete vertex;
2178
2179   delete vertexer;
2180
2181   return kTRUE;
2182 }
2183
2184 //_____________________________________________________________________________
2185 Bool_t AliReconstruction::RunHLTTracking(AliESDEvent*& esd)
2186 {
2187 // run the HLT barrel tracking
2188
2189   AliCodeTimerAuto("")
2190
2191   if (!fRunLoader) {
2192     AliError("Missing runLoader!");
2193     return kFALSE;
2194   }
2195
2196   AliInfo("running HLT tracking");
2197
2198   // Get a pointer to the HLT reconstructor
2199   AliReconstructor *reconstructor = GetReconstructor(kNDetectors-1);
2200   if (!reconstructor) return kFALSE;
2201
2202   // TPC + ITS
2203   for (Int_t iDet = 1; iDet >= 0; iDet--) {
2204     TString detName = fgkDetectorName[iDet];
2205     AliDebug(1, Form("%s HLT tracking", detName.Data()));
2206     reconstructor->SetOption(detName.Data());
2207     AliTracker *tracker = reconstructor->CreateTracker();
2208     if (!tracker) {
2209       AliWarning(Form("couldn't create a HLT tracker for %s", detName.Data()));
2210       if (fStopOnError) return kFALSE;
2211       continue;
2212     }
2213     Double_t vtxPos[3];
2214     Double_t vtxErr[3]={0.005,0.005,0.010};
2215     const AliESDVertex *vertex = esd->GetVertex();
2216     vertex->GetXYZ(vtxPos);
2217     tracker->SetVertex(vtxPos,vtxErr);
2218     if(iDet != 1) {
2219       fLoader[iDet]->LoadRecPoints("read");
2220       TTree* tree = fLoader[iDet]->TreeR();
2221       if (!tree) {
2222         AliError(Form("Can't get the %s cluster tree", detName.Data()));
2223         return kFALSE;
2224       }
2225       tracker->LoadClusters(tree);
2226     }
2227     if (tracker->Clusters2Tracks(esd) != 0) {
2228       AliError(Form("HLT %s Clusters2Tracks failed", fgkDetectorName[iDet]));
2229       return kFALSE;
2230     }
2231     if(iDet != 1) {
2232       tracker->UnloadClusters();
2233     }
2234     delete tracker;
2235   }
2236
2237   return kTRUE;
2238 }
2239
2240 //_____________________________________________________________________________
2241 Bool_t AliReconstruction::RunMuonTracking(AliESDEvent*& esd)
2242 {
2243 // run the muon spectrometer tracking
2244
2245   AliCodeTimerAuto("")
2246
2247   if (!fRunLoader) {
2248     AliError("Missing runLoader!");
2249     return kFALSE;
2250   }
2251   Int_t iDet = 7; // for MUON
2252
2253   AliInfo("is running...");
2254
2255   // Get a pointer to the MUON reconstructor
2256   AliReconstructor *reconstructor = GetReconstructor(iDet);
2257   if (!reconstructor) return kFALSE;
2258
2259   
2260   TString detName = fgkDetectorName[iDet];
2261   AliDebug(1, Form("%s tracking", detName.Data()));
2262   AliTracker *tracker =  reconstructor->CreateTracker();
2263   if (!tracker) {
2264     AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
2265     return kFALSE;
2266   }
2267      
2268   // read RecPoints
2269   fLoader[iDet]->LoadRecPoints("read");  
2270
2271   tracker->LoadClusters(fLoader[iDet]->TreeR());
2272   
2273   Int_t rv = tracker->Clusters2Tracks(esd);
2274   
2275   if ( rv )
2276   {
2277     AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
2278     return kFALSE;
2279   }
2280   
2281   fLoader[iDet]->UnloadRecPoints();
2282
2283   tracker->UnloadClusters();
2284   
2285   delete tracker;
2286   
2287   return kTRUE;
2288 }
2289
2290
2291 //_____________________________________________________________________________
2292 Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd)
2293 {
2294 // run the barrel tracking
2295   static Int_t eventNr=0;
2296   AliCodeTimerAuto("")
2297
2298   AliInfo("running tracking");
2299
2300   //Fill the ESD with the T0 info (will be used by the TOF) 
2301   if (fReconstructor[11] && fLoader[11]) {
2302     fLoader[11]->LoadRecPoints("READ");
2303     TTree *treeR = fLoader[11]->TreeR();
2304     if (treeR) {
2305       GetReconstructor(11)->FillESD((TTree *)NULL,treeR,esd);
2306     }
2307   }
2308
2309   // pass 1: TPC + ITS inwards
2310   for (Int_t iDet = 1; iDet >= 0; iDet--) {
2311     if (!fTracker[iDet]) continue;
2312     AliDebug(1, Form("%s tracking", fgkDetectorName[iDet]));
2313
2314     // load clusters
2315     fLoader[iDet]->LoadRecPoints("read");
2316     AliSysInfo::AddStamp(Form("RLoadCluster%s_%d",fgkDetectorName[iDet],eventNr),iDet,1, eventNr);
2317     TTree* tree = fLoader[iDet]->TreeR();
2318     if (!tree) {
2319       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
2320       return kFALSE;
2321     }
2322     fTracker[iDet]->LoadClusters(tree);
2323     AliSysInfo::AddStamp(Form("TLoadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
2324     // run tracking
2325     if (fTracker[iDet]->Clusters2Tracks(esd) != 0) {
2326       AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
2327       return kFALSE;
2328     }
2329     // preliminary PID in TPC needed by the ITS tracker
2330     if (iDet == 1) {
2331       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
2332       AliESDpid::MakePID(esd);
2333     } 
2334     AliSysInfo::AddStamp(Form("Tracking0%s_%d",fgkDetectorName[iDet],eventNr), iDet,3,eventNr);
2335   }
2336
2337   // pass 2: ALL backwards
2338
2339   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2340     if (!fTracker[iDet]) continue;
2341     AliDebug(1, Form("%s back propagation", fgkDetectorName[iDet]));
2342
2343     // load clusters
2344     if (iDet > 1) {     // all except ITS, TPC
2345       TTree* tree = NULL;
2346       fLoader[iDet]->LoadRecPoints("read");
2347       AliSysInfo::AddStamp(Form("RLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,1, eventNr);
2348       tree = fLoader[iDet]->TreeR();
2349       if (!tree) {
2350         AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
2351         return kFALSE;
2352       }
2353       fTracker[iDet]->LoadClusters(tree); 
2354       AliSysInfo::AddStamp(Form("TLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
2355     }
2356
2357     // run tracking
2358     if (iDet>1) // start filling residuals for the "outer" detectors
2359     if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
2360
2361     if (fTracker[iDet]->PropagateBack(esd) != 0) {
2362       AliError(Form("%s backward propagation failed", fgkDetectorName[iDet]));
2363       //      return kFALSE;
2364     }
2365
2366     // unload clusters
2367     if (iDet > 3) {     // all except ITS, TPC, TRD and TOF
2368       fTracker[iDet]->UnloadClusters();
2369       fLoader[iDet]->UnloadRecPoints();
2370     }
2371     // updated PID in TPC needed by the ITS tracker -MI
2372     if (iDet == 1) {
2373       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
2374       AliESDpid::MakePID(esd);
2375     }
2376     AliSysInfo::AddStamp(Form("Tracking1%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
2377   }
2378   //stop filling residuals for the "outer" detectors
2379   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
2380
2381   // pass 3: TRD + TPC + ITS refit inwards
2382
2383   for (Int_t iDet = 2; iDet >= 0; iDet--) {
2384     if (!fTracker[iDet]) continue;
2385     AliDebug(1, Form("%s inward refit", fgkDetectorName[iDet]));
2386
2387     // run tracking
2388     if (iDet<2) // start filling residuals for TPC and ITS
2389     if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
2390
2391     if (fTracker[iDet]->RefitInward(esd) != 0) {
2392       AliError(Form("%s inward refit failed", fgkDetectorName[iDet]));
2393       //      return kFALSE;
2394     }
2395     // run postprocessing
2396     if (fTracker[iDet]->PostProcess(esd) != 0) {
2397       AliError(Form("%s postprocessing failed", fgkDetectorName[iDet]));
2398       //      return kFALSE;
2399     }
2400     AliSysInfo::AddStamp(Form("Tracking2%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
2401   }
2402
2403   // write space-points to the ESD in case alignment data output
2404   // is switched on
2405   if (fWriteAlignmentData)
2406     WriteAlignmentData(esd);
2407
2408   for (Int_t iDet = 3; iDet >= 0; iDet--) {
2409     if (!fTracker[iDet]) continue;
2410     // unload clusters
2411     fTracker[iDet]->UnloadClusters();
2412     AliSysInfo::AddStamp(Form("TUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,4, eventNr);
2413     fLoader[iDet]->UnloadRecPoints();
2414     AliSysInfo::AddStamp(Form("RUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,5, eventNr);
2415   }
2416   // stop filling residuals for TPC and ITS
2417   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
2418
2419   eventNr++;
2420   return kTRUE;
2421 }
2422
2423 //_____________________________________________________________________________
2424 Bool_t AliReconstruction::CleanESD(AliESDEvent *esd){
2425   //
2426   // Remove the data which are not needed for the physics analysis.
2427   //
2428
2429   Int_t nTracks=esd->GetNumberOfTracks();
2430   Int_t nV0s=esd->GetNumberOfV0s();
2431   AliInfo
2432   (Form("Number of ESD tracks and V0s before cleaning: %d %d",nTracks,nV0s));
2433
2434   Float_t cleanPars[]={fV0DCAmax,fV0CsPmin,fDmax,fZmax};
2435   Bool_t rc=esd->Clean(cleanPars);
2436
2437   nTracks=esd->GetNumberOfTracks();
2438   nV0s=esd->GetNumberOfV0s();
2439   AliInfo
2440   (Form("Number of ESD tracks and V0s after cleaning %d %d",nTracks,nV0s));
2441
2442   return rc;
2443 }
2444
2445 //_____________________________________________________________________________
2446 Bool_t AliReconstruction::FillESD(AliESDEvent*& esd, const TString& detectors)
2447 {
2448 // fill the event summary data
2449
2450   AliCodeTimerAuto("")
2451     static Int_t eventNr=0; 
2452   TString detStr = detectors;
2453   
2454   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2455   if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2456     AliReconstructor* reconstructor = GetReconstructor(iDet);
2457     if (!reconstructor) continue;
2458     AliDebug(1, Form("filling ESD for %s", fgkDetectorName[iDet]));
2459     TTree* clustersTree = NULL;
2460     if (fLoader[iDet]) {
2461       fLoader[iDet]->LoadRecPoints("read");
2462       clustersTree = fLoader[iDet]->TreeR();
2463       if (!clustersTree) {
2464         AliError(Form("Can't get the %s clusters tree", 
2465                       fgkDetectorName[iDet]));
2466         if (fStopOnError) return kFALSE;
2467       }
2468     }
2469     if (fRawReader && !reconstructor->HasDigitConversion()) {
2470       reconstructor->FillESD(fRawReader, clustersTree, esd);
2471     } else {
2472       TTree* digitsTree = NULL;
2473       if (fLoader[iDet]) {
2474         fLoader[iDet]->LoadDigits("read");
2475         digitsTree = fLoader[iDet]->TreeD();
2476         if (!digitsTree) {
2477           AliError(Form("Can't get the %s digits tree", 
2478                         fgkDetectorName[iDet]));
2479           if (fStopOnError) return kFALSE;
2480         }
2481       }
2482       reconstructor->FillESD(digitsTree, clustersTree, esd);
2483       if (fLoader[iDet]) fLoader[iDet]->UnloadDigits();
2484     }
2485     if (fLoader[iDet]) {
2486       fLoader[iDet]->UnloadRecPoints();
2487     }
2488   }
2489
2490   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2491     AliError(Form("the following detectors were not found: %s", 
2492                   detStr.Data()));
2493     if (fStopOnError) return kFALSE;
2494   }
2495   AliSysInfo::AddStamp(Form("FillESD%d",eventNr), 0,1, eventNr);
2496   eventNr++;
2497   return kTRUE;
2498 }
2499
2500 //_____________________________________________________________________________
2501 Bool_t AliReconstruction::FillTriggerESD(AliESDEvent*& esd)
2502 {
2503   // Reads the trigger decision which is
2504   // stored in Trigger.root file and fills
2505   // the corresponding esd entries
2506
2507   AliCodeTimerAuto("")
2508   
2509   AliInfo("Filling trigger information into the ESD");
2510
2511   if (fRawReader) {
2512     AliCTPRawStream input(fRawReader);
2513     if (!input.Next()) {
2514       AliWarning("No valid CTP (trigger) DDL raw data is found ! The trigger info is taken from the event header!");
2515     }
2516     else {
2517       if (esd->GetTriggerMask() != input.GetClassMask())
2518         AliError(Form("Invalid trigger pattern found in CTP raw-data: %llx %llx",
2519                       input.GetClassMask(),esd->GetTriggerMask()));
2520       if (esd->GetOrbitNumber() != input.GetOrbitID())
2521         AliError(Form("Invalid orbit id found in CTP raw-data: %x %x",
2522                       input.GetOrbitID(),esd->GetOrbitNumber()));
2523       if (esd->GetBunchCrossNumber() != input.GetBCID())
2524         AliError(Form("Invalid bunch-crossing id found in CTP raw-data: %x %x",
2525                       input.GetBCID(),esd->GetBunchCrossNumber()));
2526     }
2527
2528   // Here one has to add the filling of trigger inputs and
2529   // interaction records
2530   // ...
2531   }
2532   return kTRUE;
2533 }
2534
2535
2536
2537
2538
2539 //_____________________________________________________________________________
2540 Bool_t AliReconstruction::FillRawEventHeaderESD(AliESDEvent*& esd)
2541 {
2542   // 
2543   // Filling information from RawReader Header
2544   // 
2545
2546   if (!fRawReader) return kFALSE;
2547
2548   AliInfo("Filling information from RawReader Header");
2549
2550   esd->SetBunchCrossNumber(fRawReader->GetBCID());
2551   esd->SetOrbitNumber(fRawReader->GetOrbitID());
2552   esd->SetPeriodNumber(fRawReader->GetPeriod());
2553
2554   esd->SetTimeStamp(fRawReader->GetTimestamp());  
2555   esd->SetEventType(fRawReader->GetType());
2556
2557   return kTRUE;
2558 }
2559
2560
2561 //_____________________________________________________________________________
2562 Bool_t AliReconstruction::IsSelected(TString detName, TString& detectors) const
2563 {
2564 // check whether detName is contained in detectors
2565 // if yes, it is removed from detectors
2566
2567   // check if all detectors are selected
2568   if ((detectors.CompareTo("ALL") == 0) ||
2569       detectors.BeginsWith("ALL ") ||
2570       detectors.EndsWith(" ALL") ||
2571       detectors.Contains(" ALL ")) {
2572     detectors = "ALL";
2573     return kTRUE;
2574   }
2575
2576   // search for the given detector
2577   Bool_t result = kFALSE;
2578   if ((detectors.CompareTo(detName) == 0) ||
2579       detectors.BeginsWith(detName+" ") ||
2580       detectors.EndsWith(" "+detName) ||
2581       detectors.Contains(" "+detName+" ")) {
2582     detectors.ReplaceAll(detName, "");
2583     result = kTRUE;
2584   }
2585
2586   // clean up the detectors string
2587   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
2588   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
2589   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
2590
2591   return result;
2592 }
2593
2594 //_____________________________________________________________________________
2595 Bool_t AliReconstruction::InitRunLoader()
2596 {
2597 // get or create the run loader
2598
2599   if (gAlice) delete gAlice;
2600   gAlice = NULL;
2601
2602   if (!gSystem->AccessPathName(fGAliceFileName.Data())) { // galice.root exists
2603     // load all base libraries to get the loader classes
2604     TString libs = gSystem->GetLibraries();
2605     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2606       TString detName = fgkDetectorName[iDet];
2607       if (detName == "HLT") continue;
2608       if (libs.Contains("lib" + detName + "base.so")) continue;
2609       gSystem->Load("lib" + detName + "base.so");
2610     }
2611     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data());
2612     if (!fRunLoader) {
2613       AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
2614       CleanUp();
2615       return kFALSE;
2616     }
2617
2618     fRunLoader->CdGAFile();
2619     fRunLoader->LoadgAlice();
2620
2621     //PH This is a temporary fix to give access to the kinematics
2622     //PH that is needed for the labels of ITS clusters
2623     fRunLoader->LoadHeader();
2624     fRunLoader->LoadKinematics();
2625
2626   } else {               // galice.root does not exist
2627     if (!fRawReader) {
2628       AliError(Form("the file %s does not exist", fGAliceFileName.Data()));
2629     }
2630     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data(),
2631                                     AliConfig::GetDefaultEventFolderName(),
2632                                     "recreate");
2633     if (!fRunLoader) {
2634       AliError(Form("could not create run loader in file %s", 
2635                     fGAliceFileName.Data()));
2636       CleanUp();
2637       return kFALSE;
2638     }
2639     fIsNewRunLoader = kTRUE;
2640     fRunLoader->MakeTree("E");
2641
2642     if (fNumberOfEventsPerFile > 0)
2643       fRunLoader->SetNumberOfEventsPerFile(fNumberOfEventsPerFile);
2644     else
2645       fRunLoader->SetNumberOfEventsPerFile((UInt_t)-1);
2646   }
2647
2648   return kTRUE;
2649 }
2650
2651 //_____________________________________________________________________________
2652 AliReconstructor* AliReconstruction::GetReconstructor(Int_t iDet)
2653 {
2654 // get the reconstructor object and the loader for a detector
2655
2656   if (fReconstructor[iDet]) {
2657     if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
2658       const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
2659       fReconstructor[iDet]->SetRecoParam(par);
2660     }
2661     return fReconstructor[iDet];
2662   }
2663
2664   // load the reconstructor object
2665   TPluginManager* pluginManager = gROOT->GetPluginManager();
2666   TString detName = fgkDetectorName[iDet];
2667   TString recName = "Ali" + detName + "Reconstructor";
2668
2669   if (!fIsNewRunLoader && !fRunLoader->GetLoader(detName+"Loader") && (detName != "HLT")) return NULL;
2670
2671   AliReconstructor* reconstructor = NULL;
2672   // first check if a plugin is defined for the reconstructor
2673   TPluginHandler* pluginHandler = 
2674     pluginManager->FindHandler("AliReconstructor", detName);
2675   // if not, add a plugin for it
2676   if (!pluginHandler) {
2677     AliDebug(1, Form("defining plugin for %s", recName.Data()));
2678     TString libs = gSystem->GetLibraries();
2679     if (libs.Contains("lib" + detName + "base.so") ||
2680         (gSystem->Load("lib" + detName + "base.so") >= 0)) {
2681       pluginManager->AddHandler("AliReconstructor", detName, 
2682                                 recName, detName + "rec", recName + "()");
2683     } else {
2684       pluginManager->AddHandler("AliReconstructor", detName, 
2685                                 recName, detName, recName + "()");
2686     }
2687     pluginHandler = pluginManager->FindHandler("AliReconstructor", detName);
2688   }
2689   if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
2690     reconstructor = (AliReconstructor*) pluginHandler->ExecPlugin(0);
2691   }
2692   if (reconstructor) {
2693     TObject* obj = fOptions.FindObject(detName.Data());
2694     if (obj) reconstructor->SetOption(obj->GetTitle());
2695     reconstructor->Init();
2696     fReconstructor[iDet] = reconstructor;
2697   }
2698
2699   // get or create the loader
2700   if (detName != "HLT") {
2701     fLoader[iDet] = fRunLoader->GetLoader(detName + "Loader");
2702     if (!fLoader[iDet]) {
2703       AliConfig::Instance()
2704         ->CreateDetectorFolders(fRunLoader->GetEventFolder(), 
2705                                 detName, detName);
2706       // first check if a plugin is defined for the loader
2707       pluginHandler = 
2708         pluginManager->FindHandler("AliLoader", detName);
2709       // if not, add a plugin for it
2710       if (!pluginHandler) {
2711         TString loaderName = "Ali" + detName + "Loader";
2712         AliDebug(1, Form("defining plugin for %s", loaderName.Data()));
2713         pluginManager->AddHandler("AliLoader", detName, 
2714                                   loaderName, detName + "base", 
2715                                   loaderName + "(const char*, TFolder*)");
2716         pluginHandler = pluginManager->FindHandler("AliLoader", detName);
2717       }
2718       if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
2719         fLoader[iDet] = 
2720           (AliLoader*) pluginHandler->ExecPlugin(2, detName.Data(), 
2721                                                  fRunLoader->GetEventFolder());
2722       }
2723       if (!fLoader[iDet]) {   // use default loader
2724         fLoader[iDet] = new AliLoader(detName, fRunLoader->GetEventFolder());
2725       }
2726       if (!fLoader[iDet]) {
2727         AliWarning(Form("couldn't get loader for %s", detName.Data()));
2728         if (fStopOnError) return NULL;
2729       } else {
2730         fRunLoader->AddLoader(fLoader[iDet]);
2731         fRunLoader->CdGAFile();
2732         if (gFile && !gFile->IsWritable()) gFile->ReOpen("UPDATE");
2733         fRunLoader->Write(0, TObject::kOverwrite);
2734       }
2735     }
2736   }
2737       
2738   if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
2739     const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
2740     reconstructor->SetRecoParam(par);
2741   }
2742   return reconstructor;
2743 }
2744
2745 //_____________________________________________________________________________
2746 AliVertexer* AliReconstruction::CreateVertexer()
2747 {
2748 // create the vertexer
2749 // Please note that the caller is the owner of the
2750 // vertexer
2751
2752   AliVertexer* vertexer = NULL;
2753   AliReconstructor* itsReconstructor = GetReconstructor(0);
2754   if (itsReconstructor) {
2755     vertexer = itsReconstructor->CreateVertexer();
2756   }
2757   if (!vertexer) {
2758     AliWarning("couldn't create a vertexer for ITS");
2759   }
2760
2761   return vertexer;
2762 }
2763
2764 //_____________________________________________________________________________
2765 Bool_t AliReconstruction::CreateTrackers(const TString& detectors)
2766 {
2767 // create the trackers
2768         AliInfo("Creating trackers");
2769
2770   TString detStr = detectors;
2771   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2772     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2773     AliReconstructor* reconstructor = GetReconstructor(iDet);
2774     if (!reconstructor) continue;
2775     TString detName = fgkDetectorName[iDet];
2776     if (detName == "HLT") {
2777       fRunHLTTracking = kTRUE;
2778       continue;
2779     }
2780     if (detName == "MUON") {
2781       fRunMuonTracking = kTRUE;
2782       continue;
2783     }
2784
2785
2786     fTracker[iDet] = reconstructor->CreateTracker();
2787     if (!fTracker[iDet] && (iDet < 7)) {
2788       AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
2789       if (fStopOnError) return kFALSE;
2790     }
2791     AliSysInfo::AddStamp(Form("LTracker%s",fgkDetectorName[iDet]), iDet,0);
2792   }
2793
2794   return kTRUE;
2795 }
2796
2797 //_____________________________________________________________________________
2798 void AliReconstruction::CleanUp()
2799 {
2800 // delete trackers and the run loader and close and delete the file
2801
2802   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2803     delete fReconstructor[iDet];
2804     fReconstructor[iDet] = NULL;
2805     fLoader[iDet] = NULL;
2806     delete fTracker[iDet];
2807     fTracker[iDet] = NULL;
2808   }
2809   delete fRunInfo;
2810   fRunInfo = NULL;
2811
2812   delete fSPDTrackleter;
2813   fSPDTrackleter = NULL;
2814
2815   delete ftVertexer;
2816   ftVertexer = NULL;
2817   
2818   delete fRunLoader;
2819   fRunLoader = NULL;
2820   delete fRawReader;
2821   fRawReader = NULL;
2822   delete fParentRawReader;
2823   fParentRawReader=NULL;
2824
2825   if (ffile) {
2826     ffile->Close();
2827     delete ffile;
2828     ffile = NULL;
2829   }
2830
2831   TGeoGlobalMagField::Instance()->SetField(NULL);
2832 }
2833
2834 void AliReconstruction::WriteAlignmentData(AliESDEvent* esd)
2835 {
2836   // Write space-points which are then used in the alignment procedures
2837   // For the moment only ITS, TPC, TRD and TOF
2838
2839   Int_t ntracks = esd->GetNumberOfTracks();
2840   for (Int_t itrack = 0; itrack < ntracks; itrack++)
2841     {
2842       AliESDtrack *track = esd->GetTrack(itrack);
2843       Int_t nsp = 0;
2844       Int_t idx[200];
2845       for (Int_t i=0; i<200; ++i) idx[i] = -1; //PH avoid uninitialized values
2846       for (Int_t iDet = 5; iDet >= 0; iDet--) {// TOF, TRD, TPC, ITS clusters
2847           nsp += track->GetNcls(iDet);
2848
2849           if (iDet==0) { // ITS "extra" clusters
2850              track->GetClusters(iDet,idx);
2851              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nsp++;
2852           }  
2853       }
2854
2855       if (nsp) {
2856         AliTrackPointArray *sp = new AliTrackPointArray(nsp);
2857         track->SetTrackPointArray(sp);
2858         Int_t isptrack = 0;
2859         for (Int_t iDet = 5; iDet >= 0; iDet--) {
2860           AliTracker *tracker = fTracker[iDet];
2861           if (!tracker) continue;
2862           Int_t nspdet = track->GetClusters(iDet,idx);
2863
2864           if (iDet==0) // ITS "extra" clusters             
2865              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nspdet++;
2866
2867           if (nspdet <= 0) continue;
2868           AliTrackPoint p;
2869           Int_t isp = 0;
2870           Int_t isp2 = 0;
2871           while (isp2 < nspdet) {
2872             Bool_t isvalid=kTRUE;
2873
2874             Int_t index=idx[isp++];
2875             if (index < 0) continue;
2876
2877             TString dets = fgkDetectorName[iDet];
2878             if ((fUseTrackingErrorsForAlignment.CompareTo(dets) == 0) ||
2879             fUseTrackingErrorsForAlignment.BeginsWith(dets+" ") ||
2880             fUseTrackingErrorsForAlignment.EndsWith(" "+dets) ||
2881             fUseTrackingErrorsForAlignment.Contains(" "+dets+" ")) {
2882               isvalid = tracker->GetTrackPointTrackingError(index,p,track);
2883             } else {
2884               isvalid = tracker->GetTrackPoint(index,p); 
2885             } 
2886             isp2++;
2887             if (!isvalid) continue;
2888             if (iDet==0 && (isp-1)>=6) p.SetExtra();
2889             sp->AddPoint(isptrack,&p); isptrack++;
2890           }
2891         }       
2892       }
2893     }
2894 }
2895
2896 //_____________________________________________________________________________
2897 void AliReconstruction::FillRawDataErrorLog(Int_t iEvent, AliESDEvent* esd)
2898 {
2899   // The method reads the raw-data error log
2900   // accumulated within the rawReader.
2901   // It extracts the raw-data errors related to
2902   // the current event and stores them into
2903   // a TClonesArray inside the esd object.
2904
2905   if (!fRawReader) return;
2906
2907   for(Int_t i = 0; i < fRawReader->GetNumberOfErrorLogs(); i++) {
2908
2909     AliRawDataErrorLog *log = fRawReader->GetErrorLog(i);
2910     if (!log) continue;
2911     if (iEvent != log->GetEventNumber()) continue;
2912
2913     esd->AddRawDataErrorLog(log);
2914   }
2915
2916 }
2917
2918 //_____________________________________________________________________________
2919 void AliReconstruction::CheckQA()
2920 {
2921 // check the QA of SIM for this run and remove the detectors 
2922 // with status Fatal
2923   
2924 //      TString newRunLocalReconstruction ; 
2925 //      TString newRunTracking ;
2926 //      TString newFillESD ;
2927 //       
2928 //      for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
2929 //              TString detName(AliQAv1::GetDetName(iDet)) ;
2930 //              AliQAv1 * qa = AliQAv1::Instance(AliQAv1::DETECTORINDEX_t(iDet)) ;       
2931 //      if ( qa->IsSet(AliQAv1::DETECTORINDEX_t(iDet), AliQAv1::kSIM, specie, AliQAv1::kFATAL)) {
2932 //        AliInfo(Form("QA status for %s %s in Hits and/or SDIGITS  and/or Digits was Fatal; No reconstruction performed", 
2933 //                   detName.Data(), AliRecoParam::GetEventSpecieName(es))) ;
2934 //                      } else {
2935 //                      if ( fRunLocalReconstruction.Contains(AliQAv1::GetDetName(iDet)) || 
2936 //                                      fRunLocalReconstruction.Contains("ALL") )  {
2937 //                              newRunLocalReconstruction += detName ; 
2938 //                              newRunLocalReconstruction += " " ;                      
2939 //                      }
2940 //                      if ( fRunTracking.Contains(AliQAv1::GetDetName(iDet)) || 
2941 //                                      fRunTracking.Contains("ALL") )  {
2942 //                              newRunTracking += detName ; 
2943 //                              newRunTracking += " " ;                         
2944 //                      }
2945 //                      if ( fFillESD.Contains(AliQAv1::GetDetName(iDet)) || 
2946 //                                      fFillESD.Contains("ALL") )  {
2947 //                              newFillESD += detName ; 
2948 //                              newFillESD += " " ;                     
2949 //                      }
2950 //              }
2951 //      }
2952 //      fRunLocalReconstruction = newRunLocalReconstruction ; 
2953 //      fRunTracking            = newRunTracking ; 
2954 //      fFillESD                = newFillESD ; 
2955 }
2956
2957 //_____________________________________________________________________________
2958 Int_t AliReconstruction::GetDetIndex(const char* detector)
2959 {
2960   // return the detector index corresponding to detector
2961   Int_t index = -1 ; 
2962   for (index = 0; index < kNDetectors ; index++) {
2963     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
2964         break ; 
2965   }     
2966   return index ; 
2967 }
2968 //_____________________________________________________________________________
2969 Bool_t AliReconstruction::FinishPlaneEff() {
2970  //
2971  // Here execute all the necessary operationis, at the end of the tracking phase,
2972  // in case that evaluation of PlaneEfficiencies was required for some detector.
2973  // E.g., write into a DataBase file the PlaneEfficiency which have been evaluated.
2974  //
2975  // This Preliminary version works only FOR ITS !!!!!
2976  // other detectors (TOF,TRD, etc. have to develop their specific codes)
2977  //
2978  //  Input: none
2979  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
2980  //
2981  Bool_t ret=kFALSE;
2982  //for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
2983  for (Int_t iDet = 0; iDet < 1; iDet++) { // for the time being only ITS
2984    //if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2985    if(fTracker[iDet] && fTracker[iDet]->GetPlaneEff()) {
2986       AliPlaneEff *planeeff=fTracker[iDet]->GetPlaneEff();
2987       TString name=planeeff->GetName();
2988       name+=".root";
2989       TFile* pefile = TFile::Open(name, "RECREATE");
2990       ret=(Bool_t)planeeff->Write();
2991       pefile->Close();
2992       if(planeeff->GetCreateHistos()) {
2993         TString hname=planeeff->GetName();
2994         hname+="Histo.root";
2995         ret*=planeeff->WriteHistosToFile(hname,"RECREATE");
2996       }
2997    }
2998    if(fSPDTrackleter) {
2999      AliPlaneEff *planeeff=fSPDTrackleter->GetPlaneEff();
3000       TString name="AliITSPlaneEffSPDtracklet.root";
3001       TFile* pefile = TFile::Open(name, "RECREATE");
3002       ret=(Bool_t)planeeff->Write();
3003       pefile->Close();
3004       AliESDEvent *dummy=NULL;
3005       ret=(Bool_t)fSPDTrackleter->PostProcess(dummy); // take care of writing other files
3006    }
3007  }
3008  return ret;
3009 }
3010 //_____________________________________________________________________________
3011 Bool_t AliReconstruction::InitPlaneEff() {
3012 //
3013  // Here execute all the necessary operations, before of the tracking phase,
3014  // for the evaluation of PlaneEfficiencies, in case required for some detectors.
3015  // E.g., read from a DataBase file a first evaluation of the PlaneEfficiency
3016  // which should be updated/recalculated.
3017  //
3018  // This Preliminary version will work only FOR ITS !!!!!
3019  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3020  //
3021  //  Input: none
3022  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3023  //
3024  AliWarning(Form("Implementation of this method not yet completed !! Method return kTRUE"));
3025
3026   fSPDTrackleter = NULL;
3027   AliReconstructor* itsReconstructor = GetReconstructor(0);
3028   if (itsReconstructor) {
3029     fSPDTrackleter = itsReconstructor->CreateTrackleter(); // this is NULL unless required in RecoParam
3030   }
3031   if (fSPDTrackleter) { 
3032     AliInfo("Trackleter for SPD has been created");
3033   }
3034
3035  return kTRUE;
3036 }
3037
3038 //_____________________________________________________________________________
3039 Bool_t AliReconstruction::InitAliEVE()
3040 {
3041   // This method should be called only in case 
3042   // AliReconstruction is run
3043   // within the alieve environment.
3044   // It will initialize AliEVE in a way
3045   // so that it can visualize event processed
3046   // by AliReconstruction.
3047   // The return flag shows whenever the
3048   // AliEVE initialization was successful or not.
3049
3050   TString macroStr;
3051   macroStr.Form("%s/EVE/macros/alieve_online.C",gSystem->ExpandPathName("$ALICE_ROOT"));
3052   AliInfo(Form("Loading AliEVE macro: %s",macroStr.Data()));
3053   if (gROOT->LoadMacro(macroStr.Data()) != 0) return kFALSE;
3054
3055   gROOT->ProcessLine("if (!AliEveEventManager::GetMaster()){new AliEveEventManager();AliEveEventManager::GetMaster()->AddNewEventCommand(\"alieve_online_on_new_event()\");gEve->AddEvent(AliEveEventManager::GetMaster());};");
3056   gROOT->ProcessLine("alieve_online_init()");
3057
3058   return kTRUE;
3059 }
3060   
3061 //_____________________________________________________________________________
3062 void AliReconstruction::RunAliEVE()
3063 {
3064   // Runs AliEVE visualisation of
3065   // the current event.
3066   // Should be executed only after
3067   // successful initialization of AliEVE.
3068
3069   AliInfo("Running AliEVE...");
3070   gROOT->ProcessLine(Form("AliEveEventManager::GetMaster()->SetEvent((AliRunLoader*)0x%lx,(AliRawReader*)0x%lx,(AliESDEvent*)0x%lx,(AliESDfriend*)0x%lx);",fRunLoader,fRawReader,fesd,fesdf));
3071   gSystem->Run();
3072 }
3073
3074 //_____________________________________________________________________________
3075 Bool_t AliReconstruction::SetRunQA(TString detAndAction) 
3076 {
3077         // Allows to run QA for a selected set of detectors
3078         // and a selected set of tasks among RAWS, DIGITSR, RECPOINTS and ESDS
3079         // all selected detectors run the same selected tasks
3080         
3081         if (!detAndAction.Contains(":")) {
3082                 AliError( Form("%s is a wrong syntax, use \"DetectorList:ActionList\" \n", detAndAction.Data()) ) ;
3083                 fRunQA = kFALSE ;
3084                 return kFALSE ;                 
3085         }
3086         Int_t colon = detAndAction.Index(":") ; 
3087         fQADetectors = detAndAction(0, colon) ; 
3088         if (fQADetectors.Contains("ALL") )
3089                 fQADetectors = fFillESD ; 
3090                 fQATasks   = detAndAction(colon+1, detAndAction.Sizeof() ) ; 
3091         if (fQATasks.Contains("ALL") ) {
3092                 fQATasks = Form("%d %d %d %d", AliQAv1::kRAWS, AliQAv1::kDIGITSR, AliQAv1::kRECPOINTS, AliQAv1::kESDS) ; 
3093         } else {
3094                 fQATasks.ToUpper() ; 
3095                 TString tempo("") ; 
3096                 if ( fQATasks.Contains("RAW") ) 
3097                         tempo = Form("%d ", AliQAv1::kRAWS) ; 
3098                 if ( fQATasks.Contains("DIGIT") ) 
3099                         tempo += Form("%d ", AliQAv1::kDIGITSR) ; 
3100                 if ( fQATasks.Contains("RECPOINT") ) 
3101                         tempo += Form("%d ", AliQAv1::kRECPOINTS) ; 
3102                 if ( fQATasks.Contains("ESD") ) 
3103                         tempo += Form("%d ", AliQAv1::kESDS) ; 
3104                 fQATasks = tempo ; 
3105                 if (fQATasks.IsNull()) {
3106                         AliInfo("No QA requested\n")  ;
3107                         fRunQA = kFALSE ;
3108                         return kTRUE ; 
3109                 }
3110         }       
3111         TString tempo(fQATasks) ; 
3112         tempo.ReplaceAll(Form("%d", AliQAv1::kRAWS), AliQAv1::GetTaskName(AliQAv1::kRAWS))      ;
3113         tempo.ReplaceAll(Form("%d", AliQAv1::kDIGITSR), AliQAv1::GetTaskName(AliQAv1::kDIGITSR)) ;      
3114         tempo.ReplaceAll(Form("%d", AliQAv1::kRECPOINTS), AliQAv1::GetTaskName(AliQAv1::kRECPOINTS)) ;  
3115         tempo.ReplaceAll(Form("%d", AliQAv1::kESDS), AliQAv1::GetTaskName(AliQAv1::kESDS)) ;    
3116         AliInfo( Form("QA will be done on \"%s\" for \"%s\"\n", fQADetectors.Data(), tempo.Data()) ) ;  
3117         fRunQA = kTRUE ;
3118         return kTRUE; 
3119
3120
3121 //_____________________________________________________________________________
3122 Bool_t AliReconstruction::InitRecoParams() 
3123 {
3124   // The method accesses OCDB and retrieves all
3125   // the available reco-param objects from there.
3126
3127   Bool_t isOK = kTRUE;
3128
3129   TString detStr = fLoadCDB;
3130   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3131
3132     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3133
3134     if (fRecoParam.GetDetRecoParamArray(iDet)) {
3135       AliInfo(Form("Using custom reconstruction parameters for detector %s",fgkDetectorName[iDet]));
3136       continue;
3137     }
3138
3139     AliInfo(Form("Loading reconstruction parameter objects for detector %s",fgkDetectorName[iDet]));
3140   
3141     AliCDBPath path(fgkDetectorName[iDet],"Calib","RecoParam");
3142     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
3143     if(!entry){ 
3144       AliWarning(Form("Couldn't find RecoParam entry in OCDB for detector %s",fgkDetectorName[iDet]));
3145       isOK = kFALSE;
3146     }
3147     else {
3148       TObject *recoParamObj = entry->GetObject();
3149       if (dynamic_cast<TObjArray*>(recoParamObj)) {
3150         // The detector has a normal TobjArray of AliDetectorRecoParam objects
3151         // Registering them in AliRecoParam
3152         fRecoParam.AddDetRecoParamArray(iDet,dynamic_cast<TObjArray*>(recoParamObj));
3153       }
3154       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
3155         // The detector has only onse set of reco parameters
3156         // Registering it in AliRecoParam
3157         AliInfo(Form("Single set of reconstruction parameters found for detector %s",fgkDetectorName[iDet]));
3158         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
3159         fRecoParam.AddDetRecoParam(iDet,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
3160       }
3161       else {
3162         AliError(Form("No valid RecoParam object found in the OCDB for detector %s",fgkDetectorName[iDet]));
3163         isOK = kFALSE;
3164       }
3165       entry->SetOwner(0);
3166       AliCDBManager::Instance()->UnloadFromCache(path.GetPath());
3167     }
3168   }
3169
3170   if (AliDebugLevel() > 0) fRecoParam.Print();
3171
3172   return isOK;
3173 }
3174
3175 //_____________________________________________________________________________
3176 Bool_t AliReconstruction::GetEventInfo() 
3177 {
3178   // Fill the event info object
3179   // ...
3180   AliCodeTimerAuto("")
3181
3182   AliCentralTrigger *aCTP = NULL;
3183   if (fRawReader) {
3184     fEventInfo.SetEventType(fRawReader->GetType());
3185
3186     ULong64_t mask = fRawReader->GetClassMask();
3187     fEventInfo.SetTriggerMask(mask);
3188     UInt_t clmask = fRawReader->GetDetectorPattern()[0];
3189     fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(clmask));
3190
3191     aCTP = new AliCentralTrigger();
3192     TString configstr("");
3193     if (!aCTP->LoadConfiguration(configstr)) { // Load CTP config from OCDB
3194       AliError("No trigger configuration found in OCDB! The trigger configuration information will not be used!");
3195       delete aCTP;
3196       return kFALSE;
3197     }
3198     aCTP->SetClassMask(mask);
3199     aCTP->SetClusterMask(clmask);
3200   }
3201   else {
3202     fEventInfo.SetEventType(AliRawEventHeaderBase::kPhysicsEvent);
3203
3204     if (fRunLoader && (!fRunLoader->LoadTrigger())) {
3205       aCTP = fRunLoader->GetTrigger();
3206       fEventInfo.SetTriggerMask(aCTP->GetClassMask());
3207       fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(aCTP->GetClusterMask()));
3208     }
3209     else {
3210       AliWarning("No trigger can be loaded! The trigger information will not be used!");
3211       return kFALSE;
3212     }
3213   }
3214
3215   AliTriggerConfiguration *config = aCTP->GetConfiguration();
3216   if (!config) {
3217     AliError("No trigger configuration has been found! The trigger configuration information will not be used!");
3218     if (fRawReader) delete aCTP;
3219     return kFALSE;
3220   }
3221
3222   UChar_t clustmask = 0;
3223   TString trclasses;
3224   ULong64_t trmask = fEventInfo.GetTriggerMask();
3225   const TObjArray& classesArray = config->GetClasses();
3226   Int_t nclasses = classesArray.GetEntriesFast();
3227   for( Int_t iclass=0; iclass < nclasses; iclass++ ) {
3228     AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At(iclass);
3229     if (trclass) {
3230       Int_t trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
3231       fesd->SetTriggerClass(trclass->GetName(),trindex);
3232       if (fRawReader) fRawReader->LoadTriggerClass(trclass->GetName(),trindex);
3233       if (trmask & (1 << trindex)) {
3234         trclasses += " ";
3235         trclasses += trclass->GetName();
3236         trclasses += " ";
3237         clustmask |= trclass->GetCluster()->GetClusterMask();
3238       }
3239     }
3240   }
3241   fEventInfo.SetTriggerClasses(trclasses);
3242
3243   // Set the information in ESD
3244   fesd->SetTriggerMask(trmask);
3245   fesd->SetTriggerCluster(clustmask);
3246
3247   if (!aCTP->CheckTriggeredDetectors()) {
3248     if (fRawReader) delete aCTP;
3249     return kFALSE;
3250   }    
3251
3252   if (fRawReader) delete aCTP;
3253
3254   // We have to fill also the HLT decision here!!
3255   // ...
3256
3257   return kTRUE;
3258 }
3259
3260 const char *AliReconstruction::MatchDetectorList(const char *detectorList, UInt_t detectorMask)
3261 {
3262   // Match the detector list found in the rec.C or the default 'ALL'
3263   // to the list found in the GRP (stored there by the shuttle PP which
3264   // gets the information from ECS)
3265   static TString resultList;
3266   TString detList = detectorList;
3267
3268   resultList = "";
3269
3270   for(Int_t iDet = 0; iDet < (AliDAQ::kNDetectors-1); iDet++) {
3271     if ((detectorMask >> iDet) & 0x1) {
3272       TString det = AliDAQ::OfflineModuleName(iDet);
3273       if ((detList.CompareTo("ALL") == 0) ||
3274           ((detList.BeginsWith("ALL ") ||
3275             detList.EndsWith(" ALL") ||
3276             detList.Contains(" ALL ")) &&
3277            !(detList.BeginsWith("-"+det+" ") ||
3278              detList.EndsWith(" -"+det) ||
3279              detList.Contains(" -"+det+" "))) ||
3280           (detList.CompareTo(det) == 0) ||
3281           detList.BeginsWith(det+" ") ||
3282           detList.EndsWith(" "+det) ||
3283           detList.Contains( " "+det+" " )) {
3284         if (!resultList.EndsWith(det + " ")) {
3285           resultList += det;
3286           resultList += " ";
3287         }
3288       }        
3289     }
3290   }
3291
3292   // HLT
3293   if ((detectorMask >> AliDAQ::kHLTId) & 0x1) {
3294     TString hltDet = AliDAQ::OfflineModuleName(AliDAQ::kNDetectors-1);
3295     if ((detList.CompareTo("ALL") == 0) ||
3296         ((detList.BeginsWith("ALL ") ||
3297           detList.EndsWith(" ALL") ||
3298           detList.Contains(" ALL ")) &&
3299          !(detList.BeginsWith("-"+hltDet+" ") ||
3300            detList.EndsWith(" -"+hltDet) ||
3301            detList.Contains(" -"+hltDet+" "))) ||
3302         (detList.CompareTo(hltDet) == 0) ||
3303         detList.BeginsWith(hltDet+" ") ||
3304         detList.EndsWith(" "+hltDet) ||
3305         detList.Contains( " "+hltDet+" " )) {
3306       resultList += hltDet;
3307     }
3308   }
3309
3310   return resultList.Data();
3311
3312 }
3313
3314 //______________________________________________________________________________
3315 void AliReconstruction::Abort(const char *method, EAbort what)
3316 {
3317   // Abort processing. If what = kAbortProcess, the Process() loop will be
3318   // aborted. If what = kAbortFile, the current file in a chain will be
3319   // aborted and the processing will continue with the next file, if there
3320   // is no next file then Process() will be aborted. Abort() can also  be
3321   // called from Begin(), SlaveBegin(), Init() and Notify(). After abort
3322   // the SlaveTerminate() and Terminate() are always called. The abort flag
3323   // can be checked in these methods using GetAbort().
3324   //
3325   // The method is overwritten in AliReconstruction for better handling of
3326   // reco specific errors 
3327
3328   if (!fStopOnError) return;
3329
3330   CleanUp();
3331
3332   TString whyMess = method;
3333   whyMess += " failed! Aborting...";
3334
3335   AliError(whyMess.Data());
3336
3337   fAbort = what;
3338   TString mess = "Abort";
3339   if (fAbort == kAbortProcess)
3340     mess = "AbortProcess";
3341   else if (fAbort == kAbortFile)
3342     mess = "AbortFile";
3343
3344   Info(mess, whyMess.Data());
3345 }
3346