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