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