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