1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////////
20 // class for running the reconstruction //
22 // Clusters and tracks are created for all detectors and all events by //
25 // AliReconstruction rec; //
28 // The Run method returns kTRUE in case of successful execution. //
29 // The name of the galice file can be changed from the default //
30 // "galice.root" by passing it as argument to the AliReconstruction //
31 // constructor or by //
33 // rec.SetGAliceFile("..."); //
35 // The local reconstruction can be switched on or off for individual //
38 // rec.SetRunLocalReconstruction("..."); //
40 // The argument is a (case sensitive) string with the names of the //
41 // detectors separated by a space. The special string "ALL" selects all //
42 // available detectors. This is the default. //
44 // The tracking in ITS, TPC and TRD and the creation of ESD tracks can be //
47 // rec.SetRunTracking(kFALSE); //
49 // The filling of additional ESD information can be steered by //
51 // rec.SetFillESD("..."); //
53 // Again, the string specifies the list of detectors. The default is "ALL". //
55 // The reconstruction requires digits as input. For the creation of digits //
56 // have a look at the class AliSimulation. //
58 // For debug purposes the method SetCheckPointLevel can be used. If the //
59 // argument is greater than 0, files with ESD events will be written after //
60 // selected steps of the reconstruction for each event: //
61 // level 1: after tracking and after filling of ESD (final) //
62 // level 2: in addition after each tracking step //
63 // level 3: in addition after the filling of ESD for each detector //
64 // If a final check point file exists for an event, this event will be //
65 // skipped in the reconstruction. The tracking and the filling of ESD for //
66 // a detector will be skipped as well, if the corresponding check point //
67 // file exists. The ESD event will then be loaded from the file instead. //
69 ///////////////////////////////////////////////////////////////////////////////
75 #include <TPluginManager.h>
76 #include <TStopwatch.h>
78 #include "AliReconstruction.h"
79 #include "AliRunLoader.h"
81 #include "AliTracker.h"
83 #include "AliESDVertex.h"
84 #include "AliVertexer.h"
85 #include "AliHeader.h"
86 #include "AliGenEventHeader.h"
87 #include "AliESDpid.h"
90 ClassImp(AliReconstruction)
93 //_____________________________________________________________________________
94 const char* AliReconstruction::fgkDetectorName[AliReconstruction::fgkNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "RICH", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "START", "VZERO", "CRT"};
96 //_____________________________________________________________________________
97 AliReconstruction::AliReconstruction(const char* gAliceFilename,
98 const char* name, const char* title) :
101 fRunLocalReconstruction("ALL"),
102 fRunVertexFinder(kTRUE),
105 fGAliceFileName(gAliceFilename),
106 fStopOnError(kFALSE),
120 // create reconstruction object with default parameters
124 //_____________________________________________________________________________
125 AliReconstruction::AliReconstruction(const AliReconstruction& rec) :
128 fRunLocalReconstruction(rec.fRunLocalReconstruction),
129 fRunVertexFinder(rec.fRunVertexFinder),
130 fRunTracking(rec.fRunTracking),
131 fFillESD(rec.fFillESD),
132 fGAliceFileName(rec.fGAliceFileName),
133 fStopOnError(rec.fStopOnError),
151 //_____________________________________________________________________________
152 AliReconstruction& AliReconstruction::operator = (const AliReconstruction& rec)
154 // assignment operator
156 this->~AliReconstruction();
157 new(this) AliReconstruction(rec);
161 //_____________________________________________________________________________
162 AliReconstruction::~AliReconstruction()
170 //_____________________________________________________________________________
171 void AliReconstruction::SetGAliceFile(const char* fileName)
173 // set the name of the galice file
175 fGAliceFileName = fileName;
179 //_____________________________________________________________________________
180 Bool_t AliReconstruction::Run()
182 // run the reconstruction
184 // open the run loader
185 fRunLoader = AliRunLoader::Open(fGAliceFileName.Data());
187 Error("Run", "no run loader found in file %s",
188 fGAliceFileName.Data());
192 fRunLoader->LoadgAlice();
193 AliRun* aliRun = fRunLoader->GetAliRun();
195 Error("Run", "no gAlice object found in file %s",
196 fGAliceFileName.Data());
202 // load the reconstructor objects
203 TPluginManager* pluginManager = gROOT->GetPluginManager();
204 for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
205 TString detName = fgkDetectorName[iDet];
206 TString recName = "Ali" + detName + "Reconstructor";
207 if (!gAlice->GetDetector(detName)) continue;
209 AliReconstructor* reconstructor = NULL;
210 // first check if a plugin is defined for the reconstructor
211 TPluginHandler* pluginHandler =
212 pluginManager->FindHandler("AliReconstructor", detName);
213 // if not, but the reconstructor class is implemented, add a plugin for it
214 if (!pluginHandler && gROOT->GetClass(recName.Data())) {
215 Info("Run", "defining plugin for %s", recName.Data());
216 pluginManager->AddHandler("AliReconstructor", detName,
217 recName, detName, recName + "()");
218 pluginHandler = pluginManager->FindHandler("AliReconstructor", detName);
220 if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
221 reconstructor = (AliReconstructor*) pluginHandler->ExecPlugin(0);
223 // if there is no reconstructor class for the detector use the dummy one
224 if (!reconstructor) {
225 Info("Run", "using dummy reconstructor for %s", detName.Data());
226 reconstructor = new AliDummyReconstructor(gAlice->GetDetector(detName));
228 if (reconstructor) fReconstructors.Add(reconstructor);
231 // local reconstruction
232 if (!fRunLocalReconstruction.IsNull()) {
233 if (!RunLocalReconstruction(fRunLocalReconstruction)) {
234 if (fStopOnError) {CleanUp(); return kFALSE;}
237 if (!fRunVertexFinder && !fRunTracking && fFillESD.IsNull()) return kTRUE;
240 if (fRunVertexFinder && !CreateVertexer()) {
247 // get loaders and trackers
248 if (fRunTracking && !CreateTrackers()) {
255 // create the ESD output file
256 TFile* file = TFile::Open("AliESDs.root", "RECREATE");
257 if (!file->IsOpen()) {
258 Error("Run", "opening AliESDs.root failed");
259 if (fStopOnError) {CleanUp(file); return kFALSE;}
263 for (Int_t iEvent = 0; iEvent < fRunLoader->GetNumberOfEvents(); iEvent++) {
264 Info("Run", "processing event %d", iEvent);
265 fRunLoader->GetEvent(iEvent);
268 sprintf(fileName, "ESD_%d.%d_final.root",
269 aliRun->GetRunNumber(), aliRun->GetEvNumber());
270 if (!gSystem->AccessPathName(fileName)) continue;
272 AliESD* esd = new AliESD;
273 esd->SetRunNumber(aliRun->GetRunNumber());
274 esd->SetEventNumber(aliRun->GetEvNumber());
275 esd->SetMagneticField(aliRun->Field()->SolenoidField());
278 if (fRunVertexFinder) {
279 if (!ReadESD(esd, "vertex")) {
280 if (!RunVertexFinder(esd)) {
281 if (fStopOnError) {CleanUp(file); return kFALSE;}
283 if (fCheckPointLevel > 0) WriteESD(esd, "vertex");
289 if (!ReadESD(esd, "tracking")) {
290 if (!RunTracking(esd)) {
291 if (fStopOnError) {CleanUp(file); return kFALSE;}
293 if (fCheckPointLevel > 0) WriteESD(esd, "tracking");
298 if (!fFillESD.IsNull()) {
299 if (!FillESD(esd, fFillESD)) {
300 if (fStopOnError) {CleanUp(file); return kFALSE;}
305 AliESDpid::MakePID(esd);
306 if (fCheckPointLevel > 1) WriteESD(esd, "PID");
310 sprintf(name, "ESD%d", iEvent);
312 if (!esd->Write(name)) {
313 Error("Run", "writing ESD failed");
314 if (fStopOnError) {CleanUp(file); return kFALSE;}
318 if (fCheckPointLevel > 0) WriteESD(esd, "final");
328 //_____________________________________________________________________________
329 Bool_t AliReconstruction::RunLocalReconstruction(const TString& detectors)
331 // run the local reconstruction
333 TStopwatch stopwatch;
336 TString detStr = detectors;
337 for (Int_t iDet = 0; iDet < fReconstructors.GetEntriesFast(); iDet++) {
338 AliReconstructor* reconstructor =
339 (AliReconstructor*) fReconstructors[iDet];
340 TString detName = reconstructor->GetDetectorName();
341 if (IsSelected(detName, detStr)) {
342 Info("RunReconstruction", "running reconstruction for %s",
344 TStopwatch stopwatchDet;
345 stopwatchDet.Start();
346 reconstructor->Reconstruct(fRunLoader);
347 Info("RunReconstruction", "execution time for %s:", detName.Data());
348 stopwatchDet.Print();
352 if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
353 Error("RunReconstruction", "the following detectors were not found: %s",
355 if (fStopOnError) return kFALSE;
358 Info("RunReconstruction", "execution time:");
364 //_____________________________________________________________________________
365 Bool_t AliReconstruction::RunVertexFinder(AliESD*& esd)
367 // run the barrel tracking
369 TStopwatch stopwatch;
372 AliESDVertex* vertex = NULL;
373 Double_t vtxPos[3] = {0, 0, 0};
374 Double_t vtxErr[3] = {0.07, 0.07, 0.1};
376 fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(mcVertex);
377 for (Int_t i = 0; i < 3; i++) vtxPos[i] = mcVertex[i];
380 Info("RunVertexFinder", "running the ITS vertex finder");
381 fITSVertexer->SetDebug(1);
382 vertex = fITSVertexer->FindVertexForCurrentEvent(fRunLoader->GetEventNumber());
384 Warning("RunVertexFinder","Vertex not found \n");
385 vertex = new AliESDVertex();
388 vertex->SetTruePos(vtxPos); // store also the vertex from MC
392 Info("RunVertexFinder", "getting the primary vertex from MC");
393 vertex = new AliESDVertex(vtxPos, vtxErr);
397 vertex->GetXYZ(vtxPos);
398 vertex->GetSigmaXYZ(vtxErr);
400 Warning("RunVertexFinder", "no vertex reconstructed");
401 vertex = new AliESDVertex(vtxPos, vtxErr);
403 esd->SetVertex(vertex);
404 if (fITSTracker) fITSTracker->SetVertex(vtxPos, vtxErr);
405 if (fTPCTracker) fTPCTracker->SetVertex(vtxPos, vtxErr);
406 if (fTRDTracker) fTRDTracker->SetVertex(vtxPos, vtxErr);
409 Info("RunVertexFinder", "execution time:");
415 //_____________________________________________________________________________
416 Bool_t AliReconstruction::RunTracking(AliESD*& esd)
418 // run the barrel tracking
420 TStopwatch stopwatch;
424 Error("RunTracking", "no TPC tracker");
429 Info("RunTracking", "TPC tracking");
430 fTPCLoader->LoadRecPoints("read");
431 TTree* tpcTree = fTPCLoader->TreeR();
433 Error("RunTracking", "Can't get the TPC cluster tree");
436 fTPCTracker->LoadClusters(tpcTree);
437 if (fTPCTracker->Clusters2Tracks(esd) != 0) {
438 Error("RunTracking", "TPC Clusters2Tracks failed");
441 if (fCheckPointLevel > 1) WriteESD(esd, "TPC.tracking");
444 Warning("RunTracking", "no ITS tracker");
447 fRunLoader->GetAliRun()->GetDetector("TPC")->FillESD(esd); // preliminary
448 AliESDpid::MakePID(esd); // PID for the ITS tracker
451 Info("RunTracking", "ITS tracking");
452 fITSLoader->LoadRecPoints("read");
453 TTree* itsTree = fITSLoader->TreeR();
455 Error("RunTracking", "Can't get the ITS cluster tree");
458 fITSTracker->LoadClusters(itsTree);
459 if (fITSTracker->Clusters2Tracks(esd) != 0) {
460 Error("RunTracking", "ITS Clusters2Tracks failed");
463 if (fCheckPointLevel > 1) WriteESD(esd, "ITS.tracking");
466 Warning("RunTracking", "no TRD tracker");
468 // ITS back propagation
469 Info("RunTracking", "ITS back propagation");
470 if (fITSTracker->PropagateBack(esd) != 0) {
471 Error("RunTracking", "ITS backward propagation failed");
474 if (fCheckPointLevel > 1) WriteESD(esd, "ITS.back");
476 // TPC back propagation
477 Info("RunTracking", "TPC back propagation");
478 if (fTPCTracker->PropagateBack(esd) != 0) {
479 Error("RunTracking", "TPC backward propagation failed");
482 if (fCheckPointLevel > 1) WriteESD(esd, "TPC.back");
484 // TRD back propagation
485 Info("RunTracking", "TRD back propagation");
486 fTRDLoader->LoadRecPoints("read");
487 TTree* trdTree = fTRDLoader->TreeR();
489 Error("RunTracking", "Can't get the TRD cluster tree");
492 fTRDTracker->LoadClusters(trdTree);
493 if (fTRDTracker->PropagateBack(esd) != 0) {
494 Error("RunTracking", "TRD backward propagation failed");
497 if (fCheckPointLevel > 1) WriteESD(esd, "TRD.back");
500 Warning("RunTracking", "no TOF tracker");
502 // TOF back propagation
503 Info("RunTracking", "TOF back propagation");
504 fTOFLoader->LoadDigits("read");
505 TTree* tofTree = fTOFLoader->TreeD();
507 Error("RunTracking", "Can't get the TOF digits tree");
510 fTOFTracker->LoadClusters(tofTree);
511 if (fTOFTracker->PropagateBack(esd) != 0) {
512 Error("RunTracking", "TOF backward propagation failed");
515 if (fCheckPointLevel > 1) WriteESD(esd, "TOF.back");
516 fTOFTracker->UnloadClusters();
517 fTOFLoader->UnloadDigits();
521 Info("RunTracking", "TRD inward refit");
522 if (fTRDTracker->RefitInward(esd) != 0) {
523 Error("RunTracking", "TRD inward refit failed");
526 if (fCheckPointLevel > 1) WriteESD(esd, "TRD.refit");
527 fTRDTracker->UnloadClusters();
528 fTRDLoader->UnloadRecPoints();
531 Info("RunTracking", "TPC inward refit");
532 if (fTPCTracker->RefitInward(esd) != 0) {
533 Error("RunTracking", "TPC inward refit failed");
536 if (fCheckPointLevel > 1) WriteESD(esd, "TPC.refit");
539 Info("RunTracking", "ITS inward refit");
540 if (fITSTracker->RefitInward(esd) != 0) {
541 Error("RunTracking", "ITS inward refit failed");
544 if (fCheckPointLevel > 1) WriteESD(esd, "ITS.refit");
547 fITSTracker->UnloadClusters();
548 fITSLoader->UnloadRecPoints();
551 fTPCTracker->UnloadClusters();
552 fTPCLoader->UnloadRecPoints();
554 Info("RunTracking", "execution time:");
560 //_____________________________________________________________________________
561 Bool_t AliReconstruction::FillESD(AliESD*& esd, const TString& detectors)
563 // fill the event summary data
565 TStopwatch stopwatch;
568 TString detStr = detectors;
569 for (Int_t iDet = 0; iDet < fReconstructors.GetEntriesFast(); iDet++) {
570 AliReconstructor* reconstructor =
571 (AliReconstructor*) fReconstructors[iDet];
572 TString detName = reconstructor->GetDetectorName();
573 if (IsSelected(detName, detStr)) {
574 if (!ReadESD(esd, detName.Data())) {
575 Info("FillESD", "filling ESD for %s", detName.Data());
576 reconstructor->FillESD(fRunLoader, esd);
577 if (fCheckPointLevel > 2) WriteESD(esd, detName.Data());
582 if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
583 Error("FillESD", "the following detectors were not found: %s",
585 if (fStopOnError) return kFALSE;
588 Info("FillESD", "execution time:");
595 //_____________________________________________________________________________
596 Bool_t AliReconstruction::IsSelected(TString detName, TString& detectors) const
598 // check whether detName is contained in detectors
599 // if yes, it is removed from detectors
601 // check if all detectors are selected
602 if ((detectors.CompareTo("ALL") == 0) ||
603 detectors.BeginsWith("ALL ") ||
604 detectors.EndsWith(" ALL") ||
605 detectors.Contains(" ALL ")) {
610 // search for the given detector
611 Bool_t result = kFALSE;
612 if ((detectors.CompareTo(detName) == 0) ||
613 detectors.BeginsWith(detName+" ") ||
614 detectors.EndsWith(" "+detName) ||
615 detectors.Contains(" "+detName+" ")) {
616 detectors.ReplaceAll(detName, "");
620 // clean up the detectors string
621 while (detectors.Contains(" ")) detectors.ReplaceAll(" ", " ");
622 while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
623 while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
628 //_____________________________________________________________________________
629 AliReconstructor* AliReconstruction::GetReconstructor(const char* detName) const
631 // get the reconstructor object for a detector
633 for (Int_t iDet = 0; iDet < fReconstructors.GetEntriesFast(); iDet++) {
634 AliReconstructor* reconstructor =
635 (AliReconstructor*) fReconstructors[iDet];
636 if (strcmp(reconstructor->GetDetectorName(), detName) == 0) {
637 return reconstructor;
643 //_____________________________________________________________________________
644 Bool_t AliReconstruction::CreateVertexer()
646 // create the vertexer
649 AliReconstructor* itsReconstructor = GetReconstructor("ITS");
650 if (itsReconstructor) {
651 fITSVertexer = itsReconstructor->CreateVertexer(fRunLoader);
654 Warning("CreateVertexer", "couldn't create a vertexer for ITS");
655 if (fStopOnError) return kFALSE;
661 //_____________________________________________________________________________
662 Bool_t AliReconstruction::CreateTrackers()
664 // get the loaders and create the trackers
667 fITSLoader = fRunLoader->GetLoader("ITSLoader");
669 Warning("CreateTrackers", "no ITS loader found");
670 if (fStopOnError) return kFALSE;
672 AliReconstructor* itsReconstructor = GetReconstructor("ITS");
673 if (itsReconstructor) {
674 fITSTracker = itsReconstructor->CreateTracker(fRunLoader);
677 Warning("CreateTrackers", "couldn't create a tracker for ITS");
678 if (fStopOnError) return kFALSE;
683 fTPCLoader = fRunLoader->GetLoader("TPCLoader");
685 Error("CreateTrackers", "no TPC loader found");
686 if (fStopOnError) return kFALSE;
688 AliReconstructor* tpcReconstructor = GetReconstructor("TPC");
689 if (tpcReconstructor) {
690 fTPCTracker = tpcReconstructor->CreateTracker(fRunLoader);
693 Error("CreateTrackers", "couldn't create a tracker for TPC");
694 if (fStopOnError) return kFALSE;
699 fTRDLoader = fRunLoader->GetLoader("TRDLoader");
701 Warning("CreateTrackers", "no TRD loader found");
702 if (fStopOnError) return kFALSE;
704 AliReconstructor* trdReconstructor = GetReconstructor("TRD");
705 if (trdReconstructor) {
706 fTRDTracker = trdReconstructor->CreateTracker(fRunLoader);
709 Warning("CreateTrackers", "couldn't create a tracker for TRD");
710 if (fStopOnError) return kFALSE;
715 fTOFLoader = fRunLoader->GetLoader("TOFLoader");
717 Warning("CreateTrackers", "no TOF loader found");
718 if (fStopOnError) return kFALSE;
720 AliReconstructor* tofReconstructor = GetReconstructor("TOF");
721 if (tofReconstructor) {
722 fTOFTracker = tofReconstructor->CreateTracker(fRunLoader);
725 Warning("CreateTrackers", "couldn't create a tracker for TOF");
726 if (fStopOnError) return kFALSE;
733 //_____________________________________________________________________________
734 void AliReconstruction::CleanUp(TFile* file)
736 // delete trackers and the run loader and close and delete the file
738 fReconstructors.Delete();
761 //_____________________________________________________________________________
762 Bool_t AliReconstruction::ReadESD(AliESD*& esd, const char* recStep) const
764 // read the ESD event from a file
766 if (!esd) return kFALSE;
768 sprintf(fileName, "ESD_%d.%d_%s.root",
769 esd->GetRunNumber(), esd->GetEventNumber(), recStep);
770 if (gSystem->AccessPathName(fileName)) return kFALSE;
772 Info("ReadESD", "reading ESD from file %s", fileName);
773 TFile* file = TFile::Open(fileName);
774 if (!file || !file->IsOpen()) {
775 Error("ReadESD", "opening %s failed", fileName);
782 esd = (AliESD*) file->Get("ESD");
788 //_____________________________________________________________________________
789 void AliReconstruction::WriteESD(AliESD* esd, const char* recStep) const
791 // write the ESD event to a file
795 sprintf(fileName, "ESD_%d.%d_%s.root",
796 esd->GetRunNumber(), esd->GetEventNumber(), recStep);
798 Info("WriteESD", "writing ESD to file %s", fileName);
799 TFile* file = TFile::Open(fileName, "recreate");
800 if (!file || !file->IsOpen()) {
801 Error("WriteESD", "opening %s failed", fileName);