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