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