PAR: includes from previously enabled PARfiles
[u/mrichter/AliRoot.git] / MFT / MFTrec / 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);
026547c6 559 track -> SetRAtAbsorberEnd(rAbsorber);
820b4d9e 560
b03d16a3 561 // 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 562 if (rAbsorber < fRAbsorberCut) return 4;
563
564 //------------------------- NOW THE CYCLE OVER THE MFT PLANES STARTS ---------------------------------------
565
566 for (Int_t iPlane=fNPlanesMFT-1; iPlane>=0; iPlane--) { // *** do not reverse the order of this cycle!!!
567 // *** this reflects the fact that the extrapolation is performed
568 // *** starting from the last MFT plane back to the origin
569
570 // --------- updating the array of tracks according to the clusters available in the i-th plane ---------
571
572 fNPlanesMFTAnalyzed++;
573
574 if (fMatchingMode==kRealMatching) {
575 Int_t nTracksToBeAnalyzed = fCandidateTracks->GetEntriesFast();
576 for (Int_t iTrack=0; iTrack<nTracksToBeAnalyzed; iTrack++) {
577 fCurrentTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(iTrack);
578 // if the old track is compatible with the new cluster, the track is updated and inserted as new track in the array
579 // (several new tracks can be created for one old track)
4cc511f4 580 if (FindClusterInPlane(iPlane) == kDiverged) {
a2b7dc2a 581 fGlobalTrackingDiverged = kTRUE;
582 if (fScaleSigmaClusterCut>0) fScaleSigmaClusterCut -= 0.1;
583 return 6;
584 }
820b4d9e 585 if ((fNPlanesMFTAnalyzed-fCurrentTrack->GetNMFTClusters())>fNMaxMissingMFTClusters || fIsPlaneMandatory[iPlane]) {
586 fCandidateTracks->Remove(fCurrentTrack); // the old track is removed after the check;
587 }
588 }
589 fCandidateTracks->Compress();
d4643a10 590 if (fIsCurrentMuonTrackable) {
591 // fOutputQAFile->cd();
592 fHistNTracksAfterExtrapolation[iPlane] -> Fill(fCandidateTracks->GetEntriesFast());
593 }
820b4d9e 594 }
595
d4643a10 596 else if (fMatchingMode==kIdealMatching && fIsCurrentMuonTrackable) {
820b4d9e 597 fCurrentTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(0);
d4643a10 598 AliDebug(2, Form("plane %02d: fCandidateTracks->GetEntriesFast() = %d fCandidateTracks->UncheckedAt(0) = %p fCurrentTrack = %p\n",
599 iPlane, fCandidateTracks->GetEntriesFast(), fCandidateTracks->UncheckedAt(0), fCurrentTrack));
820b4d9e 600 AttachGoodClusterInPlane(iPlane);
601 }
602
603 }
604
605 // -------------------------- END OF THE CYCLE OVER THE MFT PLANES --------------------------------------------
606
a2b7dc2a 607 fGlobalTrackingDiverged = kFALSE;
608 fScaleSigmaClusterCut = 1.0;
609
d4643a10 610 AliDebug(1, "Finished cycle over planes");
611
b03d16a3 612 Double_t momentum = pt * TMath::CosH(eta);
d4643a10 613 fTxtTrackMomentum = new TLatex(0.10, 0.70, Form("P_{spectro} = %3.1f GeV/c", momentum));
614
820b4d9e 615 if (fMatchingMode==kIdealMatching) {
d4643a10 616 AliDebug(1, "Adding track to output tree...\n");
617 fFinalBestCandidate = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(0);
820b4d9e 618 AliMuonForwardTrack *newTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(0);
d4643a10 619 new ((*fMuonForwardTracks)[fMuonForwardTracks->GetEntries()]) AliMuonForwardTrack(*newTrack);
620 AliDebug(1, "...track added!\n");
b5ab1ac4 621 fCandidateTracks->Delete();
820b4d9e 622 fCountRealTracksAnalyzedOfEvent++;
d4643a10 623 fCountRealTracksAnalyzedWithFinalCandidates++;
624 PrintParticleHistory();
625 FillPlanesWithTrackHistory();
626
627 Double_t chi2AtPlane[fNMaxPlanes] = {0};
628 Int_t nGoodClusters = 0;
629 Int_t nMFTClusters = fFinalBestCandidate->GetNMFTClusters();
630// Int_t nMUONClusters = fFinalBestCandidate->GetNMUONClusters();
631 Int_t plane = 0;
632 for (Int_t iCluster=0; iCluster<nMFTClusters; iCluster++) {
633 while (!fFinalBestCandidate->PlaneExists(plane)) plane++;
634 AliMFTCluster *localCluster = fFinalBestCandidate->GetMFTCluster(iCluster);
635 chi2AtPlane[plane] = localCluster->GetLocalChi2();
636 if (IsCorrectMatch(localCluster)) nGoodClusters++;
637// Int_t nClustersGlobalTrack = nMUONClusters + (nMFTClusters-iCluster); // Muon Spectrometer clusters + clusters in the Vertex Telescope
638// Int_t ndfGlobalTrack = GetNDF(nClustersGlobalTrack);
639// chi2AtPlane[plane] /= Double_t(ndfGlobalTrack);
640 plane++;
641 }
642 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
643 fTxtTrackChi2[iPlane] = new TLatex(0.55*fRPlaneMax[fNPlanesMFT-1],
644 0.90*fRPlaneMax[fNPlanesMFT-1],
645 Form("#chi^{2} = %3.1f", chi2AtPlane[iPlane]));
646 }
647 fTxtTrackFinalChi2 = new TLatex(0.20, 0.44, Form("#chi^{2}_{final} = %3.1f", chi2AtPlane[0]));
648
649 if (fDrawOption) DrawPlanes();
820b4d9e 650 return 5;
651 }
d4643a10 652
820b4d9e 653 // If we have several final tracks, we must find the best candidate:
654
655 Int_t nFinalTracks = fCandidateTracks->GetEntriesFast();
d4643a10 656 AliDebug(1, Form("nFinalTracks = %d", nFinalTracks));
820b4d9e 657
658 if (nFinalTracks) fCountRealTracksAnalyzedWithFinalCandidates++;
659
660 Double_t theVariable_Best = -1.; // variable defining the best candidate
661 Bool_t bestCandidateExists = kFALSE;
662 Int_t nGoodClustersBestCandidate = 0;
663 Int_t idBestCandidate = 0;
d4643a10 664 Double_t chi2HistoryForBestCandidate[fNMaxPlanes] = {0}; // chi2 on each plane, for the best candidate
665 Double_t nClustersPerPlane[fNMaxPlanes] = {0};
666 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
667 chi2HistoryForBestCandidate[iPlane] = -1.;
668 nClustersPerPlane[iPlane] = fMFTClusterArray[iPlane] -> GetEntries();
669 }
820b4d9e 670
671 fTxtFinalCandidates = new TLatex(0.10, 0.78, Form("N_{FinalCandidates} = %d", nFinalTracks));
672
673 Int_t nClustersMC = 0;
674 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) nClustersMC += fIsGoodClusterInPlane[iPlane];
675
676 for (Int_t iTrack=0; iTrack<nFinalTracks; iTrack++) {
677
678 AliMuonForwardTrack *finalTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(iTrack);
679
d4643a10 680 Double_t chi2AtPlane[fNMaxPlanes] = {0};
820b4d9e 681 Int_t nGoodClusters = 0;
682 Int_t nMFTClusters = finalTrack->GetNMFTClusters();
d4643a10 683// Int_t nMUONClusters = finalTrack->GetNMUONClusters();
820b4d9e 684
685 Int_t plane = 0;
686 for (Int_t iCluster=0; iCluster<nMFTClusters; iCluster++) {
687 while (!finalTrack->PlaneExists(plane)) plane++;
688 AliMFTCluster *localCluster = finalTrack->GetMFTCluster(iCluster);
d4643a10 689 chi2AtPlane[plane] = localCluster->GetLocalChi2();
820b4d9e 690 if (IsCorrectMatch(localCluster)) nGoodClusters++;
d4643a10 691// Int_t nClustersGlobalTrack = nMUONClusters + (nMFTClusters-iCluster); // Muon Spectrometer clusters + clusters in the Vertex Telescope
692// Int_t ndfGlobalTrack = GetNDF(nClustersGlobalTrack);
693// chi2AtPlane[plane] /= Double_t(ndfGlobalTrack);
694 plane++;
820b4d9e 695 }
696
d4643a10 697 if (fIsCurrentMuonTrackable) {
698 // fOutputQAFile->cd();
699 fHistNGoodClustersForFinalTracks -> Fill(nGoodClusters);
700 }
701
702 // fOutputQAFile->cd();
703
2942f542 704 Float_t finalCandidatesInfo[] = {static_cast<Float_t>(fRun),
705 static_cast<Float_t>(fEv),
706 static_cast<Float_t>(fCountRealTracksAnalyzedOfEvent),
707 static_cast<Float_t>(nFinalTracks),
708 static_cast<Float_t>(fLabelMC>=0),
709 static_cast<Float_t>(xVtx), static_cast<Float_t>(yVtx), static_cast<Float_t>(zVtx),
710 static_cast<Float_t>(motherPdg),
711 static_cast<Float_t>(fMuonTrackReco->GetMatchTrigger()),
712 static_cast<Float_t>(nClustersMC),
713 static_cast<Float_t>(nGoodClusters),
714 static_cast<Float_t>(pt), static_cast<Float_t>(theta), static_cast<Float_t>(eta),
715 static_cast<Float_t>(chi2AtPlane[0]),
716 static_cast<Float_t>(chi2AtPlane[1]),
717 static_cast<Float_t>(chi2AtPlane[2]),
718 static_cast<Float_t>(chi2AtPlane[3]),
719 static_cast<Float_t>(chi2AtPlane[4]),
720 static_cast<Float_t>(chi2AtPlane[5]),
721 static_cast<Float_t>(chi2AtPlane[6]),
722 static_cast<Float_t>(chi2AtPlane[7]),
723 static_cast<Float_t>(chi2AtPlane[8])};
820b4d9e 724
d4643a10 725 fNtuFinalCandidates -> Fill(finalCandidatesInfo);
726
820b4d9e 727 // now comparing the tracks with various criteria, in order to find the best one
728
729 Double_t theVariable = 0.;
d4643a10 730// theVariable = chi2AtPlane[0];
820b4d9e 731 for (Int_t iCluster=0; iCluster<nMFTClusters; iCluster++) theVariable += chi2AtPlane[iCluster];
732 theVariable /= Double_t(nMFTClusters);
d4643a10 733
820b4d9e 734
735 if (theVariable<theVariable_Best || theVariable_Best<0.) {
736 nGoodClustersBestCandidate = nGoodClusters;
737 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) chi2HistoryForBestCandidate[iPlane] = chi2AtPlane[iPlane];
738 theVariable_Best = theVariable;
d4643a10 739 fTxtTrackFinalChi2 = new TLatex(0.20, 0.44, Form("#chi^{2}_{final} = %3.1f", chi2HistoryForBestCandidate[0]));
820b4d9e 740 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
741 fTxtTrackChi2[iPlane] = new TLatex(0.55*fRPlaneMax[fNPlanesMFT-1],
742 0.90*fRPlaneMax[fNPlanesMFT-1],
743 Form("#chi^{2} = %3.1f", chi2AtPlane[iPlane]));
744 }
745 idBestCandidate = iTrack;
746 bestCandidateExists=kTRUE;
747 }
748
749 // ----------------------------------------------------------
750
751 }
d4643a10 752
820b4d9e 753 if (nFinalTracks) {
d4643a10 754 fFinalBestCandidate = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(idBestCandidate);
755 AliInfo(Form("fFinalBestCandidate->GetNMFTClusters() = %d\n", fFinalBestCandidate->GetNMFTClusters()));
756 PrintParticleHistory();
757 FillPlanesWithTrackHistory();
820b4d9e 758 AliMuonForwardTrack *newTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(idBestCandidate);
d4643a10 759 newTrack -> SetNWrongClustersMC(newTrack->GetNMFTClusters() - nGoodClustersBestCandidate);
7e3dd1af 760 newTrack -> SetTrackMCId(fRun*100000+fEv*1000+fCountRealTracksAnalyzedOfEvent);
d4643a10 761 new ((*fMuonForwardTracks)[fMuonForwardTracks->GetEntries()]) AliMuonForwardTrack(*newTrack);
7230691d 762 }
d4643a10 763
764 // fOutputQAFile->cd();
765
2942f542 766 Float_t finalBestCandidatesInfo[] = {static_cast<Float_t>(fRun),
767 static_cast<Float_t>(fEv),
768 static_cast<Float_t>(fCountRealTracksAnalyzedOfEvent),
769 static_cast<Float_t>(nFinalTracks),
770 static_cast<Float_t>(fLabelMC>=0),
771 static_cast<Float_t>(xVtx), static_cast<Float_t>(yVtx), static_cast<Float_t>(zVtx),
772 static_cast<Float_t>(motherPdg),
773 static_cast<Float_t>(fMuonTrackReco->GetMatchTrigger()),
774 static_cast<Float_t>(nClustersMC),
775 static_cast<Float_t>(nGoodClustersBestCandidate),
776 static_cast<Float_t>(pt), static_cast<Float_t>(theta), static_cast<Float_t>(eta),
777 static_cast<Float_t>(chi2HistoryForBestCandidate[0]),
778 static_cast<Float_t>(chi2HistoryForBestCandidate[1]),
779 static_cast<Float_t>(chi2HistoryForBestCandidate[2]),
780 static_cast<Float_t>(chi2HistoryForBestCandidate[3]),
781 static_cast<Float_t>(chi2HistoryForBestCandidate[4]),
782 static_cast<Float_t>(chi2HistoryForBestCandidate[5]),
783 static_cast<Float_t>(chi2HistoryForBestCandidate[6]),
784 static_cast<Float_t>(chi2HistoryForBestCandidate[7]),
785 static_cast<Float_t>(chi2HistoryForBestCandidate[8]),
786 static_cast<Float_t>(nClustersPerPlane[0]),
787 static_cast<Float_t>(nClustersPerPlane[1]),
788 static_cast<Float_t>(nClustersPerPlane[2]),
789 static_cast<Float_t>(nClustersPerPlane[3]),
790 static_cast<Float_t>(nClustersPerPlane[4]),
791 static_cast<Float_t>(nClustersPerPlane[5]),
792 static_cast<Float_t>(nClustersPerPlane[6]),
793 static_cast<Float_t>(nClustersPerPlane[7]),
794 static_cast<Float_t>(nClustersPerPlane[8])};
d4643a10 795
796 fNtuFinalBestCandidates -> Fill(finalBestCandidatesInfo);
820b4d9e 797
798 if (fDrawOption && bestCandidateExists) {
d4643a10 799 fTxtTrackGoodClusters = new TLatex(0.20, 0.51, Form("N_{GoodClusters} = %d", nGoodClustersBestCandidate));
820b4d9e 800 DrawPlanes();
801 }
802
820b4d9e 803 // -------------------------------------------------------------------------------------------
804
b5ab1ac4 805 fCandidateTracks->Delete();
d4643a10 806 fFinalBestCandidate = NULL;
820b4d9e 807
820b4d9e 808 return 5;
809
810}
811
812//===========================================================================================================================================
813
a2b7dc2a 814Int_t AliMuonForwardTrackFinder::FindClusterInPlane(Int_t planeId) {
820b4d9e 815
d4643a10 816 AliDebug(2, Form(">>>> executing AliMuonForwardTrackFinder::FindClusterInPlane(%d)\n", planeId));
820b4d9e 817
818 // !!!!!!!!! coordinates and errors on the interaction vertex should be taken from the event itself (ITS) if available
819
820 // propagate track to plane #planeId (both to front and back active sensors)
821 // look for compatible clusters
822 // update TrackParam at found cluster (if any) using Kalman Filter
823
824 AliMUONTrackParam currentParamFront, currentParamBack, currentParamForResearchFront, currentParamForResearchBack;
825
826 if (planeId == fNPlanesMFT-1) { // last plane of the telecope
827 currentParamFront = (*((AliMUONTrackParam*)(fMuonTrackReco->GetTrackParamAtCluster()->First())));
828 currentParamBack = (*((AliMUONTrackParam*)(fMuonTrackReco->GetTrackParamAtCluster()->First())));
829 currentParamForResearchFront = currentParamFront;
830 currentParamForResearchBack = currentParamBack;
b03d16a3 831 Double_t xExtrap = gRandom->Gaus(0,fVertexErrorX);
832 Double_t yExtrap = gRandom->Gaus(0,fVertexErrorY);
833 Double_t zExtrap = gRandom->Gaus(0,fVertexErrorZ);
7e3dd1af 834 if (fBransonCorrection) {
835 AliMUONTrackExtrap::ExtrapToVertex(&currentParamFront, xExtrap, yExtrap, zExtrap, fVertexErrorX, fVertexErrorY);
836 AliMUONTrackExtrap::ExtrapToVertex(&currentParamBack, xExtrap, yExtrap, zExtrap, fVertexErrorX, fVertexErrorY);
837 }
838 else {
839 AliMUONTrackExtrap::ExtrapToVertexWithoutBranson(&currentParamFront, zExtrap);
840 AliMUONTrackExtrap::ExtrapToVertexWithoutBranson(&currentParamBack, zExtrap);
841 }
b03d16a3 842 AliMUONTrackExtrap::ExtrapToVertex(&currentParamForResearchFront, xExtrap, yExtrap, zExtrap, fVertexErrorX, fVertexErrorY);
843 AliMUONTrackExtrap::ExtrapToVertex(&currentParamForResearchBack, xExtrap, yExtrap, zExtrap, fVertexErrorX, fVertexErrorY);
820b4d9e 844 }
845 else { // MFT planes others than the last one: mult. scattering correction because of the upstream MFT planes is performed
846 currentParamFront = (*((AliMUONTrackParam*)(fCurrentTrack->GetTrackParamAtCluster()->First())));
847 currentParamBack = (*((AliMUONTrackParam*)(fCurrentTrack->GetTrackParamAtCluster()->First())));
848 currentParamForResearchFront = currentParamFront;
849 currentParamForResearchBack = currentParamBack;
850 AliMUONTrackExtrap::AddMCSEffect(&currentParamFront, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
d4643a10 851 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeFront())/fRadLengthSi,-1.);
820b4d9e 852 AliMUONTrackExtrap::AddMCSEffect(&currentParamForResearchFront,(fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
d4643a10 853 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeFront())/fRadLengthSi,-1.);
820b4d9e 854 AliMUONTrackExtrap::AddMCSEffect(&currentParamBack, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
d4643a10 855 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeBack())/fRadLengthSi,-1.);
820b4d9e 856 AliMUONTrackExtrap::AddMCSEffect(&currentParamForResearchBack, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
d4643a10 857 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeBack())/fRadLengthSi,-1.);
820b4d9e 858 }
859 // for all planes: extrapolation to the Z of the plane
860 AliMUONTrackExtrap::ExtrapToZCov(&currentParamFront, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveFront());
861 AliMUONTrackExtrap::ExtrapToZCov(&currentParamForResearchFront, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveFront());
862 AliMUONTrackExtrap::ExtrapToZCov(&currentParamBack, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveBack());
863 AliMUONTrackExtrap::ExtrapToZCov(&currentParamForResearchBack, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveBack());
864
865 //---------------------------------------------------------------------------------------
866
867 TMatrixD covFront(5,5); covFront = currentParamForResearchFront.GetCovariances();
868 TMatrixD covBack(5,5); covBack = currentParamForResearchBack.GetCovariances();
869
870 Double_t squaredError_X_Front = covFront(0,0);
871 Double_t squaredError_Y_Front = covFront(2,2);
872 Double_t squaredError_X_Back = covBack(0,0);
873 Double_t squaredError_Y_Back = covBack(2,2);
874
875 Double_t corrFact = 1.0;
876
877 Double_t researchRadiusFront = TMath::Sqrt(squaredError_X_Front + squaredError_Y_Front);
878 Double_t researchRadiusBack = TMath::Sqrt(squaredError_X_Back + squaredError_Y_Back);
b5ab1ac4 879 if (0.5*(researchRadiusFront+researchRadiusBack)<fMinResearchRadiusAtPlane[planeId]) {
880 corrFact = fMinResearchRadiusAtPlane[planeId]/(0.5*(researchRadiusFront+researchRadiusBack));
820b4d9e 881 }
d4643a10 882 if (fIsCurrentMuonTrackable) {
883 // fOutputQAFile->cd();
884 fHistResearchRadius[planeId] -> Fill(0.5*(researchRadiusFront+researchRadiusBack));
885 }
820b4d9e 886
887 Double_t position_X_Front = currentParamForResearchFront.GetNonBendingCoor();
888 Double_t position_Y_Front = currentParamForResearchFront.GetBendingCoor();
889 Double_t position_X_Back = currentParamForResearchBack.GetNonBendingCoor();
890 Double_t position_Y_Back = currentParamForResearchBack.GetBendingCoor();
891 Double_t radialPositionOfTrackFront = TMath::Sqrt(position_X_Front*position_X_Front + position_Y_Front*position_Y_Front);
892 Double_t radialPositionOfTrackBack = TMath::Sqrt(position_X_Back*position_X_Back + position_Y_Back*position_Y_Back);
893
894 //---------------------------------------------------------------------------------------
895
a2b7dc2a 896 Double_t chi2cut = 2.*fScaleSigmaClusterCut*fScaleSigmaClusterCut*fSigmaClusterCut*fSigmaClusterCut; // depends on the number of variables (here, 2)
820b4d9e 897
898 // Analyizing the clusters: FRONT ACTIVE ELEMENTS
899
900 Int_t nClustersFront = fMFTClusterArrayFront[planeId]->GetEntries();
d4643a10 901 AliDebug(2, Form("There are %3d clusters in plane %02d FRONT\n", nClustersFront, planeId));
820b4d9e 902
903 for (Int_t iCluster=0; iCluster<nClustersFront; iCluster++) {
904
905 Bool_t isGoodChi2 = kFALSE;
906
907 AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArrayFront[planeId]->At(iCluster);
908 Double_t chi2 = (1./(corrFact*corrFact)) * TryOneCluster(currentParamForResearchFront, cluster); // describes the compatibility between the track and the cluster
909 if (chi2<chi2cut) isGoodChi2 = kTRUE;
910
911 Double_t radialPositionOfClusterFront = TMath::Sqrt(cluster->GetX()*cluster->GetX() + cluster->GetY()*cluster->GetY());
912 if (planeId == fNPlanesMFT-1) {
913 if (TMath::Abs(radialPositionOfTrackFront-radialPositionOfClusterFront)<fDistanceFromBestClusterAndTrackAtLastPlane ||
914 fDistanceFromBestClusterAndTrackAtLastPlane<0.) {
915 fDistanceFromBestClusterAndTrackAtLastPlane = TMath::Abs(radialPositionOfTrackFront-radialPositionOfClusterFront);
916 }
917 if (IsCorrectMatch(cluster)) {
918 fDistanceFromGoodClusterAndTrackAtLastPlane = TMath::Abs(radialPositionOfTrackFront-radialPositionOfClusterFront);
919 }
920 }
921
922 if (fIsCurrentMuonTrackable) {
d4643a10 923 // fOutputQAFile->cd();
820b4d9e 924 if (IsCorrectMatch(cluster)) fHistChi2Cluster_GoodCluster[planeId]->Fill(chi2/2.); // chi2/ndf
925 else fHistChi2Cluster_BadCluster[planeId] ->Fill(chi2/2.); // chi2/ndf
926 }
927
928 if (isGoodChi2) {
d4643a10 929 AliDebug(3, Form("accepting cluster: chi2=%f (cut = %f)\n", chi2, chi2cut));
820b4d9e 930 AliMuonForwardTrack *newTrack = new ((*fCandidateTracks)[fCandidateTracks->GetEntriesFast()]) AliMuonForwardTrack(*fCurrentTrack);
4cc511f4 931 if (fCandidateTracks->GetEntriesFast() > fMaxNCandidates) return kDiverged;
820b4d9e 932 newTrack->AddTrackParamAtMFTCluster(currentParamFront, *cluster); // creating new track param and attaching the cluster
ff80c017 933 AliDebug(2, Form("After plane %02d: newTrack->GetNMFTClusters() = %d (fCurrentTrack->GetNMFTClusters() = %d)",
d4643a10 934 planeId, newTrack->GetNMFTClusters(), fCurrentTrack->GetNMFTClusters()));
820b4d9e 935 newTrack->SetPlaneExists(planeId);
d4643a10 936 AliDebug(2, Form("current muon is trackable: %d\n", fIsCurrentMuonTrackable));
820b4d9e 937 if (fIsCurrentMuonTrackable) {
938 Double_t newGlobalChi2 = ((AliMUONTrackParam*) newTrack->GetTrackParamAtCluster()->First())->GetTrackChi2();
d4643a10 939 AliDebug(2, Form("new chi2 = %f (= %f)\n", newGlobalChi2, newTrack->GetMFTCluster(0)->GetTrackChi2()));
820b4d9e 940 Int_t nClustersGlobalTrack = newTrack->GetNMUONClusters() + newTrack->GetNMFTClusters(); // Muon Spectrometer clusters + clusters in the Vertex Telescope
941 Int_t ndfGlobalTrack = GetNDF(nClustersGlobalTrack);
d4643a10 942 // fOutputQAFile->cd();
943 if (IsCorrectMatch(cluster)) fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[planeId]->Fill(newGlobalChi2/Double_t(ndfGlobalTrack));
944 else fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[planeId] ->Fill(newGlobalChi2/Double_t(ndfGlobalTrack));
820b4d9e 945 }
d4643a10 946 fGrMFTPlane[kClustersGoodChi2][planeId] -> SetPoint(fGrMFTPlane[kClustersGoodChi2][planeId]->GetN(), cluster->GetX(), cluster->GetY());
820b4d9e 947 }
d4643a10 948 else AliDebug(3, Form("discarding cluster: chi2=%f (cut = %f)\n", chi2, chi2cut));
820b4d9e 949
950 }
951
952 // Analyizing the clusters: BACK ACTIVE ELEMENTS
953
954 Int_t nClustersBack = fMFTClusterArrayBack[planeId]->GetEntries();
d4643a10 955 AliDebug(2, Form("There are %3d clusters in plane %02d BACK\n", nClustersBack, planeId));
820b4d9e 956
957 for (Int_t iCluster=0; iCluster<nClustersBack; iCluster++) {
958
959 Bool_t isGoodChi2 = kFALSE;
960
961 AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArrayBack[planeId]->At(iCluster);
962 Double_t chi2 = (1./(corrFact*corrFact)) * TryOneCluster(currentParamForResearchBack, cluster); // describes the compatibility between the track and the cluster
963 if (chi2<chi2cut) isGoodChi2 = kTRUE;
964
965 Double_t radialPositionOfClusterBack = TMath::Sqrt(cluster->GetX()*cluster->GetX() + cluster->GetY()*cluster->GetY());
966 if (planeId == fNPlanesMFT-1) {
967 if (TMath::Abs(radialPositionOfTrackBack-radialPositionOfClusterBack)<fDistanceFromBestClusterAndTrackAtLastPlane ||
968 fDistanceFromBestClusterAndTrackAtLastPlane<0.) {
969 fDistanceFromBestClusterAndTrackAtLastPlane = TMath::Abs(radialPositionOfTrackBack-radialPositionOfClusterBack);
970 }
971 if (IsCorrectMatch(cluster)) {
972 fDistanceFromGoodClusterAndTrackAtLastPlane = TMath::Abs(radialPositionOfTrackBack-radialPositionOfClusterBack);
973 }
974 }
975
976 if (fIsCurrentMuonTrackable) {
d4643a10 977 // fOutputQAFile->cd();
820b4d9e 978 if (IsCorrectMatch(cluster)) fHistChi2Cluster_GoodCluster[planeId]->Fill(chi2/2.); // chi2/ndf
979 else fHistChi2Cluster_BadCluster[planeId] ->Fill(chi2/2.); // chi2/ndf
980 }
981
982 if (isGoodChi2) {
d4643a10 983 AliDebug(3,Form("accepting cluster: chi2=%f (cut = %f)\n", chi2, chi2cut));
820b4d9e 984 AliMuonForwardTrack *newTrack = new ((*fCandidateTracks)[fCandidateTracks->GetEntriesFast()]) AliMuonForwardTrack(*fCurrentTrack);
4cc511f4 985 if (fCandidateTracks->GetEntriesFast() > fMaxNCandidates) return kDiverged;
820b4d9e 986 newTrack->AddTrackParamAtMFTCluster(currentParamBack, *cluster); // creating new track param and attaching the cluster
ff80c017 987 AliDebug(2, Form("After plane %02d: newTrack->GetNMFTClusters() = %d (fCurrentTrack->GetNMFTClusters() = %d)",
d4643a10 988 planeId, newTrack->GetNMFTClusters(), fCurrentTrack->GetNMFTClusters()));
820b4d9e 989 newTrack->SetPlaneExists(planeId);
d4643a10 990 AliDebug(2, Form("current muon is trackable: %d\n", fIsCurrentMuonTrackable));
820b4d9e 991 if (fIsCurrentMuonTrackable) {
992 Double_t newGlobalChi2 = ((AliMUONTrackParam*) newTrack->GetTrackParamAtCluster()->First())->GetTrackChi2();
d4643a10 993 AliDebug(2, Form("new chi2 = %f (= %f)\n", newGlobalChi2, newTrack->GetMFTCluster(0)->GetTrackChi2()));
820b4d9e 994 Int_t nClustersGlobalTrack = newTrack->GetNMUONClusters() + newTrack->GetNMFTClusters(); // Muon Spectrometer clusters + clusters in the Vertex Telescope
995 Int_t ndfGlobalTrack = GetNDF(nClustersGlobalTrack);
d4643a10 996 // fOutputQAFile->cd();
997 if (IsCorrectMatch(cluster)) fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[planeId]->Fill(newGlobalChi2/Double_t(ndfGlobalTrack));
998 else fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[planeId] ->Fill(newGlobalChi2/Double_t(ndfGlobalTrack));
820b4d9e 999 }
d4643a10 1000 fGrMFTPlane[kClustersGoodChi2][planeId] -> SetPoint(fGrMFTPlane[kClustersGoodChi2][planeId]->GetN(), cluster->GetX(), cluster->GetY());
820b4d9e 1001 }
d4643a10 1002 else AliDebug(3,Form("discarding cluster: chi2=%f (cut = %f)\n", chi2, chi2cut));
820b4d9e 1003
1004 }
1005
1006 //---------------------------------------------------------------------------------------------
1007
1008 if (planeId == fNPlanesMFT-1) {
1009 if (fIsCurrentMuonTrackable && fDistanceFromGoodClusterAndTrackAtLastPlane>0.) {
d4643a10 1010 // fOutputQAFile->cd();
820b4d9e 1011 fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane -> Fill(TMath::Abs(fDistanceFromBestClusterAndTrackAtLastPlane-
1012 fDistanceFromGoodClusterAndTrackAtLastPlane));
1013 fHistDistanceGoodClusterFromTrackAtLastPlane -> Fill(fDistanceFromGoodClusterAndTrackAtLastPlane);
1014 }
1015 }
a2b7dc2a 1016
4cc511f4 1017 return kConverged;
820b4d9e 1018
1019}
1020
1021//==========================================================================================================================================
1022
1023void AliMuonForwardTrackFinder::AttachGoodClusterInPlane(Int_t planeId) {
1024
d4643a10 1025 AliDebug(1, Form(">>>> executing AliMuonForwardTrackFinder::AttachGoodClusterInPlane(%d)\n", planeId));
820b4d9e 1026
1027 AliMUONTrackParam currentParamFront, currentParamBack;
1028
1029 if (planeId == fNPlanesMFT-1) { // last plane of the telecope
1030 currentParamFront = (*((AliMUONTrackParam*)(fMuonTrackReco->GetTrackParamAtCluster()->First())));
1031 currentParamBack = (*((AliMUONTrackParam*)(fMuonTrackReco->GetTrackParamAtCluster()->First())));
1032 AliMUONTrackExtrap::ExtrapToVertexWithoutBranson(&currentParamFront, 0.);
1033 AliMUONTrackExtrap::ExtrapToVertexWithoutBranson(&currentParamBack, 0.);
1034 }
1035 else { // MFT planes others than the last one: mult. scattering correction because of the upstream MFT planes is performed
d4643a10 1036 AliDebug(2, Form("fCurrentTrack = %p\n", fCurrentTrack));
820b4d9e 1037 currentParamFront = (*((AliMUONTrackParam*)(fCurrentTrack->GetTrackParamAtCluster()->First())));
1038 currentParamBack = (*((AliMUONTrackParam*)(fCurrentTrack->GetTrackParamAtCluster()->First())));
1039 AliMUONTrackExtrap::AddMCSEffect(&currentParamFront, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
d4643a10 1040 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeFront())/fRadLengthSi,-1.);
820b4d9e 1041 AliMUONTrackExtrap::AddMCSEffect(&currentParamBack, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
d4643a10 1042 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeBack())/fRadLengthSi,-1.);
820b4d9e 1043 }
1044 // for all planes: linear extrapolation to the Z of the plane
1045 AliMUONTrackExtrap::ExtrapToZCov(&currentParamFront, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveFront());
1046 AliMUONTrackExtrap::ExtrapToZCov(&currentParamBack, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveBack());
1047
1048 Bool_t goodClusterFound = kFALSE;
1049
1050 // Analyizing the clusters: FRONT ACTIVE ELEMENTS
1051
1052 Int_t nClustersFront = fMFTClusterArrayFront[planeId]->GetEntries();
1053
d4643a10 1054 AliDebug(1, Form("nClustersFront = %d\n", nClustersFront));
820b4d9e 1055 for (Int_t iCluster=0; iCluster<nClustersFront; iCluster++) {
1056 AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArrayFront[planeId]->UncheckedAt(iCluster);
d4643a10 1057 AliDebug(2, Form("checking cluster %02d of %02d: cluter=%p, fCurrentTrack=%p\n", iCluster, nClustersFront, cluster, fCurrentTrack));
820b4d9e 1058 if (IsCorrectMatch(cluster)) {
1059 fCurrentTrack->AddTrackParamAtMFTCluster(currentParamFront, *cluster); // creating new track param and attaching the cluster
1060 fCurrentTrack->SetPlaneExists(planeId);
1061 goodClusterFound = kTRUE;
1062 break;
1063 }
1064 }
1065
1066 if (goodClusterFound) return;
1067
1068 // Analyizing the clusters: BACK ACTIVE ELEMENTS
1069
1070 Int_t nClustersBack = fMFTClusterArrayBack[planeId]->GetEntries();
1071
d4643a10 1072 AliDebug(1, Form("nClustersBack = %d\n", nClustersBack));
820b4d9e 1073 for (Int_t iCluster=0; iCluster<nClustersBack; iCluster++) {
1074 AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArrayBack[planeId]->UncheckedAt(iCluster);
d4643a10 1075 AliDebug(2,Form("checking cluster %02d of %02d: cluter=%p, fCurrentTrack=%p\n", iCluster, nClustersBack, cluster, fCurrentTrack));
820b4d9e 1076 if (IsCorrectMatch(cluster)) {
1077 fCurrentTrack->AddTrackParamAtMFTCluster(currentParamBack, *cluster); // creating new track param and attaching the cluster
1078 fCurrentTrack->SetPlaneExists(planeId);
1079 goodClusterFound = kTRUE;
1080 break;
1081 }
1082 }
1083
1084}
1085
1086//==========================================================================================================================================
1087
1088void AliMuonForwardTrackFinder::CheckCurrentMuonTrackable() {
1089
1090 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
1091 fIsGoodClusterInPlane[iPlane] = kFALSE;
1092 Int_t nClusters = fMFTClusterArray[iPlane]->GetEntriesFast();
1093 for (Int_t iCluster=0; iCluster<nClusters; iCluster++) {
1094 AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArray[iPlane]->At(iCluster);
1095 for (Int_t iTrack=0; iTrack<cluster->GetNMCTracks(); iTrack++) {
1096 if (cluster->GetMCLabel(iTrack)==fLabelMC) {
1097 fIsGoodClusterInPlane[iPlane] = kTRUE;
1098 break;
1099 }
1100 }
1101 }
1102 }
1103
1104 fIsCurrentMuonTrackable = kTRUE;
1105 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) fIsCurrentMuonTrackable = (fIsCurrentMuonTrackable&&fIsGoodClusterInPlane[iPlane]);
1106
1107}
1108
1109//==========================================================================================================================================
1110
d4643a10 1111void AliMuonForwardTrackFinder::FillPlanesWithTrackHistory() {
820b4d9e 1112
d4643a10 1113 // Fill planes with the clusters
820b4d9e 1114
d4643a10 1115 Int_t cluster = 0;
1116 AliDebug(2, Form("fFinalBestCandidate->GetNMFTClusters() = %d\n", fFinalBestCandidate->GetNMFTClusters()));
820b4d9e 1117 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
d4643a10 1118 if (fFinalBestCandidate->PlaneExists(iPlane)) {
1119 AliMFTCluster *trackCluster = fFinalBestCandidate->GetMFTCluster(cluster++);
1120 fGrMFTPlane[kClusterOfTrack][iPlane] -> SetPoint(fGrMFTPlane[kClusterOfTrack][iPlane]->GetN(), trackCluster->GetX(), trackCluster->GetY());
1121 }
820b4d9e 1122 Int_t nClusters = fMFTClusterArray[iPlane]->GetEntriesFast();
820b4d9e 1123 for (Int_t iCluster=0; iCluster<nClusters; iCluster++) {
d4643a10 1124 AliMFTCluster *myCluster = (AliMFTCluster*) fMFTClusterArray[iPlane]->UncheckedAt(iCluster);
1125 fGrMFTPlane[kAllClusters][iPlane] -> SetPoint(fGrMFTPlane[kAllClusters][iPlane]->GetN(), myCluster->GetX(), myCluster->GetY());
1126 if (IsCorrectMatch(myCluster)) {
1127 fGrMFTPlane[kClusterCorrectMC][iPlane] -> SetPoint(fGrMFTPlane[kClusterCorrectMC][iPlane]->GetN(), myCluster->GetX(), myCluster->GetY());
820b4d9e 1128 }
820b4d9e 1129 }
820b4d9e 1130 }
1131
1132}
1133
1134//======================================================================================================================================
1135
1136Bool_t AliMuonForwardTrackFinder::IsCorrectMatch(AliMFTCluster *cluster) {
1137
1138 Bool_t result = kFALSE;
1139
1140 // check if the cluster belongs to the correct MC track
1141
1142 for (Int_t iTrack=0; iTrack<cluster->GetNMCTracks(); iTrack++) {
1143 if (cluster->GetMCLabel(iTrack)==fLabelMC) {
1144 result = kTRUE;
1145 break;
1146 }
1147 }
1148
d4643a10 1149 AliDebug(2,Form("returning %d\n", result));
820b4d9e 1150
1151 return result;
1152
1153}
1154
1155//======================================================================================================================================
1156
1157Double_t AliMuonForwardTrackFinder::TryOneCluster(const AliMUONTrackParam &trackParam, AliMFTCluster *cluster) {
1158
1159 // Test the compatibility between the track and the cluster (using trackParam's covariance matrix):
1160 // return the corresponding Chi2
1161 // assume the track parameters are given at the Z of the cluster
1162
1163 // Set differences between trackParam and cluster in the bending and non bending directions
1164 Double_t dX = cluster->GetX() - trackParam.GetNonBendingCoor();
1165 Double_t dY = cluster->GetY() - trackParam.GetBendingCoor();
d4643a10 1166 AliDebug(3,Form("dX = %f, dY = %f\n", dX, dY));
820b4d9e 1167
1168 // Calculate errors and covariances
1169 const TMatrixD& kParamCov = trackParam.GetCovariances();
1170 Double_t sigmaX2 = kParamCov(0,0) + cluster->GetErrX2();
1171 Double_t sigmaY2 = kParamCov(2,2) + cluster->GetErrY2();
d4643a10 1172 AliDebug(3, Form("dX2 = %f, dY2 = %f\n", sigmaX2, sigmaY2));
820b4d9e 1173 Double_t covXY = kParamCov(0,2);
1174 Double_t det = sigmaX2 * sigmaY2 - covXY * covXY;
1175
1176 // Compute chi2
1177 if (det==0.) return 1.e10;
1178 return (dX*dX*sigmaY2 + dY*dY*sigmaX2 - 2.*dX*dY*covXY) / det;
1179
1180}
1181
1182//=========================================================================================================================================
1183
1184void AliMuonForwardTrackFinder::SeparateFrontBackClusters() {
1185
1186 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
e21f8bf5 1187 printf("Separating front/back clusters\n");
b5ab1ac4 1188 fMFTClusterArrayFront[iPlane]->Delete();
1189 fMFTClusterArrayBack[iPlane] ->Delete();
820b4d9e 1190 for (Int_t iCluster=0; iCluster<fMFTClusterArray[iPlane]->GetEntries(); iCluster++) {
1191 AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArray[iPlane]->At(iCluster);
1192 if (TMath::Abs(cluster->GetZ())<TMath::Abs(fSegmentation->GetPlane(iPlane)->GetZCenter())) {
1193 new ((*fMFTClusterArrayFront[iPlane])[fMFTClusterArrayFront[iPlane]->GetEntries()]) AliMFTCluster(*cluster);
1194 }
1195 else {
1196 new ((*fMFTClusterArrayBack[iPlane])[fMFTClusterArrayBack[iPlane]->GetEntries()]) AliMFTCluster(*cluster);
1197 }
1198 }
1199 }
1200
1201}
1202
1203//=========================================================================================================================================
1204
1205Int_t AliMuonForwardTrackFinder::GetNDF(Int_t nClusters) {
1206
1207 // the same definition as in AliMUONTrack is implemented, since here we just add more clusters to the Muon track
1208
1209 Int_t ndf = 2 * nClusters - 5;
1210 return (ndf > 0) ? ndf : 0;
1211
1212}
1213
1214//============================================================================================================================================
1215
1216void AliMuonForwardTrackFinder::BookHistos() {
d4643a10 1217
820b4d9e 1218 const Int_t nMaxNewTracks[] = {150, 200, 250, 600, 1000};
d4643a10 1219 const Double_t radiusPlane[] = {0.010, 0.010, 0.050, 0.5, 1.5};
820b4d9e 1220
820b4d9e 1221 fHistRadiusEndOfAbsorber = new TH1D("hRadiusEndOfAbsorber", "Track radial distance at the end of the absorber", 1000, 0, 100.);
1222
1223 fHistNGoodClustersForFinalTracks = new TH1D("hNGoodClustersForFinalTracks", "Number of Good Clusters per Final Track", 20, -0.25, 9.75);
1224
1225 fHistDistanceGoodClusterFromTrackAtLastPlane = new TH1D("hDistanceGoodClusterFromTrackAtLastPlane",
1226 "Distance of MC Good Cluster from Track in last MFT plane", 200, 0., 2.);
1227
1228 fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane =
1229 new TH1D("hDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane",
1230 "Good Cluster distance from track - Best Cluster distance from track in last MFT plane", 200, 0., 2.);
1231
1232 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
1233
1234 fHistNTracksAfterExtrapolation[iPlane] = new TH1D(Form("hNTracksAfterExtrapolation_pl%02d", iPlane),
1235 Form("Number of Candidates after analysis of MFT plane %02d", iPlane),
1236 nMaxNewTracks[iPlane], -0.5, nMaxNewTracks[iPlane]-0.5);
1237
1238 fHistResearchRadius[iPlane] = new TH1D(Form("hResearchRadius_pl%02d", iPlane),
1239 Form("Research Radius for candidate clusters in MFT plane %02d", iPlane),
1240 1000, 0., radiusPlane[iPlane]);
1241
1242 fHistChi2Cluster_GoodCluster[iPlane] = new TH1D(Form("hChi2Cluster_GoodCluster_pl%02d", iPlane),
1243 Form("#chi^{2}_{clust} for Good clusters in MFT plane %02d", iPlane),
1244 100, 0., 15.);
1245
1246 fHistChi2Cluster_BadCluster[iPlane] = new TH1D(Form("hChi2Cluster_BadCluster_pl%02d", iPlane),
1247 Form("#chi^{2}_{clust} for Bad clusters in MFT plane %02d", iPlane),
1248 100, 0., 15.);
1249
d4643a10 1250 fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[iPlane] = new TH1D(Form("fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons_pl%02d", iPlane),
1251 Form("#chi^{2}/ndf at plane %d for GOOD candidates of trackable muons",iPlane),
1252 100, 0., 15.);
1253
1254 fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[iPlane] = new TH1D(Form("fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons_pl%02d", iPlane),
1255 Form("#chi^{2}/ndf at plane %d for BAD candidates of trackable muons",iPlane),
1256 100, 0., 15.);
1257
820b4d9e 1258 }
1259
1260 //------------------------------------------
1261
820b4d9e 1262 fHistRadiusEndOfAbsorber -> Sumw2();
1263 fHistNGoodClustersForFinalTracks -> Sumw2();
1264
1265 fHistDistanceGoodClusterFromTrackAtLastPlane -> Sumw2();
1266 fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane -> Sumw2();
1267
1268 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
1269
1270 fHistNTracksAfterExtrapolation[iPlane] -> Sumw2();
1271 fHistResearchRadius[iPlane] -> Sumw2();
1272
1273 fHistChi2Cluster_GoodCluster[iPlane] -> Sumw2();
1274 fHistChi2Cluster_BadCluster[iPlane] -> Sumw2();
1275
d4643a10 1276 fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[iPlane] -> Sumw2();
1277 fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[iPlane] -> Sumw2();
820b4d9e 1278
1279 }
1280
6e8e4c4a 1281 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 1282
6e8e4c4a 1283 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 1284
1285}
1286
1287//============================================================================================================================================
1288
1289void AliMuonForwardTrackFinder::SetTitleHistos() {
1290
820b4d9e 1291 fHistRadiusEndOfAbsorber -> SetXTitle("R_{abs} [cm]");
1292 fHistNGoodClustersForFinalTracks -> SetXTitle("N_{GoodClusters}");
1293
1294 fHistDistanceGoodClusterFromTrackAtLastPlane -> SetXTitle("Distance [cm]");
1295 fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane -> SetXTitle("Distance [cm]");
1296
1297
1298 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
1299
1300 fHistNTracksAfterExtrapolation[iPlane] -> SetXTitle("N_{tracks}");
1301 fHistResearchRadius[iPlane] -> SetXTitle("Research Radius [cm]");
1302
1303 fHistChi2Cluster_GoodCluster[iPlane] -> SetXTitle("#chi^{2}/ndf");
1304 fHistChi2Cluster_BadCluster[iPlane] -> SetXTitle("#chi^{2}/ndf");
1305
d4643a10 1306 fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[iPlane] -> SetXTitle("#chi^{2}/ndf");
1307 fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[iPlane] -> SetXTitle("#chi^{2}/ndf");
820b4d9e 1308
1309 }
1310
1311}
1312
1313//===========================================================================================================================================
1314
1315void AliMuonForwardTrackFinder::BookPlanes() {
1316
1317 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
d4643a10 1318 fGrMFTPlane[kAllClusters][iPlane] = new TGraph();
1319 fGrMFTPlane[kAllClusters][iPlane] -> SetName(Form("fGrMFTPlane_%02d_AllClusters",iPlane));
1320 fGrMFTPlane[kAllClusters][iPlane] -> SetMarkerStyle(20);
1321 // fGrMFTPlane[kAllClusters][iPlane] -> SetMarkerSize(0.5);
1322 // fGrMFTPlane[kAllClusters][iPlane] -> SetMarkerSize(0.3);
1323 fGrMFTPlane[kAllClusters][iPlane] -> SetMarkerSize(0.2);
820b4d9e 1324 }
1325
1326 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
d4643a10 1327 fGrMFTPlane[kClustersGoodChi2][iPlane] = new TGraph();
1328 fGrMFTPlane[kClustersGoodChi2][iPlane] -> SetName(Form("fGrMFTPlane_%02d_ClustersGoodChi2",iPlane));
1329 fGrMFTPlane[kClustersGoodChi2][iPlane] -> SetMarkerStyle(20);
1330 // fGrMFTPlane[kClustersGoodChi2][iPlane] -> SetMarkerSize(0.8);
1331 // fGrMFTPlane[kClustersGoodChi2][iPlane] -> SetMarkerSize(0.4);
1332 fGrMFTPlane[kClustersGoodChi2][iPlane] -> SetMarkerSize(0.3);
1333 fGrMFTPlane[kClustersGoodChi2][iPlane] -> SetMarkerColor(kBlue);
820b4d9e 1334 }
1335
1336 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
d4643a10 1337 fGrMFTPlane[kClusterOfTrack][iPlane] = new TGraph();
1338 fGrMFTPlane[kClusterOfTrack][iPlane] -> SetName(Form("fGrMFTPlane_%02d_ClustersOfTrack",iPlane));
1339 fGrMFTPlane[kClusterOfTrack][iPlane] -> SetMarkerStyle(25);
1340 // fGrMFTPlane[kClusterOfTrack][iPlane] -> SetMarkerSize(1.2);
1341 fGrMFTPlane[kClusterOfTrack][iPlane] -> SetMarkerSize(0.9);
1342 fGrMFTPlane[kClusterOfTrack][iPlane] -> SetMarkerColor(kRed);
1343 fGrMFTPlane[kClusterOfTrack][iPlane] -> SetTitle(Form("Plane %d (%3.1f cm)", iPlane, fZPlane[iPlane]));
820b4d9e 1344 }
1345
1346 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
d4643a10 1347 fGrMFTPlane[kClusterCorrectMC][iPlane] = new TGraph();
1348 fGrMFTPlane[kClusterCorrectMC][iPlane] -> SetName(Form("fGrMFTPlane_%02d_ClustersCorrectMC",iPlane));
1349 fGrMFTPlane[kClusterCorrectMC][iPlane] -> SetMarkerStyle(20);
1350 // fGrMFTPlane[kClusterCorrectMC][iPlane] -> SetMarkerSize(0.8);
1351 fGrMFTPlane[kClusterCorrectMC][iPlane] -> SetMarkerSize(0.5);
1352 fGrMFTPlane[kClusterCorrectMC][iPlane] -> SetMarkerColor(kGreen);
820b4d9e 1353 }
1354
1355 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
1356 fCircleExt[iPlane] = new TEllipse(0., 0., fRPlaneMax[iPlane], fRPlaneMax[iPlane]);
1357 fCircleInt[iPlane] = new TEllipse(0., 0., fRPlaneMin[iPlane], fRPlaneMin[iPlane]);
1358 }
1359
d4643a10 1360 fTxtDummy = new TLatex(0.10, 0.59, "Best Candidate:");
820b4d9e 1361
1362 //---------------------------------------------------
1363
1364 fMrkAllClust = new TMarker(0.10, 0.32, 20);
1365 fMrkAllClust -> SetMarkerSize(0.5);
1366
1367 fMrkClustGoodChi2 = new TMarker(0.10, 0.26, 20);
1368 fMrkClustGoodChi2 -> SetMarkerSize(0.8);
1369 fMrkClustGoodChi2 -> SetMarkerColor(kBlue);
1370
1371 fMrkClustMC = new TMarker(0.10, 0.20, 20);
1372 fMrkClustMC -> SetMarkerSize(0.8);
1373 fMrkClustMC -> SetMarkerColor(kGreen);
1374
1375 fMrkClustOfTrack = new TMarker(0.10, 0.14, 25);
1376 fMrkClustOfTrack -> SetMarkerSize(1.2);
1377 fMrkClustOfTrack -> SetMarkerColor(kRed);
1378
1379 fTxtAllClust = new TLatex(0.15, 0.30, "All Clusters");
1380 fTxtAllClust -> SetTextSize(0.040);
1381
1382 fTxtClustGoodChi2 = new TLatex(0.15, 0.24, "Clusters involved in the research");
1383 fTxtClustGoodChi2 -> SetTextSize(0.040);
1384
1385 fTxtClustMC = new TLatex(0.15, 0.18, "MC good clusters");
1386 fTxtClustMC -> SetTextSize(0.040);
1387
1388 fTxtClustOfTrack = new TLatex(0.15, 0.12, "Clusters of the best candidate");
1389 fTxtClustOfTrack -> SetTextSize(0.040);
1390
1391}
1392
1393//===========================================================================================================================================
1394
1395void AliMuonForwardTrackFinder::ResetPlanes() {
1396
1397 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
1398 for (Int_t iGr=0; iGr<4; iGr++) {
d4643a10 1399 Int_t nOldClusters = fGrMFTPlane[iGr][iPlane]->GetN();
1400 for (Int_t iPoint=nOldClusters-1; iPoint>=0; iPoint--) fGrMFTPlane[iGr][iPlane]->RemovePoint(iPoint);
820b4d9e 1401 }
1402 }
1403
1404}
1405
1406//===========================================================================================================================================
1407
1408void AliMuonForwardTrackFinder::PrintParticleHistory() {
1409
d4643a10 1410 AliDebug(1, "Entering");
1411
820b4d9e 1412 TString history = "";
1413
d4643a10 1414 TParticle *part = 0;
1415 if (fLabelMC>=0) part = fStack->Particle(fLabelMC);
1416
ff80c017 1417 AliDebug(1, Form("fStack->Particle(%d) = %p", fLabelMC, part));
d4643a10 1418
1419 if (part) {
c0d58f1d 1420 AliDebug(1, Form("fStack->Particle(%d)->GetPdgCode() = %d", fLabelMC, part->GetPdgCode()));
d4643a10 1421 if (part->GetFirstMother() != -1) {
1422 TParticle *partMother = fStack->Particle(part->GetFirstMother());
ff80c017 1423 AliDebug(1, Form("fStack->Particle(%d) = %p", part->GetFirstMother(), partMother));
d4643a10 1424 if (partMother) {
1425 Char_t newName[100];
1426 if (partMother->GetFirstMother() != -1) history += "... #rightarrow ";
1427 PDGNameConverter(partMother->GetName(), newName);
1428 history += Form("%s #rightarrow ", newName);
1429 }
1430 }
820b4d9e 1431 Char_t newName[100];
ff80c017 1432 AliDebug(1, Form("fStack->Particle(%d)->GetPdgCode() = %d", fLabelMC, part->GetPdgCode()));
1433 AliDebug(1, Form("fStack->Particle(%d)->GetName() = %s", fLabelMC, part->GetName()));
d4643a10 1434 PDGNameConverter(part->GetName(), newName);
1435 history += Form("%s at z = %5.1f cm", newName, part->Vz());
1436 // printf("%s", history.Data());
820b4d9e 1437 }
d4643a10 1438 else history += "NO AVAILABLE HISTORY";
1439
820b4d9e 1440 fTxtMuonHistory = new TLatex(0.10, 0.86, history.Data());
d4643a10 1441
1442 // Filling particle history in the fFinalBestCandidate
1443
1444 if (part) {
1445 for (Int_t iParent=0; iParent<AliMuonForwardTrack::fgkNParentsMax; iParent++) {
1446 if (part->GetFirstMother() == -1) break;
1447 if (!(fStack->Particle(part->GetFirstMother()))) break;
1448 AliDebug(1, Form("fStack->Particle(part->GetFirstMother() = %p", fStack->Particle(part->GetFirstMother())));
1449 fFinalBestCandidate->SetParentMCLabel(iParent, part->GetFirstMother());
1450 fFinalBestCandidate->SetParentPDGCode(iParent, fStack->Particle(part->GetFirstMother())->GetPdgCode());
1451 part = fStack->Particle(part->GetFirstMother());
1452 }
1453 }
820b4d9e 1454
1455}
1456
1457//===========================================================================================================================================
1458
df4bbbc3 1459Bool_t AliMuonForwardTrackFinder::IsMother(const Char_t *nameMother) {
820b4d9e 1460
1461 Bool_t result = kFALSE;
1462
d4643a10 1463 TParticle *part = 0;
1464 if (fLabelMC>=0) part = fStack->Particle(fLabelMC);
820b4d9e 1465
d4643a10 1466 if (part) {
1467 if (part->GetFirstMother() != -1) {
1468 TParticle *partMother = fStack->Particle(part->GetFirstMother());
1469 if (partMother) {
1470 if (!strcmp(partMother->GetName(), nameMother)) result=kTRUE;
1471 }
1472 }
820b4d9e 1473 }
1474
1475 return result;
1476
1477}
1478
1479//===========================================================================================================================================
1480
1481void AliMuonForwardTrackFinder::DrawPlanes() {
1482
1483 fCanvas -> Clear();
1484 if (fNPlanesMFT <= 5) fCanvas -> Divide(3,2);
1485 else if (fNPlanesMFT <= 11) fCanvas -> Divide(4,3);
1486 else if (fNPlanesMFT <= 19) fCanvas -> Divide(5,4);
1487
1488 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
1489
1490 fCanvas->cd(fNPlanesMFT-iPlane+1);
1491
d4643a10 1492 fGrMFTPlane[kClusterOfTrack][iPlane] -> GetXaxis() -> SetLimits(-1.1*fRPlaneMax[fNPlanesMFT-1], +1.1*fRPlaneMax[fNPlanesMFT-1]);
1493 fGrMFTPlane[kClusterOfTrack][iPlane] -> GetYaxis() -> SetRangeUser(-1.1*fRPlaneMax[fNPlanesMFT-1], +1.1*fRPlaneMax[fNPlanesMFT-1]);
1494 fGrMFTPlane[kClusterOfTrack][iPlane] -> GetXaxis() -> SetTitle("X [cm]");
1495 fGrMFTPlane[kClusterOfTrack][iPlane] -> GetYaxis() -> SetTitle("Y [cm]");
1496 fGrMFTPlane[kClusterOfTrack][iPlane] -> Draw("ap");
820b4d9e 1497
1498 fCircleExt[iPlane] -> Draw("same");
1499 fCircleInt[iPlane] -> Draw("same");
1500
d4643a10 1501 if (fGrMFTPlane[kAllClusters][iPlane]->GetN()) fGrMFTPlane[kAllClusters][iPlane] -> Draw("psame");
1502 if (fGrMFTPlane[kClustersGoodChi2][iPlane]->GetN()) fGrMFTPlane[kClustersGoodChi2][iPlane] -> Draw("psame");
1503 if (fGrMFTPlane[kClusterOfTrack][iPlane]->GetN()) fGrMFTPlane[kClusterOfTrack][iPlane] -> Draw("psame");
1504 if (fGrMFTPlane[kClusterCorrectMC][iPlane]->GetN()) fGrMFTPlane[kClusterCorrectMC][iPlane] -> Draw("psame");
820b4d9e 1505
1506 fTxtTrackChi2[iPlane] -> Draw("same");
1507
1508 }
1509
1510 fCanvas -> cd(1);
1511 fTxtMuonHistory -> Draw();
1512 fTxtDummy -> Draw("same");
d4643a10 1513 if (fMatchingMode==kRealMatching) fTxtTrackGoodClusters -> Draw("same");
820b4d9e 1514 fTxtTrackFinalChi2 -> Draw("same");
d4643a10 1515 fTxtTrackMomentum -> Draw("same");
1516 if (fMatchingMode==kRealMatching) fTxtFinalCandidates -> Draw("same");
820b4d9e 1517
1518 fMrkAllClust -> Draw("same");
1519 fMrkClustGoodChi2 -> Draw("same");
1520 fMrkClustMC -> Draw("same");
1521 fMrkClustOfTrack -> Draw("same");
1522
1523 fTxtAllClust -> Draw("same");
1524 fTxtClustGoodChi2 -> Draw("same");
1525 fTxtClustMC -> Draw("same");
1526 fTxtClustOfTrack -> Draw("same");
1527
1528 // fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.eps", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
1529 fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.gif", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
1530 if (IsMother("phi")) {
1531 fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.phi.gif", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
1532 fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.phi.eps", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
1533 }
1534 if (IsMother("J/psi")) {
1535 fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.jPsi.gif", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
1536 fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.jPsi.eps", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
1537 }
1538
1539}
1540
1541//===========================================================================================================================================
1542
1543void AliMuonForwardTrackFinder::Terminate() {
1544
d4643a10 1545 AliInfo("");
1546 AliInfo("---------------------------------------------------------------------------------------------------------------");
1547 AliInfo(Form("%8d tracks analyzed", fCountRealTracksAnalyzed));
1548 AliInfo(Form("%8d tracks with MC ref", fCountRealTracksWithRefMC));
1549 AliInfo(Form("%8d tracks with MC ref & trigger match", fCountRealTracksWithRefMC_andTrigger));
1550 if (fMatchingMode==kRealMatching) {
1551 AliInfo(Form("%8d tracks analyzed with final candidates", fCountRealTracksAnalyzedWithFinalCandidates));
1552 }
1553 else {
1554 AliInfo(Form("%8d tracks matched with their MC clusters", fCountRealTracksAnalyzedWithFinalCandidates));
1555 }
1556// printf("%8d tracks with MC ref & trigger match & pt>%3.1f GeV/c", fCountRealTracksWithRefMC_andTrigger_andGoodPt, fLowPtCut);
1557// printf("%8d tracks with MC ref & trigger match & pt>%3.1f GeV/c & correct R_abs", fCountRealTracksWithRefMC_andTrigger_andGoodPt_andGoodTheta, fLowPtCut);
1558 AliInfo("---------------------------------------------------------------------------------------------------------------");
820b4d9e 1559
1560 WriteOutputTree();
1561 WriteHistos();
1562
1563}
1564
1565//==========================================================================================================================================
1566
1567void AliMuonForwardTrackFinder::FillOutputTree() {
1568
1569 if (!fMuonForwardTracks || !fOutputEventTree) return;
1570
1571 AliDebug(1, Form("Filling output tree %p with %p having %d entries whose 1st entry is %p",
1572 fOutputEventTree, fMuonForwardTracks, fMuonForwardTracks->GetEntries(), fMuonForwardTracks->At(0)));
1573
d4643a10 1574 // fOutputTreeFile->cd();
820b4d9e 1575 fOutputEventTree->Fill();
d4643a10 1576 AliDebug(1, Form("\nFilled Tree: nEvents = %d!!!!\n", Int_t(fOutputEventTree->GetEntries())));
820b4d9e 1577
1578}
1579
1580//==========================================================================================================================================
1581
1582void AliMuonForwardTrackFinder::WriteOutputTree() {
1583
1584 if (!fOutputEventTree || !fOutputTreeFile) return;
1585
1586 fOutputTreeFile -> cd();
1587
1588 fOutputEventTree -> Write();
1589 fOutputTreeFile -> Close();
1590
1591}
1592
1593//==========================================================================================================================================
1594
1595void AliMuonForwardTrackFinder::WriteHistos() {
1596
d4643a10 1597 fOutputQAFile = new TFile(Form("MuonGlobalTracking.QA.run%d.root", fRun), "recreate");
1598 fOutputQAFile -> cd();
820b4d9e 1599
820b4d9e 1600 fHistRadiusEndOfAbsorber -> Write();
1601 fHistNGoodClustersForFinalTracks -> Write();
1602
1603 fHistDistanceGoodClusterFromTrackAtLastPlane -> Write();
1604 fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane -> Write();
1605
1606 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
1607
1608 fHistNTracksAfterExtrapolation[iPlane] -> Write();
1609 fHistResearchRadius[iPlane] -> Write();
1610
1611 fHistChi2Cluster_GoodCluster[iPlane] -> Write();
1612 fHistChi2Cluster_BadCluster[iPlane] -> Write();
1613
d4643a10 1614 fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[iPlane] -> Write();
1615 fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[iPlane] -> Write();
820b4d9e 1616
1617 }
1618
d4643a10 1619 fNtuFinalCandidates -> Write();
1620 fNtuFinalBestCandidates -> Write();
820b4d9e 1621
d4643a10 1622 fOutputQAFile -> Close();
820b4d9e 1623
1624}
1625
1626//===========================================================================================================================================
1627
1628void AliMuonForwardTrackFinder::PDGNameConverter(const Char_t *nameIn, Char_t *nameOut) {
1629
d6080682 1630 if (!strcmp(nameIn, "mu+")) snprintf(nameOut, 50, "#mu^{+}");
1631 else if (!strcmp(nameIn, "mu-")) snprintf(nameOut, 50, "#mu^{-}");
1632 else if (!strcmp(nameIn, "pi+")) snprintf(nameOut, 50, "#pi^{+}");
1633 else if (!strcmp(nameIn, "pi-")) snprintf(nameOut, 50, "#pi^{-}");
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*+")) snprintf(nameOut, 50, "K^{*+}");
1637 else if (!strcmp(nameIn, "K*-")) snprintf(nameOut, 50, "K^{*-}");
1638 else if (!strcmp(nameIn, "K_S0")) snprintf(nameOut, 50, "K_{S}^{0}");
1639 else if (!strcmp(nameIn, "K_L0")) snprintf(nameOut, 50, "K_{L}^{0}");
1640 else if (!strcmp(nameIn, "K0")) snprintf(nameOut, 50, "K^{0}");
1641 else if (!strcmp(nameIn, "K0_bar")) snprintf(nameOut, 50, "#bar{K}^{0}");
1642 else if (!strcmp(nameIn, "K*0")) snprintf(nameOut, 50, "K^{*0}");
1643 else if (!strcmp(nameIn, "K*0_bar")) snprintf(nameOut, 50, "#bar{K}^{*0}");
1644 else if (!strcmp(nameIn, "rho0")) snprintf(nameOut, 50, "#rho^{0}");
1645 else if (!strcmp(nameIn, "rho+")) snprintf(nameOut, 50, "#rho^{+}");
1646 else if (!strcmp(nameIn, "rho-")) snprintf(nameOut, 50, "#rho^{-}");
1647 else if (!strcmp(nameIn, "omega")) snprintf(nameOut, 50, "#omega");
1648 else if (!strcmp(nameIn, "eta'")) snprintf(nameOut, 50, "#eta'");
1649 else if (!strcmp(nameIn, "phi")) snprintf(nameOut, 50, "#phi");
1650
1651 else if (!strcmp(nameIn, "D-")) snprintf(nameOut, 50, "D^{-}");
1652 else if (!strcmp(nameIn, "D+")) snprintf(nameOut, 50, "D^{+}");
1653 else if (!strcmp(nameIn, "D0")) snprintf(nameOut, 50, "D^{0}");
1654 else if (!strcmp(nameIn, "D0_bar")) snprintf(nameOut, 50, "#bar{D}^{0}");
1655 else if (!strcmp(nameIn, "D*-")) snprintf(nameOut, 50, "D^{*-}");
1656 else if (!strcmp(nameIn, "D*+")) snprintf(nameOut, 50, "D^{*+}");
1657 else if (!strcmp(nameIn, "D_s+")) snprintf(nameOut, 50, "D_{s}^{+}");
1658 else if (!strcmp(nameIn, "D*_s+")) snprintf(nameOut, 50, "D_{s}^{*+}");
1659
1660 else if (!strcmp(nameIn, "B-")) snprintf(nameOut, 50, "B^{-}");
1661 else if (!strcmp(nameIn, "B+")) snprintf(nameOut, 50, "B^{+}");
1662 else if (!strcmp(nameIn, "B_s0_bar")) snprintf(nameOut, 50, "#bar{B}_{s}^{0}");
1663
1664 else if (!strcmp(nameIn, "antiproton")) snprintf(nameOut, 50, "#bar{p}");
1665 else if (!strcmp(nameIn, "proton")) snprintf(nameOut, 50, "p");
1666 else if (!strcmp(nameIn, "neutron")) snprintf(nameOut, 50, "n");
1667 else if (!strcmp(nameIn, "Sigma+")) snprintf(nameOut, 50, "#Sigma^{+}");
1668 else if (!strcmp(nameIn, "Delta+")) snprintf(nameOut, 50, "#Delta{+}");
1669 else if (!strcmp(nameIn, "Delta--")) snprintf(nameOut, 50, "#Delta{--}");
1670 else if (!strcmp(nameIn, "Lambda0")) snprintf(nameOut, 50, "#Lambda_0");
1671 else if (!strcmp(nameIn, "Lambda0_bar")) snprintf(nameOut, 50, "#bar{Lambda}_0");
1672
1673 else snprintf(nameOut, 50, "%s", nameIn);
820b4d9e 1674
1675}
1676
1677//===========================================================================================================================================
1678
1679void AliMuonForwardTrackFinder::SetDraw(Bool_t drawOption) {
1680
1681 fDrawOption = drawOption;
1682
1683 if (!fCanvas) {
1684 fCanvas = new TCanvas("tracking", "tracking", 1200, 800);
1685 fCanvas -> Divide(3,2);
1686 }
1687
1688}
1689
1690//===========================================================================================================================================
1691
1692Bool_t AliMuonForwardTrackFinder::InitGRP() {
1693
1694 //------------------------------------
1695 // Initialization of the GRP entry
1696 //------------------------------------
1697
1698 AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/GRP/Data");
1699
1700 if (entry) {
1701
1702 TMap* m = dynamic_cast<TMap*>(entry->GetObject()); // old GRP entry
1703
1704 if (m) {
1705 AliInfo("Found a TMap in GRP/GRP/Data, converting it into an AliGRPObject");
1706 m->Print();
1707 fGRPData = new AliGRPObject();
1708 fGRPData->ReadValuesFromMap(m);
1709 }
1710
1711 else {
1712 AliInfo("Found an AliGRPObject in GRP/GRP/Data, reading it");
1713 fGRPData = dynamic_cast<AliGRPObject*>(entry->GetObject()); // new GRP entry
1714 entry->SetOwner(0);
1715 }
1716
1717 // FIX ME: The unloading of GRP entry is temporarily disabled
1718 // because ZDC and VZERO are using it in order to initialize
1719 // their reconstructor objects. In the future one has to think
1720 // of propagating AliRunInfo to the reconstructors.
1721 // AliCDBManager::Instance()->UnloadFromCache("GRP/GRP/Data");
1722 }
1723
1724 if (!fGRPData) {
1725 AliError("No GRP entry found in OCDB!");
1726 return kFALSE;
1727 }
1728
1729 TString lhcState = fGRPData->GetLHCState();
1730 if (lhcState==AliGRPObject::GetInvalidString()) {
1731 AliError("GRP/GRP/Data entry: missing value for the LHC state ! Using UNKNOWN");
1732 lhcState = "UNKNOWN";
1733 }
1734
1735 TString beamType = fGRPData->GetBeamType();
1736 if (beamType==AliGRPObject::GetInvalidString()) {
1737 AliError("GRP/GRP/Data entry: missing value for the beam type ! Using UNKNOWN");
1738 beamType = "UNKNOWN";
1739 }
1740
1741 Float_t beamEnergy = fGRPData->GetBeamEnergy();
1742 if (beamEnergy==AliGRPObject::GetInvalidFloat()) {
1743 AliError("GRP/GRP/Data entry: missing value for the beam energy ! Using 0");
1744 beamEnergy = 0;
1745 }
1746
1747 TString runType = fGRPData->GetRunType();
1748 if (runType==AliGRPObject::GetInvalidString()) {
1749 AliError("GRP/GRP/Data entry: missing value for the run type ! Using UNKNOWN");
1750 runType = "UNKNOWN";
1751 }
1752
1753 Int_t activeDetectors = fGRPData->GetDetectorMask();
1754 if (activeDetectors==AliGRPObject::GetInvalidUInt()) {
1755 AliError("GRP/GRP/Data entry: missing value for the detector mask ! Using 1074790399");
1756 activeDetectors = 1074790399;
1757 }
1758 AliDebug(1, Form("activeDetectors = %d", activeDetectors));
1759
1760 fRunInfo = new AliRunInfo(lhcState, beamType, beamEnergy, runType, activeDetectors);
1761 fRunInfo->Dump();
1762
1763 // *** Dealing with the magnetic field map
1764
1765 if ( TGeoGlobalMagField::Instance()->IsLocked() ) {
1766 if (TGeoGlobalMagField::Instance()->GetField()->TestBit(AliMagF::kOverrideGRP)) {
1767 AliInfo("ExpertMode!!! GRP information will be ignored !");
1768 AliInfo("ExpertMode!!! Running with the externally locked B field !");
1769 }
1770 else {
1771 AliInfo("Destroying existing B field instance!");
1772 delete TGeoGlobalMagField::Instance();
1773 }
1774 }
1775 if ( !TGeoGlobalMagField::Instance()->IsLocked() ) {
1776 // Construct the field map out of the information retrieved from GRP.
1777 Bool_t ok = kTRUE;
1778 // L3
1779 Float_t l3Current = fGRPData->GetL3Current((AliGRPObject::Stats)0);
1780 if (l3Current == AliGRPObject::GetInvalidFloat()) {
1781 AliError("GRP/GRP/Data entry: missing value for the L3 current !");
1782 ok = kFALSE;
1783 }
1784
1785 Char_t l3Polarity = fGRPData->GetL3Polarity();
1786 if (l3Polarity == AliGRPObject::GetInvalidChar()) {
1787 AliError("GRP/GRP/Data entry: missing value for the L3 polarity !");
1788 ok = kFALSE;
1789 }
1790
1791 // Dipole
1792 Float_t diCurrent = fGRPData->GetDipoleCurrent((AliGRPObject::Stats)0);
1793 if (diCurrent == AliGRPObject::GetInvalidFloat()) {
1794 AliError("GRP/GRP/Data entry: missing value for the dipole current !");
1795 ok = kFALSE;
1796 }
1797
1798 Char_t diPolarity = fGRPData->GetDipolePolarity();
1799 if (diPolarity == AliGRPObject::GetInvalidChar()) {
1800 AliError("GRP/GRP/Data entry: missing value for the dipole polarity !");
1801 ok = kFALSE;
1802 }
1803
1804 // read special bits for the polarity convention and map type
1805 Int_t polConvention = fGRPData->IsPolarityConventionLHC() ? AliMagF::kConvLHC : AliMagF::kConvDCS2008;
1806 Bool_t uniformB = fGRPData->IsUniformBMap();
1807
1808 if (ok) {
1809 AliMagF* fld = AliMagF::CreateFieldMap(TMath::Abs(l3Current) * (l3Polarity ? -1:1),
1810 TMath::Abs(diCurrent) * (diPolarity ? -1:1),
1811 polConvention,uniformB,beamEnergy, beamType.Data());
1812 if (fld) {
1813 TGeoGlobalMagField::Instance()->SetField( fld );
1814 TGeoGlobalMagField::Instance()->Lock();
1815 AliInfo("Running with the B field constructed out of GRP !");
1816 }
1817 else AliFatal("Failed to create a B field map !");
1818 }
1819 else AliFatal("B field is neither set nor constructed from GRP ! Exitig...");
1820 }
1821
1822 return kTRUE;
1823}
1824
1825//====================================================================================================================================================
1826
1827Bool_t AliMuonForwardTrackFinder::SetRunNumber() {
1828
1829 AliCDBManager *man = AliCDBManager::Instance();
1830
1831 if (!fRunLoader) {
1832 AliError("No run loader found!");
1833 return kFALSE;
1834 }
1835 else {
1836 fRunLoader->LoadHeader();
1837 // read run number from gAlice
1838 if (fRunLoader->GetHeader()) {
1839 man->SetRun(fRunLoader->GetHeader()->GetRun());
1840 fRunLoader->UnloadHeader();
1841 }
1842 else {
1843 AliError("No run-loader header found!");
1844 return kFALSE;
1845 }
1846 }
1847
1848 return kTRUE;
1849
1850}
1851
1852//====================================================================================================================================================
1853