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