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