]> git.uio.no Git - u/mrichter/AliRoot.git/blob - AliReconstruction.cxx
ee52387d744bb6b6f50962f9159615a5359a50d0
[u/mrichter/AliRoot.git] / 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 // For debug purposes the method SetCheckPointLevel can be used. If the      //
109 // argument is greater than 0, files with ESD events will be written after   //
110 // selected steps of the reconstruction for each event:                      //
111 //   level 1: after tracking and after filling of ESD (final)                //
112 //   level 2: in addition after each tracking step                           //
113 //   level 3: in addition after the filling of ESD for each detector         //
114 // If a final check point file exists for an event, this event will be       //
115 // skipped in the reconstruction. The tracking and the filling of ESD for    //
116 // a detector will be skipped as well, if the corresponding check point      //
117 // file exists. The ESD event will then be loaded from the file instead.     //
118 //                                                                           //
119 ///////////////////////////////////////////////////////////////////////////////
120
121 #include <TArrayF.h>
122 #include <TFile.h>
123 #include <TList.h>
124 #include <TSystem.h>
125 #include <TROOT.h>
126 #include <TPluginManager.h>
127 #include <TGeoManager.h>
128 #include <TLorentzVector.h>
129 #include <TArrayS.h>
130 #include <TArrayD.h>
131 #include <TObjArray.h>
132
133 #include "AliReconstruction.h"
134 #include "AliCodeTimer.h"
135 #include "AliReconstructor.h"
136 #include "AliLog.h"
137 #include "AliRunLoader.h"
138 #include "AliRun.h"
139 #include "AliRawReaderFile.h"
140 #include "AliRawReaderDate.h"
141 #include "AliRawReaderRoot.h"
142 #include "AliRawEventHeaderBase.h"
143 #include "AliESDEvent.h"
144 #include "AliESDMuonTrack.h"
145 #include "AliESDfriend.h"
146 #include "AliESDVertex.h"
147 #include "AliESDcascade.h"
148 #include "AliESDkink.h"
149 #include "AliESDtrack.h"
150 #include "AliESDCaloCluster.h"
151 #include "AliESDCaloCells.h"
152 #include "AliMultiplicity.h"
153 #include "AliTracker.h"
154 #include "AliVertexer.h"
155 #include "AliVertexerTracks.h"
156 #include "AliV0vertexer.h"
157 #include "AliCascadeVertexer.h"
158 #include "AliHeader.h"
159 #include "AliGenEventHeader.h"
160 #include "AliPID.h"
161 #include "AliESDpid.h"
162 #include "AliESDtrack.h"
163 #include "AliESDPmdTrack.h"
164
165 #include "AliESDTagCreator.h"
166 #include "AliAODTagCreator.h"
167
168 #include "AliGeomManager.h"
169 #include "AliTrackPointArray.h"
170 #include "AliCDBManager.h"
171 #include "AliCDBStorage.h"
172 #include "AliCDBEntry.h"
173 #include "AliAlignObj.h"
174
175 #include "AliCentralTrigger.h"
176 #include "AliTriggerConfiguration.h"
177 #include "AliTriggerClass.h"
178 #include "AliCTPRawStream.h"
179
180 #include "AliAODEvent.h"
181 #include "AliAODHeader.h"
182 #include "AliAODTrack.h"
183 #include "AliAODVertex.h"
184 #include "AliAODv0.h"
185 #include "AliAODJet.h"
186 #include "AliAODCaloCells.h"
187 #include "AliAODCaloCluster.h"
188 #include "AliAODPmdCluster.h"
189 #include "AliAODFmdCluster.h"
190 #include "AliAODTracklets.h"
191
192 #include "AliQADataMakerRec.h" 
193 #include "AliGlobalQADataMaker.h" 
194 #include "AliQA.h"
195 #include "AliQADataMakerSteer.h"
196
197 #include "AliPlaneEff.h"
198
199 #include "AliSysInfo.h" // memory snapshots
200 #include "AliRawHLTManager.h"
201
202
203 ClassImp(AliReconstruction)
204
205
206 //_____________________________________________________________________________
207 const char* AliReconstruction::fgkDetectorName[AliReconstruction::fgkNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT"};
208
209 //_____________________________________________________________________________
210 AliReconstruction::AliReconstruction(const char* gAliceFilename,
211                                      const char* name, const char* title) :
212   TNamed(name, title),
213
214   fUniformField(kTRUE),
215   fRunVertexFinder(kTRUE),
216   fRunVertexFinderTracks(kTRUE),
217   fRunHLTTracking(kFALSE),
218   fRunMuonTracking(kFALSE),
219   fRunV0Finder(kTRUE),
220   fRunCascadeFinder(kTRUE),
221   fStopOnError(kFALSE),
222   fWriteAlignmentData(kFALSE),
223   fWriteESDfriend(kFALSE),
224   fWriteAOD(kFALSE),
225   fFillTriggerESD(kTRUE),
226
227   fCleanESD(kTRUE),
228   fV0DCAmax(3.),
229   fV0CsPmin(0.),
230   fDmax(50.),
231   fZmax(50.),
232
233   fRunLocalReconstruction("ALL"),
234   fRunTracking("ALL"),
235   fFillESD("ALL"),
236   fUseTrackingErrorsForAlignment(""),
237   fGAliceFileName(gAliceFilename),
238   fInput(""),
239   fEquipIdMap(""),
240   fFirstEvent(0),
241   fLastEvent(-1),
242   fNumberOfEventsPerFile(1),
243   fCheckPointLevel(0),
244   fOptions(),
245   fLoadAlignFromCDB(kTRUE),
246   fLoadAlignData("ALL"),
247   fESDPar(""),
248   fUseHLTData(),
249
250   fRunLoader(NULL),
251   fRawReader(NULL),
252   fParentRawReader(NULL),
253
254   fVertexer(NULL),
255   fDiamondProfile(NULL),
256   fMeanVertexConstraint(kTRUE),
257
258   fGRPList(NULL),
259
260   fAlignObjArray(NULL),
261   fCDBUri(),
262   fSpecCDBUri(), 
263   fInitCDBCalled(kFALSE),
264   fSetRunNumberFromDataCalled(kFALSE),
265   fRunQA(kTRUE),  
266   fRunGlobalQA(kFALSE),
267   fInLoopQA(kFALSE),
268
269   fRunPlaneEff(kFALSE)
270 {
271 // create reconstruction object with default parameters
272   
273   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
274     fReconstructor[iDet] = NULL;
275     fLoader[iDet] = NULL;
276     fTracker[iDet] = NULL;
277     fQADataMaker[iDet] = NULL;
278         fQACycles[iDet] = 999999;       
279   }
280   fQADataMaker[fgkNDetectors]=NULL;  //Global QA
281   AliPID pid;
282 }
283
284 //_____________________________________________________________________________
285 AliReconstruction::AliReconstruction(const AliReconstruction& rec) :
286   TNamed(rec),
287
288   fUniformField(rec.fUniformField),
289   fRunVertexFinder(rec.fRunVertexFinder),
290   fRunVertexFinderTracks(rec.fRunVertexFinderTracks),
291   fRunHLTTracking(rec.fRunHLTTracking),
292   fRunMuonTracking(rec.fRunMuonTracking),
293   fRunV0Finder(rec.fRunV0Finder),
294   fRunCascadeFinder(rec.fRunCascadeFinder),
295   fStopOnError(rec.fStopOnError),
296   fWriteAlignmentData(rec.fWriteAlignmentData),
297   fWriteESDfriend(rec.fWriteESDfriend),
298   fWriteAOD(rec.fWriteAOD),
299   fFillTriggerESD(rec.fFillTriggerESD),
300
301   fCleanESD(rec.fCleanESD),
302   fV0DCAmax(rec.fV0DCAmax),
303   fV0CsPmin(rec.fV0CsPmin),
304   fDmax(rec.fDmax),
305   fZmax(rec.fZmax),
306
307   fRunLocalReconstruction(rec.fRunLocalReconstruction),
308   fRunTracking(rec.fRunTracking),
309   fFillESD(rec.fFillESD),
310   fUseTrackingErrorsForAlignment(rec.fUseTrackingErrorsForAlignment),
311   fGAliceFileName(rec.fGAliceFileName),
312   fInput(rec.fInput),
313   fEquipIdMap(rec.fEquipIdMap),
314   fFirstEvent(rec.fFirstEvent),
315   fLastEvent(rec.fLastEvent),
316   fNumberOfEventsPerFile(rec.fNumberOfEventsPerFile),
317   fCheckPointLevel(0),
318   fOptions(),
319   fLoadAlignFromCDB(rec.fLoadAlignFromCDB),
320   fLoadAlignData(rec.fLoadAlignData),
321   fESDPar(rec.fESDPar),
322
323   fRunLoader(NULL),
324   fRawReader(NULL),
325
326   fVertexer(NULL),
327   fDiamondProfile(NULL),
328   fMeanVertexConstraint(rec.fMeanVertexConstraint),
329
330   fGRPList(NULL),
331
332   fAlignObjArray(rec.fAlignObjArray),
333   fCDBUri(rec.fCDBUri),
334   fSpecCDBUri(), 
335   fInitCDBCalled(rec.fInitCDBCalled),
336   fSetRunNumberFromDataCalled(rec.fSetRunNumberFromDataCalled),
337   fRunQA(rec.fRunQA),  
338   fRunGlobalQA(rec.fRunGlobalQA),
339   fInLoopQA(rec.fInLoopQA),
340   fRunPlaneEff(rec.fRunPlaneEff)
341 {
342 // copy constructor
343
344   for (Int_t i = 0; i < rec.fOptions.GetEntriesFast(); i++) {
345     if (rec.fOptions[i]) fOptions.Add(rec.fOptions[i]->Clone());
346   }
347   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
348     fReconstructor[iDet] = NULL;
349     fLoader[iDet] = NULL;
350     fTracker[iDet] = NULL;
351     fQADataMaker[iDet] = NULL;
352         fQACycles[iDet] = rec.fQACycles[iDet];  
353   }
354   fQADataMaker[fgkNDetectors]=NULL;  //Global QA
355   for (Int_t i = 0; i < rec.fSpecCDBUri.GetEntriesFast(); i++) {
356     if (rec.fSpecCDBUri[i]) fSpecCDBUri.Add(rec.fSpecCDBUri[i]->Clone());
357   }
358 }
359
360 //_____________________________________________________________________________
361 AliReconstruction& AliReconstruction::operator = (const AliReconstruction& rec)
362 {
363 // assignment operator
364
365   this->~AliReconstruction();
366   new(this) AliReconstruction(rec);
367   return *this;
368 }
369
370 //_____________________________________________________________________________
371 AliReconstruction::~AliReconstruction()
372 {
373 // clean up
374
375   CleanUp();
376   fOptions.Delete();
377   fSpecCDBUri.Delete();
378
379   AliCodeTimer::Instance()->Print();
380 }
381
382 //_____________________________________________________________________________
383 void AliReconstruction::InitCDB()
384 {
385 // activate a default CDB storage
386 // First check if we have any CDB storage set, because it is used 
387 // to retrieve the calibration and alignment constants
388
389   if (fInitCDBCalled) return;
390   fInitCDBCalled = kTRUE;
391
392   AliCDBManager* man = AliCDBManager::Instance();
393   if (man->IsDefaultStorageSet())
394   {
395     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
396     AliWarning("Default CDB storage has been already set !");
397     AliWarning(Form("Ignoring the default storage declared in AliReconstruction: %s",fCDBUri.Data()));
398     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
399     fCDBUri = man->GetDefaultStorage()->GetURI();
400   }
401   else {
402     if (fCDBUri.Length() > 0) 
403     {
404         AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
405         AliDebug(2, Form("Default CDB storage is set to: %s", fCDBUri.Data()));
406         AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
407     } else {
408         fCDBUri="local://$ALICE_ROOT";
409         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
410         AliWarning("Default CDB storage not yet set !!!!");
411         AliWarning(Form("Setting it now to: %s", fCDBUri.Data()));
412         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
413                 
414     }
415     man->SetDefaultStorage(fCDBUri);
416   }
417
418   // Now activate the detector specific CDB storage locations
419   for (Int_t i = 0; i < fSpecCDBUri.GetEntriesFast(); i++) {
420     TObject* obj = fSpecCDBUri[i];
421     if (!obj) continue;
422     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
423     AliDebug(2, Form("Specific CDB storage for %s is set to: %s",obj->GetName(),obj->GetTitle()));
424     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
425     man->SetSpecificStorage(obj->GetName(), obj->GetTitle());
426   }
427   
428 }
429
430 //_____________________________________________________________________________
431 void AliReconstruction::SetDefaultStorage(const char* uri) {
432 // Store the desired default CDB storage location
433 // Activate it later within the Run() method
434
435   fCDBUri = uri;
436
437 }
438
439 //_____________________________________________________________________________
440 void AliReconstruction::SetSpecificStorage(const char* calibType, const char* uri) {
441 // Store a detector-specific CDB storage location
442 // Activate it later within the Run() method
443
444   AliCDBPath aPath(calibType);
445   if(!aPath.IsValid()){
446         // if calibType is not wildcard but it is a valid detector, add "/*" to make it a valid path
447         for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
448                 if(!strcmp(calibType, fgkDetectorName[iDet])) {
449                         aPath.SetPath(Form("%s/*", calibType));
450                         AliInfo(Form("Path for specific storage set to %s", aPath.GetPath().Data()));
451                         break;
452                 }
453         }
454         if(!aPath.IsValid()){
455                 AliError(Form("Not a valid path or detector: %s", calibType));
456                 return;
457         }
458   }
459
460 //  // check that calibType refers to a "valid" detector name
461 //  Bool_t isDetector = kFALSE;
462 //  for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
463 //    TString detName = fgkDetectorName[iDet];
464 //    if(aPath.GetLevel0() == detName) {
465 //      isDetector = kTRUE;
466 //      break;
467 //    }
468 //  }
469 //
470 //  if(!isDetector) {
471 //      AliError(Form("Not a valid detector: %s", aPath.GetLevel0().Data()));
472 //      return;
473 //  }
474
475   TObject* obj = fSpecCDBUri.FindObject(aPath.GetPath().Data());
476   if (obj) fSpecCDBUri.Remove(obj);
477   fSpecCDBUri.Add(new TNamed(aPath.GetPath().Data(), uri));
478
479 }
480
481 //_____________________________________________________________________________
482 Bool_t AliReconstruction::SetRunNumberFromData()
483 {
484   // The method is called in Run() in order
485   // to set a correct run number.
486   // In case of raw data reconstruction the
487   // run number is taken from the raw data header
488
489   if (fSetRunNumberFromDataCalled) return kTRUE;
490   fSetRunNumberFromDataCalled = kTRUE;
491   
492   AliCDBManager* man = AliCDBManager::Instance();
493   
494   if(man->GetRun() > 0) {
495         AliWarning("Run number is taken from event header! Ignoring settings in AliCDBManager!");
496   } 
497   
498   if (!fRunLoader) {
499       AliError("No run loader is found !"); 
500       return kFALSE;
501     }
502     // read run number from gAlice
503     if(fRunLoader->GetAliRun())
504       AliCDBManager::Instance()->SetRun(fRunLoader->GetHeader()->GetRun());
505     else {
506       if(fRawReader) {
507         if(fRawReader->NextEvent()) {
508           AliCDBManager::Instance()->SetRun(fRawReader->GetRunNumber());
509           fRawReader->RewindEvents();
510         }
511         else {
512           AliError("No raw-data events found !");
513           return kFALSE;
514         }
515       }
516       else {
517         AliError("Neither gAlice nor RawReader objects are found !");
518         return kFALSE;
519       }
520   }
521
522   man->Print();  
523   
524   return kTRUE;
525 }
526
527 //_____________________________________________________________________________
528 void AliReconstruction::SetCDBLock() {
529   // Set CDB lock: from now on it is forbidden to reset the run number
530   // or the default storage or to activate any further storage!
531   
532   AliCDBManager::Instance()->SetLock(1);
533 }
534
535 //_____________________________________________________________________________
536 Bool_t AliReconstruction::MisalignGeometry(const TString& detectors)
537 {
538   // Read the alignment objects from CDB.
539   // Each detector is supposed to have the
540   // alignment objects in DET/Align/Data CDB path.
541   // All the detector objects are then collected,
542   // sorted by geometry level (starting from ALIC) and
543   // then applied to the TGeo geometry.
544   // Finally an overlaps check is performed.
545
546   // Load alignment data from CDB and fill fAlignObjArray 
547   if(fLoadAlignFromCDB){
548         
549     TString detStr = detectors;
550     TString loadAlObjsListOfDets = "";
551     
552     for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
553       if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
554       loadAlObjsListOfDets += fgkDetectorName[iDet];
555       loadAlObjsListOfDets += " ";
556     } // end loop over detectors
557     loadAlObjsListOfDets.Prepend("GRP "); //add alignment objects for non-sensitive modules
558     AliGeomManager::ApplyAlignObjsFromCDB(loadAlObjsListOfDets.Data());
559   }else{
560     // Check if the array with alignment objects was
561     // provided by the user. If yes, apply the objects
562     // to the present TGeo geometry
563     if (fAlignObjArray) {
564       if (gGeoManager && gGeoManager->IsClosed()) {
565         if (AliGeomManager::ApplyAlignObjsToGeom(*fAlignObjArray) == kFALSE) {
566           AliError("The misalignment of one or more volumes failed!"
567                    "Compare the list of simulated detectors and the list of detector alignment data!");
568           return kFALSE;
569         }
570       }
571       else {
572         AliError("Can't apply the misalignment! gGeoManager doesn't exist or it is still opened!");
573         return kFALSE;
574       }
575     }
576   }
577   
578   delete fAlignObjArray; fAlignObjArray=0;
579
580   return kTRUE;
581 }
582
583 //_____________________________________________________________________________
584 void AliReconstruction::SetGAliceFile(const char* fileName)
585 {
586 // set the name of the galice file
587
588   fGAliceFileName = fileName;
589 }
590
591 //_____________________________________________________________________________
592 void AliReconstruction::SetOption(const char* detector, const char* option)
593 {
594 // set options for the reconstruction of a detector
595
596   TObject* obj = fOptions.FindObject(detector);
597   if (obj) fOptions.Remove(obj);
598   fOptions.Add(new TNamed(detector, option));
599 }
600
601
602 //_____________________________________________________________________________
603 Bool_t AliReconstruction::Run(const char* input, Bool_t IsOnline)
604 {
605 // run the reconstruction
606
607   AliCodeTimerAuto("")
608   
609   // set the input
610   if (!IsOnline) {
611     if (!input) input = fInput.Data();
612     TString fileName(input);
613     if (fileName.EndsWith("/")) {
614       fRawReader = new AliRawReaderFile(fileName);
615     } else if (fileName.EndsWith(".root")) {
616       fRawReader = new AliRawReaderRoot(fileName);
617     } else if (!fileName.IsNull()) {
618       fRawReader = new AliRawReaderDate(fileName);
619     }
620   }
621   else {
622     if (!input) {
623       AliError("Null pointer to the event structure!");
624       return kFALSE;
625     }
626     fRawReader = new AliRawReaderDate((void *)input);
627   }
628
629   if (!fEquipIdMap.IsNull() && fRawReader)
630     fRawReader->LoadEquipmentIdsMap(fEquipIdMap);
631
632   if (!fUseHLTData.IsNull()) {
633     // create the RawReaderHLT which performs redirection of HLT input data for
634     // the specified detectors
635     AliRawReader* pRawReader=AliRawHLTManager::CreateRawReaderHLT(fRawReader, fUseHLTData.Data());
636     if (pRawReader) {
637       fParentRawReader=fRawReader;
638       fRawReader=pRawReader;
639     } else {
640       AliError(Form("can not create Raw Reader for HLT input %s", fUseHLTData.Data()));
641     }
642   }
643
644    AliSysInfo::AddStamp("Start");
645   // get the run loader
646   if (!InitRunLoader()) return kFALSE;
647    AliSysInfo::AddStamp("LoadLoader");
648
649   // Initialize the CDB storage
650   InitCDB();
651   
652   AliSysInfo::AddStamp("LoadCDB");
653
654   // Set run number in CDBManager (if it is not already set by the user)
655   if (!SetRunNumberFromData()) if (fStopOnError) return kFALSE;
656   
657   // Set CDB lock: from now on it is forbidden to reset the run number
658   // or the default storage or to activate any further storage!
659   SetCDBLock();
660   
661   // Import ideal TGeo geometry and apply misalignment
662   if (!gGeoManager) {
663     TString geom(gSystem->DirName(fGAliceFileName));
664     geom += "/geometry.root";
665     AliGeomManager::LoadGeometry(geom.Data());
666     if (!gGeoManager) if (fStopOnError) return kFALSE;
667   }
668
669   if (!MisalignGeometry(fLoadAlignData)) if (fStopOnError) return kFALSE;
670    AliSysInfo::AddStamp("LoadGeom");
671
672   //QA 
673   AliQADataMakerSteer qas ; 
674   if (fRunQA && fRawReader) qas.Run(fRunLocalReconstruction, fRawReader) ; 
675   // checking the QA of previous steps
676   //CheckQA() ; 
677  
678   /*
679   // local reconstruction
680   if (!fRunLocalReconstruction.IsNull()) {
681     if (!RunLocalReconstruction(fRunLocalReconstruction)) {
682       if (fStopOnError) {CleanUp(); return kFALSE;}
683     }
684   }
685   */
686
687   // get vertexer
688   if (fRunVertexFinder && !CreateVertexer()) {
689     if (fStopOnError) {
690       CleanUp(); 
691       return kFALSE;
692     }
693   }
694    AliSysInfo::AddStamp("Vertexer");
695
696   // get trackers
697   if (!fRunTracking.IsNull() && !CreateTrackers(fRunTracking)) {
698     if (fStopOnError) {
699       CleanUp(); 
700       return kFALSE;
701     }      
702   }
703    AliSysInfo::AddStamp("LoadTrackers");
704
705   // get the possibly already existing ESD file and tree
706   AliESDEvent* esd = new AliESDEvent(); AliESDEvent* hltesd = new AliESDEvent();
707   TFile* fileOld = NULL;
708   TTree* treeOld = NULL; TTree *hlttreeOld = NULL;
709   if (!gSystem->AccessPathName("AliESDs.root")){
710     gSystem->CopyFile("AliESDs.root", "AliESDs.old.root", kTRUE);
711     fileOld = TFile::Open("AliESDs.old.root");
712     if (fileOld && fileOld->IsOpen()) {
713       treeOld = (TTree*) fileOld->Get("esdTree");
714       if (treeOld)esd->ReadFromTree(treeOld);
715       hlttreeOld = (TTree*) fileOld->Get("HLTesdTree");
716       if (hlttreeOld)   hltesd->ReadFromTree(hlttreeOld);
717     }
718   }
719
720   // create the ESD output file and tree
721   TFile* file = TFile::Open("AliESDs.root", "RECREATE");
722   file->SetCompressionLevel(2);
723   if (!file->IsOpen()) {
724     AliError("opening AliESDs.root failed");
725     if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}    
726   }
727
728   TTree* tree = new TTree("esdTree", "Tree with ESD objects");
729   esd = new AliESDEvent();
730   esd->CreateStdContent();
731   esd->WriteToTree(tree);
732
733   TTree* hlttree = new TTree("HLTesdTree", "Tree with HLT ESD objects");
734   hltesd = new AliESDEvent();
735   hltesd->CreateStdContent();
736   hltesd->WriteToTree(hlttree);
737
738   /* CKB Why?
739   delete esd; delete hltesd;
740   esd = NULL; hltesd = NULL;
741   */
742   // create the branch with ESD additions
743
744
745
746   AliESDfriend *esdf = 0; 
747   if (fWriteESDfriend) {
748     esdf = new AliESDfriend();
749     TBranch *br=tree->Branch("ESDfriend.","AliESDfriend", &esdf);
750     br->SetFile("AliESDfriends.root");
751     esd->AddObject(esdf);
752   }
753
754   
755   // Get the GRP CDB entry
756   AliCDBEntry* entryGRP = AliCDBManager::Instance()->Get("GRP/GRP/Data");
757         
758   if(entryGRP) {
759         fGRPList = dynamic_cast<TList*> (entryGRP->GetObject());  
760   } else {
761         AliError("No GRP entry found in OCDB!");
762   }
763
764   // Get the diamond profile from OCDB
765   AliCDBEntry* entry = AliCDBManager::Instance()
766         ->Get("GRP/Calib/MeanVertex");
767         
768   if(entry) {
769         fDiamondProfile = dynamic_cast<AliESDVertex*> (entry->GetObject());  
770   } else {
771         AliError("No diamond profile found in OCDB!");
772   }
773
774   AliVertexerTracks tVertexer(AliTracker::GetBz());
775   if(fDiamondProfile && fMeanVertexConstraint) tVertexer.SetVtxStart(fDiamondProfile);
776
777   if (fRawReader) fRawReader->RewindEvents();
778
779   ProcInfo_t ProcInfo;
780   gSystem->GetProcInfo(&ProcInfo);
781   AliInfo(Form("Current memory usage %d %d", ProcInfo.fMemResident, ProcInfo.fMemVirtual));
782   
783
784   //Initialize the QA and start of cycle for out-of-cycle QA
785   if (fRunQA) {
786      TString detStr(fFillESD); 
787      for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
788         if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
789         AliQADataMakerRec *qadm = GetQADataMaker(iDet);  
790         if (!qadm) continue;
791         AliInfo(Form("Initializing the QA data maker for %s", 
792                fgkDetectorName[iDet]));
793         qadm->Init(AliQA::kRECPOINTS, AliCDBManager::Instance()->GetRun());
794         qadm->Init(AliQA::kESDS, AliCDBManager::Instance()->GetRun());
795         if (!fInLoopQA) {
796            qadm->StartOfCycle(AliQA::kRECPOINTS);
797            qadm->StartOfCycle(AliQA::kESDS,"same");
798         }
799      }
800   }
801   if (fRunGlobalQA) {
802      AliQADataMakerRec *qadm = GetQADataMaker(fgkNDetectors);
803      AliInfo(Form("Initializing the global QA data maker"));
804      TObjArray *arr=
805           qadm->Init(AliQA::kRECPOINTS, AliCDBManager::Instance()->GetRun());
806      AliTracker::SetResidualsArray(arr);
807      qadm->Init(AliQA::kESDS, AliCDBManager::Instance()->GetRun());
808      if (!fInLoopQA) {
809         qadm->StartOfCycle(AliQA::kRECPOINTS);
810         qadm->StartOfCycle(AliQA::kESDS,"same");
811      }
812   }
813
814   //Initialize the Plane Efficiency framework
815   if (fRunPlaneEff && !InitPlaneEff()) {
816     if(fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
817   }
818
819   //******* The loop over events
820   for (Int_t iEvent = 0; iEvent < fRunLoader->GetNumberOfEvents(); iEvent++) {
821     if (fRawReader) fRawReader->NextEvent();
822     if ((iEvent < fFirstEvent) || ((fLastEvent >= 0) && (iEvent > fLastEvent))) {
823       // copy old ESD to the new one
824       if (treeOld) {
825         esd->ReadFromTree(treeOld);
826         treeOld->GetEntry(iEvent);
827       }
828       tree->Fill();
829       if (hlttreeOld) {
830         esd->ReadFromTree(hlttreeOld);
831         hlttreeOld->GetEntry(iEvent);
832       }
833       hlttree->Fill();
834       continue;
835     }
836     
837     AliInfo(Form("processing event %d", iEvent));
838
839     //Start of cycle for the in-loop QA
840     if (fInLoopQA) {
841        if (fRunQA) {
842           TString detStr(fFillESD); 
843           for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
844              if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
845              AliQADataMakerRec *qadm = GetQADataMaker(iDet);  
846              if (!qadm) continue;
847              qadm->StartOfCycle(AliQA::kRECPOINTS);
848              qadm->StartOfCycle(AliQA::kESDS, "same") ;         
849           }
850        }
851        if (fRunGlobalQA) {
852           AliQADataMakerRec *qadm = GetQADataMaker(fgkNDetectors);
853           qadm->StartOfCycle(AliQA::kRECPOINTS);
854           qadm->StartOfCycle(AliQA::kESDS,"same");
855        }
856     }
857
858     fRunLoader->GetEvent(iEvent);
859
860     char aFileName[256];
861     sprintf(aFileName, "ESD_%d.%d_final.root", 
862             fRunLoader->GetHeader()->GetRun(), 
863             fRunLoader->GetHeader()->GetEventNrInRun());
864     if (!gSystem->AccessPathName(aFileName)) continue;
865
866     // local signle event reconstruction
867     if (!fRunLocalReconstruction.IsNull()) {
868       if (!RunLocalEventReconstruction(fRunLocalReconstruction)) {
869         if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
870       }
871     }
872
873     esd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
874     hltesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
875     esd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
876     hltesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
877     
878     // Set magnetic field from the tracker
879     esd->SetMagneticField(AliTracker::GetBz());
880     hltesd->SetMagneticField(AliTracker::GetBz());
881
882     
883     
884     // Fill raw-data error log into the ESD
885     if (fRawReader) FillRawDataErrorLog(iEvent,esd);
886
887     // vertex finder
888     if (fRunVertexFinder) {
889       if (!ReadESD(esd, "vertex")) {
890         if (!RunVertexFinder(esd)) {
891           if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
892         }
893         if (fCheckPointLevel > 0) WriteESD(esd, "vertex");
894       }
895     }
896
897     // HLT tracking
898     if (!fRunTracking.IsNull()) {
899       if (fRunHLTTracking) {
900         hltesd->SetPrimaryVertexSPD(esd->GetVertex());
901         if (!RunHLTTracking(hltesd)) {
902           if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
903         }
904       }
905     }
906
907     // Muon tracking
908     if (!fRunTracking.IsNull()) {
909       if (fRunMuonTracking) {
910         if (!RunMuonTracking(esd)) {
911           if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
912         }
913       }
914     }
915
916     // barrel tracking
917     if (!fRunTracking.IsNull()) {
918       if (!ReadESD(esd, "tracking")) {
919         if (!RunTracking(esd)) {
920           if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
921         }
922         if (fCheckPointLevel > 0) WriteESD(esd, "tracking");
923       }
924     }
925
926     // fill ESD
927     if (!fFillESD.IsNull()) {
928       if (!FillESD(esd, fFillESD)) {
929         if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
930       }
931     }
932   
933     // fill Event header information from the RawEventHeader
934     if (fRawReader){FillRawEventHeaderESD(esd);}
935
936     // combined PID
937     AliESDpid::MakePID(esd);
938     if (fCheckPointLevel > 1) WriteESD(esd, "PID");
939
940     if (fFillTriggerESD) {
941       if (!ReadESD(esd, "trigger")) {
942         if (!FillTriggerESD(esd)) {
943           if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
944         }
945         if (fCheckPointLevel > 1) WriteESD(esd, "trigger");
946       }
947     }
948
949     file->cd();
950
951     //
952     // Propagate track to the beam pipe  (if not laready done by ITS)
953     //
954     const Int_t ntracks = esd->GetNumberOfTracks();
955     const Double_t kBz = esd->GetMagneticField();
956     const Double_t kRadius  = 2.8; //something less than the beam pipe radius
957
958     TObjArray trkArray;
959     UShort_t *selectedIdx=new UShort_t[ntracks];
960
961     for (Int_t itrack=0; itrack<ntracks; itrack++){
962       const Double_t kMaxStep = 5;   //max step over the material
963       Bool_t ok;
964
965       AliESDtrack *track = esd->GetTrack(itrack);
966       if (!track) continue;
967
968       AliExternalTrackParam *tpcTrack =
969            (AliExternalTrackParam *)track->GetTPCInnerParam();
970       ok = kFALSE;
971       if (tpcTrack)
972         ok = AliTracker::
973           PropagateTrackTo(tpcTrack,kRadius,track->GetMass(),kMaxStep,kTRUE);
974       if (ok) {
975         Int_t n=trkArray.GetEntriesFast();
976         selectedIdx[n]=track->GetID();
977         trkArray.AddLast(tpcTrack);
978       }
979
980       if (track->GetX() < kRadius) continue;
981
982       ok = AliTracker::
983            PropagateTrackTo(track,kRadius,track->GetMass(),kMaxStep,kTRUE);
984       if (ok) {
985          track->RelateToVertex(esd->GetPrimaryVertexSPD(), kBz, kRadius);
986       }
987     }
988
989     //
990     // Improve the reconstructed primary vertex position using the tracks
991     //
992     TObject *obj = fOptions.FindObject("ITS");
993     if (obj) {
994       TString optITS = obj->GetTitle();
995       if (optITS.Contains("cosmics") || optITS.Contains("COSMICS")) 
996         fRunVertexFinderTracks=kFALSE;
997     }
998     if (fRunVertexFinderTracks) {
999        // TPC + ITS primary vertex
1000        AliESDVertex *pvtx=tVertexer.FindPrimaryVertex(esd);
1001        if (pvtx) {
1002           if (pvtx->GetStatus()) {
1003              esd->SetPrimaryVertex(pvtx);
1004              for (Int_t i=0; i<ntracks; i++) {
1005                  AliESDtrack *t = esd->GetTrack(i);
1006                  t->RelateToVertex(pvtx, kBz, kRadius);
1007              } 
1008           }
1009        }
1010
1011        // TPC-only primary vertex
1012        pvtx=tVertexer.FindPrimaryVertex(&trkArray,selectedIdx);
1013        if (pvtx) {
1014           if (pvtx->GetStatus()) {
1015              esd->SetPrimaryVertexTPC(pvtx);
1016              Int_t nsel=trkArray.GetEntriesFast();
1017              for (Int_t i=0; i<nsel; i++) {
1018                  AliExternalTrackParam *t = 
1019                    (AliExternalTrackParam *)trkArray.UncheckedAt(i);
1020                  t->PropagateToDCA(pvtx, kBz, kRadius);
1021              } 
1022           }
1023        }
1024
1025     }
1026     delete[] selectedIdx;
1027
1028     if(fDiamondProfile) esd->SetDiamond(fDiamondProfile);
1029     
1030
1031     if (fRunV0Finder) {
1032        // V0 finding
1033        AliV0vertexer vtxer;
1034        vtxer.Tracks2V0vertices(esd);
1035
1036        if (fRunCascadeFinder) {
1037           // Cascade finding
1038           AliCascadeVertexer cvtxer;
1039           cvtxer.V0sTracks2CascadeVertices(esd);
1040        }
1041     }
1042  
1043     // write ESD
1044     if (fCleanESD) CleanESD(esd);
1045
1046     if (fRunGlobalQA) {
1047        AliQADataMakerRec *qadm = GetQADataMaker(fgkNDetectors);
1048        if (qadm) qadm->Exec(AliQA::kESDS, esd);
1049     }
1050
1051     if (fWriteESDfriend) {
1052       esdf->~AliESDfriend();
1053       new (esdf) AliESDfriend(); // Reset...
1054       esd->GetESDfriend(esdf);
1055     }
1056     tree->Fill();
1057
1058     // write HLT ESD
1059     hlttree->Fill();
1060
1061     if (fCheckPointLevel > 0)  WriteESD(esd, "final"); 
1062     esd->Reset();
1063     hltesd->Reset();
1064     if (fWriteESDfriend) {
1065       esdf->~AliESDfriend();
1066       new (esdf) AliESDfriend(); // Reset...
1067     }
1068  
1069     gSystem->GetProcInfo(&ProcInfo);
1070     AliInfo(Form("Event %d -> Current memory usage %d %d",iEvent, ProcInfo.fMemResident, ProcInfo.fMemVirtual));
1071   
1072
1073   // End of cycle for the in-loop QA
1074      if (fInLoopQA) {
1075         if (fRunQA) {
1076            RunQA(fFillESD.Data(), esd);
1077            TString detStr(fFillESD); 
1078            for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1079               if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1080               AliQADataMakerRec * qadm = GetQADataMaker(iDet);
1081               if (!qadm) continue;
1082               qadm->EndOfCycle(AliQA::kRECPOINTS);
1083               qadm->EndOfCycle(AliQA::kESDS);
1084               qadm->Finish();
1085            }
1086         }
1087         if (fRunGlobalQA) {
1088            AliQADataMakerRec *qadm = GetQADataMaker(fgkNDetectors);
1089            if (qadm) {
1090               qadm->EndOfCycle(AliQA::kRECPOINTS);
1091               qadm->EndOfCycle(AliQA::kESDS);
1092               qadm->Finish();
1093            }
1094         }
1095      }
1096   } 
1097   //******** End of the loop over events 
1098
1099
1100
1101   tree->GetUserInfo()->Add(esd);
1102   hlttree->GetUserInfo()->Add(hltesd);
1103   
1104   const TMap *cdbMap = AliCDBManager::Instance()->GetStorageMap();       
1105   const TList *cdbList = AliCDBManager::Instance()->GetRetrievedIds();   
1106                  
1107    TMap *cdbMapCopy = new TMap(cdbMap->GetEntries());    
1108    cdbMapCopy->SetOwner(1);      
1109    cdbMapCopy->SetName("cdbMap");        
1110    TIter iter(cdbMap->GetTable());       
1111          
1112    TPair* pair = 0;      
1113    while((pair = dynamic_cast<TPair*> (iter.Next()))){   
1114          TObjString* keyStr = dynamic_cast<TObjString*> (pair->Key());   
1115          TObjString* valStr = dynamic_cast<TObjString*> (pair->Value());         
1116          cdbMapCopy->Add(new TObjString(keyStr->GetName()), new TObjString(valStr->GetName()));  
1117    }     
1118          
1119    TList *cdbListCopy = new TList();     
1120    cdbListCopy->SetOwner(1);     
1121    cdbListCopy->SetName("cdbList");      
1122          
1123    TIter iter2(cdbList);         
1124          
1125    AliCDBId* id=0;       
1126    while((id = dynamic_cast<AliCDBId*> (iter2.Next()))){         
1127          cdbListCopy->Add(new TObjString(id->ToString().Data()));        
1128    }     
1129          
1130    tree->GetUserInfo()->Add(cdbMapCopy);         
1131    tree->GetUserInfo()->Add(cdbListCopy);
1132
1133
1134   if(fESDPar.Contains("ESD.par")){
1135     AliInfo("Attaching ESD.par to Tree");
1136     TNamed *fn = CopyFileToTNamed(fESDPar.Data(),"ESD.par");
1137     tree->GetUserInfo()->Add(fn);
1138   }
1139
1140
1141   file->cd();
1142
1143   if (fWriteESDfriend)
1144     tree->SetBranchStatus("ESDfriend*",0);
1145   // we want to have only one tree version number
1146   tree->Write(tree->GetName(),TObject::kOverwrite);
1147   hlttree->Write();
1148
1149 // Finish with Plane Efficiency evaluation: before of CleanUp !!!
1150   if (fRunPlaneEff && !FinishPlaneEff()) {
1151    AliWarning("Finish PlaneEff evaluation failed");
1152   }
1153
1154   gROOT->cd();
1155   CleanUp(file, fileOld);
1156     
1157   if (fWriteAOD) {
1158     TFile *esdFile = TFile::Open("AliESDs.root", "READONLY");
1159     TFile *aodFile = TFile::Open("AliAOD.root", "RECREATE");
1160     ESDFile2AODFile(esdFile, aodFile);
1161     aodFile->Close();
1162     esdFile->Close();
1163   }
1164
1165   // Create tags for the events in the ESD tree (the ESD tree is always present)
1166   // In case of empty events the tags will contain dummy values
1167   AliESDTagCreator *esdtagCreator = new AliESDTagCreator();
1168   esdtagCreator->CreateESDTags(fFirstEvent,fLastEvent,fGRPList);
1169   if (fWriteAOD) {
1170     AliAODTagCreator *aodtagCreator = new AliAODTagCreator();
1171     aodtagCreator->CreateAODTags(fFirstEvent,fLastEvent,fGRPList);
1172   }
1173
1174   //Finish QA and end of cycle for out-of-loop QA
1175   if (!fInLoopQA) {
1176      if (fRunQA) {
1177         qas.Run(fRunLocalReconstruction.Data(), AliQA::kRECPOINTS);
1178         //qas.Reset() ;
1179         qas.Run(fRunTracking.Data(), AliQA::kESDS);
1180      }
1181      if (fRunGlobalQA) {
1182         AliQADataMakerRec *qadm = GetQADataMaker(fgkNDetectors);
1183         if (qadm) {
1184            qadm->EndOfCycle(AliQA::kRECPOINTS);
1185            qadm->EndOfCycle(AliQA::kESDS);
1186            qadm->Finish();
1187         }
1188      }
1189   }
1190   
1191   // Cleanup of CDB manager: cache and active storages!
1192   AliCDBManager::Instance()->ClearCache();
1193   
1194   
1195   return kTRUE;
1196 }
1197
1198
1199 //_____________________________________________________________________________
1200 Bool_t AliReconstruction::RunLocalReconstruction(const TString& /*detectors*/)
1201 {
1202 // run the local reconstruction
1203   static Int_t eventNr=0;
1204   AliCodeTimerAuto("")
1205
1206  //  AliCDBManager* man = AliCDBManager::Instance();
1207 //   Bool_t origCache = man->GetCacheFlag();
1208
1209 //   TString detStr = detectors;
1210 //   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1211 //     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1212 //     AliReconstructor* reconstructor = GetReconstructor(iDet);
1213 //     if (!reconstructor) continue;
1214 //     if (reconstructor->HasLocalReconstruction()) continue;
1215
1216 //     AliCodeTimerStart(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1217 //     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1218     
1219 //     AliCodeTimerStart(Form("Loading calibration data from OCDB for %s", fgkDetectorName[iDet]));                          
1220 //     AliInfo(Form("Loading calibration data from OCDB for %s", fgkDetectorName[iDet]));
1221
1222 //     man->SetCacheFlag(kTRUE);
1223 //     TString calibPath = Form("%s/Calib/*", fgkDetectorName[iDet]);
1224 //     man->GetAll(calibPath); // entries are cached!
1225
1226 //     AliCodeTimerStop(Form("Loading calibration data from OCDB for %s", fgkDetectorName[iDet]));
1227      
1228 //     if (fRawReader) {
1229 //       fRawReader->RewindEvents();
1230 //       reconstructor->Reconstruct(fRunLoader, fRawReader);
1231 //     } else {
1232 //       reconstructor->Reconstruct(fRunLoader);
1233 //     }
1234      
1235 //      AliCodeTimerStop(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1236     // AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr));
1237
1238 //     // unload calibration data
1239 //     man->UnloadFromCache(calibPath);
1240 //     //man->ClearCache();
1241 //   }
1242
1243 //   man->SetCacheFlag(origCache);
1244
1245 //   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1246 //     AliError(Form("the following detectors were not found: %s",
1247 //                   detStr.Data()));
1248 //     if (fStopOnError) return kFALSE;
1249 //   }
1250
1251           eventNr++;
1252   return kTRUE;
1253 }
1254
1255 //_____________________________________________________________________________
1256 Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
1257 {
1258 // run the local reconstruction
1259
1260   static Int_t eventNr=0;
1261   AliCodeTimerAuto("")
1262
1263   TString detStr = detectors;
1264   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1265     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1266     AliReconstructor* reconstructor = GetReconstructor(iDet);
1267     if (!reconstructor) continue;
1268     AliLoader* loader = fLoader[iDet];
1269     if (!loader) {
1270       AliWarning(Form("No loader is defined for %s!",fgkDetectorName[iDet]));
1271       continue;
1272     }
1273     // conversion of digits
1274     if (fRawReader && reconstructor->HasDigitConversion()) {
1275       AliInfo(Form("converting raw data digits into root objects for %s", 
1276                    fgkDetectorName[iDet]));
1277       AliCodeTimerAuto(Form("converting raw data digits into root objects for %s", 
1278                             fgkDetectorName[iDet]));
1279       loader->LoadDigits("update");
1280       loader->CleanDigits();
1281       loader->MakeDigitsContainer();
1282       TTree* digitsTree = loader->TreeD();
1283       reconstructor->ConvertDigits(fRawReader, digitsTree);
1284       loader->WriteDigits("OVERWRITE");
1285       loader->UnloadDigits();
1286     }
1287     // local reconstruction
1288     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1289     AliCodeTimerAuto(Form("running reconstruction for %s", fgkDetectorName[iDet]));
1290     loader->LoadRecPoints("update");
1291     loader->CleanRecPoints();
1292     loader->MakeRecPointsContainer();
1293     TTree* clustersTree = loader->TreeR();
1294     if (fRawReader && !reconstructor->HasDigitConversion()) {
1295       reconstructor->Reconstruct(fRawReader, clustersTree);
1296     } else {
1297       loader->LoadDigits("read");
1298       TTree* digitsTree = loader->TreeD();
1299       if (!digitsTree) {
1300         AliError(Form("Can't get the %s digits tree", fgkDetectorName[iDet]));
1301         if (fStopOnError) return kFALSE;
1302       } else {
1303         reconstructor->Reconstruct(digitsTree, clustersTree);
1304       }
1305       loader->UnloadDigits();
1306     }
1307
1308     // In-loop QA for local reconstrucion 
1309     if (fRunQA && fInLoopQA) {
1310        AliQADataMakerRec * qadm = GetQADataMaker(iDet);
1311        if (qadm) {
1312           //AliCodeTimerStart
1313           //(Form("Running QA data maker for %s", fgkDetectorName[iDet]));
1314           //AliInfo
1315           //(Form("Running QA data maker for %s", fgkDetectorName[iDet]));
1316
1317           qadm->Exec(AliQA::kRECPOINTS, clustersTree) ;
1318  
1319           //AliCodeTimerStop
1320           //(Form("Running QA data maker for %s", fgkDetectorName[iDet]));
1321        }
1322     }
1323
1324     loader->WriteRecPoints("OVERWRITE");
1325     loader->UnloadRecPoints();
1326     AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr), iDet,1,eventNr);
1327   }
1328
1329   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1330     AliError(Form("the following detectors were not found: %s",
1331                   detStr.Data()));
1332     if (fStopOnError) return kFALSE;
1333   }
1334   eventNr++;
1335   return kTRUE;
1336 }
1337
1338 //_____________________________________________________________________________
1339 Bool_t AliReconstruction::RunVertexFinder(AliESDEvent*& esd)
1340 {
1341 // run the barrel tracking
1342
1343   AliCodeTimerAuto("")
1344
1345   AliESDVertex* vertex = NULL;
1346   Double_t vtxPos[3] = {0, 0, 0};
1347   Double_t vtxErr[3] = {0.07, 0.07, 0.1};
1348   TArrayF mcVertex(3); 
1349   if (fRunLoader->GetHeader() && fRunLoader->GetHeader()->GenEventHeader()) {
1350     fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(mcVertex);
1351     for (Int_t i = 0; i < 3; i++) vtxPos[i] = mcVertex[i];
1352   }
1353
1354   if (fVertexer) {
1355     if(fDiamondProfile) fVertexer->SetVtxStart(fDiamondProfile);
1356     AliInfo("running the ITS vertex finder");
1357     if (fLoader[0]) fLoader[0]->LoadRecPoints();
1358     vertex = fVertexer->FindVertexForCurrentEvent(fRunLoader->GetEventNumber());
1359     if (fLoader[0]) fLoader[0]->UnloadRecPoints();
1360     if(!vertex){
1361       AliWarning("Vertex not found");
1362       vertex = new AliESDVertex();
1363       vertex->SetName("default");
1364     }
1365     else {
1366       vertex->SetName("reconstructed");
1367     }
1368
1369   } else {
1370     AliInfo("getting the primary vertex from MC");
1371     vertex = new AliESDVertex(vtxPos, vtxErr);
1372   }
1373
1374   if (vertex) {
1375     vertex->GetXYZ(vtxPos);
1376     vertex->GetSigmaXYZ(vtxErr);
1377   } else {
1378     AliWarning("no vertex reconstructed");
1379     vertex = new AliESDVertex(vtxPos, vtxErr);
1380   }
1381   esd->SetPrimaryVertexSPD(vertex);
1382   // if SPD multiplicity has been determined, it is stored in the ESD
1383   AliMultiplicity *mult = fVertexer->GetMultiplicity();
1384   if(mult)esd->SetMultiplicity(mult);
1385
1386   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1387     if (fTracker[iDet]) fTracker[iDet]->SetVertex(vtxPos, vtxErr);
1388   }  
1389   delete vertex;
1390
1391   return kTRUE;
1392 }
1393
1394 //_____________________________________________________________________________
1395 Bool_t AliReconstruction::RunHLTTracking(AliESDEvent*& esd)
1396 {
1397 // run the HLT barrel tracking
1398
1399   AliCodeTimerAuto("")
1400
1401   if (!fRunLoader) {
1402     AliError("Missing runLoader!");
1403     return kFALSE;
1404   }
1405
1406   AliInfo("running HLT tracking");
1407
1408   // Get a pointer to the HLT reconstructor
1409   AliReconstructor *reconstructor = GetReconstructor(fgkNDetectors-1);
1410   if (!reconstructor) return kFALSE;
1411
1412   // TPC + ITS
1413   for (Int_t iDet = 1; iDet >= 0; iDet--) {
1414     TString detName = fgkDetectorName[iDet];
1415     AliDebug(1, Form("%s HLT tracking", detName.Data()));
1416     reconstructor->SetOption(detName.Data());
1417     AliTracker *tracker = reconstructor->CreateTracker();
1418     if (!tracker) {
1419       AliWarning(Form("couldn't create a HLT tracker for %s", detName.Data()));
1420       if (fStopOnError) return kFALSE;
1421       continue;
1422     }
1423     Double_t vtxPos[3];
1424     Double_t vtxErr[3]={0.005,0.005,0.010};
1425     const AliESDVertex *vertex = esd->GetVertex();
1426     vertex->GetXYZ(vtxPos);
1427     tracker->SetVertex(vtxPos,vtxErr);
1428     if(iDet != 1) {
1429       fLoader[iDet]->LoadRecPoints("read");
1430       TTree* tree = fLoader[iDet]->TreeR();
1431       if (!tree) {
1432         AliError(Form("Can't get the %s cluster tree", detName.Data()));
1433         return kFALSE;
1434       }
1435       tracker->LoadClusters(tree);
1436     }
1437     if (tracker->Clusters2Tracks(esd) != 0) {
1438       AliError(Form("HLT %s Clusters2Tracks failed", fgkDetectorName[iDet]));
1439       return kFALSE;
1440     }
1441     if(iDet != 1) {
1442       tracker->UnloadClusters();
1443     }
1444     delete tracker;
1445   }
1446
1447   return kTRUE;
1448 }
1449
1450 //_____________________________________________________________________________
1451 Bool_t AliReconstruction::RunMuonTracking(AliESDEvent*& esd)
1452 {
1453 // run the muon spectrometer tracking
1454
1455   AliCodeTimerAuto("")
1456
1457   if (!fRunLoader) {
1458     AliError("Missing runLoader!");
1459     return kFALSE;
1460   }
1461   Int_t iDet = 7; // for MUON
1462
1463   AliInfo("is running...");
1464
1465   // Get a pointer to the MUON reconstructor
1466   AliReconstructor *reconstructor = GetReconstructor(iDet);
1467   if (!reconstructor) return kFALSE;
1468
1469   
1470   TString detName = fgkDetectorName[iDet];
1471   AliDebug(1, Form("%s tracking", detName.Data()));
1472   AliTracker *tracker =  reconstructor->CreateTracker();
1473   if (!tracker) {
1474     AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
1475     return kFALSE;
1476   }
1477      
1478   // read RecPoints
1479   fLoader[iDet]->LoadRecPoints("read");  
1480
1481   tracker->LoadClusters(fLoader[iDet]->TreeR());
1482   
1483   Int_t rv = tracker->Clusters2Tracks(esd);
1484   
1485   if ( rv )
1486   {
1487     AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
1488     return kFALSE;
1489   }
1490   
1491   fLoader[iDet]->UnloadRecPoints();
1492
1493   tracker->UnloadClusters();
1494   
1495   delete tracker;
1496   
1497   return kTRUE;
1498 }
1499
1500
1501 //_____________________________________________________________________________
1502 Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd)
1503 {
1504 // run the barrel tracking
1505   static Int_t eventNr=0;
1506   AliCodeTimerAuto("")
1507
1508   AliInfo("running tracking");
1509
1510   //Fill the ESD with the T0 info (will be used by the TOF) 
1511   if (fReconstructor[11] && fLoader[11]) {
1512     fLoader[11]->LoadRecPoints("READ");
1513     TTree *treeR = fLoader[11]->TreeR();
1514     GetReconstructor(11)->FillESD((TTree *)NULL,treeR,esd);
1515   }
1516
1517   // pass 1: TPC + ITS inwards
1518   for (Int_t iDet = 1; iDet >= 0; iDet--) {
1519     if (!fTracker[iDet]) continue;
1520     AliDebug(1, Form("%s tracking", fgkDetectorName[iDet]));
1521
1522     // load clusters
1523     fLoader[iDet]->LoadRecPoints("read");
1524     AliSysInfo::AddStamp(Form("RLoadCluster%s_%d",fgkDetectorName[iDet],eventNr),iDet,1, eventNr);
1525     TTree* tree = fLoader[iDet]->TreeR();
1526     if (!tree) {
1527       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
1528       return kFALSE;
1529     }
1530     fTracker[iDet]->LoadClusters(tree);
1531     AliSysInfo::AddStamp(Form("TLoadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
1532     // run tracking
1533     if (fTracker[iDet]->Clusters2Tracks(esd) != 0) {
1534       AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
1535       return kFALSE;
1536     }
1537     if (fCheckPointLevel > 1) {
1538       WriteESD(esd, Form("%s.tracking", fgkDetectorName[iDet]));
1539     }
1540     // preliminary PID in TPC needed by the ITS tracker
1541     if (iDet == 1) {
1542       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
1543       AliESDpid::MakePID(esd);
1544     } 
1545     AliSysInfo::AddStamp(Form("Tracking0%s_%d",fgkDetectorName[iDet],eventNr), iDet,3,eventNr);
1546   }
1547
1548   // pass 2: ALL backwards
1549
1550   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1551     if (!fTracker[iDet]) continue;
1552     AliDebug(1, Form("%s back propagation", fgkDetectorName[iDet]));
1553
1554     // load clusters
1555     if (iDet > 1) {     // all except ITS, TPC
1556       TTree* tree = NULL;
1557       fLoader[iDet]->LoadRecPoints("read");
1558       AliSysInfo::AddStamp(Form("RLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,1, eventNr);
1559       tree = fLoader[iDet]->TreeR();
1560       if (!tree) {
1561         AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
1562         return kFALSE;
1563       }
1564       fTracker[iDet]->LoadClusters(tree); 
1565       AliSysInfo::AddStamp(Form("TLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
1566     }
1567
1568     // run tracking
1569     if (fTracker[iDet]->PropagateBack(esd) != 0) {
1570       AliError(Form("%s backward propagation failed", fgkDetectorName[iDet]));
1571       //      return kFALSE;
1572     }
1573     if (fCheckPointLevel > 1) {
1574       WriteESD(esd, Form("%s.back", fgkDetectorName[iDet]));
1575     }
1576
1577     // unload clusters
1578     if (iDet > 2) {     // all except ITS, TPC, TRD
1579       fTracker[iDet]->UnloadClusters();
1580       fLoader[iDet]->UnloadRecPoints();
1581     }
1582     // updated PID in TPC needed by the ITS tracker -MI
1583     if (iDet == 1) {
1584       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
1585       AliESDpid::MakePID(esd);
1586     }
1587     AliSysInfo::AddStamp(Form("Tracking1%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
1588   }
1589
1590   // write space-points to the ESD in case alignment data output
1591   // is switched on
1592   if (fWriteAlignmentData)
1593     WriteAlignmentData(esd);
1594
1595   // pass 3: TRD + TPC + ITS refit inwards
1596
1597   if (fRunGlobalQA) AliTracker::SetFillResiduals(kTRUE);     
1598
1599   for (Int_t iDet = 2; iDet >= 0; iDet--) {
1600     if (!fTracker[iDet]) continue;
1601     AliDebug(1, Form("%s inward refit", fgkDetectorName[iDet]));
1602
1603     // run tracking
1604     if (fTracker[iDet]->RefitInward(esd) != 0) {
1605       AliError(Form("%s inward refit failed", fgkDetectorName[iDet]));
1606       //      return kFALSE;
1607     }
1608     // run postprocessing
1609     if (fTracker[iDet]->PostProcess(esd) != 0) {
1610       AliError(Form("%s postprocessing failed", fgkDetectorName[iDet]));
1611       //      return kFALSE;
1612     }
1613     if (fCheckPointLevel > 1) {
1614       WriteESD(esd, Form("%s.refit", fgkDetectorName[iDet]));
1615     }
1616     AliSysInfo::AddStamp(Form("Tracking2%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
1617     // unload clusters
1618     fTracker[iDet]->UnloadClusters();
1619     AliSysInfo::AddStamp(Form("TUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,4, eventNr);
1620     fLoader[iDet]->UnloadRecPoints();
1621     AliSysInfo::AddStamp(Form("RUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,5, eventNr);
1622   }
1623
1624   if (fRunGlobalQA) AliTracker::SetFillResiduals(kFALSE);     
1625
1626   eventNr++;
1627   return kTRUE;
1628 }
1629
1630 //_____________________________________________________________________________
1631 Bool_t AliReconstruction::CleanESD(AliESDEvent *esd){
1632   //
1633   // Remove the data which are not needed for the physics analysis.
1634   //
1635
1636   Int_t nTracks=esd->GetNumberOfTracks();
1637   Int_t nV0s=esd->GetNumberOfV0s();
1638   AliInfo
1639   (Form("Number of ESD tracks and V0s before cleaning: %d %d",nTracks,nV0s));
1640
1641   Float_t cleanPars[]={fV0DCAmax,fV0CsPmin,fDmax,fZmax};
1642   Bool_t rc=esd->Clean(cleanPars);
1643
1644   nTracks=esd->GetNumberOfTracks();
1645   nV0s=esd->GetNumberOfV0s();
1646   AliInfo
1647   (Form("Number of ESD tracks and V0s after cleaning %d %d",nTracks,nV0s));
1648
1649   return rc;
1650 }
1651
1652 //_____________________________________________________________________________
1653 Bool_t AliReconstruction::FillESD(AliESDEvent*& esd, const TString& detectors)
1654 {
1655 // fill the event summary data
1656
1657   AliCodeTimerAuto("")
1658     static Int_t eventNr=0; 
1659   TString detStr = detectors;
1660   
1661   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1662   if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
1663     AliReconstructor* reconstructor = GetReconstructor(iDet);
1664     if (!reconstructor) continue;
1665     if (!ReadESD(esd, fgkDetectorName[iDet])) {
1666       AliDebug(1, Form("filling ESD for %s", fgkDetectorName[iDet]));
1667       TTree* clustersTree = NULL;
1668       if (fLoader[iDet]) {
1669         fLoader[iDet]->LoadRecPoints("read");
1670         clustersTree = fLoader[iDet]->TreeR();
1671         if (!clustersTree) {
1672           AliError(Form("Can't get the %s clusters tree", 
1673                         fgkDetectorName[iDet]));
1674           if (fStopOnError) return kFALSE;
1675         }
1676       }
1677       if (fRawReader && !reconstructor->HasDigitConversion()) {
1678         reconstructor->FillESD(fRawReader, clustersTree, esd);
1679       } else {
1680         TTree* digitsTree = NULL;
1681         if (fLoader[iDet]) {
1682           fLoader[iDet]->LoadDigits("read");
1683           digitsTree = fLoader[iDet]->TreeD();
1684           if (!digitsTree) {
1685             AliError(Form("Can't get the %s digits tree", 
1686                           fgkDetectorName[iDet]));
1687             if (fStopOnError) return kFALSE;
1688           }
1689         }
1690         reconstructor->FillESD(digitsTree, clustersTree, esd);
1691         if (fLoader[iDet]) fLoader[iDet]->UnloadDigits();
1692       }
1693       if (fLoader[iDet]) {
1694         fLoader[iDet]->UnloadRecPoints();
1695       }
1696
1697       if (fCheckPointLevel > 2) WriteESD(esd, fgkDetectorName[iDet]);
1698     }
1699   }
1700
1701   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1702     AliError(Form("the following detectors were not found: %s", 
1703                   detStr.Data()));
1704     if (fStopOnError) return kFALSE;
1705   }
1706   AliSysInfo::AddStamp(Form("FillESD%d",eventNr), 0,1, eventNr);
1707   eventNr++;
1708   return kTRUE;
1709 }
1710
1711 //_____________________________________________________________________________
1712 Bool_t AliReconstruction::FillTriggerESD(AliESDEvent*& esd)
1713 {
1714   // Reads the trigger decision which is
1715   // stored in Trigger.root file and fills
1716   // the corresponding esd entries
1717
1718   AliCodeTimerAuto("")
1719   
1720   AliInfo("Filling trigger information into the ESD");
1721
1722   AliCentralTrigger *aCTP = NULL;
1723
1724   if (fRawReader) {
1725     AliCTPRawStream input(fRawReader);
1726     if (!input.Next()) {
1727       AliError("No valid CTP (trigger) DDL raw data is found ! The trigger information is not stored in the ESD !");
1728       return kFALSE;
1729     }
1730     esd->SetTriggerMask(input.GetClassMask());
1731     esd->SetTriggerCluster(input.GetClusterMask());
1732
1733     aCTP = new AliCentralTrigger();
1734     TString configstr("");
1735     if (!aCTP->LoadConfiguration(configstr)) { // Load CTP config from OCDB
1736       AliError("No trigger configuration found in OCDB! The trigger classes information will no be stored in ESD!");
1737       return kFALSE;
1738     }
1739   }
1740   else {
1741     AliRunLoader *runloader = AliRunLoader::GetRunLoader();
1742     if (runloader) {
1743       if (!runloader->LoadTrigger()) {
1744         aCTP = runloader->GetTrigger();
1745         esd->SetTriggerMask(aCTP->GetClassMask());
1746         esd->SetTriggerCluster(aCTP->GetClusterMask());
1747       }
1748       else {
1749         AliWarning("No trigger can be loaded! The trigger information is not stored in the ESD !");
1750         return kFALSE;
1751       }
1752     }
1753     else {
1754       AliError("No run loader is available! The trigger information is not stored in the ESD !");
1755       return kFALSE;
1756     }
1757   }
1758
1759   // Now fill the trigger class names into AliESDRun object
1760   AliTriggerConfiguration *config = aCTP->GetConfiguration();
1761   if (!config) {
1762     AliError("No trigger configuration has been found! The trigger classes information will no be stored in ESD!");
1763     return kFALSE;
1764   }
1765
1766   const TObjArray& classesArray = config->GetClasses();
1767   Int_t nclasses = classesArray.GetEntriesFast();
1768   for( Int_t j=0; j<nclasses; j++ ) {
1769     AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At( j );
1770     Int_t trindex = (Int_t)TMath::Log2(trclass->GetMask());
1771     esd->SetTriggerClass(trclass->GetName(),trindex);
1772   }
1773
1774   return kTRUE;
1775 }
1776
1777
1778
1779
1780
1781 //_____________________________________________________________________________
1782 Bool_t AliReconstruction::FillRawEventHeaderESD(AliESDEvent*& esd)
1783 {
1784   // 
1785   // Filling information from RawReader Header
1786   // 
1787
1788   AliInfo("Filling information from RawReader Header");
1789   esd->SetBunchCrossNumber(0);
1790   esd->SetOrbitNumber(0);
1791   esd->SetPeriodNumber(0);
1792   esd->SetTimeStamp(0);
1793   esd->SetEventType(0);
1794   const AliRawEventHeaderBase * eventHeader = fRawReader->GetEventHeader();
1795   if (eventHeader){
1796
1797     const UInt_t *id = eventHeader->GetP("Id");
1798     esd->SetBunchCrossNumber((id)[1]&0x00000fff);
1799     esd->SetOrbitNumber((((id)[0]<<20)&0xf00000)|(((id)[1]>>12)&0xfffff));
1800     esd->SetPeriodNumber(((id)[0]>>4)&0x0fffffff);
1801
1802     esd->SetTimeStamp((eventHeader->Get("Timestamp")));  
1803     esd->SetEventType((eventHeader->Get("Type")));
1804   }
1805
1806   return kTRUE;
1807 }
1808
1809
1810 //_____________________________________________________________________________
1811 Bool_t AliReconstruction::IsSelected(TString detName, TString& detectors) const
1812 {
1813 // check whether detName is contained in detectors
1814 // if yes, it is removed from detectors
1815
1816   // check if all detectors are selected
1817   if ((detectors.CompareTo("ALL") == 0) ||
1818       detectors.BeginsWith("ALL ") ||
1819       detectors.EndsWith(" ALL") ||
1820       detectors.Contains(" ALL ")) {
1821     detectors = "ALL";
1822     return kTRUE;
1823   }
1824
1825   // search for the given detector
1826   Bool_t result = kFALSE;
1827   if ((detectors.CompareTo(detName) == 0) ||
1828       detectors.BeginsWith(detName+" ") ||
1829       detectors.EndsWith(" "+detName) ||
1830       detectors.Contains(" "+detName+" ")) {
1831     detectors.ReplaceAll(detName, "");
1832     result = kTRUE;
1833   }
1834
1835   // clean up the detectors string
1836   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
1837   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
1838   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
1839
1840   return result;
1841 }
1842
1843 //_____________________________________________________________________________
1844 Bool_t AliReconstruction::InitRunLoader()
1845 {
1846 // get or create the run loader
1847
1848   if (gAlice) delete gAlice;
1849   gAlice = NULL;
1850
1851   if (!gSystem->AccessPathName(fGAliceFileName.Data())) { // galice.root exists
1852     // load all base libraries to get the loader classes
1853     TString libs = gSystem->GetLibraries();
1854     for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
1855       TString detName = fgkDetectorName[iDet];
1856       if (detName == "HLT") continue;
1857       if (libs.Contains("lib" + detName + "base.so")) continue;
1858       gSystem->Load("lib" + detName + "base.so");
1859     }
1860     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data());
1861     if (!fRunLoader) {
1862       AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
1863       CleanUp();
1864       return kFALSE;
1865     }
1866     fRunLoader->CdGAFile();
1867     if (gFile->GetKey(AliRunLoader::GetGAliceName())) {
1868       if (fRunLoader->LoadgAlice() == 0) {
1869         gAlice = fRunLoader->GetAliRun();
1870         AliTracker::SetFieldMap(gAlice->Field(),fUniformField);
1871       }
1872     }
1873     if (!gAlice && !fRawReader) {
1874       AliError(Form("no gAlice object found in file %s",
1875                     fGAliceFileName.Data()));
1876       CleanUp();
1877       return kFALSE;
1878     }
1879
1880     //PH This is a temporary fix to give access to the kinematics
1881     //PH that is needed for the labels of ITS clusters
1882     fRunLoader->LoadHeader();
1883     fRunLoader->LoadKinematics();
1884
1885   } else {               // galice.root does not exist
1886     if (!fRawReader) {
1887       AliError(Form("the file %s does not exist", fGAliceFileName.Data()));
1888       CleanUp();
1889       return kFALSE;
1890     }
1891     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data(),
1892                                     AliConfig::GetDefaultEventFolderName(),
1893                                     "recreate");
1894     if (!fRunLoader) {
1895       AliError(Form("could not create run loader in file %s", 
1896                     fGAliceFileName.Data()));
1897       CleanUp();
1898       return kFALSE;
1899     }
1900     fRunLoader->MakeTree("E");
1901     Int_t iEvent = 0;
1902     while (fRawReader->NextEvent()) {
1903       fRunLoader->SetEventNumber(iEvent);
1904       fRunLoader->GetHeader()->Reset(fRawReader->GetRunNumber(), 
1905                                      iEvent, iEvent);
1906       fRunLoader->MakeTree("H");
1907       fRunLoader->TreeE()->Fill();
1908       iEvent++;
1909     }
1910     fRawReader->RewindEvents();
1911     if (fNumberOfEventsPerFile > 0)
1912       fRunLoader->SetNumberOfEventsPerFile(fNumberOfEventsPerFile);
1913     else
1914       fRunLoader->SetNumberOfEventsPerFile(iEvent);
1915     fRunLoader->WriteHeader("OVERWRITE");
1916     fRunLoader->CdGAFile();
1917     fRunLoader->Write(0, TObject::kOverwrite);
1918 //    AliTracker::SetFieldMap(???);
1919   }
1920
1921   return kTRUE;
1922 }
1923
1924 //_____________________________________________________________________________
1925 AliReconstructor* AliReconstruction::GetReconstructor(Int_t iDet)
1926 {
1927 // get the reconstructor object and the loader for a detector
1928
1929   if (fReconstructor[iDet]) return fReconstructor[iDet];
1930
1931   // load the reconstructor object
1932   TPluginManager* pluginManager = gROOT->GetPluginManager();
1933   TString detName = fgkDetectorName[iDet];
1934   TString recName = "Ali" + detName + "Reconstructor";
1935   if (gAlice && !gAlice->GetDetector(detName) && (detName != "HLT")) return NULL;
1936
1937   AliReconstructor* reconstructor = NULL;
1938   // first check if a plugin is defined for the reconstructor
1939   TPluginHandler* pluginHandler = 
1940     pluginManager->FindHandler("AliReconstructor", detName);
1941   // if not, add a plugin for it
1942   if (!pluginHandler) {
1943     AliDebug(1, Form("defining plugin for %s", recName.Data()));
1944     TString libs = gSystem->GetLibraries();
1945     if (libs.Contains("lib" + detName + "base.so") ||
1946         (gSystem->Load("lib" + detName + "base.so") >= 0)) {
1947       pluginManager->AddHandler("AliReconstructor", detName, 
1948                                 recName, detName + "rec", recName + "()");
1949     } else {
1950       pluginManager->AddHandler("AliReconstructor", detName, 
1951                                 recName, detName, recName + "()");
1952     }
1953     pluginHandler = pluginManager->FindHandler("AliReconstructor", detName);
1954   }
1955   if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
1956     reconstructor = (AliReconstructor*) pluginHandler->ExecPlugin(0);
1957   }
1958   if (reconstructor) {
1959     TObject* obj = fOptions.FindObject(detName.Data());
1960     if (obj) reconstructor->SetOption(obj->GetTitle());
1961     reconstructor->Init();
1962     fReconstructor[iDet] = reconstructor;
1963   }
1964
1965   // get or create the loader
1966   if (detName != "HLT") {
1967     fLoader[iDet] = fRunLoader->GetLoader(detName + "Loader");
1968     if (!fLoader[iDet]) {
1969       AliConfig::Instance()
1970         ->CreateDetectorFolders(fRunLoader->GetEventFolder(), 
1971                                 detName, detName);
1972       // first check if a plugin is defined for the loader
1973       pluginHandler = 
1974         pluginManager->FindHandler("AliLoader", detName);
1975       // if not, add a plugin for it
1976       if (!pluginHandler) {
1977         TString loaderName = "Ali" + detName + "Loader";
1978         AliDebug(1, Form("defining plugin for %s", loaderName.Data()));
1979         pluginManager->AddHandler("AliLoader", detName, 
1980                                   loaderName, detName + "base", 
1981                                   loaderName + "(const char*, TFolder*)");
1982         pluginHandler = pluginManager->FindHandler("AliLoader", detName);
1983       }
1984       if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
1985         fLoader[iDet] = 
1986           (AliLoader*) pluginHandler->ExecPlugin(2, detName.Data(), 
1987                                                  fRunLoader->GetEventFolder());
1988       }
1989       if (!fLoader[iDet]) {   // use default loader
1990         fLoader[iDet] = new AliLoader(detName, fRunLoader->GetEventFolder());
1991       }
1992       if (!fLoader[iDet]) {
1993         AliWarning(Form("couldn't get loader for %s", detName.Data()));
1994         if (fStopOnError) return NULL;
1995       } else {
1996         fRunLoader->AddLoader(fLoader[iDet]);
1997         fRunLoader->CdGAFile();
1998         if (gFile && !gFile->IsWritable()) gFile->ReOpen("UPDATE");
1999         fRunLoader->Write(0, TObject::kOverwrite);
2000       }
2001     }
2002   }
2003       
2004   return reconstructor;
2005 }
2006
2007 //_____________________________________________________________________________
2008 Bool_t AliReconstruction::CreateVertexer()
2009 {
2010 // create the vertexer
2011
2012   fVertexer = NULL;
2013   AliReconstructor* itsReconstructor = GetReconstructor(0);
2014   if (itsReconstructor) {
2015     fVertexer = itsReconstructor->CreateVertexer();
2016   }
2017   if (!fVertexer) {
2018     AliWarning("couldn't create a vertexer for ITS");
2019     if (fStopOnError) return kFALSE;
2020   }
2021
2022   return kTRUE;
2023 }
2024
2025 //_____________________________________________________________________________
2026 Bool_t AliReconstruction::CreateTrackers(const TString& detectors)
2027 {
2028 // create the trackers
2029
2030   TString detStr = detectors;
2031   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
2032     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
2033     AliReconstructor* reconstructor = GetReconstructor(iDet);
2034     if (!reconstructor) continue;
2035     TString detName = fgkDetectorName[iDet];
2036     if (detName == "HLT") {
2037       fRunHLTTracking = kTRUE;
2038       continue;
2039     }
2040     if (detName == "MUON") {
2041       fRunMuonTracking = kTRUE;
2042       continue;
2043     }
2044
2045
2046     fTracker[iDet] = reconstructor->CreateTracker();
2047     if (!fTracker[iDet] && (iDet < 7)) {
2048       AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
2049       if (fStopOnError) return kFALSE;
2050     }
2051     AliSysInfo::AddStamp(Form("LTracker%s",fgkDetectorName[iDet]), iDet,0);
2052   }
2053
2054   return kTRUE;
2055 }
2056
2057 //_____________________________________________________________________________
2058 void AliReconstruction::CleanUp(TFile* file, TFile* fileOld)
2059 {
2060 // delete trackers and the run loader and close and delete the file
2061
2062   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
2063     delete fReconstructor[iDet];
2064     fReconstructor[iDet] = NULL;
2065     fLoader[iDet] = NULL;
2066     delete fTracker[iDet];
2067     fTracker[iDet] = NULL;
2068 //    delete fQADataMaker[iDet];
2069 //    fQADataMaker[iDet] = NULL;
2070   }
2071   delete fVertexer;
2072   fVertexer = NULL;
2073   
2074   if(!(AliCDBManager::Instance()->GetCacheFlag())) {
2075         delete fDiamondProfile;
2076         fDiamondProfile = NULL;
2077   }
2078
2079   delete fGRPList;
2080   fGRPList = NULL;
2081
2082   delete fRunLoader;
2083   fRunLoader = NULL;
2084   delete fRawReader;
2085   fRawReader = NULL;
2086   if (fParentRawReader) delete fParentRawReader;
2087   fParentRawReader=NULL;
2088
2089   if (file) {
2090     file->Close();
2091     delete file;
2092   }
2093
2094   if (fileOld) {
2095     fileOld->Close();
2096     delete fileOld;
2097     gSystem->Unlink("AliESDs.old.root");
2098   }
2099 }
2100
2101 //_____________________________________________________________________________
2102
2103 Bool_t AliReconstruction::ReadESD(AliESDEvent*& esd, const char* recStep) const
2104 {
2105 // read the ESD event from a file
2106
2107   if (!esd) return kFALSE;
2108   char fileName[256];
2109   sprintf(fileName, "ESD_%d.%d_%s.root", 
2110           esd->GetRunNumber(), esd->GetEventNumberInFile(), recStep);
2111   if (gSystem->AccessPathName(fileName)) return kFALSE;
2112
2113   AliInfo(Form("reading ESD from file %s", fileName));
2114   AliDebug(1, Form("reading ESD from file %s", fileName));
2115   TFile* file = TFile::Open(fileName);
2116   if (!file || !file->IsOpen()) {
2117     AliError(Form("opening %s failed", fileName));
2118     delete file;
2119     return kFALSE;
2120   }
2121
2122   gROOT->cd();
2123   delete esd;
2124   esd = (AliESDEvent*) file->Get("ESD");
2125   file->Close();
2126   delete file;
2127   return kTRUE;
2128
2129 }
2130
2131
2132
2133 //_____________________________________________________________________________
2134 void AliReconstruction::WriteESD(AliESDEvent* esd, const char* recStep) const
2135 {
2136 // write the ESD event to a file
2137
2138   if (!esd) return;
2139   char fileName[256];
2140   sprintf(fileName, "ESD_%d.%d_%s.root", 
2141           esd->GetRunNumber(), esd->GetEventNumberInFile(), recStep);
2142
2143   AliDebug(1, Form("writing ESD to file %s", fileName));
2144   TFile* file = TFile::Open(fileName, "recreate");
2145   if (!file || !file->IsOpen()) {
2146     AliError(Form("opening %s failed", fileName));
2147   } else {
2148     esd->Write("ESD");
2149     file->Close();
2150   }
2151   delete file;
2152 }
2153
2154
2155
2156
2157
2158 //_____________________________________________________________________________
2159 void AliReconstruction::ESDFile2AODFile(TFile* esdFile, TFile* aodFile)
2160 {
2161   // write all files from the given esd file to an aod file
2162
2163   // create an AliAOD object 
2164   AliAODEvent *aod = new AliAODEvent();
2165   aod->CreateStdContent();
2166   
2167   // go to the file
2168   aodFile->cd();
2169   
2170   // create the tree
2171   TTree *aodTree = new TTree("aodTree", "AliAOD tree");
2172   aodTree->Branch(aod->GetList());
2173
2174   // connect to ESD
2175   TTree *t = (TTree*) esdFile->Get("esdTree");
2176   AliESDEvent *esd = new AliESDEvent();
2177   esd->ReadFromTree(t);
2178
2179   Int_t nEvents = t->GetEntries();
2180
2181   // set arrays and pointers
2182   Float_t posF[3];
2183   Double_t pos[3];
2184   Double_t p[3];
2185   Double_t p_pos[3];
2186   Double_t p_neg[3];
2187   Double_t covVtx[6];
2188   Double_t covTr[21];
2189   Double_t pid[10];
2190
2191   // loop over events and fill them
2192   for (Int_t iEvent = 0; iEvent < nEvents; ++iEvent) {
2193     //cout << "event: " << iEvent << endl;
2194     t->GetEntry(iEvent);
2195
2196     // Multiplicity information needed by the header (to be revised!)
2197     Int_t nTracks   = esd->GetNumberOfTracks();
2198     Int_t nPosTracks = 0;
2199     for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) 
2200       if (esd->GetTrack(iTrack)->Charge()> 0) nPosTracks++;
2201
2202     // Access the header
2203     AliAODHeader *header = aod->GetHeader();
2204
2205     // fill the header
2206     header->SetRunNumber       (esd->GetRunNumber()       );
2207     header->SetBunchCrossNumber(esd->GetBunchCrossNumber());
2208     header->SetOrbitNumber     (esd->GetOrbitNumber()     );
2209     header->SetPeriodNumber    (esd->GetPeriodNumber()    );
2210     header->SetTriggerMask     (esd->GetTriggerMask()     ); 
2211     header->SetTriggerCluster  (esd->GetTriggerCluster()  );
2212     header->SetEventType       (esd->GetEventType()       );
2213     header->SetMagneticField   (esd->GetMagneticField()   );
2214     header->SetZDCN1Energy     (esd->GetZDCN1Energy()     );
2215     header->SetZDCP1Energy     (esd->GetZDCP1Energy()     );
2216     header->SetZDCN2Energy     (esd->GetZDCN2Energy()     );
2217     header->SetZDCP2Energy     (esd->GetZDCP2Energy()     );
2218     header->SetZDCEMEnergy     (esd->GetZDCEMEnergy(0),esd->GetZDCEMEnergy(1));
2219     header->SetRefMultiplicity   (nTracks);
2220     header->SetRefMultiplicityPos(nPosTracks);
2221     header->SetRefMultiplicityNeg(nTracks - nPosTracks);
2222     header->SetMuonMagFieldScale(-999.); // FIXME
2223     header->SetCentrality(-999.);        // FIXME
2224
2225     Int_t nV0s      = esd->GetNumberOfV0s();
2226     Int_t nCascades = esd->GetNumberOfCascades();
2227     Int_t nKinks    = esd->GetNumberOfKinks();
2228         Int_t nVertices = nV0s + 2*nCascades /*could lead to two vertices, one V0 and the Xi */+ nKinks + 1 /* = prim. vtx*/;    
2229         Int_t nJets     = 0;
2230     Int_t nCaloClus = esd->GetNumberOfCaloClusters();
2231     Int_t nFmdClus  = 0;
2232     Int_t nPmdClus  = esd->GetNumberOfPmdTracks();
2233    
2234     aod->ResetStd(nTracks, nVertices, nV0s+nCascades, nJets, nCaloClus, nFmdClus, nPmdClus);
2235     
2236     // Array to take into account the tracks already added to the AOD
2237     Bool_t * usedTrack = NULL;
2238     if (nTracks>0) {
2239       usedTrack = new Bool_t[nTracks];
2240       for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) usedTrack[iTrack]=kFALSE;
2241     }
2242     // Array to take into account the V0s already added to the AOD
2243     Bool_t * usedV0 = NULL;
2244     if (nV0s>0) {
2245       usedV0 = new Bool_t[nV0s];
2246       for (Int_t iV0=0; iV0<nV0s; ++iV0) usedV0[iV0]=kFALSE;
2247     }
2248     // Array to take into account the kinks already added to the AOD
2249     Bool_t * usedKink = NULL;
2250     if (nKinks>0) {
2251       usedKink = new Bool_t[nKinks];
2252       for (Int_t iKink=0; iKink<nKinks; ++iKink) usedKink[iKink]=kFALSE;
2253     }
2254     
2255     // Access to the AOD container of vertices
2256     TClonesArray &vertices = *(aod->GetVertices());
2257     Int_t jVertices=0;
2258
2259     // Access to the AOD container of tracks
2260     TClonesArray &tracks = *(aod->GetTracks());
2261     Int_t jTracks=0; 
2262    
2263     // Access to the AOD container of V0s
2264     TClonesArray &V0s = *(aod->GetV0s());
2265     Int_t jV0s=0;
2266     
2267     // Add primary vertex. The primary tracks will be defined
2268     // after the loops on the composite objects (V0, cascades, kinks)
2269     const AliESDVertex *vtx = esd->GetPrimaryVertex();
2270       
2271     vtx->GetXYZ(pos); // position
2272     vtx->GetCovMatrix(covVtx); //covariance matrix
2273
2274     AliAODVertex * primary = new(vertices[jVertices++])
2275       AliAODVertex(pos, covVtx, vtx->GetChi2toNDF(), NULL, -1, AliAODVertex::kPrimary);
2276          
2277
2278     AliAODTrack *aodTrack = 0x0;
2279     
2280     // Create vertices starting from the most complex objects
2281
2282     // Cascades
2283     for (Int_t nCascade = 0; nCascade < nCascades; ++nCascade) {
2284       AliESDcascade *cascade = esd->GetCascade(nCascade);
2285       
2286       cascade->GetXYZ(pos[0], pos[1], pos[2]);
2287       cascade->GetPosCovXi(covVtx);
2288      
2289       // Add the cascade vertex
2290       AliAODVertex * vcascade = new(vertices[jVertices++]) AliAODVertex(pos,
2291                                                                         covVtx,
2292                                                                         cascade->GetChi2Xi(), // = chi2/NDF since NDF = 2*2-3
2293                                                                         primary,
2294                                                                         nCascade,
2295                                                                         AliAODVertex::kCascade);
2296
2297       primary->AddDaughter(vcascade); // the cascade 'particle' (represented by a vertex) is added as a daughter to the primary vertex
2298
2299       // Add the V0 from the cascade. The ESD class have to be optimized...
2300       // Now we have to search for the corresponding V0 in the list of V0s
2301       // using the indeces of the positive and negative tracks
2302
2303       Int_t posFromV0 = cascade->GetPindex();
2304       Int_t negFromV0 = cascade->GetNindex();
2305
2306
2307       AliESDv0 * v0 = 0x0;
2308       Int_t indV0 = -1;
2309
2310       for (Int_t iV0=0; iV0<nV0s; ++iV0) {
2311
2312         v0 = esd->GetV0(iV0);
2313         Int_t posV0 = v0->GetPindex();
2314         Int_t negV0 = v0->GetNindex();
2315
2316         if (posV0==posFromV0 && negV0==negFromV0) {
2317           indV0 = iV0;
2318           break;
2319         }
2320       }
2321
2322       AliAODVertex * vV0FromCascade = 0x0;
2323
2324       if (indV0>-1 && !usedV0[indV0]) {
2325         
2326         // the V0 exists in the array of V0s and is not used
2327
2328         usedV0[indV0] = kTRUE;
2329         
2330         v0->GetXYZ(pos[0], pos[1], pos[2]);
2331         v0->GetPosCov(covVtx);
2332         
2333         vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
2334                                                                  covVtx,
2335                                                                  v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
2336                                                                  vcascade,
2337                                                                  indV0,
2338                                                                  AliAODVertex::kV0);
2339       } else {
2340
2341         // the V0 doesn't exist in the array of V0s or was used
2342         cerr << "Error: event " << iEvent << " cascade " << nCascade
2343              << " The V0 " << indV0 
2344              << " doesn't exist in the array of V0s or was used!" << endl;
2345
2346         cascade->GetXYZ(pos[0], pos[1], pos[2]);
2347         cascade->GetPosCov(covVtx);
2348       
2349         vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
2350                                                                  covVtx,
2351                                                                  v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
2352                                                                  vcascade,
2353                                                                  indV0,
2354                                                                  AliAODVertex::kV0);
2355         vcascade->AddDaughter(vV0FromCascade);
2356
2357       }
2358
2359       // Add the positive tracks from the V0
2360
2361       if (! usedTrack[posFromV0]) {
2362
2363         usedTrack[posFromV0] = kTRUE;
2364
2365         AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
2366         esdTrack->GetPxPyPz(p_pos);
2367         esdTrack->GetXYZ(pos);
2368         esdTrack->GetCovarianceXYZPxPyPz(covTr);
2369         esdTrack->GetESDpid(pid);
2370         
2371         vV0FromCascade->AddDaughter(aodTrack =
2372                                     new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2373                                            esdTrack->GetLabel(), 
2374                                            p_pos, 
2375                                            kTRUE,
2376                                            pos,
2377                                            kFALSE,
2378                                            covTr, 
2379                                            (Short_t)esdTrack->Charge(),
2380                                            esdTrack->GetITSClusterMap(), 
2381                                            pid,
2382                                            vV0FromCascade,
2383                                            kTRUE,  // check if this is right
2384                                            kFALSE, // check if this is right
2385                                            AliAODTrack::kSecondary)
2386                 );
2387         aodTrack->ConvertAliPIDtoAODPID();
2388       }
2389       else {
2390         cerr << "Error: event " << iEvent << " cascade " << nCascade
2391              << " track " << posFromV0 << " has already been used!" << endl;
2392       }
2393
2394       // Add the negative tracks from the V0
2395
2396       if (!usedTrack[negFromV0]) {
2397         
2398         usedTrack[negFromV0] = kTRUE;
2399         
2400         AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
2401         esdTrack->GetPxPyPz(p_neg);
2402         esdTrack->GetXYZ(pos);
2403         esdTrack->GetCovarianceXYZPxPyPz(covTr);
2404         esdTrack->GetESDpid(pid);
2405         
2406         vV0FromCascade->AddDaughter(aodTrack =
2407                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2408                                            esdTrack->GetLabel(),
2409                                            p_neg,
2410                                            kTRUE,
2411                                            pos,
2412                                            kFALSE,
2413                                            covTr, 
2414                                            (Short_t)esdTrack->Charge(),
2415                                            esdTrack->GetITSClusterMap(), 
2416                                            pid,
2417                                            vV0FromCascade,
2418                                            kTRUE,  // check if this is right
2419                                            kFALSE, // check if this is right
2420                                            AliAODTrack::kSecondary)
2421                 );
2422         aodTrack->ConvertAliPIDtoAODPID();
2423       }
2424       else {
2425         cerr << "Error: event " << iEvent << " cascade " << nCascade
2426              << " track " << negFromV0 << " has already been used!" << endl;
2427       }
2428
2429       // add it to the V0 array as well
2430       Double_t d0[2] = { -999., -99.};
2431       // counting is probably wrong
2432       new(V0s[jV0s++]) AliAODv0(vV0FromCascade, -999., -99., p_pos, p_neg, d0); // to be refined
2433
2434       // Add the bachelor track from the cascade
2435
2436       Int_t bachelor = cascade->GetBindex();
2437       
2438       if(!usedTrack[bachelor]) {
2439       
2440         usedTrack[bachelor] = kTRUE;
2441         
2442         AliESDtrack *esdTrack = esd->GetTrack(bachelor);
2443         esdTrack->GetPxPyPz(p);
2444         esdTrack->GetXYZ(pos);
2445         esdTrack->GetCovarianceXYZPxPyPz(covTr);
2446         esdTrack->GetESDpid(pid);
2447
2448         vcascade->AddDaughter(aodTrack =
2449                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2450                                            esdTrack->GetLabel(),
2451                                            p,
2452                                            kTRUE,
2453                                            pos,
2454                                            kFALSE,
2455                                            covTr, 
2456                                            (Short_t)esdTrack->Charge(),
2457                                            esdTrack->GetITSClusterMap(), 
2458                                            pid,
2459                                            vcascade,
2460                                            kTRUE,  // check if this is right
2461                                            kFALSE, // check if this is right
2462                                            AliAODTrack::kSecondary)
2463                 );
2464         aodTrack->ConvertAliPIDtoAODPID();
2465      }
2466       else {
2467         cerr << "Error: event " << iEvent << " cascade " << nCascade
2468              << " track " << bachelor << " has already been used!" << endl;
2469       }
2470       
2471       // Add the primary track of the cascade (if any)
2472       
2473     } // end of the loop on cascades
2474  
2475     // V0s
2476         
2477     for (Int_t nV0 = 0; nV0 < nV0s; ++nV0) {
2478
2479       if (usedV0[nV0]) continue; // skip if aready added to the AOD
2480
2481       AliESDv0 *v0 = esd->GetV0(nV0); 
2482      
2483       v0->GetXYZ(pos[0], pos[1], pos[2]);
2484       v0->GetPosCov(covVtx);
2485
2486       AliAODVertex * vV0 = 
2487         new(vertices[jVertices++]) AliAODVertex(pos,
2488                                                 covVtx,
2489                                                 v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
2490                                                 primary,
2491                                                 nV0,
2492                                                 AliAODVertex::kV0);
2493       primary->AddDaughter(vV0);
2494
2495       Int_t posFromV0 = v0->GetPindex();
2496       Int_t negFromV0 = v0->GetNindex();
2497       
2498       // Add the positive tracks from the V0
2499
2500       if (!usedTrack[posFromV0]) {
2501         
2502         usedTrack[posFromV0] = kTRUE;
2503
2504         AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
2505         esdTrack->GetPxPyPz(p_pos);
2506         esdTrack->GetXYZ(pos);
2507         esdTrack->GetCovarianceXYZPxPyPz(covTr);
2508         esdTrack->GetESDpid(pid);
2509         
2510         vV0->AddDaughter(aodTrack =
2511                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2512                                            esdTrack->GetLabel(), 
2513                                            p_pos, 
2514                                            kTRUE,
2515                                            pos,
2516                                            kFALSE,
2517                                            covTr, 
2518                                            (Short_t)esdTrack->Charge(),
2519                                            esdTrack->GetITSClusterMap(), 
2520                                            pid,
2521                                            vV0,
2522                                            kTRUE,  // check if this is right
2523                                            kFALSE, // check if this is right
2524                                            AliAODTrack::kSecondary)
2525                 );
2526         aodTrack->ConvertAliPIDtoAODPID();
2527       }
2528       else {
2529         cerr << "Error: event " << iEvent << " V0 " << nV0
2530              << " track " << posFromV0 << " has already been used!" << endl;
2531       }
2532
2533       // Add the negative tracks from the V0
2534
2535       if (!usedTrack[negFromV0]) {
2536
2537         usedTrack[negFromV0] = kTRUE;
2538
2539         AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
2540         esdTrack->GetPxPyPz(p_neg);
2541         esdTrack->GetXYZ(pos);
2542         esdTrack->GetCovarianceXYZPxPyPz(covTr);
2543         esdTrack->GetESDpid(pid);
2544
2545         vV0->AddDaughter(aodTrack =
2546                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2547                                            esdTrack->GetLabel(),
2548                                            p_neg,
2549                                            kTRUE,
2550                                            pos,
2551                                            kFALSE,
2552                                            covTr, 
2553                                            (Short_t)esdTrack->Charge(),
2554                                            esdTrack->GetITSClusterMap(), 
2555                                            pid,
2556                                            vV0,
2557                                            kTRUE,  // check if this is right
2558                                            kFALSE, // check if this is right
2559                                            AliAODTrack::kSecondary)
2560                 );
2561         aodTrack->ConvertAliPIDtoAODPID();
2562       }
2563       else {
2564         cerr << "Error: event " << iEvent << " V0 " << nV0
2565              << " track " << negFromV0 << " has already been used!" << endl;
2566       }
2567
2568       // add it to the V0 array as well
2569       Double_t d0[2] = { 999., 99.};
2570       new(V0s[jV0s++]) AliAODv0(vV0, 999., 99., p_pos, p_neg, d0); // to be refined
2571     }
2572         V0s.Expand(jV0s);        
2573     // end of the loop on V0s
2574     
2575     // Kinks: it is a big mess the access to the information in the kinks
2576     // The loop is on the tracks in order to find the mother and daugther of each kink
2577
2578
2579     for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) {
2580
2581       AliESDtrack * esdTrack = esd->GetTrack(iTrack);
2582
2583       Int_t ikink = esdTrack->GetKinkIndex(0);
2584
2585       if (ikink) {
2586         // Negative kink index: mother, positive: daughter
2587
2588         // Search for the second track of the kink
2589
2590         for (Int_t jTrack = iTrack+1; jTrack<nTracks; ++jTrack) {
2591
2592           AliESDtrack * esdTrack1 = esd->GetTrack(jTrack);
2593
2594           Int_t jkink = esdTrack1->GetKinkIndex(0);
2595
2596           if ( TMath::Abs(ikink)==TMath::Abs(jkink) ) {
2597
2598             // The two tracks are from the same kink
2599           
2600             if (usedKink[TMath::Abs(ikink)-1]) continue; // skip used kinks
2601
2602             Int_t imother = -1;
2603             Int_t idaughter = -1;
2604
2605             if (ikink<0 && jkink>0) {
2606
2607               imother = iTrack;
2608               idaughter = jTrack;
2609             }
2610             else if (ikink>0 && jkink<0) {
2611
2612               imother = jTrack;
2613               idaughter = iTrack;
2614             }
2615             else {
2616               cerr << "Error: Wrong combination of kink indexes: "
2617               << ikink << " " << jkink << endl;
2618               continue;
2619             }
2620
2621             // Add the mother track
2622
2623             AliAODTrack * mother = NULL;
2624
2625             if (!usedTrack[imother]) {
2626         
2627               usedTrack[imother] = kTRUE;
2628         
2629               AliESDtrack *esdTrack = esd->GetTrack(imother);
2630               esdTrack->GetPxPyPz(p);
2631               esdTrack->GetXYZ(pos);
2632               esdTrack->GetCovarianceXYZPxPyPz(covTr);
2633               esdTrack->GetESDpid(pid);
2634
2635               mother = 
2636                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2637                                            esdTrack->GetLabel(),
2638                                            p,
2639                                            kTRUE,
2640                                            pos,
2641                                            kFALSE,
2642                                            covTr, 
2643                                            (Short_t)esdTrack->Charge(),
2644                                            esdTrack->GetITSClusterMap(), 
2645                                            pid,
2646                                            primary,
2647                                            kTRUE, // check if this is right
2648                                            kTRUE, // check if this is right
2649                                            AliAODTrack::kPrimary);
2650               primary->AddDaughter(mother);
2651               mother->ConvertAliPIDtoAODPID();
2652             }
2653             else {
2654               cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
2655               << " track " << imother << " has already been used!" << endl;
2656             }
2657
2658             // Add the kink vertex
2659             AliESDkink * kink = esd->GetKink(TMath::Abs(ikink)-1);
2660
2661             AliAODVertex * vkink = 
2662             new(vertices[jVertices++]) AliAODVertex(kink->GetPosition(),
2663                                                     NULL,
2664                                                     0.,
2665                                                     mother,
2666                                                     esdTrack->GetID(), // This is the track ID of the mother's track!
2667                                                     AliAODVertex::kKink);
2668             // Add the daughter track
2669
2670             AliAODTrack * daughter = NULL;
2671
2672             if (!usedTrack[idaughter]) {
2673         
2674               usedTrack[idaughter] = kTRUE;
2675         
2676               AliESDtrack *esdTrack = esd->GetTrack(idaughter);
2677               esdTrack->GetPxPyPz(p);
2678               esdTrack->GetXYZ(pos);
2679               esdTrack->GetCovarianceXYZPxPyPz(covTr);
2680               esdTrack->GetESDpid(pid);
2681
2682               daughter = 
2683                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2684                                            esdTrack->GetLabel(),
2685                                            p,
2686                                            kTRUE,
2687                                            pos,
2688                                            kFALSE,
2689                                            covTr, 
2690                                            (Short_t)esdTrack->Charge(),
2691                                            esdTrack->GetITSClusterMap(), 
2692                                            pid,
2693                                            vkink,
2694                                            kTRUE, // check if this is right
2695                                            kTRUE, // check if this is right
2696                                            AliAODTrack::kPrimary);
2697               vkink->AddDaughter(daughter);
2698               daughter->ConvertAliPIDtoAODPID();
2699             }
2700             else {
2701               cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
2702               << " track " << idaughter << " has already been used!" << endl;
2703             }
2704           }
2705         }
2706       }
2707     }
2708     vertices.Expand(jVertices);
2709
2710     // Tracks (primary and orphan)
2711     for (Int_t nTrack = 0; nTrack < nTracks; ++nTrack) {
2712
2713       if (usedTrack[nTrack]) continue;
2714
2715       AliESDtrack *esdTrack = esd->GetTrack(nTrack);
2716       esdTrack->GetPxPyPz(p);
2717       esdTrack->GetXYZ(pos);
2718       esdTrack->GetCovarianceXYZPxPyPz(covTr);
2719       esdTrack->GetESDpid(pid);
2720
2721       Float_t impactXY, impactZ;
2722
2723       esdTrack->GetImpactParameters(impactXY,impactZ);
2724
2725       if (impactXY<3.) {
2726         // track inside the beam pipe
2727       
2728         primary->AddDaughter(aodTrack =
2729             new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
2730                                          esdTrack->GetLabel(),
2731                                          p,
2732                                          kTRUE,
2733                                          pos,
2734                                          kFALSE,
2735                                          covTr, 
2736                                          (Short_t)esdTrack->Charge(),
2737                                          esdTrack->GetITSClusterMap(), 
2738                                          pid,
2739                                          primary,
2740                                          kTRUE, // check if this is right
2741                                          kTRUE, // check if this is right
2742                                          AliAODTrack::kPrimary)
2743             );
2744         aodTrack->ConvertAliPIDtoAODPID();
2745       }
2746       else {
2747         // outside the beam pipe: orphan track
2748         // Don't write them anymore!
2749         continue;
2750       } 
2751     } // end of loop on tracks
2752     
2753     // muon tracks
2754     Int_t nMuTracks = esd->GetNumberOfMuonTracks();
2755     for (Int_t nMuTrack = 0; nMuTrack < nMuTracks; ++nMuTrack) {
2756       
2757       AliESDMuonTrack *esdMuTrack = esd->GetMuonTrack(nMuTrack);     
2758       p[0] = esdMuTrack->Px(); 
2759       p[1] = esdMuTrack->Py(); 
2760       p[2] = esdMuTrack->Pz();
2761       pos[0] = primary->GetX(); 
2762       pos[1] = primary->GetY(); 
2763       pos[2] = primary->GetZ();
2764       
2765       // has to be changed once the muon pid is provided by the ESD
2766       for (Int_t i = 0; i < 10; pid[i++] = 0.); pid[AliAODTrack::kMuon]=1.;
2767       
2768       primary->AddDaughter(aodTrack =
2769           new(tracks[jTracks++]) AliAODTrack(0, // no ID provided
2770                                              0, // no label provided
2771                                              p,
2772                                              kTRUE,
2773                                              pos,
2774                                              kFALSE,
2775                                              NULL, // no covariance matrix provided
2776                                              esdMuTrack->Charge(),
2777                                              0, // ITSClusterMap is set below
2778                                              pid,
2779                                              primary,
2780                                              kFALSE,  // muon tracks are not used to fit the primary vtx
2781                                              kFALSE,  // not used for vertex fit
2782                                              AliAODTrack::kPrimary)
2783           );
2784
2785       aodTrack->SetHitsPatternInTrigCh(esdMuTrack->GetHitsPatternInTrigCh());
2786       Int_t track2Trigger = esdMuTrack->GetMatchTrigger();
2787       aodTrack->SetMatchTrigger(track2Trigger);
2788       if (track2Trigger) 
2789         aodTrack->SetChi2MatchTrigger(esdMuTrack->GetChi2MatchTrigger());
2790       else 
2791         aodTrack->SetChi2MatchTrigger(0.);
2792     }
2793     tracks.Expand(jTracks); // remove 'empty slots' due to unwritten tracks
2794         
2795     // Access to the AOD container of PMD clusters
2796     TClonesArray &pmdClusters = *(aod->GetPmdClusters());
2797     Int_t jPmdClusters=0;
2798   
2799     for (Int_t iPmd = 0; iPmd < nPmdClus; ++iPmd) {
2800       // file pmd clusters, to be revised!
2801       AliESDPmdTrack *pmdTrack = esd->GetPmdTrack(iPmd);
2802       Int_t nLabel = 0;
2803       Int_t *label = 0x0;
2804       Double_t pos[3] = { pmdTrack->GetClusterX(), pmdTrack->GetClusterY(), pmdTrack->GetClusterZ() };
2805       Double_t pid[9] = { 0., 0., 0., 0., 0., 0., 0., 0., 0. }; // to be revised!
2806       // type not set!
2807       // assoc cluster not set
2808       new(pmdClusters[jPmdClusters++]) AliAODPmdCluster(iPmd, nLabel, label, pmdTrack->GetClusterADC(), pos, pid);
2809     }
2810
2811     // Access to the AOD container of clusters
2812     TClonesArray &caloClusters = *(aod->GetCaloClusters());
2813     Int_t jClusters=0;
2814  
2815     for (Int_t iClust=0; iClust<nCaloClus; ++iClust) {
2816
2817       AliESDCaloCluster * cluster = esd->GetCaloCluster(iClust);
2818
2819       Int_t id = cluster->GetID();
2820       Int_t nLabel = 0;
2821       Int_t *label = 0x0;
2822       Float_t energy = cluster->E();
2823       cluster->GetPosition(posF);
2824       Char_t ttype=AliAODCluster::kUndef;
2825
2826       if (cluster->GetClusterType() == AliESDCaloCluster::kPHOSCluster) {
2827         ttype=AliAODCluster::kPHOSNeutral;
2828       } 
2829       else if (cluster->GetClusterType() == AliESDCaloCluster::kEMCALClusterv1) {
2830         ttype = AliAODCluster::kEMCALClusterv1;
2831       }
2832
2833       
2834       AliAODCaloCluster *caloCluster = new(caloClusters[jClusters++]) AliAODCaloCluster(id,
2835                                                                                         nLabel,
2836                                                                                         label,
2837                                                                                         energy,
2838                                                                                         pos,
2839                                                                                         NULL,
2840                                                                                         ttype);
2841       
2842       caloCluster->SetCaloCluster(); // to be refined!
2843
2844     } 
2845     caloClusters.Expand(jClusters); // resize TObjArray to 'remove' slots for pseudo clusters    
2846     // end of loop on calo clusters
2847
2848     // fill EMCAL cell info
2849     if (esd->GetEMCALCells()) { // protection against missing ESD information
2850       AliESDCaloCells &esdEMcells = *(esd->GetEMCALCells());
2851       Int_t nEMcell = esdEMcells.GetNumberOfCells() ;
2852       
2853       AliAODCaloCells &aodEMcells = *(aod->GetEMCALCells());
2854       aodEMcells.CreateContainer(nEMcell);
2855       aodEMcells.SetType(AliAODCaloCells::kEMCAL);
2856       for (Int_t iCell = 0; iCell < nEMcell; iCell++) {      
2857         aodEMcells.SetCell(iCell,esdEMcells.GetCellNumber(iCell),esdEMcells.GetAmplitude(iCell));
2858       }
2859       aodEMcells.Sort();
2860     }
2861
2862     // fill PHOS cell info
2863     if (esd->GetPHOSCells()) { // protection against missing ESD information
2864       AliESDCaloCells &esdPHcells = *(esd->GetPHOSCells());
2865       Int_t nPHcell = esdPHcells.GetNumberOfCells() ;
2866       
2867       AliAODCaloCells &aodPHcells = *(aod->GetPHOSCells());
2868       aodPHcells.CreateContainer(nPHcell);
2869       aodPHcells.SetType(AliAODCaloCells::kPHOS);
2870       for (Int_t iCell = 0; iCell < nPHcell; iCell++) {      
2871         aodPHcells.SetCell(iCell,esdPHcells.GetCellNumber(iCell),esdPHcells.GetAmplitude(iCell));
2872       }
2873       aodPHcells.Sort();
2874     }
2875
2876     // tracklets    
2877     AliAODTracklets &SPDTracklets = *(aod->GetTracklets());
2878     const AliMultiplicity *mult = esd->GetMultiplicity();
2879     if (mult) {
2880       if (mult->GetNumberOfTracklets()>0) {
2881         SPDTracklets.CreateContainer(mult->GetNumberOfTracklets());
2882
2883         for (Int_t n=0; n<mult->GetNumberOfTracklets(); n++) {
2884           SPDTracklets.SetTracklet(n, mult->GetTheta(n), mult->GetPhi(n), mult->GetDeltaPhi(n), mult->GetLabel(n));
2885         }
2886       }
2887     } else {
2888       Printf("ERROR: AliMultiplicity could not be retrieved from ESD");
2889     }
2890
2891     delete [] usedTrack;
2892     delete [] usedV0;
2893     delete [] usedKink;
2894
2895     // fill the tree for this event
2896     aodTree->Fill();
2897   } // end of event loop
2898
2899   aodTree->GetUserInfo()->Add(aod);
2900
2901   // write the tree to the specified file
2902   aodFile = aodTree->GetCurrentFile();
2903   aodFile->cd();
2904   aodTree->Write();
2905
2906   return;
2907 }
2908
2909 void AliReconstruction::WriteAlignmentData(AliESDEvent* esd)
2910 {
2911   // Write space-points which are then used in the alignment procedures
2912   // For the moment only ITS, TRD and TPC
2913
2914   // Load TOF clusters
2915   if (fTracker[3]){
2916     fLoader[3]->LoadRecPoints("read");
2917     TTree* tree = fLoader[3]->TreeR();
2918     if (!tree) {
2919       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[3]));
2920       return;
2921     }
2922     fTracker[3]->LoadClusters(tree);
2923   }
2924   Int_t ntracks = esd->GetNumberOfTracks();
2925   for (Int_t itrack = 0; itrack < ntracks; itrack++)
2926     {
2927       AliESDtrack *track = esd->GetTrack(itrack);
2928       Int_t nsp = 0;
2929       Int_t idx[200];
2930       for (Int_t iDet = 3; iDet >= 0; iDet--)
2931         nsp += track->GetNcls(iDet);
2932       if (nsp) {
2933         AliTrackPointArray *sp = new AliTrackPointArray(nsp);
2934         track->SetTrackPointArray(sp);
2935         Int_t isptrack = 0;
2936         for (Int_t iDet = 3; iDet >= 0; iDet--) {
2937           AliTracker *tracker = fTracker[iDet];
2938           if (!tracker) continue;
2939           Int_t nspdet = track->GetNcls(iDet);
2940           if (nspdet <= 0) continue;
2941           track->GetClusters(iDet,idx);
2942           AliTrackPoint p;
2943           Int_t isp = 0;
2944           Int_t isp2 = 0;
2945           while (isp2 < nspdet) {
2946             Bool_t isvalid;
2947             TString dets = fgkDetectorName[iDet];
2948             if ((fUseTrackingErrorsForAlignment.CompareTo(dets) == 0) ||
2949             fUseTrackingErrorsForAlignment.BeginsWith(dets+" ") ||
2950             fUseTrackingErrorsForAlignment.EndsWith(" "+dets) ||
2951             fUseTrackingErrorsForAlignment.Contains(" "+dets+" ")) {
2952               isvalid = tracker->GetTrackPointTrackingError(idx[isp2],p,track);
2953             } else {
2954               isvalid = tracker->GetTrackPoint(idx[isp2],p); 
2955             } 
2956             isp2++;
2957             const Int_t kNTPCmax = 159;
2958             if (iDet==1 && isp2>kNTPCmax) break;   // to be fixed
2959             if (!isvalid) continue;
2960             sp->AddPoint(isptrack,&p); isptrack++; isp++;
2961           }
2962         }       
2963       }
2964     }
2965   if (fTracker[3]){
2966     fTracker[3]->UnloadClusters();
2967     fLoader[3]->UnloadRecPoints();
2968   }
2969 }
2970
2971 //_____________________________________________________________________________
2972 void AliReconstruction::FillRawDataErrorLog(Int_t iEvent, AliESDEvent* esd)
2973 {
2974   // The method reads the raw-data error log
2975   // accumulated within the rawReader.
2976   // It extracts the raw-data errors related to
2977   // the current event and stores them into
2978   // a TClonesArray inside the esd object.
2979
2980   if (!fRawReader) return;
2981
2982   for(Int_t i = 0; i < fRawReader->GetNumberOfErrorLogs(); i++) {
2983
2984     AliRawDataErrorLog *log = fRawReader->GetErrorLog(i);
2985     if (!log) continue;
2986     if (iEvent != log->GetEventNumber()) continue;
2987
2988     esd->AddRawDataErrorLog(log);
2989   }
2990
2991 }
2992
2993 TNamed* AliReconstruction::CopyFileToTNamed(TString fPath,TString fName){
2994   // Dump a file content into a char in TNamed
2995   ifstream in;
2996   in.open(fPath.Data(),ios::in | ios::binary|ios::ate);
2997   Int_t kBytes = (Int_t)in.tellg();
2998   printf("Size: %d \n",kBytes);
2999   TNamed *fn = 0;
3000   if(in.good()){
3001     char* memblock = new char [kBytes];
3002     in.seekg (0, ios::beg);
3003     in.read (memblock, kBytes);
3004     in.close();
3005     TString fData(memblock,kBytes);
3006     fn = new TNamed(fName,fData);
3007     printf("fData Size: %d \n",fData.Sizeof());
3008     printf("fName Size: %d \n",fName.Sizeof());
3009     printf("fn    Size: %d \n",fn->Sizeof());
3010     delete[] memblock;
3011   }
3012   else{
3013     AliInfo(Form("Could not Open %s\n",fPath.Data()));
3014   }
3015
3016   return fn;
3017 }
3018
3019 void AliReconstruction::TNamedToFile(TTree* fTree, TString fName){
3020   // This is not really needed in AliReconstruction at the moment
3021   // but can serve as a template
3022
3023   TList *fList = fTree->GetUserInfo();
3024   TNamed *fn = (TNamed*)fList->FindObject(fName.Data());
3025   printf("fn Size: %d \n",fn->Sizeof());
3026
3027   TString fTmp(fn->GetName()); // to be 100% sure in principle fName also works
3028   const char* cdata = fn->GetTitle();
3029   printf("fTmp Size %d\n",fTmp.Sizeof());
3030
3031   int size = fn->Sizeof()-fTmp.Sizeof()-sizeof(UChar_t)-sizeof(Int_t); // see dfinition of TString::SizeOf()...
3032   printf("calculated size %d\n",size);
3033   ofstream out(fName.Data(),ios::out | ios::binary);
3034   out.write(cdata,size);
3035   out.close();
3036
3037 }
3038   
3039 //_____________________________________________________________________________
3040 AliQADataMakerRec * AliReconstruction::GetQADataMaker(Int_t iDet)
3041 {
3042  // get the quality assurance data maker object and the loader for a detector
3043
3044   if (fQADataMaker[iDet]) 
3045     return fQADataMaker[iDet];
3046
3047   AliQADataMakerRec * qadm = NULL;
3048   if (iDet == fgkNDetectors) { //Global QA
3049      qadm = new AliGlobalQADataMaker();
3050      fQADataMaker[iDet] = qadm;
3051      return qadm;
3052   }
3053
3054   // load the QA data maker object
3055   TPluginManager* pluginManager = gROOT->GetPluginManager();
3056   TString detName = fgkDetectorName[iDet];
3057   TString qadmName = "Ali" + detName + "QADataMakerRec";
3058   if (gAlice && !gAlice->GetDetector(detName) && (detName != "HLT")) 
3059     return NULL;
3060
3061   // first check if a plugin is defined for the quality assurance data maker
3062   TPluginHandler* pluginHandler = pluginManager->FindHandler("AliQADataMakerRec", detName);
3063   // if not, add a plugin for it
3064   if (!pluginHandler) {
3065     AliDebug(1, Form("defining plugin for %s", qadmName.Data()));
3066     TString libs = gSystem->GetLibraries();
3067     if (libs.Contains("lib" + detName + "base.so") ||
3068         (gSystem->Load("lib" + detName + "base.so") >= 0)) {
3069       pluginManager->AddHandler("AliQADataMakerRec", detName, 
3070                                 qadmName, detName + "qadm", qadmName + "()");
3071     } else {
3072       pluginManager->AddHandler("AliQADataMakerRec", detName, 
3073                                 qadmName, detName, qadmName + "()");
3074     }
3075     pluginHandler = pluginManager->FindHandler("AliQADataMakerRec", detName);
3076   }
3077   if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
3078     qadm = (AliQADataMakerRec *) pluginHandler->ExecPlugin(0);
3079   }
3080
3081   fQADataMaker[iDet] = qadm;
3082
3083   return qadm;
3084 }
3085
3086 //_____________________________________________________________________________
3087 Bool_t AliReconstruction::RunQA(const char* detectors, AliESDEvent *& esd)
3088 {
3089   // run the Quality Assurance data producer
3090
3091   AliCodeTimerAuto("")
3092   TString detStr = detectors;
3093   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
3094    if (!IsSelected(fgkDetectorName[iDet], detStr)) 
3095      continue;
3096    AliQADataMakerRec * qadm = GetQADataMaker(iDet);
3097    if (!qadm) 
3098      continue;
3099    AliCodeTimerStart(Form("running quality assurance data maker for %s", fgkDetectorName[iDet]));
3100    AliInfo(Form("running quality assurance data maker for %s", fgkDetectorName[iDet]));
3101     
3102    qadm->Exec(AliQA::kESDS, esd) ; 
3103    qadm->Increment() ; 
3104
3105    AliCodeTimerStop(Form("running quality assurance data maker for %s", fgkDetectorName[iDet]));
3106  }
3107  if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
3108    AliError(Form("the following detectors were not found: %s",
3109                  detStr.Data()));
3110    if (fStopOnError) 
3111      return kFALSE;
3112  }
3113  
3114  return kTRUE;
3115   
3116 }
3117
3118 //_____________________________________________________________________________
3119 void AliReconstruction::CheckQA()
3120 {
3121 // check the QA of SIM for this run and remove the detectors 
3122 // with status Fatal
3123   
3124         TString newRunLocalReconstruction ; 
3125         TString newRunTracking ;
3126         TString newFillESD ;
3127          
3128         for (Int_t iDet = 0; iDet < AliQA::kNDET; iDet++) {
3129                 TString detName(AliQA::GetDetName(iDet)) ;
3130                 AliQA * qa = AliQA::Instance(AliQA::DETECTORINDEX(iDet)) ; 
3131                 if ( qa->IsSet(AliQA::DETECTORINDEX(iDet), AliQA::kSIM, AliQA::kFATAL)) {
3132                                 AliInfo(Form("QA status for %s in Hits and/or SDIGITS  and/or Digits was Fatal; No reconstruction performed", detName.Data())) ;
3133                 } else {
3134                         if ( fRunLocalReconstruction.Contains(AliQA::GetDetName(iDet)) || 
3135                                         fRunLocalReconstruction.Contains("ALL") )  {
3136                                 newRunLocalReconstruction += detName ; 
3137                                 newRunLocalReconstruction += " " ;                      
3138                         }
3139                         if ( fRunTracking.Contains(AliQA::GetDetName(iDet)) || 
3140                                         fRunTracking.Contains("ALL") )  {
3141                                 newRunTracking += detName ; 
3142                                 newRunTracking += " " ;                         
3143                         }
3144                         if ( fFillESD.Contains(AliQA::GetDetName(iDet)) || 
3145                                         fFillESD.Contains("ALL") )  {
3146                                 newFillESD += detName ; 
3147                                 newFillESD += " " ;                     
3148                         }
3149                 }
3150         }
3151         fRunLocalReconstruction = newRunLocalReconstruction ; 
3152         fRunTracking            = newRunTracking ; 
3153         fFillESD                = newFillESD ; 
3154 }
3155
3156 //_____________________________________________________________________________
3157 Int_t AliReconstruction::GetDetIndex(const char* detector)
3158 {
3159   // return the detector index corresponding to detector
3160   Int_t index = -1 ; 
3161   for (index = 0; index < fgkNDetectors ; index++) {
3162     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
3163         break ; 
3164   }     
3165   return index ; 
3166 }
3167 //_____________________________________________________________________________
3168 Bool_t AliReconstruction::FinishPlaneEff() {
3169  //
3170  // Here execute all the necessary operationis, at the end of the tracking phase,
3171  // in case that evaluation of PlaneEfficiencies was required for some detector. 
3172  // E.g., write into a DataBase file the PlaneEfficiency which have been evaluated. 
3173  //
3174  // This Preliminary version works only FOR ITS !!!!!
3175  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3176  //
3177  //  Input: none
3178  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise 
3179  //
3180  Bool_t ret=kFALSE;
3181  //for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
3182  for (Int_t iDet = 0; iDet < 1; iDet++) { // for the time being only ITS  
3183    //if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
3184    if(fTracker[iDet]) {
3185       AliPlaneEff *planeeff=fTracker[iDet]->GetPlaneEff(); 
3186       ret=planeeff->WriteIntoCDB();
3187       if(planeeff->GetCreateHistos()) {
3188         TString name="PlaneEffHisto";
3189         name+=fgkDetectorName[iDet];
3190         name+=".root";
3191         ret*=planeeff->WriteHistosToFile(name,"RECREATE");
3192       }
3193    }
3194  }
3195  return ret;
3196 }
3197 //_____________________________________________________________________________
3198 Bool_t AliReconstruction::InitPlaneEff() {
3199 //
3200  // Here execute all the necessary operations, before of the tracking phase,
3201  // for the evaluation of PlaneEfficiencies, in case required for some detectors.
3202  // E.g., read from a DataBase file a first evaluation of the PlaneEfficiency 
3203  // which should be updated/recalculated.
3204  //
3205  // This Preliminary version will work only FOR ITS !!!!!
3206  // other detectors (TOF,TRD, etc. have to develop their specific codes)
3207  //
3208  //  Input: none
3209  //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
3210  //
3211  AliWarning(Form("Implementation of this method not yet done !! Method return kTRUE"));
3212  return kTRUE;
3213 }