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