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