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