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