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