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