]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/STEER/AliReconstruction.cxx
#101358: In complete events in runs 195389 and 195531. Propagation of DAQ information...
[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
1568   const TMap* cdbCache = AliCDBManager::Instance()->GetEntryCache();
1569   if(cdbCache->Contains("GRP/Geometry/Data"))
1570           AliCDBManager::Instance()->UnloadFromCache("GRP/Geometry/Data");
1571   if(!toCDBSnapshot) AliCDBManager::Instance()->UnloadFromCache("*/Align/*");
1572   AliSysInfo::AddStamp("MisalignGeom");
1573
1574   if (!InitGRP()) {
1575     Abort("InitGRP", TSelector::kAbortProcess);
1576     return;
1577   }
1578   AliSysInfo::AddStamp("InitGRP");
1579   if(!toCDBSnapshot)
1580       if(cdbCache->Contains("GRP/Calib/CosmicTriggers"))
1581           AliCDBManager::Instance()->UnloadFromCache("GRP/Calib/CosmicTriggers");
1582
1583   if(!fCDBSnapshotMode || toCDBSnapshot){
1584       if (!LoadCDB()) {
1585           Abort("LoadCDB", TSelector::kAbortProcess);
1586           return;
1587       }
1588       AliSysInfo::AddStamp("LoadCDB"); 
1589   }
1590
1591   if (!LoadTriggerScalersCDB()) {
1592     Abort("LoadTriggerScalersCDB", TSelector::kAbortProcess);
1593     return;
1594   }
1595   AliSysInfo::AddStamp("LoadTriggerScalersCDB");
1596
1597   if (!LoadCTPTimeParamsCDB()) {
1598     Abort("LoadCTPTimeParamsCDB", TSelector::kAbortProcess);
1599     return;
1600   }
1601   AliSysInfo::AddStamp("LoadCTPTimeParamsCDB");
1602
1603   if (!ReadIntensityInfoCDB()) {
1604     Abort("ReadIntensityInfoCDB", TSelector::kAbortProcess);
1605     return;
1606   }
1607   AliSysInfo::AddStamp("ReadIntensityInfoCDB");
1608
1609   // Read the reconstruction parameters from OCDB
1610   if (!InitRecoParams()) {
1611     AliWarning("Not all detectors have correct RecoParam objects initialized");
1612   }
1613   AliSysInfo::AddStamp("InitRecoParams");
1614
1615   if(toCDBSnapshot)
1616   {
1617       AliCDBManager::Instance()->DumpToSnapshotFile(snapshotFileOut.Data(),kFALSE);
1618       AliCDBManager::Instance()->UnloadFromCache("*/Align/*");
1619       if(cdbCache->Contains("GRP/Calib/CosmicTriggers"))
1620           AliCDBManager::Instance()->UnloadFromCache("GRP/Calib/CosmicTriggers");
1621   }
1622
1623   if (fInput && gProof) {
1624     if (reco) *reco = *this;
1625
1626     gGeoManager->SetName("Geometry");
1627     gProof->AddInputData(gGeoManager,kTRUE);
1628     gGeoManager = NULL;
1629     gProof->AddInputData(const_cast<TMap*>(AliCDBManager::Instance()->GetEntryCache()),kTRUE);
1630     fInput->Add(new TParameter<Int_t>("RunNumber",AliCDBManager::Instance()->GetRun()));
1631     AliMagF *magFieldMap = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
1632     magFieldMap->SetName("MagneticFieldMap");
1633     gProof->AddInputData(magFieldMap,kTRUE);
1634     if (fAnalysis) {
1635       fAnalysis->SetName("Analysis");
1636       gProof->AddInputData(fAnalysis,kTRUE);
1637     }  
1638   }
1639
1640 }
1641
1642 //_____________________________________________________________________________
1643 void AliReconstruction::SlaveBegin(TTree*)
1644 {
1645   // Initialization related to run-loader,
1646   // vertexer, trackers, recontructors
1647   // In proof mode it is executed on the slave
1648   AliCodeTimerAuto("",0);
1649
1650   TProofOutputFile *outProofFile = NULL;
1651   if (fInput) {
1652     if (AliDebugLevel() > 0) fInput->Print();
1653     if (AliDebugLevel() > 10) fInput->Dump();
1654     if (AliReconstruction *reco = (AliReconstruction*)fInput->FindObject("AliReconstruction")) {
1655       *this = *reco;
1656     }
1657     if (TGeoManager *tgeo = (TGeoManager*)fInput->FindObject("Geometry")) {
1658       gGeoManager = tgeo;
1659       AliGeomManager::SetGeometry(tgeo);
1660     }
1661     if (TMap *entryCache = (TMap*)fInput->FindObject("CDBEntryCache")) {
1662       Int_t runNumber = -1;
1663       if (TProof::GetParameter(fInput,"RunNumber",runNumber) == 0) {
1664         AliCDBManager *man = AliCDBManager::Instance(entryCache,runNumber);
1665         man->SetCacheFlag(kTRUE);
1666         man->SetLock(kTRUE);
1667         man->Print();
1668       }
1669     }
1670     if (AliMagF *map = (AliMagF*)fInput->FindObject("MagneticFieldMap")) {
1671       AliMagF *newMap = new AliMagF(*map);
1672       if (!newMap->LoadParameterization()) {
1673         Abort("AliMagF::LoadParameterization", TSelector::kAbortProcess);
1674         return;
1675       }
1676       TGeoGlobalMagField::Instance()->SetField(newMap);
1677       TGeoGlobalMagField::Instance()->Lock();
1678     }
1679     if (!fAnalysis) {
1680        // Attempt to get the analysis manager from the input list
1681        fAnalysis = (AliAnalysisManager*)fInput->FindObject("Analysis");
1682        if (fAnalysis) AliInfo("==== Analysis manager retrieved from input list ====");
1683     }   
1684     if (TNamed *outputFileName = (TNamed*)fInput->FindObject("PROOF_OUTPUTFILE"))
1685       fProofOutputFileName = outputFileName->GetTitle();
1686     if (TNamed *outputLocation = (TNamed*)fInput->FindObject("PROOF_OUTPUTFILE_LOCATION"))
1687       fProofOutputLocation = outputLocation->GetTitle();
1688     if (fInput->FindObject("PROOF_OUTPUTFILE_DATASET"))
1689       fProofOutputDataset = kTRUE;
1690     if (TNamed *archiveList = (TNamed*)fInput->FindObject("PROOF_OUTPUTFILE_ARCHIVE"))
1691       fProofOutputArchive = archiveList->GetTitle();
1692     if (!fProofOutputFileName.IsNull() &&
1693         !fProofOutputLocation.IsNull() &&
1694         fProofOutputArchive.IsNull()) {
1695       if (!fProofOutputDataset) {
1696         outProofFile = new TProofOutputFile(fProofOutputFileName.Data(),"M");
1697         outProofFile->SetOutputFileName(Form("%s%s",fProofOutputLocation.Data(),fProofOutputFileName.Data()));
1698       }
1699       else {
1700         outProofFile = new TProofOutputFile(fProofOutputFileName.Data(),"DROV",fProofOutputLocation.Data());
1701       }
1702       if (AliDebugLevel() > 0) outProofFile->Dump();
1703       fOutput->Add(outProofFile);
1704     }
1705     AliSysInfo::AddStamp("ReadInputInSlaveBegin");
1706   }
1707   // Check if analysis was requested in the reconstruction event loop
1708   if (!fAnalysis) {
1709     // Attempt to connect in-memory singleton
1710     fAnalysis = AliAnalysisManager::GetAnalysisManager();
1711     if (fAnalysis) AliInfo(Form("==== Analysis manager <%s> found in memory ====", fAnalysis->GetName()));
1712     // Check if an analysis macro was specified
1713     if (!fAnalysis && !fAnalysisMacro.IsNull()) {
1714       // Run specified analysis macro
1715       gROOT->ProcessLine(Form(".x %s",fAnalysisMacro.Data()));
1716       fAnalysis = AliAnalysisManager::GetAnalysisManager();
1717       if (!fAnalysis) AliError(Form("No analysis manager produced by analysis macro %s", fAnalysisMacro.Data()));
1718       else AliInfo(Form("==== Analysis manager <%s> produced by analysis macro <%s> ====", 
1719                         fAnalysis->GetName(), fAnalysisMacro.Data()));
1720     }
1721   }
1722   
1723   // get the run loader
1724   if (!InitRunLoader()) {
1725     Abort("InitRunLoader", TSelector::kAbortProcess);
1726     return;
1727   }
1728   AliSysInfo::AddStamp("LoadLoader");
1729  
1730   ftVertexer = new AliVertexerTracks(AliTracker::GetBz());
1731
1732   // get trackers
1733   if (!fRunTracking.IsNull() && !CreateTrackers(fRunTracking)) {
1734     Abort("CreateTrackers", TSelector::kAbortProcess);
1735     return;
1736   }      
1737   AliSysInfo::AddStamp("CreateTrackers");
1738
1739   // create the ESD output file and tree
1740   if (!outProofFile) {
1741     ffile = TFile::Open("AliESDs.root", "RECREATE");
1742     ffile->SetCompressionLevel(2);
1743     if (!ffile->IsOpen()) {
1744       Abort("OpenESDFile", TSelector::kAbortProcess);
1745       return;
1746     }
1747   }
1748   else {
1749     AliInfo(Form("Opening output PROOF file: %s/%s",
1750                  outProofFile->GetDir(), outProofFile->GetFileName()));
1751     if (!(ffile = outProofFile->OpenFile("RECREATE"))) {
1752       Abort(Form("Problems opening output PROOF file: %s/%s",
1753                  outProofFile->GetDir(), outProofFile->GetFileName()),
1754             TSelector::kAbortProcess);
1755       return;
1756     }
1757   }
1758
1759   ftree = new TTree("esdTree", "Tree with ESD objects");
1760   fesd = new AliESDEvent();
1761   fesd->CreateStdContent();
1762   // add a so far non-std object to the ESD, this will
1763   // become part of the std content
1764   fesd->AddObject(new AliESDHLTDecision);
1765
1766   fesd->WriteToTree(ftree);
1767   if (fWriteESDfriend) {
1768     ffileF = TFile::Open("AliESDfriends.root", "RECREATE");
1769     ftreeF = new TTree("esdFriendTree", "Tree with ESD Friend objects");
1770     fesdf  = new AliESDfriend();
1771     ftreeF->Branch("ESDfriend.","AliESDfriend", &fesdf);
1772     fesd->AddObject(fesdf);
1773     ffile->cd();
1774   }
1775   ftree->GetUserInfo()->Add(fesd);
1776
1777   fhlttree = new TTree("HLTesdTree", "Tree with HLT ESD objects");
1778   fhltesd = new AliESDEvent();
1779   fhltesd->CreateStdContent();
1780   // read the ESD template from CDB
1781   // HLT is allowed to put non-std content to its ESD, the non-std
1782   // objects need to be created before invocation of WriteToTree in
1783   // order to create all branches. Initialization is done from an
1784   // ESD layout template in CDB
1785   AliCDBManager* man = AliCDBManager::Instance();
1786   AliCDBEntry* hltESDConfig = man->Get("HLT/Calib/esdLayout");
1787   if(!hltESDConfig){
1788       AliError(Form("Error getting \"HLT/Calib/esdLayout\""));
1789       return;
1790   }
1791   AliESDEvent* pESDLayout=dynamic_cast<AliESDEvent*>(hltESDConfig->GetObject());
1792   if (pESDLayout) {
1793       // init all internal variables from the list of objects
1794       pESDLayout->GetStdContent();
1795
1796       // copy content and create non-std objects
1797       *fhltesd=*pESDLayout;
1798       fhltesd->Reset();
1799   } else {
1800       AliError(Form("error setting hltEsd layout from \"HLT/Calib/esdLayout\": invalid object type"));
1801   }
1802
1803   fhltesd->WriteToTree(fhlttree);
1804   fhlttree->GetUserInfo()->Add(fhltesd);
1805
1806   ProcInfo_t procInfo;
1807   gSystem->GetProcInfo(&procInfo);
1808   AliInfo(Form("Current memory usage %ld %ld", procInfo.fMemResident, procInfo.fMemVirtual));
1809   
1810   //QA
1811   //Initialize the QA and start of cycle 
1812   if (fRunQA || fRunGlobalQA) 
1813     InitQA() ; 
1814
1815   //Initialize the Plane Efficiency framework
1816   if (fRunPlaneEff && !InitPlaneEff()) {
1817     Abort("InitPlaneEff", TSelector::kAbortProcess);
1818     return;
1819   }
1820
1821   if (strcmp(gProgName,"alieve") == 0)
1822     fRunAliEVE = InitAliEVE();
1823   // If we have an analysis manager, connect the AliRecoInputHandler here  
1824   if (fAnalysis) {
1825     if (!dynamic_cast<AliRecoInputHandler*>(fAnalysis->GetInputEventHandler())) {
1826        AliError("Analysis manager used in reconstruction should use AliRecoInputHandler - \
1827                  \n  ->Replacing with AliRecoInputHandler instance.");
1828        delete fAnalysis->GetInputEventHandler();
1829     }
1830     // Set the event and other data pointers
1831     fRecoHandler = new AliRecoInputHandler();
1832 //    fRecoHandler->Init(ftree, "LOCAL");
1833     fRecoHandler->SetEvent(fesd);
1834     fRecoHandler->SetESDfriend(fesdf);
1835     fRecoHandler->SetHLTEvent(fhltesd);
1836     fRecoHandler->SetHLTTree(fhlttree);
1837     fAnalysis->SetInputEventHandler(fRecoHandler);
1838     // Enter external loop mode
1839     fAnalysis->SetExternalLoop(kTRUE);
1840     // Initialize analysis
1841     fAnalysis->SlaveBegin(ftree);
1842     fAnalysis->StartAnalysis("local", (TTree*)0);
1843     // Connect ESD tree with the input container
1844     fAnalysis->GetCommonInputContainer()->SetData(ftree);
1845   }  
1846   return;
1847 }
1848
1849 //_____________________________________________________________________________
1850 Bool_t AliReconstruction::Process(Long64_t entry)
1851 {
1852   // run the reconstruction over a single entry
1853   // from the chain with raw data
1854   AliCodeTimerAuto("",0);
1855
1856   TTree *currTree = fChain->GetTree();
1857   AliRawVEvent *event = NULL;
1858   currTree->SetBranchAddress("rawevent",&event);
1859   currTree->GetEntry(entry);
1860   fRawReader = new AliRawReaderRoot(event);
1861   // check if process has enough resources 
1862   if (!HasEnoughResources(entry)) return kFALSE;
1863   fStatus = ProcessEvent(fRunLoader->GetNumberOfEvents());
1864   delete fRawReader;
1865   fRawReader = NULL;
1866   delete event;
1867
1868   return fStatus;
1869 }
1870
1871 //_____________________________________________________________________________
1872 void AliReconstruction::Init(TTree *tree)
1873 {
1874   // Implementation of TSelector::Init()
1875   // method
1876   if (tree == 0) {
1877     AliError("The input tree is not found!");
1878     return;
1879   }
1880   fChain = tree;
1881 }
1882
1883 //_____________________________________________________________________________
1884 Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
1885 {
1886   // run the reconstruction over a single event
1887   // The event loop is steered in Run method
1888
1889
1890   static Long_t oldMres=0;
1891   static Long_t oldMvir=0;
1892   static Float_t oldCPU=0;
1893   static Long_t aveDMres=0;
1894   static Long_t aveDMvir=0;
1895   static Float_t aveDCPU=0;
1896
1897   AliCodeTimerAuto("",0);
1898
1899   AliESDpid pid;
1900
1901   AliSysInfo::AddStamp(Form("StartEv_%d",iEvent), 0,0,iEvent);
1902
1903   if (iEvent >= fRunLoader->GetNumberOfEvents()) {
1904     fRunLoader->SetEventNumber(iEvent);
1905     if (fRawReader)
1906       fRunLoader->GetHeader()->Reset(fRawReader->GetRunNumber(), 
1907                                      iEvent, iEvent);
1908     fRunLoader->TreeE()->Fill();
1909
1910     if (fRawReader && fRawReader->UseAutoSaveESD())
1911       fRunLoader->TreeE()->AutoSave("SaveSelf");
1912   }
1913
1914   if ((iEvent < fFirstEvent) || ((fLastEvent >= 0) && (iEvent > fLastEvent))) {
1915     return kTRUE;
1916   }
1917
1918
1919   fRunLoader->GetEvent(iEvent);
1920
1921   // Fill Event-info object
1922   GetEventInfo();
1923   fRecoParam.SetEventSpecie(fRunInfo,fEventInfo,fListOfCosmicTriggers);
1924   
1925   ProcInfo_t procInfo;
1926   if(iEvent==fFirstEvent) {
1927     gSystem->GetProcInfo(&procInfo);
1928     oldMres=procInfo.fMemResident;
1929     oldMvir=procInfo.fMemVirtual;
1930     oldCPU=procInfo.fCpuUser+procInfo.fCpuSys;
1931   }
1932   AliInfo(Form("================================= Processing event %d of type %-10s ==================================", iEvent,fRecoParam.PrintEventSpecie()));
1933
1934   AliSysInfo::AddStamp(Form("StartReco_%d",iEvent), 0,0,iEvent);
1935
1936   // Set the reco-params
1937   {
1938     TString detStr = fLoadCDB;
1939     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1940       if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1941       AliReconstructor *reconstructor = GetReconstructor(iDet);
1942       if (reconstructor && fRecoParam.GetDetRecoParamArray(iDet)) {
1943         const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
1944         reconstructor->SetRecoParam(par);
1945         reconstructor->GetPidSettings(&pid);
1946         reconstructor->SetEventInfo(&fEventInfo);
1947         if (fRunQA) {
1948           AliQAManager::QAManager()->SetEventInfo(&fEventInfo) ;
1949           AliQAManager::QAManager()->SetRecoParam(iDet, par) ; 
1950           if (par) AliQAManager::QAManager()->SetEventSpecie(AliRecoParam::Convert(par->GetEventSpecie())) ;
1951         }
1952       }
1953     }
1954     //
1955     if (fRunQA || fRunGlobalQA) AliQADataMaker::SetEventTrigClasses(fEventInfo.GetTriggerClasses()); // RS: select which histo clones are to be filled
1956     //
1957     if (fRunQA) {
1958       const AliDetectorRecoParam *grppar = fRecoParam.GetDetRecoParam(kNDetectors);
1959       AliQAManager::QAManager()->SetRecoParam(AliQAv1::kGLOBAL, grppar) ; 
1960       AliQAManager::QAManager()->SetEventSpecie(AliRecoParam::Convert(grppar->GetEventSpecie())) ;
1961     }
1962   }
1963
1964     // QA on single raw 
1965   if (fRunQA && IsInTasks(AliQAv1::kRAWS)) {
1966     AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
1967     AliQAManager::QAManager()->RunOneEvent(fRawReader) ;  
1968     AliSysInfo::AddStamp(Form("RawQA_%d",iEvent), 0,0,iEvent);
1969   }
1970
1971     // fill Event header information from the RawEventHeader
1972     if (fRawReader){FillRawEventHeaderESD(fesd);}
1973     if (fRawReader){FillRawEventHeaderESD(fhltesd);}
1974     if (fRawReader){
1975       // Store DAQ detector pattern and attributes
1976       fesd->SetDAQDetectorPattern(fRawReader->GetDetectorPattern()[0]);
1977       fesd->SetDAQAttributes(fRawReader->GetAttributes()[2]);
1978     }
1979
1980     fesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
1981     fhltesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
1982     
1983     ((AliESDRun*)fesd->GetESDRun())->SetDetectorsInDAQ(fRunInfo->GetDetectorMask());
1984     ((AliESDRun*)fhltesd->GetESDRun())->SetDetectorsInDAQ(fRunInfo->GetDetectorMask());
1985     ((AliESDRun*)fesd->GetESDRun())->SetDetectorsInReco(AliDAQ::DetectorPatternOffline(fFillESD.Data()));
1986     ((AliESDRun*)fhltesd->GetESDRun())->SetDetectorsInReco(AliDAQ::DetectorPatternOffline(fFillESD.Data()));
1987
1988     fesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
1989     fhltesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
1990
1991     fesd->SetEventSpecie(fRecoParam.GetEventSpecie());
1992     fhltesd->SetEventSpecie(fRecoParam.GetEventSpecie());
1993     
1994     // Set magnetic field from the tracker
1995     fesd->SetMagneticField(AliTracker::GetBz());
1996     fhltesd->SetMagneticField(AliTracker::GetBz());
1997     //
1998     AliESDRun *esdRun,*esdRunH;
1999     esdRun  = (AliESDRun*)fesd->GetESDRun();
2000     esdRunH = (AliESDRun*)fhltesd->GetESDRun();
2001     esdRun->SetBeamEnergyIsSqrtSHalfGeV();
2002     esdRunH->SetBeamEnergyIsSqrtSHalfGeV();
2003     //
2004     for (int ib=2;ib--;) for (int it=2;it--;) {
2005         esdRun->SetMeanIntensity(ib,it, fBeamInt[ib][it]); 
2006         esdRunH->SetMeanIntensity(ib,it, fBeamInt[ib][it]); 
2007       }
2008     //
2009     fesd->SetBeamEnergy(fGRPData->GetBeamEnergy());
2010     fesd->SetBeamType(fGRPData->GetBeamType().Data());
2011     fesd->SetBeamParticle(fGRPData->GetSingleBeamType(0).Atoi(),0);
2012     fesd->SetBeamParticle(fGRPData->GetSingleBeamType(1).Atoi(),1);
2013     fhltesd->SetBeamEnergy(fGRPData->GetBeamEnergy());
2014     fhltesd->SetBeamType(fGRPData->GetBeamType().Data());
2015     fhltesd->SetBeamParticle(fGRPData->GetSingleBeamType(0).Atoi(),0);
2016     fhltesd->SetBeamParticle(fGRPData->GetSingleBeamType(1).Atoi(),1);
2017     //
2018     AliMagF* fld = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
2019     if (fld) { // set info needed for field initialization
2020       fesd->SetCurrentL3(fld->GetCurrentSol());
2021       fesd->SetCurrentDip(fld->GetCurrentDip());
2022       fesd->SetUniformBMap(fld->IsUniform());
2023       fesd->SetBInfoStored();
2024       //
2025       fhltesd->SetCurrentL3(fld->GetCurrentSol());
2026       fhltesd->SetCurrentDip(fld->GetCurrentDip());
2027       fhltesd->SetUniformBMap(fld->IsUniform());
2028       fhltesd->SetBInfoStored();
2029     }
2030
2031     //
2032     // run full HLT reconstruction first
2033     //
2034     {
2035       TString detectors=fRunLocalReconstruction;
2036       if (IsSelected("HLT", detectors) &&
2037           !RunLocalEventReconstruction("HLT")) {
2038         if (fStopOnError) {CleanUp(); return kFALSE;}
2039       }
2040       detectors=fFillESD;
2041       // run HLT on hltesd
2042       if (IsSelected("HLT", detectors) &&
2043           !FillESD(fhltesd, "HLT")) {
2044         if (fStopOnError) {CleanUp(); return kFALSE;}
2045       }
2046     }
2047
2048     // local single event reconstruction
2049     if (!fRunLocalReconstruction.IsNull()) {
2050       TString detectors=fRunLocalReconstruction;
2051       // the logic for selection and correct sequence of reconstruction relies on the
2052       // full list of detectors. Keyword 'ALL' should have been replaced at this point.
2053       if (detectors.Contains("ALL")) {
2054         AliFatal("Keyword 'ALL' needs to be replaced by the full list of detectors in "
2055                  "fRunLocalReconstruction. This should have been done by the framework");
2056       }
2057       detectors.ReplaceAll("HLT", "");
2058       if (!RunLocalEventReconstruction(detectors)) {
2059         if (fStopOnError) {
2060           CleanUp(); 
2061           return kFALSE;
2062         }
2063       }
2064     }
2065
2066   
2067     //
2068     // Set most probable pt, for B=0 tracking
2069     // Get the global reco-params. They are atposition 16 inside the array of detectors in fRecoParam
2070     const AliGRPRecoParam *grpRecoParam = dynamic_cast<const AliGRPRecoParam*>(fRecoParam.GetDetRecoParam(kNDetectors));
2071     if (grpRecoParam) AliExternalTrackParam::SetMostProbablePt(grpRecoParam->GetMostProbablePt());
2072     
2073     // Fill raw-data error log into the ESD
2074     if (fRawReader) FillRawDataErrorLog(iEvent,fesd);
2075
2076     AliSysInfo::AddStamp(Form("FillHeadErrs_%d",iEvent), 0,0,iEvent);
2077
2078     // vertex finder
2079     if (fRunVertexFinder) {
2080       if (!RunVertexFinder(fesd)) {
2081         if (fStopOnError) {CleanUp(); return kFALSE;}
2082       }
2083       AliSysInfo::AddStamp(Form("VtxFinder_%d",iEvent), 0,0,iEvent);
2084     }
2085
2086     // For Plane Efficiency: run the SPD trackleter
2087     if (fRunPlaneEff && fSPDTrackleter) {
2088       if (!RunSPDTrackleting(fesd)) {
2089         if (fStopOnError) {CleanUp(); return kFALSE;}
2090       }
2091       AliSysInfo::AddStamp(Form("TrackletEff_%d",iEvent), 0,0,iEvent);
2092     }
2093
2094     // Muon tracking
2095     if (!fRunTracking.IsNull()) {
2096       if (fRunMuonTracking) {
2097         if (!RunMuonTracking(fesd)) {
2098           if (fStopOnError) {CleanUp(); return kFALSE;}
2099         }
2100       }
2101       AliSysInfo::AddStamp(Form("TrackingMUON_%d",iEvent), 0,0,iEvent);      
2102     }
2103
2104     // barrel tracking
2105     if (!fRunTracking.IsNull()) {
2106       if (!RunTracking(fesd,pid)) {
2107         if (fStopOnError) {CleanUp(); return kFALSE;}
2108       }
2109     }
2110
2111     // fill ESD
2112     if (!fFillESD.IsNull()) {
2113       TString detectors=fFillESD;
2114       // the logic for selection and correct sequence of reconstruction relies on the
2115       // full list of detectors. Keyword 'ALL' should have been replaced at this point.
2116       if (detectors.Contains("ALL")) {
2117         AliFatal("Keyword 'ALL' needs to be replaced by the full list of detectors in "
2118                  "fFillESD. This should have been done by the framework");
2119       }
2120       // remove HLT as this has been executed at the beginning of the event reconstruction
2121       detectors.ReplaceAll("HLT", "");
2122       if (!FillESD(fesd, detectors)) {
2123         if (fStopOnError) {CleanUp(); return kFALSE;}
2124       }
2125     }
2126
2127     ffile->cd();
2128
2129     //
2130     // Propagate track to the beam pipe  (if not already done by ITS)
2131     //
2132     const Int_t ntracks = fesd->GetNumberOfTracks();
2133     const Double_t kRadius  = 2.8; //something less than the beam pipe radius
2134
2135     TObjArray trkArray;
2136     UShort_t selectedIdx[ntracks];
2137
2138     for (Int_t itrack=0; itrack<ntracks; itrack++){
2139       const Double_t kMaxStep = 1;   //max step over the material
2140       Bool_t ok;
2141
2142       AliESDtrack *track = fesd->GetTrack(itrack);
2143       if (!track) continue;
2144
2145       AliExternalTrackParam *tpcTrack =
2146            (AliExternalTrackParam *)track->GetTPCInnerParam();
2147       ok = kFALSE;
2148       if (tpcTrack)
2149         ok = AliTracker::
2150           PropagateTrackToBxByBz(tpcTrack,kRadius,track->GetMass(),kMaxStep,kFALSE);
2151
2152       if (ok) {
2153         Int_t n=trkArray.GetEntriesFast();
2154         selectedIdx[n]=track->GetID();
2155         trkArray.AddLast(tpcTrack);
2156       }
2157
2158       //Tracks refitted by ITS should already be at the SPD vertex
2159       if (track->IsOn(AliESDtrack::kITSrefit)) continue;
2160
2161       AliTracker::
2162          PropagateTrackToBxByBz(track,kRadius,track->GetMass(),kMaxStep,kFALSE);
2163       Double_t x[3]; track->GetXYZ(x);
2164       Double_t b[3]; AliTracker::GetBxByBz(x,b);
2165       track->RelateToVertexBxByBz(fesd->GetPrimaryVertexSPD(), b, kVeryBig);
2166
2167     }
2168     AliSysInfo::AddStamp(Form("RelToSPDVtx_%d",iEvent), 0,0,iEvent);      
2169     //
2170     // Improve the reconstructed primary vertex position using the tracks
2171     //
2172     Bool_t runVertexFinderTracks = fRunVertexFinderTracks;
2173     if(fesd->GetPrimaryVertexSPD()) {
2174       TString vtitle = fesd->GetPrimaryVertexSPD()->GetTitle();
2175       if(vtitle.Contains("cosmics")) {
2176         runVertexFinderTracks=kFALSE;
2177       }
2178     }
2179
2180     if (runVertexFinderTracks) {
2181        // TPC + ITS primary vertex
2182        ftVertexer->SetITSMode();
2183        ftVertexer->SetConstraintOff();
2184        // get cuts for vertexer from AliGRPRecoParam
2185        Bool_t constrSPD=kFALSE;
2186        if (grpRecoParam) {
2187          Int_t nCutsVertexer = grpRecoParam->GetVertexerTracksNCuts();
2188          Double_t *cutsVertexer = new Double_t[nCutsVertexer];
2189          grpRecoParam->GetVertexerTracksCutsITS(cutsVertexer,nCutsVertexer);
2190          ftVertexer->SetCuts(cutsVertexer,nCutsVertexer);
2191          delete [] cutsVertexer; cutsVertexer = NULL; 
2192          if(grpRecoParam->GetVertexerTracksConstraintITS()) { 
2193            if(fDiamondProfile && fDiamondProfile->GetXRes()<kRadius){
2194              ftVertexer->SetVtxStart(fDiamondProfile); // apply constraint only if sigmax is smaller than the beam pipe radius 
2195            }else{
2196              if(fDiamondProfileSPD && fDiamondProfileSPD->GetXRes()<kRadius){
2197                ftVertexer->SetVtxStart(fDiamondProfileSPD);
2198                constrSPD=kTRUE;
2199              }
2200            }
2201          } 
2202        }
2203        AliESDVertex *pvtx=ftVertexer->FindPrimaryVertex(fesd);
2204        if (pvtx) {
2205          if(constrSPD){
2206            TString title=pvtx->GetTitle();
2207            title.Append("SPD");
2208            pvtx->SetTitle(title);
2209          }
2210           if (pvtx->GetStatus()) {
2211              fesd->SetPrimaryVertexTracks(pvtx);
2212              for (Int_t i=0; i<ntracks; i++) {
2213                  AliESDtrack *t = fesd->GetTrack(i);
2214                  Double_t x[3]; t->GetXYZ(x);
2215                  Double_t b[3]; AliTracker::GetBxByBz(x,b);
2216                  t->RelateToVertexBxByBz(pvtx, b, kVeryBig);
2217              } 
2218           }
2219           delete pvtx; pvtx=NULL;
2220        }
2221        AliSysInfo::AddStamp(Form("VtxTrk_%d",iEvent), 0,0,iEvent);      
2222
2223        // TPC-only primary vertex
2224        ftVertexer->SetTPCMode();
2225        ftVertexer->SetConstraintOff();
2226        // get cuts for vertexer from AliGRPRecoParam
2227        if (grpRecoParam) {
2228          Int_t nCutsVertexer = grpRecoParam->GetVertexerTracksNCuts();
2229          Double_t *cutsVertexer = new Double_t[nCutsVertexer];
2230          grpRecoParam->GetVertexerTracksCutsTPC(cutsVertexer,nCutsVertexer);
2231          ftVertexer->SetCuts(cutsVertexer,nCutsVertexer);
2232          delete [] cutsVertexer; cutsVertexer = NULL; 
2233          if(fDiamondProfileTPC && grpRecoParam->GetVertexerTracksConstraintTPC()) { 
2234            if(fDiamondProfileTPC->GetXRes()<kRadius) ftVertexer->SetVtxStart(fDiamondProfileTPC); // apply constraint only if sigmax is smaller than the beam pipe radius 
2235          } 
2236        }
2237        pvtx=ftVertexer->FindPrimaryVertex(&trkArray,selectedIdx);
2238        if (pvtx) {
2239           if (pvtx->GetStatus()) {
2240              fesd->SetPrimaryVertexTPC(pvtx);
2241              for (Int_t i=0; i<ntracks; i++) {
2242                  AliESDtrack *t = fesd->GetTrack(i);
2243                  Double_t x[3]; t->GetXYZ(x);
2244                  Double_t b[3]; AliTracker::GetBxByBz(x,b);
2245                  t->RelateToVertexTPCBxByBz(pvtx, b, kVeryBig);
2246              } 
2247           }
2248           delete pvtx; pvtx=NULL;
2249        }
2250        AliSysInfo::AddStamp(Form("VtxTPC_%d",iEvent), 0,0,iEvent);      
2251
2252     }
2253     
2254     if(fDiamondProfile && fDiamondProfile->GetXRes()<kRadius) fesd->SetDiamond(fDiamondProfile);
2255     else fesd->SetDiamond(fDiamondProfileSPD);
2256
2257     if (fRunV0Finder) {
2258        // V0 finding
2259        AliV0vertexer vtxer;
2260        // get cuts for V0vertexer from AliGRPRecoParam
2261        if (grpRecoParam) {
2262          Int_t nCutsV0vertexer = grpRecoParam->GetVertexerV0NCuts();
2263          Double_t cutsV0vertexer[nCutsV0vertexer];
2264          grpRecoParam->GetVertexerV0Cuts(cutsV0vertexer);
2265          vtxer.SetCuts(cutsV0vertexer);
2266        }
2267        vtxer.Tracks2V0vertices(fesd);
2268        AliSysInfo::AddStamp(Form("V0Finder_%d",iEvent), 0,0,iEvent); 
2269
2270        if (fRunCascadeFinder) {
2271           // Cascade finding
2272           AliCascadeVertexer cvtxer;
2273           // get cuts for CascadeVertexer from AliGRPRecoParam
2274           if (grpRecoParam) {
2275             Int_t nCutsCascadeVertexer = grpRecoParam->GetVertexerCascadeNCuts();
2276             Double_t cutsCascadeVertexer[nCutsCascadeVertexer];
2277             grpRecoParam->GetVertexerCascadeCuts(cutsCascadeVertexer);
2278             cvtxer.SetCuts(cutsCascadeVertexer);
2279           }
2280           cvtxer.V0sTracks2CascadeVertices(fesd);
2281           AliSysInfo::AddStamp(Form("CascadeFinder_%d",iEvent), 0,0,iEvent); 
2282        }
2283     }
2284
2285     // AdC+FN
2286     if (fReconstructor[3])
2287       GetReconstructor(3)->FillEventTimeWithTOF(fesd,&pid);
2288
2289     // combined PID
2290     pid.MakePID(fesd);
2291
2292     if (fFillTriggerESD) {
2293       if (!FillTriggerESD(fesd)) {
2294         if (fStopOnError) {CleanUp(); return kFALSE;}
2295       }
2296     }
2297     // Always fill scalers
2298     if (!FillTriggerScalers(fesd)) {
2299        if (fStopOnError) {CleanUp(); return kFALSE;}
2300     }
2301
2302     AliSysInfo::AddStamp(Form("FillVaria_%d",iEvent), 0,0,iEvent); 
2303
2304     // write ESD
2305     UInt_t specie = fesd->GetEventSpecie();
2306     Bool_t keepAll = (specie==AliRecoParam::kCosmic || specie==AliRecoParam::kCalib);
2307     if (fCleanESD && (!keepAll) ) {
2308       CleanESD(fesd);
2309       AliSysInfo::AddStamp(Form("CleanESD_%d",iEvent), 0,0,iEvent); 
2310     }
2311     // 
2312     // RS run updated trackleter: since we want to mark the clusters used by tracks and also mark the 
2313     // tracks interpreted as primary, this step should be done in the very end, when full 
2314     // ESD info is available (particulalry, V0s)
2315     // vertex finder
2316     if (fRunMultFinder) {
2317       if (!RunMultFinder(fesd)) {
2318         if (fStopOnError) {CleanUp(); return kFALSE;}
2319       }
2320       AliSysInfo::AddStamp(Form("MultFinder_%d",iEvent), 0,0,iEvent); 
2321     }
2322
2323   if (fRunQA && IsInTasks(AliQAv1::kESDS)) {
2324     AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2325     AliQAManager::QAManager()->RunOneEvent(fesd, fhltesd) ; 
2326     AliSysInfo::AddStamp(Form("RunQA_%d",iEvent), 0,0,iEvent); 
2327   }
2328   if (fRunGlobalQA) {
2329     AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
2330     if (qadm)
2331       qadm->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2332     if (qadm && IsInTasks(AliQAv1::kESDS))
2333       qadm->Exec(AliQAv1::kESDS, fesd);
2334     AliSysInfo::AddStamp(Form("RunGlobQA_%d",iEvent), 0,0,iEvent);     
2335   }
2336
2337   // copy HLT decision from HLTesd to esd
2338   // the most relevant information is stored in a reduced container in the esd,
2339   // while the full information can be found in the HLTesd
2340   TObject* pHLTSrc=fhltesd->FindListObject(AliESDHLTDecision::Name());
2341   TObject* pHLTTgt=fesd->FindListObject(AliESDHLTDecision::Name());
2342   if (pHLTSrc && pHLTTgt) {
2343     pHLTSrc->Copy(*pHLTTgt);
2344   }
2345   //
2346   // Perform analysis of this event if requested
2347   // RS: Should be done before WriteESDfriend, since the latter may clean the esdfriend
2348   if (fAnalysis) {
2349     fRecoHandler->BeginEvent(iEvent);
2350     fAnalysis->ExecAnalysis();
2351     fRecoHandler->FinishEvent();
2352     AliSysInfo::AddStamp(Form("Analysis_%d",iEvent), 0,0,iEvent);     
2353   }  
2354   //
2355   if (fWriteESDfriend) {
2356     fesd->GetESDfriend(fesdf);
2357     AliSysInfo::AddStamp(Form("CreateFriend_%d",iEvent), 0,0,iEvent);     
2358   
2359   }
2360   //
2361   ftree->Fill();
2362   AliSysInfo::AddStamp(Form("ESDFill_%d",iEvent), 0,0,iEvent);     
2363   //
2364   if (fWriteESDfriend) {
2365     WriteESDfriend();
2366     AliSysInfo::AddStamp(Form("WriteFriend_%d",iEvent), 0,0,iEvent);     
2367   }
2368   //
2369   //
2370   // Auto-save the ESD tree in case of prompt reco @P2
2371   if (fRawReader && fRawReader->UseAutoSaveESD()) {
2372     ftree->AutoSave("SaveSelf");
2373     if (fWriteESDfriend) ftreeF->AutoSave("SaveSelf");
2374   }
2375     // write HLT ESD
2376     fhlttree->Fill();
2377
2378     // call AliEVE
2379     if (fRunAliEVE) RunAliEVE();
2380     //
2381     fesd->Reset();
2382     fhltesd->Reset();
2383     if (fWriteESDfriend) {
2384       fesdf->~AliESDfriend();
2385       new (fesdf) AliESDfriend(); // Reset...
2386     }
2387
2388     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2389       if (fReconstructor[iDet]) fReconstructor[iDet]->FinishEvent();
2390     }
2391  
2392     gSystem->GetProcInfo(&procInfo);
2393     Long_t dMres=(procInfo.fMemResident-oldMres)/1024;
2394     Long_t dMvir=(procInfo.fMemVirtual-oldMvir)/1024;
2395     Float_t dCPU=procInfo.fCpuUser+procInfo.fCpuSys-oldCPU;
2396     aveDMres+=(dMres-aveDMres)/(iEvent-fFirstEvent+1);
2397     aveDMvir+=(dMvir-aveDMvir)/(iEvent-fFirstEvent+1);
2398     aveDCPU+=(dCPU-aveDCPU)/(iEvent-fFirstEvent+1);
2399     AliInfo(Form("======================= End Event %d: Res %ld(%3ld <%3ld>) Vir %ld(%3ld <%3ld>) CPU %5.2f <%5.2f> ===================",
2400                  iEvent, procInfo.fMemResident/1024, dMres, aveDMres, procInfo.fMemVirtual/1024, dMvir, aveDMvir, dCPU, aveDCPU));
2401     oldMres=procInfo.fMemResident;
2402     oldMvir=procInfo.fMemVirtual;
2403     oldCPU=procInfo.fCpuUser+procInfo.fCpuSys;
2404   
2405     fEventInfo.Reset();
2406     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2407       if (fReconstructor[iDet]) {
2408         fReconstructor[iDet]->SetRecoParam(NULL);
2409         fReconstructor[iDet]->SetEventInfo(NULL);
2410       }
2411       if (fTracker[iDet]) fTracker[iDet]->SetEventInfo(NULL);
2412     }
2413         
2414   if (fRunQA || fRunGlobalQA) 
2415     AliQAManager::QAManager()->Increment() ; 
2416
2417   DeleteRecPoints(fDeleteRecPoints);
2418   DeleteDigits(fDeleteDigits);
2419   //
2420   return kTRUE;
2421 }
2422
2423 //_____________________________________________________________________________
2424 void AliReconstruction::SlaveTerminate()
2425 {
2426   // Finalize the run on the slave side
2427   // Called after the exit
2428   // from the event loop
2429   AliCodeTimerAuto("",0);
2430   // If analysis was done during reconstruction, we need to call SlaveTerminate for it
2431   if (fAnalysis) {
2432      fAnalysis->PackOutput(fOutput);
2433      fAnalysis->SetSkipTerminate(kTRUE);
2434      fAnalysis->Terminate();
2435   }   
2436
2437   if (fIsNewRunLoader) { // galice.root didn't exist
2438     fRunLoader->WriteHeader("OVERWRITE");
2439     fRunLoader->WriteTrigger("OVERWRITE");
2440     fRunLoader->CdGAFile();
2441     fRunLoader->Write(0, TObject::kOverwrite);
2442   }
2443
2444   const TMap *cdbMap = AliCDBManager::Instance()->GetStorageMap();       
2445   const TList *cdbList = AliCDBManager::Instance()->GetRetrievedIds();   
2446                  
2447    TMap *cdbMapCopy = new TMap(cdbMap->GetEntries());    
2448    cdbMapCopy->SetOwner(1);      
2449    cdbMapCopy->SetName("cdbMap");        
2450    TIter iter(cdbMap->GetTable());       
2451          
2452    TPair* pair = 0;      
2453    while((pair = dynamic_cast<TPair*> (iter.Next()))){   
2454          TObjString* keyStr = dynamic_cast<TObjString*> (pair->Key());   
2455          TObjString* valStr = dynamic_cast<TObjString*> (pair->Value());
2456          if (keyStr && valStr)
2457            cdbMapCopy->Add(new TObjString(keyStr->GetName()), new TObjString(valStr->GetName()));        
2458    }     
2459          
2460    TList *cdbListCopy = new TList();     
2461    cdbListCopy->SetOwner(1);     
2462    cdbListCopy->SetName("cdbList");      
2463          
2464    TIter iter2(cdbList);         
2465          
2466         AliCDBId* id=0;
2467         while((id = dynamic_cast<AliCDBId*> (iter2.Next()))){    
2468          cdbListCopy->Add(new TObjString(id->ToString().Data()));        
2469    }     
2470          
2471    ftree->GetUserInfo()->Add(cdbMapCopy);        
2472    ftree->GetUserInfo()->Add(cdbListCopy);
2473
2474    // Add the AliRoot version that created this file
2475    TString sVersion("aliroot ");
2476    sVersion += ALIROOT_SVN_BRANCH;
2477    sVersion += ":";
2478    sVersion += ALIROOT_SVN_REVISION;
2479    sVersion += "; root ";
2480    sVersion += ROOT_SVN_BRANCH;
2481    sVersion += ":";
2482    sVersion += ROOT_SVN_REVISION;
2483    sVersion += "; metadata ";
2484    sVersion += getenv("PRODUCTION_METADATA");
2485                     
2486
2487    TNamed * alirootVersion = new TNamed("alirootVersion",sVersion.Data());
2488    ftree->GetUserInfo()->Add(alirootVersion); // The list becomes owner of alirootVersion
2489
2490   ffile->cd();
2491
2492   // we want to have only one tree version number
2493   ftree->Write(ftree->GetName(),TObject::kOverwrite);
2494   fhlttree->Write(fhlttree->GetName(),TObject::kOverwrite);
2495
2496   if (fWriteESDfriend) {
2497     ffileF->cd();
2498     ftreeF->Write(ftreeF->GetName(),TObject::kOverwrite);
2499   }
2500
2501 // Finish with Plane Efficiency evaluation: before of CleanUp !!!
2502   if (fRunPlaneEff && !FinishPlaneEff()) {
2503    AliWarning("Finish PlaneEff evaluation failed");
2504   }
2505
2506   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2507     if (fReconstructor[iDet]) fReconstructor[iDet]->Terminate();
2508   }
2509   // End of cycle for the in-loop  
2510
2511   if (fRunQA || fRunGlobalQA) {
2512     AliQAManager::QAManager()->EndOfCycle() ;
2513     if (fInput &&
2514         !fProofOutputLocation.IsNull() &&
2515         fProofOutputArchive.IsNull() &&
2516         !fProofOutputDataset) {
2517       TString qaOutputFile(Form("%sMerged.%s.Data.root",
2518                                 fProofOutputLocation.Data(),
2519                                 AliQAv1::GetQADataFileName()));
2520       TProofOutputFile *qaProofFile = new TProofOutputFile(Form("Merged.%s.Data.root",
2521                                                                 AliQAv1::GetQADataFileName()));
2522       qaProofFile->SetOutputFileName(qaOutputFile.Data());
2523       if (AliDebugLevel() > 0) qaProofFile->Dump();
2524       fOutput->Add(qaProofFile);
2525       MergeQA(qaProofFile->GetFileName());
2526     }
2527     else {
2528       MergeQA();
2529     }
2530   }
2531
2532   gROOT->cd();
2533   CleanUp();
2534
2535   if (fInput) {
2536     if (!fProofOutputFileName.IsNull() &&
2537         !fProofOutputLocation.IsNull() &&
2538         fProofOutputDataset &&
2539         !fProofOutputArchive.IsNull()) {
2540       TProofOutputFile *zipProofFile = new TProofOutputFile(fProofOutputFileName.Data(),
2541                                                             "DROV",
2542                                                             fProofOutputLocation.Data());
2543       if (AliDebugLevel() > 0) zipProofFile->Dump();
2544       fOutput->Add(zipProofFile);
2545       TString fileList(fProofOutputArchive.Data());
2546       fileList.ReplaceAll(","," ");
2547       TString command;
2548 #if ROOT_SVN_REVISION >= 30174
2549       command.Form("zip -n root %s/%s %s",zipProofFile->GetDir(kTRUE),zipProofFile->GetFileName(),fileList.Data());
2550 #else
2551       command.Form("zip -n root %s/%s %s",zipProofFile->GetDir(),zipProofFile->GetFileName(),fileList.Data());
2552 #endif
2553       AliInfo(Form("Executing: %s",command.Data()));
2554       gSystem->Exec(command.Data());
2555     }
2556   }
2557 }
2558     
2559 //_____________________________________________________________________________
2560 void AliReconstruction::Terminate()
2561 {
2562   // Create tags for the events in the ESD tree (the ESD tree is always present)
2563   // In case of empty events the tags will contain dummy values
2564   AliCodeTimerAuto("",0);
2565
2566   // Do not call the ESD tag creator in case of PROOF-based reconstruction
2567   if (!fInput) {
2568     AliESDTagCreator *esdtagCreator = new AliESDTagCreator();
2569     esdtagCreator->CreateESDTags(fFirstEvent,fLastEvent,fGRPData, AliQAv1::Instance()->GetQA(), AliQAv1::Instance()->GetEventSpecies(), AliQAv1::kNDET, AliRecoParam::kNSpecies);
2570     delete esdtagCreator;
2571   }
2572
2573   // Cleanup of CDB manager: cache and active storages!
2574   AliCDBManager::Instance()->ClearCache();
2575 }
2576
2577 //_____________________________________________________________________________
2578 Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
2579 {
2580 // run the local reconstruction
2581
2582   static Int_t eventNr=0;
2583   AliCodeTimerAuto("",0)
2584
2585   TString detStr = detectors;
2586   // execute HLT reconstruction first since other detector reconstruction
2587   // might depend on HLT data
2588   // key 'HLT' is removed from detStr by IsSelected
2589   if (IsSelected("HLT", detStr)) {
2590     AliReconstructor* reconstructor = GetReconstructor(kNDetectors-1);
2591     if (reconstructor) {
2592       // there is no AliLoader for HLT, see
2593       // https://savannah.cern.ch/bugs/?35473
2594       AliInfo("running reconstruction for HLT");
2595       if (fRawReader) {
2596         AliInfo("reconstructor->Reconstruct(fRawReader, NULL)");
2597         reconstructor->Reconstruct(fRawReader, NULL);
2598       } 
2599       else {
2600         AliInfo("reconstructor->Reconstruct(dummy, NULL)");
2601         TTree* dummy=NULL;
2602         reconstructor->Reconstruct(dummy, NULL);
2603       }
2604     }
2605     AliSysInfo::AddStamp(Form("LRecHLT_%d",eventNr), -1,1,eventNr);
2606   }
2607
2608   AliInfo(Form("kNDetectors = %d",kNDetectors));
2609
2610   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2611     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2612     AliDebug(1, Form("Detector: %s", fgkDetectorName[iDet]));
2613     AliReconstructor* reconstructor = GetReconstructor(iDet);
2614     if (!reconstructor) continue;
2615     AliLoader* loader = fLoader[iDet];
2616     if (!loader) {
2617       AliWarning(Form("No loader is defined for %s!",fgkDetectorName[iDet]));
2618       continue;
2619     }
2620     // conversion of digits
2621     if (fRawReader && reconstructor->HasDigitConversion()) {
2622       AliInfo(Form("converting raw data digits into root objects for %s", 
2623                    fgkDetectorName[iDet]));
2624 //      AliCodeTimerAuto(Form("converting raw data digits into root objects for %s", 
2625 //                            fgkDetectorName[iDet]),0);
2626       loader->LoadDigits("update");
2627       loader->CleanDigits();
2628       loader->MakeDigitsContainer();
2629       TTree* digitsTree = loader->TreeD();
2630       reconstructor->ConvertDigits(fRawReader, digitsTree);
2631       loader->WriteDigits("OVERWRITE");
2632       loader->UnloadDigits();
2633     }
2634     // local reconstruction
2635     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
2636     //AliCodeTimerAuto(Form("running reconstruction for %s", fgkDetectorName[iDet]),0);
2637     AliDebug(1, "Loading Rec Points");
2638     loader->LoadRecPoints("update");
2639     AliDebug(1, "Cleaning Rec Points");
2640     loader->CleanRecPoints();
2641     AliDebug(1, "Making Rec Points Container");
2642     loader->MakeRecPointsContainer();
2643     TTree* clustersTree = loader->TreeR();
2644     if (fRawReader && !reconstructor->HasDigitConversion()) {
2645       reconstructor->Reconstruct(fRawReader, clustersTree);
2646     } 
2647     else {
2648       AliDebug(1, "Loading Digits");
2649       loader->LoadDigits("read");
2650       TTree* digitsTree = loader->TreeD();
2651       AliDebug(1, Form("Digits Tree = %p",digitsTree));
2652       if (!digitsTree) {
2653         AliError(Form("Can't get the %s digits tree", fgkDetectorName[iDet]));
2654         if (fStopOnError) 
2655           return kFALSE;
2656       } 
2657       else {
2658         AliDebug(1, "Digits -> Clusters");
2659         reconstructor->Reconstruct(digitsTree, clustersTree);
2660         if (fRunQA && IsInTasks(AliQAv1::kDIGITSR)) {
2661           AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2662           AliQAManager::QAManager()->RunOneEventInOneDetector(iDet, digitsTree) ; 
2663         }
2664       }
2665       loader->UnloadDigits();
2666     }
2667     if (fRunQA && IsInTasks(AliQAv1::kRECPOINTS)) {
2668       AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
2669       AliQAManager::QAManager()->RunOneEventInOneDetector(iDet, clustersTree) ; 
2670     }
2671     loader->WriteRecPoints("OVERWRITE");
2672     loader->UnloadRecPoints();
2673     AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr), iDet,1,eventNr);
2674   }
2675   if (!IsSelected("CTP", detStr)) AliDebug(10,"No CTP");
2676   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
2677     AliError(Form("the following detectors were not found: %s",
2678                   detStr.Data()));
2679     if (fStopOnError) 
2680       return kFALSE;
2681   }
2682   eventNr++;
2683   return kTRUE;
2684 }
2685 //_____________________________________________________________________________
2686 Bool_t AliReconstruction::RunSPDTrackleting(AliESDEvent*& esd)
2687 {
2688 // run the SPD trackleting (for SPD efficiency purpouses)
2689
2690   AliCodeTimerAuto("",0)
2691
2692   Double_t vtxPos[3] = {0, 0, 0};
2693   Double_t vtxErr[3] = {0.0, 0.0, 0.0};
2694 /*
2695   TArrayF m
2696 /
2697 cVertex(3);
2698   // if(MC)
2699   if (fRunLoader->GetHeader() && fRunLoader->GetHeader()->GenEventHeader()) {
2700     fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(mcVertex);
2701     for (Int_t i = 0; i < 3; i++) vtxPos[i] = mcVertex[i];
2702   }
2703 */
2704   const AliESDVertex *vertex = esd->GetVertex();
2705   if(!vertex){
2706     AliWarning("Vertex not found");
2707     return kFALSE;
2708   }
2709   vertex->GetXYZ(vtxPos);
2710   vertex->GetSigmaXYZ(vtxErr);
2711   if (fSPDTrackleter) {
2712     AliInfo("running the SPD Trackleter for Plane Efficiency Evaluation");
2713
2714     // load clusters
2715     fLoader[0]->LoadRecPoints("read");
2716     TTree* tree = fLoader[0]->TreeR();
2717     if (!tree) {
2718       AliError("Can't get the ITS cluster tree");
2719       return kFALSE;
2720     }
2721     fSPDTrackleter->LoadClusters(tree);
2722     fSPDTrackleter->SetVertex(vtxPos, vtxErr);
2723     // run trackleting
2724     if (fSPDTrackleter->Clusters2Tracks(esd) != 0) {
2725       AliWarning("AliITSTrackleterSPDEff Clusters2Tracks failed");
2726      // fLoader[0]->UnloadRecPoints();
2727       return kFALSE;
2728     }
2729 //fSPDTrackleter->UnloadRecPoints();
2730   } else {
2731     AliWarning("SPDTrackleter not available");
2732     return kFALSE;
2733   }
2734   return kTRUE;
2735 }
2736
2737 //_____________________________________________________________________________
2738 Bool_t AliReconstruction::RunVertexFinder(AliESDEvent*& esd)
2739 {
2740 // run the barrel tracking
2741
2742   AliCodeTimerAuto("",0)
2743
2744   AliVertexer *vertexer = CreateVertexer();
2745   if (!vertexer) return kFALSE;
2746
2747   AliInfo(Form("running the ITS vertex finder: %s",vertexer->ClassName()));
2748   AliESDVertex* vertex = NULL;
2749   if (fLoader[0]) {
2750     fLoader[0]->LoadRecPoints();
2751     TTree* cltree = fLoader[0]->TreeR();
2752     if (cltree) {
2753       if(fDiamondProfileSPD) vertexer->SetVtxStart(fDiamondProfileSPD);
2754       vertex = vertexer->FindVertexForCurrentEvent(cltree);
2755     }
2756     else {
2757       AliError("Can't get the ITS cluster tree");
2758     }
2759     fLoader[0]->UnloadRecPoints();
2760   }
2761   else {
2762     AliError("Can't get the ITS loader");
2763   }
2764   if(!vertex){
2765     AliWarning("Vertex not found");
2766     vertex = new AliESDVertex();
2767     vertex->SetName("default");
2768   }
2769   else {
2770     vertex->SetName("reconstructed");
2771   }
2772
2773   Double_t vtxPos[3];
2774   Double_t vtxErr[3];
2775   vertex->GetXYZ(vtxPos);
2776   vertex->GetSigmaXYZ(vtxErr);
2777
2778   esd->SetPrimaryVertexSPD(vertex);
2779   AliESDVertex *vpileup = NULL;
2780   Int_t novertices = 0;
2781   vpileup = vertexer->GetAllVertices(novertices);
2782   if(novertices>1){
2783     for (Int_t kk=1; kk<novertices; kk++)esd->AddPileupVertexSPD(&vpileup[kk]);
2784   }
2785   /*
2786   // if SPD multiplicity has been determined, it is stored in the ESD
2787   AliMultiplicity *mult = vertexer->GetMultiplicity();
2788   if(mult)esd->SetMultiplicity(mult);
2789   */
2790   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2791     if (fTracker[iDet]) fTracker[iDet]->SetVertex(vtxPos, vtxErr);
2792   }  
2793   delete vertex;
2794
2795   delete vertexer;
2796
2797   return kTRUE;
2798 }
2799
2800 //_____________________________________________________________________________
2801 Bool_t AliReconstruction::RunMultFinder(AliESDEvent*& esd)
2802 {
2803   // run the trackleter for multiplicity study
2804
2805   AliCodeTimerAuto("",0)
2806
2807   AliTrackleter *trackleter = CreateMultFinder();
2808   if (!trackleter) return kFALSE;
2809
2810   AliInfo(Form("running the ITS multiplicity finder: %s",trackleter->ClassName()));
2811
2812   if (fLoader[0]) {
2813     fLoader[0]->LoadRecPoints();
2814     TTree* cltree = fLoader[0]->TreeR();
2815     if (cltree) {
2816       trackleter->Reconstruct(esd,cltree);
2817       AliMultiplicity *mult = trackleter->GetMultiplicity();
2818       if(mult) esd->SetMultiplicity(mult);
2819     }
2820     else {
2821       AliError("Can't get the ITS cluster tree");
2822     }
2823     fLoader[0]->UnloadRecPoints();
2824   }
2825   else {
2826     AliError("Can't get the ITS loader");
2827   }
2828
2829   delete trackleter;
2830
2831   return kTRUE;
2832 }
2833
2834 //_____________________________________________________________________________
2835 Bool_t AliReconstruction::RunMuonTracking(AliESDEvent*& esd)
2836 {
2837 // run the muon spectrometer tracking
2838
2839   AliCodeTimerAuto("",0)
2840
2841   if (!fRunLoader) {
2842     AliError("Missing runLoader!");
2843     return kFALSE;
2844   }
2845   Int_t iDet =  GetDetIndex("MUON"); // for MUON
2846
2847   // Get a pointer to the MUON reconstructor
2848   AliReconstructor *reconstructor = GetReconstructor(iDet);
2849   if (!reconstructor) return kFALSE;
2850
2851   
2852   TString detName = fgkDetectorName[iDet];
2853   AliDebug(1, Form("%s tracking", detName.Data()));
2854   AliTracker *tracker =  reconstructor->CreateTracker();
2855   if (!tracker) {
2856     AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
2857     return kFALSE;
2858   }
2859      
2860   // read RecPoints
2861   fLoader[iDet]->LoadRecPoints("read");  
2862
2863   tracker->LoadClusters(fLoader[iDet]->TreeR());
2864   
2865   Int_t rv = tracker->Clusters2Tracks(esd);
2866   
2867   fLoader[iDet]->UnloadRecPoints();
2868
2869   tracker->UnloadClusters();
2870   
2871   if ( rv )
2872   {
2873     AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
2874     return kFALSE;
2875   }
2876   
2877   return kTRUE;
2878 }
2879
2880
2881 //_____________________________________________________________________________
2882 Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd,AliESDpid &PID)
2883 {
2884 // run the barrel tracking
2885   static Int_t eventNr=0;
2886   AliCodeTimerAuto("",0)
2887
2888   AliInfo("running tracking");
2889
2890   // Set the event info which is used
2891   // by the trackers in order to obtain
2892   // information about read-out detectors,
2893   // trigger etc.
2894   AliDebug(1, "Setting event info");
2895   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2896     if (!fTracker[iDet]) continue;
2897     fTracker[iDet]->SetEventInfo(&fEventInfo);
2898   }
2899
2900   //Fill the ESD with the T0 info (will be used by the TOF) 
2901   if (fReconstructor[11] && fLoader[11]) {
2902     fLoader[11]->LoadRecPoints("READ");
2903     TTree *treeR = fLoader[11]->TreeR();
2904     if (treeR) {
2905       GetReconstructor(11)->FillESD((TTree *)NULL,treeR,esd);
2906     }
2907   }
2908
2909   // pass 1: TPC + ITS inwards
2910   for (Int_t iDet = 1; iDet >= 0; iDet--) {
2911     if (!fTracker[iDet]) continue;
2912     AliDebug(1, Form("%s tracking", fgkDetectorName[iDet]));
2913
2914     // load clusters
2915     fLoader[iDet]->LoadRecPoints("read");
2916     AliSysInfo::AddStamp(Form("RLoadCluster%s_%d",fgkDetectorName[iDet],eventNr),iDet,1, eventNr);
2917     TTree* tree = fLoader[iDet]->TreeR();
2918     if (!tree) {
2919       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
2920       return kFALSE;
2921     }
2922     fTracker[iDet]->LoadClusters(tree);
2923     AliSysInfo::AddStamp(Form("TLoadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
2924     // run tracking
2925     if (fTracker[iDet]->Clusters2TracksHLT(esd, fhltesd) != 0) {
2926       AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
2927       return kFALSE;
2928     }
2929     AliSysInfo::AddStamp(Form("Tracking0%s_%d",fgkDetectorName[iDet],eventNr), iDet,3,eventNr);
2930     // preliminary PID in TPC needed by the ITS tracker
2931     if (iDet == 1) {
2932       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
2933       PID.MakePID(esd,kTRUE);
2934       AliSysInfo::AddStamp(Form("MakePID0%s_%d",fgkDetectorName[iDet],eventNr), iDet,4,eventNr);
2935     } 
2936   }
2937
2938   // pass 2: ALL backwards
2939
2940   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
2941     if (!fTracker[iDet]) continue;
2942     AliDebug(1, Form("%s back propagation", fgkDetectorName[iDet]));
2943
2944     // load clusters
2945     if (iDet > 1) {     // all except ITS, TPC
2946       TTree* tree = NULL;
2947       fLoader[iDet]->LoadRecPoints("read");
2948       AliSysInfo::AddStamp(Form("RLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,1, eventNr);
2949       tree = fLoader[iDet]->TreeR();
2950       if (!tree) {
2951         AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
2952         return kFALSE;
2953       }
2954       fTracker[iDet]->LoadClusters(tree); 
2955       AliSysInfo::AddStamp(Form("TLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
2956     }
2957
2958     // run tracking
2959     if (iDet>1) // start filling residuals for the "outer" detectors
2960       if (fRunGlobalQA) {
2961         AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
2962         TObjArray ** arr = AliTracker::GetResidualsArray() ; 
2963         if (arr) {
2964           AliRecoParam::EventSpecie_t es=fRecoParam.GetEventSpecie();
2965           TObjArray * elem = arr[AliRecoParam::AConvert(es)];
2966           if ( elem && (! elem->At(0)) ) {
2967             AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
2968             if (qadm) qadm->InitRecPointsForTracker() ; 
2969           }
2970         }
2971         //      AliSysInfo::AddStamp(Form("QAInitResid%s_%d",fgkDetectorName[iDet],eventNr), iDet,0, eventNr);
2972       }
2973     if (fTracker[iDet]->PropagateBack(esd) != 0) {
2974       AliError(Form("%s backward propagation failed", fgkDetectorName[iDet]));
2975       //      return kFALSE;
2976     }
2977     AliSysInfo::AddStamp(Form("Tracking1%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
2978
2979     // unload clusters
2980     if (iDet > 3) {     // all except ITS, TPC, TRD and TOF
2981       fTracker[iDet]->UnloadClusters();
2982       fLoader[iDet]->UnloadRecPoints();
2983     }
2984     // updated PID in TPC needed by the ITS tracker -MI
2985     if (iDet == 1) {
2986       //GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
2987       //AliESDpid::MakePID(esd);
2988       PID.MakePID(esd,kTRUE);
2989       AliSysInfo::AddStamp(Form("MakePID1%s_%d",fgkDetectorName[iDet],eventNr), iDet,4,eventNr);
2990     }
2991
2992   }
2993   //stop filling residuals for the "outer" detectors
2994   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
2995
2996   // pass 3: TRD + TPC + ITS refit inwards
2997
2998   for (Int_t iDet = 2; iDet >= 0; iDet--) {
2999     if (!fTracker[iDet]) continue;
3000     AliDebug(1, Form("%s inward refit", fgkDetectorName[iDet]));
3001
3002     // run tracking
3003     if (iDet<2) // start filling residuals for TPC and ITS
3004       if (fRunGlobalQA) {
3005         AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
3006         TObjArray ** arr = AliTracker::GetResidualsArray() ; 
3007         if (arr) {
3008           AliRecoParam::EventSpecie_t es=fRecoParam.GetEventSpecie();
3009           TObjArray * elem = arr[AliRecoParam::AConvert(es)];
3010           if ( elem && (! elem->At(0)) ) {
3011             AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
3012             if (qadm) qadm->InitRecPointsForTracker() ; 
3013           }
3014         }
3015       }
3016     
3017     if (fTracker[iDet]->RefitInward(esd) != 0) {
3018       AliError(Form("%s inward refit failed", fgkDetectorName[iDet]));
3019       //      return kFALSE;
3020     }
3021     // run postprocessing
3022     if (fTracker[iDet]->PostProcess(esd) != 0) {
3023       AliError(Form("%s postprocessing failed", fgkDetectorName[iDet]));
3024       //      return kFALSE;
3025     }
3026     AliSysInfo::AddStamp(Form("Tracking2%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
3027   }
3028
3029   // write space-points to the ESD in case alignment data output
3030   // is switched on
3031   if (fWriteAlignmentData) {
3032     WriteAlignmentData(esd);
3033     AliSysInfo::AddStamp(Form("WrtAlignData_%d",eventNr), 0,0, eventNr);
3034   }
3035   
3036   for (Int_t iDet = 3; iDet >= 0; iDet--) {
3037     if (!fTracker[iDet]) continue;
3038     // unload clusters
3039     fTracker[iDet]->UnloadClusters();
3040     AliSysInfo::AddStamp(Form("TUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,4, eventNr);
3041     fLoader[iDet]->UnloadRecPoints();
3042     AliSysInfo::AddStamp(Form("RUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,5, eventNr);
3043   }
3044   // stop filling residuals for TPC and ITS
3045   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
3046
3047   eventNr++;
3048   return kTRUE;
3049 }
3050
3051 //_____________________________________________________________________________
3052 Bool_t AliReconstruction::CleanESD(AliESDEvent *esd){
3053   //
3054   // Remove the data which are not needed for the physics analysis.
3055   //
3056
3057   Int_t nTracks=esd->GetNumberOfTracks();
3058   Int_t nV0s=esd->GetNumberOfV0s();
3059   AliInfo
3060   (Form("Number of ESD tracks and V0s before cleaning: %d %d",nTracks,nV0s));
3061
3062   Float_t cleanPars[]={fV0DCAmax,fV0CsPmin,fDmax,fZmax};
3063   Bool_t rc=esd->Clean(cleanPars);
3064
3065   nTracks=esd->GetNumberOfTracks();
3066   nV0s=esd->GetNumberOfV0s();
3067   AliInfo
3068   (Form("Number of ESD tracks and V0s after cleaning %d %d",nTracks,nV0s));
3069
3070   return rc;
3071 }
3072
3073 //_____________________________________________________________________________
3074 Bool_t AliReconstruction::FillESD(AliESDEvent*& esd, const TString& detectors)
3075 {
3076 // fill the event summary data
3077
3078   AliCodeTimerAuto("",0)
3079     static Int_t eventNr=0; 
3080   TString detStr = detectors;
3081   
3082   AliSysInfo::AddStamp(Form("FillESDb%d",eventNr), -19,-19, eventNr);
3083   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3084   if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3085     AliReconstructor* reconstructor = GetReconstructor(iDet);
3086     if (!reconstructor) continue;
3087     AliDebug(1, Form("filling ESD for %s", fgkDetectorName[iDet]));
3088     TTree* clustersTree = NULL;
3089     if (fLoader[iDet]) {
3090       fLoader[iDet]->LoadRecPoints("read");
3091       clustersTree = fLoader[iDet]->TreeR();
3092       if (!clustersTree) {
3093         AliError(Form("Can't get the %s clusters tree", 
3094                       fgkDetectorName[iDet]));
3095         if (fStopOnError) return kFALSE;
3096       }
3097     }
3098     if (fRawReader && !reconstructor->HasDigitConversion()) {
3099       reconstructor->FillESD(fRawReader, clustersTree, esd);
3100     } else {
3101       TTree* digitsTree = NULL;
3102       if (fLoader[iDet]) {
3103         fLoader[iDet]->LoadDigits("read");
3104         digitsTree = fLoader[iDet]->TreeD();
3105         if (!digitsTree) {
3106           AliError(Form("Can't get the %s digits tree", 
3107                         fgkDetectorName[iDet]));
3108           if (fStopOnError) return kFALSE;
3109         }
3110       }
3111       reconstructor->FillESD(digitsTree, clustersTree, esd);
3112       if (fLoader[iDet]) fLoader[iDet]->UnloadDigits();
3113     }
3114     if (fLoader[iDet]) {
3115       fLoader[iDet]->UnloadRecPoints();
3116     }
3117   }
3118   
3119   if (!IsSelected("CTP", detStr)) AliDebug(10,"No CTP");
3120   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
3121     AliError(Form("the following detectors were not found: %s", 
3122                   detStr.Data()));
3123     if (fStopOnError) return kFALSE;
3124   }
3125   AliSysInfo::AddStamp(Form("FillESDe%d",eventNr), -20,-20, eventNr);
3126   eventNr++;
3127   return kTRUE;
3128 }
3129
3130 //_____________________________________________________________________________
3131 Bool_t AliReconstruction::FillTriggerESD(AliESDEvent*& esd)
3132 {
3133   // Reads the trigger decision which is
3134   // stored in Trigger.root file and fills
3135   // the corresponding esd entries
3136
3137   AliCodeTimerAuto("",0)
3138   
3139   AliInfo("Filling trigger information into the ESD");
3140
3141   if (fRawReader) {
3142     AliCTPRawStream input(fRawReader);
3143     if (!input.Next()) {
3144       AliWarning("No valid CTP (trigger) DDL raw data is found ! The trigger info is taken from the event header!");
3145     }
3146     else {
3147       if (esd->GetTriggerMask() != input.GetClassMask())
3148         AliError(Form("Invalid trigger pattern found in CTP raw-data: %llx %llx",
3149                       input.GetClassMask(),esd->GetTriggerMask()));
3150       if (esd->GetOrbitNumber() != input.GetOrbitID())
3151         AliError(Form("Invalid orbit id found in CTP raw-data: %x %x",
3152                       input.GetOrbitID(),esd->GetOrbitNumber()));
3153       if (esd->GetBunchCrossNumber() != input.GetBCID())
3154         AliError(Form("Invalid bunch-crossing id found in CTP raw-data: %x %x",
3155                       input.GetBCID(),esd->GetBunchCrossNumber()));
3156       AliESDHeader* esdheader = esd->GetHeader();
3157       esdheader->SetL0TriggerInputs(input.GetL0Inputs());
3158       esdheader->SetL1TriggerInputs(input.GetL1Inputs());
3159       esdheader->SetL2TriggerInputs(input.GetL2Inputs());
3160       // IR
3161       //      UInt_t orbit=input.GetOrbitID();
3162       for(Int_t i=0 ; i<input.GetNIRs() ; i++ ) {
3163         esdheader->AddTriggerIR(input.GetIR(i));
3164       }
3165        AliCentralTrigger* rlCTP = fRunLoader->GetTrigger();
3166        if (rlCTP) {
3167          rlCTP->SetL0TriggerInputs(input.GetL0Inputs());
3168          rlCTP->SetL1TriggerInputs(input.GetL1Inputs());
3169          rlCTP->SetL2TriggerInputs(input.GetL2Inputs());
3170        }
3171     }
3172     if (fIsNewRunLoader) fRunLoader->TreeCT()->Fill();
3173   }
3174   return kTRUE;
3175 }
3176 //_____________________________________________________________________________
3177 Bool_t AliReconstruction::FillTriggerScalers(AliESDEvent*& esd)
3178 {
3179   //Scalers
3180   //fRunScalers->Print();
3181   if(fRunScalers && fRunScalers->CheckRunScalers()){
3182      AliTimeStamp* timestamp = new AliTimeStamp(esd->GetOrbitNumber(), esd->GetPeriodNumber(), esd->GetBunchCrossNumber());
3183      //AliTimeStamp* timestamp = new AliTimeStamp(10308000, 0, (ULong64_t)486238);
3184      AliESDHeader* esdheader = fesd->GetHeader();
3185      for(Int_t i=0;i<50;i++){
3186           if((1ull<<i) & esd->GetTriggerMask()){
3187           AliTriggerScalersESD* scalesd = fRunScalers->GetScalersForEventClass( timestamp, i+1);
3188           if(scalesd)esdheader->SetTriggerScalersRecord(scalesd);
3189         }
3190      }
3191      const AliTriggerScalersRecordESD* scalrecEvent = fRunScalers->GetScalersDeltaForEvent( timestamp);
3192      const AliTriggerScalersRecordESD* scalrecRun = fRunScalers->GetScalersDeltaForRun();
3193      if (scalrecEvent) esdheader->SetTriggerScalersDeltaEvent(scalrecEvent);
3194      if (scalrecRun) esdheader->SetTriggerScalersDeltaRun(scalrecRun);
3195   }
3196   return kTRUE;
3197 }
3198 //_____________________________________________________________________________
3199 Bool_t AliReconstruction::FillRawEventHeaderESD(AliESDEvent*& esd)
3200 {
3201   // 
3202   // Filling information from RawReader Header
3203   // 
3204
3205   if (!fRawReader) return kFALSE;
3206
3207   AliInfo("Filling information from RawReader Header");
3208
3209   esd->SetBunchCrossNumber(fRawReader->GetBCID());
3210   esd->SetOrbitNumber(fRawReader->GetOrbitID());
3211   esd->SetPeriodNumber(fRawReader->GetPeriod());
3212
3213   esd->SetTimeStamp(fRawReader->GetTimestamp());  
3214   esd->SetEventType(fRawReader->GetType());
3215
3216   return kTRUE;
3217 }
3218
3219
3220 //_____________________________________________________________________________
3221 Bool_t AliReconstruction::IsSelected(TString detName, TString& detectors) const
3222 {
3223 // check whether detName is contained in detectors
3224 // if yes, it is removed from detectors
3225
3226   // check if all detectors are selected
3227   if ((detectors.CompareTo("ALL") == 0) ||
3228       detectors.BeginsWith("ALL ") ||
3229       detectors.EndsWith(" ALL") ||
3230       detectors.Contains(" ALL ")) {
3231     detectors = "ALL";
3232     return kTRUE;
3233   }
3234
3235   // search for the given detector
3236   Bool_t result = kFALSE;
3237   if ((detectors.CompareTo(detName) == 0) ||
3238       detectors.BeginsWith(detName+" ") ||
3239       detectors.EndsWith(" "+detName) ||
3240       detectors.Contains(" "+detName+" ")) {
3241     detectors.ReplaceAll(detName, "");
3242     result = kTRUE;
3243   }
3244
3245   // clean up the detectors string
3246   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
3247   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
3248   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
3249
3250   return result;
3251 }
3252
3253 //_____________________________________________________________________________
3254 Bool_t AliReconstruction::InitRunLoader()
3255 {
3256 // get or create the run loader
3257
3258   if (gAlice) delete gAlice;
3259   gAlice = NULL;
3260
3261   TFile *gafile = TFile::Open(fGAliceFileName.Data());
3262   //  if (!gSystem->AccessPathName(fGAliceFileName.Data())) { // galice.root exists
3263   if (gafile) { // galice.root exists
3264     gafile->Close();
3265     delete gafile;
3266
3267     // load all base libraries to get the loader classes
3268     TString libs = gSystem->GetLibraries();
3269     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3270       TString detName = fgkDetectorName[iDet];
3271       if (libs.Contains("lib" + detName + "base.so")) continue;
3272       gSystem->Load("lib" + detName + "base.so");
3273     }
3274     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data());
3275     if (!fRunLoader) {
3276       AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
3277       CleanUp();
3278       return kFALSE;
3279     }
3280
3281     fRunLoader->CdGAFile();
3282     fRunLoader->LoadgAlice();
3283
3284     //PH This is a temporary fix to give access to the kinematics
3285     //PH that is needed for the labels of ITS clusters
3286     fRunLoader->LoadHeader();
3287     fRunLoader->LoadKinematics();
3288
3289   } else {               // galice.root does not exist
3290     if (!fRawReader) {
3291       AliError(Form("the file %s does not exist", fGAliceFileName.Data()));
3292     }
3293     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data(),
3294                                     AliConfig::GetDefaultEventFolderName(),
3295                                     "recreate");
3296     if (!fRunLoader) {
3297       AliError(Form("could not create run loader in file %s", 
3298                     fGAliceFileName.Data()));
3299       CleanUp();
3300       return kFALSE;
3301     }
3302     fIsNewRunLoader = kTRUE;
3303     fRunLoader->MakeTree("E");
3304     fRunLoader->MakeTree("GG");
3305
3306     if (fNumberOfEventsPerFile > 0)
3307       fRunLoader->SetNumberOfEventsPerFile(fNumberOfEventsPerFile);
3308     else
3309       fRunLoader->SetNumberOfEventsPerFile((UInt_t)-1);
3310   }
3311
3312   return kTRUE;
3313 }
3314
3315 //_____________________________________________________________________________
3316 AliReconstructor* AliReconstruction::GetReconstructor(Int_t iDet)
3317 {
3318 // get the reconstructor object and the loader for a detector
3319
3320   if (fReconstructor[iDet]) {
3321     if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
3322       const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
3323       fReconstructor[iDet]->SetRecoParam(par);
3324       fReconstructor[iDet]->SetRunInfo(fRunInfo);
3325     }
3326     return fReconstructor[iDet];
3327   }
3328
3329   // load the reconstructor object
3330   TPluginManager* pluginManager = gROOT->GetPluginManager();
3331   TString detName = fgkDetectorName[iDet];
3332   TString recName = "Ali" + detName + "Reconstructor";
3333
3334   if (!fIsNewRunLoader && !fRunLoader->GetLoader(detName+"Loader") && (detName != "HLT")) return NULL;
3335
3336   AliReconstructor* reconstructor = NULL;
3337   // first check if a plugin is defined for the reconstructor
3338   TPluginHandler* pluginHandler = 
3339     pluginManager->FindHandler("AliReconstructor", detName);
3340   // if not, add a plugin for it
3341   if (!pluginHandler) {
3342     AliDebug(1, Form("defining plugin for %s", recName.Data()));
3343     TString libs = gSystem->GetLibraries();
3344     if (libs.Contains("lib" + detName + "base.so") ||
3345         (gSystem->Load("lib" + detName + "base.so") >= 0)) {
3346       pluginManager->AddHandler("AliReconstructor", detName, 
3347                                 recName, detName + "rec", recName + "()");
3348     } else {
3349       pluginManager->AddHandler("AliReconstructor", detName, 
3350                                 recName, detName, recName + "()");
3351     }
3352     pluginHandler = pluginManager->FindHandler("AliReconstructor", detName);
3353   }
3354   if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
3355     reconstructor = (AliReconstructor*) pluginHandler->ExecPlugin(0);
3356   }
3357
3358    // check if the upgrade reconstructor should be used instead of the standard one
3359   if(fUpgradeMask[iDet]) {
3360     if(reconstructor) delete reconstructor;
3361     TClass *cl = new TClass(Form("Ali%sUpgradeReconstructor",fgkDetectorName[iDet]));
3362     reconstructor = (AliReconstructor*)(cl->New());
3363    }
3364
3365   if (reconstructor) {
3366     TObject* obj = fOptions.FindObject(detName.Data());
3367     if (obj) reconstructor->SetOption(obj->GetTitle());
3368     reconstructor->SetRunInfo(fRunInfo);
3369     reconstructor->SetHLTESD(fhltesd);
3370     reconstructor->Init();
3371     fReconstructor[iDet] = reconstructor;
3372   }
3373
3374   // get or create the loader
3375   if (detName != "HLT") {
3376     fLoader[iDet] = fRunLoader->GetLoader(detName + "Loader");
3377     if (!fLoader[iDet]) {
3378       AliConfig::Instance()
3379         ->CreateDetectorFolders(fRunLoader->GetEventFolder(), 
3380                                 detName, detName);
3381       // first check if a plugin is defined for the loader
3382       pluginHandler = 
3383         pluginManager->FindHandler("AliLoader", detName);
3384       // if not, add a plugin for it
3385       if (!pluginHandler) {
3386         TString loaderName = "Ali" + detName + "Loader";
3387         AliDebug(1, Form("defining plugin for %s", loaderName.Data()));
3388         pluginManager->AddHandler("AliLoader", detName, 
3389                                   loaderName, detName + "base", 
3390                                   loaderName + "(const char*, TFolder*)");
3391         pluginHandler = pluginManager->FindHandler("AliLoader", detName);
3392       }
3393       if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
3394         fLoader[iDet] = 
3395           (AliLoader*) pluginHandler->ExecPlugin(2, detName.Data(), 
3396                                                  fRunLoader->GetEventFolder());
3397       }
3398       if (!fLoader[iDet]) {   // use default loader
3399         fLoader[iDet] = new AliLoader(detName, fRunLoader->GetEventFolder());
3400       }
3401       if (!fLoader[iDet]) {
3402         AliWarning(Form("couldn't get loader for %s", detName.Data()));
3403         if (fStopOnError) return NULL;
3404       } else {
3405         fRunLoader->AddLoader(fLoader[iDet]);
3406         fRunLoader->CdGAFile();
3407         if (gFile && !gFile->IsWritable()) gFile->ReOpen("UPDATE");
3408         fRunLoader->Write(0, TObject::kOverwrite);
3409       }
3410     }
3411   }
3412       
3413   if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
3414     const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
3415     if (reconstructor) {
3416       reconstructor->SetRecoParam(par);
3417       reconstructor->SetRunInfo(fRunInfo);
3418     }
3419   }
3420   return reconstructor;
3421 }
3422
3423 //_____________________________________________________________________________
3424 AliVertexer* AliReconstruction::CreateVertexer()
3425 {
3426 // create the vertexer
3427 // Please note that the caller is the owner of the
3428 // vertexer
3429
3430   AliVertexer* vertexer = NULL;
3431   AliReconstructor* itsReconstructor = GetReconstructor(0);
3432   if (itsReconstructor && ((fRunLocalReconstruction.Contains("ITS")) || 
3433                            fRunTracking.Contains("ITS") || fFillESD.Contains("ITS") )) {
3434     vertexer = itsReconstructor->CreateVertexer();
3435   }
3436   if (!vertexer) {
3437     AliWarning("couldn't create a vertexer for ITS");
3438   }
3439
3440   return vertexer;
3441 }
3442
3443 //_____________________________________________________________________________
3444 AliTrackleter* AliReconstruction::CreateMultFinder()
3445 {
3446 // create the ITS trackleter for mult. estimation
3447 // Please note that the caller is the owner of the
3448 // trackleter
3449
3450   AliTrackleter* trackleter = NULL;
3451   AliReconstructor* itsReconstructor = GetReconstructor(0);
3452   if (itsReconstructor && ((fRunLocalReconstruction.Contains("ITS")) || 
3453                            fRunTracking.Contains("ITS") || fFillESD.Contains("ITS") )) {
3454     trackleter = itsReconstructor->CreateMultFinder();
3455   }
3456   else {
3457     AliWarning("ITS is not in reconstruction, switching off RunMultFinder");
3458     fRunMultFinder = kFALSE;
3459   }
3460
3461   return trackleter;
3462 }
3463
3464 //_____________________________________________________________________________
3465 Bool_t AliReconstruction::CreateTrackers(const TString& detectors)
3466 {
3467 // create the trackers
3468         AliInfo("Creating trackers");
3469
3470   TString detStr = detectors;
3471   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3472     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3473     AliReconstructor* reconstructor = GetReconstructor(iDet);
3474     if (!reconstructor) continue;
3475     TString detName = fgkDetectorName[iDet];
3476     if (detName == "MUON") {
3477       fRunMuonTracking = kTRUE;
3478       continue;
3479     }
3480
3481     fTracker[iDet] = reconstructor->CreateTracker();
3482     if (!fTracker[iDet] && (iDet < 7)) {
3483       AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
3484       if (fStopOnError) return kFALSE;
3485     }
3486     AliSysInfo::AddStamp(Form("LTracker%s",fgkDetectorName[iDet]), iDet,0);
3487   }
3488
3489   return kTRUE;
3490 }
3491
3492 //_____________________________________________________________________________
3493 void AliReconstruction::CleanUp()
3494 {
3495 // delete trackers and the run loader and close and delete the file
3496   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3497     delete fReconstructor[iDet];
3498     fReconstructor[iDet] = NULL;
3499     fLoader[iDet] = NULL;
3500     delete fTracker[iDet];
3501     fTracker[iDet] = NULL;
3502   }
3503
3504   delete fRunInfo;
3505   fRunInfo = NULL;
3506
3507   delete fSPDTrackleter;
3508   fSPDTrackleter = NULL;
3509
3510   delete ftVertexer;
3511   ftVertexer = NULL;
3512   
3513   delete fRunLoader;
3514   fRunLoader = NULL;
3515   delete fRawReader;
3516   fRawReader = NULL;
3517   delete fParentRawReader;
3518   fParentRawReader=NULL;
3519
3520   if (ffile) {
3521     ffile->Close();
3522     delete ffile;
3523     ffile = NULL;
3524   }
3525
3526   if (AliQAManager::QAManager())
3527     AliQAManager::QAManager()->ShowQA() ; 
3528   //  AliQAManager::Destroy() ;
3529   delete fAnalysis; 
3530   fAnalysis = NULL;
3531 }
3532
3533 void AliReconstruction::WriteAlignmentData(AliESDEvent* esd)
3534 {
3535   // Write space-points which are then used in the alignment procedures
3536   // For the moment only ITS, TPC, TRD and TOF
3537
3538   Int_t ntracks = esd->GetNumberOfTracks();
3539   for (Int_t itrack = 0; itrack < ntracks; itrack++)
3540     {
3541       AliESDtrack *track = esd->GetTrack(itrack);
3542       Int_t nsp = 0;
3543       Int_t idx[200];
3544       for (Int_t i=0; i<200; ++i) idx[i] = -1; //PH avoid uninitialized values
3545       for (Int_t iDet = 5; iDet >= 0; iDet--) {// TOF, TRD, TPC, ITS clusters
3546           nsp += (iDet==GetDetIndex("TRD")) ? track->GetTRDntracklets():track->GetNcls(iDet);
3547
3548           if (iDet==GetDetIndex("ITS")) { // ITS "extra" clusters
3549              track->GetClusters(iDet,idx);
3550              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nsp++;
3551           }  
3552       }
3553
3554       if (nsp) {
3555         AliTrackPointArray *sp = new AliTrackPointArray(nsp);
3556         track->SetTrackPointArray(sp);
3557         Int_t isptrack = 0;
3558         for (Int_t iDet = 5; iDet >= 0; iDet--) {
3559           AliTracker *tracker = fTracker[iDet];
3560           if (!tracker) continue;
3561           Int_t nspdet = (iDet==GetDetIndex("TRD")) ? track->GetTRDtracklets(idx):track->GetClusters(iDet,idx);
3562
3563           if (iDet==GetDetIndex("ITS")) // ITS "extra" clusters             
3564              for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nspdet++;
3565
3566           if (nspdet <= 0) continue;
3567           AliTrackPoint p;
3568           Int_t isp = 0;
3569           Int_t isp2 = 0;
3570           while (isp2 < nspdet) {
3571             Bool_t isvalid=kTRUE;
3572
3573             Int_t index=idx[isp++];
3574             if (index < 0) continue;
3575
3576             TString dets = fgkDetectorName[iDet];
3577             if ((fUseTrackingErrorsForAlignment.CompareTo(dets) == 0) ||
3578             fUseTrackingErrorsForAlignment.BeginsWith(dets+" ") ||
3579             fUseTrackingErrorsForAlignment.EndsWith(" "+dets) ||
3580             fUseTrackingErrorsForAlignment.Contains(" "+dets+" ")) {
3581               isvalid = tracker->GetTrackPointTrackingError(index,p,track);
3582             } else {
3583               isvalid = tracker->GetTrackPoint(index,p); 
3584             } 
3585             isp2++;
3586             if (!isvalid) continue;
3587             if (iDet==GetDetIndex("ITS") && (isp-1)>=6) p.SetExtra();
3588             sp->AddPoint(isptrack,&p); isptrack++;
3589           }
3590         }       
3591       }
3592     }
3593 }
3594
3595 //_____________________________________________________________________________
3596 void AliReconstruction::FillRawDataErrorLog(Int_t iEvent, AliESDEvent* esd)
3597 {
3598   // The method reads the raw-data error log
3599   // accumulated within the rawReader.
3600   // It extracts the raw-data errors related to
3601   // the current event and stores them into
3602   // a TClonesArray inside the esd object.
3603
3604   if (!fRawReader) return;
3605
3606   for(Int_t i = 0; i < fRawReader->GetNumberOfErrorLogs(); i++) {
3607
3608     AliRawDataErrorLog *log = fRawReader->GetErrorLog(i);
3609     if (!log) continue;
3610     if (iEvent != log->GetEventNumber()) continue;
3611
3612     esd->AddRawDataErrorLog(log);
3613   }
3614
3615 }
3616
3617 //_____________________________________________________________________________
3618 // void AliReconstruction::CheckQA()
3619 // {
3620 // check the QA of SIM for this run and remove the detectors 
3621 // with status Fatal
3622   
3623 //      TString newRunLocalReconstruction ; 
3624 //      TString newRunTracking ;
3625 //      TString newFillESD ;
3626 //       
3627 //      for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
3628 //              TString detName(AliQAv1::GetDetName(iDet)) ;
3629 //              AliQAv1 * qa = AliQAv1::Instance(AliQAv1::DETECTORINDEX_t(iDet)) ;       
3630 //      if ( qa->IsSet(AliQAv1::DETECTORINDEX_t(iDet), AliQAv1::kSIM, specie, AliQAv1::kFATAL)) {
3631 //        AliInfo(Form("QA status for %s %s in Hits and/or SDIGITS  and/or Digits was Fatal; No reconstruction performed", 
3632 //                   detName.Data(), AliRecoParam::GetEventSpecieName(es))) ;
3633 //                      } else {
3634 //                      if ( fRunLocalReconstruction.Contains(AliQAv1::GetDetName(iDet)) || 
3635 //                                      fRunLocalReconstruction.Contains("ALL") )  {
3636 //                              newRunLocalReconstruction += detName ; 
3637 //                              newRunLocalReconstruction += " " ;                      
3638 //                      }
3639 //                      if ( fRunTracking.Contains(AliQAv1::GetDetName(iDet)) || 
3640 //                                      fRunTracking.Contains("ALL") )  {
3641 //                              newRunTracking += detName ; 
3642 //                              newRunTracking += " " ;                         
3643 //                      }
3644 //                      if ( fFillESD.Contains(AliQAv1::GetDetName(iDet)) || 
3645 //                                      fFillESD.Contains("ALL") )  {
3646 //                              newFillESD += detName ; 
3647 //                              newFillESD += " " ;                     
3648 //                      }
3649 //              }
3650 //      }
3651 //      fRunLocalReconstruction = newRunLocalReconstruction ; 
3652 //      fRunTracking            = newRunTracking ; 
3653 //      fFillESD                = newFillESD ; 
3654 // }
3655
3656 //_____________________________________________________________________________
3657 Int_t AliReconstruction::GetDetIndex(const char* detector)
3658 {
3659   // return the detector index corresponding to detector
3660   Int_t index = -1 ; 
3661   for (index = 0; index < kNDetectors ; index++) {
3662     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
3663         break ; 
3664   }     
3665   return index ; 
3666 }
3667 //_____________________________________________________________________________
3668 Bool_t AliReconstruction::FinishPlaneEff() {
3669  //
3670  // Here execute all the necessary operationis, at the end of the tracking phase,
3671  // in case that evaluation of PlaneEfficiencies was required for some detector.
3672  // E.g., write into a DataBase file the PlaneEfficiency which have been evaluated.
3673  //
3674  // This Preliminary version works only FOR ITS !!!!!
3675  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3676  //
3677  //  Input: none
3678  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3679  //
3680  Bool_t ret=kFALSE;
3681  TString detStr = fLoadCDB;
3682  //for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
3683  for (Int_t iDet = 0; iDet < 1; iDet++) { // for the time being only ITS
3684    if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3685    if(fTracker[iDet] && fTracker[iDet]->GetPlaneEff()) {
3686       AliPlaneEff *planeeff=fTracker[iDet]->GetPlaneEff();
3687       TString name=planeeff->GetName();
3688       name+=".root";
3689       TFile* pefile = TFile::Open(name, "RECREATE");
3690       ret=(Bool_t)planeeff->Write();
3691       pefile->Close();
3692       if(planeeff->GetCreateHistos()) {
3693         TString hname=planeeff->GetName();
3694         hname+="Histo.root";
3695         ret*=planeeff->WriteHistosToFile(hname,"RECREATE");
3696       }
3697    }
3698    if(fSPDTrackleter) {
3699      AliPlaneEff *planeeff=fSPDTrackleter->GetPlaneEff();
3700       TString name="AliITSPlaneEffSPDtracklet.root";
3701       TFile* pefile = TFile::Open(name, "RECREATE");
3702       ret=(Bool_t)planeeff->Write();
3703       pefile->Close();
3704       AliESDEvent *dummy=NULL;
3705       ret=(Bool_t)fSPDTrackleter->PostProcess(dummy); // take care of writing other files
3706    }
3707  }
3708  return ret;
3709 }
3710 //_____________________________________________________________________________
3711 Bool_t AliReconstruction::InitPlaneEff() {
3712 //
3713  // Here execute all the necessary operations, before of the tracking phase,
3714  // for the evaluation of PlaneEfficiencies, in case required for some detectors.
3715  // E.g., read from a DataBase file a first evaluation of the PlaneEfficiency
3716  // which should be updated/recalculated.
3717  //
3718  // This Preliminary version will work only FOR ITS !!!!!
3719  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3720  //
3721  //  Input: none
3722  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3723  //
3724
3725   fSPDTrackleter = NULL;
3726   TString detStr = fLoadCDB;
3727   if (IsSelected(fgkDetectorName[0], detStr)) {
3728     AliReconstructor* itsReconstructor = GetReconstructor(0);
3729     if (itsReconstructor) {
3730       fSPDTrackleter = itsReconstructor->CreateTrackleter(); // this is NULL unless required in RecoParam
3731     }
3732     if (fSPDTrackleter) {
3733       AliInfo("Trackleter for SPD has been created");
3734     }
3735   }
3736  return kTRUE;
3737 }
3738
3739 //_____________________________________________________________________________
3740 Bool_t AliReconstruction::InitAliEVE()
3741 {
3742   // This method should be called only in case 
3743   // AliReconstruction is run
3744   // within the alieve environment.
3745   // It will initialize AliEVE in a way
3746   // so that it can visualize event processed
3747   // by AliReconstruction.
3748   // The return flag shows whenever the
3749   // AliEVE initialization was successful or not.
3750
3751   TString macroStr(getenv("ALIEVE_ONLINE_MACRO"));
3752
3753   if (macroStr.IsNull())
3754     macroStr.Form("%s/EVE/macros/alieve_online.C",gSystem->ExpandPathName("$ALICE_ROOT"));
3755
3756   AliInfo(Form("Loading AliEVE macro: %s",macroStr.Data()));
3757
3758   if (gROOT->LoadMacro(macroStr.Data()) != 0) return kFALSE;
3759
3760   gROOT->ProcessLine("if (!AliEveEventManager::GetMaster()){new AliEveEventManager();AliEveEventManager::GetMaster()->AddNewEventCommand(\"alieve_online_on_new_event()\");gEve->AddEvent(AliEveEventManager::GetMaster());};");
3761   gROOT->ProcessLine("alieve_online_init()");
3762
3763   return kTRUE;
3764 }
3765   
3766 //_____________________________________________________________________________
3767 void AliReconstruction::RunAliEVE()
3768 {
3769   // Runs AliEVE visualisation of
3770   // the current event.
3771   // Should be executed only after
3772   // successful initialization of AliEVE.
3773
3774   AliInfo("Running AliEVE...");
3775   gROOT->ProcessLine(Form("AliEveEventManager::GetMaster()->SetEvent((AliRunLoader*)%p,(AliRawReader*)%p,(AliESDEvent*)%p,(AliESDfriend*)%p);",fRunLoader,fRawReader,fesd,fesdf));
3776   gSystem->Run();
3777 }
3778
3779 //_____________________________________________________________________________
3780 Bool_t AliReconstruction::SetRunQA(TString detAndAction) 
3781 {
3782         // Allows to run QA for a selected set of detectors
3783         // and a selected set of tasks among RAWS, DIGITSR, RECPOINTS and ESDS
3784         // all selected detectors run the same selected tasks
3785         
3786         if (!detAndAction.Contains(":")) {
3787                 AliError( Form("%s is a wrong syntax, use \"DetectorList:ActionList\" \n", detAndAction.Data()) ) ;
3788                 fRunQA = kFALSE ;
3789                 return kFALSE ;                 
3790         }
3791         Int_t colon = detAndAction.Index(":") ; 
3792         fQADetectors = detAndAction(0, colon) ; 
3793         fQATasks   = detAndAction(colon+1, detAndAction.Sizeof() ) ; 
3794         if (fQATasks.Contains("ALL") ) {
3795                 fQATasks = Form("%d %d %d %d", AliQAv1::kRAWS, AliQAv1::kDIGITSR, AliQAv1::kRECPOINTS, AliQAv1::kESDS) ; 
3796         } else {
3797                 fQATasks.ToUpper() ; 
3798                 TString tempo("") ; 
3799                 if ( fQATasks.Contains("RAW") ) 
3800                         tempo = Form("%d ", AliQAv1::kRAWS) ; 
3801                 if ( fQATasks.Contains("DIGIT") ) 
3802                         tempo += Form("%d ", AliQAv1::kDIGITSR) ; 
3803                 if ( fQATasks.Contains("RECPOINT") ) 
3804                         tempo += Form("%d ", AliQAv1::kRECPOINTS) ; 
3805                 if ( fQATasks.Contains("ESD") ) 
3806                         tempo += Form("%d ", AliQAv1::kESDS) ; 
3807                 fQATasks = tempo ; 
3808                 if (fQATasks.IsNull()) {
3809                         AliInfo("No QA requested\n")  ;
3810                         fRunQA = kFALSE ;
3811                         return kTRUE ; 
3812                 }
3813         }       
3814         TString tempo(fQATasks) ; 
3815         tempo.ReplaceAll(Form("%d", AliQAv1::kRAWS), AliQAv1::GetTaskName(AliQAv1::kRAWS))      ;
3816         tempo.ReplaceAll(Form("%d", AliQAv1::kDIGITSR), AliQAv1::GetTaskName(AliQAv1::kDIGITSR)) ;      
3817         tempo.ReplaceAll(Form("%d", AliQAv1::kRECPOINTS), AliQAv1::GetTaskName(AliQAv1::kRECPOINTS)) ;  
3818         tempo.ReplaceAll(Form("%d", AliQAv1::kESDS), AliQAv1::GetTaskName(AliQAv1::kESDS)) ;    
3819         AliInfo( Form("QA will be done on \"%s\" for \"%s\"\n", fQADetectors.Data(), tempo.Data()) ) ;  
3820         fRunQA = kTRUE ;
3821         return kTRUE; 
3822
3823
3824 //_____________________________________________________________________________
3825 Bool_t AliReconstruction::InitRecoParams() 
3826 {
3827   // The method accesses OCDB and retrieves all
3828   // the available reco-param objects from there.
3829
3830   Bool_t isOK = kTRUE;
3831
3832   if (fRecoParam.GetDetRecoParamArray(kNDetectors)) {
3833     AliInfo("Using custom GRP reconstruction parameters");
3834   }
3835   else {
3836     AliInfo("Loading GRP reconstruction parameter objects");
3837
3838     AliCDBPath path("GRP","Calib","RecoParam");
3839     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
3840     if(!entry){ 
3841       AliWarning("Couldn't find GRP RecoParam entry in OCDB");
3842       isOK = kFALSE;
3843     }
3844     else {
3845       TObject *recoParamObj = entry->GetObject();
3846       if (dynamic_cast<TObjArray*>(recoParamObj)) {
3847         // GRP has a normal TobjArray of AliDetectorRecoParam objects
3848         // Registering them in AliRecoParam
3849         fRecoParam.AddDetRecoParamArray(kNDetectors,dynamic_cast<TObjArray*>(recoParamObj));
3850       }
3851       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
3852         // GRP has only onse set of reco parameters
3853         // Registering it in AliRecoParam
3854         AliInfo("Single set of GRP reconstruction parameters found");
3855         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
3856         fRecoParam.AddDetRecoParam(kNDetectors,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
3857       }
3858       else {
3859         AliError("No valid GRP RecoParam object found in the OCDB");
3860         isOK = kFALSE;
3861       }
3862       entry->SetOwner(0);
3863     }
3864   }
3865
3866   TString detStr = fLoadCDB;
3867   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
3868
3869     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3870
3871     if (fRecoParam.GetDetRecoParamArray(iDet)) {
3872       AliInfo(Form("Using custom reconstruction parameters for detector %s",fgkDetectorName[iDet]));
3873       continue;
3874     }
3875
3876     AliInfo(Form("Loading reconstruction parameter objects for detector %s",fgkDetectorName[iDet]));
3877   
3878     AliCDBPath path(fgkDetectorName[iDet],"Calib","RecoParam");
3879     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
3880     if(!entry){ 
3881       AliWarning(Form("Couldn't find RecoParam entry in OCDB for detector %s",fgkDetectorName[iDet]));
3882       isOK = kFALSE;
3883     }
3884     else {
3885       TObject *recoParamObj = entry->GetObject();
3886       if (dynamic_cast<TObjArray*>(recoParamObj)) {
3887         // The detector has a normal TobjArray of AliDetectorRecoParam objects
3888         // Registering them in AliRecoParam
3889         fRecoParam.AddDetRecoParamArray(iDet,dynamic_cast<TObjArray*>(recoParamObj));
3890       }
3891       else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
3892         // The detector has only onse set of reco parameters
3893         // Registering it in AliRecoParam
3894         AliInfo(Form("Single set of reconstruction parameters found for detector %s",fgkDetectorName[iDet]));
3895         dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
3896         fRecoParam.AddDetRecoParam(iDet,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
3897       }
3898       else {
3899         AliError(Form("No valid RecoParam object found in the OCDB for detector %s",fgkDetectorName[iDet]));
3900         isOK = kFALSE;
3901       }
3902       entry->SetOwner(0);
3903       //      FIX ME: We have to disable the unloading of reco-param CDB
3904       //      entries because QA framework is using them. Has to be fix in
3905       //      a way that the QA takes the objects already constructed in
3906       //      this method.
3907       //      AliCDBManager::Instance()->UnloadFromCache(path.GetPath());
3908     }
3909   }
3910
3911   if (AliDebugLevel() > 0) fRecoParam.Print();
3912
3913   return isOK;
3914 }
3915
3916 //_____________________________________________________________________________
3917 Bool_t AliReconstruction::GetEventInfo() 
3918 {
3919   // Fill the event info object
3920   // ...
3921   AliCodeTimerAuto("",0)
3922
3923   AliCentralTrigger *aCTP = NULL;
3924   if (fRawReader) {
3925     fEventInfo.SetEventType(fRawReader->GetType());
3926
3927     ULong64_t mask = fRawReader->GetClassMask();
3928     fEventInfo.SetTriggerMask(mask);
3929     UInt_t clmask = fRawReader->GetDetectorPattern()[0];
3930     fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(clmask));
3931
3932     aCTP = new AliCentralTrigger();
3933     TString configstr("");
3934     if (!aCTP->LoadConfiguration(configstr)) { // Load CTP config from OCDB
3935       AliError("No trigger configuration found in OCDB! The trigger configuration information will not be used!");
3936       delete aCTP;
3937       return kFALSE;
3938     }
3939     aCTP->SetClassMask(mask);
3940     aCTP->SetClusterMask(clmask);
3941
3942     if (fRunLoader) {
3943       AliCentralTrigger* rlCTP = fRunLoader->GetTrigger();
3944       if (rlCTP) {
3945         rlCTP->SetClassMask(mask);
3946         rlCTP->SetClusterMask(clmask);
3947       }
3948     }
3949   }
3950   else {
3951     fEventInfo.SetEventType(AliRawEventHeaderBase::kPhysicsEvent);
3952
3953     if (fRunLoader && (!fRunLoader->LoadTrigger())) {
3954       aCTP = fRunLoader->GetTrigger();
3955       fEventInfo.SetTriggerMask(aCTP->GetClassMask());
3956       // get inputs from actp - just get
3957       AliESDHeader* esdheader = fesd->GetHeader();
3958       esdheader->SetL0TriggerInputs(aCTP->GetL0TriggerInputs());
3959       esdheader->SetL1TriggerInputs(aCTP->GetL1TriggerInputs());
3960       esdheader->SetL2TriggerInputs(aCTP->GetL2TriggerInputs());
3961       fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(aCTP->GetClusterMask()));
3962     }
3963     else {
3964       if (fStopOnMissingTriggerFile) AliFatal("No trigger can be loaded! Stopping reconstruction!");
3965       AliWarning("No trigger can be loaded! The trigger information will not be used!");
3966       return kFALSE;
3967     }
3968   }
3969
3970   AliTriggerConfiguration *config = aCTP->GetConfiguration();
3971   if (!config) {
3972     AliError("No trigger configuration has been found! The trigger configuration information will not be used!");
3973     if (fRawReader) delete aCTP;
3974     return kFALSE;
3975   }
3976
3977   // Load trigger aliases and declare the trigger classes included in aliases
3978   //PH Why do we do it in each event and not only once in the beginning of the chunk??
3979   //PH Temporary fix for #99725: AliReconstruction::GetEventInfo bug
3980   fDeclTriggerClasses.Clear();
3981   AliCDBEntry * entry = AliCDBManager::Instance()->Get("GRP/CTP/Aliases");
3982   if (entry) {
3983     THashList * lst = dynamic_cast<THashList*>(entry->GetObject());
3984     if (lst) {
3985       lst->Sort(kSortDescending); // to avoid problems with substrungs
3986       if (fRawReader) fRawReader->LoadTriggerAlias(lst);
3987       // Now declare all the triggers present in the aliases
3988       TIter iter(lst);
3989       TNamed *nmd = 0;
3990       while((nmd = dynamic_cast<TNamed*>(iter.Next()))){
3991         fDeclTriggerClasses += " ";
3992         fDeclTriggerClasses += nmd->GetName();
3993       }
3994     }
3995     else {
3996       AliError("Cannot cast the object with trigger aliases to THashList!");
3997     }
3998   }
3999   else {
4000     AliError("No OCDB ebtry for the trigger aliases!");
4001   }
4002   // Load trigger classes for this run
4003   UChar_t clustmask = 0;
4004   TString trclasses;
4005   ULong64_t trmask = fEventInfo.GetTriggerMask();
4006   const TObjArray& classesArray = config->GetClasses();
4007   Int_t nclasses = classesArray.GetEntriesFast();
4008   for( Int_t iclass=0; iclass < nclasses; iclass++ ) {
4009     AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At(iclass);
4010     if (trclass && trclass->GetMask()>0) {
4011       Int_t trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
4012       if (fesd) fesd->SetTriggerClass(trclass->GetName(),trindex);
4013       if (fRawReader) fRawReader->LoadTriggerClass(trclass->GetName(),trindex);
4014       if (trmask & (1ull << trindex)) {
4015         trclasses += " ";
4016         trclasses += trclass->GetName();
4017         trclasses += " ";
4018         clustmask |= trclass->GetCluster()->GetClusterMask();
4019       }
4020     }
4021   }
4022   fEventInfo.SetTriggerClasses(trclasses);
4023   // Now put the declared trigger classes (not present in the run)
4024   // to 0/false in the event selection
4025   if (!fDeclTriggerClasses.IsNull()) {
4026     TObjArray *tokens = fDeclTriggerClasses.Tokenize(" ");
4027     Int_t ntokens = tokens->GetEntriesFast();
4028     for (Int_t itoken = 0; itoken < ntokens; ++itoken) {
4029       if (fRawReader) fRawReader->LoadTriggerClass((((TObjString*)tokens->At(itoken))->String()).Data(),-1);
4030     }
4031     delete tokens;
4032   }
4033
4034   // Write names of active trigger inputs in ESD Header
4035   const TObjArray& inputsArray = config->GetInputs(); 
4036   Int_t ninputs = inputsArray.GetEntriesFast();
4037   for( Int_t iinput=0; iinput < ninputs; iinput++ ) {
4038     AliTriggerInput* trginput = (AliTriggerInput*)inputsArray.At(iinput);
4039     if (trginput && trginput->GetMask()>0) {
4040       Int_t inputIndex = (Int_t)TMath::Nint(TMath::Log2(trginput->GetMask()));
4041       AliESDHeader* headeresd = 0x0;
4042       if (fesd) headeresd = fesd->GetHeader();
4043       if (headeresd) {
4044         Int_t trglevel = (Int_t)trginput->GetLevel();
4045         if (trglevel == 0) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex);
4046         if (trglevel == 1) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex+24);
4047         if (trglevel == 2) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex+48);
4048       }
4049     }
4050   }
4051
4052   // Set the information in ESD
4053   if (fesd) {
4054     fesd->SetTriggerMask(trmask);
4055     fesd->SetTriggerCluster(clustmask);
4056   }
4057
4058   if (!aCTP->CheckTriggeredDetectors()) {
4059     if (fRawReader) delete aCTP;
4060     return kFALSE;
4061   }    
4062
4063   if (fRawReader) delete aCTP;
4064
4065   // We have to fill also the HLT decision here!!
4066   // ...
4067
4068   return kTRUE;
4069 }
4070
4071 const char *AliReconstruction::MatchDetectorList(const char *detectorList, UInt_t detectorMask)
4072 {
4073   // Match the detector list found in the rec.C or the default 'ALL'
4074   // to the list found in the GRP (stored there by the shuttle PP which
4075   // gets the information from ECS)
4076   static TString resultList;
4077   TString detList = detectorList;
4078
4079   resultList = "";
4080
4081   for(Int_t iDet = 0; iDet < (AliDAQ::kNDetectors-1); iDet++) {
4082     if ((detectorMask >> iDet) & 0x1) {
4083       TString det = AliDAQ::OfflineModuleName(iDet);
4084       if ((detList.CompareTo("ALL") == 0) ||
4085           ((detList.BeginsWith("ALL ") ||
4086             detList.EndsWith(" ALL") ||
4087             detList.Contains(" ALL ")) &&
4088            !(detList.BeginsWith("-"+det+" ") ||
4089              detList.EndsWith(" -"+det) ||
4090              detList.Contains(" -"+det+" "))) ||
4091           (detList.CompareTo(det) == 0) ||
4092           detList.BeginsWith(det+" ") ||
4093           detList.EndsWith(" "+det) ||
4094           detList.Contains( " "+det+" " )) {
4095         if (!resultList.EndsWith(det + " ")) {
4096           resultList += det;
4097           resultList += " ";
4098         }
4099       }        
4100     }
4101   }
4102
4103   // HLT
4104   if ((detectorMask >> AliDAQ::kHLTId) & 0x1) {
4105     TString hltDet = AliDAQ::OfflineModuleName(AliDAQ::kNDetectors-1);
4106     if ((detList.CompareTo("ALL") == 0) ||
4107         ((detList.BeginsWith("ALL ") ||
4108           detList.EndsWith(" ALL") ||
4109           detList.Contains(" ALL ")) &&
4110          !(detList.BeginsWith("-"+hltDet+" ") ||
4111            detList.EndsWith(" -"+hltDet) ||
4112            detList.Contains(" -"+hltDet+" "))) ||
4113         (detList.CompareTo(hltDet) == 0) ||
4114         detList.BeginsWith(hltDet+" ") ||
4115         detList.EndsWith(" "+hltDet) ||
4116         detList.Contains( " "+hltDet+" " )) {
4117       resultList += hltDet;
4118     }
4119   }
4120
4121   return resultList.Data();
4122
4123 }
4124
4125 //______________________________________________________________________________
4126 void AliReconstruction::Abort(const char *method, EAbort what)
4127 {
4128   // Abort processing. If what = kAbortProcess, the Process() loop will be
4129   // aborted. If what = kAbortFile, the current file in a chain will be
4130   // aborted and the processing will continue with the next file, if there
4131   // is no next file then Process() will be aborted. Abort() can also  be
4132   // called from Begin(), SlaveBegin(), Init() and Notify(). After abort
4133   // the SlaveTerminate() and Terminate() are always called. The abort flag
4134   // can be checked in these methods using GetAbort().
4135   //
4136   // The method is overwritten in AliReconstruction for better handling of
4137   // reco specific errors 
4138
4139   if (!fStopOnError) return;
4140
4141   CleanUp();
4142
4143   TString whyMess = method;
4144   whyMess += " failed! Aborting...";
4145
4146   AliError(whyMess.Data());
4147
4148   fAbort = what;
4149   TString mess = "Abort";
4150   if (fAbort == kAbortProcess)
4151     mess = "AbortProcess";
4152   else if (fAbort == kAbortFile)
4153     mess = "AbortFile";
4154
4155   Info(mess.Data(), "%s", whyMess.Data());
4156 }
4157
4158 //______________________________________________________________________________
4159 Bool_t AliReconstruction::ProcessEvent(void* event)
4160 {
4161   // Method that is used in case the event loop
4162   // is steered from outside, for example by AMORE
4163   // 'event' is a pointer to the DATE event in the memory
4164
4165   if (fRawReader) delete fRawReader;
4166   fRawReader = new AliRawReaderDate(event);
4167   fStatus = ProcessEvent(fRunLoader->GetNumberOfEvents());  
4168   delete fRawReader;
4169   fRawReader = NULL;
4170
4171   return fStatus;
4172 }
4173
4174 //______________________________________________________________________________
4175 Bool_t AliReconstruction::ParseOutput()
4176 {
4177   // The method parses the output file
4178   // location string in order to steer
4179   // properly the selector
4180
4181   TPMERegexp re1("(\\w+\\.zip#\\w+\\.root):([,*\\w+\\.root,*]+)@dataset://(\\w++)");
4182   TPMERegexp re2("(\\w+\\.root)?@?dataset://(\\w++)");
4183
4184   if (re1.Match(fESDOutput) == 4) {
4185     // root archive with output files stored and regustered
4186     // in proof dataset
4187     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",re1[1].Data()));
4188     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",re1[3].Data()));
4189     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_DATASET",""));
4190     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_ARCHIVE",re1[2].Data()));
4191     AliInfo(Form("%s files will be stored within %s in dataset %s",
4192                  re1[2].Data(),
4193                  re1[1].Data(),
4194                  re1[3].Data()));
4195   }
4196   else if (re2.Match(fESDOutput) == 3) {
4197     // output file stored and registered
4198     // in proof dataset
4199     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",(re2[1].IsNull()) ? "AliESDs.root" : re2[1].Data()));
4200     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",re2[2].Data()));
4201     gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_DATASET",""));
4202     AliInfo(Form("%s will be stored in dataset %s",
4203                  (re2[1].IsNull()) ? "AliESDs.root" : re2[1].Data(),
4204                  re2[2].Data()));
4205   }
4206   else {
4207     if (fESDOutput.IsNull()) {
4208       // Output location not given.
4209       // Assuming xrootd has been already started and
4210       // the output file has to be sent back
4211       // to the client machine
4212       TString esdUrl(Form("root://%s/%s/",
4213                           TUrl(gSystem->HostName()).GetHostFQDN(),
4214                           gSystem->pwd()));
4215       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE","AliESDs.root"));
4216       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",esdUrl.Data()));
4217       AliInfo(Form("AliESDs.root will be stored in %s",
4218                    esdUrl.Data()));
4219     }
4220     else {
4221       // User specified an output location.
4222       // Ones has just to parse it here
4223       TUrl outputUrl(fESDOutput.Data());
4224       TString outputFile(gSystem->BaseName(outputUrl.GetFile()));
4225       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",outputFile.IsNull() ? "AliESDs.root" : outputFile.Data()));
4226       TString outputLocation(outputUrl.GetUrl());
4227       outputLocation.ReplaceAll(outputFile.Data(),"");
4228       gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",outputLocation.Data()));
4229       AliInfo(Form("%s will be stored in %s",
4230                    outputFile.IsNull() ? "AliESDs.root" : outputFile.Data(),
4231                    outputLocation.Data()));
4232     }
4233   }
4234
4235   return kTRUE;
4236 }
4237
4238 //______________________________________________________________________________
4239 Bool_t AliReconstruction::IsHighPt() const {
4240   // Selection of events containing "high" pT tracks
4241   // If at least one track is found within 1.5 and 100 GeV (pT)
4242   // that was reconstructed by both ITS and TPC, the event is accepted
4243
4244   // Track cuts
4245   const Double_t pTmin = 1.5;
4246   const Double_t pTmax = 100;
4247   ULong_t mask = 0;
4248   mask |= (AliESDtrack::kITSrefit);
4249   mask |= (AliESDtrack::kTPCrefit);
4250   const Double_t pTminCosmic = 5.;
4251   const Double_t pTmaxCosmic = 100;
4252   ULong_t maskCosmic = 0;
4253   Int_t cosmicCount=0;
4254   maskCosmic |= (AliESDtrack::kTPCrefit);
4255
4256   Bool_t isOK = kFALSE;
4257
4258   if (fesd && fesd->GetEventType()==AliRawEventHeaderBase::kPhysicsEvent) {
4259     // Check if this ia a physics event (code 7)
4260     Int_t ntrk = fesd->GetNumberOfTracks();
4261     for (Int_t itrk=0; itrk<ntrk; ++itrk) {
4262           
4263       AliESDtrack * trk = fesd->GetTrack(itrk);
4264       if (trk 
4265           && trk->Pt() > pTmin 
4266           && trk->Pt() < pTmax
4267           && (trk->GetStatus() & mask) == mask ) {
4268         
4269         isOK = kTRUE;
4270         break;
4271       }
4272       if (trk 
4273           && trk->GetInnerParam()
4274           && trk->GetInnerParam()->Pt() > pTminCosmic 
4275           && trk->GetInnerParam()->Pt() < pTmaxCosmic
4276           && (trk->GetStatus() & maskCosmic) == maskCosmic ) {
4277         
4278         cosmicCount++;
4279         break;
4280       }
4281     }
4282     if (cosmicCount>1) isOK=kTRUE;
4283   }
4284   return isOK;
4285 }
4286
4287 //______________________________________________________________________________
4288 Bool_t AliReconstruction::IsCosmicOrCalibSpecie() const {
4289   // Select cosmic or calibration events
4290
4291   Bool_t isOK = kFALSE;
4292
4293   if (fesd && fesd->GetEventType()==AliRawEventHeaderBase::kPhysicsEvent) {
4294       // Check if this ia a physics event (code 7)
4295       
4296       UInt_t specie = fesd->GetEventSpecie();
4297       if (specie==AliRecoParam::kCosmic || specie==AliRecoParam::kCalib) {
4298         isOK = kTRUE;
4299       }
4300   }
4301   return isOK;
4302 }
4303
4304 //______________________________________________________________________________
4305 void AliReconstruction::WriteESDfriend() {
4306   // Fill the ESD friend in the tree. The required fraction of ESD friends is stored
4307   // in fFractionFriends. We select events where we store the ESD friends according
4308   // to the following algorithm:
4309   // 1. Store all Cosmic or Calibration events within the required fraction
4310   // 2. Sample "high Pt" events within the remaining fraction after step 1.
4311   // 3. Sample randomly events if we still have remaining slot
4312
4313   fNall++;
4314   Bool_t isSelected = kFALSE;
4315   //
4316   // Store all friends for B field OFF 
4317   if (TMath::Abs(AliTrackerBase::GetBz())<0.5) isSelected=kTRUE;
4318
4319   if (IsCosmicOrCalibSpecie()) { // Selection of calib or cosmic events
4320     fNspecie++;
4321
4322     isSelected = kTRUE;
4323     fSspecie++;
4324   }
4325   
4326   Double_t remainingFraction = fFractionFriends;
4327   remainingFraction -= ((Double_t)(fSspecie)/(Double_t)(fNall));
4328   
4329   if (IsHighPt())  { // Selection of "high Pt" events
4330     fNhighPt++;
4331     Double_t curentHighPtFraction = ((Double_t)(fNhighPt+1))/((Double_t)(fNall+1));
4332     // "Bayesian" estimate supposing that without events all the events are of the required type
4333     
4334     if (!isSelected) {
4335       Double_t rnd = gRandom->Rndm()*curentHighPtFraction;
4336       if (rnd<remainingFraction) {
4337         isSelected = kTRUE;
4338         fShighPt++;
4339       }
4340     }
4341   }
4342   remainingFraction -= ((Double_t)(fShighPt)/(Double_t)(fNall));
4343   
4344   // Random selection to fill the remaining fraction (if any)
4345   if (!isSelected) {
4346     Double_t rnd = gRandom->Rndm();
4347     if (rnd<remainingFraction) {        
4348       isSelected = kTRUE;
4349     }
4350   }
4351   
4352   if (!isSelected) {
4353     fesdf->~AliESDfriend();
4354     new (fesdf) AliESDfriend(); // Reset...
4355     fesdf->SetSkipBit(kTRUE);
4356   }
4357   //
4358   ftreeF->Fill();
4359 }
4360
4361 //_________________________________________________________________
4362 void AliReconstruction::DeleteDigits(const TString& detectors)
4363 {
4364   // delete requested digit files produced at current event
4365   static int iEvent = 0;
4366   if (detectors.IsNull()) return;
4367   TString detStr = detectors;
4368   AliInfo(Form("Deleting Digits: %s",detectors.Data()));
4369
4370   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
4371     if(!IsSelected(fgkDetectorName[iDet], detStr)) continue;
4372     unlink(Form("%s.Digits.root",fgkDetectorName[iDet]));
4373   }
4374   AliSysInfo::AddStamp(Form("DelDigits_%d",iEvent), 0,0,iEvent);
4375   iEvent++;
4376 }
4377
4378 //_________________________________________________________________
4379 void AliReconstruction::DeleteRecPoints(const TString& detectors)
4380 {
4381   // delete requested recpoint files produced at current event
4382   static int iEvent = 0;
4383   if (detectors.IsNull()) return;
4384   TString detStr = detectors;
4385   AliInfo(Form("Deleting Recpoints: %s",detectors.Data()));
4386   //
4387   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
4388     if(!IsSelected(fgkDetectorName[iDet], detStr)) continue;
4389     unlink(Form("%s.RecPoints.root",fgkDetectorName[iDet]));
4390   }
4391   AliSysInfo::AddStamp(Form("DelRecPoints_%d",iEvent), 0,0,iEvent);
4392   iEvent++;
4393 }
4394
4395 //_________________________________________________________________
4396 void AliReconstruction::SetStopOnResourcesExcess(Int_t vRSS,Int_t vVMEM)
4397 {
4398   // require checking the resources left and stopping on excess
4399   // if 0  : no check is done
4400   // if >0 : stop reconstruction if exceeds this value
4401   // if <0 : use as margin to system limits
4402   //
4403   const int kKB2MB = 1024;
4404   const int kInfMem = 9999999;
4405   //
4406   struct rlimit r;
4407   int pgSize = getpagesize();
4408   //
4409   if (vRSS>0) {
4410     fMaxRSS = vRSS;
4411     AliInfo(Form("Setting max. RSS usage to user value %d MB",fMaxRSS));
4412   }
4413   else if (vRSS<0) {
4414     getrlimit(RLIMIT_RSS,&r);
4415     fMaxRSS = r.rlim_max==RLIM_INFINITY ? kInfMem : int(r.rlim_max*pgSize/kKB2MB/kKB2MB) + vRSS;
4416     AliInfo(Form("Setting max. RSS usage to system hard limit %d%s MB (%d margin)",fMaxRSS,r.rlim_max==RLIM_INFINITY ? "(inf)":"",-vRSS));
4417   }
4418   else {AliInfo("No check on RSS memory usage will be applied");}
4419   //
4420   if (vVMEM>0) {
4421     fMaxVMEM = vVMEM;
4422     AliInfo(Form("Setting max. VMEM usage to user value %d MB",fMaxVMEM));
4423   }
4424   else if (vVMEM<0) {
4425     getrlimit(RLIMIT_AS,&r);
4426     fMaxVMEM = r.rlim_max==RLIM_INFINITY ? kInfMem : int(r.rlim_max*pgSize/kKB2MB/kKB2MB) + vVMEM;
4427     AliInfo(Form("Setting max. VMEM usage to system hard limit %d%s MB (%d margin)",fMaxVMEM,r.rlim_max==RLIM_INFINITY ? "(inf)":"",-vVMEM));
4428   }
4429   else {AliInfo("No check on RSS memory usage will be applied");}
4430   //  
4431 }
4432
4433 //_________________________________________________________________
4434 Bool_t AliReconstruction::HasEnoughResources(int ev)
4435 {
4436   // check if process consumed more than allowed resources
4437   const int kKB2MB = 1024;
4438   Bool_t res = kTRUE;
4439   if (!fMaxRSS && !fMaxVMEM) return res;
4440   //
4441   ProcInfo_t procInfo;
4442   gSystem->GetProcInfo(&procInfo);
4443   if (procInfo.fMemResident/kKB2MB > fMaxRSS)  res = kFALSE;
4444   if (procInfo.fMemVirtual/kKB2MB  > fMaxVMEM) res = kFALSE;  
4445   //
4446   if (!res) {
4447     AliInfo(Form("Job exceeded allowed limits: RSS:%d (%d) VMEM:%d (%d), will stop",
4448                  int(procInfo.fMemResident/kKB2MB),fMaxRSS,
4449                  int(procInfo.fMemVirtual/kKB2MB) ,fMaxVMEM));
4450     //
4451     unlink(Form("%s",fgkStopEvFName));
4452     ofstream outfile(fgkStopEvFName);
4453     outfile << ev << std::endl;
4454     outfile.close();
4455     fStopped = kTRUE;
4456   }
4457   return res;
4458 }