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