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