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