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