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