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