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