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