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