]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliReconstruction.cxx
Fix in FillTriggerESD()
[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         if (fRunQA) {
1639           AliQAManager::QAManager()->SetRecoParam(iDet, par) ; 
1640           AliQAManager::QAManager()->SetEventSpecie(AliRecoParam::Convert(par->GetEventSpecie())) ;
1641         }
1642       }
1643     }
1644   }
1645
1646     // QA on single raw 
1647   if (fRunQA) {
1648     AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
1649     AliQAManager::QAManager()->RunOneEvent(fRawReader) ;  
1650   }
1651     // local single event reconstruction
1652     if (!fRunLocalReconstruction.IsNull()) {
1653       TString detectors=fRunLocalReconstruction;
1654       // run HLT event reconstruction first
1655       // ;-( IsSelected changes the string
1656       if (IsSelected("HLT", detectors) &&
1657           !RunLocalEventReconstruction("HLT")) {
1658         if (fStopOnError) {CleanUp(); return kFALSE;}
1659       }
1660       detectors=fRunLocalReconstruction;
1661       detectors.ReplaceAll("HLT", "");
1662       if (!RunLocalEventReconstruction(detectors)) {
1663         if (fStopOnError) {CleanUp(); return kFALSE;}
1664       }
1665     }
1666
1667     fesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
1668     fhltesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
1669     fesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
1670     fhltesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
1671     
1672     // Set magnetic field from the tracker
1673     fesd->SetMagneticField(AliTracker::GetBz());
1674     fhltesd->SetMagneticField(AliTracker::GetBz());
1675
1676     // Set most probable pt, for B=0 tracking
1677     // Get the global reco-params. They are atposition 16 inside the array of detectors in fRecoParam
1678     const AliGRPRecoParam *grpRecoParam = dynamic_cast<const AliGRPRecoParam*>(fRecoParam.GetDetRecoParam(kNDetectors));
1679     if (grpRecoParam) AliExternalTrackParam::SetMostProbablePt(grpRecoParam->GetMostProbablePt());
1680     
1681     // Fill raw-data error log into the ESD
1682     if (fRawReader) FillRawDataErrorLog(iEvent,fesd);
1683
1684     // vertex finder
1685     if (fRunVertexFinder) {
1686       if (!RunVertexFinder(fesd)) {
1687         if (fStopOnError) {CleanUp(); return kFALSE;}
1688       }
1689     }
1690
1691     // For Plane Efficiency: run the SPD trackleter
1692     if (fRunPlaneEff && fSPDTrackleter) {
1693       if (!RunSPDTrackleting(fesd)) {
1694         if (fStopOnError) {CleanUp(); return kFALSE;}
1695       }
1696     }
1697
1698     // Muon tracking
1699     if (!fRunTracking.IsNull()) {
1700       if (fRunMuonTracking) {
1701         if (!RunMuonTracking(fesd)) {
1702           if (fStopOnError) {CleanUp(); return kFALSE;}
1703         }
1704       }
1705     }
1706
1707     // barrel tracking
1708     if (!fRunTracking.IsNull()) {
1709       if (!RunTracking(fesd)) {
1710         if (fStopOnError) {CleanUp(); return kFALSE;}
1711       }
1712     }
1713
1714     // fill ESD
1715     if (!fFillESD.IsNull()) {
1716       TString detectors=fFillESD;
1717       // run HLT first and on hltesd
1718       // ;-( IsSelected changes the string
1719       if (IsSelected("HLT", detectors) &&
1720           !FillESD(fhltesd, "HLT")) {
1721         if (fStopOnError) {CleanUp(); return kFALSE;}
1722       }
1723       detectors=fFillESD;
1724       // Temporary fix to avoid problems with HLT that overwrites the offline ESDs
1725       if (detectors.Contains("ALL")) {
1726         detectors="";
1727         for (Int_t idet=0; idet<kNDetectors; ++idet){
1728           detectors += fgkDetectorName[idet];
1729           detectors += " ";
1730         }
1731       }
1732       detectors.ReplaceAll("HLT", "");
1733       if (!FillESD(fesd, detectors)) {
1734         if (fStopOnError) {CleanUp(); return kFALSE;}
1735       }
1736     }
1737   
1738     // fill Event header information from the RawEventHeader
1739     if (fRawReader){FillRawEventHeaderESD(fesd);}
1740
1741     // combined PID
1742     AliESDpid::MakePID(fesd);
1743
1744     if (fFillTriggerESD) {
1745       if (!FillTriggerESD(fesd)) {
1746         if (fStopOnError) {CleanUp(); return kFALSE;}
1747       }
1748     }
1749
1750     ffile->cd();
1751
1752     //
1753     // Propagate track to the beam pipe  (if not already done by ITS)
1754     //
1755     const Int_t ntracks = fesd->GetNumberOfTracks();
1756     const Double_t kBz = fesd->GetMagneticField();
1757     const Double_t kRadius  = 2.8; //something less than the beam pipe radius
1758
1759     TObjArray trkArray;
1760     UShort_t *selectedIdx=new UShort_t[ntracks];
1761
1762     for (Int_t itrack=0; itrack<ntracks; itrack++){
1763       const Double_t kMaxStep = 1;   //max step over the material
1764       Bool_t ok;
1765
1766       AliESDtrack *track = fesd->GetTrack(itrack);
1767       if (!track) continue;
1768
1769       AliExternalTrackParam *tpcTrack =
1770            (AliExternalTrackParam *)track->GetTPCInnerParam();
1771       ok = kFALSE;
1772       if (tpcTrack)
1773         ok = AliTracker::
1774           PropagateTrackTo(tpcTrack,kRadius,track->GetMass(),kMaxStep,kFALSE);
1775
1776       if (ok) {
1777         Int_t n=trkArray.GetEntriesFast();
1778         selectedIdx[n]=track->GetID();
1779         trkArray.AddLast(tpcTrack);
1780       }
1781
1782       //Tracks refitted by ITS should already be at the SPD vertex
1783       if (track->IsOn(AliESDtrack::kITSrefit)) continue;
1784
1785       AliTracker::
1786          PropagateTrackTo(track,kRadius,track->GetMass(),kMaxStep,kFALSE);
1787       track->RelateToVertex(fesd->GetPrimaryVertexSPD(), kBz, kVeryBig);
1788
1789     }
1790
1791     //
1792     // Improve the reconstructed primary vertex position using the tracks
1793     //
1794     Bool_t runVertexFinderTracks = fRunVertexFinderTracks;
1795     if(fesd->GetPrimaryVertexSPD()) {
1796       TString vtitle = fesd->GetPrimaryVertexSPD()->GetTitle();
1797       if(vtitle.Contains("cosmics")) {
1798         runVertexFinderTracks=kFALSE;
1799       }
1800     }
1801
1802     if (runVertexFinderTracks) {
1803        // TPC + ITS primary vertex
1804        ftVertexer->SetITSMode();
1805        ftVertexer->SetConstraintOff();
1806        // get cuts for vertexer from AliGRPRecoParam
1807        if (grpRecoParam) {
1808          Int_t nCutsVertexer = grpRecoParam->GetVertexerTracksNCuts();
1809          Double_t *cutsVertexer = new Double_t[nCutsVertexer];
1810          grpRecoParam->GetVertexerTracksCutsITS(cutsVertexer);
1811          ftVertexer->SetCuts(cutsVertexer);
1812          delete [] cutsVertexer; cutsVertexer = NULL; 
1813          if(fDiamondProfile && grpRecoParam->GetVertexerTracksConstraintITS())
1814            ftVertexer->SetVtxStart(fDiamondProfile);
1815        }
1816        AliESDVertex *pvtx=ftVertexer->FindPrimaryVertex(fesd);
1817        if (pvtx) {
1818           if (pvtx->GetStatus()) {
1819              fesd->SetPrimaryVertexTracks(pvtx);
1820              for (Int_t i=0; i<ntracks; i++) {
1821                  AliESDtrack *t = fesd->GetTrack(i);
1822                  t->RelateToVertex(pvtx, kBz, kVeryBig);
1823              } 
1824           }
1825        }
1826
1827        // TPC-only primary vertex
1828        ftVertexer->SetTPCMode();
1829        ftVertexer->SetConstraintOff();
1830        // get cuts for vertexer from AliGRPRecoParam
1831        if (grpRecoParam) {
1832          Int_t nCutsVertexer = grpRecoParam->GetVertexerTracksNCuts();
1833          Double_t *cutsVertexer = new Double_t[nCutsVertexer];
1834          grpRecoParam->GetVertexerTracksCutsTPC(cutsVertexer);
1835          ftVertexer->SetCuts(cutsVertexer);
1836          delete [] cutsVertexer; cutsVertexer = NULL; 
1837          if(fDiamondProfileTPC && grpRecoParam->GetVertexerTracksConstraintTPC())
1838            ftVertexer->SetVtxStart(fDiamondProfileTPC);
1839        }
1840        pvtx=ftVertexer->FindPrimaryVertex(&trkArray,selectedIdx);
1841        if (pvtx) {
1842           if (pvtx->GetStatus()) {
1843              fesd->SetPrimaryVertexTPC(pvtx);
1844              for (Int_t i=0; i<ntracks; i++) {
1845                  AliESDtrack *t = fesd->GetTrack(i);
1846                  t->RelateToVertexTPC(pvtx, kBz, kVeryBig);
1847              } 
1848           }
1849        }
1850
1851     }
1852     delete[] selectedIdx;
1853
1854     if(fDiamondProfile) fesd->SetDiamond(fDiamondProfile);
1855     
1856
1857     if (fRunV0Finder) {
1858        // V0 finding
1859        AliV0vertexer vtxer;
1860        vtxer.Tracks2V0vertices(fesd);
1861
1862        if (fRunCascadeFinder) {
1863           // Cascade finding
1864           AliCascadeVertexer cvtxer;
1865           cvtxer.V0sTracks2CascadeVertices(fesd);
1866        }
1867     }
1868  
1869     // write ESD
1870     if (fCleanESD) CleanESD(fesd);
1871
1872   if (fRunQA) {
1873     AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
1874     AliQAManager::QAManager()->RunOneEvent(fesd) ; 
1875   }
1876   if (fRunGlobalQA) {
1877     AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
1878       qadm->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
1879     if (qadm && fQATasks.Contains(Form("%d", AliQAv1::kESDS)))
1880       qadm->Exec(AliQAv1::kESDS, fesd);
1881   }
1882
1883     if (fWriteESDfriend) {
1884       //      fesdf->~AliESDfriend();
1885       //  new (fesdf) AliESDfriend(); // Reset...
1886       fesd->GetESDfriend(fesdf);
1887     }
1888     ftree->Fill();
1889
1890     // Auto-save the ESD tree in case of prompt reco @P2
1891     if (fRawReader && fRawReader->UseAutoSaveESD()) {
1892       ftree->AutoSave("SaveSelf");
1893       TFile *friendfile = (TFile *)(gROOT->GetListOfFiles()->FindObject("AliESDfriends.root"));
1894       if (friendfile) friendfile->Save();
1895     }
1896
1897     // write HLT ESD
1898     fhlttree->Fill();
1899
1900     // call AliEVE
1901     if (fRunAliEVE) RunAliEVE();
1902
1903     fesd->Reset();
1904     fhltesd->Reset();
1905     if (fWriteESDfriend) {
1906       fesdf->~AliESDfriend();
1907       new (fesdf) AliESDfriend(); // Reset...
1908     }
1909  
1910     ProcInfo_t procInfo;
1911     gSystem->GetProcInfo(&procInfo);
1912     AliInfo(Form("Event %d -> Current memory usage %d %d",iEvent, procInfo.fMemResident, procInfo.fMemVirtual));
1913   
1914     fEventInfo.Reset();
1915     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1916       if (fReconstructor[iDet])
1917         fReconstructor[iDet]->SetRecoParam(NULL);
1918     }
1919         
1920   if (fRunQA || fRunGlobalQA) 
1921     AliQAManager::QAManager()->Increment() ; 
1922   
1923     return kTRUE;
1924 }
1925
1926 //_____________________________________________________________________________
1927 void AliReconstruction::SlaveTerminate()
1928 {
1929   // Finalize the run on the slave side
1930   // Called after the exit
1931   // from the event loop
1932   AliCodeTimerAuto("");
1933
1934   if (fIsNewRunLoader) { // galice.root didn't exist
1935     fRunLoader->WriteHeader("OVERWRITE");
1936     fRunLoader->CdGAFile();
1937     fRunLoader->Write(0, TObject::kOverwrite);
1938   }
1939
1940   const TMap *cdbMap = AliCDBManager::Instance()->GetStorageMap();       
1941   const TList *cdbList = AliCDBManager::Instance()->GetRetrievedIds();   
1942                  
1943    TMap *cdbMapCopy = new TMap(cdbMap->GetEntries());    
1944    cdbMapCopy->SetOwner(1);      
1945    cdbMapCopy->SetName("cdbMap");        
1946    TIter iter(cdbMap->GetTable());       
1947          
1948    TPair* pair = 0;      
1949    while((pair = dynamic_cast<TPair*> (iter.Next()))){   
1950          TObjString* keyStr = dynamic_cast<TObjString*> (pair->Key());   
1951          TObjString* valStr = dynamic_cast<TObjString*> (pair->Value());         
1952          cdbMapCopy->Add(new TObjString(keyStr->GetName()), new TObjString(valStr->GetName()));  
1953    }     
1954          
1955    TList *cdbListCopy = new TList();     
1956    cdbListCopy->SetOwner(1);     
1957    cdbListCopy->SetName("cdbList");      
1958          
1959    TIter iter2(cdbList);         
1960          
1961         AliCDBId* id=0;
1962         while((id = dynamic_cast<AliCDBId*> (iter2.Next()))){    
1963          cdbListCopy->Add(new TObjString(id->ToString().Data()));        
1964    }     
1965          
1966    ftree->GetUserInfo()->Add(cdbMapCopy);        
1967    ftree->GetUserInfo()->Add(cdbListCopy);
1968
1969
1970   ffile->cd();
1971
1972   if (fWriteESDfriend)
1973     ftree->SetBranchStatus("ESDfriend*",0);
1974   // we want to have only one tree version number
1975   ftree->Write(ftree->GetName(),TObject::kOverwrite);
1976   fhlttree->Write();
1977
1978 // Finish with Plane Efficiency evaluation: before of CleanUp !!!
1979   if (fRunPlaneEff && !FinishPlaneEff()) {
1980    AliWarning("Finish PlaneEff evaluation failed");
1981   }
1982
1983   // End of cycle for the in-loop  
1984   if (fRunQA) 
1985     AliQAManager::QAManager()->EndOfCycle() ;
1986   
1987   if (fRunGlobalQA) {
1988     AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
1989     if (qadm) {
1990       if (fQATasks.Contains(Form("%d", AliQAv1::kRECPOINTS))) 
1991         qadm->EndOfCycle(AliQAv1::kRECPOINTS);
1992       if (fQATasks.Contains(Form("%d", AliQAv1::kESDS))) 
1993         qadm->EndOfCycle(AliQAv1::kESDS);
1994       qadm->Finish();
1995     }
1996   }
1997
1998   if (fRunQA || fRunGlobalQA) {
1999     if (fInput) { 
2000       if (TNamed *outputFileName = (TNamed *) fInput->FindObject("PROOF_OUTPUTFILE")) {
2001         TString qaOutputFile = outputFileName->GetTitle();
2002         qaOutputFile.ReplaceAll(gSystem->BaseName(TUrl(outputFileName->GetTitle()).GetFile()),
2003                                 Form("Merged.%s.Data.root",AliQAv1::GetQADataFileName()));
2004         TProofOutputFile *qaProofFile = new TProofOutputFile(Form("Merged.%s.Data.root",AliQAv1::GetQADataFileName()));
2005         qaProofFile->SetOutputFileName(qaOutputFile.Data());
2006         fOutput->Add(qaProofFile);
2007         MergeQA(qaProofFile->GetFileName());
2008       }
2009     }
2010     else {
2011       MergeQA();
2012     }
2013   }
2014
2015   gROOT->cd();
2016   CleanUp();
2017 }
2018     
2019 //_____________________________________________________________________________
2020 void AliReconstruction::Terminate()
2021 {
2022   // Create tags for the events in the ESD tree (the ESD tree is always present)
2023   // In case of empty events the tags will contain dummy values
2024   AliCodeTimerAuto("");
2025
2026   // Do not call the ESD tag creator in case of PROOF-based reconstruction
2027   if (!fInput) {
2028     AliESDTagCreator *esdtagCreator = new AliESDTagCreator();
2029     esdtagCreator->CreateESDTags(fFirstEvent,fLastEvent,fGRPData, AliQAv1::Instance()->GetQA(), AliQAv1::Instance()->GetEventSpecies(), AliQAv1::kNDET, AliRecoParam::kNSpecies);
2030   }
2031
2032   // Cleanup of CDB manager: cache and active storages!
2033   AliCDBManager::Instance()->ClearCache();
2034 }
2035
2036 //_____________________________________________________________________________
2037 Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
2038 {
2039 // run the local reconstruction
2040
2041   static Int_t eventNr=0;
2042   AliCodeTimerAuto("")
2043
2044   TString detStr = detectors;
2045   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2046     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2047     AliReconstructor* reconstructor = GetReconstructor(iDet);
2048     if (!reconstructor) continue;
2049     AliLoader* loader = fLoader[iDet];
2050     // Matthias April 2008: temporary fix to run HLT reconstruction
2051     // although the HLT loader is missing
2052     if (strcmp(fgkDetectorName[iDet], "HLT")==0) {
2053       if (fRawReader) {
2054         reconstructor->Reconstruct(fRawReader, NULL);
2055       } else {
2056         TTree* dummy=NULL;
2057         reconstructor->Reconstruct(dummy, NULL);
2058       }
2059       continue;
2060     }
2061     if (!loader) {
2062       AliWarning(Form("No loader is defined for %s!",fgkDetectorName[iDet]));
2063       continue;
2064     }
2065     // conversion of digits
2066     if (fRawReader && reconstructor->HasDigitConversion()) {
2067       AliInfo(Form("converting raw data digits into root objects for %s", 
2068                    fgkDetectorName[iDet]));
2069 //      AliCodeTimerAuto(Form("converting raw data digits into root objects for %s", 
2070 //                            fgkDetectorName[iDet]));
2071       loader->LoadDigits("update");
2072       loader->CleanDigits();
2073       loader->MakeDigitsContainer();
2074       TTree* digitsTree = loader->TreeD();
2075       reconstructor->ConvertDigits(fRawReader, digitsTree);
2076       loader->WriteDigits("OVERWRITE");
2077       loader->UnloadDigits();
2078     }
2079     // local reconstruction
2080     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
2081     //AliCodeTimerAuto(Form("running reconstruction for %s", fgkDetectorName[iDet]));
2082     loader->LoadRecPoints("update");
2083     loader->CleanRecPoints();
2084     loader->MakeRecPointsContainer();
2085     TTree* clustersTree = loader->TreeR();
2086     if (fRawReader && !reconstructor->HasDigitConversion()) {
2087       reconstructor->Reconstruct(fRawReader, clustersTree);
2088     } else {
2089       loader->LoadDigits("read");
2090       TTree* digitsTree = loader->TreeD();
2091       if (!digitsTree) {
2092         AliError(Form("Can't get the %s digits tree", fgkDetectorName[iDet]));
2093         if (fStopOnError) return kFALSE;
2094       } else {
2095         reconstructor->Reconstruct(digitsTree, clustersTree);
2096         if (fRunQA) {
2097           AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2098           AliQAManager::QAManager()->RunOneEventInOneDetector(iDet, digitsTree) ; 
2099         }
2100       }
2101       loader->UnloadDigits();
2102     }
2103                 if (fRunQA) {
2104       AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2105                         AliQAManager::QAManager()->RunOneEventInOneDetector(iDet, clustersTree) ; 
2106     }
2107     loader->WriteRecPoints("OVERWRITE");
2108     loader->UnloadRecPoints();
2109     AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr), iDet,1,eventNr);
2110   }
2111   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2112     AliError(Form("the following detectors were not found: %s",
2113                   detStr.Data()));
2114     if (fStopOnError) return kFALSE;
2115   }
2116   eventNr++;
2117   return kTRUE;
2118 }
2119 //_____________________________________________________________________________
2120 Bool_t AliReconstruction::RunSPDTrackleting(AliESDEvent*& esd)
2121 {
2122 // run the SPD trackleting (for SPD efficiency purpouses)
2123
2124   AliCodeTimerAuto("")
2125
2126   Double_t vtxPos[3] = {0, 0, 0};
2127   Double_t vtxErr[3] = {0.0, 0.0, 0.0};
2128 /*
2129   TArrayF mcVertex(3);
2130   // if(MC)
2131   if (fRunLoader->GetHeader() && fRunLoader->GetHeader()->GenEventHeader()) {
2132     fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(mcVertex);
2133     for (Int_t i = 0; i < 3; i++) vtxPos[i] = mcVertex[i];
2134   }
2135 */
2136   const AliESDVertex *vertex = esd->GetVertex();
2137   if(!vertex){
2138     AliWarning("Vertex not found");
2139     return kFALSE;
2140   }
2141   vertex->GetXYZ(vtxPos);
2142   vertex->GetSigmaXYZ(vtxErr);
2143   if (fSPDTrackleter) {
2144     AliInfo("running the SPD Trackleter for Plane Efficiency Evaluation");
2145
2146     // load clusters
2147     fLoader[0]->LoadRecPoints("read");
2148     TTree* tree = fLoader[0]->TreeR();
2149     if (!tree) {
2150       AliError("Can't get the ITS cluster tree");
2151       return kFALSE;
2152     }
2153     fSPDTrackleter->LoadClusters(tree);
2154     fSPDTrackleter->SetVertex(vtxPos, vtxErr);
2155     // run trackleting
2156     if (fSPDTrackleter->Clusters2Tracks(esd) != 0) {
2157       AliError("AliITSTrackleterSPDEff Clusters2Tracks failed");
2158      // fLoader[0]->UnloadRecPoints();
2159       return kFALSE;
2160     }
2161 //fSPDTrackleter->UnloadRecPoints();
2162   } else {
2163     AliWarning("SPDTrackleter not available");
2164     return kFALSE;
2165   }
2166   return kTRUE;
2167 }
2168
2169 //_____________________________________________________________________________
2170 Bool_t AliReconstruction::RunVertexFinder(AliESDEvent*& esd)
2171 {
2172 // run the barrel tracking
2173
2174   AliCodeTimerAuto("")
2175
2176   AliVertexer *vertexer = CreateVertexer();
2177   if (!vertexer) return kFALSE;
2178
2179   AliInfo("running the ITS vertex finder");
2180   AliESDVertex* vertex = NULL;
2181   if (fLoader[0]) {
2182     fLoader[0]->LoadRecPoints();
2183     TTree* cltree = fLoader[0]->TreeR();
2184     if (cltree) {
2185       if(fDiamondProfileSPD) vertexer->SetVtxStart(fDiamondProfileSPD);
2186       vertex = vertexer->FindVertexForCurrentEvent(cltree);
2187     }
2188     else {
2189       AliError("Can't get the ITS cluster tree");
2190     }
2191     fLoader[0]->UnloadRecPoints();
2192   }
2193   else {
2194     AliError("Can't get the ITS loader");
2195   }
2196   if(!vertex){
2197     AliWarning("Vertex not found");
2198     vertex = new AliESDVertex();
2199     vertex->SetName("default");
2200   }
2201   else {
2202     vertex->SetName("reconstructed");
2203   }
2204
2205   Double_t vtxPos[3];
2206   Double_t vtxErr[3];
2207   vertex->GetXYZ(vtxPos);
2208   vertex->GetSigmaXYZ(vtxErr);
2209
2210   esd->SetPrimaryVertexSPD(vertex);
2211   AliESDVertex *vpileup = NULL;
2212   Int_t novertices = 0;
2213   vpileup = vertexer->GetAllVertices(novertices);
2214   if(novertices>1){
2215     for (Int_t kk=1; kk<novertices; kk++)esd->AddPileupVertexSPD(&vpileup[kk]);
2216   }
2217   // if SPD multiplicity has been determined, it is stored in the ESD
2218   AliMultiplicity *mult = vertexer->GetMultiplicity();
2219   if(mult)esd->SetMultiplicity(mult);
2220
2221   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2222     if (fTracker[iDet]) fTracker[iDet]->SetVertex(vtxPos, vtxErr);
2223   }  
2224   delete vertex;
2225
2226   delete vertexer;
2227
2228   return kTRUE;
2229 }
2230
2231 //_____________________________________________________________________________
2232 Bool_t AliReconstruction::RunHLTTracking(AliESDEvent*& esd)
2233 {
2234 // run the HLT barrel tracking
2235
2236   AliCodeTimerAuto("")
2237
2238   if (!fRunLoader) {
2239     AliError("Missing runLoader!");
2240     return kFALSE;
2241   }
2242
2243   AliInfo("running HLT tracking");
2244
2245   // Get a pointer to the HLT reconstructor
2246   AliReconstructor *reconstructor = GetReconstructor(kNDetectors-1);
2247   if (!reconstructor) return kFALSE;
2248
2249   // TPC + ITS
2250   for (Int_t iDet = 1; iDet >= 0; iDet--) {
2251     TString detName = fgkDetectorName[iDet];
2252     AliDebug(1, Form("%s HLT tracking", detName.Data()));
2253     reconstructor->SetOption(detName.Data());
2254     AliTracker *tracker = reconstructor->CreateTracker();
2255     if (!tracker) {
2256       AliWarning(Form("couldn't create a HLT tracker for %s", detName.Data()));
2257       if (fStopOnError) return kFALSE;
2258       continue;
2259     }
2260     Double_t vtxPos[3];
2261     Double_t vtxErr[3]={0.005,0.005,0.010};
2262     const AliESDVertex *vertex = esd->GetVertex();
2263     vertex->GetXYZ(vtxPos);
2264     tracker->SetVertex(vtxPos,vtxErr);
2265     if(iDet != 1) {
2266       fLoader[iDet]->LoadRecPoints("read");
2267       TTree* tree = fLoader[iDet]->TreeR();
2268       if (!tree) {
2269         AliError(Form("Can't get the %s cluster tree", detName.Data()));
2270         return kFALSE;
2271       }
2272       tracker->LoadClusters(tree);
2273     }
2274     if (tracker->Clusters2Tracks(esd) != 0) {
2275       AliError(Form("HLT %s Clusters2Tracks failed", fgkDetectorName[iDet]));
2276       return kFALSE;
2277     }
2278     if(iDet != 1) {
2279       tracker->UnloadClusters();
2280     }
2281     delete tracker;
2282   }
2283
2284   return kTRUE;
2285 }
2286
2287 //_____________________________________________________________________________
2288 Bool_t AliReconstruction::RunMuonTracking(AliESDEvent*& esd)
2289 {
2290 // run the muon spectrometer tracking
2291
2292   AliCodeTimerAuto("")
2293
2294   if (!fRunLoader) {
2295     AliError("Missing runLoader!");
2296     return kFALSE;
2297   }
2298   Int_t iDet = 7; // for MUON
2299
2300   AliInfo("is running...");
2301
2302   // Get a pointer to the MUON reconstructor
2303   AliReconstructor *reconstructor = GetReconstructor(iDet);
2304   if (!reconstructor) return kFALSE;
2305
2306   
2307   TString detName = fgkDetectorName[iDet];
2308   AliDebug(1, Form("%s tracking", detName.Data()));
2309   AliTracker *tracker =  reconstructor->CreateTracker();
2310   if (!tracker) {
2311     AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
2312     return kFALSE;
2313   }
2314      
2315   // read RecPoints
2316   fLoader[iDet]->LoadRecPoints("read");  
2317
2318   tracker->LoadClusters(fLoader[iDet]->TreeR());
2319   
2320   Int_t rv = tracker->Clusters2Tracks(esd);
2321   
2322   if ( rv )
2323   {
2324     AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
2325     return kFALSE;
2326   }
2327   
2328   fLoader[iDet]->UnloadRecPoints();
2329
2330   tracker->UnloadClusters();
2331   
2332   delete tracker;
2333   
2334   return kTRUE;
2335 }
2336
2337
2338 //_____________________________________________________________________________
2339 Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd)
2340 {
2341 // run the barrel tracking
2342   static Int_t eventNr=0;
2343   AliCodeTimerAuto("")
2344
2345   AliInfo("running tracking");
2346
2347   
2348   //Fill the ESD with the T0 info (will be used by the TOF) 
2349   if (fReconstructor[11] && fLoader[11]) {
2350     fLoader[11]->LoadRecPoints("READ");
2351     TTree *treeR = fLoader[11]->TreeR();
2352     if (treeR) {
2353       GetReconstructor(11)->FillESD((TTree *)NULL,treeR,esd);
2354     }
2355   }
2356
2357   // pass 1: TPC + ITS inwards
2358   for (Int_t iDet = 1; iDet >= 0; iDet--) {
2359     if (!fTracker[iDet]) continue;
2360     AliDebug(1, Form("%s tracking", fgkDetectorName[iDet]));
2361
2362     // load clusters
2363     fLoader[iDet]->LoadRecPoints("read");
2364     AliSysInfo::AddStamp(Form("RLoadCluster%s_%d",fgkDetectorName[iDet],eventNr),iDet,1, eventNr);
2365     TTree* tree = fLoader[iDet]->TreeR();
2366     if (!tree) {
2367       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
2368       return kFALSE;
2369     }
2370     fTracker[iDet]->LoadClusters(tree);
2371     AliSysInfo::AddStamp(Form("TLoadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
2372     // run tracking
2373     if (fTracker[iDet]->Clusters2Tracks(esd) != 0) {
2374       AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
2375       return kFALSE;
2376     }
2377     // preliminary PID in TPC needed by the ITS tracker
2378     if (iDet == 1) {
2379       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
2380       AliESDpid::MakePID(esd);
2381     } 
2382     AliSysInfo::AddStamp(Form("Tracking0%s_%d",fgkDetectorName[iDet],eventNr), iDet,3,eventNr);
2383   }
2384
2385   // pass 2: ALL backwards
2386
2387   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2388     if (!fTracker[iDet]) continue;
2389     AliDebug(1, Form("%s back propagation", fgkDetectorName[iDet]));
2390
2391     // load clusters
2392     if (iDet > 1) {     // all except ITS, TPC
2393       TTree* tree = NULL;
2394       fLoader[iDet]->LoadRecPoints("read");
2395       AliSysInfo::AddStamp(Form("RLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,1, eventNr);
2396       tree = fLoader[iDet]->TreeR();
2397       if (!tree) {
2398         AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
2399         return kFALSE;
2400       }
2401       fTracker[iDet]->LoadClusters(tree); 
2402       AliSysInfo::AddStamp(Form("TLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
2403     }
2404
2405     // run tracking
2406     if (iDet>1) // start filling residuals for the "outer" detectors
2407       if (fRunGlobalQA) {
2408         AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
2409         TObjArray ** arr = AliTracker::GetResidualsArray() ; 
2410         if (arr) {
2411           AliRecoParam::EventSpecie_t es=fRecoParam.GetEventSpecie();
2412           TObjArray * elem = arr[AliRecoParam::AConvert(es)];
2413           if ( elem && (! elem->At(0)) ) {
2414             AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
2415             if (qadm) qadm->InitRecPointsForTracker() ; 
2416           }
2417         }
2418       }
2419     if (fTracker[iDet]->PropagateBack(esd) != 0) {
2420       AliError(Form("%s backward propagation failed", fgkDetectorName[iDet]));
2421       //      return kFALSE;
2422     }
2423
2424     // unload clusters
2425     if (iDet > 3) {     // all except ITS, TPC, TRD and TOF
2426       fTracker[iDet]->UnloadClusters();
2427       fLoader[iDet]->UnloadRecPoints();
2428     }
2429     // updated PID in TPC needed by the ITS tracker -MI
2430     if (iDet == 1) {
2431       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
2432       AliESDpid::MakePID(esd);
2433     }
2434     AliSysInfo::AddStamp(Form("Tracking1%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
2435   }
2436   //stop filling residuals for the "outer" detectors
2437   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
2438
2439   // pass 3: TRD + TPC + ITS refit inwards
2440
2441   for (Int_t iDet = 2; iDet >= 0; iDet--) {
2442     if (!fTracker[iDet]) continue;
2443     AliDebug(1, Form("%s inward refit", fgkDetectorName[iDet]));
2444
2445     // run tracking
2446     if (iDet<2) // start filling residuals for TPC and ITS
2447       if (fRunGlobalQA) {
2448         AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
2449         TObjArray ** arr = AliTracker::GetResidualsArray() ; 
2450         if (arr) {
2451           AliRecoParam::EventSpecie_t es=fRecoParam.GetEventSpecie();
2452           TObjArray * elem = arr[AliRecoParam::AConvert(es)];
2453           if ( elem && (! elem->At(0)) ) {
2454             AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
2455             if (qadm) qadm->InitRecPointsForTracker() ; 
2456           }
2457         }
2458       }
2459     
2460     if (fTracker[iDet]->RefitInward(esd) != 0) {
2461       AliError(Form("%s inward refit failed", fgkDetectorName[iDet]));
2462       //      return kFALSE;
2463     }
2464     // run postprocessing
2465     if (fTracker[iDet]->PostProcess(esd) != 0) {
2466       AliError(Form("%s postprocessing failed", fgkDetectorName[iDet]));
2467       //      return kFALSE;
2468     }
2469     AliSysInfo::AddStamp(Form("Tracking2%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
2470   }
2471
2472   // write space-points to the ESD in case alignment data output
2473   // is switched on
2474   if (fWriteAlignmentData)
2475     WriteAlignmentData(esd);
2476
2477   for (Int_t iDet = 3; iDet >= 0; iDet--) {
2478     if (!fTracker[iDet]) continue;
2479     // unload clusters
2480     fTracker[iDet]->UnloadClusters();
2481     AliSysInfo::AddStamp(Form("TUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,4, eventNr);
2482     fLoader[iDet]->UnloadRecPoints();
2483     AliSysInfo::AddStamp(Form("RUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,5, eventNr);
2484   }
2485   // stop filling residuals for TPC and ITS
2486   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
2487
2488   eventNr++;
2489   return kTRUE;
2490 }
2491
2492 //_____________________________________________________________________________
2493 Bool_t AliReconstruction::CleanESD(AliESDEvent *esd){
2494   //
2495   // Remove the data which are not needed for the physics analysis.
2496   //
2497
2498   Int_t nTracks=esd->GetNumberOfTracks();
2499   Int_t nV0s=esd->GetNumberOfV0s();
2500   AliInfo
2501   (Form("Number of ESD tracks and V0s before cleaning: %d %d",nTracks,nV0s));
2502
2503   Float_t cleanPars[]={fV0DCAmax,fV0CsPmin,fDmax,fZmax};
2504   Bool_t rc=esd->Clean(cleanPars);
2505
2506   nTracks=esd->GetNumberOfTracks();
2507   nV0s=esd->GetNumberOfV0s();
2508   AliInfo
2509   (Form("Number of ESD tracks and V0s after cleaning %d %d",nTracks,nV0s));
2510
2511   return rc;
2512 }
2513
2514 //_____________________________________________________________________________
2515 Bool_t AliReconstruction::FillESD(AliESDEvent*& esd, const TString& detectors)
2516 {
2517 // fill the event summary data
2518
2519   AliCodeTimerAuto("")
2520     static Int_t eventNr=0; 
2521   TString detStr = detectors;
2522   
2523   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2524   if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2525     AliReconstructor* reconstructor = GetReconstructor(iDet);
2526     if (!reconstructor) continue;
2527     AliDebug(1, Form("filling ESD for %s", fgkDetectorName[iDet]));
2528     TTree* clustersTree = NULL;
2529     if (fLoader[iDet]) {
2530       fLoader[iDet]->LoadRecPoints("read");
2531       clustersTree = fLoader[iDet]->TreeR();
2532       if (!clustersTree) {
2533         AliError(Form("Can't get the %s clusters tree", 
2534                       fgkDetectorName[iDet]));
2535         if (fStopOnError) return kFALSE;
2536       }
2537     }
2538     if (fRawReader && !reconstructor->HasDigitConversion()) {
2539       reconstructor->FillESD(fRawReader, clustersTree, esd);
2540     } else {
2541       TTree* digitsTree = NULL;
2542       if (fLoader[iDet]) {
2543         fLoader[iDet]->LoadDigits("read");
2544         digitsTree = fLoader[iDet]->TreeD();
2545         if (!digitsTree) {
2546           AliError(Form("Can't get the %s digits tree", 
2547                         fgkDetectorName[iDet]));
2548           if (fStopOnError) return kFALSE;
2549         }
2550       }
2551       reconstructor->FillESD(digitsTree, clustersTree, esd);
2552       if (fLoader[iDet]) fLoader[iDet]->UnloadDigits();
2553     }
2554     if (fLoader[iDet]) {
2555       fLoader[iDet]->UnloadRecPoints();
2556     }
2557   }
2558
2559   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2560     AliError(Form("the following detectors were not found: %s", 
2561                   detStr.Data()));
2562     if (fStopOnError) return kFALSE;
2563   }
2564   AliSysInfo::AddStamp(Form("FillESD%d",eventNr), 0,1, eventNr);
2565   eventNr++;
2566   return kTRUE;
2567 }
2568
2569 //_____________________________________________________________________________
2570 Bool_t AliReconstruction::FillTriggerESD(AliESDEvent*& esd)
2571 {
2572   // Reads the trigger decision which is
2573   // stored in Trigger.root file and fills
2574   // the corresponding esd entries
2575
2576   AliCodeTimerAuto("")
2577   
2578   AliInfo("Filling trigger information into the ESD");
2579
2580   if (fRawReader) {
2581     AliCTPRawStream input(fRawReader);
2582     if (!input.Next()) {
2583       AliWarning("No valid CTP (trigger) DDL raw data is found ! The trigger info is taken from the event header!");
2584     }
2585     else {
2586       if (esd->GetTriggerMask() != input.GetClassMask())
2587         AliError(Form("Invalid trigger pattern found in CTP raw-data: %llx %llx",
2588                       input.GetClassMask(),esd->GetTriggerMask()));
2589       if (esd->GetOrbitNumber() != input.GetOrbitID())
2590         AliError(Form("Invalid orbit id found in CTP raw-data: %x %x",
2591                       input.GetOrbitID(),esd->GetOrbitNumber()));
2592       if (esd->GetBunchCrossNumber() != input.GetBCID())
2593         AliError(Form("Invalid bunch-crossing id found in CTP raw-data: %x %x",
2594                       input.GetBCID(),esd->GetBunchCrossNumber()));
2595       AliESDHeader* esdheader = esd->GetHeader();
2596       esdheader->SetL0TriggerInputs(input.GetL0Inputs());
2597       esdheader->SetL1TriggerInputs(input.GetL1Inputs());
2598       esdheader->SetL2TriggerInputs(input.GetL2Inputs());
2599       // IR
2600       UInt_t orbit=input.GetOrbitID();
2601        for(Int_t i=0 ; i<input.GetNIRs() ; i++ )
2602           if(TMath::Abs(Int_t(orbit-(input.GetIR(i))->GetOrbit()))<=1){
2603              esdheader->AddTriggerIR(input.GetIR(i));
2604           }
2605     }
2606   }
2607   //Scalers
2608   //fRunScalers->Print();
2609   if(fRunScalers && fRunScalers->CheckRunScalers()){
2610      AliTimeStamp* timestamp = new AliTimeStamp(esd->GetOrbitNumber(), esd->GetPeriodNumber(), esd->GetBunchCrossNumber());
2611      //AliTimeStamp* timestamp = new AliTimeStamp(10308000, 0, (ULong64_t)486238);
2612      AliESDHeader* esdheader = fesd->GetHeader();
2613      for(Int_t i=0;i<50;i++){
2614           if((1<<i) & esd->GetTriggerMask()){
2615           AliTriggerScalersESD* scalesd = fRunScalers->GetScalersForEventClass( timestamp, i+1);
2616           if(scalesd)esdheader->SetTriggerScalersRecord(scalesd);
2617         }
2618      }
2619   }
2620   return kTRUE;
2621 }
2622 //_____________________________________________________________________________
2623 Bool_t AliReconstruction::FillRawEventHeaderESD(AliESDEvent*& esd)
2624 {
2625   // 
2626   // Filling information from RawReader Header
2627   // 
2628
2629   if (!fRawReader) return kFALSE;
2630
2631   AliInfo("Filling information from RawReader Header");
2632
2633   esd->SetBunchCrossNumber(fRawReader->GetBCID());
2634   esd->SetOrbitNumber(fRawReader->GetOrbitID());
2635   esd->SetPeriodNumber(fRawReader->GetPeriod());
2636
2637   esd->SetTimeStamp(fRawReader->GetTimestamp());  
2638   esd->SetEventType(fRawReader->GetType());
2639
2640   return kTRUE;
2641 }
2642
2643
2644 //_____________________________________________________________________________
2645 Bool_t AliReconstruction::IsSelected(TString detName, TString& detectors) const
2646 {
2647 // check whether detName is contained in detectors
2648 // if yes, it is removed from detectors
2649
2650   // check if all detectors are selected
2651   if ((detectors.CompareTo("ALL") == 0) ||
2652       detectors.BeginsWith("ALL ") ||
2653       detectors.EndsWith(" ALL") ||
2654       detectors.Contains(" ALL ")) {
2655     detectors = "ALL";
2656     return kTRUE;
2657   }
2658
2659   // search for the given detector
2660   Bool_t result = kFALSE;
2661   if ((detectors.CompareTo(detName) == 0) ||
2662       detectors.BeginsWith(detName+" ") ||
2663       detectors.EndsWith(" "+detName) ||
2664       detectors.Contains(" "+detName+" ")) {
2665     detectors.ReplaceAll(detName, "");
2666     result = kTRUE;
2667   }
2668
2669   // clean up the detectors string
2670   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
2671   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
2672   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
2673
2674   return result;
2675 }
2676
2677 //_____________________________________________________________________________
2678 Bool_t AliReconstruction::InitRunLoader()
2679 {
2680 // get or create the run loader
2681
2682   if (gAlice) delete gAlice;
2683   gAlice = NULL;
2684
2685   if (!gSystem->AccessPathName(fGAliceFileName.Data())) { // galice.root exists
2686     // load all base libraries to get the loader classes
2687     TString libs = gSystem->GetLibraries();
2688     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2689       TString detName = fgkDetectorName[iDet];
2690       if (detName == "HLT") continue;
2691       if (libs.Contains("lib" + detName + "base.so")) continue;
2692       gSystem->Load("lib" + detName + "base.so");
2693     }
2694     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data());
2695     if (!fRunLoader) {
2696       AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
2697       CleanUp();
2698       return kFALSE;
2699     }
2700
2701     fRunLoader->CdGAFile();
2702     fRunLoader->LoadgAlice();
2703
2704     //PH This is a temporary fix to give access to the kinematics
2705     //PH that is needed for the labels of ITS clusters
2706     fRunLoader->LoadHeader();
2707     fRunLoader->LoadKinematics();
2708
2709   } else {               // galice.root does not exist
2710     if (!fRawReader) {
2711       AliError(Form("the file %s does not exist", fGAliceFileName.Data()));
2712     }
2713     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data(),
2714                                     AliConfig::GetDefaultEventFolderName(),
2715                                     "recreate");
2716     if (!fRunLoader) {
2717       AliError(Form("could not create run loader in file %s", 
2718                     fGAliceFileName.Data()));
2719       CleanUp();
2720       return kFALSE;
2721     }
2722     fIsNewRunLoader = kTRUE;
2723     fRunLoader->MakeTree("E");
2724
2725     if (fNumberOfEventsPerFile > 0)
2726       fRunLoader->SetNumberOfEventsPerFile(fNumberOfEventsPerFile);
2727     else
2728       fRunLoader->SetNumberOfEventsPerFile((UInt_t)-1);
2729   }
2730
2731   return kTRUE;
2732 }
2733
2734 //_____________________________________________________________________________
2735 AliReconstructor* AliReconstruction::GetReconstructor(Int_t iDet)
2736 {
2737 // get the reconstructor object and the loader for a detector
2738
2739   if (fReconstructor[iDet]) {
2740     if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
2741       const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
2742       fReconstructor[iDet]->SetRecoParam(par);
2743     }
2744     return fReconstructor[iDet];
2745   }
2746
2747   // load the reconstructor object
2748   TPluginManager* pluginManager = gROOT->GetPluginManager();
2749   TString detName = fgkDetectorName[iDet];
2750   TString recName = "Ali" + detName + "Reconstructor";
2751
2752   if (!fIsNewRunLoader && !fRunLoader->GetLoader(detName+"Loader") && (detName != "HLT")) return NULL;
2753
2754   AliReconstructor* reconstructor = NULL;
2755   // first check if a plugin is defined for the reconstructor
2756   TPluginHandler* pluginHandler = 
2757     pluginManager->FindHandler("AliReconstructor", detName);
2758   // if not, add a plugin for it
2759   if (!pluginHandler) {
2760     AliDebug(1, Form("defining plugin for %s", recName.Data()));
2761     TString libs = gSystem->GetLibraries();
2762     if (libs.Contains("lib" + detName + "base.so") ||
2763         (gSystem->Load("lib" + detName + "base.so") >= 0)) {
2764       pluginManager->AddHandler("AliReconstructor", detName, 
2765                                 recName, detName + "rec", recName + "()");
2766     } else {
2767       pluginManager->AddHandler("AliReconstructor", detName, 
2768                                 recName, detName, recName + "()");
2769     }
2770     pluginHandler = pluginManager->FindHandler("AliReconstructor", detName);
2771   }
2772   if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
2773     reconstructor = (AliReconstructor*) pluginHandler->ExecPlugin(0);
2774   }
2775   if (reconstructor) {
2776     TObject* obj = fOptions.FindObject(detName.Data());
2777     if (obj) reconstructor->SetOption(obj->GetTitle());
2778     reconstructor->Init();
2779     fReconstructor[iDet] = reconstructor;
2780   }
2781
2782   // get or create the loader
2783   if (detName != "HLT") {
2784     fLoader[iDet] = fRunLoader->GetLoader(detName + "Loader");
2785     if (!fLoader[iDet]) {
2786       AliConfig::Instance()
2787         ->CreateDetectorFolders(fRunLoader->GetEventFolder(), 
2788                                 detName, detName);
2789       // first check if a plugin is defined for the loader
2790       pluginHandler = 
2791         pluginManager->FindHandler("AliLoader", detName);
2792       // if not, add a plugin for it
2793       if (!pluginHandler) {
2794         TString loaderName = "Ali" + detName + "Loader";
2795         AliDebug(1, Form("defining plugin for %s", loaderName.Data()));
2796         pluginManager->AddHandler("AliLoader", detName, 
2797                                   loaderName, detName + "base", 
2798                                   loaderName + "(const char*, TFolder*)");
2799         pluginHandler = pluginManager->FindHandler("AliLoader", detName);
2800       }
2801       if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
2802         fLoader[iDet] = 
2803           (AliLoader*) pluginHandler->ExecPlugin(2, detName.Data(), 
2804                                                  fRunLoader->GetEventFolder());
2805       }
2806       if (!fLoader[iDet]) {   // use default loader
2807         fLoader[iDet] = new AliLoader(detName, fRunLoader->GetEventFolder());
2808       }
2809       if (!fLoader[iDet]) {
2810         AliWarning(Form("couldn't get loader for %s", detName.Data()));
2811         if (fStopOnError) return NULL;
2812       } else {
2813         fRunLoader->AddLoader(fLoader[iDet]);
2814         fRunLoader->CdGAFile();
2815         if (gFile && !gFile->IsWritable()) gFile->ReOpen("UPDATE");
2816         fRunLoader->Write(0, TObject::kOverwrite);
2817       }
2818     }
2819   }
2820       
2821   if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
2822     const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
2823     reconstructor->SetRecoParam(par);
2824   }
2825   return reconstructor;
2826 }
2827
2828 //_____________________________________________________________________________
2829 AliVertexer* AliReconstruction::CreateVertexer()
2830 {
2831 // create the vertexer
2832 // Please note that the caller is the owner of the
2833 // vertexer
2834
2835   AliVertexer* vertexer = NULL;
2836   AliReconstructor* itsReconstructor = GetReconstructor(0);
2837   if (itsReconstructor && (fRunLocalReconstruction.Contains("ITS"))) {
2838     vertexer = itsReconstructor->CreateVertexer();
2839   }
2840   if (!vertexer) {
2841     AliWarning("couldn't create a vertexer for ITS");
2842   }
2843
2844   return vertexer;
2845 }
2846
2847 //_____________________________________________________________________________
2848 Bool_t AliReconstruction::CreateTrackers(const TString& detectors)
2849 {
2850 // create the trackers
2851         AliInfo("Creating trackers");
2852
2853   TString detStr = detectors;
2854   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2855     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2856     AliReconstructor* reconstructor = GetReconstructor(iDet);
2857     if (!reconstructor) continue;
2858     TString detName = fgkDetectorName[iDet];
2859     if (detName == "HLT") {
2860       fRunHLTTracking = kTRUE;
2861       continue;
2862     }
2863     if (detName == "MUON") {
2864       fRunMuonTracking = kTRUE;
2865       continue;
2866     }
2867
2868
2869     fTracker[iDet] = reconstructor->CreateTracker();
2870     if (!fTracker[iDet] && (iDet < 7)) {
2871       AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
2872       if (fStopOnError) return kFALSE;
2873     }
2874     AliSysInfo::AddStamp(Form("LTracker%s",fgkDetectorName[iDet]), iDet,0);
2875   }
2876
2877   return kTRUE;
2878 }
2879
2880 //_____________________________________________________________________________
2881 void AliReconstruction::CleanUp()
2882 {
2883 // delete trackers and the run loader and close and delete the file
2884
2885   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2886     delete fReconstructor[iDet];
2887     fReconstructor[iDet] = NULL;
2888     fLoader[iDet] = NULL;
2889     delete fTracker[iDet];
2890     fTracker[iDet] = NULL;
2891   }
2892   delete fRunInfo;
2893   fRunInfo = NULL;
2894
2895   delete fSPDTrackleter;
2896   fSPDTrackleter = NULL;
2897
2898   delete ftVertexer;
2899   ftVertexer = NULL;
2900   
2901   delete fRunLoader;
2902   fRunLoader = NULL;
2903   delete fRawReader;
2904   fRawReader = NULL;
2905   delete fParentRawReader;
2906   fParentRawReader=NULL;
2907
2908   if (ffile) {
2909     ffile->Close();
2910     delete ffile;
2911     ffile = NULL;
2912   }
2913
2914   if (AliQAManager::QAManager())
2915     AliQAManager::QAManager()->ShowQA() ; 
2916   AliQAManager::Destroy() ; 
2917   
2918   TGeoGlobalMagField::Instance()->SetField(NULL);
2919 }
2920
2921 void AliReconstruction::WriteAlignmentData(AliESDEvent* esd)
2922 {
2923   // Write space-points which are then used in the alignment procedures
2924   // For the moment only ITS, TPC, TRD and TOF
2925
2926   Int_t ntracks = esd->GetNumberOfTracks();
2927   for (Int_t itrack = 0; itrack < ntracks; itrack++)
2928     {
2929       AliESDtrack *track = esd->GetTrack(itrack);
2930       Int_t nsp = 0;
2931       Int_t idx[200];
2932       for (Int_t i=0; i<200; ++i) idx[i] = -1; //PH avoid uninitialized values
2933       for (Int_t iDet = 5; iDet >= 0; iDet--) {// TOF, TRD, TPC, ITS clusters
2934           nsp += track->GetNcls(iDet);
2935
2936           if (iDet==0) { // ITS "extra" clusters
2937              track->GetClusters(iDet,idx);
2938              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nsp++;
2939           }  
2940       }
2941
2942       if (nsp) {
2943         AliTrackPointArray *sp = new AliTrackPointArray(nsp);
2944         track->SetTrackPointArray(sp);
2945         Int_t isptrack = 0;
2946         for (Int_t iDet = 5; iDet >= 0; iDet--) {
2947           AliTracker *tracker = fTracker[iDet];
2948           if (!tracker) continue;
2949           Int_t nspdet = track->GetClusters(iDet,idx);
2950
2951           if (iDet==0) // ITS "extra" clusters             
2952              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nspdet++;
2953
2954           if (nspdet <= 0) continue;
2955           AliTrackPoint p;
2956           Int_t isp = 0;
2957           Int_t isp2 = 0;
2958           while (isp2 < nspdet) {
2959             Bool_t isvalid=kTRUE;
2960
2961             Int_t index=idx[isp++];
2962             if (index < 0) continue;
2963
2964             TString dets = fgkDetectorName[iDet];
2965             if ((fUseTrackingErrorsForAlignment.CompareTo(dets) == 0) ||
2966             fUseTrackingErrorsForAlignment.BeginsWith(dets+" ") ||
2967             fUseTrackingErrorsForAlignment.EndsWith(" "+dets) ||
2968             fUseTrackingErrorsForAlignment.Contains(" "+dets+" ")) {
2969               isvalid = tracker->GetTrackPointTrackingError(index,p,track);
2970             } else {
2971               isvalid = tracker->GetTrackPoint(index,p); 
2972             } 
2973             isp2++;
2974             if (!isvalid) continue;
2975             if (iDet==0 && (isp-1)>=6) p.SetExtra();
2976             sp->AddPoint(isptrack,&p); isptrack++;
2977           }
2978         }       
2979       }
2980     }
2981 }
2982
2983 //_____________________________________________________________________________
2984 void AliReconstruction::FillRawDataErrorLog(Int_t iEvent, AliESDEvent* esd)
2985 {
2986   // The method reads the raw-data error log
2987   // accumulated within the rawReader.
2988   // It extracts the raw-data errors related to
2989   // the current event and stores them into
2990   // a TClonesArray inside the esd object.
2991
2992   if (!fRawReader) return;
2993
2994   for(Int_t i = 0; i < fRawReader->GetNumberOfErrorLogs(); i++) {
2995
2996     AliRawDataErrorLog *log = fRawReader->GetErrorLog(i);
2997     if (!log) continue;
2998     if (iEvent != log->GetEventNumber()) continue;
2999
3000     esd->AddRawDataErrorLog(log);
3001   }
3002
3003 }
3004
3005 //_____________________________________________________________________________
3006 void AliReconstruction::CheckQA()
3007 {
3008 // check the QA of SIM for this run and remove the detectors 
3009 // with status Fatal
3010   
3011 //      TString newRunLocalReconstruction ; 
3012 //      TString newRunTracking ;
3013 //      TString newFillESD ;
3014 //       
3015 //      for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
3016 //              TString detName(AliQAv1::GetDetName(iDet)) ;
3017 //              AliQAv1 * qa = AliQAv1::Instance(AliQAv1::DETECTORINDEX_t(iDet)) ;       
3018 //      if ( qa->IsSet(AliQAv1::DETECTORINDEX_t(iDet), AliQAv1::kSIM, specie, AliQAv1::kFATAL)) {
3019 //        AliInfo(Form("QA status for %s %s in Hits and/or SDIGITS  and/or Digits was Fatal; No reconstruction performed", 
3020 //                   detName.Data(), AliRecoParam::GetEventSpecieName(es))) ;
3021 //                      } else {
3022 //                      if ( fRunLocalReconstruction.Contains(AliQAv1::GetDetName(iDet)) || 
3023 //                                      fRunLocalReconstruction.Contains("ALL") )  {
3024 //                              newRunLocalReconstruction += detName ; 
3025 //                              newRunLocalReconstruction += " " ;                      
3026 //                      }
3027 //                      if ( fRunTracking.Contains(AliQAv1::GetDetName(iDet)) || 
3028 //                                      fRunTracking.Contains("ALL") )  {
3029 //                              newRunTracking += detName ; 
3030 //                              newRunTracking += " " ;                         
3031 //                      }
3032 //                      if ( fFillESD.Contains(AliQAv1::GetDetName(iDet)) || 
3033 //                                      fFillESD.Contains("ALL") )  {
3034 //                              newFillESD += detName ; 
3035 //                              newFillESD += " " ;                     
3036 //                      }
3037 //              }
3038 //      }
3039 //      fRunLocalReconstruction = newRunLocalReconstruction ; 
3040 //      fRunTracking            = newRunTracking ; 
3041 //      fFillESD                = newFillESD ; 
3042 }
3043
3044 //_____________________________________________________________________________
3045 Int_t AliReconstruction::GetDetIndex(const char* detector)
3046 {
3047   // return the detector index corresponding to detector
3048   Int_t index = -1 ; 
3049   for (index = 0; index < kNDetectors ; index++) {
3050     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
3051         break ; 
3052   }     
3053   return index ; 
3054 }
3055 //_____________________________________________________________________________
3056 Bool_t AliReconstruction::FinishPlaneEff() {
3057  //
3058  // Here execute all the necessary operationis, at the end of the tracking phase,
3059  // in case that evaluation of PlaneEfficiencies was required for some detector.
3060  // E.g., write into a DataBase file the PlaneEfficiency which have been evaluated.
3061  //
3062  // This Preliminary version works only FOR ITS !!!!!
3063  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3064  //
3065  //  Input: none
3066  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3067  //
3068  Bool_t ret=kFALSE;
3069  //for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
3070  for (Int_t iDet = 0; iDet < 1; iDet++) { // for the time being only ITS
3071    //if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3072    if(fTracker[iDet] && fTracker[iDet]->GetPlaneEff()) {
3073       AliPlaneEff *planeeff=fTracker[iDet]->GetPlaneEff();
3074       TString name=planeeff->GetName();
3075       name+=".root";
3076       TFile* pefile = TFile::Open(name, "RECREATE");
3077       ret=(Bool_t)planeeff->Write();
3078       pefile->Close();
3079       if(planeeff->GetCreateHistos()) {
3080         TString hname=planeeff->GetName();
3081         hname+="Histo.root";
3082         ret*=planeeff->WriteHistosToFile(hname,"RECREATE");
3083       }
3084    }
3085    if(fSPDTrackleter) {
3086      AliPlaneEff *planeeff=fSPDTrackleter->GetPlaneEff();
3087       TString name="AliITSPlaneEffSPDtracklet.root";
3088       TFile* pefile = TFile::Open(name, "RECREATE");
3089       ret=(Bool_t)planeeff->Write();
3090       pefile->Close();
3091       AliESDEvent *dummy=NULL;
3092       ret=(Bool_t)fSPDTrackleter->PostProcess(dummy); // take care of writing other files
3093    }
3094  }
3095  return ret;
3096 }
3097 //_____________________________________________________________________________
3098 Bool_t AliReconstruction::InitPlaneEff() {
3099 //
3100  // Here execute all the necessary operations, before of the tracking phase,
3101  // for the evaluation of PlaneEfficiencies, in case required for some detectors.
3102  // E.g., read from a DataBase file a first evaluation of the PlaneEfficiency
3103  // which should be updated/recalculated.
3104  //
3105  // This Preliminary version will work only FOR ITS !!!!!
3106  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3107  //
3108  //  Input: none
3109  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3110  //
3111  AliWarning(Form("Implementation of this method not yet completed !! Method return kTRUE"));
3112
3113   fSPDTrackleter = NULL;
3114   AliReconstructor* itsReconstructor = GetReconstructor(0);
3115   if (itsReconstructor) {
3116     fSPDTrackleter = itsReconstructor->CreateTrackleter(); // this is NULL unless required in RecoParam
3117   }
3118   if (fSPDTrackleter) { 
3119     AliInfo("Trackleter for SPD has been created");
3120   }
3121
3122  return kTRUE;
3123 }
3124
3125 //_____________________________________________________________________________
3126 Bool_t AliReconstruction::InitAliEVE()
3127 {
3128   // This method should be called only in case 
3129   // AliReconstruction is run
3130   // within the alieve environment.
3131   // It will initialize AliEVE in a way
3132   // so that it can visualize event processed
3133   // by AliReconstruction.
3134   // The return flag shows whenever the
3135   // AliEVE initialization was successful or not.
3136
3137   TString macroStr;
3138   macroStr.Form("%s/EVE/macros/alieve_online.C",gSystem->ExpandPathName("$ALICE_ROOT"));
3139   AliInfo(Form("Loading AliEVE macro: %s",macroStr.Data()));
3140   if (gROOT->LoadMacro(macroStr.Data()) != 0) return kFALSE;
3141
3142   gROOT->ProcessLine("if (!AliEveEventManager::GetMaster()){new AliEveEventManager();AliEveEventManager::GetMaster()->AddNewEventCommand(\"alieve_online_on_new_event()\");gEve->AddEvent(AliEveEventManager::GetMaster());};");
3143   gROOT->ProcessLine("alieve_online_init()");
3144
3145   return kTRUE;
3146 }
3147   
3148 //_____________________________________________________________________________
3149 void AliReconstruction::RunAliEVE()
3150 {
3151   // Runs AliEVE visualisation of
3152   // the current event.
3153   // Should be executed only after
3154   // successful initialization of AliEVE.
3155
3156   AliInfo("Running AliEVE...");
3157   gROOT->ProcessLine(Form("AliEveEventManager::GetMaster()->SetEvent((AliRunLoader*)0x%lx,(AliRawReader*)0x%lx,(AliESDEvent*)0x%lx,(AliESDfriend*)0x%lx);",fRunLoader,fRawReader,fesd,fesdf));
3158   gSystem->Run();
3159 }
3160
3161 //_____________________________________________________________________________
3162 Bool_t AliReconstruction::SetRunQA(TString detAndAction) 
3163 {
3164         // Allows to run QA for a selected set of detectors
3165         // and a selected set of tasks among RAWS, DIGITSR, RECPOINTS and ESDS
3166         // all selected detectors run the same selected tasks
3167         
3168         if (!detAndAction.Contains(":")) {
3169                 AliError( Form("%s is a wrong syntax, use \"DetectorList:ActionList\" \n", detAndAction.Data()) ) ;
3170                 fRunQA = kFALSE ;
3171                 return kFALSE ;                 
3172         }
3173         Int_t colon = detAndAction.Index(":") ; 
3174         fQADetectors = detAndAction(0, colon) ; 
3175         if (fQADetectors.Contains("ALL") )
3176                 fQADetectors = fFillESD ; 
3177                 fQATasks   = detAndAction(colon+1, detAndAction.Sizeof() ) ; 
3178         if (fQATasks.Contains("ALL") ) {
3179                 fQATasks = Form("%d %d %d %d", AliQAv1::kRAWS, AliQAv1::kDIGITSR, AliQAv1::kRECPOINTS, AliQAv1::kESDS) ; 
3180         } else {
3181                 fQATasks.ToUpper() ; 
3182                 TString tempo("") ; 
3183                 if ( fQATasks.Contains("RAW") ) 
3184                         tempo = Form("%d ", AliQAv1::kRAWS) ; 
3185                 if ( fQATasks.Contains("DIGIT") ) 
3186                         tempo += Form("%d ", AliQAv1::kDIGITSR) ; 
3187                 if ( fQATasks.Contains("RECPOINT") ) 
3188                         tempo += Form("%d ", AliQAv1::kRECPOINTS) ; 
3189                 if ( fQATasks.Contains("ESD") ) 
3190                         tempo += Form("%d ", AliQAv1::kESDS) ; 
3191                 fQATasks = tempo ; 
3192                 if (fQATasks.IsNull()) {
3193                         AliInfo("No QA requested\n")  ;
3194                         fRunQA = kFALSE ;
3195                         return kTRUE ; 
3196                 }
3197         }       
3198         TString tempo(fQATasks) ; 
3199         tempo.ReplaceAll(Form("%d", AliQAv1::kRAWS), AliQAv1::GetTaskName(AliQAv1::kRAWS))      ;
3200         tempo.ReplaceAll(Form("%d", AliQAv1::kDIGITSR), AliQAv1::GetTaskName(AliQAv1::kDIGITSR)) ;      
3201         tempo.ReplaceAll(Form("%d", AliQAv1::kRECPOINTS), AliQAv1::GetTaskName(AliQAv1::kRECPOINTS)) ;  
3202         tempo.ReplaceAll(Form("%d", AliQAv1::kESDS), AliQAv1::GetTaskName(AliQAv1::kESDS)) ;    
3203         AliInfo( Form("QA will be done on \"%s\" for \"%s\"\n", fQADetectors.Data(), tempo.Data()) ) ;  
3204         fRunQA = kTRUE ;
3205         return kTRUE; 
3206
3207
3208 //_____________________________________________________________________________
3209 Bool_t AliReconstruction::InitRecoParams() 
3210 {
3211   // The method accesses OCDB and retrieves all
3212   // the available reco-param objects from there.
3213
3214   Bool_t isOK = kTRUE;
3215
3216   TString detStr = fLoadCDB;
3217   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3218
3219     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3220
3221     if (fRecoParam.GetDetRecoParamArray(iDet)) {
3222       AliInfo(Form("Using custom reconstruction parameters for detector %s",fgkDetectorName[iDet]));
3223       continue;
3224     }
3225
3226     AliInfo(Form("Loading reconstruction parameter objects for detector %s",fgkDetectorName[iDet]));
3227   
3228     AliCDBPath path(fgkDetectorName[iDet],"Calib","RecoParam");
3229     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
3230     if(!entry){ 
3231       AliWarning(Form("Couldn't find RecoParam entry in OCDB for detector %s",fgkDetectorName[iDet]));
3232       isOK = kFALSE;
3233     }
3234     else {
3235       TObject *recoParamObj = entry->GetObject();
3236       if (dynamic_cast<TObjArray*>(recoParamObj)) {
3237         // The detector has a normal TobjArray of AliDetectorRecoParam objects
3238         // Registering them in AliRecoParam
3239         fRecoParam.AddDetRecoParamArray(iDet,dynamic_cast<TObjArray*>(recoParamObj));
3240       }
3241       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
3242         // The detector has only onse set of reco parameters
3243         // Registering it in AliRecoParam
3244         AliInfo(Form("Single set of reconstruction parameters found for detector %s",fgkDetectorName[iDet]));
3245         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
3246         fRecoParam.AddDetRecoParam(iDet,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
3247       }
3248       else {
3249         AliError(Form("No valid RecoParam object found in the OCDB for detector %s",fgkDetectorName[iDet]));
3250         isOK = kFALSE;
3251       }
3252       entry->SetOwner(0);
3253       //      FIX ME: We have to disable the unloading of reco-param CDB
3254       //      entries because QA framework is using them. Has to be fix in
3255       //      a way that the QA takes the objects already constructed in
3256       //      this method.
3257       //      AliCDBManager::Instance()->UnloadFromCache(path.GetPath());
3258     }
3259   }
3260
3261   if (AliDebugLevel() > 0) fRecoParam.Print();
3262
3263   return isOK;
3264 }
3265
3266 //_____________________________________________________________________________
3267 Bool_t AliReconstruction::GetEventInfo() 
3268 {
3269   // Fill the event info object
3270   // ...
3271   AliCodeTimerAuto("")
3272
3273   AliCentralTrigger *aCTP = NULL;
3274   if (fRawReader) {
3275     fEventInfo.SetEventType(fRawReader->GetType());
3276
3277     ULong64_t mask = fRawReader->GetClassMask();
3278     fEventInfo.SetTriggerMask(mask);
3279     UInt_t clmask = fRawReader->GetDetectorPattern()[0];
3280     fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(clmask));
3281
3282     aCTP = new AliCentralTrigger();
3283     TString configstr("");
3284     if (!aCTP->LoadConfiguration(configstr)) { // Load CTP config from OCDB
3285       AliError("No trigger configuration found in OCDB! The trigger configuration information will not be used!");
3286       delete aCTP;
3287       return kFALSE;
3288     }
3289     aCTP->SetClassMask(mask);
3290     aCTP->SetClusterMask(clmask);
3291   }
3292   else {
3293     fEventInfo.SetEventType(AliRawEventHeaderBase::kPhysicsEvent);
3294
3295     if (fRunLoader && (!fRunLoader->LoadTrigger())) {
3296       aCTP = fRunLoader->GetTrigger();
3297       fEventInfo.SetTriggerMask(aCTP->GetClassMask());
3298       // get inputs from actp - just get
3299       AliESDHeader* esdheader = fesd->GetHeader();
3300       esdheader->SetL0TriggerInputs(aCTP->GetL0TriggerInputs());
3301       esdheader->SetL1TriggerInputs(aCTP->GetL1TriggerInputs());
3302       esdheader->SetL2TriggerInputs(aCTP->GetL2TriggerInputs());
3303       fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(aCTP->GetClusterMask()));
3304     }
3305     else {
3306       AliWarning("No trigger can be loaded! The trigger information will not be used!");
3307       return kFALSE;
3308     }
3309   }
3310
3311   AliTriggerConfiguration *config = aCTP->GetConfiguration();
3312   if (!config) {
3313     AliError("No trigger configuration has been found! The trigger configuration information will not be used!");
3314     if (fRawReader) delete aCTP;
3315     return kFALSE;
3316   }
3317
3318   UChar_t clustmask = 0;
3319   TString trclasses;
3320   ULong64_t trmask = fEventInfo.GetTriggerMask();
3321   const TObjArray& classesArray = config->GetClasses();
3322   Int_t nclasses = classesArray.GetEntriesFast();
3323   for( Int_t iclass=0; iclass < nclasses; iclass++ ) {
3324     AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At(iclass);
3325     if (trclass) {
3326       Int_t trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
3327       fesd->SetTriggerClass(trclass->GetName(),trindex);
3328       if (fRawReader) fRawReader->LoadTriggerClass(trclass->GetName(),trindex);
3329       if (trmask & (1ull << trindex)) {
3330         trclasses += " ";
3331         trclasses += trclass->GetName();
3332         trclasses += " ";
3333         clustmask |= trclass->GetCluster()->GetClusterMask();
3334       }
3335     }
3336   }
3337   fEventInfo.SetTriggerClasses(trclasses);
3338
3339   // Set the information in ESD
3340   fesd->SetTriggerMask(trmask);
3341   fesd->SetTriggerCluster(clustmask);
3342
3343   if (!aCTP->CheckTriggeredDetectors()) {
3344     if (fRawReader) delete aCTP;
3345     return kFALSE;
3346   }    
3347
3348   if (fRawReader) delete aCTP;
3349
3350   // We have to fill also the HLT decision here!!
3351   // ...
3352
3353   return kTRUE;
3354 }
3355
3356 const char *AliReconstruction::MatchDetectorList(const char *detectorList, UInt_t detectorMask)
3357 {
3358   // Match the detector list found in the rec.C or the default 'ALL'
3359   // to the list found in the GRP (stored there by the shuttle PP which
3360   // gets the information from ECS)
3361   static TString resultList;
3362   TString detList = detectorList;
3363
3364   resultList = "";
3365
3366   for(Int_t iDet = 0; iDet < (AliDAQ::kNDetectors-1); iDet++) {
3367     if ((detectorMask >> iDet) & 0x1) {
3368       TString det = AliDAQ::OfflineModuleName(iDet);
3369       if ((detList.CompareTo("ALL") == 0) ||
3370           ((detList.BeginsWith("ALL ") ||
3371             detList.EndsWith(" ALL") ||
3372             detList.Contains(" ALL ")) &&
3373            !(detList.BeginsWith("-"+det+" ") ||
3374              detList.EndsWith(" -"+det) ||
3375              detList.Contains(" -"+det+" "))) ||
3376           (detList.CompareTo(det) == 0) ||
3377           detList.BeginsWith(det+" ") ||
3378           detList.EndsWith(" "+det) ||
3379           detList.Contains( " "+det+" " )) {
3380         if (!resultList.EndsWith(det + " ")) {
3381           resultList += det;
3382           resultList += " ";
3383         }
3384       }        
3385     }
3386   }
3387
3388   // HLT
3389   if ((detectorMask >> AliDAQ::kHLTId) & 0x1) {
3390     TString hltDet = AliDAQ::OfflineModuleName(AliDAQ::kNDetectors-1);
3391     if ((detList.CompareTo("ALL") == 0) ||
3392         ((detList.BeginsWith("ALL ") ||
3393           detList.EndsWith(" ALL") ||
3394           detList.Contains(" ALL ")) &&
3395          !(detList.BeginsWith("-"+hltDet+" ") ||
3396            detList.EndsWith(" -"+hltDet) ||
3397            detList.Contains(" -"+hltDet+" "))) ||
3398         (detList.CompareTo(hltDet) == 0) ||
3399         detList.BeginsWith(hltDet+" ") ||
3400         detList.EndsWith(" "+hltDet) ||
3401         detList.Contains( " "+hltDet+" " )) {
3402       resultList += hltDet;
3403     }
3404   }
3405
3406   return resultList.Data();
3407
3408 }
3409
3410 //______________________________________________________________________________
3411 void AliReconstruction::Abort(const char *method, EAbort what)
3412 {
3413   // Abort processing. If what = kAbortProcess, the Process() loop will be
3414   // aborted. If what = kAbortFile, the current file in a chain will be
3415   // aborted and the processing will continue with the next file, if there
3416   // is no next file then Process() will be aborted. Abort() can also  be
3417   // called from Begin(), SlaveBegin(), Init() and Notify(). After abort
3418   // the SlaveTerminate() and Terminate() are always called. The abort flag
3419   // can be checked in these methods using GetAbort().
3420   //
3421   // The method is overwritten in AliReconstruction for better handling of
3422   // reco specific errors 
3423
3424   if (!fStopOnError) return;
3425
3426   CleanUp();
3427
3428   TString whyMess = method;
3429   whyMess += " failed! Aborting...";
3430
3431   AliError(whyMess.Data());
3432
3433   fAbort = what;
3434   TString mess = "Abort";
3435   if (fAbort == kAbortProcess)
3436     mess = "AbortProcess";
3437   else if (fAbort == kAbortFile)
3438     mess = "AbortFile";
3439
3440   Info(mess, whyMess.Data());
3441 }
3442