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