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