]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliReconstruction.cxx
calibration for coming collisions
[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) {
1666           CleanUp(); 
1667           return kFALSE;
1668         }
1669       }
1670     }
1671
1672     fesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
1673     fhltesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
1674     fesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
1675     fhltesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
1676
1677     fesd->SetEventSpecie(fRecoParam.GetEventSpecie());
1678     fhltesd->SetEventSpecie(fRecoParam.GetEventSpecie());
1679     
1680     // Set magnetic field from the tracker
1681     fesd->SetMagneticField(AliTracker::GetBz());
1682     fhltesd->SetMagneticField(AliTracker::GetBz());
1683     //
1684     AliMagF* fld = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
1685     if (fld) { // set info needed for field initialization
1686       fesd->SetCurrentL3(fld->GetCurrentSol());
1687       fesd->SetCurrentDip(fld->GetCurrentDip());
1688       fesd->SetBeamEnergy(fld->GetBeamEnergy());
1689       fesd->SetBeamType(fld->GetBeamTypeText());
1690       fesd->SetUniformBMap(fld->IsUniform());
1691       fesd->SetBInfoStored();
1692       //
1693       fhltesd->SetCurrentL3(fld->GetCurrentSol());
1694       fhltesd->SetCurrentDip(fld->GetCurrentDip());
1695       fhltesd->SetBeamEnergy(fld->GetBeamEnergy());
1696       fhltesd->SetBeamType(fld->GetBeamTypeText());
1697       fhltesd->SetUniformBMap(fld->IsUniform());
1698       fhltesd->SetBInfoStored();
1699     }
1700     //
1701     // Set most probable pt, for B=0 tracking
1702     // Get the global reco-params. They are atposition 16 inside the array of detectors in fRecoParam
1703     const AliGRPRecoParam *grpRecoParam = dynamic_cast<const AliGRPRecoParam*>(fRecoParam.GetDetRecoParam(kNDetectors));
1704     if (grpRecoParam) AliExternalTrackParam::SetMostProbablePt(grpRecoParam->GetMostProbablePt());
1705     
1706     // Fill raw-data error log into the ESD
1707     if (fRawReader) FillRawDataErrorLog(iEvent,fesd);
1708
1709     // vertex finder
1710     if (fRunVertexFinder) {
1711       if (!RunVertexFinder(fesd)) {
1712         if (fStopOnError) {CleanUp(); return kFALSE;}
1713       }
1714     }
1715
1716     // For Plane Efficiency: run the SPD trackleter
1717     if (fRunPlaneEff && fSPDTrackleter) {
1718       if (!RunSPDTrackleting(fesd)) {
1719         if (fStopOnError) {CleanUp(); return kFALSE;}
1720       }
1721     }
1722
1723     // Muon tracking
1724     if (!fRunTracking.IsNull()) {
1725       if (fRunMuonTracking) {
1726         if (!RunMuonTracking(fesd)) {
1727           if (fStopOnError) {CleanUp(); return kFALSE;}
1728         }
1729       }
1730     }
1731
1732     // barrel tracking
1733     if (!fRunTracking.IsNull()) {
1734       if (!RunTracking(fesd)) {
1735         if (fStopOnError) {CleanUp(); return kFALSE;}
1736       }
1737     }
1738
1739     // fill ESD
1740     if (!fFillESD.IsNull()) {
1741       TString detectors=fFillESD;
1742       // run HLT first and on hltesd
1743       // ;-( IsSelected changes the string
1744       if (IsSelected("HLT", detectors) &&
1745           !FillESD(fhltesd, "HLT")) {
1746         if (fStopOnError) {CleanUp(); return kFALSE;}
1747       }
1748       detectors=fFillESD;
1749       // Temporary fix to avoid problems with HLT that overwrites the offline ESDs
1750       if (detectors.Contains("ALL")) {
1751         detectors="";
1752         for (Int_t idet=0; idet<kNDetectors; ++idet){
1753           detectors += fgkDetectorName[idet];
1754           detectors += " ";
1755         }
1756       }
1757       detectors.ReplaceAll("HLT", "");
1758       if (!FillESD(fesd, detectors)) {
1759         if (fStopOnError) {CleanUp(); return kFALSE;}
1760       }
1761     }
1762   
1763     // fill Event header information from the RawEventHeader
1764     if (fRawReader){FillRawEventHeaderESD(fesd);}
1765     if (fRawReader){FillRawEventHeaderESD(fhltesd);}
1766
1767     // combined PID
1768     AliESDpid::MakePID(fesd);
1769
1770     if (fFillTriggerESD) {
1771       if (!FillTriggerESD(fesd)) {
1772         if (fStopOnError) {CleanUp(); return kFALSE;}
1773       }
1774     }
1775     // Always fill scalers
1776     if (!FillTriggerScalers(fesd)) {
1777        if (fStopOnError) {CleanUp(); return kFALSE;}
1778     }
1779     
1780
1781     ffile->cd();
1782
1783     //
1784     // Propagate track to the beam pipe  (if not already done by ITS)
1785     //
1786     const Int_t ntracks = fesd->GetNumberOfTracks();
1787     const Double_t kRadius  = 2.8; //something less than the beam pipe radius
1788
1789     TObjArray trkArray;
1790     UShort_t *selectedIdx=new UShort_t[ntracks];
1791
1792     for (Int_t itrack=0; itrack<ntracks; itrack++){
1793       const Double_t kMaxStep = 1;   //max step over the material
1794       Bool_t ok;
1795
1796       AliESDtrack *track = fesd->GetTrack(itrack);
1797       if (!track) continue;
1798
1799       AliExternalTrackParam *tpcTrack =
1800            (AliExternalTrackParam *)track->GetTPCInnerParam();
1801       ok = kFALSE;
1802       if (tpcTrack)
1803         ok = AliTracker::
1804           PropagateTrackToBxByBz(tpcTrack,kRadius,track->GetMass(),kMaxStep,kFALSE);
1805
1806       if (ok) {
1807         Int_t n=trkArray.GetEntriesFast();
1808         selectedIdx[n]=track->GetID();
1809         trkArray.AddLast(tpcTrack);
1810       }
1811
1812       //Tracks refitted by ITS should already be at the SPD vertex
1813       if (track->IsOn(AliESDtrack::kITSrefit)) continue;
1814
1815       AliTracker::
1816          PropagateTrackToBxByBz(track,kRadius,track->GetMass(),kMaxStep,kFALSE);
1817       Double_t x[3]; track->GetXYZ(x);
1818       Double_t b[3]; AliTracker::GetBxByBz(x,b);
1819       track->RelateToVertexBxByBz(fesd->GetPrimaryVertexSPD(), b, kVeryBig);
1820
1821     }
1822
1823     //
1824     // Improve the reconstructed primary vertex position using the tracks
1825     //
1826     Bool_t runVertexFinderTracks = fRunVertexFinderTracks;
1827     if(fesd->GetPrimaryVertexSPD()) {
1828       TString vtitle = fesd->GetPrimaryVertexSPD()->GetTitle();
1829       if(vtitle.Contains("cosmics")) {
1830         runVertexFinderTracks=kFALSE;
1831       }
1832     }
1833
1834     if (runVertexFinderTracks) {
1835        // TPC + ITS primary vertex
1836        ftVertexer->SetITSMode();
1837        ftVertexer->SetConstraintOff();
1838        // get cuts for vertexer from AliGRPRecoParam
1839        if (grpRecoParam) {
1840          Int_t nCutsVertexer = grpRecoParam->GetVertexerTracksNCuts();
1841          Double_t *cutsVertexer = new Double_t[nCutsVertexer];
1842          grpRecoParam->GetVertexerTracksCutsITS(cutsVertexer);
1843          ftVertexer->SetCuts(cutsVertexer);
1844          delete [] cutsVertexer; cutsVertexer = NULL; 
1845          if(fDiamondProfile && grpRecoParam->GetVertexerTracksConstraintITS())
1846            ftVertexer->SetVtxStart(fDiamondProfile);
1847        }
1848        AliESDVertex *pvtx=ftVertexer->FindPrimaryVertex(fesd);
1849        if (pvtx) {
1850           if (pvtx->GetStatus()) {
1851              fesd->SetPrimaryVertexTracks(pvtx);
1852              for (Int_t i=0; i<ntracks; i++) {
1853                  AliESDtrack *t = fesd->GetTrack(i);
1854                  Double_t x[3]; t->GetXYZ(x);
1855                  Double_t b[3]; AliTracker::GetBxByBz(x,b);
1856                  t->RelateToVertexBxByBz(pvtx, b, kVeryBig);
1857              } 
1858           }
1859           delete pvtx; pvtx=NULL;
1860        }
1861
1862        // TPC-only primary vertex
1863        ftVertexer->SetTPCMode();
1864        ftVertexer->SetConstraintOff();
1865        // get cuts for vertexer from AliGRPRecoParam
1866        if (grpRecoParam) {
1867          Int_t nCutsVertexer = grpRecoParam->GetVertexerTracksNCuts();
1868          Double_t *cutsVertexer = new Double_t[nCutsVertexer];
1869          grpRecoParam->GetVertexerTracksCutsTPC(cutsVertexer);
1870          ftVertexer->SetCuts(cutsVertexer);
1871          delete [] cutsVertexer; cutsVertexer = NULL; 
1872          if(fDiamondProfileTPC && grpRecoParam->GetVertexerTracksConstraintTPC())
1873            ftVertexer->SetVtxStart(fDiamondProfileTPC);
1874        }
1875        pvtx=ftVertexer->FindPrimaryVertex(&trkArray,selectedIdx);
1876        if (pvtx) {
1877           if (pvtx->GetStatus()) {
1878              fesd->SetPrimaryVertexTPC(pvtx);
1879              for (Int_t i=0; i<ntracks; i++) {
1880                  AliESDtrack *t = fesd->GetTrack(i);
1881                  Double_t x[3]; t->GetXYZ(x);
1882                  Double_t b[3]; AliTracker::GetBxByBz(x,b);
1883                  t->RelateToVertexTPCBxByBz(pvtx, b, kVeryBig);
1884              } 
1885           }
1886           delete pvtx; pvtx=NULL;
1887        }
1888
1889     }
1890     delete[] selectedIdx;
1891
1892     if(fDiamondProfile) fesd->SetDiamond(fDiamondProfile);
1893     
1894
1895     if (fRunV0Finder) {
1896        // V0 finding
1897        AliV0vertexer vtxer;
1898        vtxer.Tracks2V0vertices(fesd);
1899
1900        if (fRunCascadeFinder) {
1901           // Cascade finding
1902           AliCascadeVertexer cvtxer;
1903           cvtxer.V0sTracks2CascadeVertices(fesd);
1904        }
1905     }
1906  
1907     // write ESD
1908     if (fCleanESD) CleanESD(fesd);
1909
1910   if (fRunQA && IsInTasks(AliQAv1::kESDS)) {
1911     AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
1912     AliQAManager::QAManager()->RunOneEvent(fesd, fhltesd) ; 
1913   }
1914   if (fRunGlobalQA) {
1915     AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
1916       qadm->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
1917     if (qadm && IsInTasks(AliQAv1::kESDS))
1918       qadm->Exec(AliQAv1::kESDS, fesd);
1919   }
1920
1921     if (fWriteESDfriend) {
1922       //      fesdf->~AliESDfriend();
1923       //  new (fesdf) AliESDfriend(); // Reset...
1924       fesd->GetESDfriend(fesdf);
1925     }
1926     ftree->Fill();
1927
1928     // Auto-save the ESD tree in case of prompt reco @P2
1929     if (fRawReader && fRawReader->UseAutoSaveESD()) {
1930       ftree->AutoSave("SaveSelf");
1931       TFile *friendfile = (TFile *)(gROOT->GetListOfFiles()->FindObject("AliESDfriends.root"));
1932       if (friendfile) friendfile->Save();
1933     }
1934
1935     // write HLT ESD
1936     fhlttree->Fill();
1937
1938     // call AliEVE
1939     if (fRunAliEVE) RunAliEVE();
1940
1941     fesd->Reset();
1942     fhltesd->Reset();
1943     if (fWriteESDfriend) {
1944       fesdf->~AliESDfriend();
1945       new (fesdf) AliESDfriend(); // Reset...
1946     }
1947  
1948     ProcInfo_t procInfo;
1949     gSystem->GetProcInfo(&procInfo);
1950     AliInfo(Form("Event %d -> Current memory usage %d %d",iEvent, procInfo.fMemResident, procInfo.fMemVirtual));
1951   
1952     fEventInfo.Reset();
1953     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1954       if (fReconstructor[iDet]) {
1955         fReconstructor[iDet]->SetRecoParam(NULL);
1956         fReconstructor[iDet]->SetEventInfo(NULL);
1957       }
1958       if (fTracker[iDet]) fTracker[iDet]->SetEventInfo(NULL);
1959     }
1960         
1961   if (fRunQA || fRunGlobalQA) 
1962     AliQAManager::QAManager()->Increment() ; 
1963   
1964     return kTRUE;
1965 }
1966
1967 //_____________________________________________________________________________
1968 void AliReconstruction::SlaveTerminate()
1969 {
1970   // Finalize the run on the slave side
1971   // Called after the exit
1972   // from the event loop
1973   AliCodeTimerAuto("",0);
1974
1975   if (fIsNewRunLoader) { // galice.root didn't exist
1976     fRunLoader->WriteHeader("OVERWRITE");
1977     fRunLoader->CdGAFile();
1978     fRunLoader->Write(0, TObject::kOverwrite);
1979   }
1980
1981   const TMap *cdbMap = AliCDBManager::Instance()->GetStorageMap();       
1982   const TList *cdbList = AliCDBManager::Instance()->GetRetrievedIds();   
1983                  
1984    TMap *cdbMapCopy = new TMap(cdbMap->GetEntries());    
1985    cdbMapCopy->SetOwner(1);      
1986    cdbMapCopy->SetName("cdbMap");        
1987    TIter iter(cdbMap->GetTable());       
1988          
1989    TPair* pair = 0;      
1990    while((pair = dynamic_cast<TPair*> (iter.Next()))){   
1991          TObjString* keyStr = dynamic_cast<TObjString*> (pair->Key());   
1992          TObjString* valStr = dynamic_cast<TObjString*> (pair->Value());         
1993          cdbMapCopy->Add(new TObjString(keyStr->GetName()), new TObjString(valStr->GetName()));  
1994    }     
1995          
1996    TList *cdbListCopy = new TList();     
1997    cdbListCopy->SetOwner(1);     
1998    cdbListCopy->SetName("cdbList");      
1999          
2000    TIter iter2(cdbList);         
2001          
2002         AliCDBId* id=0;
2003         while((id = dynamic_cast<AliCDBId*> (iter2.Next()))){    
2004          cdbListCopy->Add(new TObjString(id->ToString().Data()));        
2005    }     
2006          
2007    ftree->GetUserInfo()->Add(cdbMapCopy);        
2008    ftree->GetUserInfo()->Add(cdbListCopy);
2009
2010
2011   ffile->cd();
2012
2013   if (fWriteESDfriend)
2014     ftree->SetBranchStatus("ESDfriend*",0);
2015   // we want to have only one tree version number
2016   ftree->Write(ftree->GetName(),TObject::kOverwrite);
2017   fhlttree->Write(fhlttree->GetName(),TObject::kOverwrite);
2018
2019 // Finish with Plane Efficiency evaluation: before of CleanUp !!!
2020   if (fRunPlaneEff && !FinishPlaneEff()) {
2021    AliWarning("Finish PlaneEff evaluation failed");
2022   }
2023
2024   // End of cycle for the in-loop  
2025
2026   if (fRunQA || fRunGlobalQA) {
2027     AliQAManager::QAManager()->EndOfCycle() ;
2028     if (fInput &&
2029         !fProofOutputLocation.IsNull() &&
2030         fProofOutputArchive.IsNull() &&
2031         !fProofOutputDataset) {
2032       TString qaOutputFile(Form("%sMerged.%s.Data.root",
2033                                 fProofOutputLocation.Data(),
2034                                 AliQAv1::GetQADataFileName()));
2035       TProofOutputFile *qaProofFile = new TProofOutputFile(Form("Merged.%s.Data.root",
2036                                                                 AliQAv1::GetQADataFileName()));
2037       qaProofFile->SetOutputFileName(qaOutputFile.Data());
2038       if (AliDebugLevel() > 0) qaProofFile->Dump();
2039       fOutput->Add(qaProofFile);
2040       MergeQA(qaProofFile->GetFileName());
2041     }
2042     else {
2043       MergeQA();
2044     }
2045   }
2046
2047   gROOT->cd();
2048   CleanUp();
2049
2050   if (fInput) {
2051     if (!fProofOutputFileName.IsNull() &&
2052         !fProofOutputLocation.IsNull() &&
2053         fProofOutputDataset &&
2054         !fProofOutputArchive.IsNull()) {
2055       TProofOutputFile *zipProofFile = new TProofOutputFile(fProofOutputFileName.Data(),
2056                                                             "DROV",
2057                                                             fProofOutputLocation.Data());
2058       if (AliDebugLevel() > 0) zipProofFile->Dump();
2059       fOutput->Add(zipProofFile);
2060       TString fileList(fProofOutputArchive.Data());
2061       fileList.ReplaceAll(","," ");
2062       TString command;
2063 #if ROOT_SVN_REVISION >= 30174
2064       command.Form("zip -n root %s/%s %s",zipProofFile->GetDir(kTRUE),zipProofFile->GetFileName(),fileList.Data());
2065 #else
2066       command.Form("zip -n root %s/%s %s",zipProofFile->GetDir(),zipProofFile->GetFileName(),fileList.Data());
2067 #endif
2068       AliInfo(Form("Executing: %s",command.Data()));
2069       gSystem->Exec(command.Data());
2070     }
2071   }
2072 }
2073     
2074 //_____________________________________________________________________________
2075 void AliReconstruction::Terminate()
2076 {
2077   // Create tags for the events in the ESD tree (the ESD tree is always present)
2078   // In case of empty events the tags will contain dummy values
2079   AliCodeTimerAuto("",0);
2080
2081   // Do not call the ESD tag creator in case of PROOF-based reconstruction
2082   if (!fInput) {
2083     AliESDTagCreator *esdtagCreator = new AliESDTagCreator();
2084     esdtagCreator->CreateESDTags(fFirstEvent,fLastEvent,fGRPData, AliQAv1::Instance()->GetQA(), AliQAv1::Instance()->GetEventSpecies(), AliQAv1::kNDET, AliRecoParam::kNSpecies);
2085     delete esdtagCreator;
2086   }
2087
2088   // Cleanup of CDB manager: cache and active storages!
2089   AliCDBManager::Instance()->ClearCache();
2090 }
2091
2092 //_____________________________________________________________________________
2093 Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
2094 {
2095 // run the local reconstruction
2096
2097   static Int_t eventNr=0;
2098   AliCodeTimerAuto("",0)
2099
2100   TString detStr = detectors;
2101   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2102     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2103     AliReconstructor* reconstructor = GetReconstructor(iDet);
2104     if (!reconstructor) continue;
2105     AliLoader* loader = fLoader[iDet];
2106     // Matthias April 2008: temporary fix to run HLT reconstruction
2107     // although the HLT loader is missing
2108     if (strcmp(fgkDetectorName[iDet], "HLT")==0) {
2109       if (fRawReader) {
2110         reconstructor->Reconstruct(fRawReader, NULL);
2111       } else {
2112         TTree* dummy=NULL;
2113         reconstructor->Reconstruct(dummy, NULL);
2114       }
2115       continue;
2116     }
2117     if (!loader) {
2118       AliWarning(Form("No loader is defined for %s!",fgkDetectorName[iDet]));
2119       continue;
2120     }
2121     // conversion of digits
2122     if (fRawReader && reconstructor->HasDigitConversion()) {
2123       AliInfo(Form("converting raw data digits into root objects for %s", 
2124                    fgkDetectorName[iDet]));
2125 //      AliCodeTimerAuto(Form("converting raw data digits into root objects for %s", 
2126 //                            fgkDetectorName[iDet]),0);
2127       loader->LoadDigits("update");
2128       loader->CleanDigits();
2129       loader->MakeDigitsContainer();
2130       TTree* digitsTree = loader->TreeD();
2131       reconstructor->ConvertDigits(fRawReader, digitsTree);
2132       loader->WriteDigits("OVERWRITE");
2133       loader->UnloadDigits();
2134     }
2135     // local reconstruction
2136     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
2137     //AliCodeTimerAuto(Form("running reconstruction for %s", fgkDetectorName[iDet]),0);
2138     loader->LoadRecPoints("update");
2139     loader->CleanRecPoints();
2140     loader->MakeRecPointsContainer();
2141     TTree* clustersTree = loader->TreeR();
2142     if (fRawReader && !reconstructor->HasDigitConversion()) {
2143       reconstructor->Reconstruct(fRawReader, clustersTree);
2144     } else {
2145       loader->LoadDigits("read");
2146       TTree* digitsTree = loader->TreeD();
2147       if (!digitsTree) {
2148         AliError(Form("Can't get the %s digits tree", fgkDetectorName[iDet]));
2149         if (fStopOnError) 
2150           return kFALSE;
2151       } else {
2152         reconstructor->Reconstruct(digitsTree, clustersTree);
2153         if (fRunQA && IsInTasks(AliQAv1::kDIGITSR)) {
2154           AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2155           AliQAManager::QAManager()->RunOneEventInOneDetector(iDet, digitsTree) ; 
2156         }
2157       }
2158       loader->UnloadDigits();
2159     }
2160                 if (fRunQA && IsInTasks(AliQAv1::kRECPOINTS)) {
2161       AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2162                         AliQAManager::QAManager()->RunOneEventInOneDetector(iDet, clustersTree) ; 
2163     }
2164     loader->WriteRecPoints("OVERWRITE");
2165     loader->UnloadRecPoints();
2166     AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr), iDet,1,eventNr);
2167   }
2168   IsSelected("CTP", detStr);
2169   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2170     AliError(Form("the following detectors were not found: %s",
2171                   detStr.Data()));
2172     if (fStopOnError) 
2173       return kFALSE;
2174   }
2175   eventNr++;
2176   return kTRUE;
2177 }
2178 //_____________________________________________________________________________
2179 Bool_t AliReconstruction::RunSPDTrackleting(AliESDEvent*& esd)
2180 {
2181 // run the SPD trackleting (for SPD efficiency purpouses)
2182
2183   AliCodeTimerAuto("",0)
2184
2185   Double_t vtxPos[3] = {0, 0, 0};
2186   Double_t vtxErr[3] = {0.0, 0.0, 0.0};
2187 /*
2188   TArrayF mcVertex(3);
2189   // if(MC)
2190   if (fRunLoader->GetHeader() && fRunLoader->GetHeader()->GenEventHeader()) {
2191     fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(mcVertex);
2192     for (Int_t i = 0; i < 3; i++) vtxPos[i] = mcVertex[i];
2193   }
2194 */
2195   const AliESDVertex *vertex = esd->GetVertex();
2196   if(!vertex){
2197     AliWarning("Vertex not found");
2198     return kFALSE;
2199   }
2200   vertex->GetXYZ(vtxPos);
2201   vertex->GetSigmaXYZ(vtxErr);
2202   if (fSPDTrackleter) {
2203     AliInfo("running the SPD Trackleter for Plane Efficiency Evaluation");
2204
2205     // load clusters
2206     fLoader[0]->LoadRecPoints("read");
2207     TTree* tree = fLoader[0]->TreeR();
2208     if (!tree) {
2209       AliError("Can't get the ITS cluster tree");
2210       return kFALSE;
2211     }
2212     fSPDTrackleter->LoadClusters(tree);
2213     fSPDTrackleter->SetVertex(vtxPos, vtxErr);
2214     // run trackleting
2215     if (fSPDTrackleter->Clusters2Tracks(esd) != 0) {
2216       AliError("AliITSTrackleterSPDEff Clusters2Tracks failed");
2217      // fLoader[0]->UnloadRecPoints();
2218       return kFALSE;
2219     }
2220 //fSPDTrackleter->UnloadRecPoints();
2221   } else {
2222     AliWarning("SPDTrackleter not available");
2223     return kFALSE;
2224   }
2225   return kTRUE;
2226 }
2227
2228 //_____________________________________________________________________________
2229 Bool_t AliReconstruction::RunVertexFinder(AliESDEvent*& esd)
2230 {
2231 // run the barrel tracking
2232
2233   AliCodeTimerAuto("",0)
2234
2235   AliVertexer *vertexer = CreateVertexer();
2236   if (!vertexer) return kFALSE;
2237
2238   AliInfo("running the ITS vertex finder");
2239   AliESDVertex* vertex = NULL;
2240   if (fLoader[0]) {
2241     fLoader[0]->LoadRecPoints();
2242     TTree* cltree = fLoader[0]->TreeR();
2243     if (cltree) {
2244       if(fDiamondProfileSPD) vertexer->SetVtxStart(fDiamondProfileSPD);
2245       vertex = vertexer->FindVertexForCurrentEvent(cltree);
2246     }
2247     else {
2248       AliError("Can't get the ITS cluster tree");
2249     }
2250     fLoader[0]->UnloadRecPoints();
2251   }
2252   else {
2253     AliError("Can't get the ITS loader");
2254   }
2255   if(!vertex){
2256     AliWarning("Vertex not found");
2257     vertex = new AliESDVertex();
2258     vertex->SetName("default");
2259   }
2260   else {
2261     vertex->SetName("reconstructed");
2262   }
2263
2264   Double_t vtxPos[3];
2265   Double_t vtxErr[3];
2266   vertex->GetXYZ(vtxPos);
2267   vertex->GetSigmaXYZ(vtxErr);
2268
2269   esd->SetPrimaryVertexSPD(vertex);
2270   AliESDVertex *vpileup = NULL;
2271   Int_t novertices = 0;
2272   vpileup = vertexer->GetAllVertices(novertices);
2273   if(novertices>1){
2274     for (Int_t kk=1; kk<novertices; kk++)esd->AddPileupVertexSPD(&vpileup[kk]);
2275   }
2276   // if SPD multiplicity has been determined, it is stored in the ESD
2277   AliMultiplicity *mult = vertexer->GetMultiplicity();
2278   if(mult)esd->SetMultiplicity(mult);
2279
2280   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2281     if (fTracker[iDet]) fTracker[iDet]->SetVertex(vtxPos, vtxErr);
2282   }  
2283   delete vertex;
2284
2285   delete vertexer;
2286
2287   return kTRUE;
2288 }
2289
2290 //_____________________________________________________________________________
2291 Bool_t AliReconstruction::RunHLTTracking(AliESDEvent*& esd)
2292 {
2293 // run the HLT barrel tracking
2294
2295   AliCodeTimerAuto("",0)
2296
2297   if (!fRunLoader) {
2298     AliError("Missing runLoader!");
2299     return kFALSE;
2300   }
2301
2302   AliInfo("running HLT tracking");
2303
2304   // Get a pointer to the HLT reconstructor
2305   AliReconstructor *reconstructor = GetReconstructor(kNDetectors-1);
2306   if (!reconstructor) return kFALSE;
2307
2308   // TPC + ITS
2309   for (Int_t iDet = 1; iDet >= 0; iDet--) {
2310     TString detName = fgkDetectorName[iDet];
2311     AliDebug(1, Form("%s HLT tracking", detName.Data()));
2312     reconstructor->SetOption(detName.Data());
2313     AliTracker *tracker = reconstructor->CreateTracker();
2314     if (!tracker) {
2315       AliWarning(Form("couldn't create a HLT tracker for %s", detName.Data()));
2316       if (fStopOnError) return kFALSE;
2317       continue;
2318     }
2319     Double_t vtxPos[3];
2320     Double_t vtxErr[3]={0.005,0.005,0.010};
2321     const AliESDVertex *vertex = esd->GetVertex();
2322     vertex->GetXYZ(vtxPos);
2323     tracker->SetVertex(vtxPos,vtxErr);
2324     if(iDet != 1) {
2325       fLoader[iDet]->LoadRecPoints("read");
2326       TTree* tree = fLoader[iDet]->TreeR();
2327       if (!tree) {
2328         AliError(Form("Can't get the %s cluster tree", detName.Data()));
2329         return kFALSE;
2330       }
2331       tracker->LoadClusters(tree);
2332     }
2333     if (tracker->Clusters2Tracks(esd) != 0) {
2334       AliError(Form("HLT %s Clusters2Tracks failed", fgkDetectorName[iDet]));
2335       return kFALSE;
2336     }
2337     if(iDet != 1) {
2338       tracker->UnloadClusters();
2339     }
2340     delete tracker;
2341   }
2342
2343   return kTRUE;
2344 }
2345
2346 //_____________________________________________________________________________
2347 Bool_t AliReconstruction::RunMuonTracking(AliESDEvent*& esd)
2348 {
2349 // run the muon spectrometer tracking
2350
2351   AliCodeTimerAuto("",0)
2352
2353   if (!fRunLoader) {
2354     AliError("Missing runLoader!");
2355     return kFALSE;
2356   }
2357   Int_t iDet = 7; // for MUON
2358
2359   AliInfo("is running...");
2360
2361   // Get a pointer to the MUON reconstructor
2362   AliReconstructor *reconstructor = GetReconstructor(iDet);
2363   if (!reconstructor) return kFALSE;
2364
2365   
2366   TString detName = fgkDetectorName[iDet];
2367   AliDebug(1, Form("%s tracking", detName.Data()));
2368   AliTracker *tracker =  reconstructor->CreateTracker();
2369   if (!tracker) {
2370     AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
2371     return kFALSE;
2372   }
2373      
2374   // read RecPoints
2375   fLoader[iDet]->LoadRecPoints("read");  
2376
2377   tracker->LoadClusters(fLoader[iDet]->TreeR());
2378   
2379   Int_t rv = tracker->Clusters2Tracks(esd);
2380   
2381   fLoader[iDet]->UnloadRecPoints();
2382
2383   tracker->UnloadClusters();
2384   
2385   delete tracker;
2386   
2387   if ( rv )
2388   {
2389     AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
2390     return kFALSE;
2391   }
2392   
2393   return kTRUE;
2394 }
2395
2396
2397 //_____________________________________________________________________________
2398 Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd)
2399 {
2400 // run the barrel tracking
2401   static Int_t eventNr=0;
2402   AliCodeTimerAuto("",0)
2403
2404   AliInfo("running tracking");
2405
2406   // Set the event info which is used
2407   // by the trackers in order to obtain
2408   // information about read-out detectors,
2409   // trigger etc.
2410   AliDebug(1, "Setting event info");
2411   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2412     if (!fTracker[iDet]) continue;
2413     fTracker[iDet]->SetEventInfo(&fEventInfo);
2414   }
2415
2416   //Fill the ESD with the T0 info (will be used by the TOF) 
2417   if (fReconstructor[11] && fLoader[11]) {
2418     fLoader[11]->LoadRecPoints("READ");
2419     TTree *treeR = fLoader[11]->TreeR();
2420     if (treeR) {
2421       GetReconstructor(11)->FillESD((TTree *)NULL,treeR,esd);
2422     }
2423   }
2424
2425   // pass 1: TPC + ITS inwards
2426   for (Int_t iDet = 1; iDet >= 0; iDet--) {
2427     if (!fTracker[iDet]) continue;
2428     AliDebug(1, Form("%s tracking", fgkDetectorName[iDet]));
2429
2430     // load clusters
2431     fLoader[iDet]->LoadRecPoints("read");
2432     AliSysInfo::AddStamp(Form("RLoadCluster%s_%d",fgkDetectorName[iDet],eventNr),iDet,1, eventNr);
2433     TTree* tree = fLoader[iDet]->TreeR();
2434     if (!tree) {
2435       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
2436       return kFALSE;
2437     }
2438     fTracker[iDet]->LoadClusters(tree);
2439     AliSysInfo::AddStamp(Form("TLoadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
2440     // run tracking
2441     if (fTracker[iDet]->Clusters2Tracks(esd) != 0) {
2442       AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
2443       return kFALSE;
2444     }
2445     // preliminary PID in TPC needed by the ITS tracker
2446     if (iDet == 1) {
2447       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
2448       AliESDpid::MakePID(esd);
2449     } 
2450     AliSysInfo::AddStamp(Form("Tracking0%s_%d",fgkDetectorName[iDet],eventNr), iDet,3,eventNr);
2451   }
2452
2453   // pass 2: ALL backwards
2454
2455   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2456     if (!fTracker[iDet]) continue;
2457     AliDebug(1, Form("%s back propagation", fgkDetectorName[iDet]));
2458
2459     // load clusters
2460     if (iDet > 1) {     // all except ITS, TPC
2461       TTree* tree = NULL;
2462       fLoader[iDet]->LoadRecPoints("read");
2463       AliSysInfo::AddStamp(Form("RLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,1, eventNr);
2464       tree = fLoader[iDet]->TreeR();
2465       if (!tree) {
2466         AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
2467         return kFALSE;
2468       }
2469       fTracker[iDet]->LoadClusters(tree); 
2470       AliSysInfo::AddStamp(Form("TLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
2471     }
2472
2473     // run tracking
2474     if (iDet>1) // start filling residuals for the "outer" detectors
2475       if (fRunGlobalQA) {
2476         AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
2477         TObjArray ** arr = AliTracker::GetResidualsArray() ; 
2478         if (arr) {
2479           AliRecoParam::EventSpecie_t es=fRecoParam.GetEventSpecie();
2480           TObjArray * elem = arr[AliRecoParam::AConvert(es)];
2481           if ( elem && (! elem->At(0)) ) {
2482             AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
2483             if (qadm) qadm->InitRecPointsForTracker() ; 
2484           }
2485         }
2486       }
2487     if (fTracker[iDet]->PropagateBack(esd) != 0) {
2488       AliError(Form("%s backward propagation failed", fgkDetectorName[iDet]));
2489       //      return kFALSE;
2490     }
2491
2492     // unload clusters
2493     if (iDet > 3) {     // all except ITS, TPC, TRD and TOF
2494       fTracker[iDet]->UnloadClusters();
2495       fLoader[iDet]->UnloadRecPoints();
2496     }
2497     // updated PID in TPC needed by the ITS tracker -MI
2498     if (iDet == 1) {
2499       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
2500       AliESDpid::MakePID(esd);
2501     }
2502     AliSysInfo::AddStamp(Form("Tracking1%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
2503   }
2504   //stop filling residuals for the "outer" detectors
2505   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
2506
2507   // pass 3: TRD + TPC + ITS refit inwards
2508
2509   for (Int_t iDet = 2; iDet >= 0; iDet--) {
2510     if (!fTracker[iDet]) continue;
2511     AliDebug(1, Form("%s inward refit", fgkDetectorName[iDet]));
2512
2513     // run tracking
2514     if (iDet<2) // start filling residuals for TPC and ITS
2515       if (fRunGlobalQA) {
2516         AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
2517         TObjArray ** arr = AliTracker::GetResidualsArray() ; 
2518         if (arr) {
2519           AliRecoParam::EventSpecie_t es=fRecoParam.GetEventSpecie();
2520           TObjArray * elem = arr[AliRecoParam::AConvert(es)];
2521           if ( elem && (! elem->At(0)) ) {
2522             AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
2523             if (qadm) qadm->InitRecPointsForTracker() ; 
2524           }
2525         }
2526       }
2527     
2528     if (fTracker[iDet]->RefitInward(esd) != 0) {
2529       AliError(Form("%s inward refit failed", fgkDetectorName[iDet]));
2530       //      return kFALSE;
2531     }
2532     // run postprocessing
2533     if (fTracker[iDet]->PostProcess(esd) != 0) {
2534       AliError(Form("%s postprocessing failed", fgkDetectorName[iDet]));
2535       //      return kFALSE;
2536     }
2537     AliSysInfo::AddStamp(Form("Tracking2%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
2538   }
2539
2540   // write space-points to the ESD in case alignment data output
2541   // is switched on
2542   if (fWriteAlignmentData)
2543     WriteAlignmentData(esd);
2544
2545   for (Int_t iDet = 3; iDet >= 0; iDet--) {
2546     if (!fTracker[iDet]) continue;
2547     // unload clusters
2548     fTracker[iDet]->UnloadClusters();
2549     AliSysInfo::AddStamp(Form("TUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,4, eventNr);
2550     fLoader[iDet]->UnloadRecPoints();
2551     AliSysInfo::AddStamp(Form("RUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,5, eventNr);
2552   }
2553   // stop filling residuals for TPC and ITS
2554   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
2555
2556   eventNr++;
2557   return kTRUE;
2558 }
2559
2560 //_____________________________________________________________________________
2561 Bool_t AliReconstruction::CleanESD(AliESDEvent *esd){
2562   //
2563   // Remove the data which are not needed for the physics analysis.
2564   //
2565
2566   Int_t nTracks=esd->GetNumberOfTracks();
2567   Int_t nV0s=esd->GetNumberOfV0s();
2568   AliInfo
2569   (Form("Number of ESD tracks and V0s before cleaning: %d %d",nTracks,nV0s));
2570
2571   Float_t cleanPars[]={fV0DCAmax,fV0CsPmin,fDmax,fZmax};
2572   Bool_t rc=esd->Clean(cleanPars);
2573
2574   nTracks=esd->GetNumberOfTracks();
2575   nV0s=esd->GetNumberOfV0s();
2576   AliInfo
2577   (Form("Number of ESD tracks and V0s after cleaning %d %d",nTracks,nV0s));
2578
2579   return rc;
2580 }
2581
2582 //_____________________________________________________________________________
2583 Bool_t AliReconstruction::FillESD(AliESDEvent*& esd, const TString& detectors)
2584 {
2585 // fill the event summary data
2586
2587   AliCodeTimerAuto("",0)
2588     static Int_t eventNr=0; 
2589   TString detStr = detectors;
2590   
2591   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2592   if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2593     AliReconstructor* reconstructor = GetReconstructor(iDet);
2594     if (!reconstructor) continue;
2595     AliDebug(1, Form("filling ESD for %s", fgkDetectorName[iDet]));
2596     TTree* clustersTree = NULL;
2597     if (fLoader[iDet]) {
2598       fLoader[iDet]->LoadRecPoints("read");
2599       clustersTree = fLoader[iDet]->TreeR();
2600       if (!clustersTree) {
2601         AliError(Form("Can't get the %s clusters tree", 
2602                       fgkDetectorName[iDet]));
2603         if (fStopOnError) return kFALSE;
2604       }
2605     }
2606     if (fRawReader && !reconstructor->HasDigitConversion()) {
2607       reconstructor->FillESD(fRawReader, clustersTree, esd);
2608     } else {
2609       TTree* digitsTree = NULL;
2610       if (fLoader[iDet]) {
2611         fLoader[iDet]->LoadDigits("read");
2612         digitsTree = fLoader[iDet]->TreeD();
2613         if (!digitsTree) {
2614           AliError(Form("Can't get the %s digits tree", 
2615                         fgkDetectorName[iDet]));
2616           if (fStopOnError) return kFALSE;
2617         }
2618       }
2619       reconstructor->FillESD(digitsTree, clustersTree, esd);
2620       if (fLoader[iDet]) fLoader[iDet]->UnloadDigits();
2621     }
2622     if (fLoader[iDet]) {
2623       fLoader[iDet]->UnloadRecPoints();
2624     }
2625   }
2626   
2627   IsSelected("CTP", detStr);
2628   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2629     AliError(Form("the following detectors were not found: %s", 
2630                   detStr.Data()));
2631     if (fStopOnError) return kFALSE;
2632   }
2633   AliSysInfo::AddStamp(Form("FillESD%d",eventNr), 0,1, eventNr);
2634   eventNr++;
2635   return kTRUE;
2636 }
2637
2638 //_____________________________________________________________________________
2639 Bool_t AliReconstruction::FillTriggerESD(AliESDEvent*& esd)
2640 {
2641   // Reads the trigger decision which is
2642   // stored in Trigger.root file and fills
2643   // the corresponding esd entries
2644
2645   AliCodeTimerAuto("",0)
2646   
2647   AliInfo("Filling trigger information into the ESD");
2648
2649   if (fRawReader) {
2650     AliCTPRawStream input(fRawReader);
2651     if (!input.Next()) {
2652       AliWarning("No valid CTP (trigger) DDL raw data is found ! The trigger info is taken from the event header!");
2653     }
2654     else {
2655       if (esd->GetTriggerMask() != input.GetClassMask())
2656         AliError(Form("Invalid trigger pattern found in CTP raw-data: %llx %llx",
2657                       input.GetClassMask(),esd->GetTriggerMask()));
2658       if (esd->GetOrbitNumber() != input.GetOrbitID())
2659         AliError(Form("Invalid orbit id found in CTP raw-data: %x %x",
2660                       input.GetOrbitID(),esd->GetOrbitNumber()));
2661       if (esd->GetBunchCrossNumber() != input.GetBCID())
2662         AliError(Form("Invalid bunch-crossing id found in CTP raw-data: %x %x",
2663                       input.GetBCID(),esd->GetBunchCrossNumber()));
2664       AliESDHeader* esdheader = esd->GetHeader();
2665       esdheader->SetL0TriggerInputs(input.GetL0Inputs());
2666       esdheader->SetL1TriggerInputs(input.GetL1Inputs());
2667       esdheader->SetL2TriggerInputs(input.GetL2Inputs());
2668       // IR
2669       UInt_t orbit=input.GetOrbitID();
2670        for(Int_t i=0 ; i<input.GetNIRs() ; i++ )
2671           if(TMath::Abs(Int_t(orbit-(input.GetIR(i))->GetOrbit()))<=1){
2672              esdheader->AddTriggerIR(input.GetIR(i));
2673           }
2674     }
2675   }
2676   return kTRUE;
2677 }
2678 //_____________________________________________________________________________
2679 Bool_t AliReconstruction::FillTriggerScalers(AliESDEvent*& esd)
2680 {
2681   //Scalers
2682   //fRunScalers->Print();
2683   if(fRunScalers && fRunScalers->CheckRunScalers()){
2684      AliTimeStamp* timestamp = new AliTimeStamp(esd->GetOrbitNumber(), esd->GetPeriodNumber(), esd->GetBunchCrossNumber());
2685      //AliTimeStamp* timestamp = new AliTimeStamp(10308000, 0, (ULong64_t)486238);
2686      AliESDHeader* esdheader = fesd->GetHeader();
2687      for(Int_t i=0;i<50;i++){
2688           if((1ull<<i) & esd->GetTriggerMask()){
2689           AliTriggerScalersESD* scalesd = fRunScalers->GetScalersForEventClass( timestamp, i+1);
2690           if(scalesd)esdheader->SetTriggerScalersRecord(scalesd);
2691         }
2692      }
2693   }
2694   return kTRUE;
2695 }
2696 //_____________________________________________________________________________
2697 Bool_t AliReconstruction::FillRawEventHeaderESD(AliESDEvent*& esd)
2698 {
2699   // 
2700   // Filling information from RawReader Header
2701   // 
2702
2703   if (!fRawReader) return kFALSE;
2704
2705   AliInfo("Filling information from RawReader Header");
2706
2707   esd->SetBunchCrossNumber(fRawReader->GetBCID());
2708   esd->SetOrbitNumber(fRawReader->GetOrbitID());
2709   esd->SetPeriodNumber(fRawReader->GetPeriod());
2710
2711   esd->SetTimeStamp(fRawReader->GetTimestamp());  
2712   esd->SetEventType(fRawReader->GetType());
2713
2714   return kTRUE;
2715 }
2716
2717
2718 //_____________________________________________________________________________
2719 Bool_t AliReconstruction::IsSelected(TString detName, TString& detectors) const
2720 {
2721 // check whether detName is contained in detectors
2722 // if yes, it is removed from detectors
2723
2724   // check if all detectors are selected
2725   if ((detectors.CompareTo("ALL") == 0) ||
2726       detectors.BeginsWith("ALL ") ||
2727       detectors.EndsWith(" ALL") ||
2728       detectors.Contains(" ALL ")) {
2729     detectors = "ALL";
2730     return kTRUE;
2731   }
2732
2733   // search for the given detector
2734   Bool_t result = kFALSE;
2735   if ((detectors.CompareTo(detName) == 0) ||
2736       detectors.BeginsWith(detName+" ") ||
2737       detectors.EndsWith(" "+detName) ||
2738       detectors.Contains(" "+detName+" ")) {
2739     detectors.ReplaceAll(detName, "");
2740     result = kTRUE;
2741   }
2742
2743   // clean up the detectors string
2744   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
2745   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
2746   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
2747
2748   return result;
2749 }
2750
2751 //_____________________________________________________________________________
2752 Bool_t AliReconstruction::InitRunLoader()
2753 {
2754 // get or create the run loader
2755
2756   if (gAlice) delete gAlice;
2757   gAlice = NULL;
2758
2759   TFile *gafile = TFile::Open(fGAliceFileName.Data());
2760   //  if (!gSystem->AccessPathName(fGAliceFileName.Data())) { // galice.root exists
2761   if (gafile) { // galice.root exists
2762     gafile->Close();
2763     delete gafile;
2764
2765     // load all base libraries to get the loader classes
2766     TString libs = gSystem->GetLibraries();
2767     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2768       TString detName = fgkDetectorName[iDet];
2769       if (detName == "HLT") continue;
2770       if (libs.Contains("lib" + detName + "base.so")) continue;
2771       gSystem->Load("lib" + detName + "base.so");
2772     }
2773     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data());
2774     if (!fRunLoader) {
2775       AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
2776       CleanUp();
2777       return kFALSE;
2778     }
2779
2780     fRunLoader->CdGAFile();
2781     fRunLoader->LoadgAlice();
2782
2783     //PH This is a temporary fix to give access to the kinematics
2784     //PH that is needed for the labels of ITS clusters
2785     fRunLoader->LoadHeader();
2786     fRunLoader->LoadKinematics();
2787
2788   } else {               // galice.root does not exist
2789     if (!fRawReader) {
2790       AliError(Form("the file %s does not exist", fGAliceFileName.Data()));
2791     }
2792     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data(),
2793                                     AliConfig::GetDefaultEventFolderName(),
2794                                     "recreate");
2795     if (!fRunLoader) {
2796       AliError(Form("could not create run loader in file %s", 
2797                     fGAliceFileName.Data()));
2798       CleanUp();
2799       return kFALSE;
2800     }
2801     fIsNewRunLoader = kTRUE;
2802     fRunLoader->MakeTree("E");
2803
2804     if (fNumberOfEventsPerFile > 0)
2805       fRunLoader->SetNumberOfEventsPerFile(fNumberOfEventsPerFile);
2806     else
2807       fRunLoader->SetNumberOfEventsPerFile((UInt_t)-1);
2808   }
2809
2810   return kTRUE;
2811 }
2812
2813 //_____________________________________________________________________________
2814 AliReconstructor* AliReconstruction::GetReconstructor(Int_t iDet)
2815 {
2816 // get the reconstructor object and the loader for a detector
2817
2818   if (fReconstructor[iDet]) {
2819     if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
2820       const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
2821       fReconstructor[iDet]->SetRecoParam(par);
2822       fReconstructor[iDet]->SetRunInfo(fRunInfo);
2823     }
2824     return fReconstructor[iDet];
2825   }
2826
2827   // load the reconstructor object
2828   TPluginManager* pluginManager = gROOT->GetPluginManager();
2829   TString detName = fgkDetectorName[iDet];
2830   TString recName = "Ali" + detName + "Reconstructor";
2831
2832   if (!fIsNewRunLoader && !fRunLoader->GetLoader(detName+"Loader") && (detName != "HLT")) return NULL;
2833
2834   AliReconstructor* reconstructor = NULL;
2835   // first check if a plugin is defined for the reconstructor
2836   TPluginHandler* pluginHandler = 
2837     pluginManager->FindHandler("AliReconstructor", detName);
2838   // if not, add a plugin for it
2839   if (!pluginHandler) {
2840     AliDebug(1, Form("defining plugin for %s", recName.Data()));
2841     TString libs = gSystem->GetLibraries();
2842     if (libs.Contains("lib" + detName + "base.so") ||
2843         (gSystem->Load("lib" + detName + "base.so") >= 0)) {
2844       pluginManager->AddHandler("AliReconstructor", detName, 
2845                                 recName, detName + "rec", recName + "()");
2846     } else {
2847       pluginManager->AddHandler("AliReconstructor", detName, 
2848                                 recName, detName, recName + "()");
2849     }
2850     pluginHandler = pluginManager->FindHandler("AliReconstructor", detName);
2851   }
2852   if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
2853     reconstructor = (AliReconstructor*) pluginHandler->ExecPlugin(0);
2854   }
2855   if (reconstructor) {
2856     TObject* obj = fOptions.FindObject(detName.Data());
2857     if (obj) reconstructor->SetOption(obj->GetTitle());
2858     reconstructor->SetRunInfo(fRunInfo);
2859     reconstructor->Init();
2860     fReconstructor[iDet] = reconstructor;
2861   }
2862
2863   // get or create the loader
2864   if (detName != "HLT") {
2865     fLoader[iDet] = fRunLoader->GetLoader(detName + "Loader");
2866     if (!fLoader[iDet]) {
2867       AliConfig::Instance()
2868         ->CreateDetectorFolders(fRunLoader->GetEventFolder(), 
2869                                 detName, detName);
2870       // first check if a plugin is defined for the loader
2871       pluginHandler = 
2872         pluginManager->FindHandler("AliLoader", detName);
2873       // if not, add a plugin for it
2874       if (!pluginHandler) {
2875         TString loaderName = "Ali" + detName + "Loader";
2876         AliDebug(1, Form("defining plugin for %s", loaderName.Data()));
2877         pluginManager->AddHandler("AliLoader", detName, 
2878                                   loaderName, detName + "base", 
2879                                   loaderName + "(const char*, TFolder*)");
2880         pluginHandler = pluginManager->FindHandler("AliLoader", detName);
2881       }
2882       if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
2883         fLoader[iDet] = 
2884           (AliLoader*) pluginHandler->ExecPlugin(2, detName.Data(), 
2885                                                  fRunLoader->GetEventFolder());
2886       }
2887       if (!fLoader[iDet]) {   // use default loader
2888         fLoader[iDet] = new AliLoader(detName, fRunLoader->GetEventFolder());
2889       }
2890       if (!fLoader[iDet]) {
2891         AliWarning(Form("couldn't get loader for %s", detName.Data()));
2892         if (fStopOnError) return NULL;
2893       } else {
2894         fRunLoader->AddLoader(fLoader[iDet]);
2895         fRunLoader->CdGAFile();
2896         if (gFile && !gFile->IsWritable()) gFile->ReOpen("UPDATE");
2897         fRunLoader->Write(0, TObject::kOverwrite);
2898       }
2899     }
2900   }
2901       
2902   if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
2903     const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
2904     reconstructor->SetRecoParam(par);
2905     reconstructor->SetRunInfo(fRunInfo);
2906   }
2907   return reconstructor;
2908 }
2909
2910 //_____________________________________________________________________________
2911 AliVertexer* AliReconstruction::CreateVertexer()
2912 {
2913 // create the vertexer
2914 // Please note that the caller is the owner of the
2915 // vertexer
2916
2917   AliVertexer* vertexer = NULL;
2918   AliReconstructor* itsReconstructor = GetReconstructor(0);
2919   if (itsReconstructor && ((fRunLocalReconstruction.Contains("ITS")) || fRunTracking.Contains("ITS"))) {
2920     vertexer = itsReconstructor->CreateVertexer();
2921   }
2922   if (!vertexer) {
2923     AliWarning("couldn't create a vertexer for ITS");
2924   }
2925
2926   return vertexer;
2927 }
2928
2929 //_____________________________________________________________________________
2930 Bool_t AliReconstruction::CreateTrackers(const TString& detectors)
2931 {
2932 // create the trackers
2933         AliInfo("Creating trackers");
2934
2935   TString detStr = detectors;
2936   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2937     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2938     AliReconstructor* reconstructor = GetReconstructor(iDet);
2939     if (!reconstructor) continue;
2940     TString detName = fgkDetectorName[iDet];
2941     if (detName == "HLT") {
2942       fRunHLTTracking = kTRUE;
2943       continue;
2944     }
2945     if (detName == "MUON") {
2946       fRunMuonTracking = kTRUE;
2947       continue;
2948     }
2949
2950
2951     fTracker[iDet] = reconstructor->CreateTracker();
2952     if (!fTracker[iDet] && (iDet < 7)) {
2953       AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
2954       if (fStopOnError) return kFALSE;
2955     }
2956     AliSysInfo::AddStamp(Form("LTracker%s",fgkDetectorName[iDet]), iDet,0);
2957   }
2958
2959   return kTRUE;
2960 }
2961
2962 //_____________________________________________________________________________
2963 void AliReconstruction::CleanUp()
2964 {
2965 // delete trackers and the run loader and close and delete the file
2966
2967   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2968     delete fReconstructor[iDet];
2969     fReconstructor[iDet] = NULL;
2970     fLoader[iDet] = NULL;
2971     delete fTracker[iDet];
2972     fTracker[iDet] = NULL;
2973   }
2974   delete fRunInfo;
2975   fRunInfo = NULL;
2976
2977   delete fSPDTrackleter;
2978   fSPDTrackleter = NULL;
2979
2980   delete ftVertexer;
2981   ftVertexer = NULL;
2982   
2983   delete fRunLoader;
2984   fRunLoader = NULL;
2985   delete fRawReader;
2986   fRawReader = NULL;
2987   delete fParentRawReader;
2988   fParentRawReader=NULL;
2989
2990   if (ffile) {
2991     ffile->Close();
2992     delete ffile;
2993     ffile = NULL;
2994   }
2995
2996   if (AliQAManager::QAManager())
2997     AliQAManager::QAManager()->ShowQA() ; 
2998   AliQAManager::Destroy() ; 
2999   
3000 }
3001
3002 void AliReconstruction::WriteAlignmentData(AliESDEvent* esd)
3003 {
3004   // Write space-points which are then used in the alignment procedures
3005   // For the moment only ITS, TPC, TRD and TOF
3006
3007   Int_t ntracks = esd->GetNumberOfTracks();
3008   for (Int_t itrack = 0; itrack < ntracks; itrack++)
3009     {
3010       AliESDtrack *track = esd->GetTrack(itrack);
3011       Int_t nsp = 0;
3012       Int_t idx[200];
3013       for (Int_t i=0; i<200; ++i) idx[i] = -1; //PH avoid uninitialized values
3014       for (Int_t iDet = 5; iDet >= 0; iDet--) {// TOF, TRD, TPC, ITS clusters
3015           nsp += (iDet==GetDetIndex("TRD")) ? track->GetTRDntracklets():track->GetNcls(iDet);
3016
3017           if (iDet==GetDetIndex("ITS")) { // ITS "extra" clusters
3018              track->GetClusters(iDet,idx);
3019              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nsp++;
3020           }  
3021       }
3022
3023       if (nsp) {
3024         AliTrackPointArray *sp = new AliTrackPointArray(nsp);
3025         track->SetTrackPointArray(sp);
3026         Int_t isptrack = 0;
3027         for (Int_t iDet = 5; iDet >= 0; iDet--) {
3028           AliTracker *tracker = fTracker[iDet];
3029           if (!tracker) continue;
3030           Int_t nspdet = (iDet==GetDetIndex("TRD")) ? track->GetTRDtracklets(idx):track->GetClusters(iDet,idx);
3031
3032           if (iDet==GetDetIndex("ITS")) // ITS "extra" clusters             
3033              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nspdet++;
3034
3035           if (nspdet <= 0) continue;
3036           AliTrackPoint p;
3037           Int_t isp = 0;
3038           Int_t isp2 = 0;
3039           while (isp2 < nspdet) {
3040             Bool_t isvalid=kTRUE;
3041
3042             Int_t index=idx[isp++];
3043             if (index < 0) continue;
3044
3045             TString dets = fgkDetectorName[iDet];
3046             if ((fUseTrackingErrorsForAlignment.CompareTo(dets) == 0) ||
3047             fUseTrackingErrorsForAlignment.BeginsWith(dets+" ") ||
3048             fUseTrackingErrorsForAlignment.EndsWith(" "+dets) ||
3049             fUseTrackingErrorsForAlignment.Contains(" "+dets+" ")) {
3050               isvalid = tracker->GetTrackPointTrackingError(index,p,track);
3051             } else {
3052               isvalid = tracker->GetTrackPoint(index,p); 
3053             } 
3054             isp2++;
3055             if (!isvalid) continue;
3056             if (iDet==GetDetIndex("ITS") && (isp-1)>=6) p.SetExtra();
3057             sp->AddPoint(isptrack,&p); isptrack++;
3058           }
3059         }       
3060       }
3061     }
3062 }
3063
3064 //_____________________________________________________________________________
3065 void AliReconstruction::FillRawDataErrorLog(Int_t iEvent, AliESDEvent* esd)
3066 {
3067   // The method reads the raw-data error log
3068   // accumulated within the rawReader.
3069   // It extracts the raw-data errors related to
3070   // the current event and stores them into
3071   // a TClonesArray inside the esd object.
3072
3073   if (!fRawReader) return;
3074
3075   for(Int_t i = 0; i < fRawReader->GetNumberOfErrorLogs(); i++) {
3076
3077     AliRawDataErrorLog *log = fRawReader->GetErrorLog(i);
3078     if (!log) continue;
3079     if (iEvent != log->GetEventNumber()) continue;
3080
3081     esd->AddRawDataErrorLog(log);
3082   }
3083
3084 }
3085
3086 //_____________________________________________________________________________
3087 void AliReconstruction::CheckQA()
3088 {
3089 // check the QA of SIM for this run and remove the detectors 
3090 // with status Fatal
3091   
3092 //      TString newRunLocalReconstruction ; 
3093 //      TString newRunTracking ;
3094 //      TString newFillESD ;
3095 //       
3096 //      for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
3097 //              TString detName(AliQAv1::GetDetName(iDet)) ;
3098 //              AliQAv1 * qa = AliQAv1::Instance(AliQAv1::DETECTORINDEX_t(iDet)) ;       
3099 //      if ( qa->IsSet(AliQAv1::DETECTORINDEX_t(iDet), AliQAv1::kSIM, specie, AliQAv1::kFATAL)) {
3100 //        AliInfo(Form("QA status for %s %s in Hits and/or SDIGITS  and/or Digits was Fatal; No reconstruction performed", 
3101 //                   detName.Data(), AliRecoParam::GetEventSpecieName(es))) ;
3102 //                      } else {
3103 //                      if ( fRunLocalReconstruction.Contains(AliQAv1::GetDetName(iDet)) || 
3104 //                                      fRunLocalReconstruction.Contains("ALL") )  {
3105 //                              newRunLocalReconstruction += detName ; 
3106 //                              newRunLocalReconstruction += " " ;                      
3107 //                      }
3108 //                      if ( fRunTracking.Contains(AliQAv1::GetDetName(iDet)) || 
3109 //                                      fRunTracking.Contains("ALL") )  {
3110 //                              newRunTracking += detName ; 
3111 //                              newRunTracking += " " ;                         
3112 //                      }
3113 //                      if ( fFillESD.Contains(AliQAv1::GetDetName(iDet)) || 
3114 //                                      fFillESD.Contains("ALL") )  {
3115 //                              newFillESD += detName ; 
3116 //                              newFillESD += " " ;                     
3117 //                      }
3118 //              }
3119 //      }
3120 //      fRunLocalReconstruction = newRunLocalReconstruction ; 
3121 //      fRunTracking            = newRunTracking ; 
3122 //      fFillESD                = newFillESD ; 
3123 }
3124
3125 //_____________________________________________________________________________
3126 Int_t AliReconstruction::GetDetIndex(const char* detector)
3127 {
3128   // return the detector index corresponding to detector
3129   Int_t index = -1 ; 
3130   for (index = 0; index < kNDetectors ; index++) {
3131     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
3132         break ; 
3133   }     
3134   return index ; 
3135 }
3136 //_____________________________________________________________________________
3137 Bool_t AliReconstruction::FinishPlaneEff() {
3138  //
3139  // Here execute all the necessary operationis, at the end of the tracking phase,
3140  // in case that evaluation of PlaneEfficiencies was required for some detector.
3141  // E.g., write into a DataBase file the PlaneEfficiency which have been evaluated.
3142  //
3143  // This Preliminary version works only FOR ITS !!!!!
3144  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3145  //
3146  //  Input: none
3147  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3148  //
3149  Bool_t ret=kFALSE;
3150  TString detStr = fLoadCDB;
3151  //for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
3152  for (Int_t iDet = 0; iDet < 1; iDet++) { // for the time being only ITS
3153    if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3154    if(fTracker[iDet] && fTracker[iDet]->GetPlaneEff()) {
3155       AliPlaneEff *planeeff=fTracker[iDet]->GetPlaneEff();
3156       TString name=planeeff->GetName();
3157       name+=".root";
3158       TFile* pefile = TFile::Open(name, "RECREATE");
3159       ret=(Bool_t)planeeff->Write();
3160       pefile->Close();
3161       if(planeeff->GetCreateHistos()) {
3162         TString hname=planeeff->GetName();
3163         hname+="Histo.root";
3164         ret*=planeeff->WriteHistosToFile(hname,"RECREATE");
3165       }
3166    }
3167    if(fSPDTrackleter) {
3168      AliPlaneEff *planeeff=fSPDTrackleter->GetPlaneEff();
3169       TString name="AliITSPlaneEffSPDtracklet.root";
3170       TFile* pefile = TFile::Open(name, "RECREATE");
3171       ret=(Bool_t)planeeff->Write();
3172       pefile->Close();
3173       AliESDEvent *dummy=NULL;
3174       ret=(Bool_t)fSPDTrackleter->PostProcess(dummy); // take care of writing other files
3175    }
3176  }
3177  return ret;
3178 }
3179 //_____________________________________________________________________________
3180 Bool_t AliReconstruction::InitPlaneEff() {
3181 //
3182  // Here execute all the necessary operations, before of the tracking phase,
3183  // for the evaluation of PlaneEfficiencies, in case required for some detectors.
3184  // E.g., read from a DataBase file a first evaluation of the PlaneEfficiency
3185  // which should be updated/recalculated.
3186  //
3187  // This Preliminary version will work only FOR ITS !!!!!
3188  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3189  //
3190  //  Input: none
3191  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3192  //
3193  AliWarning(Form("Implementation of this method not yet completed !! Method return kTRUE"));
3194
3195   fSPDTrackleter = NULL;
3196   TString detStr = fLoadCDB;
3197   if (IsSelected(fgkDetectorName[0], detStr)) {
3198     AliReconstructor* itsReconstructor = GetReconstructor(0);
3199     if (itsReconstructor) {
3200       fSPDTrackleter = itsReconstructor->CreateTrackleter(); // this is NULL unless required in RecoParam
3201     }
3202     if (fSPDTrackleter) {
3203       AliInfo("Trackleter for SPD has been created");
3204     }
3205   }
3206  return kTRUE;
3207 }
3208
3209 //_____________________________________________________________________________
3210 Bool_t AliReconstruction::InitAliEVE()
3211 {
3212   // This method should be called only in case 
3213   // AliReconstruction is run
3214   // within the alieve environment.
3215   // It will initialize AliEVE in a way
3216   // so that it can visualize event processed
3217   // by AliReconstruction.
3218   // The return flag shows whenever the
3219   // AliEVE initialization was successful or not.
3220
3221   TString macroStr;
3222   macroStr.Form("%s/EVE/macros/alieve_online.C",gSystem->ExpandPathName("$ALICE_ROOT"));
3223   AliInfo(Form("Loading AliEVE macro: %s",macroStr.Data()));
3224   if (gROOT->LoadMacro(macroStr.Data()) != 0) return kFALSE;
3225
3226   gROOT->ProcessLine("if (!AliEveEventManager::GetMaster()){new AliEveEventManager();AliEveEventManager::GetMaster()->AddNewEventCommand(\"alieve_online_on_new_event()\");gEve->AddEvent(AliEveEventManager::GetMaster());};");
3227   gROOT->ProcessLine("alieve_online_init()");
3228
3229   return kTRUE;
3230 }
3231   
3232 //_____________________________________________________________________________
3233 void AliReconstruction::RunAliEVE()
3234 {
3235   // Runs AliEVE visualisation of
3236   // the current event.
3237   // Should be executed only after
3238   // successful initialization of AliEVE.
3239
3240   AliInfo("Running AliEVE...");
3241   gROOT->ProcessLine(Form("AliEveEventManager::GetMaster()->SetEvent((AliRunLoader*)0x%lx,(AliRawReader*)0x%lx,(AliESDEvent*)0x%lx,(AliESDfriend*)0x%lx);",fRunLoader,fRawReader,fesd,fesdf));
3242   gSystem->Run();
3243 }
3244
3245 //_____________________________________________________________________________
3246 Bool_t AliReconstruction::SetRunQA(TString detAndAction) 
3247 {
3248         // Allows to run QA for a selected set of detectors
3249         // and a selected set of tasks among RAWS, DIGITSR, RECPOINTS and ESDS
3250         // all selected detectors run the same selected tasks
3251         
3252         if (!detAndAction.Contains(":")) {
3253                 AliError( Form("%s is a wrong syntax, use \"DetectorList:ActionList\" \n", detAndAction.Data()) ) ;
3254                 fRunQA = kFALSE ;
3255                 return kFALSE ;                 
3256         }
3257         Int_t colon = detAndAction.Index(":") ; 
3258         fQADetectors = detAndAction(0, colon) ; 
3259         if (fQADetectors.Contains("ALL") ){
3260     TString tmp = fFillESD ;
3261     Int_t minus = fQADetectors.Last('-') ; 
3262     TString toKeep = fFillESD ; 
3263     TString toRemove("") ;
3264     while (minus >= 0) {
3265       toRemove = fQADetectors(minus+1, fQADetectors.Length()) ; 
3266       toRemove = toRemove.Strip() ; 
3267       toKeep.ReplaceAll(toRemove, "") ; 
3268       fQADetectors.ReplaceAll(Form("-%s", toRemove.Data()), "") ; 
3269       minus = fQADetectors.Last('-') ; 
3270     }
3271     fQADetectors = toKeep ; 
3272   }  
3273   fQATasks   = detAndAction(colon+1, detAndAction.Sizeof() ) ; 
3274         if (fQATasks.Contains("ALL") ) {
3275                 fQATasks = Form("%d %d %d %d", AliQAv1::kRAWS, AliQAv1::kDIGITSR, AliQAv1::kRECPOINTS, AliQAv1::kESDS) ; 
3276         } else {
3277                 fQATasks.ToUpper() ; 
3278                 TString tempo("") ; 
3279                 if ( fQATasks.Contains("RAW") ) 
3280                         tempo = Form("%d ", AliQAv1::kRAWS) ; 
3281                 if ( fQATasks.Contains("DIGIT") ) 
3282                         tempo += Form("%d ", AliQAv1::kDIGITSR) ; 
3283                 if ( fQATasks.Contains("RECPOINT") ) 
3284                         tempo += Form("%d ", AliQAv1::kRECPOINTS) ; 
3285                 if ( fQATasks.Contains("ESD") ) 
3286                         tempo += Form("%d ", AliQAv1::kESDS) ; 
3287                 fQATasks = tempo ; 
3288                 if (fQATasks.IsNull()) {
3289                         AliInfo("No QA requested\n")  ;
3290                         fRunQA = kFALSE ;
3291                         return kTRUE ; 
3292                 }
3293         }       
3294         TString tempo(fQATasks) ; 
3295         tempo.ReplaceAll(Form("%d", AliQAv1::kRAWS), AliQAv1::GetTaskName(AliQAv1::kRAWS))      ;
3296         tempo.ReplaceAll(Form("%d", AliQAv1::kDIGITSR), AliQAv1::GetTaskName(AliQAv1::kDIGITSR)) ;      
3297         tempo.ReplaceAll(Form("%d", AliQAv1::kRECPOINTS), AliQAv1::GetTaskName(AliQAv1::kRECPOINTS)) ;  
3298         tempo.ReplaceAll(Form("%d", AliQAv1::kESDS), AliQAv1::GetTaskName(AliQAv1::kESDS)) ;    
3299         AliInfo( Form("QA will be done on \"%s\" for \"%s\"\n", fQADetectors.Data(), tempo.Data()) ) ;  
3300         fRunQA = kTRUE ;
3301         return kTRUE; 
3302
3303
3304 //_____________________________________________________________________________
3305 Bool_t AliReconstruction::InitRecoParams() 
3306 {
3307   // The method accesses OCDB and retrieves all
3308   // the available reco-param objects from there.
3309
3310   Bool_t isOK = kTRUE;
3311
3312   if (fRecoParam.GetDetRecoParamArray(kNDetectors)) {
3313     AliInfo("Using custom GRP reconstruction parameters");
3314   }
3315   else {
3316     AliInfo("Loading GRP reconstruction parameter objects");
3317
3318     AliCDBPath path("GRP","Calib","RecoParam");
3319     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
3320     if(!entry){ 
3321       AliWarning("Couldn't find GRP RecoParam entry in OCDB");
3322       isOK = kFALSE;
3323     }
3324     else {
3325       TObject *recoParamObj = entry->GetObject();
3326       if (dynamic_cast<TObjArray*>(recoParamObj)) {
3327         // GRP has a normal TobjArray of AliDetectorRecoParam objects
3328         // Registering them in AliRecoParam
3329         fRecoParam.AddDetRecoParamArray(kNDetectors,dynamic_cast<TObjArray*>(recoParamObj));
3330       }
3331       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
3332         // GRP has only onse set of reco parameters
3333         // Registering it in AliRecoParam
3334         AliInfo("Single set of GRP reconstruction parameters found");
3335         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
3336         fRecoParam.AddDetRecoParam(kNDetectors,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
3337       }
3338       else {
3339         AliError("No valid GRP RecoParam object found in the OCDB");
3340         isOK = kFALSE;
3341       }
3342       entry->SetOwner(0);
3343     }
3344   }
3345
3346   TString detStr = fLoadCDB;
3347   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3348
3349     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3350
3351     if (fRecoParam.GetDetRecoParamArray(iDet)) {
3352       AliInfo(Form("Using custom reconstruction parameters for detector %s",fgkDetectorName[iDet]));
3353       continue;
3354     }
3355
3356     AliInfo(Form("Loading reconstruction parameter objects for detector %s",fgkDetectorName[iDet]));
3357   
3358     AliCDBPath path(fgkDetectorName[iDet],"Calib","RecoParam");
3359     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
3360     if(!entry){ 
3361       AliWarning(Form("Couldn't find RecoParam entry in OCDB for detector %s",fgkDetectorName[iDet]));
3362       isOK = kFALSE;
3363     }
3364     else {
3365       TObject *recoParamObj = entry->GetObject();
3366       if (dynamic_cast<TObjArray*>(recoParamObj)) {
3367         // The detector has a normal TobjArray of AliDetectorRecoParam objects
3368         // Registering them in AliRecoParam
3369         fRecoParam.AddDetRecoParamArray(iDet,dynamic_cast<TObjArray*>(recoParamObj));
3370       }
3371       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
3372         // The detector has only onse set of reco parameters
3373         // Registering it in AliRecoParam
3374         AliInfo(Form("Single set of reconstruction parameters found for detector %s",fgkDetectorName[iDet]));
3375         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
3376         fRecoParam.AddDetRecoParam(iDet,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
3377       }
3378       else {
3379         AliError(Form("No valid RecoParam object found in the OCDB for detector %s",fgkDetectorName[iDet]));
3380         isOK = kFALSE;
3381       }
3382       entry->SetOwner(0);
3383       //      FIX ME: We have to disable the unloading of reco-param CDB
3384       //      entries because QA framework is using them. Has to be fix in
3385       //      a way that the QA takes the objects already constructed in
3386       //      this method.
3387       //      AliCDBManager::Instance()->UnloadFromCache(path.GetPath());
3388     }
3389   }
3390
3391   if (AliDebugLevel() > 0) fRecoParam.Print();
3392
3393   return isOK;
3394 }
3395
3396 //_____________________________________________________________________________
3397 Bool_t AliReconstruction::GetEventInfo() 
3398 {
3399   // Fill the event info object
3400   // ...
3401   AliCodeTimerAuto("",0)
3402
3403   AliCentralTrigger *aCTP = NULL;
3404   if (fRawReader) {
3405     fEventInfo.SetEventType(fRawReader->GetType());
3406
3407     ULong64_t mask = fRawReader->GetClassMask();
3408     fEventInfo.SetTriggerMask(mask);
3409     UInt_t clmask = fRawReader->GetDetectorPattern()[0];
3410     fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(clmask));
3411
3412     aCTP = new AliCentralTrigger();
3413     TString configstr("");
3414     if (!aCTP->LoadConfiguration(configstr)) { // Load CTP config from OCDB
3415       AliError("No trigger configuration found in OCDB! The trigger configuration information will not be used!");
3416       delete aCTP;
3417       return kFALSE;
3418     }
3419     aCTP->SetClassMask(mask);
3420     aCTP->SetClusterMask(clmask);
3421   }
3422   else {
3423     fEventInfo.SetEventType(AliRawEventHeaderBase::kPhysicsEvent);
3424
3425     if (fRunLoader && (!fRunLoader->LoadTrigger())) {
3426       aCTP = fRunLoader->GetTrigger();
3427       fEventInfo.SetTriggerMask(aCTP->GetClassMask());
3428       // get inputs from actp - just get
3429       AliESDHeader* esdheader = fesd->GetHeader();
3430       esdheader->SetL0TriggerInputs(aCTP->GetL0TriggerInputs());
3431       esdheader->SetL1TriggerInputs(aCTP->GetL1TriggerInputs());
3432       esdheader->SetL2TriggerInputs(aCTP->GetL2TriggerInputs());
3433       fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(aCTP->GetClusterMask()));
3434     }
3435     else {
3436       AliWarning("No trigger can be loaded! The trigger information will not be used!");
3437       return kFALSE;
3438     }
3439   }
3440
3441   AliTriggerConfiguration *config = aCTP->GetConfiguration();
3442   if (!config) {
3443     AliError("No trigger configuration has been found! The trigger configuration information will not be used!");
3444     if (fRawReader) delete aCTP;
3445     return kFALSE;
3446   }
3447
3448   UChar_t clustmask = 0;
3449   TString trclasses;
3450   ULong64_t trmask = fEventInfo.GetTriggerMask();
3451   const TObjArray& classesArray = config->GetClasses();
3452   Int_t nclasses = classesArray.GetEntriesFast();
3453   for( Int_t iclass=0; iclass < nclasses; iclass++ ) {
3454     AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At(iclass);
3455     if (trclass) {
3456       Int_t trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
3457       fesd->SetTriggerClass(trclass->GetName(),trindex);
3458       if (fRawReader) fRawReader->LoadTriggerClass(trclass->GetName(),trindex);
3459       if (trmask & (1ull << trindex)) {
3460         trclasses += " ";
3461         trclasses += trclass->GetName();
3462         trclasses += " ";
3463         clustmask |= trclass->GetCluster()->GetClusterMask();
3464       }
3465     }
3466   }
3467   fEventInfo.SetTriggerClasses(trclasses);
3468
3469   // Set the information in ESD
3470   fesd->SetTriggerMask(trmask);
3471   fesd->SetTriggerCluster(clustmask);
3472
3473   if (!aCTP->CheckTriggeredDetectors()) {
3474     if (fRawReader) delete aCTP;
3475     return kFALSE;
3476   }    
3477
3478   if (fRawReader) delete aCTP;
3479
3480   // We have to fill also the HLT decision here!!
3481   // ...
3482
3483   return kTRUE;
3484 }
3485
3486 const char *AliReconstruction::MatchDetectorList(const char *detectorList, UInt_t detectorMask)
3487 {
3488   // Match the detector list found in the rec.C or the default 'ALL'
3489   // to the list found in the GRP (stored there by the shuttle PP which
3490   // gets the information from ECS)
3491   static TString resultList;
3492   TString detList = detectorList;
3493
3494   resultList = "";
3495
3496   for(Int_t iDet = 0; iDet < (AliDAQ::kNDetectors-1); iDet++) {
3497     if ((detectorMask >> iDet) & 0x1) {
3498       TString det = AliDAQ::OfflineModuleName(iDet);
3499       if ((detList.CompareTo("ALL") == 0) ||
3500           ((detList.BeginsWith("ALL ") ||
3501             detList.EndsWith(" ALL") ||
3502             detList.Contains(" ALL ")) &&
3503            !(detList.BeginsWith("-"+det+" ") ||
3504              detList.EndsWith(" -"+det) ||
3505              detList.Contains(" -"+det+" "))) ||
3506           (detList.CompareTo(det) == 0) ||
3507           detList.BeginsWith(det+" ") ||
3508           detList.EndsWith(" "+det) ||
3509           detList.Contains( " "+det+" " )) {
3510         if (!resultList.EndsWith(det + " ")) {
3511           resultList += det;
3512           resultList += " ";
3513         }
3514       }        
3515     }
3516   }
3517
3518   // HLT
3519   if ((detectorMask >> AliDAQ::kHLTId) & 0x1) {
3520     TString hltDet = AliDAQ::OfflineModuleName(AliDAQ::kNDetectors-1);
3521     if ((detList.CompareTo("ALL") == 0) ||
3522         ((detList.BeginsWith("ALL ") ||
3523           detList.EndsWith(" ALL") ||
3524           detList.Contains(" ALL ")) &&
3525          !(detList.BeginsWith("-"+hltDet+" ") ||
3526            detList.EndsWith(" -"+hltDet) ||
3527            detList.Contains(" -"+hltDet+" "))) ||
3528         (detList.CompareTo(hltDet) == 0) ||
3529         detList.BeginsWith(hltDet+" ") ||
3530         detList.EndsWith(" "+hltDet) ||
3531         detList.Contains( " "+hltDet+" " )) {
3532       resultList += hltDet;
3533     }
3534   }
3535
3536   return resultList.Data();
3537
3538 }
3539
3540 //______________________________________________________________________________
3541 void AliReconstruction::Abort(const char *method, EAbort what)
3542 {
3543   // Abort processing. If what = kAbortProcess, the Process() loop will be
3544   // aborted. If what = kAbortFile, the current file in a chain will be
3545   // aborted and the processing will continue with the next file, if there
3546   // is no next file then Process() will be aborted. Abort() can also  be
3547   // called from Begin(), SlaveBegin(), Init() and Notify(). After abort
3548   // the SlaveTerminate() and Terminate() are always called. The abort flag
3549   // can be checked in these methods using GetAbort().
3550   //
3551   // The method is overwritten in AliReconstruction for better handling of
3552   // reco specific errors 
3553
3554   if (!fStopOnError) return;
3555
3556   CleanUp();
3557
3558   TString whyMess = method;
3559   whyMess += " failed! Aborting...";
3560
3561   AliError(whyMess.Data());
3562
3563   fAbort = what;
3564   TString mess = "Abort";
3565   if (fAbort == kAbortProcess)
3566     mess = "AbortProcess";
3567   else if (fAbort == kAbortFile)
3568     mess = "AbortFile";
3569
3570   Info(mess, whyMess.Data());
3571 }
3572
3573 //______________________________________________________________________________
3574 Bool_t AliReconstruction::ProcessEvent(void* event)
3575 {
3576   // Method that is used in case the event loop
3577   // is steered from outside, for example by AMORE
3578   // 'event' is a pointer to the DATE event in the memory
3579
3580   if (fRawReader) delete fRawReader;
3581   fRawReader = new AliRawReaderDate(event);
3582   fStatus = ProcessEvent(fRunLoader->GetNumberOfEvents());  
3583   delete fRawReader;
3584   fRawReader = NULL;
3585
3586   return fStatus;
3587 }
3588
3589 //______________________________________________________________________________
3590 Bool_t AliReconstruction::ParseOutput()
3591 {
3592   // The method parses the output file
3593   // location string in order to steer
3594   // properly the selector
3595
3596   TPMERegexp re1("(\\w+\\.zip#\\w+\\.root):([,*\\w+\\.root,*]+)@dataset://(\\w++)");
3597   TPMERegexp re2("(\\w+\\.root)?@?dataset://(\\w++)");
3598
3599   if (re1.Match(fESDOutput) == 4) {
3600     // root archive with output files stored and regustered
3601     // in proof dataset
3602     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",re1[1].Data()));
3603     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",re1[3].Data()));
3604     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_DATASET",""));
3605     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_ARCHIVE",re1[2].Data()));
3606     AliInfo(Form("%s files will be stored within %s in dataset %s",
3607                  re1[2].Data(),
3608                  re1[1].Data(),
3609                  re1[3].Data()));
3610   }
3611   else if (re2.Match(fESDOutput) == 3) {
3612     // output file stored and registered
3613     // in proof dataset
3614     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",(re2[1].IsNull()) ? "AliESDs.root" : re2[1].Data()));
3615     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",re2[2].Data()));
3616     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_DATASET",""));
3617     AliInfo(Form("%s will be stored in dataset %s",
3618                  (re2[1].IsNull()) ? "AliESDs.root" : re2[1].Data(),
3619                  re2[2].Data()));
3620   }
3621   else {
3622     if (fESDOutput.IsNull()) {
3623       // Output location not given.
3624       // Assuming xrootd has been already started and
3625       // the output file has to be sent back
3626       // to the client machine
3627       TString esdUrl(Form("root://%s/%s/",
3628                           TUrl(gSystem->HostName()).GetHostFQDN(),
3629                           gSystem->pwd()));
3630       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE","AliESDs.root"));
3631       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",esdUrl.Data()));
3632       AliInfo(Form("AliESDs.root will be stored in %s",
3633                    esdUrl.Data()));
3634     }
3635     else {
3636       // User specified an output location.
3637       // Ones has just to parse it here
3638       TUrl outputUrl(fESDOutput.Data());
3639       TString outputFile(gSystem->BaseName(outputUrl.GetFile()));
3640       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",outputFile.IsNull() ? "AliESDs.root" : outputFile.Data()));
3641       TString outputLocation(outputUrl.GetUrl());
3642       outputLocation.ReplaceAll(outputFile.Data(),"");
3643       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",outputLocation.Data()));
3644       AliInfo(Form("%s will be stored in %s",
3645                    outputFile.IsNull() ? "AliESDs.root" : outputFile.Data(),
3646                    outputLocation.Data()));
3647     }
3648   }
3649
3650   return kTRUE;
3651 }