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