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