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