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