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