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