]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/STEER/AliReconstruction.cxx
Clearer fatal message.
[u/mrichter/AliRoot.git] / STEER / 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: AliReconstruction.cxx 63911 2013-08-19 16:46:41Z hristov $ */
17
18 ///////////////////////////////////////////////////////////////////////////////
19 //                                                                           //
20 // class for running the reconstruction                                      //
21 //                                                                           //
22 // Clusters and tracks are created for all detectors and all events by       //
23 // typing:                                                                   //
24 //                                                                           //
25 //   AliReconstruction rec;                                                  //
26 //   rec.Run();                                                              //
27 //                                                                           //
28 // The Run method returns kTRUE in case of successful execution.             //
29 //                                                                           //
30 // If the input to the reconstruction are not simulated digits but raw data, //
31 // this can be specified by an argument of the Run method or by the method   //
32 //                                                                           //
33 //   rec.SetInput("...");                                                    //
34 //                                                                           //
35 // The input formats and the corresponding argument are:                     //
36 // - DDL raw data files: directory name, ends with "/"                       //
37 // - raw data root file: root file name, extension ".root"                   //
38 // - raw data DATE file: DATE file name, any other non-empty string          //
39 // - MC root files     : empty string, default                               //
40 //                                                                           //
41 // By default all events are reconstructed. The reconstruction can be        //
42 // limited to a range of events by giving the index of the first and the     //
43 // last event as an argument to the Run method or by calling                 //
44 //                                                                           //
45 //   rec.SetEventRange(..., ...);                                            //
46 //                                                                           //
47 // The index -1 (default) can be used for the last event to indicate no      //
48 // upper limit of the event range.                                           //
49 //                                                                           //
50 // In case of raw-data reconstruction the user can modify the default        //
51 // number of events per digits/clusters/tracks file. In case the option      //
52 // is not used the number is set 1. In case the user provides 0, than        //
53 // the number of events is equal to the number of events inside the          //
54 // raw-data file (i.e. one digits/clusters/tracks file):                     //
55 //                                                                           //
56 //   rec.SetNumberOfEventsPerFile(...);                                      //
57 //                                                                           //
58 //                                                                           //
59 // The name of the galice file can be changed from the default               //
60 // "galice.root" by passing it as argument to the AliReconstruction          //
61 // constructor or by                                                         //
62 //                                                                           //
63 //   rec.SetGAliceFile("...");                                               //
64 //                                                                           //
65 // The local reconstruction can be switched on or off for individual         //
66 // detectors by                                                              //
67 //                                                                           //
68 //   rec.SetRunLocalReconstruction("...");                                   //
69 //                                                                           //
70 // The argument is a (case sensitive) string with the names of the           //
71 // detectors separated by a space. The special string "ALL" selects all      //
72 // available detectors. This is the default.                                 //
73 //                                                                           //
74 // The reconstruction of the primary vertex position can be switched off by  //
75 //                                                                           //
76 //   rec.SetRunVertexFinder(kFALSE);                                         //
77 //                                                                           //
78 // The tracking and the creation of ESD tracks can be switched on for        //
79 // selected detectors by                                                     //
80 //                                                                           //
81 //   rec.SetRunTracking("...");                                              //
82 //                                                                           //
83 // Uniform/nonuniform field tracking switches (default: uniform field)       //
84 //                                                                           //
85 //   rec.SetUniformFieldTracking(); ( rec.SetUniformFieldTracking(kFALSE); ) //
86 //                                                                           //
87 // The filling of additional ESD information can be steered by               //
88 //                                                                           //
89 //   rec.SetFillESD("...");                                                  //
90 //                                                                           //
91 // Again, for both methods the string specifies the list of detectors.       //
92 // The default is "ALL".                                                     //
93 //                                                                           //
94 // The call of the shortcut method                                           //
95 //                                                                           //
96 //   rec.SetRunReconstruction("...");                                        //
97 //                                                                           //
98 // is equivalent to calling SetRunLocalReconstruction, SetRunTracking and    //
99 // SetFillESD with the same detector selecting string as argument.           //
100 //                                                                           //
101 // The reconstruction requires digits or raw data as input. For the creation //
102 // of digits and raw data have a look at the class AliSimulation.            //
103 //                                                                           //
104 // The input data of a detector can be replaced by the corresponding HLT     //
105 // data by calling (usual detector string)                                   //
106 // SetUseHLTData("...");                                                     //
107 //                                                                           //
108 //                                                                           //
109 ///////////////////////////////////////////////////////////////////////////////
110
111 #include <TArrayD.h>
112 #include <TArrayF.h>
113 #include <TArrayS.h>
114 #include <TChain.h>
115 #include <TFile.h>
116 #include <TGeoGlobalMagField.h>
117 #include <TGeoManager.h>
118 #include <TList.h>
119 #include <TLorentzVector.h>
120 #include <TMap.h>
121 #include <TObjArray.h>
122 #include <TPRegexp.h>
123 #include <TParameter.h>
124 #include <TPluginManager.h>
125 #include <TProof.h>
126 #include <TProofOutputFile.h>
127 #include <TROOT.h>
128 #include <TSystem.h>
129 #include <THashTable.h>
130 #include <TGrid.h>
131 #include <TMessage.h>
132 #include <TUrl.h>
133 #include <TRandom.h>
134 #include <THashList.h>
135
136 #include "AliAlignObj.h"
137 #include "AliAnalysisManager.h"
138 #include "AliAnalysisDataContainer.h"
139 #include "AliCDBEntry.h"
140 #include "AliCDBManager.h"
141 #include "AliCDBStorage.h"
142 #include "AliCTPRawStream.h"
143 #include "AliCascadeVertexer.h"
144 #include "AliCentralTrigger.h"
145 #include "AliCodeTimer.h"
146 #include "AliDAQ.h"
147 #include "AliDetectorRecoParam.h"
148 #include "AliESDCaloCells.h"
149 #include "AliESDCaloCluster.h"
150 #include "AliESDEvent.h"
151 #include "AliESDMuonTrack.h"
152 #include "AliESDPmdTrack.h"
153 #include "AliESDTagCreator.h"
154 #include "AliESDVertex.h"
155 #include "AliESDcascade.h"
156 #include "AliESDfriend.h"
157 #include "AliESDkink.h"
158 #include "AliESDpid.h"
159 #include "AliESDtrack.h"
160 #include "AliESDtrack.h"
161 #include "AliEventInfo.h"
162 #include "AliGRPObject.h"
163 #include "AliGRPRecoParam.h"
164 #include "AliGenEventHeader.h"
165 #include "AliGeomManager.h"
166 #include "AliGlobalQADataMaker.h" 
167 #include "AliHeader.h"
168 #include "AliLog.h"
169 #include "AliMagF.h"
170 #include "AliMultiplicity.h"
171 #include "AliPID.h"
172 #include "AliPlaneEff.h"
173 #include "AliQAv1.h"
174 #include "AliQADataMakerRec.h" 
175 #include "AliQAManager.h"
176 #include "AliRawVEvent.h"
177 #include "AliRawEventHeaderBase.h"
178 #include "AliRawHLTManager.h"
179 #include "AliRawReaderDate.h"
180 #include "AliRawReaderFile.h"
181 #include "AliRawReaderRoot.h"
182 #include "AliRecoInputHandler.h"
183 #include "AliReconstruction.h"
184 #include "AliReconstructor.h"
185 #include "AliRun.h"
186 #include "AliRunInfo.h"
187 #include "AliRunLoader.h"
188 #include "AliSysInfo.h" // memory snapshots
189 #include "AliTrackPointArray.h"
190 #include "AliTracker.h"
191 #include "AliTriggerClass.h"
192 #include "AliTriggerCluster.h"
193 #include "AliTriggerIR.h"
194 #include "AliTriggerConfiguration.h"
195 #include "AliV0vertexer.h"
196 #include "AliVertexer.h"
197 #include "AliTrackleter.h"
198 #include "AliVertexerTracks.h"
199 #include "AliTriggerRunScalers.h"
200 #include "AliCTPTimeParams.h" 
201 #include "AliESDHLTDecision.h"
202 #include "AliTriggerInput.h"
203 #include "AliLHCData.h"
204 #include "ARVersion.h"
205 #include <RVersion.h>
206 #include <stdlib.h>
207 #include <unistd.h>
208 #include <sys/resource.h>
209 ClassImp(AliReconstruction)
210
211 using std::endl;
212
213 //_____________________________________________________________________________
214 const char* AliReconstruction::fgkStopEvFName = "_stopEvent_";
215 const char* AliReconstruction::fgkDetectorName[AliReconstruction::kNDetectors] = {"ITS", "TPC", "TRD",
216 "TOF", "PHOS", 
217 "HMPID", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "ACORDE","AD","FIT","MFT", "HLT"};
218
219 //_____________________________________________________________________________
220 AliReconstruction::AliReconstruction(const char* gAliceFilename) :
221   TSelector(),
222   fRunVertexFinder(kTRUE),
223   fRunVertexFinderTracks(kTRUE),
224   fRunMuonTracking(kFALSE),
225   fRunMFTTrackingMU(kFALSE),
226   fRunV0Finder(kTRUE),
227   fRunCascadeFinder(kTRUE),
228   fRunMultFinder(kTRUE),
229   fStopOnError(kTRUE),
230   fStopOnMissingTriggerFile(kTRUE),
231   fWriteAlignmentData(kFALSE),
232   fWriteESDfriend(kFALSE),
233   fFillTriggerESD(kTRUE),
234
235   fCleanESD(kTRUE),
236   fV0DCAmax(3.),
237   fV0CsPmin(0.),
238   fDmax(50.),
239   fZmax(50.),
240
241   fRunLocalReconstruction("ALL"),
242   fRunTracking("ALL"),
243   fFillESD("ALL"),
244   fDeleteRecPoints(""),
245   fDeleteDigits(""),
246   fLoadCDB(""),
247   fUseTrackingErrorsForAlignment(""),
248   fGAliceFileName(gAliceFilename),
249   fRawInput(""),
250   fESDOutput(""),
251   fProofOutputFileName(""),
252   fProofOutputLocation(""),
253   fProofOutputDataset(kFALSE),
254   fProofOutputArchive(""),
255   fEquipIdMap(""),
256   fFirstEvent(0),
257   fLastEvent(-1),
258   fNumberOfEventsPerFile((UInt_t)-1),
259   fFractionFriends(0.04),
260   fOptions(),
261   fLoadAlignFromCDB(kTRUE),
262   fLoadAlignData("ALL"),
263   fUseHLTData(),
264   fRunInfo(NULL),
265   fEventInfo(),
266   fRunScalers(NULL),
267   fCTPTimeParams(NULL),  
268   fCTPTimeAlign(NULL),  
269
270   fRunLoader(NULL),
271   fRawReader(NULL),
272   fParentRawReader(NULL),
273
274   fRecoParam(),
275
276   fSPDTrackleter(NULL),
277
278   fDiamondProfileSPD(NULL),
279   fDiamondProfile(NULL),
280   fDiamondProfileTPC(NULL),
281   fListOfCosmicTriggers(NULL),
282   
283   fGRPData(NULL),
284
285   fAlignObjArray(NULL),
286   fCDBUri(),
287   fQARefUri(),
288   fSpecCDBUri(), 
289   fCheckRecoCDBvsSimuCDB(),
290   fInitCDBCalled(kFALSE),
291   fCDBSnapshotMode(kFALSE),
292   fSetRunNumberFromDataCalled(kFALSE),
293   fQADetectors("ALL"), 
294   fQATasks("ALL"), 
295   fRunQA(kTRUE),  
296   fRunGlobalQA(kTRUE),
297   fSameQACycle(kFALSE),
298   fInitQACalled(kFALSE), 
299   fWriteQAExpertData(kTRUE), 
300   fRunPlaneEff(kFALSE),
301
302   fESDpid(NULL),
303
304   fesd(NULL),
305   fhltesd(NULL),
306   fesdf(NULL),
307   ffile(NULL),
308   ffileF(NULL),
309   ftree(NULL),
310   ftreeF(NULL),
311   fhlttree(NULL),
312   ftVertexer(NULL),
313   fIsNewRunLoader(kFALSE),
314   fRunAliEVE(kFALSE),
315   fChain(NULL),
316   fNall(0),
317   fNspecie(0),
318   fSspecie(0),
319   fNhighPt(0),
320   fShighPt(0),
321   //
322   fTreeBuffSize(30000000),
323   fMemCountESD(0),
324   fMemCountESDF(0),
325   fMemCountESDHLT(0),
326   //
327   fUpgradeModule(""),
328   fAnalysisMacro(),
329   fAnalysis(0),
330   fRecoHandler(0),
331   fDeclTriggerClasses(""),
332   fStopped(kFALSE),
333   fMaxRSS(0),
334   fMaxVMEM(0)
335 {
336 // create reconstruction object with default parameters
337   AliGeomManager::Destroy();
338   
339   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
340     fReconstructor[iDet] = NULL;
341     fUpgradeMask[iDet]=kFALSE;
342     fLoader[iDet] = NULL;
343     fTracker[iDet] = NULL;
344   }
345   for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
346     fQACycles[iDet] = 999999 ;
347     fQAWriteExpert[iDet] = kFALSE ; 
348   }
349   fBeamInt[0][0]=fBeamInt[0][1]=fBeamInt[1][0]=fBeamInt[1][1] = -1;
350   //
351   AddCheckRecoCDBvsSimuCDB("TPC/Calib/RecoParam"); // check for similarity in the sim and rec
352   //
353   AliPID pid;
354 }
355
356 //_____________________________________________________________________________
357 AliReconstruction::AliReconstruction(const AliReconstruction& rec) :
358   TSelector(),
359   fRunVertexFinder(rec.fRunVertexFinder),
360   fRunVertexFinderTracks(rec.fRunVertexFinderTracks),
361   fRunMuonTracking(rec.fRunMuonTracking),
362   fRunMFTTrackingMU(rec.fRunMFTTrackingMU),
363   fRunV0Finder(rec.fRunV0Finder),
364   fRunCascadeFinder(rec.fRunCascadeFinder),
365   fRunMultFinder(rec.fRunMultFinder),
366   fStopOnError(rec.fStopOnError),
367   fStopOnMissingTriggerFile(rec.fStopOnMissingTriggerFile),
368   fWriteAlignmentData(rec.fWriteAlignmentData),
369   fWriteESDfriend(rec.fWriteESDfriend),
370   fFillTriggerESD(rec.fFillTriggerESD),
371
372   fCleanESD(rec.fCleanESD),
373   fV0DCAmax(rec.fV0DCAmax),
374   fV0CsPmin(rec.fV0CsPmin),
375   fDmax(rec.fDmax),
376   fZmax(rec.fZmax),
377
378   fRunLocalReconstruction(rec.fRunLocalReconstruction),
379   fRunTracking(rec.fRunTracking),
380   fFillESD(rec.fFillESD),
381   fDeleteRecPoints(""),
382   fDeleteDigits(""),
383   fLoadCDB(rec.fLoadCDB),
384   fUseTrackingErrorsForAlignment(rec.fUseTrackingErrorsForAlignment),
385   fGAliceFileName(rec.fGAliceFileName),
386   fRawInput(rec.fRawInput),
387   fESDOutput(rec.fESDOutput),
388   fProofOutputFileName(rec.fProofOutputFileName),
389   fProofOutputLocation(rec.fProofOutputLocation),
390   fProofOutputDataset(rec.fProofOutputDataset),
391   fProofOutputArchive(rec.fProofOutputArchive),
392   fEquipIdMap(rec.fEquipIdMap),
393   fFirstEvent(rec.fFirstEvent),
394   fLastEvent(rec.fLastEvent),
395   fNumberOfEventsPerFile(rec.fNumberOfEventsPerFile),
396   fFractionFriends(rec.fFractionFriends),
397   fOptions(),
398   fLoadAlignFromCDB(rec.fLoadAlignFromCDB),
399   fLoadAlignData(rec.fLoadAlignData),
400   fUseHLTData(rec.fUseHLTData),
401   fRunInfo(NULL),
402   fEventInfo(),
403   fRunScalers(NULL),
404   fCTPTimeParams(NULL),
405   fCTPTimeAlign(NULL),
406
407   fRunLoader(NULL),
408   fRawReader(NULL),
409   fParentRawReader(NULL),
410
411   fRecoParam(rec.fRecoParam),
412
413   fSPDTrackleter(NULL),
414
415   fDiamondProfileSPD(rec.fDiamondProfileSPD),
416   fDiamondProfile(rec.fDiamondProfile),
417   fDiamondProfileTPC(rec.fDiamondProfileTPC),
418   fListOfCosmicTriggers(NULL),
419   
420   fGRPData(NULL),
421
422   fAlignObjArray(rec.fAlignObjArray),
423   fCDBUri(rec.fCDBUri),
424   fQARefUri(rec.fQARefUri),
425   fSpecCDBUri(), 
426   fCheckRecoCDBvsSimuCDB(),
427   fInitCDBCalled(rec.fInitCDBCalled),
428   fCDBSnapshotMode(rec.fCDBSnapshotMode),
429   fSetRunNumberFromDataCalled(rec.fSetRunNumberFromDataCalled),
430   fQADetectors(rec.fQADetectors), 
431   fQATasks(rec.fQATasks), 
432   fRunQA(rec.fRunQA),  
433   fRunGlobalQA(rec.fRunGlobalQA),
434   fSameQACycle(rec.fSameQACycle),
435   fInitQACalled(rec.fInitQACalled),
436   fWriteQAExpertData(rec.fWriteQAExpertData), 
437   fRunPlaneEff(rec.fRunPlaneEff),
438
439   fESDpid(NULL),
440
441   fesd(NULL),
442   fhltesd(NULL),
443   fesdf(NULL),
444   ffile(NULL),
445   ffileF(NULL),
446   ftree(NULL),
447   ftreeF(NULL),
448   fhlttree(NULL),
449   ftVertexer(NULL),
450   fIsNewRunLoader(rec.fIsNewRunLoader),
451   fRunAliEVE(kFALSE),
452   fChain(NULL),
453   fNall(0),
454   fNspecie(0),
455   fSspecie(0),
456   fNhighPt(0),
457   fShighPt(0),
458   //
459   fTreeBuffSize(rec.fTreeBuffSize),
460   fMemCountESD(0),
461   fMemCountESDF(0),
462   fMemCountESDHLT(0),
463   //
464   fUpgradeModule(""),
465   fAnalysisMacro(rec.fAnalysisMacro),
466   fAnalysis(0),
467   fRecoHandler(0),
468   fDeclTriggerClasses(rec.fDeclTriggerClasses),
469   fStopped(kFALSE),
470   fMaxRSS(0),
471   fMaxVMEM(0)
472 {
473 // copy constructor
474
475   for (Int_t i = 0; i < rec.fOptions.GetEntriesFast(); i++) {
476     if (rec.fOptions[i]) fOptions.Add(rec.fOptions[i]->Clone());
477   }
478   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
479     fReconstructor[iDet] = NULL;
480     fUpgradeMask[iDet] = kFALSE;
481     fLoader[iDet] = NULL;
482     fTracker[iDet] = NULL;
483   }  
484   
485   for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
486     fQACycles[iDet] = rec.fQACycles[iDet];
487     fQAWriteExpert[iDet] = rec.fQAWriteExpert[iDet] ; 
488   }
489
490   for (Int_t i = 0; i < rec.fSpecCDBUri.GetEntriesFast(); i++) {
491     if (rec.fSpecCDBUri[i]) fSpecCDBUri.Add(rec.fSpecCDBUri[i]->Clone());
492   }
493
494   for (Int_t i = 0; i < rec.fCheckRecoCDBvsSimuCDB.GetEntriesFast(); i++) {
495     if (rec.fCheckRecoCDBvsSimuCDB[i]) fCheckRecoCDBvsSimuCDB.AddLast(rec.fCheckRecoCDBvsSimuCDB[i]->Clone());
496   }
497
498   for (int i=2;i--;) for (int j=2;j--;) fBeamInt[i][j] = rec.fBeamInt[i][j];
499
500 }
501
502 //_____________________________________________________________________________
503 AliReconstruction& AliReconstruction::operator = (const AliReconstruction& rec)
504 {
505 // assignment operator
506 // Used in PROOF mode
507 // Be very careful while modifing it!
508 // Simple rules to follow:
509 // for persistent data members - use their assignment operators
510 // for non-persistent ones - do nothing or take the default values from constructor
511 // TSelector members should not be touched
512   if(&rec == this) return *this;
513
514   fRunVertexFinder       = rec.fRunVertexFinder;
515   fRunVertexFinderTracks = rec.fRunVertexFinderTracks;
516   fRunMuonTracking       = rec.fRunMuonTracking;
517   fRunMFTTrackingMU      = rec.fRunMFTTrackingMU;
518   fRunV0Finder           = rec.fRunV0Finder;
519   fRunCascadeFinder      = rec.fRunCascadeFinder;
520   fRunMultFinder         = rec.fRunMultFinder;
521   fStopOnError           = rec.fStopOnError;
522   fStopOnMissingTriggerFile = rec.fStopOnMissingTriggerFile;
523   fWriteAlignmentData    = rec.fWriteAlignmentData;
524   fWriteESDfriend        = rec.fWriteESDfriend;
525   fFillTriggerESD        = rec.fFillTriggerESD;
526
527   fCleanESD  = rec.fCleanESD;
528   fV0DCAmax  = rec.fV0DCAmax;
529   fV0CsPmin  = rec.fV0CsPmin;
530   fDmax      = rec.fDmax;
531   fZmax      = rec.fZmax;
532
533   fRunLocalReconstruction        = rec.fRunLocalReconstruction;
534   fRunTracking                   = rec.fRunTracking;
535   fFillESD                       = rec.fFillESD;
536   fDeleteRecPoints               = rec.fDeleteRecPoints;
537   fDeleteDigits                  = rec.fDeleteDigits;
538   fLoadCDB                       = rec.fLoadCDB;
539   fUseTrackingErrorsForAlignment = rec.fUseTrackingErrorsForAlignment;
540   fGAliceFileName                = rec.fGAliceFileName;
541   fRawInput                      = rec.fRawInput;
542   fESDOutput                     = rec.fESDOutput;
543   fProofOutputFileName           = rec.fProofOutputFileName;
544   fProofOutputLocation           = rec.fProofOutputLocation;
545   fProofOutputDataset            = rec.fProofOutputDataset;
546   fProofOutputArchive            = rec.fProofOutputArchive;
547   fEquipIdMap                    = rec.fEquipIdMap;
548   fFirstEvent                    = rec.fFirstEvent;
549   fLastEvent                     = rec.fLastEvent;
550   fNumberOfEventsPerFile         = rec.fNumberOfEventsPerFile;
551   fFractionFriends               = rec.fFractionFriends;
552
553   for (Int_t i = 0; i < rec.fOptions.GetEntriesFast(); i++) {
554     if (rec.fOptions[i]) fOptions.Add(rec.fOptions[i]->Clone());
555   }
556
557   fLoadAlignFromCDB              = rec.fLoadAlignFromCDB;
558   fLoadAlignData                 = rec.fLoadAlignData;
559   fUseHLTData                    = rec.fUseHLTData;
560
561   delete fRunInfo; fRunInfo = NULL;
562   if (rec.fRunInfo) fRunInfo = new AliRunInfo(*rec.fRunInfo);
563
564   fEventInfo                     = rec.fEventInfo;
565
566   delete fRunScalers; fRunScalers = NULL;
567   if (rec.fRunScalers) fRunScalers = new AliTriggerRunScalers(*rec.fRunScalers); 
568
569   delete fCTPTimeParams; fCTPTimeParams = NULL;
570   if (rec.fCTPTimeParams) fCTPTimeParams = new AliCTPTimeParams(*rec.fCTPTimeParams);
571   delete fCTPTimeAlign; fCTPTimeAlign = NULL;
572   if (rec.fCTPTimeAlign) fCTPTimeAlign = new AliCTPTimeParams(*rec.fCTPTimeAlign);
573
574   fRunLoader       = NULL;
575   fRawReader       = NULL;
576   fParentRawReader = NULL;
577
578   fRecoParam = rec.fRecoParam;
579
580   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
581     fUpgradeMask[iDet] = kFALSE;
582     delete fReconstructor[iDet]; fReconstructor[iDet] = NULL;
583     delete fLoader[iDet]; fLoader[iDet] = NULL;
584     delete fTracker[iDet]; fTracker[iDet] = NULL;
585   }
586   
587   for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
588     fQACycles[iDet] = rec.fQACycles[iDet];
589     fQAWriteExpert[iDet] = rec.fQAWriteExpert[iDet] ;
590   } 
591
592   delete fSPDTrackleter; fSPDTrackleter = NULL;
593     
594   delete fDiamondProfileSPD; fDiamondProfileSPD = NULL;
595   if (rec.fDiamondProfileSPD) fDiamondProfileSPD = new AliESDVertex(*rec.fDiamondProfileSPD);
596   delete fDiamondProfile; fDiamondProfile = NULL;
597   if (rec.fDiamondProfile) fDiamondProfile = new AliESDVertex(*rec.fDiamondProfile);
598   delete fDiamondProfileTPC; fDiamondProfileTPC = NULL;
599   if (rec.fDiamondProfileTPC) fDiamondProfileTPC = new AliESDVertex(*rec.fDiamondProfileTPC);
600
601   delete fListOfCosmicTriggers; fListOfCosmicTriggers = NULL;
602   if (rec.fListOfCosmicTriggers) fListOfCosmicTriggers = (THashTable*)((rec.fListOfCosmicTriggers)->Clone());
603
604   delete fGRPData; fGRPData = NULL;
605   //  if (rec.fGRPData) fGRPData = (TMap*)((rec.fGRPData)->Clone());
606   if (rec.fGRPData) fGRPData = (AliGRPObject*)((rec.fGRPData)->Clone());
607
608   delete fAlignObjArray; fAlignObjArray = NULL;
609
610   fCDBUri        = "";
611   fQARefUri      = rec.fQARefUri;
612   fSpecCDBUri.Delete();
613   fCheckRecoCDBvsSimuCDB.Delete();
614   //
615   for (Int_t i = 0; i < rec.fCheckRecoCDBvsSimuCDB.GetEntriesFast(); i++) {
616     if (rec.fCheckRecoCDBvsSimuCDB[i]) fCheckRecoCDBvsSimuCDB.AddLast(rec.fCheckRecoCDBvsSimuCDB[i]->Clone());
617   }
618   //
619   fInitCDBCalled               = rec.fInitCDBCalled;
620   fCDBSnapshotMode             = rec.fCDBSnapshotMode;
621   fSetRunNumberFromDataCalled  = rec.fSetRunNumberFromDataCalled;
622   fQADetectors                 = rec.fQADetectors;
623   fQATasks                     = rec.fQATasks; 
624   fRunQA                       = rec.fRunQA;  
625   fRunGlobalQA                 = rec.fRunGlobalQA;
626   fSameQACycle                 = rec.fSameQACycle;
627   fInitQACalled                = rec.fInitQACalled;
628   fWriteQAExpertData           = rec.fWriteQAExpertData;
629   fRunPlaneEff                 = rec.fRunPlaneEff;
630   for (int i=2;i--;) for (int j=2;j--;) fBeamInt[i][j] = rec.fBeamInt[i][j];
631   fESDpid  = NULL;
632   fesd     = NULL;
633   fhltesd  = NULL;
634   fesdf    = NULL;
635   ffile    = NULL;
636   ffileF   = NULL;
637   ftree    = NULL;
638   ftreeF   = NULL;
639   fhlttree = NULL;
640   ftVertexer = NULL;
641   fIsNewRunLoader = rec.fIsNewRunLoader;
642   fRunAliEVE = kFALSE;
643   fChain = NULL;
644   fNall = 0;
645   fNspecie = 0;
646   fSspecie = 0;
647   fNhighPt = 0;
648   fShighPt = 0;
649   //
650   fTreeBuffSize = rec.fTreeBuffSize;
651   fMemCountESD = 0;
652   fMemCountESDF = 0;
653   fMemCountESDHLT = 0;
654   //
655   fUpgradeModule="";
656   fAnalysisMacro = rec.fAnalysisMacro;
657   fAnalysis = 0;
658   fRecoHandler = 0;
659   fDeclTriggerClasses = rec.fDeclTriggerClasses;
660
661   return *this;
662 }
663
664 //_____________________________________________________________________________
665 AliReconstruction::~AliReconstruction()
666 {
667 // clean up
668
669   CleanUp();
670   if (fListOfCosmicTriggers) {
671     fListOfCosmicTriggers->Delete();
672     delete fListOfCosmicTriggers;
673   }
674   delete fGRPData;
675   delete fRunScalers;
676   delete fCTPTimeParams;
677   delete fCTPTimeAlign;
678   fOptions.Delete();
679   if (fAlignObjArray) {
680     fAlignObjArray->Delete();
681     delete fAlignObjArray;
682   }
683   fSpecCDBUri.Delete();
684   fCheckRecoCDBvsSimuCDB.Delete();
685   AliCodeTimer::Instance()->Print();
686 }
687
688 //_____________________________________________________________________________
689 void AliReconstruction::InitQA()
690 {
691   //Initialize the QA and start of cycle 
692   AliCodeTimerAuto("",0);
693   
694   if (fInitQACalled) return;
695   fInitQACalled = kTRUE;
696   
697   if (fGRPData) AliQADataMaker::SetCloningRequest( fGRPData->GetQATrigClasses(), fGRPData->GetQACloningRequest());
698
699
700   AliQAManager * qam = AliQAManager::QAManager(AliQAv1::kRECMODE) ; 
701   qam->SetSaveData(kTRUE); 
702   qam->SetCycleLength(AliQAv1::kITS, 5) ; 
703   if (fWriteQAExpertData)
704     qam->SetWriteExpert() ; 
705  
706   if (qam->IsDefaultStorageSet()) {
707     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
708     AliWarning("Default QA reference storage has been already set !");
709     AliWarning(Form("Ignoring the default storage declared in AliReconstruction: %s",fQARefUri.Data()));
710     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
711     fQARefUri = qam->GetDefaultStorage()->GetURI();
712   } else {
713     if (fQARefUri.Length() > 0) {
714         AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
715         AliDebug(2, Form("Default QA reference storage is set to: %s", fQARefUri.Data()));
716         AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
717       } else {
718         fQARefUri="local://$ALICE_ROOT/QAref";
719         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
720         AliWarning("Default QA refeference storage not yet set !!!!");
721         AliWarning(Form("Setting it now to: %s", fQARefUri.Data()));
722         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
723                 
724       }
725     qam->SetDefaultStorage(fQARefUri);
726   }
727   
728   if (fRunQA) {
729   qam->SetActiveDetectors(fQADetectors) ;
730   qam->SetActiveOnlineDetectors(fRunInfo->GetActiveDetectors());
731     
732   for (Int_t det = 0 ; det < AliQAv1::kNDET ; det++) {
733     qam->SetCycleLength(AliQAv1::DETECTORINDEX_t(det), fQACycles[det]) ;  
734     qam->SetWriteExpert(AliQAv1::DETECTORINDEX_t(det)) ;
735   }
736   if (!fRawReader && !fInput && IsInTasks(AliQAv1::kRAWS))
737     fQATasks.ReplaceAll(Form("%d",AliQAv1::kRAWS), "") ;
738   qam->SetTasks(fQATasks) ; 
739   qam->InitQADataMaker(AliCDBManager::Instance()->GetRun()) ; 
740   }
741   if (fRunGlobalQA) {
742     Bool_t sameCycle = kFALSE ;
743     AliQADataMaker *qadm = qam->GetQADataMaker(AliQAv1::kGLOBAL);
744     AliInfo(Form("Initializing the global QA data maker"));
745     if (IsInTasks(AliQAv1::kRECPOINTS)) {
746       qadm->StartOfCycle(AliQAv1::kRECPOINTS, AliCDBManager::Instance()->GetRun(), sameCycle) ; 
747       TObjArray **arr=qadm->Init(AliQAv1::kRECPOINTS);
748       AliTracker::SetResidualsArray(arr);
749       sameCycle = kTRUE ; 
750     }
751     if (IsInTasks(AliQAv1::kESDS)) {
752       qadm->StartOfCycle(AliQAv1::kESDS, AliCDBManager::Instance()->GetRun(), sameCycle) ; 
753       qadm->Init(AliQAv1::kESDS);
754     }
755   }
756     AliSysInfo::AddStamp("InitQA") ; 
757 }
758
759 //_____________________________________________________________________________
760 void AliReconstruction::MergeQA(const char *fileName)
761 {
762   //Initialize the QA and start of cycle 
763   AliCodeTimerAuto("",0) ;
764   AliQAManager::QAManager()->Merge(AliCDBManager::Instance()->GetRun(),fileName) ; 
765   AliSysInfo::AddStamp("MergeQA") ; 
766 }
767   
768 //_____________________________________________________________________________
769 void AliReconstruction::InitCDB()
770 {
771 // activate a default CDB storage
772 // First check if we have any CDB storage set, because it is used 
773 // to retrieve the calibration and alignment constants
774   AliCodeTimerAuto("",0);
775
776   if (fInitCDBCalled) return;
777   fInitCDBCalled = kTRUE;
778
779   AliCDBManager* man = AliCDBManager::Instance();
780   if (man->IsDefaultStorageSet())
781   {
782     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
783     AliWarning("Default CDB storage has been already set !");
784     AliWarning(Form("Ignoring the default storage declared in AliReconstruction: %s",fCDBUri.Data()));
785     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
786     fCDBUri = man->GetDefaultStorage()->GetURI();
787   }
788   else {
789     if (fCDBUri.Length() > 0) 
790     {
791         AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
792         AliDebug(2, Form("Default CDB storage is set to: %s", fCDBUri.Data()));
793         AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
794         man->SetDefaultStorage(fCDBUri);
795     } 
796     else if (!man->GetRaw()){
797         fCDBUri="local://$ALICE_ROOT/OCDB";
798         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
799         AliWarning("Default CDB storage not yet set !!!!");
800         AliWarning(Form("Setting it now to: %s", fCDBUri.Data()));
801         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
802         man->SetDefaultStorage(fCDBUri);
803     }
804     else {    
805         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
806         AliWarning("Default storage will be set after setting the Run Number!!!");
807         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");                    
808     }
809   }
810
811   // Now activate the detector specific CDB storage locations
812   for (Int_t i = 0; i < fSpecCDBUri.GetEntriesFast(); i++) {
813     TObject* obj = fSpecCDBUri[i];
814     if (!obj) continue;
815     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
816     AliDebug(2, Form("Specific CDB storage for %s is set to: %s",obj->GetName(),obj->GetTitle()));
817     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
818     man->SetSpecificStorage(obj->GetName(), obj->GetTitle());
819   }
820   AliSysInfo::AddStamp("InitCDB");
821 }
822
823 //_____________________________________________________________________________
824 void AliReconstruction::SetCDBSnapshotMode(const char* snapshotFileName) {
825     if (!AliCDBManager::Instance()->SetSnapshotMode(snapshotFileName))
826       AliFatal("Setting CDB snapshot mode failed.");
827     fCDBSnapshotMode = kTRUE;
828 }
829
830 //_____________________________________________________________________________
831 void AliReconstruction::SetDefaultStorage(const char* uri) {
832 // Store the desired default CDB storage location
833 // Activate it later within the Run() method
834
835   fCDBUri = uri;
836
837 }
838
839 //_____________________________________________________________________________
840 void AliReconstruction::SetQARefDefaultStorage(const char* uri) {
841   // Store the desired default CDB storage location
842   // Activate it later within the Run() method
843   
844   fQARefUri = uri;
845   AliQAv1::SetQARefStorage(fQARefUri.Data()) ;
846   
847 }
848
849 //_____________________________________________________________________________
850 void AliReconstruction::SetSpecificStorage(const char* calibType, const char* uri) {
851 // Store a detector-specific CDB storage location
852 // Activate it later within the Run() method
853
854   AliCDBPath aPath(calibType);
855   if(!aPath.IsValid()){
856         // if calibType is not wildcard but it is a valid detector, add "/*" to make it a valid path
857         for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
858                 if(!strcmp(calibType, fgkDetectorName[iDet])) {
859                         aPath.SetPath(Form("%s/*", calibType));
860                         AliInfo(Form("Path for specific storage set to %s", aPath.GetPath().Data()));
861                         break;
862                 }
863         }
864         if(!aPath.IsValid()){
865                 AliError(Form("Not a valid path or detector: %s", calibType));
866                 return;
867         }
868   }
869
870 //  // check that calibType refers to a "valid" detector name
871 //  Bool_t isDetector = kFALSE;
872 //  for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
873 //    TString detName = fgkDetectorName[iDet];
874 //    if(aPath.GetLevel0() == detName) {
875 //      isDetector = kTRUE;
876 //      break;
877 //    }
878 //  }
879 //
880 //  if(!isDetector) {
881 //      AliError(Form("Not a valid detector: %s", aPath.GetLevel0().Data()));
882 //      return;
883 //  }
884
885   TObject* obj = fSpecCDBUri.FindObject(aPath.GetPath().Data());
886   if (obj) fSpecCDBUri.Remove(obj);
887   fSpecCDBUri.Add(new TNamed(aPath.GetPath().Data(), uri));
888
889 }
890
891 //_____________________________________________________________________________
892 void AliReconstruction::AddCheckRecoCDBvsSimuCDB(const char* cdbpath,const char* comment) 
893 {
894   // require the cdb item to be the same in the rec as in the sim
895   // Activate it later within the Run() method
896   TString newent = cdbpath;
897   if (newent.IsNull()) return;
898   TIter nextit(&fCheckRecoCDBvsSimuCDB);
899   TNamed* cdbent=0;
900   while ((cdbent=(TNamed*)nextit())) {
901     TString str = cdbent->GetName();
902     if (str==newent) {
903       AliInfo(Form("%s is already in the list to check",cdbpath));
904       return;
905     }
906   }
907   fCheckRecoCDBvsSimuCDB.AddLast(new TNamed(cdbpath,comment));
908   //
909 }
910
911 //_____________________________________________________________________________
912 void AliReconstruction::RemCheckRecoCDBvsSimuCDB(const char* cdbpath) 
913 {
914   // require the cdb item to be the same in the rec as in the sim
915   // Activate it later within the Run() method
916   TString newent = cdbpath;
917   if (newent.IsNull()) return;
918   TIter nextit(&fCheckRecoCDBvsSimuCDB);
919   TNamed* cdbent=0;
920   while ((cdbent=(TNamed*)nextit())) {
921     TString str = cdbent->GetName();
922     if (str==newent) {
923       AliInfo(Form("Removing %s from the list to check",cdbpath));
924       delete fCheckRecoCDBvsSimuCDB.Remove(cdbent);
925       fCheckRecoCDBvsSimuCDB.Compress();
926       return;
927     }
928   }
929   AliInfo(Form("%s is not in the list to check",cdbpath));
930   //
931 }
932
933 //_____________________________________________________________________________
934 Bool_t AliReconstruction::SetRunNumberFromData()
935 {
936   // The method is called in Run() in order
937   // to set a correct run number.
938   // In case of raw data reconstruction the
939   // run number is taken from the raw data header
940
941   if (fSetRunNumberFromDataCalled) return kTRUE;
942   fSetRunNumberFromDataCalled = kTRUE;
943   
944   AliCDBManager* man = AliCDBManager::Instance();
945  
946   if(fRawReader) {
947     if(fRawReader->NextEvent()) {
948       if(man->GetRun() > 0) {
949         AliWarning("Run number is taken from raw-event header! Ignoring settings in AliCDBManager!");
950       } 
951       man->SetRun(fRawReader->GetRunNumber());
952       GetEventInfo();
953       fRawReader->RewindEvents();
954     }
955     else {
956       if(man->GetRun() > 0) {
957         AliWarning("No raw-data events are found ! Using settings in AliCDBManager !");
958       }
959       else {
960         AliWarning("Neither raw events nor settings in AliCDBManager are found !");
961         return kFALSE;
962       }
963     }
964   }
965   else {
966     AliRunLoader *rl = AliRunLoader::Open(fGAliceFileName.Data());
967     if (!rl) {
968       AliError(Form("No run loader found in file %s", fGAliceFileName.Data()));
969       return kFALSE;
970     }
971     else {
972       rl->LoadHeader();
973       // read run number from gAlice
974       if(rl->GetHeader()) {
975         man->SetRun(rl->GetHeader()->GetRun());
976         rl->UnloadHeader();
977         delete rl;
978       }
979       else {
980         AliError("Neither run-loader header nor RawReader objects are found !");
981         delete rl;
982         return kFALSE;
983       }
984     }
985   }
986
987   man->Print();  
988   
989   return kTRUE;
990 }
991
992 //_____________________________________________________________________________
993 void AliReconstruction::SetCDBLock() {
994   // Set CDB lock: from now on it is forbidden to reset the run number
995   // or the default storage or to activate any further storage!
996   
997   AliCDBManager::Instance()->SetLock(1);
998 }
999
1000 //_____________________________________________________________________________
1001 void AliReconstruction::MatchUpgradeDetector() {
1002   // Translates detector name in a boolean.
1003   // The boolean is used in GetReconstructor to load the 
1004   // upgrade reconstructor instead of the standard one.
1005    for(Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1006     if(fUpgradeModule.Contains(fgkDetectorName[iDet])) fUpgradeMask[iDet]=kTRUE;
1007    }
1008 }
1009 //_____________________________________________________________________________
1010 Bool_t AliReconstruction::MisalignGeometry(const TString& detectors)
1011 {
1012   // Read the alignment objects from CDB.
1013   // Each detector is supposed to have the
1014   // alignment objects in DET/Align/Data CDB path.
1015   // All the detector objects are then collected,
1016   // sorted by geometry level (starting from ALIC) and
1017   // then applied to the TGeo geometry.
1018   // Finally an overlaps check is performed.
1019
1020   // Load alignment data from CDB and fill fAlignObjArray 
1021   if(fLoadAlignFromCDB){
1022         
1023     TString detStr = detectors;
1024     TString loadAlObjsListOfDets = "";
1025     
1026     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1027       if(!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1028       if(!strcmp(fgkDetectorName[iDet],"HLT")) continue;
1029       
1030       if(AliGeomManager::GetNalignable(fgkDetectorName[iDet]) != 0)
1031       {
1032         loadAlObjsListOfDets += fgkDetectorName[iDet];
1033         loadAlObjsListOfDets += " ";
1034       }
1035     } // end loop over detectors
1036     
1037     if(AliGeomManager::GetNalignable("GRP") != 0)
1038       loadAlObjsListOfDets.Prepend("GRP "); //add alignment objects for non-sensitive modules
1039     AliGeomManager::ApplyAlignObjsFromCDB(loadAlObjsListOfDets.Data());
1040   }else{
1041     // Check if the array with alignment objects was
1042     // provided by the user. If yes, apply the objects
1043     // to the present TGeo geometry
1044     if (fAlignObjArray) {
1045       if (gGeoManager && gGeoManager->IsClosed()) {
1046         if (AliGeomManager::ApplyAlignObjsToGeom(*fAlignObjArray) == kFALSE) {
1047           AliError("The misalignment of one or more volumes failed!"
1048                    "Compare the list of simulated detectors and the list of detector alignment data!");
1049           return kFALSE;
1050         }
1051       }
1052       else {
1053         AliError("Can't apply the misalignment! gGeoManager doesn't exist or it is still opened!");
1054         return kFALSE;
1055       }
1056     }
1057   }
1058   
1059   if (fAlignObjArray) {
1060     fAlignObjArray->Delete();
1061     delete fAlignObjArray; fAlignObjArray=NULL;
1062   }
1063
1064   return kTRUE;
1065 }
1066
1067 //_____________________________________________________________________________
1068 void AliReconstruction::SetGAliceFile(const char* fileName)
1069 {
1070 // set the name of the galice file
1071
1072   fGAliceFileName = fileName;
1073 }
1074
1075 //_____________________________________________________________________________
1076 void AliReconstruction::SetInput(const char* input) 
1077 {
1078   // In case the input string starts with 'mem://', we run in an online mode
1079   // and AliRawReaderDateOnline object is created. In all other cases a raw-data
1080   // file is assumed. One can give as an input:
1081   // mem://: - events taken from DAQ monitoring libs online
1082   //  or
1083   // mem://<filename> - emulation of the above mode (via DATE monitoring libs)
1084   if (input) fRawInput = input;
1085 }
1086
1087 //_____________________________________________________________________________
1088 void AliReconstruction::SetOutput(const char* output) 
1089 {
1090   // Set the output ESD filename
1091   // 'output' is a normalt ROOT url
1092   // The method is used in case of raw-data reco with PROOF
1093   if (output) fESDOutput = output;
1094 }
1095
1096 //_____________________________________________________________________________
1097 void AliReconstruction::SetOption(const char* detector, const char* option)
1098 {
1099 // set options for the reconstruction of a detector
1100
1101   TObject* obj = fOptions.FindObject(detector);
1102   if (obj) fOptions.Remove(obj);
1103   fOptions.Add(new TNamed(detector, option));
1104 }
1105
1106 //_____________________________________________________________________________
1107 void AliReconstruction::SetRecoParam(const char* detector, AliDetectorRecoParam *par)
1108 {
1109   // Set custom reconstruction parameters for a given detector
1110   // Single set of parameters for all the events
1111
1112   // First check if the reco-params are global
1113   if(!strcmp(detector, "GRP")) {
1114     par->SetAsDefault();
1115     fRecoParam.AddDetRecoParam(kNDetectors,par);
1116     return;
1117   }
1118
1119   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1120     if(!strcmp(detector, fgkDetectorName[iDet])) {
1121       par->SetAsDefault();
1122       fRecoParam.AddDetRecoParam(iDet,par);
1123       break;
1124     }
1125   }
1126
1127 }
1128
1129 //_____________________________________________________________________________
1130 Bool_t AliReconstruction::InitGRP() {
1131   //------------------------------------
1132   // Initialization of the GRP entry 
1133   //------------------------------------
1134   AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/GRP/Data");
1135
1136   if (entry) {
1137
1138     TMap* m = dynamic_cast<TMap*>(entry->GetObject());  // old GRP entry
1139
1140     if (m) {
1141        AliInfo("Found a TMap in GRP/GRP/Data, converting it into an AliGRPObject");
1142        m->Print();
1143        fGRPData = new AliGRPObject();
1144        fGRPData->ReadValuesFromMap(m);
1145     }
1146
1147     else {
1148        AliInfo("Found an AliGRPObject in GRP/GRP/Data, reading it");
1149        fGRPData = dynamic_cast<AliGRPObject*>(entry->GetObject());  // new GRP entry
1150        entry->SetOwner(0);
1151     }
1152
1153     //    FIX ME: The unloading of GRP entry is temporarily disabled
1154     //    because ZDC and VZERO are using it in order to initialize
1155     //    their reconstructor objects. In the future one has to think
1156     //    of propagating AliRunInfo to the reconstructors.
1157     //    AliCDBManager::Instance()->UnloadFromCache("GRP/GRP/Data");
1158   }
1159
1160   if (!fGRPData) {
1161      AliError("No GRP entry found in OCDB!");
1162      return kFALSE;
1163   }
1164
1165   TString lhcState = fGRPData->GetLHCState();
1166   if (lhcState==AliGRPObject::GetInvalidString()) {
1167     AliError("GRP/GRP/Data entry:  missing value for the LHC state ! Using UNKNOWN");
1168     lhcState = "UNKNOWN";
1169   }
1170
1171   TString beamType = fGRPData->GetBeamType();
1172   if (beamType==AliGRPObject::GetInvalidString()) {
1173     AliError("GRP/GRP/Data entry:  missing value for the beam type ! Using UNKNOWN");
1174     beamType = "UNKNOWN";
1175   }
1176
1177   Float_t beamEnergy = fGRPData->GetBeamEnergy();
1178   if (beamEnergy==AliGRPObject::GetInvalidFloat()) {
1179     AliError("GRP/GRP/Data entry:  missing value for the beam energy ! Using 0");
1180     beamEnergy = 0;
1181   }
1182
1183   TString runType = fGRPData->GetRunType();
1184   if (runType==AliGRPObject::GetInvalidString()) {
1185     AliError("GRP/GRP/Data entry:  missing value for the run type ! Using UNKNOWN");
1186     runType = "UNKNOWN";
1187   }
1188
1189   Int_t activeDetectors = fGRPData->GetDetectorMask();
1190   if (activeDetectors==AliGRPObject::GetInvalidUInt()) {
1191     AliError("GRP/GRP/Data entry:  missing value for the detector mask ! Using 1074790399");
1192     activeDetectors = 1074790399;
1193   }
1194   AliDebug(1, Form("activeDetectors = %d", activeDetectors));
1195
1196   fRunInfo = new AliRunInfo(lhcState, beamType, beamEnergy, runType, activeDetectors);
1197   fRunInfo->Dump();
1198
1199
1200   // Process the list of active detectors
1201   if (activeDetectors) {
1202     UInt_t detMask = activeDetectors;
1203     AliDebug(1, Form("Detector List = %s", fRunLocalReconstruction.Data()));
1204     fRunLocalReconstruction = MatchDetectorList(fRunLocalReconstruction,detMask);
1205     AliDebug(1, Form("Detector List = %s", fRunLocalReconstruction.Data()));
1206     fRunTracking = MatchDetectorList(fRunTracking,detMask);
1207     fFillESD = MatchDetectorList(fFillESD,detMask);
1208     fQADetectors = MatchDetectorList(fQADetectors,detMask);
1209     AliInfo(Form("fQADetectors=%s",fQADetectors.Data()));
1210     fDeleteRecPoints = MatchDetectorList(fDeleteRecPoints,detMask);
1211     fDeleteDigits    = MatchDetectorList(fDeleteDigits,detMask);
1212     fLoadCDB.Form("%s %s %s %s",
1213                   fRunLocalReconstruction.Data(),
1214                   fRunTracking.Data(),
1215                   fFillESD.Data(),
1216                   fQADetectors.Data());
1217     fLoadCDB = MatchDetectorList(fLoadCDB,detMask);
1218     if (!((detMask >> AliDAQ::DetectorID("ITSSPD")) & 0x1) &&
1219         !((detMask >> AliDAQ::DetectorID("ITSSDD")) & 0x1) &&
1220         !((detMask >> AliDAQ::DetectorID("ITSSSD")) & 0x1) ) {
1221       // switch off the vertexer
1222       AliInfo("SPD,SDD,SSD is not in the list of active detectors. Vertexer and Trackleter are switched off.");
1223       fRunVertexFinder = kFALSE;
1224       fRunMultFinder = kFALSE;
1225     }
1226     if (!((detMask >> AliDAQ::DetectorID("TRG")) & 0x1)) {
1227       // switch off the reading of CTP raw-data payload
1228       if (fFillTriggerESD) {
1229         AliInfo("CTP is not in the list of active detectors. CTP data reading switched off.");
1230         fFillTriggerESD = kFALSE;
1231       }
1232     }
1233   }
1234
1235   AliInfo("===================================================================================");
1236   AliInfo(Form("Running local reconstruction for detectors: %s",fRunLocalReconstruction.Data()));
1237   AliInfo(Form("Running tracking for detectors: %s",fRunTracking.Data()));
1238   AliInfo(Form("Filling ESD for detectors: %s",fFillESD.Data()));
1239   AliInfo(Form("Quality assurance is active for detectors: %s",fQADetectors.Data()));
1240   AliInfo(Form("CDB and reconstruction parameters are loaded for detectors: %s",fLoadCDB.Data()));
1241   AliInfo("===================================================================================");
1242
1243   //*** Dealing with the magnetic field map
1244   if ( TGeoGlobalMagField::Instance()->IsLocked() ) {
1245     if (TGeoGlobalMagField::Instance()->GetField()->TestBit(AliMagF::kOverrideGRP)) {
1246       AliInfo("ExpertMode!!! GRP information will be ignored !");
1247       AliInfo("ExpertMode!!! Running with the externally locked B field !");
1248     }
1249     else {
1250       AliInfo("Destroying existing B field instance!");
1251       delete TGeoGlobalMagField::Instance();
1252     }    
1253   }
1254   if ( !TGeoGlobalMagField::Instance()->IsLocked() ) {
1255     // Construct the field map out of the information retrieved from GRP.
1256     Bool_t ok = kTRUE;
1257     // L3
1258     Float_t l3Current = fGRPData->GetL3Current((AliGRPObject::Stats)0);
1259     if (l3Current == AliGRPObject::GetInvalidFloat()) {
1260       AliError("GRP/GRP/Data entry:  missing value for the L3 current !");
1261       ok = kFALSE;
1262     }
1263     
1264     Char_t l3Polarity = fGRPData->GetL3Polarity();
1265     if (l3Polarity == AliGRPObject::GetInvalidChar()) {
1266       AliError("GRP/GRP/Data entry:  missing value for the L3 polarity !");
1267       ok = kFALSE;
1268     }
1269
1270     // Dipole
1271     Float_t diCurrent = fGRPData->GetDipoleCurrent((AliGRPObject::Stats)0);
1272     if (diCurrent == AliGRPObject::GetInvalidFloat()) {
1273       AliError("GRP/GRP/Data entry:  missing value for the dipole current !");
1274       ok = kFALSE;
1275     }
1276
1277     Char_t diPolarity = fGRPData->GetDipolePolarity();
1278     if (diPolarity == AliGRPObject::GetInvalidChar()) {
1279       AliError("GRP/GRP/Data entry:  missing value for the dipole polarity !");
1280       ok = kFALSE;
1281     }
1282
1283     // read special bits for the polarity convention and map type
1284     Int_t  polConvention = fGRPData->IsPolarityConventionLHC() ? AliMagF::kConvLHC : AliMagF::kConvDCS2008;
1285     Bool_t uniformB = fGRPData->IsUniformBMap();
1286
1287     if (ok) { 
1288       AliMagF* fld = AliMagF::CreateFieldMap(TMath::Abs(l3Current) * (l3Polarity ? -1:1), 
1289                                              TMath::Abs(diCurrent) * (diPolarity ? -1:1), 
1290                                              polConvention,uniformB,beamEnergy, beamType.Data());
1291       if (fld) {
1292         TGeoGlobalMagField::Instance()->SetField( fld );
1293         TGeoGlobalMagField::Instance()->Lock();
1294         AliInfo("Running with the B field constructed out of GRP !");
1295       }
1296       else AliFatal("Failed to create a B field map !");
1297     }
1298     else AliFatal("B field is neither set nor constructed from GRP ! Exitig...");
1299   }
1300   
1301   //*** Get the diamond profiles from OCDB
1302   entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexSPD");
1303   if (entry) {
1304     fDiamondProfileSPD = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1305   } else {
1306      AliError("No SPD diamond profile found in OCDB!");
1307   }
1308
1309   entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertex");
1310   if (entry) {
1311     fDiamondProfile = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1312   } else {
1313      AliError("No diamond profile found in OCDB!");
1314   }
1315
1316   entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexTPC");
1317   if (entry) {
1318     fDiamondProfileTPC = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1319   } else {
1320      AliError("No TPC diamond profile found in OCDB!");
1321   }
1322
1323   entry = AliCDBManager::Instance()->Get("GRP/Calib/CosmicTriggers");
1324   if (entry) {
1325     fListOfCosmicTriggers = dynamic_cast<THashTable*>(entry->GetObject());
1326     entry->SetOwner(0);
1327   }
1328
1329   if (!fListOfCosmicTriggers) {
1330     AliWarning("Can not get list of cosmic triggers from OCDB! Cosmic event specie will be effectively disabled!");
1331   }
1332
1333   return kTRUE;
1334
1335
1336 //_____________________________________________________________________________
1337 Bool_t AliReconstruction::LoadCDB()
1338 {
1339   // Load CDB entries for all active detectors.
1340   // By default we load all the entries in <det>/Calib
1341   // folder.
1342
1343   AliCodeTimerAuto("",0);
1344
1345   AliCDBManager::Instance()->Get("GRP/CTP/Config");
1346
1347   AliCDBManager::Instance()->Get("GRP/Calib/LHCClockPhase");
1348
1349   TString detStr = fLoadCDB;
1350   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1351     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1352     AliCDBManager::Instance()->GetAll(Form("%s/Calib/*",fgkDetectorName[iDet]));
1353     AliCDBManager::Instance()->GetAll(Form("%s/Trigger/*",fgkDetectorName[iDet]));
1354   }
1355
1356   // Temporary fix - one has to define the correct policy in order
1357   // to load the trigger OCDB entries only for the detectors that
1358   // in the trigger or that are needed in order to put correct
1359   // information in ESD
1360   AliCDBManager::Instance()->GetAll("TRIGGER/*/*");
1361   AliCDBManager::Instance()->GetAll("HLT/*/*");
1362
1363   return kTRUE;
1364 }
1365 //_____________________________________________________________________________
1366 Bool_t AliReconstruction::LoadTriggerScalersCDB()
1367 {
1368   // Load CTP scalers from OCDB.
1369   // The scalers are checked for consistency.
1370
1371   AliCodeTimerAuto("",0);
1372
1373   AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/CTP/Scalers");
1374
1375   if (entry) { 
1376    
1377        AliInfo("Found an AliTriggerRunScalers in GRP/CTP/Scalers, reading it");
1378        fRunScalers = dynamic_cast<AliTriggerRunScalers*> (entry->GetObject());
1379        entry->SetOwner(0);
1380        if (fRunScalers && (fRunScalers->CorrectScalersOverflow() == 0)) AliInfo("32bit Trigger counters corrected for overflow");
1381
1382   }
1383   return kTRUE;
1384 }
1385 //_____________________________________________________________________________
1386 Bool_t AliReconstruction::LoadCTPTimeParamsCDB()
1387 {
1388   // Load CTP timing information (alignment)
1389   // from OCDB.
1390
1391   AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/CTP/CTPtiming");
1392   if (!entry) return kFALSE;
1393
1394   AliInfo("Found an AliCTPTimeParams in GRP/CTP/CTPtiming, reading it");
1395   fCTPTimeParams = dynamic_cast<AliCTPTimeParams*> (entry->GetObject());
1396   entry->SetOwner(0);
1397
1398   AliCDBEntry* entry2 = AliCDBManager::Instance()->Get("GRP/CTP/TimeAlign");
1399   if (!entry2) return kFALSE;
1400
1401   AliInfo("Found an AliCTPTimeParams in GRP/CTP/TimeAlign, reading it");
1402   fCTPTimeAlign = dynamic_cast<AliCTPTimeParams*> (entry2->GetObject());
1403   entry2->SetOwner(0);
1404
1405   return kTRUE;
1406 }
1407
1408 //_____________________________________________________________________________
1409 Bool_t AliReconstruction::ReadIntensityInfoCDB()
1410 {
1411   // Load LHC DIP data
1412   AliCDBEntry* entry    = AliCDBManager::Instance()->Get("GRP/GRP/LHCData");
1413   AliCDBEntry* entryCTP = AliCDBManager::Instance()->Get("GRP/CTP/Config");
1414   //
1415   if (!entry || !entryCTP) {
1416     AliError(Form("Failed to extract CDB objects GRP/GRP/LHCData: %p or GRP/CTP/Config: %p",entry,entryCTP));
1417     return kFALSE;
1418   }
1419   // extract BC masks
1420   enum {kA,kB,kC,kE,kNMasks};
1421   AliTriggerConfiguration* conf = (AliTriggerConfiguration*)entryCTP->GetObject();
1422   const TObjArray& clArr = conf->GetClasses();
1423   TObjArray masks(kNMasks);
1424   TIter next(&clArr);
1425   AliTriggerClass* trClass = 0;
1426   int nFound = 0;
1427   masks.SetOwner(kFALSE);
1428   //
1429   while ( (trClass=(AliTriggerClass*)next()) ) {
1430     TString trName = trClass->GetName();
1431     int ind = trName.Index("-"); // prefix in front of A,B,C,E
1432     if (ind<1) continue;   // anomaly
1433     //
1434     trName = trName.Data() + ind;
1435     AliTriggerBCMask* bcMask = trClass->GetBCMask();
1436     if (!bcMask) continue;
1437     UInt_t which = 0;
1438     if      (trName.BeginsWith("-A-"))  which |= 0x1<<kA;
1439     else if (trName.BeginsWith("-B-"))  which |= 0x1<<kB;
1440     else if (trName.BeginsWith("-C-"))  which |= 0x1<<kC;
1441     else if (trName.BeginsWith("-E-"))  which |= 0x1<<kE;
1442     else if (trName.BeginsWith("-AC-")) which |= (0x1<<kA) | (0x1<<kC);
1443     else if (trName.BeginsWith("-CA-")) which |= (0x1<<kA) | (0x1<<kC);
1444     else { AliWarning(Form("Unknown trigger type %s\n",trClass->GetName())); continue;}
1445     //
1446     for (int ip=kNMasks;ip--;) {
1447       if ( !(which&(0x1<<ip)) || masks[ip] ) continue; // does not match or already done
1448       masks[ip] = (TObject*)bcMask;
1449       nFound++;
1450     }
1451     if (nFound==kNMasks) break;
1452   }  
1453   //  
1454   AliInfo("Reading mean bunch intensities from GRP/GRP/LHCData");
1455   AliLHCData* dipData = dynamic_cast<AliLHCData*> (entry->GetObject());
1456   //
1457   for (int ib=2;ib--;) {
1458     double intI,intNI;
1459     if (dipData && (dipData->GetMeanIntensity(ib,intI,intNI,&masks)>=0)) {
1460       fBeamInt[ib][0] = intI;
1461       fBeamInt[ib][1] = intNI;  
1462       AliInfo(Form("Mean intensity for beam %d: Interacting:%.2e Non-Interacting:%.2e",ib,intI,intNI));
1463     }
1464   }
1465   return kTRUE;
1466   //
1467 }
1468
1469
1470 //_____________________________________________________________________________
1471 Bool_t AliReconstruction::Run(const char* input)
1472 {
1473   // Run Run Run
1474   AliCodeTimerAuto("",0);
1475
1476   InitRun(input);
1477   if (GetAbort() != TSelector::kContinue) return kFALSE;
1478
1479   TChain *chain = NULL;
1480   if (fRawReader && (chain = fRawReader->GetChain())) {
1481     Long64_t nEntries = (fLastEvent < 0) ? (TChain::kBigNumber) : (fLastEvent - fFirstEvent + 1);
1482     // Proof mode
1483     if (gProof) {
1484       // Temporary fix for long raw-data runs (until socket timeout handling in PROOF is revised)
1485       gProof->Exec("gEnv->SetValue(\"Proof.SocketActivityTimeout\",-1)", kTRUE);
1486
1487       if (gGrid)
1488         gProof->Exec("TGrid::Connect(\"alien://\")",kTRUE);
1489
1490       TMessage::EnableSchemaEvolutionForAll(kTRUE);
1491       gProof->Exec("TMessage::EnableSchemaEvolutionForAll(kTRUE)",kTRUE);
1492
1493       gProof->AddInput(this);
1494
1495       if (!ParseOutput()) return kFALSE;
1496
1497       gProof->SetParameter("PROOF_MaxSlavesPerNode", 9999);
1498       chain->SetProof();
1499       chain->Process("AliReconstruction","",nEntries,fFirstEvent);
1500     }
1501     else {
1502       chain->Process(this,"",nEntries,fFirstEvent);
1503     }
1504   }
1505   else {
1506     Begin(NULL);
1507     if (GetAbort() != TSelector::kContinue) return kFALSE;
1508     SlaveBegin(NULL);
1509     if (GetAbort() != TSelector::kContinue) return kFALSE;
1510     //******* The loop over events
1511     AliInfo("Starting looping over events");
1512     Int_t iEvent = 0;
1513     while ((iEvent < fRunLoader->GetNumberOfEvents()) ||
1514            (fRawReader && fRawReader->NextEvent())) {
1515       //
1516       // check if process has enough resources 
1517       if (!HasEnoughResources(iEvent)) break;
1518       if (!ProcessEvent(iEvent)) {
1519         Abort("ProcessEvent",TSelector::kAbortFile);
1520         return kFALSE;
1521       }
1522       CleanProcessedEvent();
1523       iEvent++;
1524     }
1525     if (!iEvent) AliWarning("No events passed trigger selection");
1526     SlaveTerminate();
1527     if (GetAbort() != TSelector::kContinue) return kFALSE;
1528     Terminate();
1529     if (GetAbort() != TSelector::kContinue) return kFALSE;
1530   }
1531
1532   return kTRUE;
1533 }
1534
1535 //_____________________________________________________________________________
1536 void AliReconstruction::InitRawReader(const char* input)
1537 {
1538   // Init raw-reader and
1539   // set the input in case of raw data
1540
1541   AliCodeTimerAuto("",0);
1542
1543   if (input) fRawInput = input;
1544   fRawReader = AliRawReader::Create(fRawInput.Data());
1545   if (!fRawReader) {
1546     if (fRawInput.IsNull()) {
1547       AliInfo("Reconstruction will run over digits");
1548     }
1549     else {
1550       AliFatal("Can not create raw-data reader ! Exiting..."); 
1551     }
1552   }
1553
1554   if (!fEquipIdMap.IsNull() && fRawReader)
1555     fRawReader->LoadEquipmentIdsMap(fEquipIdMap);
1556
1557   if (!fUseHLTData.IsNull()) {
1558     // create the RawReaderHLT which performs redirection of HLT input data for
1559     // the specified detectors
1560     AliRawReader* pRawReader=AliRawHLTManager::CreateRawReaderHLT(fRawReader, fUseHLTData.Data());
1561     if (pRawReader) {
1562       fParentRawReader=fRawReader;
1563       fRawReader=pRawReader;
1564     } else {
1565       AliError(Form("can not create Raw Reader for HLT input %s", fUseHLTData.Data()));
1566     }
1567   }
1568   AliSysInfo::AddStamp("CreateRawReader");
1569 }
1570
1571 //_____________________________________________________________________________
1572 void AliReconstruction::InitRun(const char* input)
1573 {
1574   // Initialization of raw-reader,
1575   // run number, CDB etc.
1576   AliCodeTimerAuto("",0);
1577   AliSysInfo::AddStamp("Start");
1578
1579   // Initialize raw-reader if any
1580   InitRawReader(input);
1581
1582   // Initialize the CDB storage
1583   InitCDB();
1584
1585   // Set run number in CDBManager (if it is not already set by the user)
1586   if (!SetRunNumberFromData()) {
1587     Abort("SetRunNumberFromData", TSelector::kAbortProcess);
1588     return;
1589   }
1590
1591   // Set CDB lock: from now on it is forbidden to reset the run number
1592   // or the default storage or to activate any further storage!
1593   SetCDBLock();
1594   
1595 }
1596
1597 //_____________________________________________________________________________
1598 void AliReconstruction::Begin(TTree *)
1599 {
1600   // Initialize AlReconstruction before
1601   // going into the event loop
1602   // Should follow the TSelector convention
1603   // i.e. initialize only the object on the client side
1604   AliCodeTimerAuto("",0);
1605
1606   AliReconstruction *reco = NULL;
1607   if (fInput) {
1608     if ((reco = (AliReconstruction*)fInput->FindObject("AliReconstruction"))) {
1609       *this = *reco;
1610     }
1611     AliSysInfo::AddStamp("ReadInputInBegin");
1612   }
1613
1614   // Import ideal TGeo geometry and apply misalignment
1615   if (!AliGeomManager::GetGeometry()) {
1616     TString geom(gSystem->DirName(fGAliceFileName));
1617     geom += "/geometry.root";
1618     AliGeomManager::LoadGeometry(geom.Data());
1619     if (!gGeoManager) {
1620       Abort("LoadGeometry", TSelector::kAbortProcess);
1621       return;
1622     }
1623     AliSysInfo::AddStamp("LoadGeom");
1624     TString detsToCheck=fRunLocalReconstruction;
1625     if(!AliGeomManager::CheckSymNamesLUT(detsToCheck.Data())) {
1626       Abort("CheckSymNamesLUT", TSelector::kAbortProcess);
1627       return;
1628     }
1629     AliSysInfo::AddStamp("CheckGeom");
1630   }
1631
1632   Bool_t toCDBSnapshot=kFALSE;
1633   TString snapshotFileOut(""); // we could use fSnapshotFileName if we are not interested
1634   // in reading from and writing to a snapshot file at the same time
1635   if(TString(getenv("OCDB_SNAPSHOT_CREATE")) == TString("kTRUE")){
1636       toCDBSnapshot=kTRUE;
1637       //fFromCDBSnapshot=kFALSE;
1638       TString snapshotFile(getenv("OCDB_SNAPSHOT_FILENAME"));
1639       if(!(snapshotFile.IsNull() || snapshotFile.IsWhitespace()))
1640           snapshotFileOut = snapshotFile;
1641       else
1642           snapshotFileOut="OCDB.root";
1643   }
1644
1645   TString detStr(fLoadAlignData);
1646   if (!toCDBSnapshot) {
1647     if (!MisalignGeometry(fLoadAlignData)) {
1648       Abort("MisalignGeometry", TSelector::kAbortProcess);
1649       return;
1650     }
1651   } else {
1652     // when creating the snapshot, load the CDB alignment objects without applying them to the geometry
1653     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1654       if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1655       if (!strcmp(fgkDetectorName[iDet],"HLT")) continue;
1656       if (AliGeomManager::GetNalignable(fgkDetectorName[iDet]) != 0)
1657       {
1658         TString detAlignPath = fgkDetectorName[iDet];
1659         detAlignPath += "/Align/Data";
1660         AliCDBManager::Instance()->Get(detAlignPath);
1661       }
1662     } // end loop over detectors
1663     if(AliGeomManager::GetNalignable("GRP") != 0)
1664       AliCDBManager::Instance()->Get("GRP/Align/Data");
1665   }
1666
1667   const TMap* cdbCache = AliCDBManager::Instance()->GetEntryCache();
1668   if(!toCDBSnapshot) {
1669     if(cdbCache->Contains("GRP/Geometry/Data"))
1670       AliCDBManager::Instance()->UnloadFromCache("GRP/Geometry/Data");
1671     AliCDBManager::Instance()->UnloadFromCache("*/Align/*");
1672   }
1673   AliSysInfo::AddStamp("MisalignGeom");
1674
1675   if (!InitGRP()) {
1676     Abort("InitGRP", TSelector::kAbortProcess);
1677     return;
1678   }
1679   AliSysInfo::AddStamp("InitGRP");
1680   if(!toCDBSnapshot)
1681       if(cdbCache->Contains("GRP/Calib/CosmicTriggers"))
1682           AliCDBManager::Instance()->UnloadFromCache("GRP/Calib/CosmicTriggers");
1683
1684   if(!fCDBSnapshotMode || toCDBSnapshot){
1685       if (!LoadCDB()) {
1686           Abort("LoadCDB", TSelector::kAbortProcess);
1687           return;
1688       }
1689       AliSysInfo::AddStamp("LoadCDB"); 
1690   }
1691
1692   if (!LoadTriggerScalersCDB()) {
1693     Abort("LoadTriggerScalersCDB", TSelector::kAbortProcess);
1694     return;
1695   }
1696   AliSysInfo::AddStamp("LoadTriggerScalersCDB");
1697
1698   if (!LoadCTPTimeParamsCDB()) {
1699     Abort("LoadCTPTimeParamsCDB", TSelector::kAbortProcess);
1700     return;
1701   }
1702   AliSysInfo::AddStamp("LoadCTPTimeParamsCDB");
1703
1704   if (!ReadIntensityInfoCDB()) {
1705     Abort("ReadIntensityInfoCDB", TSelector::kAbortProcess);
1706     return;
1707   }
1708   AliSysInfo::AddStamp("ReadIntensityInfoCDB");
1709
1710   // Read the reconstruction parameters from OCDB
1711   if (!InitRecoParams()) {
1712     AliWarning("Not all detectors have correct RecoParam objects initialized");
1713   }
1714   AliSysInfo::AddStamp("InitRecoParams");
1715
1716   if(toCDBSnapshot)
1717   {
1718       AliCDBManager::Instance()->DumpToSnapshotFile(snapshotFileOut.Data(),kFALSE);
1719       exit(0);
1720   }
1721
1722   if (fInput && gProof) {
1723     if (reco) *reco = *this;
1724
1725     gGeoManager->SetName("Geometry");
1726     gProof->AddInputData(gGeoManager,kTRUE);
1727     gGeoManager = NULL;
1728     gProof->AddInputData(const_cast<TMap*>(AliCDBManager::Instance()->GetEntryCache()),kTRUE);
1729     fInput->Add(new TParameter<Int_t>("RunNumber",AliCDBManager::Instance()->GetRun()));
1730     AliMagF *magFieldMap = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
1731     magFieldMap->SetName("MagneticFieldMap");
1732     gProof->AddInputData(magFieldMap,kTRUE);
1733     if (fAnalysis) {
1734       fAnalysis->SetName("Analysis");
1735       gProof->AddInputData(fAnalysis,kTRUE);
1736     }  
1737   }
1738
1739 }
1740
1741 //_____________________________________________________________________________
1742 void AliReconstruction::SlaveBegin(TTree*)
1743 {
1744   // Initialization related to run-loader,
1745   // vertexer, trackers, recontructors
1746   // In proof mode it is executed on the slave
1747   AliCodeTimerAuto("",0);
1748
1749   TProofOutputFile *outProofFile = NULL;
1750   if (fInput) {
1751     if (AliDebugLevel() > 0) fInput->Print();
1752     if (AliDebugLevel() > 10) fInput->Dump();
1753     if (AliReconstruction *reco = (AliReconstruction*)fInput->FindObject("AliReconstruction")) {
1754       *this = *reco;
1755     }
1756     if (TGeoManager *tgeo = (TGeoManager*)fInput->FindObject("Geometry")) {
1757       gGeoManager = tgeo;
1758       AliGeomManager::SetGeometry(tgeo);
1759     }
1760     if (TMap *entryCache = (TMap*)fInput->FindObject("CDBEntryCache")) {
1761       Int_t runNumber = -1;
1762       if (TProof::GetParameter(fInput,"RunNumber",runNumber) == 0) {
1763         AliCDBManager *man = AliCDBManager::Instance(entryCache,runNumber);
1764         man->SetCacheFlag(kTRUE);
1765         man->SetLock(kTRUE);
1766         man->Print();
1767       }
1768     }
1769     if (AliMagF *map = (AliMagF*)fInput->FindObject("MagneticFieldMap")) {
1770       AliMagF *newMap = new AliMagF(*map);
1771       if (!newMap->LoadParameterization()) {
1772         Abort("AliMagF::LoadParameterization", TSelector::kAbortProcess);
1773         return;
1774       }
1775       TGeoGlobalMagField::Instance()->SetField(newMap);
1776       TGeoGlobalMagField::Instance()->Lock();
1777     }
1778     if (!fAnalysis) {
1779        // Attempt to get the analysis manager from the input list
1780        fAnalysis = (AliAnalysisManager*)fInput->FindObject("Analysis");
1781        if (fAnalysis) AliInfo("==== Analysis manager retrieved from input list ====");
1782     }   
1783     if (TNamed *outputFileName = (TNamed*)fInput->FindObject("PROOF_OUTPUTFILE"))
1784       fProofOutputFileName = outputFileName->GetTitle();
1785     if (TNamed *outputLocation = (TNamed*)fInput->FindObject("PROOF_OUTPUTFILE_LOCATION"))
1786       fProofOutputLocation = outputLocation->GetTitle();
1787     if (fInput->FindObject("PROOF_OUTPUTFILE_DATASET"))
1788       fProofOutputDataset = kTRUE;
1789     if (TNamed *archiveList = (TNamed*)fInput->FindObject("PROOF_OUTPUTFILE_ARCHIVE"))
1790       fProofOutputArchive = archiveList->GetTitle();
1791     if (!fProofOutputFileName.IsNull() &&
1792         !fProofOutputLocation.IsNull() &&
1793         fProofOutputArchive.IsNull()) {
1794       if (!fProofOutputDataset) {
1795         outProofFile = new TProofOutputFile(fProofOutputFileName.Data(),"M");
1796         outProofFile->SetOutputFileName(Form("%s%s",fProofOutputLocation.Data(),fProofOutputFileName.Data()));
1797       }
1798       else {
1799         outProofFile = new TProofOutputFile(fProofOutputFileName.Data(),"DROV",fProofOutputLocation.Data());
1800       }
1801       if (AliDebugLevel() > 0) outProofFile->Dump();
1802       fOutput->Add(outProofFile);
1803     }
1804     AliSysInfo::AddStamp("ReadInputInSlaveBegin");
1805   }
1806   // Check if analysis was requested in the reconstruction event loop
1807   if (!fAnalysis) {
1808     // Attempt to connect in-memory singleton
1809     fAnalysis = AliAnalysisManager::GetAnalysisManager();
1810     if (fAnalysis) AliInfo(Form("==== Analysis manager <%s> found in memory ====", fAnalysis->GetName()));
1811     // Check if an analysis macro was specified
1812     if (!fAnalysis && !fAnalysisMacro.IsNull()) {
1813       // Run specified analysis macro
1814       gROOT->ProcessLine(Form(".x %s",fAnalysisMacro.Data()));
1815       fAnalysis = AliAnalysisManager::GetAnalysisManager();
1816       if (!fAnalysis) AliError(Form("No analysis manager produced by analysis macro %s", fAnalysisMacro.Data()));
1817       else AliInfo(Form("==== Analysis manager <%s> produced by analysis macro <%s> ====", 
1818                         fAnalysis->GetName(), fAnalysisMacro.Data()));
1819     }
1820   }
1821   
1822   // get the run loader
1823   if (!InitRunLoader()) {
1824     Abort("InitRunLoader", TSelector::kAbortProcess);
1825     return;
1826   }
1827   AliSysInfo::AddStamp("LoadLoader");
1828  
1829   CheckRecoCDBvsSimuCDB();
1830
1831   ftVertexer = new AliVertexerTracks(AliTracker::GetBz());
1832
1833   // get trackers
1834   if (!fRunTracking.IsNull() && !CreateTrackers(fRunTracking)) {
1835     Abort("CreateTrackers", TSelector::kAbortProcess);
1836     return;
1837   }      
1838   AliSysInfo::AddStamp("CreateTrackers");
1839
1840   // create the ESD output file and tree
1841   if (!outProofFile) {
1842     ffile = TFile::Open("AliESDs.root", "RECREATE");
1843     ffile->SetCompressionLevel(2);
1844     if (!ffile->IsOpen()) {
1845       Abort("OpenESDFile", TSelector::kAbortProcess);
1846       return;
1847     }
1848   }
1849   else {
1850     AliInfo(Form("Opening output PROOF file: %s/%s",
1851                  outProofFile->GetDir(), outProofFile->GetFileName()));
1852     if (!(ffile = outProofFile->OpenFile("RECREATE"))) {
1853       Abort(Form("Problems opening output PROOF file: %s/%s",
1854                  outProofFile->GetDir(), outProofFile->GetFileName()),
1855             TSelector::kAbortProcess);
1856       return;
1857     }
1858   }
1859
1860   ftree = new TTree("esdTree", "Tree with ESD objects");
1861   fesd = new AliESDEvent();
1862   fesd->CreateStdContent();
1863   // add a so far non-std object to the ESD, this will
1864   // become part of the std content
1865   fesd->AddObject(new AliESDHLTDecision);
1866
1867   fesd->WriteToTree(ftree);
1868   if (fWriteESDfriend) {
1869     ffileF = TFile::Open("AliESDfriends.root", "RECREATE");
1870     ftreeF = new TTree("esdFriendTree", "Tree with ESD Friend objects");
1871     fesdf  = new AliESDfriend();
1872     ftreeF->Branch("ESDfriend.","AliESDfriend", &fesdf);
1873     fesd->AddObject(fesdf);
1874     ffile->cd();
1875   }
1876   ftree->GetUserInfo()->Add(fesd);
1877
1878   fhlttree = new TTree("HLTesdTree", "Tree with HLT ESD objects");
1879   fhltesd = new AliESDEvent();
1880   fhltesd->CreateStdContent();
1881   // read the ESD template from CDB
1882   // HLT is allowed to put non-std content to its ESD, the non-std
1883   // objects need to be created before invocation of WriteToTree in
1884   // order to create all branches. Initialization is done from an
1885   // ESD layout template in CDB
1886   AliCDBManager* man = AliCDBManager::Instance();
1887   AliCDBEntry* hltESDConfig = man->Get("HLT/Calib/esdLayout");
1888   if(!hltESDConfig){
1889       AliError(Form("Error getting \"HLT/Calib/esdLayout\""));
1890       return;
1891   }
1892   AliESDEvent* pESDLayout=dynamic_cast<AliESDEvent*>(hltESDConfig->GetObject());
1893   if (pESDLayout) {
1894       // init all internal variables from the list of objects
1895       pESDLayout->GetStdContent();
1896
1897       // copy content and create non-std objects
1898       *fhltesd=*pESDLayout;
1899       fhltesd->Reset();
1900   } else {
1901       AliError(Form("error setting hltEsd layout from \"HLT/Calib/esdLayout\": invalid object type"));
1902   }
1903
1904   fhltesd->WriteToTree(fhlttree);
1905   fhlttree->GetUserInfo()->Add(fhltesd);
1906
1907   ProcInfo_t procInfo;
1908   gSystem->GetProcInfo(&procInfo);
1909   AliInfo(Form("Current memory usage %ld %ld", procInfo.fMemResident, procInfo.fMemVirtual));
1910   
1911   // PID
1912   fESDpid = new AliESDpid();
1913
1914   //QA
1915   //Initialize the QA and start of cycle 
1916   if (fRunQA || fRunGlobalQA) 
1917     InitQA() ; 
1918
1919   //Initialize the Plane Efficiency framework
1920   if (fRunPlaneEff && !InitPlaneEff()) {
1921     Abort("InitPlaneEff", TSelector::kAbortProcess);
1922     return;
1923   }
1924
1925   if (strcmp(gProgName,"alieve") == 0)
1926     fRunAliEVE = InitAliEVE();
1927   // If we have an analysis manager, connect the AliRecoInputHandler here  
1928   if (fAnalysis) {
1929     if (!dynamic_cast<AliRecoInputHandler*>(fAnalysis->GetInputEventHandler())) {
1930        AliError("Analysis manager used in reconstruction should use AliRecoInputHandler - \
1931                  \n  ->Replacing with AliRecoInputHandler instance.");
1932        delete fAnalysis->GetInputEventHandler();
1933     }
1934     // Set the event and other data pointers
1935     fRecoHandler = new AliRecoInputHandler();
1936 //    fRecoHandler->Init(ftree, "LOCAL");
1937     fRecoHandler->SetEvent(fesd);
1938     fRecoHandler->SetESDfriend(fesdf);
1939     fRecoHandler->SetHLTEvent(fhltesd);
1940     fRecoHandler->SetHLTTree(fhlttree);
1941     fAnalysis->SetInputEventHandler(fRecoHandler);
1942     // Enter external loop mode
1943     fAnalysis->SetExternalLoop(kTRUE);
1944     // Initialize analysis
1945     fAnalysis->SlaveBegin(ftree);
1946     fAnalysis->StartAnalysis("local", (TTree*)0);
1947     // Connect ESD tree with the input container
1948     fAnalysis->GetCommonInputContainer()->SetData(ftree);
1949   }  
1950   return;
1951 }
1952
1953 //_____________________________________________________________________________
1954 Bool_t AliReconstruction::Process(Long64_t entry)
1955 {
1956   // run the reconstruction over a single entry
1957   // from the chain with raw data
1958   AliCodeTimerAuto("",0);
1959
1960   TTree *currTree = fChain->GetTree();
1961   AliRawVEvent *event = NULL;
1962   currTree->SetBranchAddress("rawevent",&event);
1963   currTree->GetEntry(entry);
1964   fRawReader = new AliRawReaderRoot(event);
1965   // check if process has enough resources 
1966   if (!HasEnoughResources(entry)) return kFALSE;
1967   fStatus = ProcessEvent(fRunLoader->GetNumberOfEvents());
1968   delete fRawReader;
1969   fRawReader = NULL;
1970   delete event;
1971
1972   return fStatus;
1973 }
1974
1975 //_____________________________________________________________________________
1976 void AliReconstruction::Init(TTree *tree)
1977 {
1978   // Implementation of TSelector::Init()
1979   // method
1980   if (tree == 0) {
1981     AliError("The input tree is not found!");
1982     return;
1983   }
1984   fChain = tree;
1985 }
1986
1987 //_____________________________________________________________________________
1988 Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
1989 {
1990   // run the reconstruction over a single event
1991   // The event loop is steered in Run method
1992
1993
1994   static Long_t oldMres=0;
1995   static Long_t oldMvir=0;
1996   static Float_t oldCPU=0;
1997   static Long_t aveDMres=0;
1998   static Long_t aveDMvir=0;
1999   static Float_t aveDCPU=0;
2000
2001   AliCodeTimerAuto("",0);
2002
2003   AliSysInfo::AddStamp(Form("StartEv_%d",iEvent), 0,0,iEvent);
2004
2005   if (iEvent >= fRunLoader->GetNumberOfEvents()) {
2006     fRunLoader->SetEventNumber(iEvent);
2007     if (fRawReader)
2008       fRunLoader->GetHeader()->Reset(fRawReader->GetRunNumber(), 
2009                                      iEvent, iEvent);
2010     fRunLoader->TreeE()->Fill();
2011
2012     if (fRawReader && fRawReader->UseAutoSaveESD())
2013       fRunLoader->TreeE()->AutoSave("SaveSelf");
2014   }
2015
2016   if ((iEvent < fFirstEvent) || ((fLastEvent >= 0) && (iEvent > fLastEvent))) {
2017     return kTRUE;
2018   }
2019
2020
2021   fRunLoader->GetEvent(iEvent);
2022
2023   // Fill Event-info object
2024   GetEventInfo();
2025   fRecoParam.SetEventSpecie(fRunInfo,fEventInfo,fListOfCosmicTriggers);
2026   
2027   ProcInfo_t procInfo;
2028   if(iEvent==fFirstEvent) {
2029     gSystem->GetProcInfo(&procInfo);
2030     oldMres=procInfo.fMemResident;
2031     oldMvir=procInfo.fMemVirtual;
2032     oldCPU=procInfo.fCpuUser+procInfo.fCpuSys;
2033   }
2034   AliInfo(Form("================================= Processing event %d of type %-10s ==================================", iEvent,fRecoParam.PrintEventSpecie()));
2035
2036   AliSysInfo::AddStamp(Form("StartReco_%d",iEvent), 0,0,iEvent);
2037
2038   // Set the reco-params
2039   {
2040     TString detStr = fLoadCDB;
2041     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2042       if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2043       AliReconstructor *reconstructor = GetReconstructor(iDet);
2044       if (reconstructor && fRecoParam.GetDetRecoParamArray(iDet)) {
2045         const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
2046         reconstructor->SetRecoParam(par);
2047         reconstructor->GetPidSettings(fESDpid);
2048         reconstructor->SetEventInfo(&fEventInfo);
2049         if (fRunQA) {
2050           AliQAManager::QAManager()->SetEventInfo(&fEventInfo) ;
2051           AliQAManager::QAManager()->SetRecoParam(iDet, par) ; 
2052           if (par) AliQAManager::QAManager()->SetEventSpecie(AliRecoParam::Convert(par->GetEventSpecie())) ;
2053         }
2054       }
2055     }
2056     //
2057     if (fRunQA || fRunGlobalQA) AliQADataMaker::SetEventTrigClasses(fEventInfo.GetTriggerClasses()); // RS: select which histo clones are to be filled
2058     //
2059     if (fRunQA) {
2060       const AliDetectorRecoParam *grppar = fRecoParam.GetDetRecoParam(kNDetectors);
2061       AliQAManager::QAManager()->SetRecoParam(AliQAv1::kGLOBAL, grppar) ; 
2062       AliQAManager::QAManager()->SetEventSpecie(AliRecoParam::Convert(grppar->GetEventSpecie())) ;
2063     }
2064   }
2065
2066     // QA on single raw 
2067   if (fRunQA && IsInTasks(AliQAv1::kRAWS)) {
2068     AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2069     AliQAManager::QAManager()->RunOneEvent(fRawReader) ;  
2070     AliSysInfo::AddStamp(Form("RawQA_%d",iEvent), 0,0,iEvent);
2071   }
2072
2073     // fill Event header information from the RawEventHeader
2074     if (fRawReader){FillRawEventHeaderESD(fesd);}
2075     if (fRawReader){FillRawEventHeaderESD(fhltesd);}
2076     if (fRawReader){
2077       // Store DAQ detector pattern and attributes
2078       fesd->SetDAQDetectorPattern(fRawReader->GetDetectorPattern()[0]);
2079       fesd->SetDAQAttributes(fRawReader->GetAttributes()[2]);
2080     }
2081
2082     fesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
2083     fhltesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
2084     
2085     ((AliESDRun*)fesd->GetESDRun())->SetDetectorsInDAQ(fRunInfo->GetDetectorMask());
2086     ((AliESDRun*)fhltesd->GetESDRun())->SetDetectorsInDAQ(fRunInfo->GetDetectorMask());
2087     ((AliESDRun*)fesd->GetESDRun())->SetDetectorsInReco(AliDAQ::DetectorPatternOffline(fFillESD.Data()));
2088     ((AliESDRun*)fhltesd->GetESDRun())->SetDetectorsInReco(AliDAQ::DetectorPatternOffline(fFillESD.Data()));
2089
2090     fesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
2091     fhltesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
2092
2093     fesd->SetEventSpecie(fRecoParam.GetEventSpecie());
2094     fhltesd->SetEventSpecie(fRecoParam.GetEventSpecie());
2095     
2096     // Set magnetic field from the tracker
2097     fesd->SetMagneticField(AliTracker::GetBz());
2098     fhltesd->SetMagneticField(AliTracker::GetBz());
2099     //
2100     AliESDRun *esdRun,*esdRunH;
2101     esdRun  = (AliESDRun*)fesd->GetESDRun();
2102     esdRunH = (AliESDRun*)fhltesd->GetESDRun();
2103     esdRun->SetBeamEnergyIsSqrtSHalfGeV();
2104     esdRunH->SetBeamEnergyIsSqrtSHalfGeV();
2105     //
2106     for (int ib=2;ib--;) for (int it=2;it--;) {
2107         esdRun->SetMeanIntensity(ib,it, fBeamInt[ib][it]); 
2108         esdRunH->SetMeanIntensity(ib,it, fBeamInt[ib][it]); 
2109       }
2110     //
2111     fesd->SetBeamEnergy(fGRPData->GetBeamEnergy());
2112     fesd->SetBeamType(fGRPData->GetBeamType().Data());
2113     fesd->SetBeamParticle(fGRPData->GetSingleBeamType(0).Atoi(),0);
2114     fesd->SetBeamParticle(fGRPData->GetSingleBeamType(1).Atoi(),1);
2115     fhltesd->SetBeamEnergy(fGRPData->GetBeamEnergy());
2116     fhltesd->SetBeamType(fGRPData->GetBeamType().Data());
2117     fhltesd->SetBeamParticle(fGRPData->GetSingleBeamType(0).Atoi(),0);
2118     fhltesd->SetBeamParticle(fGRPData->GetSingleBeamType(1).Atoi(),1);
2119     //
2120     AliMagF* fld = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
2121     if (fld) { // set info needed for field initialization
2122       fesd->SetCurrentL3(fld->GetCurrentSol());
2123       fesd->SetCurrentDip(fld->GetCurrentDip());
2124       fesd->SetUniformBMap(fld->IsUniform());
2125       fesd->SetBInfoStored();
2126       //
2127       fhltesd->SetCurrentL3(fld->GetCurrentSol());
2128       fhltesd->SetCurrentDip(fld->GetCurrentDip());
2129       fhltesd->SetUniformBMap(fld->IsUniform());
2130       fhltesd->SetBInfoStored();
2131     }
2132
2133     //
2134     // run full HLT reconstruction first
2135     //
2136     {
2137       TString detectors=fRunLocalReconstruction;
2138       if (IsSelected("HLT", detectors) &&
2139           !RunLocalEventReconstruction("HLT")) {
2140         if (fStopOnError) {CleanUp(); return kFALSE;}
2141       }
2142       detectors=fFillESD;
2143       // run HLT on hltesd
2144       if (IsSelected("HLT", detectors) &&
2145           !FillESD(fhltesd, "HLT")) {
2146         if (fStopOnError) {CleanUp(); return kFALSE;}
2147       }
2148     }
2149
2150     // local single event reconstruction
2151     if (!fRunLocalReconstruction.IsNull()) {
2152       TString detectors=fRunLocalReconstruction;
2153       // the logic for selection and correct sequence of reconstruction relies on the
2154       // full list of detectors. Keyword 'ALL' should have been replaced at this point.
2155       if (detectors.Contains("ALL")) {
2156         AliFatal("Keyword 'ALL' needs to be replaced by the full list of detectors in "
2157                  "fRunLocalReconstruction. This should have been done by the framework");
2158       }
2159       detectors.ReplaceAll("HLT", "");
2160       if (!RunLocalEventReconstruction(detectors)) {
2161         if (fStopOnError) {
2162           CleanUp(); 
2163           return kFALSE;
2164         }
2165       }
2166     }
2167
2168   
2169     //
2170     // Set most probable pt, for B=0 tracking
2171     // Get the global reco-params. They are atposition 16 inside the array of detectors in fRecoParam
2172     const AliGRPRecoParam *grpRecoParam = dynamic_cast<const AliGRPRecoParam*>(fRecoParam.GetDetRecoParam(kNDetectors));
2173     if (grpRecoParam) AliExternalTrackParam::SetMostProbablePt(grpRecoParam->GetMostProbablePt());
2174     
2175     // Fill raw-data error log into the ESD
2176     if (fRawReader) FillRawDataErrorLog(iEvent,fesd);
2177
2178     AliSysInfo::AddStamp(Form("FillHeadErrs_%d",iEvent), 0,0,iEvent);
2179
2180     // vertex finder
2181     if (fRunVertexFinder) {
2182       if (!RunVertexFinder(fesd)) {
2183         if (fStopOnError) {CleanUp(); return kFALSE;}
2184       }
2185       AliSysInfo::AddStamp(Form("VtxFinder_%d",iEvent), 0,0,iEvent);
2186     }
2187
2188     // For Plane Efficiency: run the SPD trackleter
2189     if (fRunPlaneEff && fSPDTrackleter) {
2190       if (!RunSPDTrackleting(fesd)) {
2191         if (fStopOnError) {CleanUp(); return kFALSE;}
2192       }
2193       AliSysInfo::AddStamp(Form("TrackletEff_%d",iEvent), 0,0,iEvent);
2194     }
2195
2196     // Muon tracking
2197     if (!fRunTracking.IsNull()) {
2198       if (fRunMuonTracking) {
2199         if (!RunMuonTracking(fesd)) {
2200           if (fStopOnError) {CleanUp(); return kFALSE;}
2201         }
2202       }
2203       AliSysInfo::AddStamp(Form("TrackingMUON_%d",iEvent), 0,0,iEvent);      
2204     }
2205
2206     //---------------- AU From here...
2207
2208     // MFT tracking of MUON tracks
2209     if (!fRunTracking.IsNull()) {
2210       if (fRunMFTTrackingMU && fRunMuonTracking) {
2211         if (!RunMFTTrackingMU(fesd)) {
2212           if (fStopOnError) {CleanUp(); return kFALSE;}
2213         }
2214       }
2215       AliSysInfo::AddStamp(Form("TrackingMFT_MUON_%d",iEvent), 0,0,iEvent);      
2216     }
2217
2218     //---------------- ...to here
2219
2220     // barrel tracking
2221     if (!fRunTracking.IsNull()) {
2222       if (!RunTracking(fesd,*fESDpid)) {
2223         if (fStopOnError) {CleanUp(); return kFALSE;}
2224       }
2225     }
2226
2227     // fill ESD
2228     if (!fFillESD.IsNull()) {
2229       TString detectors=fFillESD;
2230       // the logic for selection and correct sequence of reconstruction relies on the
2231       // full list of detectors. Keyword 'ALL' should have been replaced at this point.
2232       if (detectors.Contains("ALL")) {
2233         AliFatal("Keyword 'ALL' needs to be replaced by the full list of detectors in "
2234                  "fFillESD. This should have been done by the framework");
2235       }
2236       // remove HLT as this has been executed at the beginning of the event reconstruction
2237       detectors.ReplaceAll("HLT", "");
2238       if (!FillESD(fesd, detectors)) {
2239         if (fStopOnError) {CleanUp(); return kFALSE;}
2240       }
2241     }
2242
2243     ffile->cd();
2244
2245     //
2246     // Propagate track to the beam pipe  (if not already done by ITS)
2247     //
2248     const Int_t ntracks = fesd->GetNumberOfTracks();
2249     const Double_t kRadius  = 2.8; //something less than the beam pipe radius
2250
2251     TObjArray trkArray;
2252     UShort_t selectedIdx[ntracks];
2253
2254     for (Int_t itrack=0; itrack<ntracks; itrack++){
2255       const Double_t kMaxStep = 1;   //max step over the material
2256       Bool_t ok;
2257
2258       AliESDtrack *track = fesd->GetTrack(itrack);
2259       if (!track) continue;
2260
2261       AliExternalTrackParam *tpcTrack =
2262            (AliExternalTrackParam *)track->GetTPCInnerParam();
2263       ok = kFALSE;
2264       if (tpcTrack)
2265         ok = AliTracker::
2266           PropagateTrackToBxByBz(tpcTrack,kRadius,track->GetMassForTracking(),kMaxStep,kFALSE);
2267
2268       if (ok) {
2269         Int_t n=trkArray.GetEntriesFast();
2270         selectedIdx[n]=track->GetID();
2271         trkArray.AddLast(tpcTrack);
2272       }
2273
2274       //Tracks refitted by ITS should already be at the SPD vertex
2275       if (track->IsOn(AliESDtrack::kITSrefit)) continue;
2276
2277       AliTracker::
2278          PropagateTrackToBxByBz(track,kRadius,track->GetMassForTracking(),kMaxStep,kFALSE);
2279       Double_t x[3]; track->GetXYZ(x);
2280       Double_t b[3]; AliTracker::GetBxByBz(x,b);
2281       track->RelateToVertexBxByBz(fesd->GetPrimaryVertexSPD(), b, kVeryBig);
2282
2283     }
2284     AliSysInfo::AddStamp(Form("RelToSPDVtx_%d",iEvent), 0,0,iEvent);      
2285     //
2286     // Improve the reconstructed primary vertex position using the tracks
2287     //
2288     Bool_t runVertexFinderTracks = fRunVertexFinderTracks;
2289     if(fesd->GetPrimaryVertexSPD()) {
2290       TString vtitle = fesd->GetPrimaryVertexSPD()->GetTitle();
2291       if(vtitle.Contains("cosmics")) {
2292         runVertexFinderTracks=kFALSE;
2293       }
2294     }
2295
2296     if (runVertexFinderTracks) {
2297        // TPC + ITS primary vertex
2298        ftVertexer->SetITSMode();
2299        ftVertexer->SetConstraintOff();
2300        // get cuts for vertexer from AliGRPRecoParam
2301        Bool_t constrSPD=kFALSE;
2302        if (grpRecoParam) {
2303          Int_t nCutsVertexer = grpRecoParam->GetVertexerTracksNCuts();
2304          Double_t *cutsVertexer = new Double_t[nCutsVertexer];
2305          grpRecoParam->GetVertexerTracksCutsITS(cutsVertexer,nCutsVertexer);
2306          ftVertexer->SetCuts(cutsVertexer,nCutsVertexer);
2307          delete [] cutsVertexer; cutsVertexer = NULL; 
2308          if(grpRecoParam->GetVertexerTracksConstraintITS()) { 
2309            if(fDiamondProfile && fDiamondProfile->GetXRes()<kRadius){
2310              ftVertexer->SetVtxStart(fDiamondProfile); // apply constraint only if sigmax is smaller than the beam pipe radius 
2311            }else{
2312              if(fDiamondProfileSPD && fDiamondProfileSPD->GetXRes()<kRadius){
2313                ftVertexer->SetVtxStart(fDiamondProfileSPD);
2314                constrSPD=kTRUE;
2315              }
2316            }
2317          } 
2318        }
2319        AliESDVertex *pvtx=ftVertexer->FindPrimaryVertex(fesd);
2320        if (pvtx) {
2321          if(constrSPD){
2322            TString title=pvtx->GetTitle();
2323            title.Append("SPD");
2324            pvtx->SetTitle(title);
2325          }
2326           if (pvtx->GetStatus()) {
2327              fesd->SetPrimaryVertexTracks(pvtx);
2328              for (Int_t i=0; i<ntracks; i++) {
2329                  AliESDtrack *t = fesd->GetTrack(i);
2330                  Double_t x[3]; t->GetXYZ(x);
2331                  Double_t b[3]; AliTracker::GetBxByBz(x,b);
2332                  t->RelateToVertexBxByBz(pvtx, b, kVeryBig);
2333              } 
2334           }
2335           delete pvtx; pvtx=NULL;
2336        }
2337        AliSysInfo::AddStamp(Form("VtxTrk_%d",iEvent), 0,0,iEvent);      
2338
2339        // TPC-only primary vertex
2340        ftVertexer->SetTPCMode();
2341        ftVertexer->SetConstraintOff();
2342        // get cuts for vertexer from AliGRPRecoParam
2343        if (grpRecoParam) {
2344          Int_t nCutsVertexer = grpRecoParam->GetVertexerTracksNCuts();
2345          Double_t *cutsVertexer = new Double_t[nCutsVertexer];
2346          grpRecoParam->GetVertexerTracksCutsTPC(cutsVertexer,nCutsVertexer);
2347          ftVertexer->SetCuts(cutsVertexer,nCutsVertexer);
2348          delete [] cutsVertexer; cutsVertexer = NULL; 
2349          if(fDiamondProfileTPC && grpRecoParam->GetVertexerTracksConstraintTPC()) { 
2350            if(fDiamondProfileTPC->GetXRes()<kRadius) ftVertexer->SetVtxStart(fDiamondProfileTPC); // apply constraint only if sigmax is smaller than the beam pipe radius 
2351          } 
2352        }
2353        pvtx=ftVertexer->FindPrimaryVertex(&trkArray,selectedIdx);
2354        if (pvtx) {
2355           if (pvtx->GetStatus()) {
2356              fesd->SetPrimaryVertexTPC(pvtx);
2357              for (Int_t i=0; i<ntracks; i++) {
2358                  AliESDtrack *t = fesd->GetTrack(i);
2359                  Double_t x[3]; t->GetXYZ(x);
2360                  Double_t b[3]; AliTracker::GetBxByBz(x,b);
2361                  t->RelateToVertexTPCBxByBz(pvtx, b, kVeryBig);
2362              } 
2363           }
2364           delete pvtx; pvtx=NULL;
2365        }
2366        AliSysInfo::AddStamp(Form("VtxTPC_%d",iEvent), 0,0,iEvent);      
2367
2368     }
2369     
2370     if(fDiamondProfile && fDiamondProfile->GetXRes()<kRadius) fesd->SetDiamond(fDiamondProfile);
2371     else fesd->SetDiamond(fDiamondProfileSPD);
2372
2373     if (fRunV0Finder) {
2374        // V0 finding
2375        AliV0vertexer vtxer;
2376        // get cuts for V0vertexer from AliGRPRecoParam
2377        if (grpRecoParam) {
2378          Int_t nCutsV0vertexer = grpRecoParam->GetVertexerV0NCuts();
2379          Double_t cutsV0vertexer[nCutsV0vertexer];
2380          grpRecoParam->GetVertexerV0Cuts(cutsV0vertexer);
2381          vtxer.SetCuts(cutsV0vertexer);
2382        }
2383        vtxer.Tracks2V0vertices(fesd);
2384        AliSysInfo::AddStamp(Form("V0Finder_%d",iEvent), 0,0,iEvent); 
2385
2386        if (fRunCascadeFinder) {
2387           // Cascade finding
2388           AliCascadeVertexer cvtxer;
2389           // get cuts for CascadeVertexer from AliGRPRecoParam
2390           if (grpRecoParam) {
2391             Int_t nCutsCascadeVertexer = grpRecoParam->GetVertexerCascadeNCuts();
2392             Double_t cutsCascadeVertexer[nCutsCascadeVertexer];
2393             grpRecoParam->GetVertexerCascadeCuts(cutsCascadeVertexer);
2394             cvtxer.SetCuts(cutsCascadeVertexer);
2395           }
2396           cvtxer.V0sTracks2CascadeVertices(fesd);
2397           AliSysInfo::AddStamp(Form("CascadeFinder_%d",iEvent), 0,0,iEvent); 
2398        }
2399     }
2400
2401     // AdC+FN
2402     if (fReconstructor[3])
2403       GetReconstructor(3)->FillEventTimeWithTOF(fesd,fESDpid);
2404
2405     // combined PID
2406     //    fESDpid->MakePID(fesd);
2407
2408     if (fFillTriggerESD) {
2409       if (!FillTriggerESD(fesd)) {
2410         if (fStopOnError) {CleanUp(); return kFALSE;}
2411       }
2412     }
2413     // Always fill scalers
2414     if (!FillTriggerScalers(fesd)) {
2415        if (fStopOnError) {CleanUp(); return kFALSE;}
2416     }
2417
2418     AliSysInfo::AddStamp(Form("FillVaria_%d",iEvent), 0,0,iEvent); 
2419
2420     // write ESD
2421     UInt_t specie = fesd->GetEventSpecie();
2422     Bool_t keepAll = (specie==AliRecoParam::kCosmic || specie==AliRecoParam::kCalib);
2423     if (fCleanESD && (!keepAll) ) {
2424       CleanESD(fesd);
2425       AliSysInfo::AddStamp(Form("CleanESD_%d",iEvent), 0,0,iEvent); 
2426     }
2427     // 
2428     // RS run updated trackleter: since we want to mark the clusters used by tracks and also mark the 
2429     // tracks interpreted as primary, this step should be done in the very end, when full 
2430     // ESD info is available (particulalry, V0s)
2431     // vertex finder
2432     if (fRunMultFinder) {
2433       if (!RunMultFinder(fesd)) {
2434         if (fStopOnError) {CleanUp(); return kFALSE;}
2435       }
2436       AliSysInfo::AddStamp(Form("MultFinder_%d",iEvent), 0,0,iEvent); 
2437     }
2438
2439   if (fRunQA && IsInTasks(AliQAv1::kESDS)) {
2440     AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2441     AliQAManager::QAManager()->RunOneEvent(fesd, fhltesd) ; 
2442     AliSysInfo::AddStamp(Form("RunQA_%d",iEvent), 0,0,iEvent); 
2443   }
2444   if (fRunGlobalQA) {
2445     AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
2446     if (qadm)
2447       qadm->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2448     if (qadm && IsInTasks(AliQAv1::kESDS))
2449       qadm->Exec(AliQAv1::kESDS, fesd);
2450     AliSysInfo::AddStamp(Form("RunGlobQA_%d",iEvent), 0,0,iEvent);     
2451   }
2452
2453   // copy HLT decision from HLTesd to esd
2454   // the most relevant information is stored in a reduced container in the esd,
2455   // while the full information can be found in the HLTesd
2456   TObject* pHLTSrc=fhltesd->FindListObject(AliESDHLTDecision::Name());
2457   TObject* pHLTTgt=fesd->FindListObject(AliESDHLTDecision::Name());
2458   if (pHLTSrc && pHLTTgt) {
2459     pHLTSrc->Copy(*pHLTTgt);
2460   }
2461   //
2462   // Perform analysis of this event if requested
2463   // RS: Should be done before WriteESDfriend, since the latter may clean the esdfriend
2464   if (fAnalysis) {
2465     fRecoHandler->BeginEvent(iEvent);
2466     fAnalysis->ExecAnalysis();
2467     fRecoHandler->FinishEvent();
2468     AliSysInfo::AddStamp(Form("Analysis_%d",iEvent), 0,0,iEvent);     
2469   }  
2470   //
2471   if (fWriteESDfriend) {
2472     fesd->GetESDfriend(fesdf);
2473     AliSysInfo::AddStamp(Form("CreateFriend_%d",iEvent), 0,0,iEvent);     
2474   
2475   }
2476   //
2477   Long64_t nbf;
2478   nbf = ftree->Fill();
2479   if (fTreeBuffSize>0 && ftree->GetAutoFlush()<0 && (fMemCountESD += nbf)>fTreeBuffSize ) { // default limit is still not reached
2480     nbf = ftree->GetZipBytes();
2481     if (nbf>0) nbf = -nbf;
2482     else       nbf = ftree->GetEntries();
2483     ftree->SetAutoFlush(nbf);
2484     AliInfo(Form("Calling ftree->SetAutoFlush(%lld) | W:%lld T:%lld Z:%lld",
2485                  nbf,fMemCountESD,ftree->GetTotBytes(),ftree->GetZipBytes()));        
2486   }
2487   AliSysInfo::AddStamp(Form("ESDFill_%d",iEvent), 0,0,iEvent);     
2488   //
2489   if (fWriteESDfriend) {
2490     WriteESDfriend();
2491     AliSysInfo::AddStamp(Form("WriteFriend_%d",iEvent), 0,0,iEvent);     
2492   }
2493   //
2494   //
2495   // Auto-save the ESD tree in case of prompt reco @P2
2496   if (fRawReader && fRawReader->UseAutoSaveESD()) {
2497     ftree->AutoSave("SaveSelf");
2498     if (fWriteESDfriend) ftreeF->AutoSave("SaveSelf");
2499   }
2500   // write HLT ESD
2501   
2502   nbf = fhlttree->Fill();
2503   if (fTreeBuffSize>0 && fhlttree->GetAutoFlush()<0 && (fMemCountESDHLT += nbf)>fTreeBuffSize ) { // default limit is still not reached
2504     nbf = fhlttree->GetZipBytes();
2505     if (nbf>0) nbf = -nbf;
2506     else       nbf = fhlttree->GetEntries();
2507     fhlttree->SetAutoFlush(nbf);
2508     AliInfo(Form("Calling fhlttree->SetAutoFlush(%lld) | W:%lld T:%lld Z:%lld",
2509                  nbf,fMemCountESDHLT,fhlttree->GetTotBytes(),fhlttree->GetZipBytes()));        
2510   }
2511     
2512     gSystem->GetProcInfo(&procInfo);
2513     Long_t dMres=(procInfo.fMemResident-oldMres)/1024;
2514     Long_t dMvir=(procInfo.fMemVirtual-oldMvir)/1024;
2515     Float_t dCPU=procInfo.fCpuUser+procInfo.fCpuSys-oldCPU;
2516     aveDMres+=(dMres-aveDMres)/(iEvent-fFirstEvent+1);
2517     aveDMvir+=(dMvir-aveDMvir)/(iEvent-fFirstEvent+1);
2518     aveDCPU+=(dCPU-aveDCPU)/(iEvent-fFirstEvent+1);
2519     AliInfo(Form("======================= End Event %d: Res %ld(%3ld <%3ld>) Vir %ld(%3ld <%3ld>) CPU %5.2f <%5.2f> ===================",
2520                 iEvent, procInfo.fMemResident/1024, dMres, aveDMres, procInfo.fMemVirtual/1024, dMvir, aveDMvir, dCPU, aveDCPU));
2521     oldMres=procInfo.fMemResident;
2522     oldMvir=procInfo.fMemVirtual;
2523     oldCPU=procInfo.fCpuUser+procInfo.fCpuSys;
2524   
2525     
2526   return kTRUE;
2527 }
2528
2529 void AliReconstruction::CleanProcessedEvent()
2530 {
2531     //
2532     fesd->Reset();
2533     fhltesd->Reset();
2534     if (fWriteESDfriend) {
2535       fesdf->~AliESDfriend();
2536       new (fesdf) AliESDfriend(); // Reset...
2537     }
2538
2539     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2540       if (fReconstructor[iDet]) fReconstructor[iDet]->FinishEvent();
2541     }
2542  
2543     AliInfo("======================= End Event ===================");
2544     
2545     fEventInfo.Reset();
2546     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2547       if (fReconstructor[iDet]) {
2548         fReconstructor[iDet]->SetRecoParam(NULL);
2549         fReconstructor[iDet]->SetEventInfo(NULL);
2550       }
2551       if (fTracker[iDet]) fTracker[iDet]->SetEventInfo(NULL);
2552     }
2553         
2554   if (fRunQA || fRunGlobalQA) 
2555     AliQAManager::QAManager()->Increment() ; 
2556
2557   DeleteRecPoints(fDeleteRecPoints);
2558   DeleteDigits(fDeleteDigits);
2559   //
2560
2561 }
2562
2563 //_____________________________________________________________________________
2564 void AliReconstruction::SlaveTerminate()
2565 {
2566   // Finalize the run on the slave side
2567   // Called after the exit
2568   // from the event loop
2569   AliCodeTimerAuto("",0);
2570   // If analysis was done during reconstruction, we need to call SlaveTerminate for it
2571   if (fAnalysis) {
2572      fAnalysis->PackOutput(fOutput);
2573      fAnalysis->SetSkipTerminate(kTRUE);
2574      fAnalysis->Terminate();
2575   }   
2576
2577   if (fIsNewRunLoader) { // galice.root didn't exist
2578     fRunLoader->WriteHeader("OVERWRITE");
2579     fRunLoader->WriteTrigger("OVERWRITE");
2580     fRunLoader->CdGAFile();
2581     fRunLoader->Write(0, TObject::kOverwrite);
2582   }
2583
2584   const TMap *cdbMap = AliCDBManager::Instance()->GetStorageMap();       
2585   const TList *cdbList = AliCDBManager::Instance()->GetRetrievedIds();   
2586                  
2587    TMap *cdbMapCopy = new TMap(cdbMap->GetEntries());    
2588    cdbMapCopy->SetOwner(1);      
2589    cdbMapCopy->SetName("cdbMap");        
2590    TIter iter(cdbMap->GetTable());       
2591          
2592    TPair* pair = 0;      
2593    while((pair = dynamic_cast<TPair*> (iter.Next()))){   
2594          TObjString* keyStr = dynamic_cast<TObjString*> (pair->Key());   
2595          TObjString* valStr = dynamic_cast<TObjString*> (pair->Value());
2596          if (keyStr && valStr)
2597            cdbMapCopy->Add(new TObjString(keyStr->GetName()), new TObjString(valStr->GetName()));        
2598    }     
2599          
2600    TList *cdbListCopy = new TList();     
2601    cdbListCopy->SetOwner(1);     
2602    cdbListCopy->SetName("cdbList");      
2603          
2604    TIter iter2(cdbList);         
2605          
2606         AliCDBId* id=0;
2607         while((id = dynamic_cast<AliCDBId*> (iter2.Next()))){    
2608          cdbListCopy->Add(new TObjString(id->ToString().Data()));        
2609    }     
2610          
2611    ftree->GetUserInfo()->Add(cdbMapCopy);        
2612    ftree->GetUserInfo()->Add(cdbListCopy);
2613
2614    // Add the AliRoot version that created this file
2615    TString sVersion("aliroot ");
2616    sVersion += ALIROOT_BRANCH;
2617    sVersion += ":";
2618    sVersion += ALIROOT_REVISION;
2619    sVersion += "; root ";
2620 #ifdef ROOT_SVN_BRANCH
2621    sVersion += ROOT_SVN_BRANCH;
2622 #elif defined(ROOT_GIT_BRANCH)
2623    sVersion += ROOT_GIT_BRANCH;
2624 #else
2625    sVersion += "?";
2626 #endif
2627    sVersion += ":";
2628 #ifdef ROOT_SVN_REVSION
2629    sVersion += ROOT_SVN_REVISION;
2630 #elif defined(ROOT_GIT_COMMIT)
2631    sVersion += ROOT_GIT_COMMIT;
2632 #else 
2633    sVersion += "?";
2634 #endif
2635    sVersion += "; metadata ";
2636    sVersion += getenv("PRODUCTION_METADATA");
2637                     
2638
2639    TNamed * alirootVersion = new TNamed("alirootVersion",sVersion.Data());
2640    ftree->GetUserInfo()->Add(alirootVersion); // The list becomes owner of alirootVersion
2641
2642   ffile->cd();
2643
2644   // we want to have only one tree version number
2645   ftree->Write(ftree->GetName(),TObject::kOverwrite);
2646   fhlttree->Write(fhlttree->GetName(),TObject::kOverwrite);
2647
2648   if (fWriteESDfriend) {
2649     ffileF->cd();
2650     ftreeF->Write(ftreeF->GetName(),TObject::kOverwrite);
2651   }
2652
2653 // Finish with Plane Efficiency evaluation: before of CleanUp !!!
2654   if (fRunPlaneEff && !FinishPlaneEff()) {
2655    AliWarning("Finish PlaneEff evaluation failed");
2656   }
2657
2658   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2659     if (fReconstructor[iDet]) fReconstructor[iDet]->Terminate();
2660   }
2661   // End of cycle for the in-loop  
2662
2663   if (fRunQA || fRunGlobalQA) {
2664     AliQAManager::QAManager()->EndOfCycle() ;
2665     if (fInput &&
2666         !fProofOutputLocation.IsNull() &&
2667         fProofOutputArchive.IsNull() &&
2668         !fProofOutputDataset) {
2669       TString qaOutputFile(Form("%sMerged.%s.Data.root",
2670                                 fProofOutputLocation.Data(),
2671                                 AliQAv1::GetQADataFileName()));
2672       TProofOutputFile *qaProofFile = new TProofOutputFile(Form("Merged.%s.Data.root",
2673                                                                 AliQAv1::GetQADataFileName()));
2674       qaProofFile->SetOutputFileName(qaOutputFile.Data());
2675       if (AliDebugLevel() > 0) qaProofFile->Dump();
2676       fOutput->Add(qaProofFile);
2677       MergeQA(qaProofFile->GetFileName());
2678     }
2679     else {
2680       MergeQA();
2681     }
2682   }
2683
2684   gROOT->cd();
2685   CleanUp();
2686
2687   if (fInput) {
2688     if (!fProofOutputFileName.IsNull() &&
2689         !fProofOutputLocation.IsNull() &&
2690         fProofOutputDataset &&
2691         !fProofOutputArchive.IsNull()) {
2692       TProofOutputFile *zipProofFile = new TProofOutputFile(fProofOutputFileName.Data(),
2693                                                             "DROV",
2694                                                             fProofOutputLocation.Data());
2695       if (AliDebugLevel() > 0) zipProofFile->Dump();
2696       fOutput->Add(zipProofFile);
2697       TString fileList(fProofOutputArchive.Data());
2698       fileList.ReplaceAll(","," ");
2699       TString command;
2700 #if ROOT_SVN_REVISION >= 30174
2701       command.Form("zip -n root %s/%s %s",zipProofFile->GetDir(kTRUE),zipProofFile->GetFileName(),fileList.Data());
2702 #else
2703       command.Form("zip -n root %s/%s %s",zipProofFile->GetDir(),zipProofFile->GetFileName(),fileList.Data());
2704 #endif
2705       AliInfo(Form("Executing: %s",command.Data()));
2706       gSystem->Exec(command.Data());
2707     }
2708   }
2709 }
2710     
2711 //_____________________________________________________________________________
2712 void AliReconstruction::Terminate()
2713 {
2714   // Create tags for the events in the ESD tree (the ESD tree is always present)
2715   // In case of empty events the tags will contain dummy values
2716   AliCodeTimerAuto("",0);
2717
2718   // Do not call the ESD tag creator in case of PROOF-based reconstruction
2719   if (!fInput) {
2720     AliESDTagCreator *esdtagCreator = new AliESDTagCreator();
2721     esdtagCreator->CreateESDTags(fFirstEvent,fLastEvent,fGRPData, AliQAv1::Instance()->GetQA(), AliQAv1::Instance()->GetEventSpecies(), AliQAv1::kNDET, AliRecoParam::kNSpecies);
2722     delete esdtagCreator;
2723   }
2724
2725   // Cleanup of CDB manager: cache and active storages!
2726   AliCDBManager::Instance()->ClearCache();
2727 }
2728
2729 //_____________________________________________________________________________
2730 Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
2731 {
2732 // run the local reconstruction
2733
2734   static Int_t eventNr=0;
2735   AliCodeTimerAuto("",0)
2736
2737   TString detStr = detectors;
2738   // execute HLT reconstruction first since other detector reconstruction
2739   // might depend on HLT data
2740   // key 'HLT' is removed from detStr by IsSelected
2741   if (IsSelected("HLT", detStr)) {
2742     AliReconstructor* reconstructor = GetReconstructor(kNDetectors-1);
2743     if (reconstructor) {
2744       // there is no AliLoader for HLT, see
2745       // https://savannah.cern.ch/bugs/?35473
2746       AliInfo("running reconstruction for HLT");
2747       if (fRawReader) {
2748         AliInfo("reconstructor->Reconstruct(fRawReader, NULL)");
2749         reconstructor->Reconstruct(fRawReader, NULL);
2750       } 
2751       else {
2752         AliInfo("reconstructor->Reconstruct(dummy, NULL)");
2753         TTree* dummy=NULL;
2754         reconstructor->Reconstruct(dummy, NULL);
2755       }
2756     }
2757     AliSysInfo::AddStamp(Form("LRecHLT_%d",eventNr), -1,1,eventNr);
2758   }
2759
2760   AliInfo(Form("kNDetectors = %d",kNDetectors));
2761
2762   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2763     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2764     AliDebug(1, Form("Detector: %s", fgkDetectorName[iDet]));
2765     AliReconstructor* reconstructor = GetReconstructor(iDet);
2766     if (!reconstructor) continue;
2767     AliLoader* loader = fLoader[iDet];
2768     if (!loader) {
2769       AliWarning(Form("No loader is defined for %s!",fgkDetectorName[iDet]));
2770       continue;
2771     }
2772     // conversion of digits
2773     if (fRawReader && reconstructor->HasDigitConversion()) {
2774       AliInfo(Form("converting raw data digits into root objects for %s", 
2775                    fgkDetectorName[iDet]));
2776 //      AliCodeTimerAuto(Form("converting raw data digits into root objects for %s", 
2777 //                            fgkDetectorName[iDet]),0);
2778       loader->LoadDigits("update");
2779       loader->CleanDigits();
2780       loader->MakeDigitsContainer();
2781       TTree* digitsTree = loader->TreeD();
2782       reconstructor->ConvertDigits(fRawReader, digitsTree);
2783       loader->WriteDigits("OVERWRITE");
2784       loader->UnloadDigits();
2785     }
2786     // local reconstruction
2787     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
2788     //AliCodeTimerAuto(Form("running reconstruction for %s", fgkDetectorName[iDet]),0);
2789     AliDebug(1, "Loading Rec Points");
2790     loader->LoadRecPoints("update");
2791     AliDebug(1, "Cleaning Rec Points");
2792     loader->CleanRecPoints();
2793     AliDebug(1, "Making Rec Points Container");
2794     loader->MakeRecPointsContainer();
2795     TTree* clustersTree = loader->TreeR();
2796     if (fRawReader && !reconstructor->HasDigitConversion()) {
2797       reconstructor->Reconstruct(fRawReader, clustersTree);
2798     } 
2799     else {
2800       AliDebug(1, "Loading Digits");
2801       loader->LoadDigits("read");
2802       TTree* digitsTree = loader->TreeD();
2803       AliDebug(1, Form("Digits Tree = %p",digitsTree));
2804       if (!digitsTree) {
2805         AliError(Form("Can't get the %s digits tree", fgkDetectorName[iDet]));
2806         if (fStopOnError) 
2807           return kFALSE;
2808       } 
2809       else {
2810         AliDebug(1, "Digits -> Clusters");
2811         reconstructor->Reconstruct(digitsTree, clustersTree);
2812         if (fRunQA && IsInTasks(AliQAv1::kDIGITSR)) {
2813           AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2814           AliQAManager::QAManager()->RunOneEventInOneDetector(iDet, digitsTree) ; 
2815         }
2816       }
2817       loader->UnloadDigits();
2818     }
2819     if (fRunQA && IsInTasks(AliQAv1::kRECPOINTS)) {
2820       AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2821       AliQAManager::QAManager()->RunOneEventInOneDetector(iDet, clustersTree) ; 
2822     }
2823     loader->WriteRecPoints("OVERWRITE");
2824     loader->UnloadRecPoints();
2825     AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr), iDet,1,eventNr);
2826   }
2827   if (!IsSelected("CTP", detStr)) AliDebug(10,"No CTP");
2828   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2829     AliError(Form("the following detectors were not found: %s",
2830                   detStr.Data()));
2831     if (fStopOnError) 
2832       return kFALSE;
2833   }
2834   eventNr++;
2835   return kTRUE;
2836 }
2837 //_____________________________________________________________________________
2838 Bool_t AliReconstruction::RunSPDTrackleting(AliESDEvent*& esd)
2839 {
2840 // run the SPD trackleting (for SPD efficiency purpouses)
2841
2842   AliCodeTimerAuto("",0)
2843
2844   Double_t vtxPos[3] = {0, 0, 0};
2845   Double_t vtxErr[3] = {0.0, 0.0, 0.0};
2846 /*
2847   TArrayF m
2848 /
2849 cVertex(3);
2850   // if(MC)
2851   if (fRunLoader->GetHeader() && fRunLoader->GetHeader()->GenEventHeader()) {
2852     fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(mcVertex);
2853     for (Int_t i = 0; i < 3; i++) vtxPos[i] = mcVertex[i];
2854   }
2855 */
2856   const AliESDVertex *vertex = esd->GetVertex();
2857   if(!vertex){
2858     AliWarning("Vertex not found");
2859     return kFALSE;
2860   }
2861   vertex->GetXYZ(vtxPos);
2862   vertex->GetSigmaXYZ(vtxErr);
2863   if (fSPDTrackleter) {
2864     AliInfo("running the SPD Trackleter for Plane Efficiency Evaluation");
2865
2866     // load clusters
2867     fLoader[0]->LoadRecPoints("read");
2868     TTree* tree = fLoader[0]->TreeR();
2869     if (!tree) {
2870       AliError("Can't get the ITS cluster tree");
2871       return kFALSE;
2872     }
2873     fSPDTrackleter->LoadClusters(tree);
2874     fSPDTrackleter->SetVertex(vtxPos, vtxErr);
2875     // run trackleting
2876     if (fSPDTrackleter->Clusters2Tracks(esd) != 0) {
2877       AliWarning("AliITSTrackleterSPDEff Clusters2Tracks failed");
2878      // fLoader[0]->UnloadRecPoints();
2879       return kFALSE;
2880     }
2881 //fSPDTrackleter->UnloadRecPoints();
2882   } else {
2883     AliWarning("SPDTrackleter not available");
2884     return kFALSE;
2885   }
2886   return kTRUE;
2887 }
2888
2889 //_____________________________________________________________________________
2890 Bool_t AliReconstruction::RunVertexFinder(AliESDEvent*& esd)
2891 {
2892 // run the barrel tracking
2893
2894   AliCodeTimerAuto("",0)
2895
2896   AliVertexer *vertexer = CreateVertexer();
2897   if (!vertexer) return kFALSE;
2898
2899   AliInfo(Form("running the ITS vertex finder: %s",vertexer->ClassName()));
2900   AliESDVertex* vertex = NULL;
2901   if (fLoader[0]) {
2902     fLoader[0]->LoadRecPoints();
2903     TTree* cltree = fLoader[0]->TreeR();
2904     if (cltree) {
2905       if(fDiamondProfileSPD) vertexer->SetVtxStart(fDiamondProfileSPD);
2906       vertex = vertexer->FindVertexForCurrentEvent(cltree);
2907     }
2908     else {
2909       AliError("Can't get the ITS cluster tree");
2910     }
2911     fLoader[0]->UnloadRecPoints();
2912   }
2913   else {
2914     AliError("Can't get the ITS loader");
2915   }
2916   if(!vertex){
2917     AliWarning("Vertex not found");
2918     vertex = new AliESDVertex();
2919     vertex->SetName("default");
2920   }
2921   else {
2922     vertex->SetName("reconstructed");
2923   }
2924
2925   Double_t vtxPos[3];
2926   Double_t vtxErr[3];
2927   vertex->GetXYZ(vtxPos);
2928   vertex->GetSigmaXYZ(vtxErr);
2929
2930   esd->SetPrimaryVertexSPD(vertex);
2931   AliESDVertex *vpileup = NULL;
2932   Int_t novertices = 0;
2933   vpileup = vertexer->GetAllVertices(novertices);
2934   if(novertices>1){
2935     for (Int_t kk=1; kk<novertices; kk++)esd->AddPileupVertexSPD(&vpileup[kk]);
2936   }
2937   /*
2938   // if SPD multiplicity has been determined, it is stored in the ESD
2939   AliMultiplicity *mult = vertexer->GetMultiplicity();
2940   if(mult)esd->SetMultiplicity(mult);
2941   */
2942   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2943     if (fTracker[iDet]) fTracker[iDet]->SetVertex(vtxPos, vtxErr);
2944   }  
2945   delete vertex;
2946
2947   delete vertexer;
2948
2949   return kTRUE;
2950 }
2951
2952 //_____________________________________________________________________________
2953 Bool_t AliReconstruction::RunMultFinder(AliESDEvent*& esd)
2954 {
2955   // run the trackleter for multiplicity study
2956
2957   AliCodeTimerAuto("",0)
2958
2959   AliTrackleter *trackleter = CreateMultFinder();
2960   if (!trackleter) return kFALSE;
2961
2962   AliInfo(Form("running the ITS multiplicity finder: %s",trackleter->ClassName()));
2963
2964   if (fLoader[0]) {
2965     fLoader[0]->LoadRecPoints();
2966     TTree* cltree = fLoader[0]->TreeR();
2967     if (cltree) {
2968       trackleter->Reconstruct(esd,cltree);
2969       AliMultiplicity *mult = trackleter->GetMultiplicity();
2970       if(mult) esd->SetMultiplicity(mult);
2971     }
2972     else {
2973       AliError("Can't get the ITS cluster tree");
2974     }
2975     fLoader[0]->UnloadRecPoints();
2976   }
2977   else {
2978     AliError("Can't get the ITS loader");
2979   }
2980
2981   delete trackleter;
2982
2983   return kTRUE;
2984 }
2985
2986 //_____________________________________________________________________________
2987 Bool_t AliReconstruction::RunMuonTracking(AliESDEvent*& esd)
2988 {
2989 // run the muon spectrometer tracking
2990
2991   AliCodeTimerAuto("",0)
2992
2993   if (!fRunLoader) {
2994     AliError("Missing runLoader!");
2995     return kFALSE;
2996   }
2997   Int_t iDet =  GetDetIndex("MUON"); // for MUON
2998
2999   // Get a pointer to the MUON reconstructor
3000   AliReconstructor *reconstructor = GetReconstructor(iDet);
3001   if (!reconstructor) return kFALSE;
3002
3003   
3004   TString detName = fgkDetectorName[iDet];
3005   AliDebug(1, Form("%s tracking", detName.Data()));
3006   AliTracker *tracker =  reconstructor->CreateTracker();
3007   if (!tracker) {
3008     AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
3009     return kFALSE;
3010   }
3011      
3012   // read RecPoints
3013   fLoader[iDet]->LoadRecPoints("read");  
3014
3015   tracker->LoadClusters(fLoader[iDet]->TreeR());
3016   
3017   Int_t rv = tracker->Clusters2Tracks(esd);
3018   
3019   fLoader[iDet]->UnloadRecPoints();
3020
3021   tracker->UnloadClusters();
3022   
3023   if ( rv )
3024   {
3025     AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
3026     return kFALSE;
3027   }
3028   
3029   return kTRUE;
3030 }
3031
3032
3033 //_____________________________________________________________________________
3034 Bool_t AliReconstruction::RunMFTTrackingMU(AliESDEvent*& esd) {
3035
3036   // AU
3037
3038   // run the global muon tracking: matching the MUON tracks with the MFT clusters
3039
3040   AliCodeTimerAuto("",0)
3041
3042   if (!fRunLoader) {
3043     AliError("Missing runLoader!");
3044     return kFALSE;
3045   }
3046   Int_t iDet = GetDetIndex("MFT"); // for MFT
3047
3048   // Get a pointer to the MFT reconstructor
3049   AliReconstructor *reconstructor = GetReconstructor(iDet);
3050   if (!reconstructor) return kFALSE;
3051   
3052   TString detName = fgkDetectorName[iDet];
3053   AliDebug(1, Form("%s tracking for muon tracks", detName.Data()));
3054   AliTracker *tracker = reconstructor->CreateTracker();
3055   if (!tracker) {
3056     AliWarning(Form("couldn't create a Muon tracker for %s", detName.Data()));
3057     return kFALSE;
3058   }
3059      
3060   // read RecPoints
3061   fLoader[iDet]->LoadRecPoints("read");  
3062
3063   tracker->LoadClusters(fLoader[iDet]->TreeR());
3064   
3065   Int_t rv = tracker->Clusters2Tracks(esd);
3066   
3067   fLoader[iDet]->UnloadRecPoints();
3068
3069   tracker->UnloadClusters();
3070   
3071   if (rv) {
3072     AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
3073     return kFALSE;
3074   }
3075   
3076   return kTRUE;
3077
3078 }
3079
3080 //_____________________________________________________________________________
3081 Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd,AliESDpid &PID)
3082 {
3083 // run the barrel tracking
3084   static Int_t eventNr=0;
3085   AliCodeTimerAuto("",0)
3086
3087   AliInfo("running tracking");
3088
3089   // Set the event info which is used
3090   // by the trackers in order to obtain
3091   // information about read-out detectors,
3092   // trigger etc.
3093   AliDebug(1, "Setting event info");
3094   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3095     if (!fTracker[iDet]) continue;
3096     fTracker[iDet]->SetEventInfo(&fEventInfo);
3097   }
3098
3099   //Fill the ESD with the T0 info (will be used by the TOF) 
3100   if (fReconstructor[11] && fLoader[11]) {
3101     fLoader[11]->LoadRecPoints("READ");
3102     TTree *treeR = fLoader[11]->TreeR();
3103     if (treeR) {
3104       GetReconstructor(11)->FillESD((TTree *)NULL,treeR,esd);
3105     }
3106   }
3107
3108   // pass 1: TPC + ITS inwards
3109   for (Int_t iDet = 1; iDet >= 0; iDet--) {
3110     if (!fTracker[iDet]) continue;
3111     AliDebug(1, Form("%s tracking", fgkDetectorName[iDet]));
3112
3113     // load clusters
3114     fLoader[iDet]->LoadRecPoints("read");
3115     AliSysInfo::AddStamp(Form("RLoadCluster%s_%d",fgkDetectorName[iDet],eventNr),iDet,1, eventNr);
3116     TTree* tree = fLoader[iDet]->TreeR();
3117     if (!tree) {
3118       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
3119       return kFALSE;
3120     }
3121     fTracker[iDet]->LoadClusters(tree);
3122     AliSysInfo::AddStamp(Form("TLoadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
3123     // run tracking
3124     if (fTracker[iDet]->Clusters2TracksHLT(esd, fhltesd) != 0) {
3125       AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
3126       return kFALSE;
3127     }
3128     AliSysInfo::AddStamp(Form("Tracking0%s_%d",fgkDetectorName[iDet],eventNr), iDet,3,eventNr);
3129     // preliminary PID in TPC needed by the ITS tracker
3130     if (iDet == 1) {
3131       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
3132       PID.MakePIDForTracking(esd);
3133       AliSysInfo::AddStamp(Form("MakePID0%s_%d",fgkDetectorName[iDet],eventNr), iDet,4,eventNr);
3134     } 
3135   }
3136
3137   // pass 2: ALL backwards
3138
3139   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3140     if (!fTracker[iDet]) continue;
3141     AliDebug(1, Form("%s back propagation", fgkDetectorName[iDet]));
3142
3143     // load clusters
3144     if (iDet > 1) {     // all except ITS, TPC
3145       TTree* tree = NULL;
3146       fLoader[iDet]->LoadRecPoints("read");
3147       AliSysInfo::AddStamp(Form("RLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,1, eventNr);
3148       tree = fLoader[iDet]->TreeR();
3149       if (!tree) {
3150         AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
3151         return kFALSE;
3152       }
3153       fTracker[iDet]->LoadClusters(tree); 
3154       AliSysInfo::AddStamp(Form("TLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
3155     }
3156
3157     // run tracking
3158     if (iDet>1) // start filling residuals for the "outer" detectors
3159       if (fRunGlobalQA) {
3160         AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
3161         TObjArray ** arr = AliTracker::GetResidualsArray() ; 
3162         if (arr) {
3163           AliRecoParam::EventSpecie_t es=fRecoParam.GetEventSpecie();
3164           TObjArray * elem = arr[AliRecoParam::AConvert(es)];
3165           if ( elem && (! elem->At(0)) ) {
3166             AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
3167             if (qadm) qadm->InitRecPointsForTracker() ; 
3168           }
3169         }
3170         //      AliSysInfo::AddStamp(Form("QAInitResid%s_%d",fgkDetectorName[iDet],eventNr), iDet,0, eventNr);
3171       }
3172     if (fTracker[iDet]->PropagateBack(esd) != 0) {
3173       AliError(Form("%s backward propagation failed", fgkDetectorName[iDet]));
3174       //      return kFALSE;
3175     }
3176     AliSysInfo::AddStamp(Form("Tracking1%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
3177
3178     // unload clusters
3179     if (iDet > 3) {     // all except ITS, TPC, TRD and TOF
3180       fTracker[iDet]->UnloadClusters();
3181       fLoader[iDet]->UnloadRecPoints();
3182     }
3183     // updated PID in TPC needed by the ITS tracker -MI
3184     if (iDet == 1) {
3185       //GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
3186       //AliESDpid::MakePID(esd);
3187       PID.MakePIDForTracking(esd);
3188       AliSysInfo::AddStamp(Form("MakePID1%s_%d",fgkDetectorName[iDet],eventNr), iDet,4,eventNr);
3189     }
3190
3191   }
3192   //stop filling residuals for the "outer" detectors
3193   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
3194
3195   // pass 3: TRD + TPC + ITS refit inwards
3196
3197   for (Int_t iDet = 2; iDet >= 0; iDet--) {
3198     if (!fTracker[iDet]) continue;
3199     AliDebug(1, Form("%s inward refit", fgkDetectorName[iDet]));
3200
3201     // run tracking
3202     if (iDet<2) // start filling residuals for TPC and ITS
3203       if (fRunGlobalQA) {
3204         AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
3205         TObjArray ** arr = AliTracker::GetResidualsArray() ; 
3206         if (arr) {
3207           AliRecoParam::EventSpecie_t es=fRecoParam.GetEventSpecie();
3208           TObjArray * elem = arr[AliRecoParam::AConvert(es)];
3209           if ( elem && (! elem->At(0)) ) {
3210             AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
3211             if (qadm) qadm->InitRecPointsForTracker() ; 
3212           }
3213         }
3214       }
3215     
3216     if (fTracker[iDet]->RefitInward(esd) != 0) {
3217       AliError(Form("%s inward refit failed", fgkDetectorName[iDet]));
3218       //      return kFALSE;
3219     }
3220     // run postprocessing
3221     if (fTracker[iDet]->PostProcess(esd) != 0) {
3222       AliError(Form("%s postprocessing failed", fgkDetectorName[iDet]));
3223       //      return kFALSE;
3224     }
3225     AliSysInfo::AddStamp(Form("Tracking2%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
3226   }
3227
3228   // write space-points to the ESD in case alignment data output
3229   // is switched on
3230   if (fWriteAlignmentData) {
3231     WriteAlignmentData(esd);
3232     AliSysInfo::AddStamp(Form("WrtAlignData_%d",eventNr), 0,0, eventNr);
3233   }
3234   
3235   for (Int_t iDet = 3; iDet >= 0; iDet--) {
3236     if (!fTracker[iDet]) continue;
3237     // unload clusters
3238     fTracker[iDet]->UnloadClusters();
3239     AliSysInfo::AddStamp(Form("TUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,4, eventNr);
3240     fLoader[iDet]->UnloadRecPoints();
3241     AliSysInfo::AddStamp(Form("RUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,5, eventNr);
3242   }
3243   // stop filling residuals for TPC and ITS
3244   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
3245
3246   eventNr++;
3247   return kTRUE;
3248 }
3249
3250 //_____________________________________________________________________________
3251 Bool_t AliReconstruction::CleanESD(AliESDEvent *esd){
3252   //
3253   // Remove the data which are not needed for the physics analysis.
3254   //
3255
3256   Int_t nTracks=esd->GetNumberOfTracks();
3257   Int_t nV0s=esd->GetNumberOfV0s();
3258   AliInfo
3259   (Form("Number of ESD tracks and V0s before cleaning: %d %d",nTracks,nV0s));
3260
3261   Float_t cleanPars[]={fV0DCAmax,fV0CsPmin,fDmax,fZmax};
3262   Bool_t rc=esd->Clean(cleanPars);
3263
3264   nTracks=esd->GetNumberOfTracks();
3265   nV0s=esd->GetNumberOfV0s();
3266   AliInfo
3267   (Form("Number of ESD tracks and V0s after cleaning %d %d",nTracks,nV0s));
3268
3269   return rc;
3270 }
3271
3272 //_____________________________________________________________________________
3273 Bool_t AliReconstruction::FillESD(AliESDEvent*& esd, const TString& detectors)
3274 {
3275 // fill the event summary data
3276
3277   AliCodeTimerAuto("",0)
3278     static Int_t eventNr=0; 
3279   TString detStr = detectors;
3280   
3281   AliSysInfo::AddStamp(Form("FillESDb%d",eventNr), -19,-19, eventNr);
3282   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3283   if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3284     AliReconstructor* reconstructor = GetReconstructor(iDet);
3285     if (!reconstructor) continue;
3286     AliDebug(1, Form("filling ESD for %s", fgkDetectorName[iDet]));
3287     TTree* clustersTree = NULL;
3288     if (fLoader[iDet]) {
3289       fLoader[iDet]->LoadRecPoints("read");
3290       clustersTree = fLoader[iDet]->TreeR();
3291       if (!clustersTree) {
3292         AliError(Form("Can't get the %s clusters tree", 
3293                       fgkDetectorName[iDet]));
3294         if (fStopOnError) return kFALSE;
3295       }
3296     }
3297     if (fRawReader && !reconstructor->HasDigitConversion()) {
3298       reconstructor->FillESD(fRawReader, clustersTree, esd);
3299     } else {
3300       TTree* digitsTree = NULL;
3301       if (fLoader[iDet]) {
3302         fLoader[iDet]->LoadDigits("read");
3303         digitsTree = fLoader[iDet]->TreeD();
3304         if (!digitsTree) {
3305           AliError(Form("Can't get the %s digits tree", 
3306                         fgkDetectorName[iDet]));
3307           if (fStopOnError) return kFALSE;
3308         }
3309       }
3310       reconstructor->FillESD(digitsTree, clustersTree, esd);
3311       if (fLoader[iDet]) fLoader[iDet]->UnloadDigits();
3312     }
3313     if (fLoader[iDet]) {
3314       fLoader[iDet]->UnloadRecPoints();
3315     }
3316   }
3317   
3318   if (!IsSelected("CTP", detStr)) AliDebug(10,"No CTP");
3319   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
3320     AliError(Form("the following detectors were not found: %s", 
3321                   detStr.Data()));
3322     if (fStopOnError) return kFALSE;
3323   }
3324   AliSysInfo::AddStamp(Form("FillESDe%d",eventNr), -20,-20, eventNr);
3325   eventNr++;
3326   return kTRUE;
3327 }
3328
3329 //_____________________________________________________________________________
3330 Bool_t AliReconstruction::FillTriggerESD(AliESDEvent*& esd)
3331 {
3332   // Reads the trigger decision which is
3333   // stored in Trigger.root file and fills
3334   // the corresponding esd entries
3335
3336   AliCodeTimerAuto("",0)
3337   
3338   AliInfo("Filling trigger information into the ESD");
3339
3340   if (fRawReader) {
3341     AliCTPRawStream input(fRawReader);
3342     if (!input.Next()) {
3343       AliWarning("No valid CTP (trigger) DDL raw data is found ! The trigger info is taken from the event header!");
3344     }
3345     else {
3346       if (esd->GetTriggerMask() != input.GetClassMask())
3347         AliError(Form("Invalid trigger pattern found in CTP raw-data: %llx %llx",
3348                       input.GetClassMask(),esd->GetTriggerMask()));
3349       if (esd->GetTriggerMaskNext50() != input.GetClassMaskNext50())
3350         AliError(Form("Invalid trigger pattern found in CTP raw-data Next50: %llx %llx",
3351                       input.GetClassMaskNext50(),esd->GetTriggerMaskNext50()));
3352       if (esd->GetOrbitNumber() != input.GetOrbitID())
3353         AliError(Form("Invalid orbit id found in CTP raw-data: %x %x",
3354                       input.GetOrbitID(),esd->GetOrbitNumber()));
3355       if (esd->GetBunchCrossNumber() != input.GetBCID())
3356         AliError(Form("Invalid bunch-crossing id found in CTP raw-data: %x %x",
3357                       input.GetBCID(),esd->GetBunchCrossNumber()));
3358       AliESDHeader* esdheader = esd->GetHeader();
3359       esdheader->SetL0TriggerInputs(input.GetL0Inputs());
3360       esdheader->SetL1TriggerInputs(input.GetL1Inputs());
3361       esdheader->SetL2TriggerInputs(input.GetL2Inputs());
3362       // IR
3363       //      UInt_t orbit=input.GetOrbitID();
3364       for(Int_t i=0 ; i<input.GetNIRs() ; i++ ) {
3365         esdheader->AddTriggerIR(input.GetIR(i));
3366       }
3367        AliCentralTrigger* rlCTP = fRunLoader->GetTrigger();
3368        if (rlCTP) {
3369          rlCTP->SetL0TriggerInputs(input.GetL0Inputs());
3370          rlCTP->SetL1TriggerInputs(input.GetL1Inputs());
3371          rlCTP->SetL2TriggerInputs(input.GetL2Inputs());
3372        }
3373     }
3374     if (fIsNewRunLoader) fRunLoader->TreeCT()->Fill();
3375   }
3376   return kTRUE;
3377 }
3378 //_____________________________________________________________________________
3379 Bool_t AliReconstruction::FillTriggerScalers(AliESDEvent*& esd)
3380 {
3381   //Scalers
3382   //fRunScalers->Print();
3383   if(fRunScalers && fRunScalers->CheckRunScalers()){
3384      AliTimeStamp* timestamp = new AliTimeStamp(esd->GetOrbitNumber(), esd->GetPeriodNumber(), esd->GetBunchCrossNumber());
3385      //AliTimeStamp* timestamp = new AliTimeStamp(10308000, 0, (ULong64_t)486238);
3386      AliESDHeader* esdheader = fesd->GetHeader();
3387      for(Int_t i=0;i<50;i++){
3388           if((1ull<<i) & esd->GetTriggerMask()){
3389           AliTriggerScalersESD* scalesd = fRunScalers->GetScalersForEventClass( timestamp, i+1);
3390           if(scalesd)esdheader->SetTriggerScalersRecord(scalesd);
3391         }
3392      }
3393      for(Int_t i=0;i<50;i++){
3394           if((1ull<<i) & esd->GetTriggerMaskNext50()){
3395           AliTriggerScalersESD* scalesd = fRunScalers->GetScalersForEventClass( timestamp, i+51);
3396           if(scalesd)esdheader->SetTriggerScalersRecord(scalesd);
3397         }
3398      }
3399      const AliTriggerScalersRecordESD* scalrecEvent = fRunScalers->GetScalersDeltaForEvent( timestamp);
3400      const AliTriggerScalersRecordESD* scalrecRun = fRunScalers->GetScalersDeltaForRun();
3401      if (scalrecEvent) esdheader->SetTriggerScalersDeltaEvent(scalrecEvent);
3402      if (scalrecRun) esdheader->SetTriggerScalersDeltaRun(scalrecRun);
3403   }
3404   return kTRUE;
3405 }
3406 //_____________________________________________________________________________
3407 Bool_t AliReconstruction::FillRawEventHeaderESD(AliESDEvent*& esd)
3408 {
3409   // 
3410   // Filling information from RawReader Header
3411   // 
3412
3413   if (!fRawReader) return kFALSE;
3414
3415   AliInfo("Filling information from RawReader Header");
3416
3417   esd->SetBunchCrossNumber(fRawReader->GetBCID());
3418   esd->SetOrbitNumber(fRawReader->GetOrbitID());
3419   esd->SetPeriodNumber(fRawReader->GetPeriod());
3420
3421   esd->SetTimeStamp(fRawReader->GetTimestamp());  
3422   esd->SetEventType(fRawReader->GetType());
3423
3424   return kTRUE;
3425 }
3426
3427
3428 //_____________________________________________________________________________
3429 Bool_t AliReconstruction::IsSelected(TString detName, TString& detectors) const
3430 {
3431 // check whether detName is contained in detectors
3432 // if yes, it is removed from detectors
3433
3434   // check if all detectors are selected
3435   if ((detectors.CompareTo("ALL") == 0) ||
3436       detectors.BeginsWith("ALL ") ||
3437       detectors.EndsWith(" ALL") ||
3438       detectors.Contains(" ALL ")) {
3439     detectors = "ALL";
3440     return kTRUE;
3441   }
3442
3443   // search for the given detector
3444   Bool_t result = kFALSE;
3445   if ((detectors.CompareTo(detName) == 0) ||
3446       detectors.BeginsWith(detName+" ") ||
3447       detectors.EndsWith(" "+detName) ||
3448       detectors.Contains(" "+detName+" ")) {
3449     detectors.ReplaceAll(detName, "");
3450     result = kTRUE;
3451   }
3452
3453   // clean up the detectors string
3454   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
3455   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
3456   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
3457
3458   return result;
3459 }
3460
3461 //_____________________________________________________________________________
3462 Bool_t AliReconstruction::InitRunLoader()
3463 {
3464 // get or create the run loader
3465
3466   if (gAlice) delete gAlice;
3467   gAlice = NULL;
3468
3469   TFile *gafile = TFile::Open(fGAliceFileName.Data());
3470   //  if (!gSystem->AccessPathName(fGAliceFileName.Data())) { // galice.root exists
3471   if (gafile) { // galice.root exists
3472     gafile->Close();
3473     delete gafile;
3474
3475     // load all base libraries to get the loader classes
3476     TString libs = gSystem->GetLibraries();
3477     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3478       TString detName = fgkDetectorName[iDet];
3479       if (libs.Contains("lib" + detName + "base.so")) continue;
3480       gSystem->Load("lib" + detName + "base");
3481     }
3482     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data());
3483     if (!fRunLoader) {
3484       AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
3485       CleanUp();
3486       return kFALSE;
3487     }
3488
3489     fRunLoader->CdGAFile();
3490     fRunLoader->LoadgAlice();
3491
3492     //PH This is a temporary fix to give access to the kinematics
3493     //PH that is needed for the labels of ITS clusters
3494     fRunLoader->LoadHeader();
3495     fRunLoader->LoadKinematics();
3496
3497   } else {               // galice.root does not exist
3498     if (!fRawReader) {
3499       AliError(Form("the file %s does not exist", fGAliceFileName.Data()));
3500     }
3501     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data(),
3502                                     AliConfig::GetDefaultEventFolderName(),
3503                                     "recreate");
3504     if (!fRunLoader) {
3505       AliError(Form("could not create run loader in file %s", 
3506                     fGAliceFileName.Data()));
3507       CleanUp();
3508       return kFALSE;
3509     }
3510     fIsNewRunLoader = kTRUE;
3511     fRunLoader->MakeTree("E");
3512     fRunLoader->MakeTree("GG");
3513
3514     if (fNumberOfEventsPerFile > 0)
3515       fRunLoader->SetNumberOfEventsPerFile(fNumberOfEventsPerFile);
3516     else
3517       fRunLoader->SetNumberOfEventsPerFile((UInt_t)-1);
3518   }
3519
3520   return kTRUE;
3521 }
3522
3523 //_____________________________________________________________________________
3524 AliReconstructor* AliReconstruction::GetReconstructor(Int_t iDet)
3525 {
3526 // get the reconstructor object and the loader for a detector
3527
3528   if (fReconstructor[iDet]) {
3529     if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
3530       const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
3531       fReconstructor[iDet]->SetRecoParam(par);
3532       fReconstructor[iDet]->SetRunInfo(fRunInfo);
3533     }
3534     return fReconstructor[iDet];
3535   }
3536
3537   // load the reconstructor object
3538   TPluginManager* pluginManager = gROOT->GetPluginManager();
3539   TString detName = fgkDetectorName[iDet];
3540   TString recName = "Ali" + detName + "Reconstructor";
3541
3542   if (!fIsNewRunLoader && !fRunLoader->GetLoader(detName+"Loader") && (detName != "HLT")) return NULL;
3543
3544   AliReconstructor* reconstructor = NULL;
3545   // first check if a plugin is defined for the reconstructor
3546   TPluginHandler* pluginHandler = 
3547     pluginManager->FindHandler("AliReconstructor", detName);
3548   // if not, add a plugin for it
3549   if (!pluginHandler) {
3550     AliDebug(1, Form("defining plugin for %s", recName.Data()));
3551     TString libs = gSystem->GetLibraries();
3552     if (libs.Contains("lib" + detName + "base.so") ||
3553         (gSystem->Load("lib" + detName + "base") >= 0)) {
3554       pluginManager->AddHandler("AliReconstructor", detName, 
3555                                 recName, detName + "rec", recName + "()");
3556     } else {
3557       pluginManager->AddHandler("AliReconstructor", detName, 
3558                                 recName, detName, recName + "()");
3559     }
3560     pluginHandler = pluginManager->FindHandler("AliReconstructor", detName);
3561   }
3562   if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
3563     reconstructor = (AliReconstructor*) pluginHandler->ExecPlugin(0);
3564   }
3565
3566    // check if the upgrade reconstructor should be used instead of the standard one
3567   if(fUpgradeMask[iDet]) {
3568     if(reconstructor) delete reconstructor;
3569     TClass *cl = new TClass(Form("Ali%sUpgradeReconstructor",fgkDetectorName[iDet]));
3570     reconstructor = (AliReconstructor*)(cl->New());
3571    }
3572
3573   if (reconstructor) {
3574     TObject* obj = fOptions.FindObject(detName.Data());
3575     if (obj) reconstructor->SetOption(obj->GetTitle());
3576     reconstructor->SetRunInfo(fRunInfo);
3577     reconstructor->SetHLTESD(fhltesd);
3578     reconstructor->Init();
3579     fReconstructor[iDet] = reconstructor;
3580   }
3581
3582   // get or create the loader
3583   if (detName != "HLT") {
3584     fLoader[iDet] = fRunLoader->GetLoader(detName + "Loader");
3585     if (!fLoader[iDet]) {
3586       AliConfig::Instance()
3587         ->CreateDetectorFolders(fRunLoader->GetEventFolder(), 
3588                                 detName, detName);
3589       // first check if a plugin is defined for the loader
3590       pluginHandler = 
3591         pluginManager->FindHandler("AliLoader", detName);
3592       // if not, add a plugin for it
3593       if (!pluginHandler) {
3594         TString loaderName = "Ali" + detName + "Loader";
3595         AliDebug(1, Form("defining plugin for %s", loaderName.Data()));
3596         pluginManager->AddHandler("AliLoader", detName, 
3597                                   loaderName, detName + "base", 
3598                                   loaderName + "(const char*, TFolder*)");
3599         pluginHandler = pluginManager->FindHandler("AliLoader", detName);
3600       }
3601       if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
3602         fLoader[iDet] = 
3603           (AliLoader*) pluginHandler->ExecPlugin(2, detName.Data(), 
3604                                                  fRunLoader->GetEventFolder());
3605       }
3606       if (!fLoader[iDet]) {   // use default loader
3607         fLoader[iDet] = new AliLoader(detName, fRunLoader->GetEventFolder());
3608       }
3609       if (!fLoader[iDet]) {
3610         AliWarning(Form("couldn't get loader for %s", detName.Data()));
3611         if (fStopOnError) return NULL;
3612       } else {
3613         fRunLoader->AddLoader(fLoader[iDet]);
3614         fRunLoader->CdGAFile();
3615         if (gFile && !gFile->IsWritable()) gFile->ReOpen("UPDATE");
3616         fRunLoader->Write(0, TObject::kOverwrite);
3617       }
3618     }
3619   }
3620       
3621   if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
3622     const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
3623     if (reconstructor) {
3624       reconstructor->SetRecoParam(par);
3625       reconstructor->SetRunInfo(fRunInfo);
3626     }
3627   }
3628   return reconstructor;
3629 }
3630
3631 //_____________________________________________________________________________
3632 AliVertexer* AliReconstruction::CreateVertexer()
3633 {
3634 // create the vertexer
3635 // Please note that the caller is the owner of the
3636 // vertexer
3637
3638   AliVertexer* vertexer = NULL;
3639   AliReconstructor* itsReconstructor = GetReconstructor(0);
3640   if (itsReconstructor && ((fRunLocalReconstruction.Contains("ITS")) || 
3641                            fRunTracking.Contains("ITS") || fFillESD.Contains("ITS") )) {
3642     vertexer = itsReconstructor->CreateVertexer();
3643   }
3644   if (!vertexer) {
3645     AliWarning("couldn't create a vertexer for ITS");
3646   }
3647
3648   return vertexer;
3649 }
3650
3651 //_____________________________________________________________________________
3652 AliTrackleter* AliReconstruction::CreateMultFinder()
3653 {
3654 // create the ITS trackleter for mult. estimation
3655 // Please note that the caller is the owner of the
3656 // trackleter
3657
3658   AliTrackleter* trackleter = NULL;
3659   AliReconstructor* itsReconstructor = GetReconstructor(0);
3660   if (itsReconstructor && ((fRunLocalReconstruction.Contains("ITS")) || 
3661                            fRunTracking.Contains("ITS") || fFillESD.Contains("ITS") )) {
3662     trackleter = itsReconstructor->CreateMultFinder();
3663   }
3664   else {
3665     AliWarning("ITS is not in reconstruction, switching off RunMultFinder");
3666     fRunMultFinder = kFALSE;
3667   }
3668
3669   return trackleter;
3670 }
3671
3672 //_____________________________________________________________________________
3673 Bool_t AliReconstruction::CreateTrackers(const TString& detectors)
3674 {
3675 // create the trackers
3676         AliInfo("Creating trackers");
3677
3678   TString detStr = detectors;
3679   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3680     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3681     AliReconstructor* reconstructor = GetReconstructor(iDet);
3682     if (!reconstructor) continue;
3683     TString detName = fgkDetectorName[iDet];
3684     if (detName == "MUON") {
3685       fRunMuonTracking = kTRUE;
3686       continue;
3687     }
3688     if (detName == "MFT") {           // AU    
3689       fRunMFTTrackingMU = kTRUE;      // AU
3690       continue;                       // AU
3691     }                                 // AU
3692
3693     fTracker[iDet] = reconstructor->CreateTracker();
3694     if (!fTracker[iDet] && (iDet < 7)) {
3695       AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
3696       if (fStopOnError) return kFALSE;
3697     }
3698     AliSysInfo::AddStamp(Form("LTracker%s",fgkDetectorName[iDet]), iDet,0);
3699   }
3700
3701   return kTRUE;
3702 }
3703
3704 //_____________________________________________________________________________
3705 void AliReconstruction::CleanUp()
3706 {
3707 // delete trackers and the run loader and close and delete the file
3708   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3709     if (fReconstructor[iDet]) fReconstructor[iDet]->SetRecoParam(NULL);
3710     delete fReconstructor[iDet];
3711     fReconstructor[iDet] = NULL;
3712     fLoader[iDet] = NULL;
3713     delete fTracker[iDet];
3714     fTracker[iDet] = NULL;
3715   }
3716
3717   delete fRunInfo;
3718   fRunInfo = NULL;
3719
3720   delete fSPDTrackleter;
3721   fSPDTrackleter = NULL;
3722
3723   delete ftVertexer;
3724   ftVertexer = NULL;
3725   
3726   delete fRunLoader;
3727   fRunLoader = NULL;
3728   delete fRawReader;
3729   fRawReader = NULL;
3730   delete fParentRawReader;
3731   fParentRawReader=NULL;
3732
3733   delete fESDpid;
3734   fESDpid = NULL;
3735
3736   if (ffile) {
3737     ffile->Close();
3738     delete ffile;
3739     ffile = NULL;
3740   }
3741
3742   if (AliQAManager::QAManager())
3743     AliQAManager::QAManager()->ShowQA() ; 
3744   //  AliQAManager::Destroy() ;
3745   delete fAnalysis; 
3746   fAnalysis = NULL;
3747 }
3748
3749 void AliReconstruction::WriteAlignmentData(AliESDEvent* esd)
3750 {
3751   // Write space-points which are then used in the alignment procedures
3752   // For the moment only ITS, TPC, TRD and TOF
3753
3754   Int_t ntracks = esd->GetNumberOfTracks();
3755   for (Int_t itrack = 0; itrack < ntracks; itrack++)
3756     {
3757       AliESDtrack *track = esd->GetTrack(itrack);
3758       Int_t nsp = 0;
3759       Int_t idx[200];
3760       for (Int_t i=0; i<200; ++i) idx[i] = -1; //PH avoid uninitialized values
3761       for (Int_t iDet = 5; iDet >= 0; iDet--) {// TOF, TRD, TPC, ITS clusters
3762           nsp += (iDet==GetDetIndex("TRD")) ? track->GetTRDntracklets():track->GetNcls(iDet);
3763
3764           if (iDet==GetDetIndex("ITS")) { // ITS "extra" clusters
3765              track->GetClusters(iDet,idx);
3766              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nsp++;
3767           }  
3768       }
3769
3770       if (nsp) {
3771         AliTrackPointArray *sp = new AliTrackPointArray(nsp);
3772         track->SetTrackPointArray(sp);
3773         Int_t isptrack = 0;
3774         for (Int_t iDet = 5; iDet >= 0; iDet--) {
3775           AliTracker *tracker = fTracker[iDet];
3776           if (!tracker) continue;
3777           Int_t nspdet = (iDet==GetDetIndex("TRD")) ? track->GetTRDtracklets(idx):track->GetClusters(iDet,idx);
3778
3779           if (iDet==GetDetIndex("ITS")) // ITS "extra" clusters             
3780              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nspdet++;
3781
3782           if (nspdet <= 0) continue;
3783           AliTrackPoint p;
3784           Int_t isp = 0;
3785           Int_t isp2 = 0;
3786           while (isp2 < nspdet) {
3787             Bool_t isvalid=kTRUE;
3788
3789             Int_t index=idx[isp++];
3790             if (index < 0) continue;
3791
3792             TString dets = fgkDetectorName[iDet];
3793             if ((fUseTrackingErrorsForAlignment.CompareTo(dets) == 0) ||
3794             fUseTrackingErrorsForAlignment.BeginsWith(dets+" ") ||
3795             fUseTrackingErrorsForAlignment.EndsWith(" "+dets) ||
3796             fUseTrackingErrorsForAlignment.Contains(" "+dets+" ")) {
3797               isvalid = tracker->GetTrackPointTrackingError(index,p,track);
3798             } else {
3799               isvalid = tracker->GetTrackPoint(index,p); 
3800             } 
3801             isp2++;
3802             if (!isvalid) continue;
3803             if (iDet==GetDetIndex("ITS") && (isp-1)>=6) p.SetExtra();
3804             sp->AddPoint(isptrack,&p); isptrack++;
3805           }
3806         }       
3807       }
3808     }
3809 }
3810
3811 //_____________________________________________________________________________
3812 void AliReconstruction::FillRawDataErrorLog(Int_t iEvent, AliESDEvent* esd)
3813 {
3814   // The method reads the raw-data error log
3815   // accumulated within the rawReader.
3816   // It extracts the raw-data errors related to
3817   // the current event and stores them into
3818   // a TClonesArray inside the esd object.
3819
3820   if (!fRawReader) return;
3821
3822   for(Int_t i = 0; i < fRawReader->GetNumberOfErrorLogs(); i++) {
3823
3824     AliRawDataErrorLog *log = fRawReader->GetErrorLog(i);
3825     if (!log) continue;
3826     if (iEvent != log->GetEventNumber()) continue;
3827
3828     esd->AddRawDataErrorLog(log);
3829   }
3830
3831 }
3832
3833 //_____________________________________________________________________________
3834 // void AliReconstruction::CheckQA()
3835 // {
3836 // check the QA of SIM for this run and remove the detectors 
3837 // with status Fatal
3838   
3839 //      TString newRunLocalReconstruction ; 
3840 //      TString newRunTracking ;
3841 //      TString newFillESD ;
3842 //       
3843 //      for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
3844 //              TString detName(AliQAv1::GetDetName(iDet)) ;
3845 //              AliQAv1 * qa = AliQAv1::Instance(AliQAv1::DETECTORINDEX_t(iDet)) ;       
3846 //      if ( qa->IsSet(AliQAv1::DETECTORINDEX_t(iDet), AliQAv1::kSIM, specie, AliQAv1::kFATAL)) {
3847 //        AliInfo(Form("QA status for %s %s in Hits and/or SDIGITS  and/or Digits was Fatal; No reconstruction performed", 
3848 //                   detName.Data(), AliRecoParam::GetEventSpecieName(es))) ;
3849 //                      } else {
3850 //                      if ( fRunLocalReconstruction.Contains(AliQAv1::GetDetName(iDet)) || 
3851 //                                      fRunLocalReconstruction.Contains("ALL") )  {
3852 //                              newRunLocalReconstruction += detName ; 
3853 //                              newRunLocalReconstruction += " " ;                      
3854 //                      }
3855 //                      if ( fRunTracking.Contains(AliQAv1::GetDetName(iDet)) || 
3856 //                                      fRunTracking.Contains("ALL") )  {
3857 //                              newRunTracking += detName ; 
3858 //                              newRunTracking += " " ;                         
3859 //                      }
3860 //                      if ( fFillESD.Contains(AliQAv1::GetDetName(iDet)) || 
3861 //                                      fFillESD.Contains("ALL") )  {
3862 //                              newFillESD += detName ; 
3863 //                              newFillESD += " " ;                     
3864 //                      }
3865 //              }
3866 //      }
3867 //      fRunLocalReconstruction = newRunLocalReconstruction ; 
3868 //      fRunTracking            = newRunTracking ; 
3869 //      fFillESD                = newFillESD ; 
3870 // }
3871
3872 //_____________________________________________________________________________
3873 Int_t AliReconstruction::GetDetIndex(const char* detector)
3874 {
3875   // return the detector index corresponding to detector
3876   Int_t index = -1 ; 
3877   for (index = 0; index < kNDetectors ; index++) {
3878     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
3879         break ; 
3880   }     
3881   return index ; 
3882 }
3883 //_____________________________________________________________________________
3884 Bool_t AliReconstruction::FinishPlaneEff() {
3885  //
3886  // Here execute all the necessary operationis, at the end of the tracking phase,
3887  // in case that evaluation of PlaneEfficiencies was required for some detector.
3888  // E.g., write into a DataBase file the PlaneEfficiency which have been evaluated.
3889  //
3890  // This Preliminary version works only FOR ITS !!!!!
3891  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3892  //
3893  //  Input: none
3894  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3895  //
3896  Bool_t ret=kFALSE;
3897  TString detStr = fLoadCDB;
3898  //for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
3899  for (Int_t iDet = 0; iDet < 1; iDet++) { // for the time being only ITS
3900    if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3901    if(fTracker[iDet] && fTracker[iDet]->GetPlaneEff()) {
3902       AliPlaneEff *planeeff=fTracker[iDet]->GetPlaneEff();
3903       TString name=planeeff->GetName();
3904       name+=".root";
3905       TFile* pefile = TFile::Open(name, "RECREATE");
3906       ret=(Bool_t)planeeff->Write();
3907       pefile->Close();
3908       if(planeeff->GetCreateHistos()) {
3909         TString hname=planeeff->GetName();
3910         hname+="Histo.root";
3911         ret*=planeeff->WriteHistosToFile(hname,"RECREATE");
3912       }
3913    }
3914    if(fSPDTrackleter) {
3915      AliPlaneEff *planeeff=fSPDTrackleter->GetPlaneEff();
3916       TString name="AliITSPlaneEffSPDtracklet.root";
3917       TFile* pefile = TFile::Open(name, "RECREATE");
3918       ret=(Bool_t)planeeff->Write();
3919       pefile->Close();
3920       AliESDEvent *dummy=NULL;
3921       ret=(Bool_t)fSPDTrackleter->PostProcess(dummy); // take care of writing other files
3922    }
3923  }
3924  return ret;
3925 }
3926 //_____________________________________________________________________________
3927 Bool_t AliReconstruction::InitPlaneEff() {
3928 //
3929  // Here execute all the necessary operations, before of the tracking phase,
3930  // for the evaluation of PlaneEfficiencies, in case required for some detectors.
3931  // E.g., read from a DataBase file a first evaluation of the PlaneEfficiency
3932  // which should be updated/recalculated.
3933  //
3934  // This Preliminary version will work only FOR ITS !!!!!
3935  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3936  //
3937  //  Input: none
3938  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3939  //
3940
3941   fSPDTrackleter = NULL;
3942   TString detStr = fLoadCDB;
3943   if (IsSelected(fgkDetectorName[0], detStr)) {
3944     AliReconstructor* itsReconstructor = GetReconstructor(0);
3945     if (itsReconstructor) {
3946       fSPDTrackleter = itsReconstructor->CreateTrackleter(); // this is NULL unless required in RecoParam
3947     }
3948     if (fSPDTrackleter) {
3949       AliInfo("Trackleter for SPD has been created");
3950     }
3951   }
3952  return kTRUE;
3953 }
3954
3955 //_____________________________________________________________________________
3956 Bool_t AliReconstruction::InitAliEVE()
3957 {
3958   // This method should be called only in case 
3959   // AliReconstruction is run
3960   // within the alieve environment.
3961   // It will initialize AliEVE in a way
3962   // so that it can visualize event processed
3963   // by AliReconstruction.
3964   // The return flag shows whenever the
3965   // AliEVE initialization was successful or not.
3966
3967   TString macroStr(getenv("ALIEVE_ONLINE_MACRO"));
3968
3969   if (macroStr.IsNull())
3970     macroStr.Form("%s/EVE/macros/alieve_online.C",gSystem->ExpandPathName("$ALICE_ROOT"));
3971
3972   AliInfo(Form("Loading AliEVE macro: %s",macroStr.Data()));
3973
3974   if (gROOT->LoadMacro(macroStr.Data()) != 0) return kFALSE;
3975
3976   gROOT->ProcessLine("if (!AliEveEventManager::GetMaster()){new AliEveEventManager();AliEveEventManager::GetMaster()->AddNewEventCommand(\"alieve_online_on_new_event()\");gEve->AddEvent(AliEveEventManager::GetMaster());};");
3977   gROOT->ProcessLine("alieve_online_init()");
3978
3979   return kTRUE;
3980 }
3981   
3982 //_____________________________________________________________________________
3983 void AliReconstruction::RunAliEVE()
3984 {
3985   // Runs AliEVE visualisation of
3986   // the current event.
3987   // Should be executed only after
3988   // successful initialization of AliEVE.
3989
3990   AliInfo("Running AliEVE...");
3991   gROOT->ProcessLine(Form("AliEveEventManager::GetMaster()->SetEvent((AliRunLoader*)%p,(AliRawReader*)%p,(AliESDEvent*)%p,(AliESDfriend*)%p);",fRunLoader,fRawReader,fesd,fesdf));
3992   gSystem->Run();
3993 }
3994
3995 //_____________________________________________________________________________
3996 Bool_t AliReconstruction::SetRunQA(TString detAndAction) 
3997 {
3998         // Allows to run QA for a selected set of detectors
3999         // and a selected set of tasks among RAWS, DIGITSR, RECPOINTS and ESDS
4000         // all selected detectors run the same selected tasks
4001         
4002         if (!detAndAction.Contains(":")) {
4003                 AliError( Form("%s is a wrong syntax, use \"DetectorList:ActionList\" \n", detAndAction.Data()) ) ;
4004                 fRunQA = kFALSE ;
4005                 return kFALSE ;                 
4006         }
4007         Int_t colon = detAndAction.Index(":") ; 
4008         fQADetectors = detAndAction(0, colon) ; 
4009         fQATasks   = detAndAction(colon+1, detAndAction.Sizeof() ) ; 
4010         if (fQATasks.Contains("ALL") ) {
4011                 fQATasks = Form("%d %d %d %d", AliQAv1::kRAWS, AliQAv1::kDIGITSR, AliQAv1::kRECPOINTS, AliQAv1::kESDS) ; 
4012         } else {
4013                 fQATasks.ToUpper() ; 
4014                 TString tempo("") ; 
4015                 if ( fQATasks.Contains("RAW") ) 
4016                         tempo = Form("%d ", AliQAv1::kRAWS) ; 
4017                 if ( fQATasks.Contains("DIGIT") ) 
4018                         tempo += Form("%d ", AliQAv1::kDIGITSR) ; 
4019                 if ( fQATasks.Contains("RECPOINT") ) 
4020                         tempo += Form("%d ", AliQAv1::kRECPOINTS) ; 
4021                 if ( fQATasks.Contains("ESD") ) 
4022                         tempo += Form("%d ", AliQAv1::kESDS) ; 
4023                 fQATasks = tempo ; 
4024                 if (fQATasks.IsNull()) {
4025                         AliInfo("No QA requested\n")  ;
4026                         fRunQA = kFALSE ;
4027                         return kTRUE ; 
4028                 }
4029         }       
4030         TString tempo(fQATasks) ; 
4031         tempo.ReplaceAll(Form("%d", AliQAv1::kRAWS), AliQAv1::GetTaskName(AliQAv1::kRAWS))      ;
4032         tempo.ReplaceAll(Form("%d", AliQAv1::kDIGITSR), AliQAv1::GetTaskName(AliQAv1::kDIGITSR)) ;      
4033         tempo.ReplaceAll(Form("%d", AliQAv1::kRECPOINTS), AliQAv1::GetTaskName(AliQAv1::kRECPOINTS)) ;  
4034         tempo.ReplaceAll(Form("%d", AliQAv1::kESDS), AliQAv1::GetTaskName(AliQAv1::kESDS)) ;    
4035         AliInfo( Form("QA will be done on \"%s\" for \"%s\"\n", fQADetectors.Data(), tempo.Data()) ) ;  
4036         fRunQA = kTRUE ;
4037         return kTRUE; 
4038
4039
4040 //_____________________________________________________________________________
4041 Bool_t AliReconstruction::InitRecoParams() 
4042 {
4043   // The method accesses OCDB and retrieves all
4044   // the available reco-param objects from there.
4045
4046   Bool_t isOK = kTRUE;
4047
4048   if (fRecoParam.GetDetRecoParamArray(kNDetectors)) {
4049     AliInfo("Using custom GRP reconstruction parameters");
4050   }
4051   else {
4052     AliInfo("Loading GRP reconstruction parameter objects");
4053
4054     AliCDBPath path("GRP","Calib","RecoParam");
4055     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
4056     if(!entry){ 
4057       AliWarning("Couldn't find GRP RecoParam entry in OCDB");
4058       isOK = kFALSE;
4059     }
4060     else {
4061       TObject *recoParamObj = entry->GetObject();
4062       if (dynamic_cast<TObjArray*>(recoParamObj)) {
4063         // GRP has a normal TobjArray of AliDetectorRecoParam objects
4064         // Registering them in AliRecoParam
4065         fRecoParam.AddDetRecoParamArray(kNDetectors,dynamic_cast<TObjArray*>(recoParamObj));
4066       }
4067       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
4068         // GRP has only onse set of reco parameters
4069         // Registering it in AliRecoParam
4070         AliInfo("Single set of GRP reconstruction parameters found");
4071         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
4072         fRecoParam.AddDetRecoParam(kNDetectors,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
4073       }
4074       else {
4075         AliError("No valid GRP RecoParam object found in the OCDB");
4076         isOK = kFALSE;
4077       }
4078       entry->SetOwner(0);
4079     }
4080   }
4081
4082   TString detStr = fLoadCDB;
4083   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
4084
4085     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
4086
4087     if (fRecoParam.GetDetRecoParamArray(iDet)) {
4088       AliInfo(Form("Using custom reconstruction parameters for detector %s",fgkDetectorName[iDet]));
4089       continue;
4090     }
4091
4092     AliInfo(Form("Loading reconstruction parameter objects for detector %s",fgkDetectorName[iDet]));
4093   
4094     AliCDBPath path(fgkDetectorName[iDet],"Calib","RecoParam");
4095     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
4096     if(!entry){ 
4097       AliWarning(Form("Couldn't find RecoParam entry in OCDB for detector %s",fgkDetectorName[iDet]));
4098       isOK = kFALSE;
4099     }
4100     else {
4101       TObject *recoParamObj = entry->GetObject();
4102       if (dynamic_cast<TObjArray*>(recoParamObj)) {
4103         // The detector has a normal TobjArray of AliDetectorRecoParam objects
4104         // Registering them in AliRecoParam
4105         fRecoParam.AddDetRecoParamArray(iDet,dynamic_cast<TObjArray*>(recoParamObj));
4106       }
4107       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
4108         // The detector has only onse set of reco parameters
4109         // Registering it in AliRecoParam
4110         AliInfo(Form("Single set of reconstruction parameters found for detector %s",fgkDetectorName[iDet]));
4111         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
4112         fRecoParam.AddDetRecoParam(iDet,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
4113       }
4114       else {
4115         AliError(Form("No valid RecoParam object found in the OCDB for detector %s",fgkDetectorName[iDet]));
4116         isOK = kFALSE;
4117       }
4118       entry->SetOwner(0);
4119       //      FIX ME: We have to disable the unloading of reco-param CDB
4120       //      entries because QA framework is using them. Has to be fix in
4121       //      a way that the QA takes the objects already constructed in
4122       //      this method.
4123       //      AliCDBManager::Instance()->UnloadFromCache(path.GetPath());
4124     }
4125   }
4126
4127   if (AliDebugLevel() > 0) fRecoParam.Print();
4128
4129   return isOK;
4130 }
4131
4132 //_____________________________________________________________________________
4133 Bool_t AliReconstruction::GetEventInfo() 
4134 {
4135   // Fill the event info object
4136   // ...
4137   AliCodeTimerAuto("",0)
4138
4139   AliCentralTrigger *aCTP = NULL;
4140   if (fRawReader) {
4141     fEventInfo.SetEventType(fRawReader->GetType());
4142
4143     ULong64_t mask = fRawReader->GetClassMask();
4144     ULong64_t maskNext50 = fRawReader->GetClassMaskNext50();
4145     fEventInfo.SetTriggerMask(mask);
4146     fEventInfo.SetTriggerMaskNext50(maskNext50);
4147     UInt_t clmask = fRawReader->GetDetectorPattern()[0];
4148     fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(clmask));
4149
4150     aCTP = new AliCentralTrigger();
4151     TString configstr("");
4152     if (!aCTP->LoadConfiguration(configstr)) { // Load CTP config from OCDB
4153       AliError("No trigger configuration found in OCDB! The trigger configuration information will not be used!");
4154       delete aCTP;
4155       return kFALSE;
4156     }
4157     aCTP->SetClassMask(mask);
4158     aCTP->SetClusterMask(clmask);
4159
4160     if (fRunLoader) {
4161       AliCentralTrigger* rlCTP = fRunLoader->GetTrigger();
4162       if (rlCTP) {
4163         rlCTP->SetClassMask(mask);
4164         rlCTP->SetClusterMask(clmask);
4165       }
4166     }
4167   }
4168   else {
4169     fEventInfo.SetEventType(AliRawEventHeaderBase::kPhysicsEvent);
4170
4171     if (fRunLoader && (!fRunLoader->LoadTrigger())) {
4172       aCTP = fRunLoader->GetTrigger();
4173       fEventInfo.SetTriggerMask(aCTP->GetClassMask());
4174       fEventInfo.SetTriggerMaskNext50(aCTP->GetClassMaskNext50());
4175       // get inputs from actp - just get
4176       AliESDHeader* esdheader = fesd->GetHeader();
4177       esdheader->SetL0TriggerInputs(aCTP->GetL0TriggerInputs());
4178       esdheader->SetL1TriggerInputs(aCTP->GetL1TriggerInputs());
4179       esdheader->SetL2TriggerInputs(aCTP->GetL2TriggerInputs());
4180       fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(aCTP->GetClusterMask()));
4181     }
4182     else {
4183       if (fStopOnMissingTriggerFile) AliFatal("No trigger can be loaded! Stopping reconstruction!");
4184       AliWarning("No trigger can be loaded! The trigger information will not be used!");
4185       return kFALSE;
4186     }
4187   }
4188
4189   AliTriggerConfiguration *config = aCTP->GetConfiguration();
4190   if (!config) {
4191     AliError("No trigger configuration has been found! The trigger configuration information will not be used!");
4192     if (fRawReader) delete aCTP;
4193     return kFALSE;
4194   }
4195
4196   // Load trigger aliases and declare the trigger classes included in aliases
4197   //PH Why do we do it in each event and not only once in the beginning of the chunk??
4198   //PH Temporary fix for #99725: AliReconstruction::GetEventInfo bug
4199   fDeclTriggerClasses.Clear();
4200   AliCDBEntry * entry = AliCDBManager::Instance()->Get("GRP/CTP/Aliases");
4201   if (entry) {
4202     THashList * lst = dynamic_cast<THashList*>(entry->GetObject());
4203     if (lst) {
4204       lst->Sort(kSortDescending); // to avoid problems with substrungs
4205       if (fRawReader) fRawReader->LoadTriggerAlias(lst);
4206       // Now declare all the triggers present in the aliases
4207       TIter iter(lst);
4208       TNamed *nmd = 0;
4209       while((nmd = dynamic_cast<TNamed*>(iter.Next()))){
4210         fDeclTriggerClasses += " ";
4211         fDeclTriggerClasses += nmd->GetName();
4212       }
4213     }
4214     else {
4215       AliError("Cannot cast the object with trigger aliases to THashList!");
4216     }
4217   }
4218   else {
4219     AliError("No OCDB ebtry for the trigger aliases!");
4220   }
4221   // Load trigger classes for this run
4222   UChar_t clustmask = 0;
4223   TString trclasses;
4224   ULong64_t trmask = fEventInfo.GetTriggerMask();
4225   ULong64_t trmaskNext50 = fEventInfo.GetTriggerMaskNext50();
4226   const TObjArray& classesArray = config->GetClasses();
4227   Int_t nclasses = classesArray.GetEntriesFast();
4228   for( Int_t iclass=0; iclass < nclasses; iclass++ ) {
4229     AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At(iclass);
4230     if (trclass && trclass->GetMask()>0) {
4231       Int_t trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
4232       if (fesd) fesd->SetTriggerClass(trclass->GetName(),trindex);
4233       if (fRawReader) fRawReader->LoadTriggerClass(trclass->GetName(),trindex);
4234       if (trmask & (1ull << trindex)) {
4235         trclasses += " ";
4236         trclasses += trclass->GetName();
4237         trclasses += " ";
4238         clustmask |= trclass->GetCluster()->GetClusterMask();
4239       }
4240     }
4241     if (trclass && trclass->GetMaskNext50()>0) {
4242       Int_t trindex = TMath::Nint(TMath::Log2(trclass->GetMaskNext50()))+50;
4243       if (fesd) fesd->SetTriggerClass(trclass->GetName(),trindex);
4244       if (fRawReader) fRawReader->LoadTriggerClass(trclass->GetName(),trindex);
4245       if (trmaskNext50 & (1ull << (trindex-50))) {
4246         trclasses += " ";
4247         trclasses += trclass->GetName();
4248         trclasses += " ";
4249         clustmask |= trclass->GetCluster()->GetClusterMask();
4250       }
4251     }
4252   }
4253   fEventInfo.SetTriggerClasses(trclasses);
4254   // Now put the declared trigger classes (not present in the run)
4255   // to 0/false in the event selection
4256   if (!fDeclTriggerClasses.IsNull()) {
4257     TObjArray *tokens = fDeclTriggerClasses.Tokenize(" ");
4258     Int_t ntokens = tokens->GetEntriesFast();
4259     for (Int_t itoken = 0; itoken < ntokens; ++itoken) {
4260       if (fRawReader) fRawReader->LoadTriggerClass((((TObjString*)tokens->At(itoken))->String()).Data(),-1);
4261     }
4262     delete tokens;
4263   }
4264
4265   // Write names of active trigger inputs in ESD Header
4266   const TObjArray& inputsArray = config->GetInputs(); 
4267   Int_t ninputs = inputsArray.GetEntriesFast();
4268   for( Int_t iinput=0; iinput < ninputs; iinput++ ) {
4269     AliTriggerInput* trginput = (AliTriggerInput*)inputsArray.At(iinput);
4270     if (trginput && trginput->GetMask()>0) {
4271       Int_t inputIndex = (Int_t)TMath::Nint(TMath::Log2(trginput->GetMask()));
4272       AliESDHeader* headeresd = 0x0;
4273       if (fesd) headeresd = fesd->GetHeader();
4274       if (headeresd) {
4275         Int_t trglevel = (Int_t)trginput->GetLevel();
4276         if (trglevel == 0) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex);
4277         if (trglevel == 1) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex+24);
4278         if (trglevel == 2) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex+48);
4279       }
4280     }
4281   }
4282
4283   // Set the information in ESD
4284   if (fesd) {
4285     fesd->SetTriggerMask(trmask);
4286     fesd->SetTriggerMaskNext50(trmaskNext50);
4287     fesd->SetTriggerCluster(clustmask);
4288   }
4289
4290   if (!aCTP->CheckTriggeredDetectors()) {
4291     if (fRawReader) delete aCTP;
4292     return kFALSE;
4293   }    
4294
4295   if (fRawReader) delete aCTP;
4296
4297   // We have to fill also the HLT decision here!!
4298   // ...
4299
4300   return kTRUE;
4301 }
4302
4303 const char *AliReconstruction::MatchDetectorList(const char *detectorList, UInt_t detectorMask)
4304 {
4305   // Match the detector list found in the rec.C or the default 'ALL'
4306   // to the list found in the GRP (stored there by the shuttle PP which
4307   // gets the information from ECS)
4308   static TString resultList;
4309   TString detList = detectorList;
4310
4311   resultList = "";
4312
4313   for(Int_t iDet = 0; iDet < (AliDAQ::kNDetectors-1); iDet++) {
4314     if ((detectorMask >> iDet) & 0x1) {
4315       TString det = AliDAQ::OfflineModuleName(iDet);
4316       if ((detList.CompareTo("ALL") == 0) ||
4317           ((detList.BeginsWith("ALL ") ||
4318             detList.EndsWith(" ALL") ||
4319             detList.Contains(" ALL ")) &&
4320            !(detList.BeginsWith("-"+det+" ") ||
4321              detList.EndsWith(" -"+det) ||
4322              detList.Contains(" -"+det+" "))) ||
4323           (detList.CompareTo(det) == 0) ||
4324           detList.BeginsWith(det+" ") ||
4325           detList.EndsWith(" "+det) ||
4326           detList.Contains( " "+det+" " )) {
4327         if (!resultList.EndsWith(det + " ")) {
4328           resultList += det;
4329           resultList += " ";
4330         }
4331       }        
4332     }
4333   }
4334
4335   // HLT
4336   if ((detectorMask >> AliDAQ::kHLTId) & 0x1) {
4337     TString hltDet = AliDAQ::OfflineModuleName(AliDAQ::kNDetectors-1);
4338     if ((detList.CompareTo("ALL") == 0) ||
4339         ((detList.BeginsWith("ALL ") ||
4340           detList.EndsWith(" ALL") ||
4341           detList.Contains(" ALL ")) &&
4342          !(detList.BeginsWith("-"+hltDet+" ") ||
4343            detList.EndsWith(" -"+hltDet) ||
4344            detList.Contains(" -"+hltDet+" "))) ||
4345         (detList.CompareTo(hltDet) == 0) ||
4346         detList.BeginsWith(hltDet+" ") ||
4347         detList.EndsWith(" "+hltDet) ||
4348         detList.Contains( " "+hltDet+" " )) {
4349       resultList += hltDet;
4350     }
4351   }
4352
4353   return resultList.Data();
4354
4355 }
4356
4357 //______________________________________________________________________________
4358 void AliReconstruction::Abort(const char *method, EAbort what)
4359 {
4360   // Abort processing. If what = kAbortProcess, the Process() loop will be
4361   // aborted. If what = kAbortFile, the current file in a chain will be
4362   // aborted and the processing will continue with the next file, if there
4363   // is no next file then Process() will be aborted. Abort() can also  be
4364   // called from Begin(), SlaveBegin(), Init() and Notify(). After abort
4365   // the SlaveTerminate() and Terminate() are always called. The abort flag
4366   // can be checked in these methods using GetAbort().
4367   //
4368   // The method is overwritten in AliReconstruction for better handling of
4369   // reco specific errors 
4370
4371   if (!fStopOnError) return;
4372
4373   CleanUp();
4374
4375   TString whyMess = method;
4376   whyMess += " failed! Aborting...";
4377
4378   AliError(whyMess.Data());
4379
4380   fAbort = what;
4381   TString mess = "Abort";
4382   if (fAbort == kAbortProcess)
4383     mess = "AbortProcess";
4384   else if (fAbort == kAbortFile)
4385     mess = "AbortFile";
4386
4387   Info(mess.Data(), "%s", whyMess.Data());
4388 }
4389
4390 //______________________________________________________________________________
4391 Bool_t AliReconstruction::ProcessEvent(void* event)
4392 {
4393   // Method that is used in case the event loop
4394   // is steered from outside, for example by AMORE
4395   // 'event' is a pointer to the DATE event in the memory
4396
4397   if (fRawReader) delete fRawReader;
4398   fRawReader = new AliRawReaderDate(event);
4399   fStatus = ProcessEvent(fRunLoader->GetNumberOfEvents());  
4400   delete fRawReader;
4401   fRawReader = NULL;
4402
4403   return fStatus;
4404 }
4405
4406 //______________________________________________________________________________
4407 Bool_t AliReconstruction::ParseOutput()
4408 {
4409   // The method parses the output file
4410   // location string in order to steer
4411   // properly the selector
4412
4413   TPMERegexp re1("(\\w+\\.zip#\\w+\\.root):([,*\\w+\\.root,*]+)@dataset://(\\w++)");
4414   TPMERegexp re2("(\\w+\\.root)?@?dataset://(\\w++)");
4415
4416   if (re1.Match(fESDOutput) == 4) {
4417     // root archive with output files stored and regustered
4418     // in proof dataset
4419     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",re1[1].Data()));
4420     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",re1[3].Data()));
4421     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_DATASET",""));
4422     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_ARCHIVE",re1[2].Data()));
4423     AliInfo(Form("%s files will be stored within %s in dataset %s",
4424                  re1[2].Data(),
4425                  re1[1].Data(),
4426                  re1[3].Data()));
4427   }
4428   else if (re2.Match(fESDOutput) == 3) {
4429     // output file stored and registered
4430     // in proof dataset
4431     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",(re2[1].IsNull()) ? "AliESDs.root" : re2[1].Data()));
4432     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",re2[2].Data()));
4433     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_DATASET",""));
4434     AliInfo(Form("%s will be stored in dataset %s",
4435                  (re2[1].IsNull()) ? "AliESDs.root" : re2[1].Data(),
4436                  re2[2].Data()));
4437   }
4438   else {
4439     if (fESDOutput.IsNull()) {
4440       // Output location not given.
4441       // Assuming xrootd has been already started and
4442       // the output file has to be sent back
4443       // to the client machine
4444       TString esdUrl(Form("root://%s/%s/",
4445                           TUrl(gSystem->HostName()).GetHostFQDN(),
4446                           gSystem->pwd()));
4447       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE","AliESDs.root"));
4448       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",esdUrl.Data()));
4449       AliInfo(Form("AliESDs.root will be stored in %s",
4450                    esdUrl.Data()));
4451     }
4452     else {
4453       // User specified an output location.
4454       // Ones has just to parse it here
4455       TUrl outputUrl(fESDOutput.Data());
4456       TString outputFile(gSystem->BaseName(outputUrl.GetFile()));
4457       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",outputFile.IsNull() ? "AliESDs.root" : outputFile.Data()));
4458       TString outputLocation(outputUrl.GetUrl());
4459       outputLocation.ReplaceAll(outputFile.Data(),"");
4460       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",outputLocation.Data()));
4461       AliInfo(Form("%s will be stored in %s",
4462                    outputFile.IsNull() ? "AliESDs.root" : outputFile.Data(),
4463                    outputLocation.Data()));
4464     }
4465   }
4466
4467   return kTRUE;
4468 }
4469
4470 //______________________________________________________________________________
4471 Bool_t AliReconstruction::IsHighPt() const {
4472   // Selection of events containing "high" pT tracks
4473   // If at least one track is found within 1.5 and 100 GeV (pT)
4474   // that was reconstructed by both ITS and TPC, the event is accepted
4475
4476   // Track cuts
4477   const Double_t pTmin = 1.5;
4478   const Double_t pTmax = 100;
4479   ULong_t mask = 0;
4480   mask |= (AliESDtrack::kITSrefit);
4481   mask |= (AliESDtrack::kTPCrefit);
4482   const Double_t pTminCosmic = 5.;
4483   const Double_t pTmaxCosmic = 100;
4484   ULong_t maskCosmic = 0;
4485   Int_t cosmicCount=0;
4486   maskCosmic |= (AliESDtrack::kTPCrefit);
4487
4488   Bool_t isOK = kFALSE;
4489
4490   if (fesd && fesd->GetEventType()==AliRawEventHeaderBase::kPhysicsEvent) {
4491     // Check if this ia a physics event (code 7)
4492     Int_t ntrk = fesd->GetNumberOfTracks();
4493     for (Int_t itrk=0; itrk<ntrk; ++itrk) {
4494           
4495       AliESDtrack * trk = fesd->GetTrack(itrk);
4496       if (trk 
4497           && trk->Pt() > pTmin 
4498           && trk->Pt() < pTmax
4499           && (trk->GetStatus() & mask) == mask ) {
4500         
4501         isOK = kTRUE;
4502         break;
4503       }
4504       if (trk 
4505           && trk->GetInnerParam()
4506           && trk->GetInnerParam()->Pt() > pTminCosmic 
4507           && trk->GetInnerParam()->Pt() < pTmaxCosmic
4508           && (trk->GetStatus() & maskCosmic) == maskCosmic ) {
4509         
4510         cosmicCount++;
4511         break;
4512       }
4513     }
4514     if (cosmicCount>1) isOK=kTRUE;
4515   }
4516   return isOK;
4517 }
4518
4519 //______________________________________________________________________________
4520 Bool_t AliReconstruction::IsCosmicOrCalibSpecie() const {
4521   // Select cosmic or calibration events
4522
4523   Bool_t isOK = kFALSE;
4524
4525   if (fesd && fesd->GetEventType()==AliRawEventHeaderBase::kPhysicsEvent) {
4526       // Check if this ia a physics event (code 7)
4527       
4528       UInt_t specie = fesd->GetEventSpecie();
4529       if (specie==AliRecoParam::kCosmic || specie==AliRecoParam::kCalib) {
4530         isOK = kTRUE;
4531       }
4532   }
4533   return isOK;
4534 }
4535
4536 //______________________________________________________________________________
4537 void AliReconstruction::WriteESDfriend() {
4538   // Fill the ESD friend in the tree. The required fraction of ESD friends is stored
4539   // in fFractionFriends. We select events where we store the ESD friends according
4540   // to the following algorithm:
4541   // 1. Store all Cosmic or Calibration events within the required fraction
4542   // 2. Sample "high Pt" events within the remaining fraction after step 1.
4543   // 3. Sample randomly events if we still have remaining slot
4544
4545   fNall++;
4546   Bool_t isSelected = kFALSE;
4547   //
4548   // Store all friends for B field OFF 
4549   if (TMath::Abs(AliTrackerBase::GetBz())<0.5) isSelected=kTRUE;
4550
4551   if (IsCosmicOrCalibSpecie()) { // Selection of calib or cosmic events
4552     fNspecie++;
4553
4554     isSelected = kTRUE;
4555     fSspecie++;
4556   }
4557   
4558   Double_t remainingFraction = fFractionFriends;
4559   remainingFraction -= ((Double_t)(fSspecie)/(Double_t)(fNall));
4560   
4561   if (IsHighPt())  { // Selection of "high Pt" events
4562     fNhighPt++;
4563     Double_t curentHighPtFraction = ((Double_t)(fNhighPt+1))/((Double_t)(fNall+1));
4564     // "Bayesian" estimate supposing that without events all the events are of the required type
4565     
4566     if (!isSelected) {
4567       Double_t rnd = gRandom->Rndm()*curentHighPtFraction;
4568       if (rnd<remainingFraction) {
4569         isSelected = kTRUE;
4570         fShighPt++;
4571       }
4572     }
4573   }
4574   remainingFraction -= ((Double_t)(fShighPt)/(Double_t)(fNall));
4575   
4576   // Random selection to fill the remaining fraction (if any)
4577   if (!isSelected) {
4578     Double_t rnd = gRandom->Rndm();
4579     if (rnd<remainingFraction) {        
4580       isSelected = kTRUE;
4581     }
4582   }
4583   
4584   if (!isSelected) {
4585     fesdf->~AliESDfriend();
4586     new (fesdf) AliESDfriend(); // Reset...
4587     fesdf->SetSkipBit(kTRUE);
4588   }
4589   //
4590   Long64_t nbf = ftreeF->Fill();
4591   if (fTreeBuffSize>0 && ftreeF->GetAutoFlush()<0 && (fMemCountESDF += nbf)>fTreeBuffSize ) { // default limit is still not reached
4592     nbf = ftreeF->GetZipBytes();
4593     if (nbf>0) nbf = -nbf;
4594     else       nbf = ftreeF->GetEntries();
4595     ftreeF->SetAutoFlush(nbf);
4596     AliInfo(Form("Calling ftreeF->SetAutoFlush(%lld) | W:%lld T:%lld Z:%lld",
4597                  nbf,fMemCountESDF,ftreeF->GetTotBytes(),ftreeF->GetZipBytes()));        
4598   }
4599   
4600 }
4601
4602 //_________________________________________________________________
4603 void AliReconstruction::DeleteDigits(const TString& detectors)
4604 {
4605   // delete requested digit files produced at current event
4606   static int iEvent = 0;
4607   if (detectors.IsNull()) return;
4608   TString detStr = detectors;
4609   AliInfo(Form("Deleting Digits: %s",detectors.Data()));
4610
4611   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
4612     if(!IsSelected(fgkDetectorName[iDet], detStr)) continue;
4613     unlink(Form("%s.Digits.root",fgkDetectorName[iDet]));
4614   }
4615   AliSysInfo::AddStamp(Form("DelDigits_%d",iEvent), 0,0,iEvent);
4616   iEvent++;
4617 }
4618
4619 //_________________________________________________________________
4620 void AliReconstruction::DeleteRecPoints(const TString& detectors)
4621 {
4622   // delete requested recpoint files produced at current event
4623   static int iEvent = 0;
4624   if (detectors.IsNull()) return;
4625   TString detStr = detectors;
4626   AliInfo(Form("Deleting Recpoints: %s",detectors.Data()));
4627   //
4628   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
4629     if(!IsSelected(fgkDetectorName[iDet], detStr)) continue;
4630     unlink(Form("%s.RecPoints.root",fgkDetectorName[iDet]));
4631   }
4632   AliSysInfo::AddStamp(Form("DelRecPoints_%d",iEvent), 0,0,iEvent);
4633   iEvent++;
4634 }
4635
4636 //_________________________________________________________________
4637 void AliReconstruction::SetStopOnResourcesExcess(Int_t vRSS,Int_t vVMEM)
4638 {
4639   // require checking the resources left and stopping on excess
4640   // if 0  : no check is done
4641   // if >0 : stop reconstruction if exceeds this value
4642   // if <0 : use as margin to system limits
4643   //
4644   const int kKB2MB = 1024;
4645   const int kInfMem = 9999999;
4646   //
4647   struct rlimit r;
4648   int pgSize = getpagesize();
4649   //
4650   if (vRSS>0) {
4651     fMaxRSS = vRSS;
4652     AliInfo(Form("Setting max. RSS usage to user value %d MB",fMaxRSS));
4653   }
4654   else if (vRSS<0) {
4655     getrlimit(RLIMIT_RSS,&r);
4656     fMaxRSS = r.rlim_max==RLIM_INFINITY ? kInfMem : int(r.rlim_max*pgSize/kKB2MB/kKB2MB) + vRSS;
4657     AliInfo(Form("Setting max. RSS usage to system hard limit %d%s MB (%d margin)",fMaxRSS,r.rlim_max==RLIM_INFINITY ? "(inf)":"",-vRSS));
4658   }
4659   else {AliInfo("No check on RSS memory usage will be applied");}
4660   //
4661   if (vVMEM>0) {
4662     fMaxVMEM = vVMEM;
4663     AliInfo(Form("Setting max. VMEM usage to user value %d MB",fMaxVMEM));
4664   }
4665   else if (vVMEM<0) {
4666     getrlimit(RLIMIT_AS,&r);
4667     fMaxVMEM = r.rlim_max==RLIM_INFINITY ? kInfMem : int(r.rlim_max*pgSize/kKB2MB/kKB2MB) + vVMEM;
4668     AliInfo(Form("Setting max. VMEM usage to system hard limit %d%s MB (%d margin)",fMaxVMEM,r.rlim_max==RLIM_INFINITY ? "(inf)":"",-vVMEM));
4669   }
4670   else {AliInfo("No check on RSS memory usage will be applied");}
4671   //  
4672 }
4673
4674 //_________________________________________________________________
4675 Bool_t AliReconstruction::HasEnoughResources(int ev)
4676 {
4677   // check if process consumed more than allowed resources
4678   const int kKB2MB = 1024;
4679   Bool_t res = kTRUE;
4680   if (!fMaxRSS && !fMaxVMEM) return res;
4681   //
4682   ProcInfo_t procInfo;
4683   gSystem->GetProcInfo(&procInfo);
4684   if (procInfo.fMemResident/kKB2MB > fMaxRSS)  res = kFALSE;
4685   if (procInfo.fMemVirtual/kKB2MB  > fMaxVMEM) res = kFALSE;  
4686   //
4687   if (!res) {
4688     AliInfo(Form("Job exceeded allowed limits: RSS:%d (%d) VMEM:%d (%d), will stop",
4689                  int(procInfo.fMemResident/kKB2MB),fMaxRSS,
4690                  int(procInfo.fMemVirtual/kKB2MB) ,fMaxVMEM));
4691     //
4692     unlink(Form("%s",fgkStopEvFName));
4693     ofstream outfile(fgkStopEvFName);
4694     outfile << ev << std::endl;
4695     outfile.close();
4696     fStopped = kTRUE;
4697   }
4698   return res;
4699 }
4700
4701 Bool_t AliReconstruction::HasNextEventAfter(Int_t eventId)
4702 {
4703          return ( (eventId < fRunLoader->GetNumberOfEvents()) ||
4704            (fRawReader && fRawReader->NextEvent()) );
4705 }
4706
4707 //_________________________________________________________________
4708 void AliReconstruction::CheckRecoCDBvsSimuCDB()
4709 {
4710   // if some CDB entries must be the same in the simulation
4711   // and reconstruction, check here
4712   int nent = fCheckRecoCDBvsSimuCDB.GetEntriesFast();
4713   AliInfo(Form("Check %d entries for matching between sim and rec",nent));
4714   //
4715   // get simulation CDB
4716   fRunLoader->CdGAFile();
4717   TMap*  cdbMapSim  = (TMap*)gDirectory->Get("cdbMap");
4718   TList* cdbListSim = (TList*)gDirectory->Get("cdbList");
4719   if (!(cdbMapSim && cdbListSim)) {
4720     AliInfo(Form("No CDBMap/List found in %s, nothing to check",fGAliceFileName.Data()));
4721     return;
4722   }
4723   // read the requested objects to make sure they will appear in the reco list
4724   for (Int_t i=0;i<nent;i++) {
4725     TNamed* cdbent = (TNamed*) fCheckRecoCDBvsSimuCDB[i];
4726     if (!cdbent) continue;
4727     AliCDBManager::Instance()->Get(cdbent->GetName());
4728   }
4729   // get default path for simulation
4730   TPair* pair;
4731   TObjString* stro;
4732   pair = (TPair*)cdbMapSim->FindObject("default");
4733   if (!pair) {AliFatal("Did not find default storage used for simulations"); return;}
4734   TString defSimStore = ((TObjString*)pair->Value())->GetString();
4735   RectifyCDBurl(defSimStore);
4736   //
4737   // get reconstruction CDB
4738   const TMap *cdbMapRec = AliCDBManager::Instance()->GetStorageMap();    
4739   const TList *cdbListRec = AliCDBManager::Instance()->GetRetrievedIds();
4740   //
4741   // get default path for reconstruction
4742   pair = (TPair*)cdbMapRec->FindObject("default");
4743   if (!pair) {AliFatal("Did not find default storage used for reconstruction"); return;}
4744   TString defRecStore = ((TObjString*)pair->Value())->GetString();
4745   RectifyCDBurl(defRecStore);
4746   //
4747   for (Int_t i=0;i<nent;i++) {
4748     TNamed* cdbent = (TNamed*) fCheckRecoCDBvsSimuCDB[i];
4749     if (!cdbent) continue;
4750     //
4751     AliInfo(Form("#%d Checking %s",i,cdbent->GetName()));
4752     //
4753     // find cdbID used for sim
4754     TString idSim="",storSim="";
4755     TIter nextSim(cdbListSim);
4756     while ((stro=(TObjString*)nextSim())) {
4757       if (stro->GetString().Contains(cdbent->GetName())) {
4758         idSim = stro->GetString();
4759         break;
4760       }
4761     }    
4762     // find the storage used for sim
4763     // check in the simuCDB special paths
4764     pair = (TPair*)cdbMapSim->FindObject(cdbent->GetName());
4765     if (pair) { // specific path is used
4766       storSim = ((TObjString*)pair->Value())->GetString();
4767       RectifyCDBurl(storSim);
4768     }
4769     else storSim = defSimStore;  // default storage list is used
4770     //
4771     if (!idSim.IsNull()) AliInfo(Form("Sim. used %s from %s",idSim.Data(), storSim.Data()));
4772     else                 AliInfo("Sim. did not use this object");
4773     //
4774     // find cdbID used for rec
4775     TString idRec="",storRec="";
4776     TIter nextRec(cdbListRec);
4777     AliCDBId* id=0;
4778     while ((id=(AliCDBId*)nextRec())) {
4779       idRec = id->ToString();
4780       if (idRec.Contains(cdbent->GetName())) break;
4781       idRec="";
4782     }
4783     //
4784     // find storage used for the rec
4785     pair = (TPair*)cdbMapRec->FindObject(cdbent->GetName());
4786     if (pair) {  // specific path is used
4787       storRec = ((TObjString*)pair->Value())->GetString();
4788       RectifyCDBurl(storRec);
4789     }
4790     else storRec = defRecStore; // default storage list is used
4791     //
4792     if (!idRec.IsNull()) AliInfo(Form("Rec. used %s from %s",idRec.Data(), storRec.Data()));
4793     else                 AliInfo("Rec. did not use this object");
4794     //
4795     if (!idSim.IsNull() && !idRec.IsNull() && ((idSim!=idRec) || (storSim!=storRec)) ) 
4796       AliFatal("Different objects were used in sim and rec");
4797   }
4798   
4799 }
4800
4801 //_________________________________________________________
4802 void AliReconstruction::RectifyCDBurl(TString& url)
4803 {
4804   // TBD RS
4805   // remove everything but the url
4806   TString sbs;
4807   if (!(sbs=url("\\?User=[^?]*")).IsNull())                url.ReplaceAll(sbs,"");
4808   if (!(sbs=url("\\?DBFolder=[^?]*")).IsNull())            url.ReplaceAll("?DB","");
4809   if (!(sbs=url("\\?SE=[^?]*")).IsNull())                  url.ReplaceAll(sbs,"");
4810   if (!(sbs=url("\\?CacheFolder=[^?]*")).IsNull())         url.ReplaceAll(sbs,"");
4811   if (!(sbs=url("\\?OperateDisconnected=[^?]*")).IsNull()) url.ReplaceAll(sbs,"");
4812   if (!(sbs=url("\\?CacheSize=[^?]*")).IsNull())           url.ReplaceAll(sbs,"");  
4813   if (!(sbs=url("\\?CleanupInterval=[^?]*")).IsNull())     url.ReplaceAll(sbs,"");  
4814   Bool_t slash=kFALSE,space=kFALSE;
4815   while ( (slash=url.EndsWith("/")) || (space=url.EndsWith(" ")) ) {
4816     if (slash) url = url.Strip(TString::kTrailing,'/');
4817     if (space) url = url.Strip(TString::kTrailing,' ');
4818   }
4819   //url.ToLower();
4820   //
4821 }