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