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