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