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