cyaldo additions 270114
[u/mrichter/AliRoot.git] / MFT / AliMuonForwardTrackFinder.cxx
CommitLineData
820b4d9e 1// ROOT includes
2#include "TObject.h"
3#include "TClonesArray.h"
4#include "TObjArray.h"
5#include "TH2D.h"
6#include "TH1D.h"
7#include "TFile.h"
8#include "TGeoManager.h"
9#include "TMatrixD.h"
10#include "TParticle.h"
11#include "TMath.h"
12#include "TGraph.h"
13#include "TEllipse.h"
14#include "TCanvas.h"
15#include "TString.h"
16#include "TLatex.h"
17#include "TMarker.h"
18#include "TNtuple.h"
19#include "TRandom.h"
20#include "TIterator.h"
21
22// STEER includes
23#include "AliLog.h"
24#include "AliRun.h"
25#include "AliRunLoader.h"
26#include "AliLoader.h"
27#include "AliHeader.h"
28#include "AliMC.h"
29#include "AliStack.h"
30#include "AliMagF.h"
31#include "AliTracker.h"
32#include "AliGRPObject.h"
33#include "AliCDBEntry.h"
34#include "AliCDBManager.h"
35
36// MUON includes
37#include "AliMUONConstants.h"
38#include "AliMUONTrack.h"
39#include "AliMUONRecoCheck.h"
40#include "AliMUONTrackParam.h"
41#include "AliMUONTrackExtrap.h"
42#include "AliMUONVTrackStore.h"
43#include "AliMUONVCluster.h"
44
45// MFT includes
46#include "AliMuonForwardTrack.h"
47#include "AliMFTCluster.h"
48#include "AliMFT.h"
49#include "AliMFTSegmentation.h"
d4643a10 50#include "AliMFTConstants.h"
820b4d9e 51
52#include "AliMuonForwardTrackFinder.h"
53
54//====================================================================================================================================================
55//
56// Class for the creation of the "global muon tracks" built from the clusters in the
57// muon spectrometer and the clusters of the Muon Forward Tracker. QA histograms are also created
58//
59// Contact author: antonio.uras@cern.ch
60//
61//====================================================================================================================================================
62
d4643a10 63const Double_t AliMuonForwardTrackFinder::fRadLengthSi = AliMFTConstants::fRadLengthSi;
64
820b4d9e 65ClassImp(AliMuonForwardTrackFinder)
66
67//=====================================================================================================
68
69AliMuonForwardTrackFinder::AliMuonForwardTrackFinder():
70 TObject(),
71 fRun(0),
72 fNEventsToAnalyze(0),
73 fSigmaClusterCut(0),
a2b7dc2a 74 fScaleSigmaClusterCut(1.),
75 fGlobalTrackingDiverged(kFALSE),
820b4d9e 76 fChi2GlobalCut(0),
77 fSigmaSpectrometerCut(0),
b03d16a3 78 fVertexErrorX(0.015),
79 fVertexErrorY(0.015),
80 fVertexErrorZ(0.010),
820b4d9e 81 fNFinalCandidatesCut(0),
82 fReadDir(0),
83 fOutDir(0),
84 fDrawOption(0),
85
86 fDistanceFromGoodClusterAndTrackAtLastPlane(-1),
87 fDistanceFromBestClusterAndTrackAtLastPlane(-1),
88
89 fRAbsorberCut(0),
90 fLowPtCut(0),
91 fNPlanesMFT(0),
92 fNPlanesMFTAnalyzed(0),
93 fNMaxMissingMFTClusters(0),
94
95 fEv(0),
96 fLabelMC(0),
97
820b4d9e 98 fHistRadiusEndOfAbsorber(0),
99 fHistNGoodClustersForFinalTracks(0),
100 fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane(0),
101 fHistDistanceGoodClusterFromTrackAtLastPlane(0),
102
d4643a10 103 fNtuFinalCandidates(0),
104 fNtuFinalBestCandidates(0),
820b4d9e 105
106 fCanvas(0),
107
108 fTxtMuonHistory(0),
109 fTxtTrackGoodClusters(0),
d4643a10 110 fTxtTrackFinalChi2(0),
111 fTxtTrackMomentum(0),
820b4d9e 112 fTxtFinalCandidates(0),
113 fTxtDummy(0),
114 fTxtAllClust(0),
115 fTxtClustGoodChi2(0),
116 fTxtClustMC(0),
117 fTxtClustOfTrack(0),
118 fMrkAllClust(0),
119 fMrkClustGoodChi2(0),
120 fMrkClustMC(0),
121 fMrkClustOfTrack(0),
122
d4643a10 123 fCountRealTracksAnalyzed(0),
124 fMaxNTracksToBeAnalyzed(99999999),
820b4d9e 125 fCountRealTracksWithRefMC(0),
126 fCountRealTracksWithRefMC_andTrigger(0),
127 fCountRealTracksWithRefMC_andTrigger_andGoodPt(0),
128 fCountRealTracksWithRefMC_andTrigger_andGoodPt_andGoodTheta(0),
129 fCountRealTracksAnalyzedOfEvent(0),
130 fCountRealTracksAnalyzedWithFinalCandidates(0),
131
132 fFileCluster(0),
133 fFileESD(0),
134 fFile_gAlice(0),
135
136 fRunLoader(0),
137 fMFTLoader(0),
138 fMuonRecoCheck(0),
139 fMFTClusterTree(0),
140 fMuonTrackReco(0),
141 fCurrentTrack(0),
d4643a10 142 fFinalBestCandidate(0),
820b4d9e 143 fIsCurrentMuonTrackable(0),
144 fCandidateTracks(0),
145 fTrackStore(0),
146 fTrackRefStore(0),
147 fNextTrack(0),
148 fStack(0),
149 fMFT(0),
150 fSegmentation(0),
151 fOutputTreeFile(0),
d4643a10 152 fOutputQAFile(0),
820b4d9e 153 fOutputEventTree(0),
154 fMuonForwardTracks(0),
155 fMatchingMode(-1),
820b4d9e 156 fGRPData(0),
7e3dd1af 157 fRunInfo(0),
158 fBransonCorrection(kTRUE)
820b4d9e 159
160{
161
162 // Default constructor
163
d4643a10 164 for (Int_t iPlane=0; iPlane<AliMFTConstants::fNMaxPlanes; iPlane++) {
820b4d9e 165
166 fHistNTracksAfterExtrapolation[iPlane] = 0;
167 fHistChi2Cluster_GoodCluster[iPlane] = 0;
168 fHistChi2Cluster_BadCluster[iPlane] = 0;
169 fHistResearchRadius[iPlane] = 0;
170
171 fIsGoodClusterInPlane[iPlane] = kFALSE;
172
173 fHistChi2Cluster_GoodCluster[iPlane] = 0;
174 fHistChi2Cluster_BadCluster[iPlane] = 0;
175
d4643a10 176 fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[iPlane] = 0;
177 fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[iPlane] = 0;
820b4d9e 178
179 fZPlane[iPlane] = 0.;
180 fRPlaneMax[iPlane] = 0.;
181 fRPlaneMin[iPlane] = 0.;
182
d4643a10 183 for (Int_t i=0; i<4; i++) fGrMFTPlane[i][iPlane] = 0;
820b4d9e 184 fCircleExt[iPlane] = 0;
185 fCircleInt[iPlane] = 0;
186
187 fTxtTrackChi2[iPlane] = 0;
188
189 fIsClusterCompatible[iPlane] = 0;
190
191 fMFTClusterArray[iPlane] = 0;
192 fMFTClusterArrayFront[iPlane] = new TClonesArray("AliMFTCluster");
193 fMFTClusterArrayBack[iPlane] = new TClonesArray("AliMFTCluster");
194
195 fIsPlaneMandatory[iPlane] = kFALSE;
196
b5ab1ac4 197 fMinResearchRadiusAtPlane[iPlane] = 0.;
198
820b4d9e 199 }
200
201 // fNextTrack = 0;
202
203 fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane = 0;
204 fHistDistanceGoodClusterFromTrackAtLastPlane = 0;
205
206 fMFTClusterTree = 0;
207 fCandidateTracks = 0;
208
d4643a10 209 fOutputTreeFile = new TFile("MuonGlobalTracks.root", "recreate");
820b4d9e 210 fOutputEventTree = new TTree("AliMuonForwardTracks", "Tree of AliMuonForwardTracks");
211 fMuonForwardTracks = new TClonesArray("AliMuonForwardTrack");
212 fOutputEventTree -> Branch("tracks", &fMuonForwardTracks);
213
214}
215
216//=====================================================================================================
217
d4643a10 218AliMuonForwardTrackFinder::~AliMuonForwardTrackFinder() {
219
220 for (Int_t iPlane=0; iPlane<AliMFTConstants::fNMaxPlanes; iPlane++) {
221
222 delete fHistNTracksAfterExtrapolation[iPlane];
223 delete fHistChi2Cluster_GoodCluster[iPlane];
224 delete fHistChi2Cluster_BadCluster[iPlane];
225 delete fHistResearchRadius[iPlane];
226
227 delete fHistChi2Cluster_GoodCluster[iPlane];
228 delete fHistChi2Cluster_BadCluster[iPlane];
229
230 delete fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[iPlane];
231 delete fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[iPlane];
232
233 for (Int_t i=0; i<4; i++) delete fGrMFTPlane[i][iPlane];
234 delete fCircleExt[iPlane];
235 delete fCircleInt[iPlane];
236
237 delete fTxtTrackChi2[iPlane];
238
239 delete fMFTClusterArray[iPlane];
240 delete fMFTClusterArrayFront[iPlane];
241 delete fMFTClusterArrayBack[iPlane];
242
243 }
244
245 delete fNtuFinalCandidates;
246 delete fNtuFinalBestCandidates;
247
d4643a10 248 delete fHistRadiusEndOfAbsorber;
249
250 delete fHistNGoodClustersForFinalTracks;
251 delete fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane; //
252 delete fHistDistanceGoodClusterFromTrackAtLastPlane; //
253
254 delete fCanvas;
255
256 delete fTxtMuonHistory;
257 delete fTxtTrackGoodClusters;
258 delete fTxtTrackFinalChi2;
259 delete fTxtTrackMomentum;
260 delete fTxtFinalCandidates;
261 delete fTxtDummy;
262 delete fTxtAllClust;
263 delete fTxtClustGoodChi2;
264 delete fTxtClustMC;
265 delete fTxtClustOfTrack;
266 delete fMrkAllClust;
267 delete fMrkClustGoodChi2;
268 delete fMrkClustMC;
269 delete fMrkClustOfTrack;
270
271 delete fFileCluster;
272 delete fFileESD;
273 delete fFile_gAlice;
274
275 delete fRunLoader;
276 delete fMFTLoader;
277 delete fMuonRecoCheck;
278
279 delete fMFTClusterTree;
280
281 delete fMuonTrackReco;
282 delete fCurrentTrack;
283 delete fFinalBestCandidate;
284
285 delete fCandidateTracks;
286
287 delete fTrackStore;
288 delete fTrackRefStore;
289
290 delete fNextTrack;
291
292 delete fStack;
293
294 delete fMFT;
295 delete fSegmentation;
296
297 delete fOutputTreeFile;
298 delete fOutputQAFile;
299 delete fOutputEventTree;
300
301 delete fMuonForwardTracks;
302
303 delete fGRPData;
304 delete fRunInfo;
305
306}
307
308//=====================================================================================================
309
820b4d9e 310void AliMuonForwardTrackFinder::Init(Int_t nRun,
311 Char_t *readDir,
312 Char_t *outDir,
313 Int_t nEventsToAnalyze) {
314
315 if (fRunLoader) {
d4643a10 316 AliInfo("WARNING: run already initialized!!\n");
820b4d9e 317 }
318
319 SetRun(nRun);
320 SetReadDir(readDir);
321 SetOutDir(outDir);
322
d4643a10 323 AliInfo(Form("input dir = %s\n", fReadDir.Data()));
324 AliInfo(Form("output dir = %s\n", fOutDir.Data()));
820b4d9e 325
326 // -------------------------- initializing files...
327
d4643a10 328 AliInfo(Form("initializing files for run %d...\n", fRun));
820b4d9e 329
330 Char_t geoFileName[300];
331 Char_t esdFileName[300];
332 Char_t gAliceName[300];
333 Char_t clusterName[300];
334
d6080682 335 snprintf(geoFileName , 300, "%s/geometry.root", fReadDir.Data());
336 snprintf(esdFileName , 300, "%s/AliESDs.root" , fReadDir.Data());
337 snprintf(gAliceName , 300, "%s/galice.root" , fReadDir.Data());
338 snprintf(clusterName , 300, "%s/MFT.RecPoints.root", fReadDir.Data());
820b4d9e 339
340 // Import TGeo geometry (needed by AliMUONTrackExtrap::ExtrapToVertex)
341 if (!gGeoManager) {
342 TGeoManager::Import(geoFileName);
343 if (!gGeoManager) {
d4643a10 344 AliError(Form("getting geometry from file %s failed", geoFileName));
820b4d9e 345 return;
346 }
347 }
348
349 fFileESD = new TFile(esdFileName);
350 if (!fFileESD || !fFileESD->IsOpen()) return;
d4643a10 351 else AliInfo(Form("file %s successfully opened\n", fFileESD->GetName()));
820b4d9e 352
353 fMuonRecoCheck = new AliMUONRecoCheck(esdFileName, Form("%s/generated/", fReadDir.Data())); // Utility class to check reconstruction
354 fFile_gAlice = new TFile(gAliceName);
355 if (!fFile_gAlice || !fFile_gAlice->IsOpen()) return;
d4643a10 356 else AliInfo(Form("file %s successfully opened\n", fFile_gAlice->GetName()));
820b4d9e 357
358 fRunLoader = AliRunLoader::Open(gAliceName);
359 gAlice = fRunLoader->GetAliRun();
360 if (!gAlice) fRunLoader->LoadgAlice();
361 fMFT = (AliMFT*) gAlice->GetDetector("MFT");
362 fSegmentation = fMFT->GetSegmentation();
363 SetNPlanesMFT(fSegmentation->GetNPlanes());
364
365 if (!SetRunNumber()) return;
366 if (!InitGRP()) return;
367 AliMUONTrackExtrap::SetField(); // set the magnetic field for track extrapolations
368
369 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
370 fZPlane[iPlane] = fSegmentation->GetPlane(iPlane)->GetZCenter();
371 fRPlaneMax[iPlane] = fSegmentation->GetPlane(iPlane)->GetRMaxSupport();
372 fRPlaneMin[iPlane] = fSegmentation->GetPlane(iPlane)->GetRMinSupport();
373 }
374
375 // Loading MFT clusters
376 fMFTLoader = fRunLoader->GetDetectorLoader("MFT");
377 fMFTLoader->LoadRecPoints("READ");
378
379 fMFTClusterTree = fMFTLoader->TreeR();
380
820b4d9e 381 Int_t nEventsInFile = fMuonRecoCheck->NumberOfEvents();
382 if (!nEventsInFile) {
d4643a10 383 AliError("no events available!!!\n");
820b4d9e 384 return;
385 }
386 if (nEventsInFile<nEventsToAnalyze || nEventsToAnalyze<0) fNEventsToAnalyze = nEventsInFile;
387 else fNEventsToAnalyze = nEventsToAnalyze;
388
d4643a10 389 fCandidateTracks = new TClonesArray("AliMuonForwardTrack",50000);
820b4d9e 390
391 // -------------------------- initializing histograms...
392
d4643a10 393 AliInfo("\ninitializing histograms...\n");
820b4d9e 394 BookHistos();
395 SetTitleHistos();
d4643a10 396 AliInfo("... done!\n\n");
820b4d9e 397
398 // -------------------------- initializing graphics...
399
d4643a10 400 AliInfo("initializing graphics...\n");
820b4d9e 401 BookPlanes();
d4643a10 402 AliInfo("... done!\n\n");
820b4d9e 403
404 SetSigmaSpectrometerCut(4.0);
405 SetSigmaClusterCut(4.5);
406 SetChi2GlobalCut(2.0);
407 SetNFinalCandidatesCut(10);
408 SetRAbsorberCut(26.4);
409 SetLowPtCut(0.5);
820b4d9e 410
411}
412
413//======================================================================================================================================
414
415Bool_t AliMuonForwardTrackFinder::LoadNextEvent() {
416
417 // load next reconstructed event from the tree
418
419 if (fEv) FillOutputTree();
420
421 if (fEv>=fNEventsToAnalyze) return kFALSE;
422
423 fCountRealTracksAnalyzedOfEvent = 0;
424
d4643a10 425 AliInfo(Form(" **** analyzing event # %d \n", fEv));
820b4d9e 426
58b93f36 427 fTrackStore = fMuonRecoCheck->ReconstructedTracks(fEv);
428 if (fTrackStore->IsEmpty()) {
429 AliInfo("fTrackStore Is Empty: exiting NOW!");
430 return kFALSE;
431 }
432 AliInfo("fTrackStore contains tracks!");
433
434 AliDebug(2, Form("Getting fMuonRecoCheck->ReconstructibleTracks(%d)", fEv));
820b4d9e 435 fTrackRefStore = fMuonRecoCheck->ReconstructibleTracks(fEv);
436
58b93f36 437 AliDebug(2, Form("Getting fRunLoader->GetEvent(%d)", fEv));
820b4d9e 438 fRunLoader->GetEvent(fEv);
58b93f36 439
440 AliDebug(2, Form("fMFTLoader->TreeR() = %p",fMFTLoader->TreeR()));
820b4d9e 441 if (!fMFTLoader->TreeR()->GetEvent()) return kFALSE;
442 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
d4643a10 443 AliDebug(1, Form("plane %02d: nClusters = %d\n", iPlane, (fMFT->GetRecPointsList(iPlane))->GetEntries()));
820b4d9e 444 fMFTClusterArray[iPlane] = fMFT->GetRecPointsList(iPlane);
445 }
446 SeparateFrontBackClusters();
447
448 fRunLoader -> LoadKinematics();
449 fStack = fRunLoader->Stack();
450 fNextTrack = fTrackStore->CreateIterator();
b5ab1ac4 451 fMuonForwardTracks->Delete();
820b4d9e 452
453 fEv++;
454
455 return kTRUE;
456
457}
458
459//======================================================================================================================================
460
461Int_t AliMuonForwardTrackFinder::LoadNextTrack() {
462
463 fNPlanesMFTAnalyzed = 0;
464
465 // load next muon track from the reconstructed event
466
a2b7dc2a 467 if (fCountRealTracksAnalyzed>=fMaxNTracksToBeAnalyzed) return kFALSE;
820b4d9e 468 if (!fCountRealTracksAnalyzed) if (!LoadNextEvent()) return kFALSE;
a2b7dc2a 469
470 if (!fGlobalTrackingDiverged) {
471 while ( !(fMuonTrackReco = static_cast<AliMUONTrack*>(fNextTrack->Next())) ) if (!LoadNextEvent()) return kFALSE;
d4643a10 472 fCountRealTracksAnalyzed++;
a2b7dc2a 473 fCountRealTracksAnalyzedOfEvent++;
d4643a10 474 }
820b4d9e 475
d4643a10 476 AliDebug(1, "**************************************************************************************\n");
477 AliDebug(1, Form("*************************** MUON TRACK %3d ***************************************\n", fCountRealTracksAnalyzedOfEvent));
478 AliDebug(1, "**************************************************************************************\n");
820b4d9e 479
b5ab1ac4 480 fCandidateTracks -> Delete();
820b4d9e 481
482 fLabelMC = -1;
483 fDistanceFromGoodClusterAndTrackAtLastPlane = -1.;
484 fDistanceFromBestClusterAndTrackAtLastPlane = -1.;
485 ResetPlanes();
486
487 TIter nextTrackRef(fTrackRefStore->CreateIterator());
488 AliMUONTrack *trackRef=0;
489
490 // --------------------------------------- loop on MC generated tracks to find the MC reference...
491
492 while ( (trackRef = static_cast<AliMUONTrack*>(nextTrackRef())) ) {
493 // number of compatible clusters between trackReco and trackRef
494 Int_t nMatchCluster = fMuonTrackReco->FindCompatibleClusters(*trackRef, fSigmaSpectrometerCut, fIsClusterCompatible);
495 if ( (fIsClusterCompatible[0] || fIsClusterCompatible[1] || fIsClusterCompatible[2] || fIsClusterCompatible[3]) && // before the dipole
496 (fIsClusterCompatible[6] || fIsClusterCompatible[7] || fIsClusterCompatible[8] || fIsClusterCompatible[9]) && // after the dipole
497 2*nMatchCluster>fMuonTrackReco->GetNClusters() ) {
498 fMuonTrackReco->SetMCLabel(trackRef->GetUniqueID()); // MC reference has been found for trackReco!
499 break;
500 }
501 }
502
503 // ------------------------------------- ...done!
504
820b4d9e 505 fLabelMC = fMuonTrackReco->GetMCLabel();
506
6e8e4c4a 507 Int_t motherPdg=0;
508 if (fLabelMC>=0) {
a2b7dc2a 509 if (!fGlobalTrackingDiverged) fCountRealTracksWithRefMC++;
6e8e4c4a 510 if (fStack->Particle(fLabelMC)->GetFirstMother() != -1) {
511 motherPdg = fStack->Particle(fStack->Particle(fLabelMC)->GetFirstMother())->GetPdgCode();
512 }
513 }
514
820b4d9e 515 CheckCurrentMuonTrackable();
516
a2b7dc2a 517 if (!fGlobalTrackingDiverged) if (fMuonTrackReco->GetMatchTrigger()) fCountRealTracksWithRefMC_andTrigger++;
820b4d9e 518
519 // the track we are going to build, starting from fMuonTrackReco and adding the MFT clusters
520 AliMuonForwardTrack *track = new ((*fCandidateTracks)[0]) AliMuonForwardTrack();
ff80c017 521 track -> SetMUONTrack(new AliMUONTrack(*fMuonTrackReco));
522 if (fLabelMC>=0 && fStack->Particle(fLabelMC)) track->SetMCTrackRef(new TParticle(*(fStack->Particle(fLabelMC))));
820b4d9e 523 track -> SetMCLabel(fMuonTrackReco->GetMCLabel());
524 track -> SetMatchTrigger(fMuonTrackReco->GetMatchTrigger());
b03d16a3 525
526 // track origin
527 Double_t xVtx=-999., yVtx=-999., zVtx=-999999.;
528 if (track->GetMCTrackRef()) {
529 xVtx = track->GetMCTrackRef()->Vx();
530 yVtx = track->GetMCTrackRef()->Vy();
531 zVtx = track->GetMCTrackRef()->Vz();
532 }
533
534 // track kinematics
535 Double_t pt=-999., theta=-999., eta=-999.;
536 if (track->GetMCTrackRef()) {
537 pt = track->GetMCTrackRef()->Pt();
538 theta = track->GetMCTrackRef()->Theta();
539 if (theta<0.) theta += TMath::Pi();
540 eta = track->GetMCTrackRef()->Eta();
541 }
542 else {
543 AliMUONTrackParam *param = (AliMUONTrackParam*) (fMuonTrackReco->GetTrackParamAtCluster()->First());
544 pt = TMath::Sqrt(param->Px()*param->Px() + param->Py()*param->Py());
545 theta = TMath::ATan(pt/param->Pz());
546 if (theta<0.) theta += TMath::Pi();
547 eta = -1.*TMath::Log(TMath::Tan(0.5*theta));
548 }
549 // if the transverse momentum is smaller than the threshold, skip to the next track
550 if (pt < fLowPtCut) return 3;
820b4d9e 551
552 // track parameters linearly extrapolated from the first tracking station to the end of the absorber
553 AliMUONTrackParam trackParamEndOfAbsorber(*((AliMUONTrackParam*)(fMuonTrackReco->GetTrackParamAtCluster()->First())));
554 AliMUONTrackExtrap::ExtrapToZCov(&trackParamEndOfAbsorber, -503.); // absorber extends from -90 to -503 cm
555 Double_t xEndOfAbsorber = trackParamEndOfAbsorber.GetNonBendingCoor();
556 Double_t yEndOfAbsorber = trackParamEndOfAbsorber.GetBendingCoor();
557 Double_t rAbsorber = TMath::Sqrt(xEndOfAbsorber*xEndOfAbsorber + yEndOfAbsorber*yEndOfAbsorber);
558 fHistRadiusEndOfAbsorber -> Fill(rAbsorber);
559
b03d16a3 560 // if the radial distance of the track at the end of the absorber is smaller than a given radius, skip to the next track
820b4d9e 561 if (rAbsorber < fRAbsorberCut) return 4;
562
563 //------------------------- NOW THE CYCLE OVER THE MFT PLANES STARTS ---------------------------------------
564
565 for (Int_t iPlane=fNPlanesMFT-1; iPlane>=0; iPlane--) { // *** do not reverse the order of this cycle!!!
566 // *** this reflects the fact that the extrapolation is performed
567 // *** starting from the last MFT plane back to the origin
568
569 // --------- updating the array of tracks according to the clusters available in the i-th plane ---------
570
571 fNPlanesMFTAnalyzed++;
572
573 if (fMatchingMode==kRealMatching) {
574 Int_t nTracksToBeAnalyzed = fCandidateTracks->GetEntriesFast();
575 for (Int_t iTrack=0; iTrack<nTracksToBeAnalyzed; iTrack++) {
576 fCurrentTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(iTrack);
577 // if the old track is compatible with the new cluster, the track is updated and inserted as new track in the array
578 // (several new tracks can be created for one old track)
a2b7dc2a 579 if (FindClusterInPlane(iPlane) == 2) {
580 fGlobalTrackingDiverged = kTRUE;
581 if (fScaleSigmaClusterCut>0) fScaleSigmaClusterCut -= 0.1;
582 return 6;
583 }
820b4d9e 584 if ((fNPlanesMFTAnalyzed-fCurrentTrack->GetNMFTClusters())>fNMaxMissingMFTClusters || fIsPlaneMandatory[iPlane]) {
585 fCandidateTracks->Remove(fCurrentTrack); // the old track is removed after the check;
586 }
587 }
588 fCandidateTracks->Compress();
d4643a10 589 if (fIsCurrentMuonTrackable) {
590 // fOutputQAFile->cd();
591 fHistNTracksAfterExtrapolation[iPlane] -> Fill(fCandidateTracks->GetEntriesFast());
592 }
820b4d9e 593 }
594
d4643a10 595 else if (fMatchingMode==kIdealMatching && fIsCurrentMuonTrackable) {
820b4d9e 596 fCurrentTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(0);
d4643a10 597 AliDebug(2, Form("plane %02d: fCandidateTracks->GetEntriesFast() = %d fCandidateTracks->UncheckedAt(0) = %p fCurrentTrack = %p\n",
598 iPlane, fCandidateTracks->GetEntriesFast(), fCandidateTracks->UncheckedAt(0), fCurrentTrack));
820b4d9e 599 AttachGoodClusterInPlane(iPlane);
600 }
601
602 }
603
604 // -------------------------- END OF THE CYCLE OVER THE MFT PLANES --------------------------------------------
605
a2b7dc2a 606 fGlobalTrackingDiverged = kFALSE;
607 fScaleSigmaClusterCut = 1.0;
608
d4643a10 609 AliDebug(1, "Finished cycle over planes");
610
b03d16a3 611 Double_t momentum = pt * TMath::CosH(eta);
d4643a10 612 fTxtTrackMomentum = new TLatex(0.10, 0.70, Form("P_{spectro} = %3.1f GeV/c", momentum));
613
820b4d9e 614 if (fMatchingMode==kIdealMatching) {
d4643a10 615 AliDebug(1, "Adding track to output tree...\n");
616 fFinalBestCandidate = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(0);
820b4d9e 617 AliMuonForwardTrack *newTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(0);
d4643a10 618 new ((*fMuonForwardTracks)[fMuonForwardTracks->GetEntries()]) AliMuonForwardTrack(*newTrack);
619 AliDebug(1, "...track added!\n");
b5ab1ac4 620 fCandidateTracks->Delete();
820b4d9e 621 fCountRealTracksAnalyzedOfEvent++;
d4643a10 622 fCountRealTracksAnalyzedWithFinalCandidates++;
623 PrintParticleHistory();
624 FillPlanesWithTrackHistory();
625
626 Double_t chi2AtPlane[fNMaxPlanes] = {0};
627 Int_t nGoodClusters = 0;
628 Int_t nMFTClusters = fFinalBestCandidate->GetNMFTClusters();
629// Int_t nMUONClusters = fFinalBestCandidate->GetNMUONClusters();
630 Int_t plane = 0;
631 for (Int_t iCluster=0; iCluster<nMFTClusters; iCluster++) {
632 while (!fFinalBestCandidate->PlaneExists(plane)) plane++;
633 AliMFTCluster *localCluster = fFinalBestCandidate->GetMFTCluster(iCluster);
634 chi2AtPlane[plane] = localCluster->GetLocalChi2();
635 if (IsCorrectMatch(localCluster)) nGoodClusters++;
636// Int_t nClustersGlobalTrack = nMUONClusters + (nMFTClusters-iCluster); // Muon Spectrometer clusters + clusters in the Vertex Telescope
637// Int_t ndfGlobalTrack = GetNDF(nClustersGlobalTrack);
638// chi2AtPlane[plane] /= Double_t(ndfGlobalTrack);
639 plane++;
640 }
641 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
642 fTxtTrackChi2[iPlane] = new TLatex(0.55*fRPlaneMax[fNPlanesMFT-1],
643 0.90*fRPlaneMax[fNPlanesMFT-1],
644 Form("#chi^{2} = %3.1f", chi2AtPlane[iPlane]));
645 }
646 fTxtTrackFinalChi2 = new TLatex(0.20, 0.44, Form("#chi^{2}_{final} = %3.1f", chi2AtPlane[0]));
647
648 if (fDrawOption) DrawPlanes();
820b4d9e 649 return 5;
650 }
d4643a10 651
820b4d9e 652 // If we have several final tracks, we must find the best candidate:
653
654 Int_t nFinalTracks = fCandidateTracks->GetEntriesFast();
d4643a10 655 AliDebug(1, Form("nFinalTracks = %d", nFinalTracks));
820b4d9e 656
657 if (nFinalTracks) fCountRealTracksAnalyzedWithFinalCandidates++;
658
659 Double_t theVariable_Best = -1.; // variable defining the best candidate
660 Bool_t bestCandidateExists = kFALSE;
661 Int_t nGoodClustersBestCandidate = 0;
662 Int_t idBestCandidate = 0;
d4643a10 663 Double_t chi2HistoryForBestCandidate[fNMaxPlanes] = {0}; // chi2 on each plane, for the best candidate
664 Double_t nClustersPerPlane[fNMaxPlanes] = {0};
665 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
666 chi2HistoryForBestCandidate[iPlane] = -1.;
667 nClustersPerPlane[iPlane] = fMFTClusterArray[iPlane] -> GetEntries();
668 }
820b4d9e 669
670 fTxtFinalCandidates = new TLatex(0.10, 0.78, Form("N_{FinalCandidates} = %d", nFinalTracks));
671
672 Int_t nClustersMC = 0;
673 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) nClustersMC += fIsGoodClusterInPlane[iPlane];
674
675 for (Int_t iTrack=0; iTrack<nFinalTracks; iTrack++) {
676
677 AliMuonForwardTrack *finalTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(iTrack);
678
d4643a10 679 Double_t chi2AtPlane[fNMaxPlanes] = {0};
820b4d9e 680 Int_t nGoodClusters = 0;
681 Int_t nMFTClusters = finalTrack->GetNMFTClusters();
d4643a10 682// Int_t nMUONClusters = finalTrack->GetNMUONClusters();
820b4d9e 683
684 Int_t plane = 0;
685 for (Int_t iCluster=0; iCluster<nMFTClusters; iCluster++) {
686 while (!finalTrack->PlaneExists(plane)) plane++;
687 AliMFTCluster *localCluster = finalTrack->GetMFTCluster(iCluster);
d4643a10 688 chi2AtPlane[plane] = localCluster->GetLocalChi2();
820b4d9e 689 if (IsCorrectMatch(localCluster)) nGoodClusters++;
d4643a10 690// Int_t nClustersGlobalTrack = nMUONClusters + (nMFTClusters-iCluster); // Muon Spectrometer clusters + clusters in the Vertex Telescope
691// Int_t ndfGlobalTrack = GetNDF(nClustersGlobalTrack);
692// chi2AtPlane[plane] /= Double_t(ndfGlobalTrack);
693 plane++;
820b4d9e 694 }
695
d4643a10 696 if (fIsCurrentMuonTrackable) {
697 // fOutputQAFile->cd();
698 fHistNGoodClustersForFinalTracks -> Fill(nGoodClusters);
699 }
700
701 // fOutputQAFile->cd();
702
703 Float_t finalCandidatesInfo[] = {Double_t(fRun),
704 Double_t(fEv),
705 Double_t(fCountRealTracksAnalyzedOfEvent),
706 Double_t(nFinalTracks),
b03d16a3 707 Double_t(fLabelMC>=0),
708 xVtx, yVtx, zVtx,
6e8e4c4a 709 motherPdg,
b03d16a3 710 Double_t(fMuonTrackReco->GetMatchTrigger()),
d4643a10 711 Double_t(nClustersMC),
712 Double_t(nGoodClusters),
b03d16a3 713 pt, theta, eta,
d4643a10 714 chi2AtPlane[0],
715 chi2AtPlane[1],
716 chi2AtPlane[2],
717 chi2AtPlane[3],
718 chi2AtPlane[4],
719 chi2AtPlane[5],
720 chi2AtPlane[6],
721 chi2AtPlane[7],
722 chi2AtPlane[8]};
820b4d9e 723
d4643a10 724 fNtuFinalCandidates -> Fill(finalCandidatesInfo);
725
820b4d9e 726 // now comparing the tracks with various criteria, in order to find the best one
727
728 Double_t theVariable = 0.;
d4643a10 729// theVariable = chi2AtPlane[0];
820b4d9e 730 for (Int_t iCluster=0; iCluster<nMFTClusters; iCluster++) theVariable += chi2AtPlane[iCluster];
731 theVariable /= Double_t(nMFTClusters);
d4643a10 732
820b4d9e 733
734 if (theVariable<theVariable_Best || theVariable_Best<0.) {
735 nGoodClustersBestCandidate = nGoodClusters;
736 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) chi2HistoryForBestCandidate[iPlane] = chi2AtPlane[iPlane];
737 theVariable_Best = theVariable;
d4643a10 738 fTxtTrackFinalChi2 = new TLatex(0.20, 0.44, Form("#chi^{2}_{final} = %3.1f", chi2HistoryForBestCandidate[0]));
820b4d9e 739 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
740 fTxtTrackChi2[iPlane] = new TLatex(0.55*fRPlaneMax[fNPlanesMFT-1],
741 0.90*fRPlaneMax[fNPlanesMFT-1],
742 Form("#chi^{2} = %3.1f", chi2AtPlane[iPlane]));
743 }
744 idBestCandidate = iTrack;
745 bestCandidateExists=kTRUE;
746 }
747
748 // ----------------------------------------------------------
749
750 }
d4643a10 751
820b4d9e 752 if (nFinalTracks) {
d4643a10 753 fFinalBestCandidate = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(idBestCandidate);
754 AliInfo(Form("fFinalBestCandidate->GetNMFTClusters() = %d\n", fFinalBestCandidate->GetNMFTClusters()));
755 PrintParticleHistory();
756 FillPlanesWithTrackHistory();
820b4d9e 757 AliMuonForwardTrack *newTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(idBestCandidate);
d4643a10 758 newTrack -> SetNWrongClustersMC(newTrack->GetNMFTClusters() - nGoodClustersBestCandidate);
7e3dd1af 759 newTrack -> SetTrackMCId(fRun*100000+fEv*1000+fCountRealTracksAnalyzedOfEvent);
d4643a10 760 new ((*fMuonForwardTracks)[fMuonForwardTracks->GetEntries()]) AliMuonForwardTrack(*newTrack);
7230691d 761 }
d4643a10 762
763 // fOutputQAFile->cd();
764
765 Float_t finalBestCandidatesInfo[] = {Double_t(fRun),
766 Double_t(fEv),
767 Double_t(fCountRealTracksAnalyzedOfEvent),
768 Double_t(nFinalTracks),
b03d16a3 769 Double_t(fLabelMC>=0),
770 xVtx, yVtx, zVtx,
6e8e4c4a 771 motherPdg,
b03d16a3 772 Double_t(fMuonTrackReco->GetMatchTrigger()),
d4643a10 773 Double_t(nClustersMC),
774 Double_t(nGoodClustersBestCandidate),
b03d16a3 775 pt, theta, eta,
d4643a10 776 chi2HistoryForBestCandidate[0],
777 chi2HistoryForBestCandidate[1],
778 chi2HistoryForBestCandidate[2],
779 chi2HistoryForBestCandidate[3],
780 chi2HistoryForBestCandidate[4],
781 chi2HistoryForBestCandidate[5],
782 chi2HistoryForBestCandidate[6],
783 chi2HistoryForBestCandidate[7],
784 chi2HistoryForBestCandidate[8],
785 nClustersPerPlane[0],
786 nClustersPerPlane[1],
787 nClustersPerPlane[2],
788 nClustersPerPlane[3],
789 nClustersPerPlane[4],
790 nClustersPerPlane[5],
791 nClustersPerPlane[6],
792 nClustersPerPlane[7],
793 nClustersPerPlane[8]};
794
795 fNtuFinalBestCandidates -> Fill(finalBestCandidatesInfo);
820b4d9e 796
797 if (fDrawOption && bestCandidateExists) {
d4643a10 798 fTxtTrackGoodClusters = new TLatex(0.20, 0.51, Form("N_{GoodClusters} = %d", nGoodClustersBestCandidate));
820b4d9e 799 DrawPlanes();
800 }
801
820b4d9e 802 // -------------------------------------------------------------------------------------------
803
b5ab1ac4 804 fCandidateTracks->Delete();
d4643a10 805 fFinalBestCandidate = NULL;
820b4d9e 806
820b4d9e 807 return 5;
808
809}
810
811//===========================================================================================================================================
812
a2b7dc2a 813Int_t AliMuonForwardTrackFinder::FindClusterInPlane(Int_t planeId) {
820b4d9e 814
d4643a10 815 AliDebug(2, Form(">>>> executing AliMuonForwardTrackFinder::FindClusterInPlane(%d)\n", planeId));
820b4d9e 816
817 // !!!!!!!!! coordinates and errors on the interaction vertex should be taken from the event itself (ITS) if available
818
819 // propagate track to plane #planeId (both to front and back active sensors)
820 // look for compatible clusters
821 // update TrackParam at found cluster (if any) using Kalman Filter
822
823 AliMUONTrackParam currentParamFront, currentParamBack, currentParamForResearchFront, currentParamForResearchBack;
824
825 if (planeId == fNPlanesMFT-1) { // last plane of the telecope
826 currentParamFront = (*((AliMUONTrackParam*)(fMuonTrackReco->GetTrackParamAtCluster()->First())));
827 currentParamBack = (*((AliMUONTrackParam*)(fMuonTrackReco->GetTrackParamAtCluster()->First())));
828 currentParamForResearchFront = currentParamFront;
829 currentParamForResearchBack = currentParamBack;
b03d16a3 830 Double_t xExtrap = gRandom->Gaus(0,fVertexErrorX);
831 Double_t yExtrap = gRandom->Gaus(0,fVertexErrorY);
832 Double_t zExtrap = gRandom->Gaus(0,fVertexErrorZ);
7e3dd1af 833 if (fBransonCorrection) {
834 AliMUONTrackExtrap::ExtrapToVertex(&currentParamFront, xExtrap, yExtrap, zExtrap, fVertexErrorX, fVertexErrorY);
835 AliMUONTrackExtrap::ExtrapToVertex(&currentParamBack, xExtrap, yExtrap, zExtrap, fVertexErrorX, fVertexErrorY);
836 }
837 else {
838 AliMUONTrackExtrap::ExtrapToVertexWithoutBranson(&currentParamFront, zExtrap);
839 AliMUONTrackExtrap::ExtrapToVertexWithoutBranson(&currentParamBack, zExtrap);
840 }
b03d16a3 841 AliMUONTrackExtrap::ExtrapToVertex(&currentParamForResearchFront, xExtrap, yExtrap, zExtrap, fVertexErrorX, fVertexErrorY);
842 AliMUONTrackExtrap::ExtrapToVertex(&currentParamForResearchBack, xExtrap, yExtrap, zExtrap, fVertexErrorX, fVertexErrorY);
820b4d9e 843 }
844 else { // MFT planes others than the last one: mult. scattering correction because of the upstream MFT planes is performed
845 currentParamFront = (*((AliMUONTrackParam*)(fCurrentTrack->GetTrackParamAtCluster()->First())));
846 currentParamBack = (*((AliMUONTrackParam*)(fCurrentTrack->GetTrackParamAtCluster()->First())));
847 currentParamForResearchFront = currentParamFront;
848 currentParamForResearchBack = currentParamBack;
849 AliMUONTrackExtrap::AddMCSEffect(&currentParamFront, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
d4643a10 850 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeFront())/fRadLengthSi,-1.);
820b4d9e 851 AliMUONTrackExtrap::AddMCSEffect(&currentParamForResearchFront,(fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
d4643a10 852 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeFront())/fRadLengthSi,-1.);
820b4d9e 853 AliMUONTrackExtrap::AddMCSEffect(&currentParamBack, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
d4643a10 854 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeBack())/fRadLengthSi,-1.);
820b4d9e 855 AliMUONTrackExtrap::AddMCSEffect(&currentParamForResearchBack, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
d4643a10 856 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeBack())/fRadLengthSi,-1.);
820b4d9e 857 }
858 // for all planes: extrapolation to the Z of the plane
859 AliMUONTrackExtrap::ExtrapToZCov(&currentParamFront, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveFront());
860 AliMUONTrackExtrap::ExtrapToZCov(&currentParamForResearchFront, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveFront());
861 AliMUONTrackExtrap::ExtrapToZCov(&currentParamBack, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveBack());
862 AliMUONTrackExtrap::ExtrapToZCov(&currentParamForResearchBack, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveBack());
863
864 //---------------------------------------------------------------------------------------
865
866 TMatrixD covFront(5,5); covFront = currentParamForResearchFront.GetCovariances();
867 TMatrixD covBack(5,5); covBack = currentParamForResearchBack.GetCovariances();
868
869 Double_t squaredError_X_Front = covFront(0,0);
870 Double_t squaredError_Y_Front = covFront(2,2);
871 Double_t squaredError_X_Back = covBack(0,0);
872 Double_t squaredError_Y_Back = covBack(2,2);
873
874 Double_t corrFact = 1.0;
875
876 Double_t researchRadiusFront = TMath::Sqrt(squaredError_X_Front + squaredError_Y_Front);
877 Double_t researchRadiusBack = TMath::Sqrt(squaredError_X_Back + squaredError_Y_Back);
b5ab1ac4 878 if (0.5*(researchRadiusFront+researchRadiusBack)<fMinResearchRadiusAtPlane[planeId]) {
879 corrFact = fMinResearchRadiusAtPlane[planeId]/(0.5*(researchRadiusFront+researchRadiusBack));
820b4d9e 880 }
d4643a10 881 if (fIsCurrentMuonTrackable) {
882 // fOutputQAFile->cd();
883 fHistResearchRadius[planeId] -> Fill(0.5*(researchRadiusFront+researchRadiusBack));
884 }
820b4d9e 885
886 Double_t position_X_Front = currentParamForResearchFront.GetNonBendingCoor();
887 Double_t position_Y_Front = currentParamForResearchFront.GetBendingCoor();
888 Double_t position_X_Back = currentParamForResearchBack.GetNonBendingCoor();
889 Double_t position_Y_Back = currentParamForResearchBack.GetBendingCoor();
890 Double_t radialPositionOfTrackFront = TMath::Sqrt(position_X_Front*position_X_Front + position_Y_Front*position_Y_Front);
891 Double_t radialPositionOfTrackBack = TMath::Sqrt(position_X_Back*position_X_Back + position_Y_Back*position_Y_Back);
892
893 //---------------------------------------------------------------------------------------
894
a2b7dc2a 895 Double_t chi2cut = 2.*fScaleSigmaClusterCut*fScaleSigmaClusterCut*fSigmaClusterCut*fSigmaClusterCut; // depends on the number of variables (here, 2)
820b4d9e 896
897 // Analyizing the clusters: FRONT ACTIVE ELEMENTS
898
899 Int_t nClustersFront = fMFTClusterArrayFront[planeId]->GetEntries();
d4643a10 900 AliDebug(2, Form("There are %3d clusters in plane %02d FRONT\n", nClustersFront, planeId));
820b4d9e 901
902 for (Int_t iCluster=0; iCluster<nClustersFront; iCluster++) {
903
904 Bool_t isGoodChi2 = kFALSE;
905
906 AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArrayFront[planeId]->At(iCluster);
907 Double_t chi2 = (1./(corrFact*corrFact)) * TryOneCluster(currentParamForResearchFront, cluster); // describes the compatibility between the track and the cluster
908 if (chi2<chi2cut) isGoodChi2 = kTRUE;
909
910 Double_t radialPositionOfClusterFront = TMath::Sqrt(cluster->GetX()*cluster->GetX() + cluster->GetY()*cluster->GetY());
911 if (planeId == fNPlanesMFT-1) {
912 if (TMath::Abs(radialPositionOfTrackFront-radialPositionOfClusterFront)<fDistanceFromBestClusterAndTrackAtLastPlane ||
913 fDistanceFromBestClusterAndTrackAtLastPlane<0.) {
914 fDistanceFromBestClusterAndTrackAtLastPlane = TMath::Abs(radialPositionOfTrackFront-radialPositionOfClusterFront);
915 }
916 if (IsCorrectMatch(cluster)) {
917 fDistanceFromGoodClusterAndTrackAtLastPlane = TMath::Abs(radialPositionOfTrackFront-radialPositionOfClusterFront);
918 }
919 }
920
921 if (fIsCurrentMuonTrackable) {
d4643a10 922 // fOutputQAFile->cd();
820b4d9e 923 if (IsCorrectMatch(cluster)) fHistChi2Cluster_GoodCluster[planeId]->Fill(chi2/2.); // chi2/ndf
924 else fHistChi2Cluster_BadCluster[planeId] ->Fill(chi2/2.); // chi2/ndf
925 }
926
927 if (isGoodChi2) {
d4643a10 928 AliDebug(3, Form("accepting cluster: chi2=%f (cut = %f)\n", chi2, chi2cut));
820b4d9e 929 AliMuonForwardTrack *newTrack = new ((*fCandidateTracks)[fCandidateTracks->GetEntriesFast()]) AliMuonForwardTrack(*fCurrentTrack);
a2b7dc2a 930 if (fCandidateTracks->GetEntriesFast() > fMaxNCandidates) return 2;
820b4d9e 931 newTrack->AddTrackParamAtMFTCluster(currentParamFront, *cluster); // creating new track param and attaching the cluster
ff80c017 932 AliDebug(2, Form("After plane %02d: newTrack->GetNMFTClusters() = %d (fCurrentTrack->GetNMFTClusters() = %d)",
d4643a10 933 planeId, newTrack->GetNMFTClusters(), fCurrentTrack->GetNMFTClusters()));
820b4d9e 934 newTrack->SetPlaneExists(planeId);
d4643a10 935 AliDebug(2, Form("current muon is trackable: %d\n", fIsCurrentMuonTrackable));
820b4d9e 936 if (fIsCurrentMuonTrackable) {
937 Double_t newGlobalChi2 = ((AliMUONTrackParam*) newTrack->GetTrackParamAtCluster()->First())->GetTrackChi2();
d4643a10 938 AliDebug(2, Form("new chi2 = %f (= %f)\n", newGlobalChi2, newTrack->GetMFTCluster(0)->GetTrackChi2()));
820b4d9e 939 Int_t nClustersGlobalTrack = newTrack->GetNMUONClusters() + newTrack->GetNMFTClusters(); // Muon Spectrometer clusters + clusters in the Vertex Telescope
940 Int_t ndfGlobalTrack = GetNDF(nClustersGlobalTrack);
d4643a10 941 // fOutputQAFile->cd();
942 if (IsCorrectMatch(cluster)) fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[planeId]->Fill(newGlobalChi2/Double_t(ndfGlobalTrack));
943 else fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[planeId] ->Fill(newGlobalChi2/Double_t(ndfGlobalTrack));
820b4d9e 944 }
d4643a10 945 fGrMFTPlane[kClustersGoodChi2][planeId] -> SetPoint(fGrMFTPlane[kClustersGoodChi2][planeId]->GetN(), cluster->GetX(), cluster->GetY());
820b4d9e 946 }
d4643a10 947 else AliDebug(3, Form("discarding cluster: chi2=%f (cut = %f)\n", chi2, chi2cut));
820b4d9e 948
949 }
950
951 // Analyizing the clusters: BACK ACTIVE ELEMENTS
952
953 Int_t nClustersBack = fMFTClusterArrayBack[planeId]->GetEntries();
d4643a10 954 AliDebug(2, Form("There are %3d clusters in plane %02d BACK\n", nClustersBack, planeId));
820b4d9e 955
956 for (Int_t iCluster=0; iCluster<nClustersBack; iCluster++) {
957
958 Bool_t isGoodChi2 = kFALSE;
959
960 AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArrayBack[planeId]->At(iCluster);
961 Double_t chi2 = (1./(corrFact*corrFact)) * TryOneCluster(currentParamForResearchBack, cluster); // describes the compatibility between the track and the cluster
962 if (chi2<chi2cut) isGoodChi2 = kTRUE;
963
964 Double_t radialPositionOfClusterBack = TMath::Sqrt(cluster->GetX()*cluster->GetX() + cluster->GetY()*cluster->GetY());
965 if (planeId == fNPlanesMFT-1) {
966 if (TMath::Abs(radialPositionOfTrackBack-radialPositionOfClusterBack)<fDistanceFromBestClusterAndTrackAtLastPlane ||
967 fDistanceFromBestClusterAndTrackAtLastPlane<0.) {
968 fDistanceFromBestClusterAndTrackAtLastPlane = TMath::Abs(radialPositionOfTrackBack-radialPositionOfClusterBack);
969 }
970 if (IsCorrectMatch(cluster)) {
971 fDistanceFromGoodClusterAndTrackAtLastPlane = TMath::Abs(radialPositionOfTrackBack-radialPositionOfClusterBack);
972 }
973 }
974
975 if (fIsCurrentMuonTrackable) {
d4643a10 976 // fOutputQAFile->cd();
820b4d9e 977 if (IsCorrectMatch(cluster)) fHistChi2Cluster_GoodCluster[planeId]->Fill(chi2/2.); // chi2/ndf
978 else fHistChi2Cluster_BadCluster[planeId] ->Fill(chi2/2.); // chi2/ndf
979 }
980
981 if (isGoodChi2) {
d4643a10 982 AliDebug(3,Form("accepting cluster: chi2=%f (cut = %f)\n", chi2, chi2cut));
820b4d9e 983 AliMuonForwardTrack *newTrack = new ((*fCandidateTracks)[fCandidateTracks->GetEntriesFast()]) AliMuonForwardTrack(*fCurrentTrack);
a2b7dc2a 984 if (fCandidateTracks->GetEntriesFast() > fMaxNCandidates) return 2;
820b4d9e 985 newTrack->AddTrackParamAtMFTCluster(currentParamBack, *cluster); // creating new track param and attaching the cluster
ff80c017 986 AliDebug(2, Form("After plane %02d: newTrack->GetNMFTClusters() = %d (fCurrentTrack->GetNMFTClusters() = %d)",
d4643a10 987 planeId, newTrack->GetNMFTClusters(), fCurrentTrack->GetNMFTClusters()));
820b4d9e 988 newTrack->SetPlaneExists(planeId);
d4643a10 989 AliDebug(2, Form("current muon is trackable: %d\n", fIsCurrentMuonTrackable));
820b4d9e 990 if (fIsCurrentMuonTrackable) {
991 Double_t newGlobalChi2 = ((AliMUONTrackParam*) newTrack->GetTrackParamAtCluster()->First())->GetTrackChi2();
d4643a10 992 AliDebug(2, Form("new chi2 = %f (= %f)\n", newGlobalChi2, newTrack->GetMFTCluster(0)->GetTrackChi2()));
820b4d9e 993 Int_t nClustersGlobalTrack = newTrack->GetNMUONClusters() + newTrack->GetNMFTClusters(); // Muon Spectrometer clusters + clusters in the Vertex Telescope
994 Int_t ndfGlobalTrack = GetNDF(nClustersGlobalTrack);
d4643a10 995 // fOutputQAFile->cd();
996 if (IsCorrectMatch(cluster)) fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[planeId]->Fill(newGlobalChi2/Double_t(ndfGlobalTrack));
997 else fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[planeId] ->Fill(newGlobalChi2/Double_t(ndfGlobalTrack));
820b4d9e 998 }
d4643a10 999 fGrMFTPlane[kClustersGoodChi2][planeId] -> SetPoint(fGrMFTPlane[kClustersGoodChi2][planeId]->GetN(), cluster->GetX(), cluster->GetY());
820b4d9e 1000 }
d4643a10 1001 else AliDebug(3,Form("discarding cluster: chi2=%f (cut = %f)\n", chi2, chi2cut));
820b4d9e 1002
1003 }
1004
1005 //---------------------------------------------------------------------------------------------
1006
1007 if (planeId == fNPlanesMFT-1) {
1008 if (fIsCurrentMuonTrackable && fDistanceFromGoodClusterAndTrackAtLastPlane>0.) {
d4643a10 1009 // fOutputQAFile->cd();
820b4d9e 1010 fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane -> Fill(TMath::Abs(fDistanceFromBestClusterAndTrackAtLastPlane-
1011 fDistanceFromGoodClusterAndTrackAtLastPlane));
1012 fHistDistanceGoodClusterFromTrackAtLastPlane -> Fill(fDistanceFromGoodClusterAndTrackAtLastPlane);
1013 }
1014 }
a2b7dc2a 1015
1016 return 0;
820b4d9e 1017
1018}
1019
1020//==========================================================================================================================================
1021
1022void AliMuonForwardTrackFinder::AttachGoodClusterInPlane(Int_t planeId) {
1023
d4643a10 1024 AliDebug(1, Form(">>>> executing AliMuonForwardTrackFinder::AttachGoodClusterInPlane(%d)\n", planeId));
820b4d9e 1025
1026 AliMUONTrackParam currentParamFront, currentParamBack;
1027
1028 if (planeId == fNPlanesMFT-1) { // last plane of the telecope
1029 currentParamFront = (*((AliMUONTrackParam*)(fMuonTrackReco->GetTrackParamAtCluster()->First())));
1030 currentParamBack = (*((AliMUONTrackParam*)(fMuonTrackReco->GetTrackParamAtCluster()->First())));
1031 AliMUONTrackExtrap::ExtrapToVertexWithoutBranson(&currentParamFront, 0.);
1032 AliMUONTrackExtrap::ExtrapToVertexWithoutBranson(&currentParamBack, 0.);
1033 }
1034 else { // MFT planes others than the last one: mult. scattering correction because of the upstream MFT planes is performed
d4643a10 1035 AliDebug(2, Form("fCurrentTrack = %p\n", fCurrentTrack));
820b4d9e 1036 currentParamFront = (*((AliMUONTrackParam*)(fCurrentTrack->GetTrackParamAtCluster()->First())));
1037 currentParamBack = (*((AliMUONTrackParam*)(fCurrentTrack->GetTrackParamAtCluster()->First())));
1038 AliMUONTrackExtrap::AddMCSEffect(&currentParamFront, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
d4643a10 1039 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeFront())/fRadLengthSi,-1.);
820b4d9e 1040 AliMUONTrackExtrap::AddMCSEffect(&currentParamBack, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
d4643a10 1041 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeBack())/fRadLengthSi,-1.);
820b4d9e 1042 }
1043 // for all planes: linear extrapolation to the Z of the plane
1044 AliMUONTrackExtrap::ExtrapToZCov(&currentParamFront, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveFront());
1045 AliMUONTrackExtrap::ExtrapToZCov(&currentParamBack, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveBack());
1046
1047 Bool_t goodClusterFound = kFALSE;
1048
1049 // Analyizing the clusters: FRONT ACTIVE ELEMENTS
1050
1051 Int_t nClustersFront = fMFTClusterArrayFront[planeId]->GetEntries();
1052
d4643a10 1053 AliDebug(1, Form("nClustersFront = %d\n", nClustersFront));
820b4d9e 1054 for (Int_t iCluster=0; iCluster<nClustersFront; iCluster++) {
1055 AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArrayFront[planeId]->UncheckedAt(iCluster);
d4643a10 1056 AliDebug(2, Form("checking cluster %02d of %02d: cluter=%p, fCurrentTrack=%p\n", iCluster, nClustersFront, cluster, fCurrentTrack));
820b4d9e 1057 if (IsCorrectMatch(cluster)) {
1058 fCurrentTrack->AddTrackParamAtMFTCluster(currentParamFront, *cluster); // creating new track param and attaching the cluster
1059 fCurrentTrack->SetPlaneExists(planeId);
1060 goodClusterFound = kTRUE;
1061 break;
1062 }
1063 }
1064
1065 if (goodClusterFound) return;
1066
1067 // Analyizing the clusters: BACK ACTIVE ELEMENTS
1068
1069 Int_t nClustersBack = fMFTClusterArrayBack[planeId]->GetEntries();
1070
d4643a10 1071 AliDebug(1, Form("nClustersBack = %d\n", nClustersBack));
820b4d9e 1072 for (Int_t iCluster=0; iCluster<nClustersBack; iCluster++) {
1073 AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArrayBack[planeId]->UncheckedAt(iCluster);
d4643a10 1074 AliDebug(2,Form("checking cluster %02d of %02d: cluter=%p, fCurrentTrack=%p\n", iCluster, nClustersBack, cluster, fCurrentTrack));
820b4d9e 1075 if (IsCorrectMatch(cluster)) {
1076 fCurrentTrack->AddTrackParamAtMFTCluster(currentParamBack, *cluster); // creating new track param and attaching the cluster
1077 fCurrentTrack->SetPlaneExists(planeId);
1078 goodClusterFound = kTRUE;
1079 break;
1080 }
1081 }
1082
1083}
1084
1085//==========================================================================================================================================
1086
1087void AliMuonForwardTrackFinder::CheckCurrentMuonTrackable() {
1088
1089 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
1090 fIsGoodClusterInPlane[iPlane] = kFALSE;
1091 Int_t nClusters = fMFTClusterArray[iPlane]->GetEntriesFast();
1092 for (Int_t iCluster=0; iCluster<nClusters; iCluster++) {
1093 AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArray[iPlane]->At(iCluster);
1094 for (Int_t iTrack=0; iTrack<cluster->GetNMCTracks(); iTrack++) {
1095 if (cluster->GetMCLabel(iTrack)==fLabelMC) {
1096 fIsGoodClusterInPlane[iPlane] = kTRUE;
1097 break;
1098 }
1099 }
1100 }
1101 }
1102
1103 fIsCurrentMuonTrackable = kTRUE;
1104 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) fIsCurrentMuonTrackable = (fIsCurrentMuonTrackable&&fIsGoodClusterInPlane[iPlane]);
1105
1106}
1107
1108//==========================================================================================================================================
1109
d4643a10 1110void AliMuonForwardTrackFinder::FillPlanesWithTrackHistory() {
820b4d9e 1111
d4643a10 1112 // Fill planes with the clusters
820b4d9e 1113
d4643a10 1114 Int_t cluster = 0;
1115 AliDebug(2, Form("fFinalBestCandidate->GetNMFTClusters() = %d\n", fFinalBestCandidate->GetNMFTClusters()));
820b4d9e 1116 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
d4643a10 1117 if (fFinalBestCandidate->PlaneExists(iPlane)) {
1118 AliMFTCluster *trackCluster = fFinalBestCandidate->GetMFTCluster(cluster++);
1119 fGrMFTPlane[kClusterOfTrack][iPlane] -> SetPoint(fGrMFTPlane[kClusterOfTrack][iPlane]->GetN(), trackCluster->GetX(), trackCluster->GetY());
1120 }
820b4d9e 1121 Int_t nClusters = fMFTClusterArray[iPlane]->GetEntriesFast();
820b4d9e 1122 for (Int_t iCluster=0; iCluster<nClusters; iCluster++) {
d4643a10 1123 AliMFTCluster *myCluster = (AliMFTCluster*) fMFTClusterArray[iPlane]->UncheckedAt(iCluster);
1124 fGrMFTPlane[kAllClusters][iPlane] -> SetPoint(fGrMFTPlane[kAllClusters][iPlane]->GetN(), myCluster->GetX(), myCluster->GetY());
1125 if (IsCorrectMatch(myCluster)) {
1126 fGrMFTPlane[kClusterCorrectMC][iPlane] -> SetPoint(fGrMFTPlane[kClusterCorrectMC][iPlane]->GetN(), myCluster->GetX(), myCluster->GetY());
820b4d9e 1127 }
820b4d9e 1128 }
820b4d9e 1129 }
1130
1131}
1132
1133//======================================================================================================================================
1134
1135Bool_t AliMuonForwardTrackFinder::IsCorrectMatch(AliMFTCluster *cluster) {
1136
1137 Bool_t result = kFALSE;
1138
1139 // check if the cluster belongs to the correct MC track
1140
1141 for (Int_t iTrack=0; iTrack<cluster->GetNMCTracks(); iTrack++) {
1142 if (cluster->GetMCLabel(iTrack)==fLabelMC) {
1143 result = kTRUE;
1144 break;
1145 }
1146 }
1147
d4643a10 1148 AliDebug(2,Form("returning %d\n", result));
820b4d9e 1149
1150 return result;
1151
1152}
1153
1154//======================================================================================================================================
1155
1156Double_t AliMuonForwardTrackFinder::TryOneCluster(const AliMUONTrackParam &trackParam, AliMFTCluster *cluster) {
1157
1158 // Test the compatibility between the track and the cluster (using trackParam's covariance matrix):
1159 // return the corresponding Chi2
1160 // assume the track parameters are given at the Z of the cluster
1161
1162 // Set differences between trackParam and cluster in the bending and non bending directions
1163 Double_t dX = cluster->GetX() - trackParam.GetNonBendingCoor();
1164 Double_t dY = cluster->GetY() - trackParam.GetBendingCoor();
d4643a10 1165 AliDebug(3,Form("dX = %f, dY = %f\n", dX, dY));
820b4d9e 1166
1167 // Calculate errors and covariances
1168 const TMatrixD& kParamCov = trackParam.GetCovariances();
1169 Double_t sigmaX2 = kParamCov(0,0) + cluster->GetErrX2();
1170 Double_t sigmaY2 = kParamCov(2,2) + cluster->GetErrY2();
d4643a10 1171 AliDebug(3, Form("dX2 = %f, dY2 = %f\n", sigmaX2, sigmaY2));
820b4d9e 1172 Double_t covXY = kParamCov(0,2);
1173 Double_t det = sigmaX2 * sigmaY2 - covXY * covXY;
1174
1175 // Compute chi2
1176 if (det==0.) return 1.e10;
1177 return (dX*dX*sigmaY2 + dY*dY*sigmaX2 - 2.*dX*dY*covXY) / det;
1178
1179}
1180
1181//=========================================================================================================================================
1182
1183void AliMuonForwardTrackFinder::SeparateFrontBackClusters() {
1184
1185 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
b5ab1ac4 1186 fMFTClusterArrayFront[iPlane]->Delete();
1187 fMFTClusterArrayBack[iPlane] ->Delete();
820b4d9e 1188 for (Int_t iCluster=0; iCluster<fMFTClusterArray[iPlane]->GetEntries(); iCluster++) {
1189 AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArray[iPlane]->At(iCluster);
1190 if (TMath::Abs(cluster->GetZ())<TMath::Abs(fSegmentation->GetPlane(iPlane)->GetZCenter())) {
1191 new ((*fMFTClusterArrayFront[iPlane])[fMFTClusterArrayFront[iPlane]->GetEntries()]) AliMFTCluster(*cluster);
1192 }
1193 else {
1194 new ((*fMFTClusterArrayBack[iPlane])[fMFTClusterArrayBack[iPlane]->GetEntries()]) AliMFTCluster(*cluster);
1195 }
1196 }
1197 }
1198
1199}
1200
1201//=========================================================================================================================================
1202
1203Int_t AliMuonForwardTrackFinder::GetNDF(Int_t nClusters) {
1204
1205 // the same definition as in AliMUONTrack is implemented, since here we just add more clusters to the Muon track
1206
1207 Int_t ndf = 2 * nClusters - 5;
1208 return (ndf > 0) ? ndf : 0;
1209
1210}
1211
1212//============================================================================================================================================
1213
1214void AliMuonForwardTrackFinder::BookHistos() {
d4643a10 1215
820b4d9e 1216 const Int_t nMaxNewTracks[] = {150, 200, 250, 600, 1000};
d4643a10 1217 const Double_t radiusPlane[] = {0.010, 0.010, 0.050, 0.5, 1.5};
820b4d9e 1218
820b4d9e 1219 fHistRadiusEndOfAbsorber = new TH1D("hRadiusEndOfAbsorber", "Track radial distance at the end of the absorber", 1000, 0, 100.);
1220
1221 fHistNGoodClustersForFinalTracks = new TH1D("hNGoodClustersForFinalTracks", "Number of Good Clusters per Final Track", 20, -0.25, 9.75);
1222
1223 fHistDistanceGoodClusterFromTrackAtLastPlane = new TH1D("hDistanceGoodClusterFromTrackAtLastPlane",
1224 "Distance of MC Good Cluster from Track in last MFT plane", 200, 0., 2.);
1225
1226 fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane =
1227 new TH1D("hDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane",
1228 "Good Cluster distance from track - Best Cluster distance from track in last MFT plane", 200, 0., 2.);
1229
1230 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
1231
1232 fHistNTracksAfterExtrapolation[iPlane] = new TH1D(Form("hNTracksAfterExtrapolation_pl%02d", iPlane),
1233 Form("Number of Candidates after analysis of MFT plane %02d", iPlane),
1234 nMaxNewTracks[iPlane], -0.5, nMaxNewTracks[iPlane]-0.5);
1235
1236 fHistResearchRadius[iPlane] = new TH1D(Form("hResearchRadius_pl%02d", iPlane),
1237 Form("Research Radius for candidate clusters in MFT plane %02d", iPlane),
1238 1000, 0., radiusPlane[iPlane]);
1239
1240 fHistChi2Cluster_GoodCluster[iPlane] = new TH1D(Form("hChi2Cluster_GoodCluster_pl%02d", iPlane),
1241 Form("#chi^{2}_{clust} for Good clusters in MFT plane %02d", iPlane),
1242 100, 0., 15.);
1243
1244 fHistChi2Cluster_BadCluster[iPlane] = new TH1D(Form("hChi2Cluster_BadCluster_pl%02d", iPlane),
1245 Form("#chi^{2}_{clust} for Bad clusters in MFT plane %02d", iPlane),
1246 100, 0., 15.);
1247
d4643a10 1248 fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[iPlane] = new TH1D(Form("fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons_pl%02d", iPlane),
1249 Form("#chi^{2}/ndf at plane %d for GOOD candidates of trackable muons",iPlane),
1250 100, 0., 15.);
1251
1252 fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[iPlane] = new TH1D(Form("fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons_pl%02d", iPlane),
1253 Form("#chi^{2}/ndf at plane %d for BAD candidates of trackable muons",iPlane),
1254 100, 0., 15.);
1255
820b4d9e 1256 }
1257
1258 //------------------------------------------
1259
820b4d9e 1260 fHistRadiusEndOfAbsorber -> Sumw2();
1261 fHistNGoodClustersForFinalTracks -> Sumw2();
1262
1263 fHistDistanceGoodClusterFromTrackAtLastPlane -> Sumw2();
1264 fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane -> Sumw2();
1265
1266 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
1267
1268 fHistNTracksAfterExtrapolation[iPlane] -> Sumw2();
1269 fHistResearchRadius[iPlane] -> Sumw2();
1270
1271 fHistChi2Cluster_GoodCluster[iPlane] -> Sumw2();
1272 fHistChi2Cluster_BadCluster[iPlane] -> Sumw2();
1273
d4643a10 1274 fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[iPlane] -> Sumw2();
1275 fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[iPlane] -> Sumw2();
820b4d9e 1276
1277 }
1278
6e8e4c4a 1279 fNtuFinalCandidates = new TNtuple("ntuFinalCandidates", "Final Candidates (ALL)", "run:event:muonTrack:nFinalCandidates:MCTrackRefExists:xVtx:yVtx:zVtx:motherPdg:triggerMatch:nClustersMC:nGoodClusters:pt:theta:eta:chi2AtPlane0:chi2AtPlane1:chi2AtPlane2:chi2AtPlane3:chi2AtPlane4:chi2AtPlane5:chi2AtPlane6:chi2AtPlane7:chi2AtPlane8");
7230691d 1280
6e8e4c4a 1281 fNtuFinalBestCandidates = new TNtuple("ntuFinalBestCandidates", "Final Best Candidates", "run:event:muonTrack:nFinalCandidates:MCTrackRefExists:xVtx:yVtx:zVtx:motherPdg:triggerMatch:nClustersMC:nGoodClusters:pt:theta:eta:chi2AtPlane0:chi2AtPlane1:chi2AtPlane2:chi2AtPlane3:chi2AtPlane4:chi2AtPlane5:chi2AtPlane6:chi2AtPlane7:chi2AtPlane8:nClustersAtPlane0:nClustersAtPlane1:nClustersAtPlane2:nClustersAtPlane3:nClustersAtPlane4:nClustersAtPlane5:nClustersAtPlane6:nClustersAtPlane7:nClustersAtPlane8");
820b4d9e 1282
1283}
1284
1285//============================================================================================================================================
1286
1287void AliMuonForwardTrackFinder::SetTitleHistos() {
1288
820b4d9e 1289 fHistRadiusEndOfAbsorber -> SetXTitle("R_{abs} [cm]");
1290 fHistNGoodClustersForFinalTracks -> SetXTitle("N_{GoodClusters}");
1291
1292 fHistDistanceGoodClusterFromTrackAtLastPlane -> SetXTitle("Distance [cm]");
1293 fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane -> SetXTitle("Distance [cm]");
1294
1295
1296 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
1297
1298 fHistNTracksAfterExtrapolation[iPlane] -> SetXTitle("N_{tracks}");
1299 fHistResearchRadius[iPlane] -> SetXTitle("Research Radius [cm]");
1300
1301 fHistChi2Cluster_GoodCluster[iPlane] -> SetXTitle("#chi^{2}/ndf");
1302 fHistChi2Cluster_BadCluster[iPlane] -> SetXTitle("#chi^{2}/ndf");
1303
d4643a10 1304 fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[iPlane] -> SetXTitle("#chi^{2}/ndf");
1305 fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[iPlane] -> SetXTitle("#chi^{2}/ndf");
820b4d9e 1306
1307 }
1308
1309}
1310
1311//===========================================================================================================================================
1312
1313void AliMuonForwardTrackFinder::BookPlanes() {
1314
1315 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
d4643a10 1316 fGrMFTPlane[kAllClusters][iPlane] = new TGraph();
1317 fGrMFTPlane[kAllClusters][iPlane] -> SetName(Form("fGrMFTPlane_%02d_AllClusters",iPlane));
1318 fGrMFTPlane[kAllClusters][iPlane] -> SetMarkerStyle(20);
1319 // fGrMFTPlane[kAllClusters][iPlane] -> SetMarkerSize(0.5);
1320 // fGrMFTPlane[kAllClusters][iPlane] -> SetMarkerSize(0.3);
1321 fGrMFTPlane[kAllClusters][iPlane] -> SetMarkerSize(0.2);
820b4d9e 1322 }
1323
1324 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
d4643a10 1325 fGrMFTPlane[kClustersGoodChi2][iPlane] = new TGraph();
1326 fGrMFTPlane[kClustersGoodChi2][iPlane] -> SetName(Form("fGrMFTPlane_%02d_ClustersGoodChi2",iPlane));
1327 fGrMFTPlane[kClustersGoodChi2][iPlane] -> SetMarkerStyle(20);
1328 // fGrMFTPlane[kClustersGoodChi2][iPlane] -> SetMarkerSize(0.8);
1329 // fGrMFTPlane[kClustersGoodChi2][iPlane] -> SetMarkerSize(0.4);
1330 fGrMFTPlane[kClustersGoodChi2][iPlane] -> SetMarkerSize(0.3);
1331 fGrMFTPlane[kClustersGoodChi2][iPlane] -> SetMarkerColor(kBlue);
820b4d9e 1332 }
1333
1334 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
d4643a10 1335 fGrMFTPlane[kClusterOfTrack][iPlane] = new TGraph();
1336 fGrMFTPlane[kClusterOfTrack][iPlane] -> SetName(Form("fGrMFTPlane_%02d_ClustersOfTrack",iPlane));
1337 fGrMFTPlane[kClusterOfTrack][iPlane] -> SetMarkerStyle(25);
1338 // fGrMFTPlane[kClusterOfTrack][iPlane] -> SetMarkerSize(1.2);
1339 fGrMFTPlane[kClusterOfTrack][iPlane] -> SetMarkerSize(0.9);
1340 fGrMFTPlane[kClusterOfTrack][iPlane] -> SetMarkerColor(kRed);
1341 fGrMFTPlane[kClusterOfTrack][iPlane] -> SetTitle(Form("Plane %d (%3.1f cm)", iPlane, fZPlane[iPlane]));
820b4d9e 1342 }
1343
1344 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
d4643a10 1345 fGrMFTPlane[kClusterCorrectMC][iPlane] = new TGraph();
1346 fGrMFTPlane[kClusterCorrectMC][iPlane] -> SetName(Form("fGrMFTPlane_%02d_ClustersCorrectMC",iPlane));
1347 fGrMFTPlane[kClusterCorrectMC][iPlane] -> SetMarkerStyle(20);
1348 // fGrMFTPlane[kClusterCorrectMC][iPlane] -> SetMarkerSize(0.8);
1349 fGrMFTPlane[kClusterCorrectMC][iPlane] -> SetMarkerSize(0.5);
1350 fGrMFTPlane[kClusterCorrectMC][iPlane] -> SetMarkerColor(kGreen);
820b4d9e 1351 }
1352
1353 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
1354 fCircleExt[iPlane] = new TEllipse(0., 0., fRPlaneMax[iPlane], fRPlaneMax[iPlane]);
1355 fCircleInt[iPlane] = new TEllipse(0., 0., fRPlaneMin[iPlane], fRPlaneMin[iPlane]);
1356 }
1357
d4643a10 1358 fTxtDummy = new TLatex(0.10, 0.59, "Best Candidate:");
820b4d9e 1359
1360 //---------------------------------------------------
1361
1362 fMrkAllClust = new TMarker(0.10, 0.32, 20);
1363 fMrkAllClust -> SetMarkerSize(0.5);
1364
1365 fMrkClustGoodChi2 = new TMarker(0.10, 0.26, 20);
1366 fMrkClustGoodChi2 -> SetMarkerSize(0.8);
1367 fMrkClustGoodChi2 -> SetMarkerColor(kBlue);
1368
1369 fMrkClustMC = new TMarker(0.10, 0.20, 20);
1370 fMrkClustMC -> SetMarkerSize(0.8);
1371 fMrkClustMC -> SetMarkerColor(kGreen);
1372
1373 fMrkClustOfTrack = new TMarker(0.10, 0.14, 25);
1374 fMrkClustOfTrack -> SetMarkerSize(1.2);
1375 fMrkClustOfTrack -> SetMarkerColor(kRed);
1376
1377 fTxtAllClust = new TLatex(0.15, 0.30, "All Clusters");
1378 fTxtAllClust -> SetTextSize(0.040);
1379
1380 fTxtClustGoodChi2 = new TLatex(0.15, 0.24, "Clusters involved in the research");
1381 fTxtClustGoodChi2 -> SetTextSize(0.040);
1382
1383 fTxtClustMC = new TLatex(0.15, 0.18, "MC good clusters");
1384 fTxtClustMC -> SetTextSize(0.040);
1385
1386 fTxtClustOfTrack = new TLatex(0.15, 0.12, "Clusters of the best candidate");
1387 fTxtClustOfTrack -> SetTextSize(0.040);
1388
1389}
1390
1391//===========================================================================================================================================
1392
1393void AliMuonForwardTrackFinder::ResetPlanes() {
1394
1395 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
1396 for (Int_t iGr=0; iGr<4; iGr++) {
d4643a10 1397 Int_t nOldClusters = fGrMFTPlane[iGr][iPlane]->GetN();
1398 for (Int_t iPoint=nOldClusters-1; iPoint>=0; iPoint--) fGrMFTPlane[iGr][iPlane]->RemovePoint(iPoint);
820b4d9e 1399 }
1400 }
1401
1402}
1403
1404//===========================================================================================================================================
1405
1406void AliMuonForwardTrackFinder::PrintParticleHistory() {
1407
d4643a10 1408 AliDebug(1, "Entering");
1409
820b4d9e 1410 TString history = "";
1411
d4643a10 1412 TParticle *part = 0;
1413 if (fLabelMC>=0) part = fStack->Particle(fLabelMC);
1414
ff80c017 1415 AliDebug(1, Form("fStack->Particle(%d) = %p", fLabelMC, part));
d4643a10 1416
1417 if (part) {
c0d58f1d 1418 AliDebug(1, Form("fStack->Particle(%d)->GetPdgCode() = %d", fLabelMC, part->GetPdgCode()));
d4643a10 1419 if (part->GetFirstMother() != -1) {
1420 TParticle *partMother = fStack->Particle(part->GetFirstMother());
ff80c017 1421 AliDebug(1, Form("fStack->Particle(%d) = %p", part->GetFirstMother(), partMother));
d4643a10 1422 if (partMother) {
1423 Char_t newName[100];
1424 if (partMother->GetFirstMother() != -1) history += "... #rightarrow ";
1425 PDGNameConverter(partMother->GetName(), newName);
1426 history += Form("%s #rightarrow ", newName);
1427 }
1428 }
820b4d9e 1429 Char_t newName[100];
ff80c017 1430 AliDebug(1, Form("fStack->Particle(%d)->GetPdgCode() = %d", fLabelMC, part->GetPdgCode()));
1431 AliDebug(1, Form("fStack->Particle(%d)->GetName() = %s", fLabelMC, part->GetName()));
d4643a10 1432 PDGNameConverter(part->GetName(), newName);
1433 history += Form("%s at z = %5.1f cm", newName, part->Vz());
1434 // printf("%s", history.Data());
820b4d9e 1435 }
d4643a10 1436 else history += "NO AVAILABLE HISTORY";
1437
820b4d9e 1438 fTxtMuonHistory = new TLatex(0.10, 0.86, history.Data());
d4643a10 1439
1440 // Filling particle history in the fFinalBestCandidate
1441
1442 if (part) {
1443 for (Int_t iParent=0; iParent<AliMuonForwardTrack::fgkNParentsMax; iParent++) {
1444 if (part->GetFirstMother() == -1) break;
1445 if (!(fStack->Particle(part->GetFirstMother()))) break;
1446 AliDebug(1, Form("fStack->Particle(part->GetFirstMother() = %p", fStack->Particle(part->GetFirstMother())));
1447 fFinalBestCandidate->SetParentMCLabel(iParent, part->GetFirstMother());
1448 fFinalBestCandidate->SetParentPDGCode(iParent, fStack->Particle(part->GetFirstMother())->GetPdgCode());
1449 part = fStack->Particle(part->GetFirstMother());
1450 }
1451 }
820b4d9e 1452
1453}
1454
1455//===========================================================================================================================================
1456
df4bbbc3 1457Bool_t AliMuonForwardTrackFinder::IsMother(const Char_t *nameMother) {
820b4d9e 1458
1459 Bool_t result = kFALSE;
1460
d4643a10 1461 TParticle *part = 0;
1462 if (fLabelMC>=0) part = fStack->Particle(fLabelMC);
820b4d9e 1463
d4643a10 1464 if (part) {
1465 if (part->GetFirstMother() != -1) {
1466 TParticle *partMother = fStack->Particle(part->GetFirstMother());
1467 if (partMother) {
1468 if (!strcmp(partMother->GetName(), nameMother)) result=kTRUE;
1469 }
1470 }
820b4d9e 1471 }
1472
1473 return result;
1474
1475}
1476
1477//===========================================================================================================================================
1478
1479void AliMuonForwardTrackFinder::DrawPlanes() {
1480
1481 fCanvas -> Clear();
1482 if (fNPlanesMFT <= 5) fCanvas -> Divide(3,2);
1483 else if (fNPlanesMFT <= 11) fCanvas -> Divide(4,3);
1484 else if (fNPlanesMFT <= 19) fCanvas -> Divide(5,4);
1485
1486 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
1487
1488 fCanvas->cd(fNPlanesMFT-iPlane+1);
1489
d4643a10 1490 fGrMFTPlane[kClusterOfTrack][iPlane] -> GetXaxis() -> SetLimits(-1.1*fRPlaneMax[fNPlanesMFT-1], +1.1*fRPlaneMax[fNPlanesMFT-1]);
1491 fGrMFTPlane[kClusterOfTrack][iPlane] -> GetYaxis() -> SetRangeUser(-1.1*fRPlaneMax[fNPlanesMFT-1], +1.1*fRPlaneMax[fNPlanesMFT-1]);
1492 fGrMFTPlane[kClusterOfTrack][iPlane] -> GetXaxis() -> SetTitle("X [cm]");
1493 fGrMFTPlane[kClusterOfTrack][iPlane] -> GetYaxis() -> SetTitle("Y [cm]");
1494 fGrMFTPlane[kClusterOfTrack][iPlane] -> Draw("ap");
820b4d9e 1495
1496 fCircleExt[iPlane] -> Draw("same");
1497 fCircleInt[iPlane] -> Draw("same");
1498
d4643a10 1499 if (fGrMFTPlane[kAllClusters][iPlane]->GetN()) fGrMFTPlane[kAllClusters][iPlane] -> Draw("psame");
1500 if (fGrMFTPlane[kClustersGoodChi2][iPlane]->GetN()) fGrMFTPlane[kClustersGoodChi2][iPlane] -> Draw("psame");
1501 if (fGrMFTPlane[kClusterOfTrack][iPlane]->GetN()) fGrMFTPlane[kClusterOfTrack][iPlane] -> Draw("psame");
1502 if (fGrMFTPlane[kClusterCorrectMC][iPlane]->GetN()) fGrMFTPlane[kClusterCorrectMC][iPlane] -> Draw("psame");
820b4d9e 1503
1504 fTxtTrackChi2[iPlane] -> Draw("same");
1505
1506 }
1507
1508 fCanvas -> cd(1);
1509 fTxtMuonHistory -> Draw();
1510 fTxtDummy -> Draw("same");
d4643a10 1511 if (fMatchingMode==kRealMatching) fTxtTrackGoodClusters -> Draw("same");
820b4d9e 1512 fTxtTrackFinalChi2 -> Draw("same");
d4643a10 1513 fTxtTrackMomentum -> Draw("same");
1514 if (fMatchingMode==kRealMatching) fTxtFinalCandidates -> Draw("same");
820b4d9e 1515
1516 fMrkAllClust -> Draw("same");
1517 fMrkClustGoodChi2 -> Draw("same");
1518 fMrkClustMC -> Draw("same");
1519 fMrkClustOfTrack -> Draw("same");
1520
1521 fTxtAllClust -> Draw("same");
1522 fTxtClustGoodChi2 -> Draw("same");
1523 fTxtClustMC -> Draw("same");
1524 fTxtClustOfTrack -> Draw("same");
1525
1526 // fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.eps", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
1527 fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.gif", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
1528 if (IsMother("phi")) {
1529 fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.phi.gif", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
1530 fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.phi.eps", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
1531 }
1532 if (IsMother("J/psi")) {
1533 fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.jPsi.gif", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
1534 fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.jPsi.eps", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
1535 }
1536
1537}
1538
1539//===========================================================================================================================================
1540
1541void AliMuonForwardTrackFinder::Terminate() {
1542
d4643a10 1543 AliInfo("");
1544 AliInfo("---------------------------------------------------------------------------------------------------------------");
1545 AliInfo(Form("%8d tracks analyzed", fCountRealTracksAnalyzed));
1546 AliInfo(Form("%8d tracks with MC ref", fCountRealTracksWithRefMC));
1547 AliInfo(Form("%8d tracks with MC ref & trigger match", fCountRealTracksWithRefMC_andTrigger));
1548 if (fMatchingMode==kRealMatching) {
1549 AliInfo(Form("%8d tracks analyzed with final candidates", fCountRealTracksAnalyzedWithFinalCandidates));
1550 }
1551 else {
1552 AliInfo(Form("%8d tracks matched with their MC clusters", fCountRealTracksAnalyzedWithFinalCandidates));
1553 }
1554// printf("%8d tracks with MC ref & trigger match & pt>%3.1f GeV/c", fCountRealTracksWithRefMC_andTrigger_andGoodPt, fLowPtCut);
1555// printf("%8d tracks with MC ref & trigger match & pt>%3.1f GeV/c & correct R_abs", fCountRealTracksWithRefMC_andTrigger_andGoodPt_andGoodTheta, fLowPtCut);
1556 AliInfo("---------------------------------------------------------------------------------------------------------------");
820b4d9e 1557
1558 WriteOutputTree();
1559 WriteHistos();
1560
1561}
1562
1563//==========================================================================================================================================
1564
1565void AliMuonForwardTrackFinder::FillOutputTree() {
1566
1567 if (!fMuonForwardTracks || !fOutputEventTree) return;
1568
1569 AliDebug(1, Form("Filling output tree %p with %p having %d entries whose 1st entry is %p",
1570 fOutputEventTree, fMuonForwardTracks, fMuonForwardTracks->GetEntries(), fMuonForwardTracks->At(0)));
1571
d4643a10 1572 // fOutputTreeFile->cd();
820b4d9e 1573 fOutputEventTree->Fill();
d4643a10 1574 AliDebug(1, Form("\nFilled Tree: nEvents = %d!!!!\n", Int_t(fOutputEventTree->GetEntries())));
820b4d9e 1575
1576}
1577
1578//==========================================================================================================================================
1579
1580void AliMuonForwardTrackFinder::WriteOutputTree() {
1581
1582 if (!fOutputEventTree || !fOutputTreeFile) return;
1583
1584 fOutputTreeFile -> cd();
1585
1586 fOutputEventTree -> Write();
1587 fOutputTreeFile -> Close();
1588
1589}
1590
1591//==========================================================================================================================================
1592
1593void AliMuonForwardTrackFinder::WriteHistos() {
1594
d4643a10 1595 fOutputQAFile = new TFile(Form("MuonGlobalTracking.QA.run%d.root", fRun), "recreate");
1596 fOutputQAFile -> cd();
820b4d9e 1597
820b4d9e 1598 fHistRadiusEndOfAbsorber -> Write();
1599 fHistNGoodClustersForFinalTracks -> Write();
1600
1601 fHistDistanceGoodClusterFromTrackAtLastPlane -> Write();
1602 fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane -> Write();
1603
1604 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
1605
1606 fHistNTracksAfterExtrapolation[iPlane] -> Write();
1607 fHistResearchRadius[iPlane] -> Write();
1608
1609 fHistChi2Cluster_GoodCluster[iPlane] -> Write();
1610 fHistChi2Cluster_BadCluster[iPlane] -> Write();
1611
d4643a10 1612 fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[iPlane] -> Write();
1613 fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[iPlane] -> Write();
820b4d9e 1614
1615 }
1616
d4643a10 1617 fNtuFinalCandidates -> Write();
1618 fNtuFinalBestCandidates -> Write();
820b4d9e 1619
d4643a10 1620 fOutputQAFile -> Close();
820b4d9e 1621
1622}
1623
1624//===========================================================================================================================================
1625
1626void AliMuonForwardTrackFinder::PDGNameConverter(const Char_t *nameIn, Char_t *nameOut) {
1627
d6080682 1628 if (!strcmp(nameIn, "mu+")) snprintf(nameOut, 50, "#mu^{+}");
1629 else if (!strcmp(nameIn, "mu-")) snprintf(nameOut, 50, "#mu^{-}");
1630 else if (!strcmp(nameIn, "pi+")) snprintf(nameOut, 50, "#pi^{+}");
1631 else if (!strcmp(nameIn, "pi-")) snprintf(nameOut, 50, "#pi^{-}");
1632 else if (!strcmp(nameIn, "K+")) snprintf(nameOut, 50, "K^{+}");
1633 else if (!strcmp(nameIn, "K-")) snprintf(nameOut, 50, "K^{-}");
1634 else if (!strcmp(nameIn, "K*+")) snprintf(nameOut, 50, "K^{*+}");
1635 else if (!strcmp(nameIn, "K*-")) snprintf(nameOut, 50, "K^{*-}");
1636 else if (!strcmp(nameIn, "K_S0")) snprintf(nameOut, 50, "K_{S}^{0}");
1637 else if (!strcmp(nameIn, "K_L0")) snprintf(nameOut, 50, "K_{L}^{0}");
1638 else if (!strcmp(nameIn, "K0")) snprintf(nameOut, 50, "K^{0}");
1639 else if (!strcmp(nameIn, "K0_bar")) snprintf(nameOut, 50, "#bar{K}^{0}");
1640 else if (!strcmp(nameIn, "K*0")) snprintf(nameOut, 50, "K^{*0}");
1641 else if (!strcmp(nameIn, "K*0_bar")) snprintf(nameOut, 50, "#bar{K}^{*0}");
1642 else if (!strcmp(nameIn, "rho0")) snprintf(nameOut, 50, "#rho^{0}");
1643 else if (!strcmp(nameIn, "rho+")) snprintf(nameOut, 50, "#rho^{+}");
1644 else if (!strcmp(nameIn, "rho-")) snprintf(nameOut, 50, "#rho^{-}");
1645 else if (!strcmp(nameIn, "omega")) snprintf(nameOut, 50, "#omega");
1646 else if (!strcmp(nameIn, "eta'")) snprintf(nameOut, 50, "#eta'");
1647 else if (!strcmp(nameIn, "phi")) snprintf(nameOut, 50, "#phi");
1648
1649 else if (!strcmp(nameIn, "D-")) snprintf(nameOut, 50, "D^{-}");
1650 else if (!strcmp(nameIn, "D+")) snprintf(nameOut, 50, "D^{+}");
1651 else if (!strcmp(nameIn, "D0")) snprintf(nameOut, 50, "D^{0}");
1652 else if (!strcmp(nameIn, "D0_bar")) snprintf(nameOut, 50, "#bar{D}^{0}");
1653 else if (!strcmp(nameIn, "D*-")) snprintf(nameOut, 50, "D^{*-}");
1654 else if (!strcmp(nameIn, "D*+")) snprintf(nameOut, 50, "D^{*+}");
1655 else if (!strcmp(nameIn, "D_s+")) snprintf(nameOut, 50, "D_{s}^{+}");
1656 else if (!strcmp(nameIn, "D*_s+")) snprintf(nameOut, 50, "D_{s}^{*+}");
1657
1658 else if (!strcmp(nameIn, "B-")) snprintf(nameOut, 50, "B^{-}");
1659 else if (!strcmp(nameIn, "B+")) snprintf(nameOut, 50, "B^{+}");
1660 else if (!strcmp(nameIn, "B_s0_bar")) snprintf(nameOut, 50, "#bar{B}_{s}^{0}");
1661
1662 else if (!strcmp(nameIn, "antiproton")) snprintf(nameOut, 50, "#bar{p}");
1663 else if (!strcmp(nameIn, "proton")) snprintf(nameOut, 50, "p");
1664 else if (!strcmp(nameIn, "neutron")) snprintf(nameOut, 50, "n");
1665 else if (!strcmp(nameIn, "Sigma+")) snprintf(nameOut, 50, "#Sigma^{+}");
1666 else if (!strcmp(nameIn, "Delta+")) snprintf(nameOut, 50, "#Delta{+}");
1667 else if (!strcmp(nameIn, "Delta--")) snprintf(nameOut, 50, "#Delta{--}");
1668 else if (!strcmp(nameIn, "Lambda0")) snprintf(nameOut, 50, "#Lambda_0");
1669 else if (!strcmp(nameIn, "Lambda0_bar")) snprintf(nameOut, 50, "#bar{Lambda}_0");
1670
1671 else snprintf(nameOut, 50, "%s", nameIn);
820b4d9e 1672
1673}
1674
1675//===========================================================================================================================================
1676
1677void AliMuonForwardTrackFinder::SetDraw(Bool_t drawOption) {
1678
1679 fDrawOption = drawOption;
1680
1681 if (!fCanvas) {
1682 fCanvas = new TCanvas("tracking", "tracking", 1200, 800);
1683 fCanvas -> Divide(3,2);
1684 }
1685
1686}
1687
1688//===========================================================================================================================================
1689
1690Bool_t AliMuonForwardTrackFinder::InitGRP() {
1691
1692 //------------------------------------
1693 // Initialization of the GRP entry
1694 //------------------------------------
1695
1696 AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/GRP/Data");
1697
1698 if (entry) {
1699
1700 TMap* m = dynamic_cast<TMap*>(entry->GetObject()); // old GRP entry
1701
1702 if (m) {
1703 AliInfo("Found a TMap in GRP/GRP/Data, converting it into an AliGRPObject");
1704 m->Print();
1705 fGRPData = new AliGRPObject();
1706 fGRPData->ReadValuesFromMap(m);
1707 }
1708
1709 else {
1710 AliInfo("Found an AliGRPObject in GRP/GRP/Data, reading it");
1711 fGRPData = dynamic_cast<AliGRPObject*>(entry->GetObject()); // new GRP entry
1712 entry->SetOwner(0);
1713 }
1714
1715 // FIX ME: The unloading of GRP entry is temporarily disabled
1716 // because ZDC and VZERO are using it in order to initialize
1717 // their reconstructor objects. In the future one has to think
1718 // of propagating AliRunInfo to the reconstructors.
1719 // AliCDBManager::Instance()->UnloadFromCache("GRP/GRP/Data");
1720 }
1721
1722 if (!fGRPData) {
1723 AliError("No GRP entry found in OCDB!");
1724 return kFALSE;
1725 }
1726
1727 TString lhcState = fGRPData->GetLHCState();
1728 if (lhcState==AliGRPObject::GetInvalidString()) {
1729 AliError("GRP/GRP/Data entry: missing value for the LHC state ! Using UNKNOWN");
1730 lhcState = "UNKNOWN";
1731 }
1732
1733 TString beamType = fGRPData->GetBeamType();
1734 if (beamType==AliGRPObject::GetInvalidString()) {
1735 AliError("GRP/GRP/Data entry: missing value for the beam type ! Using UNKNOWN");
1736 beamType = "UNKNOWN";
1737 }
1738
1739 Float_t beamEnergy = fGRPData->GetBeamEnergy();
1740 if (beamEnergy==AliGRPObject::GetInvalidFloat()) {
1741 AliError("GRP/GRP/Data entry: missing value for the beam energy ! Using 0");
1742 beamEnergy = 0;
1743 }
1744
1745 TString runType = fGRPData->GetRunType();
1746 if (runType==AliGRPObject::GetInvalidString()) {
1747 AliError("GRP/GRP/Data entry: missing value for the run type ! Using UNKNOWN");
1748 runType = "UNKNOWN";
1749 }
1750
1751 Int_t activeDetectors = fGRPData->GetDetectorMask();
1752 if (activeDetectors==AliGRPObject::GetInvalidUInt()) {
1753 AliError("GRP/GRP/Data entry: missing value for the detector mask ! Using 1074790399");
1754 activeDetectors = 1074790399;
1755 }
1756 AliDebug(1, Form("activeDetectors = %d", activeDetectors));
1757
1758 fRunInfo = new AliRunInfo(lhcState, beamType, beamEnergy, runType, activeDetectors);
1759 fRunInfo->Dump();
1760
1761 // *** Dealing with the magnetic field map
1762
1763 if ( TGeoGlobalMagField::Instance()->IsLocked() ) {
1764 if (TGeoGlobalMagField::Instance()->GetField()->TestBit(AliMagF::kOverrideGRP)) {
1765 AliInfo("ExpertMode!!! GRP information will be ignored !");
1766 AliInfo("ExpertMode!!! Running with the externally locked B field !");
1767 }
1768 else {
1769 AliInfo("Destroying existing B field instance!");
1770 delete TGeoGlobalMagField::Instance();
1771 }
1772 }
1773 if ( !TGeoGlobalMagField::Instance()->IsLocked() ) {
1774 // Construct the field map out of the information retrieved from GRP.
1775 Bool_t ok = kTRUE;
1776 // L3
1777 Float_t l3Current = fGRPData->GetL3Current((AliGRPObject::Stats)0);
1778 if (l3Current == AliGRPObject::GetInvalidFloat()) {
1779 AliError("GRP/GRP/Data entry: missing value for the L3 current !");
1780 ok = kFALSE;
1781 }
1782
1783 Char_t l3Polarity = fGRPData->GetL3Polarity();
1784 if (l3Polarity == AliGRPObject::GetInvalidChar()) {
1785 AliError("GRP/GRP/Data entry: missing value for the L3 polarity !");
1786 ok = kFALSE;
1787 }
1788
1789 // Dipole
1790 Float_t diCurrent = fGRPData->GetDipoleCurrent((AliGRPObject::Stats)0);
1791 if (diCurrent == AliGRPObject::GetInvalidFloat()) {
1792 AliError("GRP/GRP/Data entry: missing value for the dipole current !");
1793 ok = kFALSE;
1794 }
1795
1796 Char_t diPolarity = fGRPData->GetDipolePolarity();
1797 if (diPolarity == AliGRPObject::GetInvalidChar()) {
1798 AliError("GRP/GRP/Data entry: missing value for the dipole polarity !");
1799 ok = kFALSE;
1800 }
1801
1802 // read special bits for the polarity convention and map type
1803 Int_t polConvention = fGRPData->IsPolarityConventionLHC() ? AliMagF::kConvLHC : AliMagF::kConvDCS2008;
1804 Bool_t uniformB = fGRPData->IsUniformBMap();
1805
1806 if (ok) {
1807 AliMagF* fld = AliMagF::CreateFieldMap(TMath::Abs(l3Current) * (l3Polarity ? -1:1),
1808 TMath::Abs(diCurrent) * (diPolarity ? -1:1),
1809 polConvention,uniformB,beamEnergy, beamType.Data());
1810 if (fld) {
1811 TGeoGlobalMagField::Instance()->SetField( fld );
1812 TGeoGlobalMagField::Instance()->Lock();
1813 AliInfo("Running with the B field constructed out of GRP !");
1814 }
1815 else AliFatal("Failed to create a B field map !");
1816 }
1817 else AliFatal("B field is neither set nor constructed from GRP ! Exitig...");
1818 }
1819
1820 return kTRUE;
1821}
1822
1823//====================================================================================================================================================
1824
1825Bool_t AliMuonForwardTrackFinder::SetRunNumber() {
1826
1827 AliCDBManager *man = AliCDBManager::Instance();
1828
1829 if (!fRunLoader) {
1830 AliError("No run loader found!");
1831 return kFALSE;
1832 }
1833 else {
1834 fRunLoader->LoadHeader();
1835 // read run number from gAlice
1836 if (fRunLoader->GetHeader()) {
1837 man->SetRun(fRunLoader->GetHeader()->GetRun());
1838 fRunLoader->UnloadHeader();
1839 }
1840 else {
1841 AliError("No run-loader header found!");
1842 return kFALSE;
1843 }
1844 }
1845
1846 return kTRUE;
1847
1848}
1849
1850//====================================================================================================================================================
1851