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