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