]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MFT/AliMuonForwardTrackFinder.cxx
Added option to switch on/off Branson correction in the matching stage. Analysis...
[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();
513 track -> SetMUONTrack(fMuonTrackReco);
b03d16a3 514 if (fLabelMC>=0 && fStack->Particle(fLabelMC)) track->SetMCTrackRef(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
d4643a10 918 AliDebug(1, Form("After plane %02d: newTrack->GetNMFTClusters() = %d (fCurrentTrack->GetNMFTClusters() = %d)",
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
d4643a10 971 AliDebug(1, Form("After plane %02d: newTrack->GetNMFTClusters() = %d (fCurrentTrack->GetNMFTClusters() = %d)",
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
1398 AliDebug(1, Form("fStack->Particle(fLabelMC) = %p", part));
1399
1400 if (part) {
1401 if (part->GetFirstMother() != -1) {
1402 TParticle *partMother = fStack->Particle(part->GetFirstMother());
1403 AliDebug(1, Form("fStack->Particle(part->GetFirstMother() = %p", partMother));
1404 if (partMother) {
1405 Char_t newName[100];
1406 if (partMother->GetFirstMother() != -1) history += "... #rightarrow ";
1407 PDGNameConverter(partMother->GetName(), newName);
1408 history += Form("%s #rightarrow ", newName);
1409 }
1410 }
820b4d9e 1411 Char_t newName[100];
d4643a10 1412 PDGNameConverter(part->GetName(), newName);
1413 history += Form("%s at z = %5.1f cm", newName, part->Vz());
1414 // printf("%s", history.Data());
820b4d9e 1415 }
d4643a10 1416 else history += "NO AVAILABLE HISTORY";
1417
820b4d9e 1418 fTxtMuonHistory = new TLatex(0.10, 0.86, history.Data());
d4643a10 1419
1420 // Filling particle history in the fFinalBestCandidate
1421
1422 if (part) {
1423 for (Int_t iParent=0; iParent<AliMuonForwardTrack::fgkNParentsMax; iParent++) {
1424 if (part->GetFirstMother() == -1) break;
1425 if (!(fStack->Particle(part->GetFirstMother()))) break;
1426 AliDebug(1, Form("fStack->Particle(part->GetFirstMother() = %p", fStack->Particle(part->GetFirstMother())));
1427 fFinalBestCandidate->SetParentMCLabel(iParent, part->GetFirstMother());
1428 fFinalBestCandidate->SetParentPDGCode(iParent, fStack->Particle(part->GetFirstMother())->GetPdgCode());
1429 part = fStack->Particle(part->GetFirstMother());
1430 }
1431 }
820b4d9e 1432
1433}
1434
1435//===========================================================================================================================================
1436
df4bbbc3 1437Bool_t AliMuonForwardTrackFinder::IsMother(const Char_t *nameMother) {
820b4d9e 1438
1439 Bool_t result = kFALSE;
1440
d4643a10 1441 TParticle *part = 0;
1442 if (fLabelMC>=0) part = fStack->Particle(fLabelMC);
820b4d9e 1443
d4643a10 1444 if (part) {
1445 if (part->GetFirstMother() != -1) {
1446 TParticle *partMother = fStack->Particle(part->GetFirstMother());
1447 if (partMother) {
1448 if (!strcmp(partMother->GetName(), nameMother)) result=kTRUE;
1449 }
1450 }
820b4d9e 1451 }
1452
1453 return result;
1454
1455}
1456
1457//===========================================================================================================================================
1458
1459void AliMuonForwardTrackFinder::DrawPlanes() {
1460
1461 fCanvas -> Clear();
1462 if (fNPlanesMFT <= 5) fCanvas -> Divide(3,2);
1463 else if (fNPlanesMFT <= 11) fCanvas -> Divide(4,3);
1464 else if (fNPlanesMFT <= 19) fCanvas -> Divide(5,4);
1465
1466 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
1467
1468 fCanvas->cd(fNPlanesMFT-iPlane+1);
1469
d4643a10 1470 fGrMFTPlane[kClusterOfTrack][iPlane] -> GetXaxis() -> SetLimits(-1.1*fRPlaneMax[fNPlanesMFT-1], +1.1*fRPlaneMax[fNPlanesMFT-1]);
1471 fGrMFTPlane[kClusterOfTrack][iPlane] -> GetYaxis() -> SetRangeUser(-1.1*fRPlaneMax[fNPlanesMFT-1], +1.1*fRPlaneMax[fNPlanesMFT-1]);
1472 fGrMFTPlane[kClusterOfTrack][iPlane] -> GetXaxis() -> SetTitle("X [cm]");
1473 fGrMFTPlane[kClusterOfTrack][iPlane] -> GetYaxis() -> SetTitle("Y [cm]");
1474 fGrMFTPlane[kClusterOfTrack][iPlane] -> Draw("ap");
820b4d9e 1475
1476 fCircleExt[iPlane] -> Draw("same");
1477 fCircleInt[iPlane] -> Draw("same");
1478
d4643a10 1479 if (fGrMFTPlane[kAllClusters][iPlane]->GetN()) fGrMFTPlane[kAllClusters][iPlane] -> Draw("psame");
1480 if (fGrMFTPlane[kClustersGoodChi2][iPlane]->GetN()) fGrMFTPlane[kClustersGoodChi2][iPlane] -> Draw("psame");
1481 if (fGrMFTPlane[kClusterOfTrack][iPlane]->GetN()) fGrMFTPlane[kClusterOfTrack][iPlane] -> Draw("psame");
1482 if (fGrMFTPlane[kClusterCorrectMC][iPlane]->GetN()) fGrMFTPlane[kClusterCorrectMC][iPlane] -> Draw("psame");
820b4d9e 1483
1484 fTxtTrackChi2[iPlane] -> Draw("same");
1485
1486 }
1487
1488 fCanvas -> cd(1);
1489 fTxtMuonHistory -> Draw();
1490 fTxtDummy -> Draw("same");
d4643a10 1491 if (fMatchingMode==kRealMatching) fTxtTrackGoodClusters -> Draw("same");
820b4d9e 1492 fTxtTrackFinalChi2 -> Draw("same");
d4643a10 1493 fTxtTrackMomentum -> Draw("same");
1494 if (fMatchingMode==kRealMatching) fTxtFinalCandidates -> Draw("same");
820b4d9e 1495
1496 fMrkAllClust -> Draw("same");
1497 fMrkClustGoodChi2 -> Draw("same");
1498 fMrkClustMC -> Draw("same");
1499 fMrkClustOfTrack -> Draw("same");
1500
1501 fTxtAllClust -> Draw("same");
1502 fTxtClustGoodChi2 -> Draw("same");
1503 fTxtClustMC -> Draw("same");
1504 fTxtClustOfTrack -> Draw("same");
1505
1506 // fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.eps", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
1507 fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.gif", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
1508 if (IsMother("phi")) {
1509 fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.phi.gif", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
1510 fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.phi.eps", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
1511 }
1512 if (IsMother("J/psi")) {
1513 fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.jPsi.gif", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
1514 fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.jPsi.eps", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
1515 }
1516
1517}
1518
1519//===========================================================================================================================================
1520
1521void AliMuonForwardTrackFinder::Terminate() {
1522
d4643a10 1523 AliInfo("");
1524 AliInfo("---------------------------------------------------------------------------------------------------------------");
1525 AliInfo(Form("%8d tracks analyzed", fCountRealTracksAnalyzed));
1526 AliInfo(Form("%8d tracks with MC ref", fCountRealTracksWithRefMC));
1527 AliInfo(Form("%8d tracks with MC ref & trigger match", fCountRealTracksWithRefMC_andTrigger));
1528 if (fMatchingMode==kRealMatching) {
1529 AliInfo(Form("%8d tracks analyzed with final candidates", fCountRealTracksAnalyzedWithFinalCandidates));
1530 }
1531 else {
1532 AliInfo(Form("%8d tracks matched with their MC clusters", fCountRealTracksAnalyzedWithFinalCandidates));
1533 }
1534// printf("%8d tracks with MC ref & trigger match & pt>%3.1f GeV/c", fCountRealTracksWithRefMC_andTrigger_andGoodPt, fLowPtCut);
1535// printf("%8d tracks with MC ref & trigger match & pt>%3.1f GeV/c & correct R_abs", fCountRealTracksWithRefMC_andTrigger_andGoodPt_andGoodTheta, fLowPtCut);
1536 AliInfo("---------------------------------------------------------------------------------------------------------------");
820b4d9e 1537
1538 WriteOutputTree();
1539 WriteHistos();
1540
1541}
1542
1543//==========================================================================================================================================
1544
1545void AliMuonForwardTrackFinder::FillOutputTree() {
1546
1547 if (!fMuonForwardTracks || !fOutputEventTree) return;
1548
1549 AliDebug(1, Form("Filling output tree %p with %p having %d entries whose 1st entry is %p",
1550 fOutputEventTree, fMuonForwardTracks, fMuonForwardTracks->GetEntries(), fMuonForwardTracks->At(0)));
1551
d4643a10 1552 // fOutputTreeFile->cd();
820b4d9e 1553 fOutputEventTree->Fill();
d4643a10 1554 AliDebug(1, Form("\nFilled Tree: nEvents = %d!!!!\n", Int_t(fOutputEventTree->GetEntries())));
820b4d9e 1555
1556}
1557
1558//==========================================================================================================================================
1559
1560void AliMuonForwardTrackFinder::WriteOutputTree() {
1561
1562 if (!fOutputEventTree || !fOutputTreeFile) return;
1563
1564 fOutputTreeFile -> cd();
1565
1566 fOutputEventTree -> Write();
1567 fOutputTreeFile -> Close();
1568
1569}
1570
1571//==========================================================================================================================================
1572
1573void AliMuonForwardTrackFinder::WriteHistos() {
1574
d4643a10 1575 fOutputQAFile = new TFile(Form("MuonGlobalTracking.QA.run%d.root", fRun), "recreate");
1576 fOutputQAFile -> cd();
820b4d9e 1577
820b4d9e 1578 fHistRadiusEndOfAbsorber -> Write();
1579 fHistNGoodClustersForFinalTracks -> Write();
1580
1581 fHistDistanceGoodClusterFromTrackAtLastPlane -> Write();
1582 fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane -> Write();
1583
1584 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
1585
1586 fHistNTracksAfterExtrapolation[iPlane] -> Write();
1587 fHistResearchRadius[iPlane] -> Write();
1588
1589 fHistChi2Cluster_GoodCluster[iPlane] -> Write();
1590 fHistChi2Cluster_BadCluster[iPlane] -> Write();
1591
d4643a10 1592 fHistGlobalChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[iPlane] -> Write();
1593 fHistGlobalChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[iPlane] -> Write();
820b4d9e 1594
1595 }
1596
d4643a10 1597 fNtuFinalCandidates -> Write();
1598 fNtuFinalBestCandidates -> Write();
820b4d9e 1599
d4643a10 1600 fOutputQAFile -> Close();
820b4d9e 1601
1602}
1603
1604//===========================================================================================================================================
1605
1606void AliMuonForwardTrackFinder::PDGNameConverter(const Char_t *nameIn, Char_t *nameOut) {
1607
d6080682 1608 if (!strcmp(nameIn, "mu+")) snprintf(nameOut, 50, "#mu^{+}");
1609 else if (!strcmp(nameIn, "mu-")) snprintf(nameOut, 50, "#mu^{-}");
1610 else if (!strcmp(nameIn, "pi+")) snprintf(nameOut, 50, "#pi^{+}");
1611 else if (!strcmp(nameIn, "pi-")) snprintf(nameOut, 50, "#pi^{-}");
1612 else if (!strcmp(nameIn, "K+")) snprintf(nameOut, 50, "K^{+}");
1613 else if (!strcmp(nameIn, "K-")) snprintf(nameOut, 50, "K^{-}");
1614 else if (!strcmp(nameIn, "K*+")) snprintf(nameOut, 50, "K^{*+}");
1615 else if (!strcmp(nameIn, "K*-")) snprintf(nameOut, 50, "K^{*-}");
1616 else if (!strcmp(nameIn, "K_S0")) snprintf(nameOut, 50, "K_{S}^{0}");
1617 else if (!strcmp(nameIn, "K_L0")) snprintf(nameOut, 50, "K_{L}^{0}");
1618 else if (!strcmp(nameIn, "K0")) snprintf(nameOut, 50, "K^{0}");
1619 else if (!strcmp(nameIn, "K0_bar")) snprintf(nameOut, 50, "#bar{K}^{0}");
1620 else if (!strcmp(nameIn, "K*0")) snprintf(nameOut, 50, "K^{*0}");
1621 else if (!strcmp(nameIn, "K*0_bar")) snprintf(nameOut, 50, "#bar{K}^{*0}");
1622 else if (!strcmp(nameIn, "rho0")) snprintf(nameOut, 50, "#rho^{0}");
1623 else if (!strcmp(nameIn, "rho+")) snprintf(nameOut, 50, "#rho^{+}");
1624 else if (!strcmp(nameIn, "rho-")) snprintf(nameOut, 50, "#rho^{-}");
1625 else if (!strcmp(nameIn, "omega")) snprintf(nameOut, 50, "#omega");
1626 else if (!strcmp(nameIn, "eta'")) snprintf(nameOut, 50, "#eta'");
1627 else if (!strcmp(nameIn, "phi")) snprintf(nameOut, 50, "#phi");
1628
1629 else if (!strcmp(nameIn, "D-")) snprintf(nameOut, 50, "D^{-}");
1630 else if (!strcmp(nameIn, "D+")) snprintf(nameOut, 50, "D^{+}");
1631 else if (!strcmp(nameIn, "D0")) snprintf(nameOut, 50, "D^{0}");
1632 else if (!strcmp(nameIn, "D0_bar")) snprintf(nameOut, 50, "#bar{D}^{0}");
1633 else if (!strcmp(nameIn, "D*-")) snprintf(nameOut, 50, "D^{*-}");
1634 else if (!strcmp(nameIn, "D*+")) snprintf(nameOut, 50, "D^{*+}");
1635 else if (!strcmp(nameIn, "D_s+")) snprintf(nameOut, 50, "D_{s}^{+}");
1636 else if (!strcmp(nameIn, "D*_s+")) snprintf(nameOut, 50, "D_{s}^{*+}");
1637
1638 else if (!strcmp(nameIn, "B-")) snprintf(nameOut, 50, "B^{-}");
1639 else if (!strcmp(nameIn, "B+")) snprintf(nameOut, 50, "B^{+}");
1640 else if (!strcmp(nameIn, "B_s0_bar")) snprintf(nameOut, 50, "#bar{B}_{s}^{0}");
1641
1642 else if (!strcmp(nameIn, "antiproton")) snprintf(nameOut, 50, "#bar{p}");
1643 else if (!strcmp(nameIn, "proton")) snprintf(nameOut, 50, "p");
1644 else if (!strcmp(nameIn, "neutron")) snprintf(nameOut, 50, "n");
1645 else if (!strcmp(nameIn, "Sigma+")) snprintf(nameOut, 50, "#Sigma^{+}");
1646 else if (!strcmp(nameIn, "Delta+")) snprintf(nameOut, 50, "#Delta{+}");
1647 else if (!strcmp(nameIn, "Delta--")) snprintf(nameOut, 50, "#Delta{--}");
1648 else if (!strcmp(nameIn, "Lambda0")) snprintf(nameOut, 50, "#Lambda_0");
1649 else if (!strcmp(nameIn, "Lambda0_bar")) snprintf(nameOut, 50, "#bar{Lambda}_0");
1650
1651 else snprintf(nameOut, 50, "%s", nameIn);
820b4d9e 1652
1653}
1654
1655//===========================================================================================================================================
1656
1657void AliMuonForwardTrackFinder::SetDraw(Bool_t drawOption) {
1658
1659 fDrawOption = drawOption;
1660
1661 if (!fCanvas) {
1662 fCanvas = new TCanvas("tracking", "tracking", 1200, 800);
1663 fCanvas -> Divide(3,2);
1664 }
1665
1666}
1667
1668//===========================================================================================================================================
1669
1670Bool_t AliMuonForwardTrackFinder::InitGRP() {
1671
1672 //------------------------------------
1673 // Initialization of the GRP entry
1674 //------------------------------------
1675
1676 AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/GRP/Data");
1677
1678 if (entry) {
1679
1680 TMap* m = dynamic_cast<TMap*>(entry->GetObject()); // old GRP entry
1681
1682 if (m) {
1683 AliInfo("Found a TMap in GRP/GRP/Data, converting it into an AliGRPObject");
1684 m->Print();
1685 fGRPData = new AliGRPObject();
1686 fGRPData->ReadValuesFromMap(m);
1687 }
1688
1689 else {
1690 AliInfo("Found an AliGRPObject in GRP/GRP/Data, reading it");
1691 fGRPData = dynamic_cast<AliGRPObject*>(entry->GetObject()); // new GRP entry
1692 entry->SetOwner(0);
1693 }
1694
1695 // FIX ME: The unloading of GRP entry is temporarily disabled
1696 // because ZDC and VZERO are using it in order to initialize
1697 // their reconstructor objects. In the future one has to think
1698 // of propagating AliRunInfo to the reconstructors.
1699 // AliCDBManager::Instance()->UnloadFromCache("GRP/GRP/Data");
1700 }
1701
1702 if (!fGRPData) {
1703 AliError("No GRP entry found in OCDB!");
1704 return kFALSE;
1705 }
1706
1707 TString lhcState = fGRPData->GetLHCState();
1708 if (lhcState==AliGRPObject::GetInvalidString()) {
1709 AliError("GRP/GRP/Data entry: missing value for the LHC state ! Using UNKNOWN");
1710 lhcState = "UNKNOWN";
1711 }
1712
1713 TString beamType = fGRPData->GetBeamType();
1714 if (beamType==AliGRPObject::GetInvalidString()) {
1715 AliError("GRP/GRP/Data entry: missing value for the beam type ! Using UNKNOWN");
1716 beamType = "UNKNOWN";
1717 }
1718
1719 Float_t beamEnergy = fGRPData->GetBeamEnergy();
1720 if (beamEnergy==AliGRPObject::GetInvalidFloat()) {
1721 AliError("GRP/GRP/Data entry: missing value for the beam energy ! Using 0");
1722 beamEnergy = 0;
1723 }
1724
1725 TString runType = fGRPData->GetRunType();
1726 if (runType==AliGRPObject::GetInvalidString()) {
1727 AliError("GRP/GRP/Data entry: missing value for the run type ! Using UNKNOWN");
1728 runType = "UNKNOWN";
1729 }
1730
1731 Int_t activeDetectors = fGRPData->GetDetectorMask();
1732 if (activeDetectors==AliGRPObject::GetInvalidUInt()) {
1733 AliError("GRP/GRP/Data entry: missing value for the detector mask ! Using 1074790399");
1734 activeDetectors = 1074790399;
1735 }
1736 AliDebug(1, Form("activeDetectors = %d", activeDetectors));
1737
1738 fRunInfo = new AliRunInfo(lhcState, beamType, beamEnergy, runType, activeDetectors);
1739 fRunInfo->Dump();
1740
1741 // *** Dealing with the magnetic field map
1742
1743 if ( TGeoGlobalMagField::Instance()->IsLocked() ) {
1744 if (TGeoGlobalMagField::Instance()->GetField()->TestBit(AliMagF::kOverrideGRP)) {
1745 AliInfo("ExpertMode!!! GRP information will be ignored !");
1746 AliInfo("ExpertMode!!! Running with the externally locked B field !");
1747 }
1748 else {
1749 AliInfo("Destroying existing B field instance!");
1750 delete TGeoGlobalMagField::Instance();
1751 }
1752 }
1753 if ( !TGeoGlobalMagField::Instance()->IsLocked() ) {
1754 // Construct the field map out of the information retrieved from GRP.
1755 Bool_t ok = kTRUE;
1756 // L3
1757 Float_t l3Current = fGRPData->GetL3Current((AliGRPObject::Stats)0);
1758 if (l3Current == AliGRPObject::GetInvalidFloat()) {
1759 AliError("GRP/GRP/Data entry: missing value for the L3 current !");
1760 ok = kFALSE;
1761 }
1762
1763 Char_t l3Polarity = fGRPData->GetL3Polarity();
1764 if (l3Polarity == AliGRPObject::GetInvalidChar()) {
1765 AliError("GRP/GRP/Data entry: missing value for the L3 polarity !");
1766 ok = kFALSE;
1767 }
1768
1769 // Dipole
1770 Float_t diCurrent = fGRPData->GetDipoleCurrent((AliGRPObject::Stats)0);
1771 if (diCurrent == AliGRPObject::GetInvalidFloat()) {
1772 AliError("GRP/GRP/Data entry: missing value for the dipole current !");
1773 ok = kFALSE;
1774 }
1775
1776 Char_t diPolarity = fGRPData->GetDipolePolarity();
1777 if (diPolarity == AliGRPObject::GetInvalidChar()) {
1778 AliError("GRP/GRP/Data entry: missing value for the dipole polarity !");
1779 ok = kFALSE;
1780 }
1781
1782 // read special bits for the polarity convention and map type
1783 Int_t polConvention = fGRPData->IsPolarityConventionLHC() ? AliMagF::kConvLHC : AliMagF::kConvDCS2008;
1784 Bool_t uniformB = fGRPData->IsUniformBMap();
1785
1786 if (ok) {
1787 AliMagF* fld = AliMagF::CreateFieldMap(TMath::Abs(l3Current) * (l3Polarity ? -1:1),
1788 TMath::Abs(diCurrent) * (diPolarity ? -1:1),
1789 polConvention,uniformB,beamEnergy, beamType.Data());
1790 if (fld) {
1791 TGeoGlobalMagField::Instance()->SetField( fld );
1792 TGeoGlobalMagField::Instance()->Lock();
1793 AliInfo("Running with the B field constructed out of GRP !");
1794 }
1795 else AliFatal("Failed to create a B field map !");
1796 }
1797 else AliFatal("B field is neither set nor constructed from GRP ! Exitig...");
1798 }
1799
1800 return kTRUE;
1801}
1802
1803//====================================================================================================================================================
1804
1805Bool_t AliMuonForwardTrackFinder::SetRunNumber() {
1806
1807 AliCDBManager *man = AliCDBManager::Instance();
1808
1809 if (!fRunLoader) {
1810 AliError("No run loader found!");
1811 return kFALSE;
1812 }
1813 else {
1814 fRunLoader->LoadHeader();
1815 // read run number from gAlice
1816 if (fRunLoader->GetHeader()) {
1817 man->SetRun(fRunLoader->GetHeader()->GetRun());
1818 fRunLoader->UnloadHeader();
1819 }
1820 else {
1821 AliError("No run-loader header found!");
1822 return kFALSE;
1823 }
1824 }
1825
1826 return kTRUE;
1827
1828}
1829
1830//====================================================================================================================================================
1831