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