]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliReconstruction.cxx
Techinal fix for raw-data recon on CAF: Enabling the raw-data access from AliEn....
[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 && 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()
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()) ; 
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   gROOT->cd();
1952   CleanUp();
1953 }
1954     
1955 //_____________________________________________________________________________
1956 void AliReconstruction::Terminate()
1957 {
1958   // Create tags for the events in the ESD tree (the ESD tree is always present)
1959   // In case of empty events the tags will contain dummy values
1960   AliCodeTimerAuto("");
1961
1962   AliESDTagCreator *esdtagCreator = new AliESDTagCreator();
1963   esdtagCreator->CreateESDTags(fFirstEvent,fLastEvent,fGRPData, AliQAv1::Instance()->GetQA(), AliQAv1::Instance()->GetEventSpecies(), AliQAv1::kNDET, AliRecoParam::kNSpecies);
1964
1965   // Cleanup of CDB manager: cache and active storages!
1966   AliCDBManager::Instance()->ClearCache();
1967 }
1968
1969 //_____________________________________________________________________________
1970 Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
1971 {
1972 // run the local reconstruction
1973
1974   static Int_t eventNr=0;
1975   AliCodeTimerAuto("")
1976
1977   TString detStr = detectors;
1978   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1979     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1980     AliReconstructor* reconstructor = GetReconstructor(iDet);
1981     if (!reconstructor) continue;
1982     AliLoader* loader = fLoader[iDet];
1983     // Matthias April 2008: temporary fix to run HLT reconstruction
1984     // although the HLT loader is missing
1985     if (strcmp(fgkDetectorName[iDet], "HLT")==0) {
1986       if (fRawReader) {
1987         reconstructor->Reconstruct(fRawReader, NULL);
1988       } else {
1989         TTree* dummy=NULL;
1990         reconstructor->Reconstruct(dummy, NULL);
1991       }
1992       continue;
1993     }
1994     if (!loader) {
1995       AliWarning(Form("No loader is defined for %s!",fgkDetectorName[iDet]));
1996       continue;
1997     }
1998     // conversion of digits
1999     if (fRawReader && reconstructor->HasDigitConversion()) {
2000       AliInfo(Form("converting raw data digits into root objects for %s", 
2001                    fgkDetectorName[iDet]));
2002 //      AliCodeTimerAuto(Form("converting raw data digits into root objects for %s", 
2003 //                            fgkDetectorName[iDet]));
2004       loader->LoadDigits("update");
2005       loader->CleanDigits();
2006       loader->MakeDigitsContainer();
2007       TTree* digitsTree = loader->TreeD();
2008       reconstructor->ConvertDigits(fRawReader, digitsTree);
2009       loader->WriteDigits("OVERWRITE");
2010       loader->UnloadDigits();
2011     }
2012     // local reconstruction
2013     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
2014     //AliCodeTimerAuto(Form("running reconstruction for %s", fgkDetectorName[iDet]));
2015     loader->LoadRecPoints("update");
2016     loader->CleanRecPoints();
2017     loader->MakeRecPointsContainer();
2018     TTree* clustersTree = loader->TreeR();
2019     if (fRawReader && !reconstructor->HasDigitConversion()) {
2020       reconstructor->Reconstruct(fRawReader, clustersTree);
2021     } else {
2022       loader->LoadDigits("read");
2023       TTree* digitsTree = loader->TreeD();
2024       if (!digitsTree) {
2025         AliError(Form("Can't get the %s digits tree", fgkDetectorName[iDet]));
2026         if (fStopOnError) return kFALSE;
2027       } else {
2028         reconstructor->Reconstruct(digitsTree, clustersTree);
2029         if (fRunQA) {
2030           fQAManager->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2031           fQAManager->RunOneEventInOneDetector(iDet, digitsTree) ; 
2032         }
2033       }
2034       loader->UnloadDigits();
2035     }
2036
2037                 TString detQAStr(fQADetectors) ; 
2038                 if (fRunQA) {
2039       fQAManager->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2040                         fQAManager->RunOneEventInOneDetector(iDet, clustersTree) ; 
2041     }
2042         loader->WriteRecPoints("OVERWRITE");
2043         loader->UnloadRecPoints();
2044         AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr), iDet,1,eventNr);
2045   }
2046   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2047     AliError(Form("the following detectors were not found: %s",
2048                   detStr.Data()));
2049     if (fStopOnError) return kFALSE;
2050   }
2051   eventNr++;
2052   return kTRUE;
2053 }
2054 //_____________________________________________________________________________
2055 Bool_t AliReconstruction::RunSPDTrackleting(AliESDEvent*& esd)
2056 {
2057 // run the SPD trackleting (for SPD efficiency purpouses)
2058
2059   AliCodeTimerAuto("")
2060
2061   Double_t vtxPos[3] = {0, 0, 0};
2062   Double_t vtxErr[3] = {0.0, 0.0, 0.0};
2063 /*
2064   TArrayF mcVertex(3);
2065   // if(MC)
2066   if (fRunLoader->GetHeader() && fRunLoader->GetHeader()->GenEventHeader()) {
2067     fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(mcVertex);
2068     for (Int_t i = 0; i < 3; i++) vtxPos[i] = mcVertex[i];
2069   }
2070 */
2071   const AliESDVertex *vertex = esd->GetVertex();
2072   if(!vertex){
2073     AliWarning("Vertex not found");
2074     return kFALSE;
2075   }
2076   vertex->GetXYZ(vtxPos);
2077   vertex->GetSigmaXYZ(vtxErr);
2078   if (fSPDTrackleter) {
2079     AliInfo("running the SPD Trackleter for Plane Efficiency Evaluation");
2080
2081     // load clusters
2082     fLoader[0]->LoadRecPoints("read");
2083     TTree* tree = fLoader[0]->TreeR();
2084     if (!tree) {
2085       AliError("Can't get the ITS cluster tree");
2086       return kFALSE;
2087     }
2088     fSPDTrackleter->LoadClusters(tree);
2089     fSPDTrackleter->SetVertex(vtxPos, vtxErr);
2090     // run trackleting
2091     if (fSPDTrackleter->Clusters2Tracks(esd) != 0) {
2092       AliError("AliITSTrackleterSPDEff Clusters2Tracks failed");
2093      // fLoader[0]->UnloadRecPoints();
2094       return kFALSE;
2095     }
2096 //fSPDTrackleter->UnloadRecPoints();
2097   } else {
2098     AliWarning("SPDTrackleter not available");
2099     return kFALSE;
2100   }
2101   return kTRUE;
2102 }
2103
2104 //_____________________________________________________________________________
2105 Bool_t AliReconstruction::RunVertexFinder(AliESDEvent*& esd)
2106 {
2107 // run the barrel tracking
2108
2109   AliCodeTimerAuto("")
2110
2111   AliVertexer *vertexer = CreateVertexer();
2112   if (!vertexer) return kFALSE;
2113
2114   AliInfo("running the ITS vertex finder");
2115   AliESDVertex* vertex = NULL;
2116   if (fLoader[0]) {
2117     fLoader[0]->LoadRecPoints();
2118     TTree* cltree = fLoader[0]->TreeR();
2119     if (cltree) {
2120       if(fDiamondProfileSPD) vertexer->SetVtxStart(fDiamondProfileSPD);
2121       vertex = vertexer->FindVertexForCurrentEvent(cltree);
2122     }
2123     else {
2124       AliError("Can't get the ITS cluster tree");
2125     }
2126     fLoader[0]->UnloadRecPoints();
2127   }
2128   else {
2129     AliError("Can't get the ITS loader");
2130   }
2131   if(!vertex){
2132     AliWarning("Vertex not found");
2133     vertex = new AliESDVertex();
2134     vertex->SetName("default");
2135   }
2136   else {
2137     vertex->SetName("reconstructed");
2138   }
2139
2140   Double_t vtxPos[3];
2141   Double_t vtxErr[3];
2142   vertex->GetXYZ(vtxPos);
2143   vertex->GetSigmaXYZ(vtxErr);
2144
2145   esd->SetPrimaryVertexSPD(vertex);
2146   AliESDVertex *vpileup = NULL;
2147   Int_t novertices = 0;
2148   vpileup = vertexer->GetAllVertices(novertices);
2149   if(novertices>1){
2150     for (Int_t kk=1; kk<novertices; kk++)esd->AddPileupVertexSPD(&vpileup[kk]);
2151   }
2152   // if SPD multiplicity has been determined, it is stored in the ESD
2153   AliMultiplicity *mult = vertexer->GetMultiplicity();
2154   if(mult)esd->SetMultiplicity(mult);
2155
2156   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2157     if (fTracker[iDet]) fTracker[iDet]->SetVertex(vtxPos, vtxErr);
2158   }  
2159   delete vertex;
2160
2161   delete vertexer;
2162
2163   return kTRUE;
2164 }
2165
2166 //_____________________________________________________________________________
2167 Bool_t AliReconstruction::RunHLTTracking(AliESDEvent*& esd)
2168 {
2169 // run the HLT barrel tracking
2170
2171   AliCodeTimerAuto("")
2172
2173   if (!fRunLoader) {
2174     AliError("Missing runLoader!");
2175     return kFALSE;
2176   }
2177
2178   AliInfo("running HLT tracking");
2179
2180   // Get a pointer to the HLT reconstructor
2181   AliReconstructor *reconstructor = GetReconstructor(kNDetectors-1);
2182   if (!reconstructor) return kFALSE;
2183
2184   // TPC + ITS
2185   for (Int_t iDet = 1; iDet >= 0; iDet--) {
2186     TString detName = fgkDetectorName[iDet];
2187     AliDebug(1, Form("%s HLT tracking", detName.Data()));
2188     reconstructor->SetOption(detName.Data());
2189     AliTracker *tracker = reconstructor->CreateTracker();
2190     if (!tracker) {
2191       AliWarning(Form("couldn't create a HLT tracker for %s", detName.Data()));
2192       if (fStopOnError) return kFALSE;
2193       continue;
2194     }
2195     Double_t vtxPos[3];
2196     Double_t vtxErr[3]={0.005,0.005,0.010};
2197     const AliESDVertex *vertex = esd->GetVertex();
2198     vertex->GetXYZ(vtxPos);
2199     tracker->SetVertex(vtxPos,vtxErr);
2200     if(iDet != 1) {
2201       fLoader[iDet]->LoadRecPoints("read");
2202       TTree* tree = fLoader[iDet]->TreeR();
2203       if (!tree) {
2204         AliError(Form("Can't get the %s cluster tree", detName.Data()));
2205         return kFALSE;
2206       }
2207       tracker->LoadClusters(tree);
2208     }
2209     if (tracker->Clusters2Tracks(esd) != 0) {
2210       AliError(Form("HLT %s Clusters2Tracks failed", fgkDetectorName[iDet]));
2211       return kFALSE;
2212     }
2213     if(iDet != 1) {
2214       tracker->UnloadClusters();
2215     }
2216     delete tracker;
2217   }
2218
2219   return kTRUE;
2220 }
2221
2222 //_____________________________________________________________________________
2223 Bool_t AliReconstruction::RunMuonTracking(AliESDEvent*& esd)
2224 {
2225 // run the muon spectrometer tracking
2226
2227   AliCodeTimerAuto("")
2228
2229   if (!fRunLoader) {
2230     AliError("Missing runLoader!");
2231     return kFALSE;
2232   }
2233   Int_t iDet = 7; // for MUON
2234
2235   AliInfo("is running...");
2236
2237   // Get a pointer to the MUON reconstructor
2238   AliReconstructor *reconstructor = GetReconstructor(iDet);
2239   if (!reconstructor) return kFALSE;
2240
2241   
2242   TString detName = fgkDetectorName[iDet];
2243   AliDebug(1, Form("%s tracking", detName.Data()));
2244   AliTracker *tracker =  reconstructor->CreateTracker();
2245   if (!tracker) {
2246     AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
2247     return kFALSE;
2248   }
2249      
2250   // read RecPoints
2251   fLoader[iDet]->LoadRecPoints("read");  
2252
2253   tracker->LoadClusters(fLoader[iDet]->TreeR());
2254   
2255   Int_t rv = tracker->Clusters2Tracks(esd);
2256   
2257   if ( rv )
2258   {
2259     AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
2260     return kFALSE;
2261   }
2262   
2263   fLoader[iDet]->UnloadRecPoints();
2264
2265   tracker->UnloadClusters();
2266   
2267   delete tracker;
2268   
2269   return kTRUE;
2270 }
2271
2272
2273 //_____________________________________________________________________________
2274 Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd)
2275 {
2276 // run the barrel tracking
2277   static Int_t eventNr=0;
2278   AliCodeTimerAuto("")
2279
2280   AliInfo("running tracking");
2281
2282   //Fill the ESD with the T0 info (will be used by the TOF) 
2283   if (fReconstructor[11] && fLoader[11]) {
2284     fLoader[11]->LoadRecPoints("READ");
2285     TTree *treeR = fLoader[11]->TreeR();
2286     if (treeR) {
2287       GetReconstructor(11)->FillESD((TTree *)NULL,treeR,esd);
2288     }
2289   }
2290
2291   // pass 1: TPC + ITS inwards
2292   for (Int_t iDet = 1; iDet >= 0; iDet--) {
2293     if (!fTracker[iDet]) continue;
2294     AliDebug(1, Form("%s tracking", fgkDetectorName[iDet]));
2295
2296     // load clusters
2297     fLoader[iDet]->LoadRecPoints("read");
2298     AliSysInfo::AddStamp(Form("RLoadCluster%s_%d",fgkDetectorName[iDet],eventNr),iDet,1, eventNr);
2299     TTree* tree = fLoader[iDet]->TreeR();
2300     if (!tree) {
2301       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
2302       return kFALSE;
2303     }
2304     fTracker[iDet]->LoadClusters(tree);
2305     AliSysInfo::AddStamp(Form("TLoadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
2306     // run tracking
2307     if (fTracker[iDet]->Clusters2Tracks(esd) != 0) {
2308       AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
2309       return kFALSE;
2310     }
2311     // preliminary PID in TPC needed by the ITS tracker
2312     if (iDet == 1) {
2313       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
2314       AliESDpid::MakePID(esd);
2315     } 
2316     AliSysInfo::AddStamp(Form("Tracking0%s_%d",fgkDetectorName[iDet],eventNr), iDet,3,eventNr);
2317   }
2318
2319   // pass 2: ALL backwards
2320
2321   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2322     if (!fTracker[iDet]) continue;
2323     AliDebug(1, Form("%s back propagation", fgkDetectorName[iDet]));
2324
2325     // load clusters
2326     if (iDet > 1) {     // all except ITS, TPC
2327       TTree* tree = NULL;
2328       fLoader[iDet]->LoadRecPoints("read");
2329       AliSysInfo::AddStamp(Form("RLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,1, eventNr);
2330       tree = fLoader[iDet]->TreeR();
2331       if (!tree) {
2332         AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
2333         return kFALSE;
2334       }
2335       fTracker[iDet]->LoadClusters(tree); 
2336       AliSysInfo::AddStamp(Form("TLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
2337     }
2338
2339     // run tracking
2340     if (iDet>1) // start filling residuals for the "outer" detectors
2341     if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
2342
2343     if (fTracker[iDet]->PropagateBack(esd) != 0) {
2344       AliError(Form("%s backward propagation failed", fgkDetectorName[iDet]));
2345       //      return kFALSE;
2346     }
2347
2348     // unload clusters
2349     if (iDet > 3) {     // all except ITS, TPC, TRD and TOF
2350       fTracker[iDet]->UnloadClusters();
2351       fLoader[iDet]->UnloadRecPoints();
2352     }
2353     // updated PID in TPC needed by the ITS tracker -MI
2354     if (iDet == 1) {
2355       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
2356       AliESDpid::MakePID(esd);
2357     }
2358     AliSysInfo::AddStamp(Form("Tracking1%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
2359   }
2360   //stop filling residuals for the "outer" detectors
2361   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
2362
2363   // pass 3: TRD + TPC + ITS refit inwards
2364
2365   for (Int_t iDet = 2; iDet >= 0; iDet--) {
2366     if (!fTracker[iDet]) continue;
2367     AliDebug(1, Form("%s inward refit", fgkDetectorName[iDet]));
2368
2369     // run tracking
2370     if (iDet<2) // start filling residuals for TPC and ITS
2371     if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
2372
2373     if (fTracker[iDet]->RefitInward(esd) != 0) {
2374       AliError(Form("%s inward refit failed", fgkDetectorName[iDet]));
2375       //      return kFALSE;
2376     }
2377     // run postprocessing
2378     if (fTracker[iDet]->PostProcess(esd) != 0) {
2379       AliError(Form("%s postprocessing failed", fgkDetectorName[iDet]));
2380       //      return kFALSE;
2381     }
2382     AliSysInfo::AddStamp(Form("Tracking2%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
2383   }
2384
2385   // write space-points to the ESD in case alignment data output
2386   // is switched on
2387   if (fWriteAlignmentData)
2388     WriteAlignmentData(esd);
2389
2390   for (Int_t iDet = 3; iDet >= 0; iDet--) {
2391     if (!fTracker[iDet]) continue;
2392     // unload clusters
2393     fTracker[iDet]->UnloadClusters();
2394     AliSysInfo::AddStamp(Form("TUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,4, eventNr);
2395     fLoader[iDet]->UnloadRecPoints();
2396     AliSysInfo::AddStamp(Form("RUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,5, eventNr);
2397   }
2398   // stop filling residuals for TPC and ITS
2399   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
2400
2401   eventNr++;
2402   return kTRUE;
2403 }
2404
2405 //_____________________________________________________________________________
2406 Bool_t AliReconstruction::CleanESD(AliESDEvent *esd){
2407   //
2408   // Remove the data which are not needed for the physics analysis.
2409   //
2410
2411   Int_t nTracks=esd->GetNumberOfTracks();
2412   Int_t nV0s=esd->GetNumberOfV0s();
2413   AliInfo
2414   (Form("Number of ESD tracks and V0s before cleaning: %d %d",nTracks,nV0s));
2415
2416   Float_t cleanPars[]={fV0DCAmax,fV0CsPmin,fDmax,fZmax};
2417   Bool_t rc=esd->Clean(cleanPars);
2418
2419   nTracks=esd->GetNumberOfTracks();
2420   nV0s=esd->GetNumberOfV0s();
2421   AliInfo
2422   (Form("Number of ESD tracks and V0s after cleaning %d %d",nTracks,nV0s));
2423
2424   return rc;
2425 }
2426
2427 //_____________________________________________________________________________
2428 Bool_t AliReconstruction::FillESD(AliESDEvent*& esd, const TString& detectors)
2429 {
2430 // fill the event summary data
2431
2432   AliCodeTimerAuto("")
2433     static Int_t eventNr=0; 
2434   TString detStr = detectors;
2435   
2436   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2437   if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2438     AliReconstructor* reconstructor = GetReconstructor(iDet);
2439     if (!reconstructor) continue;
2440     AliDebug(1, Form("filling ESD for %s", fgkDetectorName[iDet]));
2441     TTree* clustersTree = NULL;
2442     if (fLoader[iDet]) {
2443       fLoader[iDet]->LoadRecPoints("read");
2444       clustersTree = fLoader[iDet]->TreeR();
2445       if (!clustersTree) {
2446         AliError(Form("Can't get the %s clusters tree", 
2447                       fgkDetectorName[iDet]));
2448         if (fStopOnError) return kFALSE;
2449       }
2450     }
2451     if (fRawReader && !reconstructor->HasDigitConversion()) {
2452       reconstructor->FillESD(fRawReader, clustersTree, esd);
2453     } else {
2454       TTree* digitsTree = NULL;
2455       if (fLoader[iDet]) {
2456         fLoader[iDet]->LoadDigits("read");
2457         digitsTree = fLoader[iDet]->TreeD();
2458         if (!digitsTree) {
2459           AliError(Form("Can't get the %s digits tree", 
2460                         fgkDetectorName[iDet]));
2461           if (fStopOnError) return kFALSE;
2462         }
2463       }
2464       reconstructor->FillESD(digitsTree, clustersTree, esd);
2465       if (fLoader[iDet]) fLoader[iDet]->UnloadDigits();
2466     }
2467     if (fLoader[iDet]) {
2468       fLoader[iDet]->UnloadRecPoints();
2469     }
2470   }
2471
2472   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2473     AliError(Form("the following detectors were not found: %s", 
2474                   detStr.Data()));
2475     if (fStopOnError) return kFALSE;
2476   }
2477   AliSysInfo::AddStamp(Form("FillESD%d",eventNr), 0,1, eventNr);
2478   eventNr++;
2479   return kTRUE;
2480 }
2481
2482 //_____________________________________________________________________________
2483 Bool_t AliReconstruction::FillTriggerESD(AliESDEvent*& esd)
2484 {
2485   // Reads the trigger decision which is
2486   // stored in Trigger.root file and fills
2487   // the corresponding esd entries
2488
2489   AliCodeTimerAuto("")
2490   
2491   AliInfo("Filling trigger information into the ESD");
2492
2493   if (fRawReader) {
2494     AliCTPRawStream input(fRawReader);
2495     if (!input.Next()) {
2496       AliWarning("No valid CTP (trigger) DDL raw data is found ! The trigger info is taken from the event header!");
2497     }
2498     else {
2499       if (esd->GetTriggerMask() != input.GetClassMask())
2500         AliError(Form("Invalid trigger pattern found in CTP raw-data: %llx %llx",
2501                       input.GetClassMask(),esd->GetTriggerMask()));
2502       if (esd->GetOrbitNumber() != input.GetOrbitID())
2503         AliError(Form("Invalid orbit id found in CTP raw-data: %x %x",
2504                       input.GetOrbitID(),esd->GetOrbitNumber()));
2505       if (esd->GetBunchCrossNumber() != input.GetBCID())
2506         AliError(Form("Invalid bunch-crossing id found in CTP raw-data: %x %x",
2507                       input.GetBCID(),esd->GetBunchCrossNumber()));
2508     }
2509
2510   // Here one has to add the filling of trigger inputs and
2511   // interaction records
2512   // ...
2513   }
2514   return kTRUE;
2515 }
2516
2517
2518
2519
2520
2521 //_____________________________________________________________________________
2522 Bool_t AliReconstruction::FillRawEventHeaderESD(AliESDEvent*& esd)
2523 {
2524   // 
2525   // Filling information from RawReader Header
2526   // 
2527
2528   if (!fRawReader) return kFALSE;
2529
2530   AliInfo("Filling information from RawReader Header");
2531
2532   esd->SetBunchCrossNumber(fRawReader->GetBCID());
2533   esd->SetOrbitNumber(fRawReader->GetOrbitID());
2534   esd->SetPeriodNumber(fRawReader->GetPeriod());
2535
2536   esd->SetTimeStamp(fRawReader->GetTimestamp());  
2537   esd->SetEventType(fRawReader->GetType());
2538
2539   return kTRUE;
2540 }
2541
2542
2543 //_____________________________________________________________________________
2544 Bool_t AliReconstruction::IsSelected(TString detName, TString& detectors) const
2545 {
2546 // check whether detName is contained in detectors
2547 // if yes, it is removed from detectors
2548
2549   // check if all detectors are selected
2550   if ((detectors.CompareTo("ALL") == 0) ||
2551       detectors.BeginsWith("ALL ") ||
2552       detectors.EndsWith(" ALL") ||
2553       detectors.Contains(" ALL ")) {
2554     detectors = "ALL";
2555     return kTRUE;
2556   }
2557
2558   // search for the given detector
2559   Bool_t result = kFALSE;
2560   if ((detectors.CompareTo(detName) == 0) ||
2561       detectors.BeginsWith(detName+" ") ||
2562       detectors.EndsWith(" "+detName) ||
2563       detectors.Contains(" "+detName+" ")) {
2564     detectors.ReplaceAll(detName, "");
2565     result = kTRUE;
2566   }
2567
2568   // clean up the detectors string
2569   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
2570   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
2571   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
2572
2573   return result;
2574 }
2575
2576 //_____________________________________________________________________________
2577 Bool_t AliReconstruction::InitRunLoader()
2578 {
2579 // get or create the run loader
2580
2581   if (gAlice) delete gAlice;
2582   gAlice = NULL;
2583
2584   if (!gSystem->AccessPathName(fGAliceFileName.Data())) { // galice.root exists
2585     // load all base libraries to get the loader classes
2586     TString libs = gSystem->GetLibraries();
2587     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2588       TString detName = fgkDetectorName[iDet];
2589       if (detName == "HLT") continue;
2590       if (libs.Contains("lib" + detName + "base.so")) continue;
2591       gSystem->Load("lib" + detName + "base.so");
2592     }
2593     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data());
2594     if (!fRunLoader) {
2595       AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
2596       CleanUp();
2597       return kFALSE;
2598     }
2599
2600     fRunLoader->CdGAFile();
2601     fRunLoader->LoadgAlice();
2602
2603     //PH This is a temporary fix to give access to the kinematics
2604     //PH that is needed for the labels of ITS clusters
2605     fRunLoader->LoadHeader();
2606     fRunLoader->LoadKinematics();
2607
2608   } else {               // galice.root does not exist
2609     if (!fRawReader) {
2610       AliError(Form("the file %s does not exist", fGAliceFileName.Data()));
2611     }
2612     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data(),
2613                                     AliConfig::GetDefaultEventFolderName(),
2614                                     "recreate");
2615     if (!fRunLoader) {
2616       AliError(Form("could not create run loader in file %s", 
2617                     fGAliceFileName.Data()));
2618       CleanUp();
2619       return kFALSE;
2620     }
2621     fIsNewRunLoader = kTRUE;
2622     fRunLoader->MakeTree("E");
2623
2624     if (fNumberOfEventsPerFile > 0)
2625       fRunLoader->SetNumberOfEventsPerFile(fNumberOfEventsPerFile);
2626     else
2627       fRunLoader->SetNumberOfEventsPerFile((UInt_t)-1);
2628   }
2629
2630   return kTRUE;
2631 }
2632
2633 //_____________________________________________________________________________
2634 AliReconstructor* AliReconstruction::GetReconstructor(Int_t iDet)
2635 {
2636 // get the reconstructor object and the loader for a detector
2637
2638   if (fReconstructor[iDet]) {
2639     if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
2640       const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
2641       fReconstructor[iDet]->SetRecoParam(par);
2642     }
2643     return fReconstructor[iDet];
2644   }
2645
2646   // load the reconstructor object
2647   TPluginManager* pluginManager = gROOT->GetPluginManager();
2648   TString detName = fgkDetectorName[iDet];
2649   TString recName = "Ali" + detName + "Reconstructor";
2650
2651   if (!fIsNewRunLoader && !fRunLoader->GetLoader(detName+"Loader") && (detName != "HLT")) return NULL;
2652
2653   AliReconstructor* reconstructor = NULL;
2654   // first check if a plugin is defined for the reconstructor
2655   TPluginHandler* pluginHandler = 
2656     pluginManager->FindHandler("AliReconstructor", detName);
2657   // if not, add a plugin for it
2658   if (!pluginHandler) {
2659     AliDebug(1, Form("defining plugin for %s", recName.Data()));
2660     TString libs = gSystem->GetLibraries();
2661     if (libs.Contains("lib" + detName + "base.so") ||
2662         (gSystem->Load("lib" + detName + "base.so") >= 0)) {
2663       pluginManager->AddHandler("AliReconstructor", detName, 
2664                                 recName, detName + "rec", recName + "()");
2665     } else {
2666       pluginManager->AddHandler("AliReconstructor", detName, 
2667                                 recName, detName, recName + "()");
2668     }
2669     pluginHandler = pluginManager->FindHandler("AliReconstructor", detName);
2670   }
2671   if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
2672     reconstructor = (AliReconstructor*) pluginHandler->ExecPlugin(0);
2673   }
2674   if (reconstructor) {
2675     TObject* obj = fOptions.FindObject(detName.Data());
2676     if (obj) reconstructor->SetOption(obj->GetTitle());
2677     reconstructor->Init();
2678     fReconstructor[iDet] = reconstructor;
2679   }
2680
2681   // get or create the loader
2682   if (detName != "HLT") {
2683     fLoader[iDet] = fRunLoader->GetLoader(detName + "Loader");
2684     if (!fLoader[iDet]) {
2685       AliConfig::Instance()
2686         ->CreateDetectorFolders(fRunLoader->GetEventFolder(), 
2687                                 detName, detName);
2688       // first check if a plugin is defined for the loader
2689       pluginHandler = 
2690         pluginManager->FindHandler("AliLoader", detName);
2691       // if not, add a plugin for it
2692       if (!pluginHandler) {
2693         TString loaderName = "Ali" + detName + "Loader";
2694         AliDebug(1, Form("defining plugin for %s", loaderName.Data()));
2695         pluginManager->AddHandler("AliLoader", detName, 
2696                                   loaderName, detName + "base", 
2697                                   loaderName + "(const char*, TFolder*)");
2698         pluginHandler = pluginManager->FindHandler("AliLoader", detName);
2699       }
2700       if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
2701         fLoader[iDet] = 
2702           (AliLoader*) pluginHandler->ExecPlugin(2, detName.Data(), 
2703                                                  fRunLoader->GetEventFolder());
2704       }
2705       if (!fLoader[iDet]) {   // use default loader
2706         fLoader[iDet] = new AliLoader(detName, fRunLoader->GetEventFolder());
2707       }
2708       if (!fLoader[iDet]) {
2709         AliWarning(Form("couldn't get loader for %s", detName.Data()));
2710         if (fStopOnError) return NULL;
2711       } else {
2712         fRunLoader->AddLoader(fLoader[iDet]);
2713         fRunLoader->CdGAFile();
2714         if (gFile && !gFile->IsWritable()) gFile->ReOpen("UPDATE");
2715         fRunLoader->Write(0, TObject::kOverwrite);
2716       }
2717     }
2718   }
2719       
2720   if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
2721     const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
2722     reconstructor->SetRecoParam(par);
2723   }
2724   return reconstructor;
2725 }
2726
2727 //_____________________________________________________________________________
2728 AliVertexer* AliReconstruction::CreateVertexer()
2729 {
2730 // create the vertexer
2731 // Please note that the caller is the owner of the
2732 // vertexer
2733
2734   AliVertexer* vertexer = NULL;
2735   AliReconstructor* itsReconstructor = GetReconstructor(0);
2736   if (itsReconstructor) {
2737     vertexer = itsReconstructor->CreateVertexer();
2738   }
2739   if (!vertexer) {
2740     AliWarning("couldn't create a vertexer for ITS");
2741   }
2742
2743   return vertexer;
2744 }
2745
2746 //_____________________________________________________________________________
2747 Bool_t AliReconstruction::CreateTrackers(const TString& detectors)
2748 {
2749 // create the trackers
2750         AliInfo("Creating trackers");
2751
2752   TString detStr = detectors;
2753   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2754     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2755     AliReconstructor* reconstructor = GetReconstructor(iDet);
2756     if (!reconstructor) continue;
2757     TString detName = fgkDetectorName[iDet];
2758     if (detName == "HLT") {
2759       fRunHLTTracking = kTRUE;
2760       continue;
2761     }
2762     if (detName == "MUON") {
2763       fRunMuonTracking = kTRUE;
2764       continue;
2765     }
2766
2767
2768     fTracker[iDet] = reconstructor->CreateTracker();
2769     if (!fTracker[iDet] && (iDet < 7)) {
2770       AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
2771       if (fStopOnError) return kFALSE;
2772     }
2773     AliSysInfo::AddStamp(Form("LTracker%s",fgkDetectorName[iDet]), iDet,0);
2774   }
2775
2776   return kTRUE;
2777 }
2778
2779 //_____________________________________________________________________________
2780 void AliReconstruction::CleanUp()
2781 {
2782 // delete trackers and the run loader and close and delete the file
2783
2784   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2785     delete fReconstructor[iDet];
2786     fReconstructor[iDet] = NULL;
2787     fLoader[iDet] = NULL;
2788     delete fTracker[iDet];
2789     fTracker[iDet] = NULL;
2790   }
2791   delete fRunInfo;
2792   fRunInfo = NULL;
2793
2794   delete fSPDTrackleter;
2795   fSPDTrackleter = NULL;
2796
2797   delete ftVertexer;
2798   ftVertexer = NULL;
2799   
2800   delete fRunLoader;
2801   fRunLoader = NULL;
2802   delete fRawReader;
2803   fRawReader = NULL;
2804   delete fParentRawReader;
2805   fParentRawReader=NULL;
2806
2807   if (ffile) {
2808     ffile->Close();
2809     delete ffile;
2810     ffile = NULL;
2811   }
2812 }
2813
2814 void AliReconstruction::WriteAlignmentData(AliESDEvent* esd)
2815 {
2816   // Write space-points which are then used in the alignment procedures
2817   // For the moment only ITS, TPC, TRD and TOF
2818
2819   Int_t ntracks = esd->GetNumberOfTracks();
2820   for (Int_t itrack = 0; itrack < ntracks; itrack++)
2821     {
2822       AliESDtrack *track = esd->GetTrack(itrack);
2823       Int_t nsp = 0;
2824       Int_t idx[200];
2825       for (Int_t i=0; i<200; ++i) idx[i] = -1; //PH avoid uninitialized values
2826       for (Int_t iDet = 5; iDet >= 0; iDet--) {// TOF, TRD, TPC, ITS clusters
2827           nsp += track->GetNcls(iDet);
2828
2829           if (iDet==0) { // ITS "extra" clusters
2830              track->GetClusters(iDet,idx);
2831              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nsp++;
2832           }  
2833       }
2834
2835       if (nsp) {
2836         AliTrackPointArray *sp = new AliTrackPointArray(nsp);
2837         track->SetTrackPointArray(sp);
2838         Int_t isptrack = 0;
2839         for (Int_t iDet = 5; iDet >= 0; iDet--) {
2840           AliTracker *tracker = fTracker[iDet];
2841           if (!tracker) continue;
2842           Int_t nspdet = track->GetClusters(iDet,idx);
2843
2844           if (iDet==0) // ITS "extra" clusters             
2845              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nspdet++;
2846
2847           if (nspdet <= 0) continue;
2848           AliTrackPoint p;
2849           Int_t isp = 0;
2850           Int_t isp2 = 0;
2851           while (isp2 < nspdet) {
2852             Bool_t isvalid=kTRUE;
2853
2854             Int_t index=idx[isp++];
2855             if (index < 0) continue;
2856
2857             TString dets = fgkDetectorName[iDet];
2858             if ((fUseTrackingErrorsForAlignment.CompareTo(dets) == 0) ||
2859             fUseTrackingErrorsForAlignment.BeginsWith(dets+" ") ||
2860             fUseTrackingErrorsForAlignment.EndsWith(" "+dets) ||
2861             fUseTrackingErrorsForAlignment.Contains(" "+dets+" ")) {
2862               isvalid = tracker->GetTrackPointTrackingError(index,p,track);
2863             } else {
2864               isvalid = tracker->GetTrackPoint(index,p); 
2865             } 
2866             isp2++;
2867             if (!isvalid) continue;
2868             if (iDet==0 && (isp-1)>=6) p.SetExtra();
2869             sp->AddPoint(isptrack,&p); isptrack++;
2870           }
2871         }       
2872       }
2873     }
2874 }
2875
2876 //_____________________________________________________________________________
2877 void AliReconstruction::FillRawDataErrorLog(Int_t iEvent, AliESDEvent* esd)
2878 {
2879   // The method reads the raw-data error log
2880   // accumulated within the rawReader.
2881   // It extracts the raw-data errors related to
2882   // the current event and stores them into
2883   // a TClonesArray inside the esd object.
2884
2885   if (!fRawReader) return;
2886
2887   for(Int_t i = 0; i < fRawReader->GetNumberOfErrorLogs(); i++) {
2888
2889     AliRawDataErrorLog *log = fRawReader->GetErrorLog(i);
2890     if (!log) continue;
2891     if (iEvent != log->GetEventNumber()) continue;
2892
2893     esd->AddRawDataErrorLog(log);
2894   }
2895
2896 }
2897
2898 //_____________________________________________________________________________
2899 void AliReconstruction::CheckQA()
2900 {
2901 // check the QA of SIM for this run and remove the detectors 
2902 // with status Fatal
2903   
2904 //      TString newRunLocalReconstruction ; 
2905 //      TString newRunTracking ;
2906 //      TString newFillESD ;
2907 //       
2908 //      for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
2909 //              TString detName(AliQAv1::GetDetName(iDet)) ;
2910 //              AliQAv1 * qa = AliQAv1::Instance(AliQAv1::DETECTORINDEX_t(iDet)) ;       
2911 //      if ( qa->IsSet(AliQAv1::DETECTORINDEX_t(iDet), AliQAv1::kSIM, specie, AliQAv1::kFATAL)) {
2912 //        AliInfo(Form("QA status for %s %s in Hits and/or SDIGITS  and/or Digits was Fatal; No reconstruction performed", 
2913 //                   detName.Data(), AliRecoParam::GetEventSpecieName(es))) ;
2914 //                      } else {
2915 //                      if ( fRunLocalReconstruction.Contains(AliQAv1::GetDetName(iDet)) || 
2916 //                                      fRunLocalReconstruction.Contains("ALL") )  {
2917 //                              newRunLocalReconstruction += detName ; 
2918 //                              newRunLocalReconstruction += " " ;                      
2919 //                      }
2920 //                      if ( fRunTracking.Contains(AliQAv1::GetDetName(iDet)) || 
2921 //                                      fRunTracking.Contains("ALL") )  {
2922 //                              newRunTracking += detName ; 
2923 //                              newRunTracking += " " ;                         
2924 //                      }
2925 //                      if ( fFillESD.Contains(AliQAv1::GetDetName(iDet)) || 
2926 //                                      fFillESD.Contains("ALL") )  {
2927 //                              newFillESD += detName ; 
2928 //                              newFillESD += " " ;                     
2929 //                      }
2930 //              }
2931 //      }
2932 //      fRunLocalReconstruction = newRunLocalReconstruction ; 
2933 //      fRunTracking            = newRunTracking ; 
2934 //      fFillESD                = newFillESD ; 
2935 }
2936
2937 //_____________________________________________________________________________
2938 Int_t AliReconstruction::GetDetIndex(const char* detector)
2939 {
2940   // return the detector index corresponding to detector
2941   Int_t index = -1 ; 
2942   for (index = 0; index < kNDetectors ; index++) {
2943     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
2944         break ; 
2945   }     
2946   return index ; 
2947 }
2948 //_____________________________________________________________________________
2949 Bool_t AliReconstruction::FinishPlaneEff() {
2950  //
2951  // Here execute all the necessary operationis, at the end of the tracking phase,
2952  // in case that evaluation of PlaneEfficiencies was required for some detector.
2953  // E.g., write into a DataBase file the PlaneEfficiency which have been evaluated.
2954  //
2955  // This Preliminary version works only FOR ITS !!!!!
2956  // other detectors (TOF,TRD, etc. have to develop their specific codes)
2957  //
2958  //  Input: none
2959  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
2960  //
2961  Bool_t ret=kFALSE;
2962  //for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
2963  for (Int_t iDet = 0; iDet < 1; iDet++) { // for the time being only ITS
2964    //if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2965    if(fTracker[iDet] && fTracker[iDet]->GetPlaneEff()) {
2966       AliPlaneEff *planeeff=fTracker[iDet]->GetPlaneEff();
2967       TString name=planeeff->GetName();
2968       name+=".root";
2969       TFile* pefile = TFile::Open(name, "RECREATE");
2970       ret=(Bool_t)planeeff->Write();
2971       pefile->Close();
2972       if(planeeff->GetCreateHistos()) {
2973         TString hname=planeeff->GetName();
2974         hname+="Histo.root";
2975         ret*=planeeff->WriteHistosToFile(hname,"RECREATE");
2976       }
2977    }
2978    if(fSPDTrackleter) {
2979      AliPlaneEff *planeeff=fSPDTrackleter->GetPlaneEff();
2980       TString name="AliITSPlaneEffSPDtracklet.root";
2981       TFile* pefile = TFile::Open(name, "RECREATE");
2982       ret=(Bool_t)planeeff->Write();
2983       pefile->Close();
2984       AliESDEvent *dummy=NULL;
2985       ret=(Bool_t)fSPDTrackleter->PostProcess(dummy); // take care of writing other files
2986    }
2987  }
2988  return ret;
2989 }
2990 //_____________________________________________________________________________
2991 Bool_t AliReconstruction::InitPlaneEff() {
2992 //
2993  // Here execute all the necessary operations, before of the tracking phase,
2994  // for the evaluation of PlaneEfficiencies, in case required for some detectors.
2995  // E.g., read from a DataBase file a first evaluation of the PlaneEfficiency
2996  // which should be updated/recalculated.
2997  //
2998  // This Preliminary version will work only FOR ITS !!!!!
2999  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3000  //
3001  //  Input: none
3002  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3003  //
3004  AliWarning(Form("Implementation of this method not yet completed !! Method return kTRUE"));
3005
3006   fSPDTrackleter = NULL;
3007   AliReconstructor* itsReconstructor = GetReconstructor(0);
3008   if (itsReconstructor) {
3009     fSPDTrackleter = itsReconstructor->CreateTrackleter(); // this is NULL unless required in RecoParam
3010   }
3011   if (fSPDTrackleter) { 
3012     AliInfo("Trackleter for SPD has been created");
3013   }
3014
3015  return kTRUE;
3016 }
3017
3018 //_____________________________________________________________________________
3019 Bool_t AliReconstruction::InitAliEVE()
3020 {
3021   // This method should be called only in case 
3022   // AliReconstruction is run
3023   // within the alieve environment.
3024   // It will initialize AliEVE in a way
3025   // so that it can visualize event processed
3026   // by AliReconstruction.
3027   // The return flag shows whenever the
3028   // AliEVE initialization was successful or not.
3029
3030   TString macroStr;
3031   macroStr.Form("%s/EVE/macros/alieve_online.C",gSystem->ExpandPathName("$ALICE_ROOT"));
3032   AliInfo(Form("Loading AliEVE macro: %s",macroStr.Data()));
3033   if (gROOT->LoadMacro(macroStr.Data()) != 0) return kFALSE;
3034
3035   gROOT->ProcessLine("if (!AliEveEventManager::GetMaster()){new AliEveEventManager();AliEveEventManager::GetMaster()->AddNewEventCommand(\"alieve_online_on_new_event()\");gEve->AddEvent(AliEveEventManager::GetMaster());};");
3036   gROOT->ProcessLine("alieve_online_init()");
3037
3038   return kTRUE;
3039 }
3040   
3041 //_____________________________________________________________________________
3042 void AliReconstruction::RunAliEVE()
3043 {
3044   // Runs AliEVE visualisation of
3045   // the current event.
3046   // Should be executed only after
3047   // successful initialization of AliEVE.
3048
3049   AliInfo("Running AliEVE...");
3050   gROOT->ProcessLine(Form("AliEveEventManager::GetMaster()->SetEvent((AliRunLoader*)0x%lx,(AliRawReader*)0x%lx,(AliESDEvent*)0x%lx,(AliESDfriend*)0x%lx);",fRunLoader,fRawReader,fesd,fesdf));
3051   gSystem->Run();
3052 }
3053
3054 //_____________________________________________________________________________
3055 Bool_t AliReconstruction::SetRunQA(TString detAndAction) 
3056 {
3057         // Allows to run QA for a selected set of detectors
3058         // and a selected set of tasks among RAWS, DIGITSR, RECPOINTS and ESDS
3059         // all selected detectors run the same selected tasks
3060         
3061         if (!detAndAction.Contains(":")) {
3062                 AliError( Form("%s is a wrong syntax, use \"DetectorList:ActionList\" \n", detAndAction.Data()) ) ;
3063                 fRunQA = kFALSE ;
3064                 return kFALSE ;                 
3065         }
3066         Int_t colon = detAndAction.Index(":") ; 
3067         fQADetectors = detAndAction(0, colon) ; 
3068         if (fQADetectors.Contains("ALL") )
3069                 fQADetectors = fFillESD ; 
3070                 fQATasks   = detAndAction(colon+1, detAndAction.Sizeof() ) ; 
3071         if (fQATasks.Contains("ALL") ) {
3072                 fQATasks = Form("%d %d %d %d", AliQAv1::kRAWS, AliQAv1::kDIGITSR, AliQAv1::kRECPOINTS, AliQAv1::kESDS) ; 
3073         } else {
3074                 fQATasks.ToUpper() ; 
3075                 TString tempo("") ; 
3076                 if ( fQATasks.Contains("RAW") ) 
3077                         tempo = Form("%d ", AliQAv1::kRAWS) ; 
3078                 if ( fQATasks.Contains("DIGIT") ) 
3079                         tempo += Form("%d ", AliQAv1::kDIGITSR) ; 
3080                 if ( fQATasks.Contains("RECPOINT") ) 
3081                         tempo += Form("%d ", AliQAv1::kRECPOINTS) ; 
3082                 if ( fQATasks.Contains("ESD") ) 
3083                         tempo += Form("%d ", AliQAv1::kESDS) ; 
3084                 fQATasks = tempo ; 
3085                 if (fQATasks.IsNull()) {
3086                         AliInfo("No QA requested\n")  ;
3087                         fRunQA = kFALSE ;
3088                         return kTRUE ; 
3089                 }
3090         }       
3091         TString tempo(fQATasks) ; 
3092         tempo.ReplaceAll(Form("%d", AliQAv1::kRAWS), AliQAv1::GetTaskName(AliQAv1::kRAWS))      ;
3093         tempo.ReplaceAll(Form("%d", AliQAv1::kDIGITSR), AliQAv1::GetTaskName(AliQAv1::kDIGITSR)) ;      
3094         tempo.ReplaceAll(Form("%d", AliQAv1::kRECPOINTS), AliQAv1::GetTaskName(AliQAv1::kRECPOINTS)) ;  
3095         tempo.ReplaceAll(Form("%d", AliQAv1::kESDS), AliQAv1::GetTaskName(AliQAv1::kESDS)) ;    
3096         AliInfo( Form("QA will be done on \"%s\" for \"%s\"\n", fQADetectors.Data(), tempo.Data()) ) ;  
3097         fRunQA = kTRUE ;
3098         return kTRUE; 
3099
3100
3101 //_____________________________________________________________________________
3102 Bool_t AliReconstruction::InitRecoParams() 
3103 {
3104   // The method accesses OCDB and retrieves all
3105   // the available reco-param objects from there.
3106
3107   Bool_t isOK = kTRUE;
3108
3109   TString detStr = fLoadCDB;
3110   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3111
3112     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3113
3114     if (fRecoParam.GetDetRecoParamArray(iDet)) {
3115       AliInfo(Form("Using custom reconstruction parameters for detector %s",fgkDetectorName[iDet]));
3116       continue;
3117     }
3118
3119     AliInfo(Form("Loading reconstruction parameter objects for detector %s",fgkDetectorName[iDet]));
3120   
3121     AliCDBPath path(fgkDetectorName[iDet],"Calib","RecoParam");
3122     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
3123     if(!entry){ 
3124       AliWarning(Form("Couldn't find RecoParam entry in OCDB for detector %s",fgkDetectorName[iDet]));
3125       isOK = kFALSE;
3126     }
3127     else {
3128       TObject *recoParamObj = entry->GetObject();
3129       if (dynamic_cast<TObjArray*>(recoParamObj)) {
3130         // The detector has a normal TobjArray of AliDetectorRecoParam objects
3131         // Registering them in AliRecoParam
3132         fRecoParam.AddDetRecoParamArray(iDet,dynamic_cast<TObjArray*>(recoParamObj));
3133       }
3134       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
3135         // The detector has only onse set of reco parameters
3136         // Registering it in AliRecoParam
3137         AliInfo(Form("Single set of reconstruction parameters found for detector %s",fgkDetectorName[iDet]));
3138         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
3139         fRecoParam.AddDetRecoParam(iDet,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
3140       }
3141       else {
3142         AliError(Form("No valid RecoParam object found in the OCDB for detector %s",fgkDetectorName[iDet]));
3143         isOK = kFALSE;
3144       }
3145       entry->SetOwner(0);
3146       AliCDBManager::Instance()->UnloadFromCache(path.GetPath());
3147     }
3148   }
3149
3150   if (AliDebugLevel() > 0) fRecoParam.Print();
3151
3152   return isOK;
3153 }
3154
3155 //_____________________________________________________________________________
3156 Bool_t AliReconstruction::GetEventInfo() 
3157 {
3158   // Fill the event info object
3159   // ...
3160   AliCodeTimerAuto("")
3161
3162   AliCentralTrigger *aCTP = NULL;
3163   if (fRawReader) {
3164     fEventInfo.SetEventType(fRawReader->GetType());
3165
3166     ULong64_t mask = fRawReader->GetClassMask();
3167     fEventInfo.SetTriggerMask(mask);
3168     UInt_t clmask = fRawReader->GetDetectorPattern()[0];
3169     fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(clmask));
3170
3171     aCTP = new AliCentralTrigger();
3172     TString configstr("");
3173     if (!aCTP->LoadConfiguration(configstr)) { // Load CTP config from OCDB
3174       AliError("No trigger configuration found in OCDB! The trigger configuration information will not be used!");
3175       delete aCTP;
3176       return kFALSE;
3177     }
3178     aCTP->SetClassMask(mask);
3179     aCTP->SetClusterMask(clmask);
3180   }
3181   else {
3182     fEventInfo.SetEventType(AliRawEventHeaderBase::kPhysicsEvent);
3183
3184     if (fRunLoader && (!fRunLoader->LoadTrigger())) {
3185       aCTP = fRunLoader->GetTrigger();
3186       fEventInfo.SetTriggerMask(aCTP->GetClassMask());
3187       fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(aCTP->GetClusterMask()));
3188     }
3189     else {
3190       AliWarning("No trigger can be loaded! The trigger information will not be used!");
3191       return kFALSE;
3192     }
3193   }
3194
3195   AliTriggerConfiguration *config = aCTP->GetConfiguration();
3196   if (!config) {
3197     AliError("No trigger configuration has been found! The trigger configuration information will not be used!");
3198     if (fRawReader) delete aCTP;
3199     return kFALSE;
3200   }
3201
3202   UChar_t clustmask = 0;
3203   TString trclasses;
3204   ULong64_t trmask = fEventInfo.GetTriggerMask();
3205   const TObjArray& classesArray = config->GetClasses();
3206   Int_t nclasses = classesArray.GetEntriesFast();
3207   for( Int_t iclass=0; iclass < nclasses; iclass++ ) {
3208     AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At(iclass);
3209     if (trclass) {
3210       Int_t trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
3211       fesd->SetTriggerClass(trclass->GetName(),trindex);
3212       if (fRawReader) fRawReader->LoadTriggerClass(trclass->GetName(),trindex);
3213       if (trmask & (1 << trindex)) {
3214         trclasses += " ";
3215         trclasses += trclass->GetName();
3216         trclasses += " ";
3217         clustmask |= trclass->GetCluster()->GetClusterMask();
3218       }
3219     }
3220   }
3221   fEventInfo.SetTriggerClasses(trclasses);
3222
3223   // Set the information in ESD
3224   fesd->SetTriggerMask(trmask);
3225   fesd->SetTriggerCluster(clustmask);
3226
3227   if (!aCTP->CheckTriggeredDetectors()) {
3228     if (fRawReader) delete aCTP;
3229     return kFALSE;
3230   }    
3231
3232   if (fRawReader) delete aCTP;
3233
3234   // We have to fill also the HLT decision here!!
3235   // ...
3236
3237   return kTRUE;
3238 }
3239
3240 const char *AliReconstruction::MatchDetectorList(const char *detectorList, UInt_t detectorMask)
3241 {
3242   // Match the detector list found in the rec.C or the default 'ALL'
3243   // to the list found in the GRP (stored there by the shuttle PP which
3244   // gets the information from ECS)
3245   static TString resultList;
3246   TString detList = detectorList;
3247
3248   resultList = "";
3249
3250   for(Int_t iDet = 0; iDet < (AliDAQ::kNDetectors-1); iDet++) {
3251     if ((detectorMask >> iDet) & 0x1) {
3252       TString det = AliDAQ::OfflineModuleName(iDet);
3253       if ((detList.CompareTo("ALL") == 0) ||
3254           ((detList.BeginsWith("ALL ") ||
3255             detList.EndsWith(" ALL") ||
3256             detList.Contains(" ALL ")) &&
3257            !(detList.BeginsWith("-"+det+" ") ||
3258              detList.EndsWith(" -"+det) ||
3259              detList.Contains(" -"+det+" "))) ||
3260           (detList.CompareTo(det) == 0) ||
3261           detList.BeginsWith(det+" ") ||
3262           detList.EndsWith(" "+det) ||
3263           detList.Contains( " "+det+" " )) {
3264         if (!resultList.EndsWith(det + " ")) {
3265           resultList += det;
3266           resultList += " ";
3267         }
3268       }        
3269     }
3270   }
3271
3272   // HLT
3273   if ((detectorMask >> AliDAQ::kHLTId) & 0x1) {
3274     TString hltDet = AliDAQ::OfflineModuleName(AliDAQ::kNDetectors-1);
3275     if ((detList.CompareTo("ALL") == 0) ||
3276         ((detList.BeginsWith("ALL ") ||
3277           detList.EndsWith(" ALL") ||
3278           detList.Contains(" ALL ")) &&
3279          !(detList.BeginsWith("-"+hltDet+" ") ||
3280            detList.EndsWith(" -"+hltDet) ||
3281            detList.Contains(" -"+hltDet+" "))) ||
3282         (detList.CompareTo(hltDet) == 0) ||
3283         detList.BeginsWith(hltDet+" ") ||
3284         detList.EndsWith(" "+hltDet) ||
3285         detList.Contains( " "+hltDet+" " )) {
3286       resultList += hltDet;
3287     }
3288   }
3289
3290   return resultList.Data();
3291
3292 }
3293
3294 //______________________________________________________________________________
3295 void AliReconstruction::Abort(const char *method, EAbort what)
3296 {
3297   // Abort processing. If what = kAbortProcess, the Process() loop will be
3298   // aborted. If what = kAbortFile, the current file in a chain will be
3299   // aborted and the processing will continue with the next file, if there
3300   // is no next file then Process() will be aborted. Abort() can also  be
3301   // called from Begin(), SlaveBegin(), Init() and Notify(). After abort
3302   // the SlaveTerminate() and Terminate() are always called. The abort flag
3303   // can be checked in these methods using GetAbort().
3304   //
3305   // The method is overwritten in AliReconstruction for better handling of
3306   // reco specific errors 
3307
3308   if (!fStopOnError) return;
3309
3310   CleanUp();
3311
3312   TString whyMess = method;
3313   whyMess += " failed! Aborting...";
3314
3315   AliError(whyMess.Data());
3316
3317   fAbort = what;
3318   TString mess = "Abort";
3319   if (fAbort == kAbortProcess)
3320     mess = "AbortProcess";
3321   else if (fAbort == kAbortFile)
3322     mess = "AbortFile";
3323
3324   Info(mess, whyMess.Data());
3325 }
3326