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