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