]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - MFT/AliMuonForwardTrackFinder.cxx
update from salvatore
[u/mrichter/AliRoot.git] / MFT / AliMuonForwardTrackFinder.cxx
... / ...
CommitLineData
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"
50#include "AliMFTConstants.h"
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
63const Double_t AliMuonForwardTrackFinder::fRadLengthSi = AliMFTConstants::fRadLengthSi;
64
65ClassImp(AliMuonForwardTrackFinder)
66
67//=====================================================================================================
68
69AliMuonForwardTrackFinder::AliMuonForwardTrackFinder():
70 TObject(),
71 fRun(0),
72 fNEventsToAnalyze(0),
73 fSigmaClusterCut(0),
74 fChi2GlobalCut(0),
75 fSigmaSpectrometerCut(0),
76 fVertexErrorX(0.015),
77 fVertexErrorY(0.015),
78 fVertexErrorZ(0.010),
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
96 fHistRadiusEndOfAbsorber(0),
97 fHistNGoodClustersForFinalTracks(0),
98 fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane(0),
99 fHistDistanceGoodClusterFromTrackAtLastPlane(0),
100
101 fNtuFinalCandidates(0),
102 fNtuFinalBestCandidates(0),
103
104 fCanvas(0),
105
106 fTxtMuonHistory(0),
107 fTxtTrackGoodClusters(0),
108 fTxtTrackFinalChi2(0),
109 fTxtTrackMomentum(0),
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
121 fCountRealTracksAnalyzed(0),
122 fMaxNTracksToBeAnalyzed(99999999),
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),
140 fFinalBestCandidate(0),
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),
150 fOutputQAFile(0),
151 fOutputEventTree(0),
152 fMuonForwardTracks(0),
153 fMatchingMode(-1),
154 fGRPData(0),
155 fRunInfo(0),
156 fBransonCorrection(kTRUE)
157
158{
159
160 // Default constructor
161
162 for (Int_t iPlane=0; iPlane<AliMFTConstants::fNMaxPlanes; iPlane++) {
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
174 fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[iPlane] = 0;
175 fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[iPlane] = 0;
176
177 fZPlane[iPlane] = 0.;
178 fRPlaneMax[iPlane] = 0.;
179 fRPlaneMin[iPlane] = 0.;
180
181 for (Int_t i=0; i<4; i++) fGrMFTPlane[i][iPlane] = 0;
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
195 fMinResearchRadiusAtPlane[iPlane] = 0.;
196
197 }
198
199 // fNextTrack = 0;
200
201 fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane = 0;
202 fHistDistanceGoodClusterFromTrackAtLastPlane = 0;
203
204 fMFTClusterTree = 0;
205 fCandidateTracks = 0;
206
207 fOutputTreeFile = new TFile("MuonGlobalTracks.root", "recreate");
208 fOutputEventTree = new TTree("AliMuonForwardTracks", "Tree of AliMuonForwardTracks");
209 fMuonForwardTracks = new TClonesArray("AliMuonForwardTrack");
210 fOutputEventTree -> Branch("tracks", &fMuonForwardTracks);
211
212}
213
214//=====================================================================================================
215
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
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
308void AliMuonForwardTrackFinder::Init(Int_t nRun,
309 Char_t *readDir,
310 Char_t *outDir,
311 Int_t nEventsToAnalyze) {
312
313 if (fRunLoader) {
314 AliInfo("WARNING: run already initialized!!\n");
315 }
316
317 SetRun(nRun);
318 SetReadDir(readDir);
319 SetOutDir(outDir);
320
321 AliInfo(Form("input dir = %s\n", fReadDir.Data()));
322 AliInfo(Form("output dir = %s\n", fOutDir.Data()));
323
324 // -------------------------- initializing files...
325
326 AliInfo(Form("initializing files for run %d...\n", fRun));
327
328 Char_t geoFileName[300];
329 Char_t esdFileName[300];
330 Char_t gAliceName[300];
331 Char_t clusterName[300];
332
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());
337
338 // Import TGeo geometry (needed by AliMUONTrackExtrap::ExtrapToVertex)
339 if (!gGeoManager) {
340 TGeoManager::Import(geoFileName);
341 if (!gGeoManager) {
342 AliError(Form("getting geometry from file %s failed", geoFileName));
343 return;
344 }
345 }
346
347 fFileESD = new TFile(esdFileName);
348 if (!fFileESD || !fFileESD->IsOpen()) return;
349 else AliInfo(Form("file %s successfully opened\n", fFileESD->GetName()));
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;
354 else AliInfo(Form("file %s successfully opened\n", fFile_gAlice->GetName()));
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
379 Int_t nEventsInFile = fMuonRecoCheck->NumberOfEvents();
380 if (!nEventsInFile) {
381 AliError("no events available!!!\n");
382 return;
383 }
384 if (nEventsInFile<nEventsToAnalyze || nEventsToAnalyze<0) fNEventsToAnalyze = nEventsInFile;
385 else fNEventsToAnalyze = nEventsToAnalyze;
386
387 fCandidateTracks = new TClonesArray("AliMuonForwardTrack",50000);
388
389 // -------------------------- initializing histograms...
390
391 AliInfo("\ninitializing histograms...\n");
392 BookHistos();
393 SetTitleHistos();
394 AliInfo("... done!\n\n");
395
396 // -------------------------- initializing graphics...
397
398 AliInfo("initializing graphics...\n");
399 BookPlanes();
400 AliInfo("... done!\n\n");
401
402 SetSigmaSpectrometerCut(4.0);
403 SetSigmaClusterCut(4.5);
404 SetChi2GlobalCut(2.0);
405 SetNFinalCandidatesCut(10);
406 SetRAbsorberCut(26.4);
407 SetLowPtCut(0.5);
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
423 AliInfo(Form(" **** analyzing event # %d \n", fEv));
424
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));
433 fTrackRefStore = fMuonRecoCheck->ReconstructibleTracks(fEv);
434
435 AliDebug(2, Form("Getting fRunLoader->GetEvent(%d)", fEv));
436 fRunLoader->GetEvent(fEv);
437
438 AliDebug(2, Form("fMFTLoader->TreeR() = %p",fMFTLoader->TreeR()));
439 if (!fMFTLoader->TreeR()->GetEvent()) return kFALSE;
440 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
441 AliDebug(1, Form("plane %02d: nClusters = %d\n", iPlane, (fMFT->GetRecPointsList(iPlane))->GetEntries()));
442 fMFTClusterArray[iPlane] = fMFT->GetRecPointsList(iPlane);
443 }
444 SeparateFrontBackClusters();
445
446 fRunLoader -> LoadKinematics();
447 fStack = fRunLoader->Stack();
448 fNextTrack = fTrackStore->CreateIterator();
449 fMuonForwardTracks->Delete();
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
465 if (fCountRealTracksAnalyzed>fMaxNTracksToBeAnalyzed) return kFALSE;
466
467 if (!fCountRealTracksAnalyzed) if (!LoadNextEvent()) return kFALSE;
468 if (fCountRealTracksAnalyzed==fMaxNTracksToBeAnalyzed) {
469 fCountRealTracksAnalyzed++;
470 if (!LoadNextEvent()) return kFALSE;
471 }
472
473 while ( !(fMuonTrackReco = static_cast<AliMUONTrack*>(fNextTrack->Next())) ) if (!LoadNextEvent()) return kFALSE;
474
475 AliDebug(1, "**************************************************************************************\n");
476 AliDebug(1, Form("*************************** MUON TRACK %3d ***************************************\n", fCountRealTracksAnalyzedOfEvent));
477 AliDebug(1, "**************************************************************************************\n");
478
479 fCountRealTracksAnalyzed++;
480
481 fCandidateTracks -> Delete();
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
506 fLabelMC = fMuonTrackReco->GetMCLabel();
507
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
516 CheckCurrentMuonTrackable();
517
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();
522 track -> SetMUONTrack(new AliMUONTrack(*fMuonTrackReco));
523 if (fLabelMC>=0 && fStack->Particle(fLabelMC)) track->SetMCTrackRef(new TParticle(*(fStack->Particle(fLabelMC))));
524 track -> SetMCLabel(fMuonTrackReco->GetMCLabel());
525 track -> SetMatchTrigger(fMuonTrackReco->GetMatchTrigger());
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;
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
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
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();
586 if (fIsCurrentMuonTrackable) {
587 // fOutputQAFile->cd();
588 fHistNTracksAfterExtrapolation[iPlane] -> Fill(fCandidateTracks->GetEntriesFast());
589 }
590 }
591
592 else if (fMatchingMode==kIdealMatching && fIsCurrentMuonTrackable) {
593 fCurrentTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(0);
594 AliDebug(2, Form("plane %02d: fCandidateTracks->GetEntriesFast() = %d fCandidateTracks->UncheckedAt(0) = %p fCurrentTrack = %p\n",
595 iPlane, fCandidateTracks->GetEntriesFast(), fCandidateTracks->UncheckedAt(0), fCurrentTrack));
596 AttachGoodClusterInPlane(iPlane);
597 }
598
599 }
600
601 // -------------------------- END OF THE CYCLE OVER THE MFT PLANES --------------------------------------------
602
603 AliDebug(1, "Finished cycle over planes");
604
605 Double_t momentum = pt * TMath::CosH(eta);
606 fTxtTrackMomentum = new TLatex(0.10, 0.70, Form("P_{spectro} = %3.1f GeV/c", momentum));
607
608 if (fMatchingMode==kIdealMatching) {
609 AliDebug(1, "Adding track to output tree...\n");
610 fFinalBestCandidate = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(0);
611 AliMuonForwardTrack *newTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(0);
612 new ((*fMuonForwardTracks)[fMuonForwardTracks->GetEntries()]) AliMuonForwardTrack(*newTrack);
613 AliDebug(1, "...track added!\n");
614 fCandidateTracks->Delete();
615 fCountRealTracksAnalyzedOfEvent++;
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();
643 return 5;
644 }
645
646 // If we have several final tracks, we must find the best candidate:
647
648 Int_t nFinalTracks = fCandidateTracks->GetEntriesFast();
649 AliDebug(1, Form("nFinalTracks = %d", nFinalTracks));
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;
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 }
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
673 Double_t chi2AtPlane[fNMaxPlanes] = {0};
674 Int_t nGoodClusters = 0;
675 Int_t nMFTClusters = finalTrack->GetNMFTClusters();
676// Int_t nMUONClusters = finalTrack->GetNMUONClusters();
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);
682 chi2AtPlane[plane] = localCluster->GetLocalChi2();
683 if (IsCorrectMatch(localCluster)) nGoodClusters++;
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++;
688 }
689
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),
701 Double_t(fLabelMC>=0),
702 xVtx, yVtx, zVtx,
703 motherPdg,
704 Double_t(fMuonTrackReco->GetMatchTrigger()),
705 Double_t(nClustersMC),
706 Double_t(nGoodClusters),
707 pt, theta, eta,
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]};
717
718 fNtuFinalCandidates -> Fill(finalCandidatesInfo);
719
720 // now comparing the tracks with various criteria, in order to find the best one
721
722 Double_t theVariable = 0.;
723// theVariable = chi2AtPlane[0];
724 for (Int_t iCluster=0; iCluster<nMFTClusters; iCluster++) theVariable += chi2AtPlane[iCluster];
725 theVariable /= Double_t(nMFTClusters);
726
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;
732 fTxtTrackFinalChi2 = new TLatex(0.20, 0.44, Form("#chi^{2}_{final} = %3.1f", chi2HistoryForBestCandidate[0]));
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 }
745
746 if (nFinalTracks) {
747 fFinalBestCandidate = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(idBestCandidate);
748 AliInfo(Form("fFinalBestCandidate->GetNMFTClusters() = %d\n", fFinalBestCandidate->GetNMFTClusters()));
749 PrintParticleHistory();
750 FillPlanesWithTrackHistory();
751 AliMuonForwardTrack *newTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(idBestCandidate);
752 newTrack -> SetNWrongClustersMC(newTrack->GetNMFTClusters() - nGoodClustersBestCandidate);
753 newTrack -> SetTrackMCId(fRun*100000+fEv*1000+fCountRealTracksAnalyzedOfEvent);
754 new ((*fMuonForwardTracks)[fMuonForwardTracks->GetEntries()]) AliMuonForwardTrack(*newTrack);
755 }
756
757 // fOutputQAFile->cd();
758
759 Float_t finalBestCandidatesInfo[] = {Double_t(fRun),
760 Double_t(fEv),
761 Double_t(fCountRealTracksAnalyzedOfEvent),
762 Double_t(nFinalTracks),
763 Double_t(fLabelMC>=0),
764 xVtx, yVtx, zVtx,
765 motherPdg,
766 Double_t(fMuonTrackReco->GetMatchTrigger()),
767 Double_t(nClustersMC),
768 Double_t(nGoodClustersBestCandidate),
769 pt, theta, eta,
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);
790
791 if (fDrawOption && bestCandidateExists) {
792 fTxtTrackGoodClusters = new TLatex(0.20, 0.51, Form("N_{GoodClusters} = %d", nGoodClustersBestCandidate));
793 DrawPlanes();
794 }
795
796 // -------------------------------------------------------------------------------------------
797
798 fCandidateTracks->Delete();
799 fFinalBestCandidate = NULL;
800
801 fCountRealTracksAnalyzedOfEvent++;
802
803 return 5;
804
805}
806
807//===========================================================================================================================================
808
809void AliMuonForwardTrackFinder::FindClusterInPlane(Int_t planeId) {
810
811 AliDebug(2, Form(">>>> executing AliMuonForwardTrackFinder::FindClusterInPlane(%d)\n", planeId));
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;
826 Double_t xExtrap = gRandom->Gaus(0,fVertexErrorX);
827 Double_t yExtrap = gRandom->Gaus(0,fVertexErrorY);
828 Double_t zExtrap = gRandom->Gaus(0,fVertexErrorZ);
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 }
837 AliMUONTrackExtrap::ExtrapToVertex(&currentParamForResearchFront, xExtrap, yExtrap, zExtrap, fVertexErrorX, fVertexErrorY);
838 AliMUONTrackExtrap::ExtrapToVertex(&currentParamForResearchBack, xExtrap, yExtrap, zExtrap, fVertexErrorX, fVertexErrorY);
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()+
846 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeFront())/fRadLengthSi,-1.);
847 AliMUONTrackExtrap::AddMCSEffect(&currentParamForResearchFront,(fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
848 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeFront())/fRadLengthSi,-1.);
849 AliMUONTrackExtrap::AddMCSEffect(&currentParamBack, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
850 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeBack())/fRadLengthSi,-1.);
851 AliMUONTrackExtrap::AddMCSEffect(&currentParamForResearchBack, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
852 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeBack())/fRadLengthSi,-1.);
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);
874 if (0.5*(researchRadiusFront+researchRadiusBack)<fMinResearchRadiusAtPlane[planeId]) {
875 corrFact = fMinResearchRadiusAtPlane[planeId]/(0.5*(researchRadiusFront+researchRadiusBack));
876 }
877 if (fIsCurrentMuonTrackable) {
878 // fOutputQAFile->cd();
879 fHistResearchRadius[planeId] -> Fill(0.5*(researchRadiusFront+researchRadiusBack));
880 }
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();
896 AliDebug(2, Form("There are %3d clusters in plane %02d FRONT\n", nClustersFront, planeId));
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) {
918 // fOutputQAFile->cd();
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) {
924 AliDebug(3, Form("accepting cluster: chi2=%f (cut = %f)\n", chi2, chi2cut));
925 AliMuonForwardTrack *newTrack = new ((*fCandidateTracks)[fCandidateTracks->GetEntriesFast()]) AliMuonForwardTrack(*fCurrentTrack);
926 newTrack->AddTrackParamAtMFTCluster(currentParamFront, *cluster); // creating new track param and attaching the cluster
927 AliDebug(2, Form("After plane %02d: newTrack->GetNMFTClusters() = %d (fCurrentTrack->GetNMFTClusters() = %d)",
928 planeId, newTrack->GetNMFTClusters(), fCurrentTrack->GetNMFTClusters()));
929 newTrack->SetPlaneExists(planeId);
930 AliDebug(2, Form("current muon is trackable: %d\n", fIsCurrentMuonTrackable));
931 if (fIsCurrentMuonTrackable) {
932 Double_t newGlobalChi2 = ((AliMUONTrackParam*) newTrack->GetTrackParamAtCluster()->First())->GetTrackChi2();
933 AliDebug(2, Form("new chi2 = %f (= %f)\n", newGlobalChi2, newTrack->GetMFTCluster(0)->GetTrackChi2()));
934 Int_t nClustersGlobalTrack = newTrack->GetNMUONClusters() + newTrack->GetNMFTClusters(); // Muon Spectrometer clusters + clusters in the Vertex Telescope
935 Int_t ndfGlobalTrack = GetNDF(nClustersGlobalTrack);
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));
939 }
940 fGrMFTPlane[kClustersGoodChi2][planeId] -> SetPoint(fGrMFTPlane[kClustersGoodChi2][planeId]->GetN(), cluster->GetX(), cluster->GetY());
941 }
942 else AliDebug(3, Form("discarding cluster: chi2=%f (cut = %f)\n", chi2, chi2cut));
943
944 }
945
946 // Analyizing the clusters: BACK ACTIVE ELEMENTS
947
948 Int_t nClustersBack = fMFTClusterArrayBack[planeId]->GetEntries();
949 AliDebug(2, Form("There are %3d clusters in plane %02d BACK\n", nClustersBack, planeId));
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) {
971 // fOutputQAFile->cd();
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) {
977 AliDebug(3,Form("accepting cluster: chi2=%f (cut = %f)\n", chi2, chi2cut));
978 AliMuonForwardTrack *newTrack = new ((*fCandidateTracks)[fCandidateTracks->GetEntriesFast()]) AliMuonForwardTrack(*fCurrentTrack);
979 newTrack->AddTrackParamAtMFTCluster(currentParamBack, *cluster); // creating new track param and attaching the cluster
980 AliDebug(2, Form("After plane %02d: newTrack->GetNMFTClusters() = %d (fCurrentTrack->GetNMFTClusters() = %d)",
981 planeId, newTrack->GetNMFTClusters(), fCurrentTrack->GetNMFTClusters()));
982 newTrack->SetPlaneExists(planeId);
983 AliDebug(2, Form("current muon is trackable: %d\n", fIsCurrentMuonTrackable));
984 if (fIsCurrentMuonTrackable) {
985 Double_t newGlobalChi2 = ((AliMUONTrackParam*) newTrack->GetTrackParamAtCluster()->First())->GetTrackChi2();
986 AliDebug(2, Form("new chi2 = %f (= %f)\n", newGlobalChi2, newTrack->GetMFTCluster(0)->GetTrackChi2()));
987 Int_t nClustersGlobalTrack = newTrack->GetNMUONClusters() + newTrack->GetNMFTClusters(); // Muon Spectrometer clusters + clusters in the Vertex Telescope
988 Int_t ndfGlobalTrack = GetNDF(nClustersGlobalTrack);
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));
992 }
993 fGrMFTPlane[kClustersGoodChi2][planeId] -> SetPoint(fGrMFTPlane[kClustersGoodChi2][planeId]->GetN(), cluster->GetX(), cluster->GetY());
994 }
995 else AliDebug(3,Form("discarding cluster: chi2=%f (cut = %f)\n", chi2, chi2cut));
996
997 }
998
999 //---------------------------------------------------------------------------------------------
1000
1001 if (planeId == fNPlanesMFT-1) {
1002 if (fIsCurrentMuonTrackable && fDistanceFromGoodClusterAndTrackAtLastPlane>0.) {
1003 // fOutputQAFile->cd();
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
1016 AliDebug(1, Form(">>>> executing AliMuonForwardTrackFinder::AttachGoodClusterInPlane(%d)\n", planeId));
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
1027 AliDebug(2, Form("fCurrentTrack = %p\n", fCurrentTrack));
1028 currentParamFront = (*((AliMUONTrackParam*)(fCurrentTrack->GetTrackParamAtCluster()->First())));
1029 currentParamBack = (*((AliMUONTrackParam*)(fCurrentTrack->GetTrackParamAtCluster()->First())));
1030 AliMUONTrackExtrap::AddMCSEffect(&currentParamFront, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
1031 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeFront())/fRadLengthSi,-1.);
1032 AliMUONTrackExtrap::AddMCSEffect(&currentParamBack, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
1033 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeBack())/fRadLengthSi,-1.);
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
1045 AliDebug(1, Form("nClustersFront = %d\n", nClustersFront));
1046 for (Int_t iCluster=0; iCluster<nClustersFront; iCluster++) {
1047 AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArrayFront[planeId]->UncheckedAt(iCluster);
1048 AliDebug(2, Form("checking cluster %02d of %02d: cluter=%p, fCurrentTrack=%p\n", iCluster, nClustersFront, cluster, fCurrentTrack));
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
1063 AliDebug(1, Form("nClustersBack = %d\n", nClustersBack));
1064 for (Int_t iCluster=0; iCluster<nClustersBack; iCluster++) {
1065 AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArrayBack[planeId]->UncheckedAt(iCluster);
1066 AliDebug(2,Form("checking cluster %02d of %02d: cluter=%p, fCurrentTrack=%p\n", iCluster, nClustersBack, cluster, fCurrentTrack));
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
1102void AliMuonForwardTrackFinder::FillPlanesWithTrackHistory() {
1103
1104 // Fill planes with the clusters
1105
1106 Int_t cluster = 0;
1107 AliDebug(2, Form("fFinalBestCandidate->GetNMFTClusters() = %d\n", fFinalBestCandidate->GetNMFTClusters()));
1108 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
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 }
1113 Int_t nClusters = fMFTClusterArray[iPlane]->GetEntriesFast();
1114 for (Int_t iCluster=0; iCluster<nClusters; iCluster++) {
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());
1119 }
1120 }
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
1140 AliDebug(2,Form("returning %d\n", result));
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();
1157 AliDebug(3,Form("dX = %f, dY = %f\n", dX, dY));
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();
1163 AliDebug(3, Form("dX2 = %f, dY2 = %f\n", sigmaX2, sigmaY2));
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++) {
1178 fMFTClusterArrayFront[iPlane]->Delete();
1179 fMFTClusterArrayBack[iPlane] ->Delete();
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() {
1207
1208 const Int_t nMaxNewTracks[] = {150, 200, 250, 600, 1000};
1209 const Double_t radiusPlane[] = {0.010, 0.010, 0.050, 0.5, 1.5};
1210
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
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
1248 }
1249
1250 //------------------------------------------
1251
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
1266 fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[iPlane] -> Sumw2();
1267 fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[iPlane] -> Sumw2();
1268
1269 }
1270
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");
1272
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");
1274
1275}
1276
1277//============================================================================================================================================
1278
1279void AliMuonForwardTrackFinder::SetTitleHistos() {
1280
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
1296 fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[iPlane] -> SetXTitle("#chi^{2}/ndf");
1297 fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[iPlane] -> SetXTitle("#chi^{2}/ndf");
1298
1299 }
1300
1301}
1302
1303//===========================================================================================================================================
1304
1305void AliMuonForwardTrackFinder::BookPlanes() {
1306
1307 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
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);
1314 }
1315
1316 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
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);
1324 }
1325
1326 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
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]));
1334 }
1335
1336 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
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);
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
1350 fTxtDummy = new TLatex(0.10, 0.59, "Best Candidate:");
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++) {
1389 Int_t nOldClusters = fGrMFTPlane[iGr][iPlane]->GetN();
1390 for (Int_t iPoint=nOldClusters-1; iPoint>=0; iPoint--) fGrMFTPlane[iGr][iPlane]->RemovePoint(iPoint);
1391 }
1392 }
1393
1394}
1395
1396//===========================================================================================================================================
1397
1398void AliMuonForwardTrackFinder::PrintParticleHistory() {
1399
1400 AliDebug(1, "Entering");
1401
1402 TString history = "";
1403
1404 TParticle *part = 0;
1405 if (fLabelMC>=0) part = fStack->Particle(fLabelMC);
1406
1407 AliDebug(1, Form("fStack->Particle(%d) = %p", fLabelMC, part));
1408 AliDebug(1, Form("fStack->Particle(%d)->GetPdgCode() = %d", fLabelMC, part->GetPdgCode()));
1409
1410 if (part) {
1411 if (part->GetFirstMother() != -1) {
1412 TParticle *partMother = fStack->Particle(part->GetFirstMother());
1413 AliDebug(1, Form("fStack->Particle(%d) = %p", part->GetFirstMother(), partMother));
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 }
1421 Char_t newName[100];
1422 AliDebug(1, Form("fStack->Particle(%d)->GetPdgCode() = %d", fLabelMC, part->GetPdgCode()));
1423 AliDebug(1, Form("fStack->Particle(%d)->GetName() = %s", fLabelMC, part->GetName()));
1424 PDGNameConverter(part->GetName(), newName);
1425 history += Form("%s at z = %5.1f cm", newName, part->Vz());
1426 // printf("%s", history.Data());
1427 }
1428 else history += "NO AVAILABLE HISTORY";
1429
1430 fTxtMuonHistory = new TLatex(0.10, 0.86, history.Data());
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 }
1444
1445}
1446
1447//===========================================================================================================================================
1448
1449Bool_t AliMuonForwardTrackFinder::IsMother(const Char_t *nameMother) {
1450
1451 Bool_t result = kFALSE;
1452
1453 TParticle *part = 0;
1454 if (fLabelMC>=0) part = fStack->Particle(fLabelMC);
1455
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 }
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
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");
1487
1488 fCircleExt[iPlane] -> Draw("same");
1489 fCircleInt[iPlane] -> Draw("same");
1490
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");
1495
1496 fTxtTrackChi2[iPlane] -> Draw("same");
1497
1498 }
1499
1500 fCanvas -> cd(1);
1501 fTxtMuonHistory -> Draw();
1502 fTxtDummy -> Draw("same");
1503 if (fMatchingMode==kRealMatching) fTxtTrackGoodClusters -> Draw("same");
1504 fTxtTrackFinalChi2 -> Draw("same");
1505 fTxtTrackMomentum -> Draw("same");
1506 if (fMatchingMode==kRealMatching) fTxtFinalCandidates -> Draw("same");
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
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("---------------------------------------------------------------------------------------------------------------");
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
1564 // fOutputTreeFile->cd();
1565 fOutputEventTree->Fill();
1566 AliDebug(1, Form("\nFilled Tree: nEvents = %d!!!!\n", Int_t(fOutputEventTree->GetEntries())));
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
1587 fOutputQAFile = new TFile(Form("MuonGlobalTracking.QA.run%d.root", fRun), "recreate");
1588 fOutputQAFile -> cd();
1589
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
1604 fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[iPlane] -> Write();
1605 fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[iPlane] -> Write();
1606
1607 }
1608
1609 fNtuFinalCandidates -> Write();
1610 fNtuFinalBestCandidates -> Write();
1611
1612 fOutputQAFile -> Close();
1613
1614}
1615
1616//===========================================================================================================================================
1617
1618void AliMuonForwardTrackFinder::PDGNameConverter(const Char_t *nameIn, Char_t *nameOut) {
1619
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);
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