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