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