coverity fix
[u/mrichter/AliRoot.git] / MFT / AliMFTTrackerMU.cxx
CommitLineData
4cc511f4
AU
1/**************************************************************************
2* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3* *
4* Author: The ALICE Off-line Project. *
5* Contributors are mentioned in the code where appropriate. *
6* *
7* Permission to use, copy, modify and distribute this software and its *
8* documentation strictly for non-commercial purposes is hereby granted *
9* without fee, provided that the above copyright notice appears in all *
10* copies and that both the copyright notice and this permission notice *
11* appear in the supporting documentation. The authors make no claims *
12* about the suitability of this software for any purpose. It is *
13* provided "as is" without express or implied warranty. *
14**************************************************************************/
15
16//====================================================================================================================================================
17//
18// MFT tracker
19//
20// Class for the creation of the "global muon tracks" built from the tracks reconstructed in the
21// muon spectrometer and the clusters of the Muon Forward Tracker
22//
23// Contact author: antonio.uras@cern.ch
24//
25//====================================================================================================================================================
26
27#include "TTree.h"
28#include "AliLog.h"
29#include "AliGeomManager.h"
30#include "AliESDEvent.h"
31#include "AliESDMuonTrack.h"
026547c6 32#include "AliESDMuonGlobalTrack.h"
4cc511f4
AU
33#include "AliMFTTrackerMU.h"
34#include "TMath.h"
35#include "AliRun.h"
36#include "AliMFT.h"
37#include "AliMUONTrackExtrap.h"
38#include "AliMUONTrack.h"
39#include "AliMUONESDInterface.h"
40#include "AliMuonForwardTrack.h"
026547c6 41#include "AliMUONConstants.h"
4cc511f4
AU
42
43ClassImp(AliMFTTrackerMU)
44
45const Double_t AliMFTTrackerMU::fRadLengthSi = AliMFTConstants::fRadLengthSi;
46
47//====================================================================================================================================================
48
49AliMFTTrackerMU::AliMFTTrackerMU() :
50 AliTracker(),
51 fESD(0),
52 fMFT(0),
53 fSegmentation(0),
54 fNPlanesMFT(0),
55 fNPlanesMFTAnalyzed(0),
e21f8bf5 56 fSigmaClusterCut(2),
4cc511f4
AU
57 fScaleSigmaClusterCut(1.),
58 fNMaxMissingMFTClusters(0),
59 fGlobalTrackingDiverged(kFALSE),
60 fCandidateTracks(0),
61 fMUONTrack(0),
62 fCurrentTrack(0),
63 fFinalBestCandidate(0),
64 fVertexErrorX(0.015),
65 fVertexErrorY(0.015),
66 fVertexErrorZ(0.010),
67 fBransonCorrection(kFALSE)
68{
69
70 //--------------------------------------------------------------------
71 // This is the AliMFTTrackerMU constructor
72 //--------------------------------------------------------------------
73
74 fMFT = (AliMFT*) gAlice->GetDetector("MFT");
75 fSegmentation = fMFT->GetSegmentation();
76 SetNPlanesMFT(fSegmentation->GetNPlanes());
77 AliMUONTrackExtrap::SetField(); // set the magnetic field for track extrapolations
78
e21f8bf5 79 AliInfo(Form("fMFT = %p, fSegmentation = %p", fMFT, fSegmentation));
80
4cc511f4 81 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
e21f8bf5 82 fMFTClusterArray[iPlane] = new TClonesArray("AliMFTCluster");
4cc511f4
AU
83 fMFTClusterArrayFront[iPlane] = new TClonesArray("AliMFTCluster");
84 fMFTClusterArrayBack[iPlane] = new TClonesArray("AliMFTCluster");
e21f8bf5 85 fMFTClusterArray[iPlane] -> SetOwner(kTRUE);
86 fMFTClusterArrayFront[iPlane] -> SetOwner(kTRUE);
87 fMFTClusterArrayBack[iPlane] -> SetOwner(kTRUE);
88 fMinResearchRadiusAtPlane[iPlane] = 0.;
4cc511f4
AU
89 }
90
e21f8bf5 91 fCandidateTracks = new TClonesArray("AliMuonForwardTrack",50000);
92
4cc511f4
AU
93}
94
95//====================================================================================================================================================
96
97AliMFTTrackerMU::~AliMFTTrackerMU() {
98
99 // destructor
100
101 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
e21f8bf5 102 fMFTClusterArray[iPlane] -> Delete();
4cc511f4
AU
103 delete fMFTClusterArray[iPlane];
104 delete fMFTClusterArrayFront[iPlane];
105 delete fMFTClusterArrayBack[iPlane];
106 }
107
e21f8bf5 108 delete fCandidateTracks;
109
4cc511f4
AU
110}
111
112//====================================================================================================================================================
113
114Int_t AliMFTTrackerMU::LoadClusters(TTree *cTree) {
115
116 //--------------------------------------------------------------------
117 // This function loads the MFT clusters
118 //--------------------------------------------------------------------
119
e21f8bf5 120 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
121 AliDebug(1, Form("Setting Address for Branch Plane_%02d", iPlane));
122 cTree->SetBranchAddress(Form("Plane_%02d",iPlane), &fMFTClusterArray[iPlane]);
123 }
124
4cc511f4
AU
125 if (!cTree->GetEvent()) return kFALSE;
126 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
e21f8bf5 127 AliInfo(Form("plane %02d: nClusters = %d\n", iPlane, fMFTClusterArray[iPlane]->GetEntries()));
4cc511f4
AU
128 }
129 SeparateFrontBackClusters();
130
131 return 0;
132
133}
134
135//====================================================================================================================================================
136
137void AliMFTTrackerMU::UnloadClusters() {
138
e21f8bf5 139// //--------------------------------------------------------------------
140// // This function unloads MFT clusters
141// //--------------------------------------------------------------------
4cc511f4
AU
142
143 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
144 fMFTClusterArray[iPlane] -> Clear("C");
145 fMFTClusterArrayFront[iPlane] -> Clear("C");
146 fMFTClusterArrayBack[iPlane] -> Clear("C");
147 }
148
149}
150
151//====================================================================================================================================================
152
153Int_t AliMFTTrackerMU::Clusters2Tracks(AliESDEvent *event) {
154
155 //--------------------------------------------------------------------
156 // This functions reconstructs the Muon Forward Tracks
157 // The clusters must be already loaded !
158 //--------------------------------------------------------------------
159
e21f8bf5 160 // Tree of AliMuonForwardTrack objects. Created outside the ESD framework for cross-check purposes
161
162 TFile *outputFileMuonGlobalTracks = new TFile("MuonGlobalTracks.root", "update");
4cc511f4
AU
163 TTree *outputTreeMuonGlobalTracks = new TTree("AliMuonForwardTracks", "Tree of AliMuonForwardTracks");
164 TClonesArray *muonForwardTracks = new TClonesArray("AliMuonForwardTrack");
165 outputTreeMuonGlobalTracks -> Branch("tracks", &muonForwardTracks);
166
167 //--------------------------------------------------------------------
168
169 fESD = event;
170
e21f8bf5 171 // get the ITS primary vertex
172
173 Double_t vertex[3] = {0., 0., 0.};
174 const AliESDVertex* esdVert = fESD->GetVertex();
175 if (esdVert->GetNContributors() > 0 || !strcmp(esdVert->GetTitle(),"vertexer: smearMC")) {
176 esdVert->GetXYZ(vertex);
177 AliDebug(1,Form("found vertex (%e,%e,%e)",vertex[0],vertex[1],vertex[2]));
178 }
179
4cc511f4
AU
180 //----------- Read ESD MUON tracks -------------------
181
182 Int_t nTracksMUON = event->GetNumberOfMuonTracks();
183
184 AliInfo(Form("Number of ESD MUON tracks: %d\n", nTracksMUON));
185
186 Int_t iTrack=0;
187 while (iTrack<nTracksMUON) {
188
189 fNPlanesMFTAnalyzed = 0;
190
e21f8bf5 191 AliInfo("****************************************************************************************");
192 AliInfo(Form("*************************** MUON TRACK %3d/%d ***************************************", iTrack, nTracksMUON));
193 AliInfo("****************************************************************************************");
4cc511f4
AU
194
195 fCandidateTracks -> Delete();
196
197 fNPlanesMFTAnalyzed = 0;
198
199 const AliESDMuonTrack *esdTrack = event->GetMuonTrack(iTrack);
e21f8bf5 200 if (fMUONTrack) delete fMUONTrack;
201 fMUONTrack = new AliMUONTrack();
202
f7cc8591 203 AliMUONESDInterface::ESDToMUON(*esdTrack, *fMUONTrack, kFALSE);
204
205 if (!fMUONTrack->GetTrackParamAtCluster()->First()) {
206 AliInfo("Skipping track, no parameters available!!!");
207 iTrack++;
208 continue;
209 }
4cc511f4
AU
210
211 // the track we are going to build, starting from fMUONTrack and adding the MFT clusters
212 AliMuonForwardTrack *track = new ((*fCandidateTracks)[0]) AliMuonForwardTrack();
213 track -> SetMUONTrack(new AliMUONTrack(*fMUONTrack));
214 track -> SetMCLabel(fMUONTrack->GetMCLabel());
215 track -> SetMatchTrigger(fMUONTrack->GetMatchTrigger());
216
026547c6 217 // track parameters linearly extrapolated from the first tracking station to the end of the absorber
218 AliMUONTrackParam trackParamEndOfAbsorber(*((AliMUONTrackParam*)(fMUONTrack->GetTrackParamAtCluster()->First())));
219 AliMUONTrackExtrap::ExtrapToZCov(&trackParamEndOfAbsorber, AliMUONConstants::AbsZEnd()); // absorber extends from -90 to -503 cm
220 Double_t xEndOfAbsorber = trackParamEndOfAbsorber.GetNonBendingCoor();
221 Double_t yEndOfAbsorber = trackParamEndOfAbsorber.GetBendingCoor();
222 Double_t rAbsorber = TMath::Sqrt(xEndOfAbsorber*xEndOfAbsorber + yEndOfAbsorber*yEndOfAbsorber);
223 track -> SetRAtAbsorberEnd(rAbsorber);
224
4cc511f4
AU
225 //------------------------- NOW THE CYCLE OVER THE MFT PLANES STARTS ---------------------------------------
226
227 for (Int_t iPlane=fNPlanesMFT-1; iPlane>=0; iPlane--) { /* *** do not reverse the order of this cycle!!!
228 *** this reflects the fact that the extrapolation is performed
229 *** starting from the last MFT plane back to the origin */
230
231 // --------- updating the array of candidates according to the clusters available in the i-th plane ---------
232
233 fNPlanesMFTAnalyzed++;
234
235 Int_t nCandidates = fCandidateTracks->GetEntriesFast();
236 for (Int_t iCandidate=0; iCandidate<nCandidates; iCandidate++) {
237 fCurrentTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(iCandidate);
e21f8bf5 238
4cc511f4
AU
239 // if the old track is compatible with the new cluster, the track is updated and inserted as new track in the array
240 // (several new tracks can be created for one old track)
241 if (FindClusterInPlane(iPlane) == kDiverged) {
242 fGlobalTrackingDiverged = kTRUE;
243 break;
244 }
245
246 if ((fNPlanesMFTAnalyzed-fCurrentTrack->GetNMFTClusters())>fNMaxMissingMFTClusters || fIsPlaneMandatory[iPlane]) {
247 fCandidateTracks->Remove(fCurrentTrack); // the old track is removed after the check;
248 }
249 }
250 if (fGlobalTrackingDiverged) {
251 if (fScaleSigmaClusterCut>0) fScaleSigmaClusterCut -= 0.1;
252 continue;
253 }
254
255 fCandidateTracks->Compress();
256
257 }
e21f8bf5 258
4cc511f4
AU
259 // -------------------------- END OF THE CYCLE OVER THE MFT PLANES --------------------------------------------
260
261 fGlobalTrackingDiverged = kFALSE;
262 fScaleSigmaClusterCut = 1.0;
263
264 AliDebug(1, "Finished cycle over planes");
265
266 iTrack++;
267
268 // If we have several final tracks, we must find the best candidate:
269
270 Int_t nFinalTracks = fCandidateTracks->GetEntriesFast();
e21f8bf5 271 AliInfo(Form("nFinalTracks = %d", nFinalTracks));
272
4cc511f4
AU
273 Int_t nGoodClustersBestCandidate = 0;
274 Int_t idBestCandidate = 0;
275 Double_t bestChi2 = -1.; // variable defining the best candidate
276
277 for (Int_t iFinalCandidate=0; iFinalCandidate<nFinalTracks; iFinalCandidate++) {
278
279 AliMuonForwardTrack *finalTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(iFinalCandidate);
280 Int_t nMFTClusters = finalTrack->GetNMFTClusters();
281
282 Double_t chi2 = 0;
283 for (Int_t iCluster=0; iCluster<nMFTClusters; iCluster++) {
284 AliMFTCluster *localCluster = finalTrack->GetMFTCluster(iCluster);
285 chi2 += localCluster->GetLocalChi2();
286 }
287 chi2 /= nMFTClusters;
288
289 // now comparing the tracks in order to find the best one
290
291 if (chi2<bestChi2 || bestChi2<0) {
292 bestChi2 = chi2;
293 idBestCandidate = iFinalCandidate;
294 }
295
296 }
297
298 if (nFinalTracks) {
299
300 AliMuonForwardTrack *newTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(idBestCandidate);
301 newTrack -> SetNWrongClustersMC(newTrack->GetNMFTClusters() - nGoodClustersBestCandidate);
302
e21f8bf5 303 new ((*muonForwardTracks)[muonForwardTracks->GetEntries()]) AliMuonForwardTrack(*newTrack);
4cc511f4 304
e21f8bf5 305 //----------------------- Save the information to the AliESDMuonGlobalTrack object
306
307 newTrack -> EvalKinem(vertex[2]); // we evaluate the kinematics at the primary vertex
308
309 AliDebug(2,"Creating a new Muon Global Track");
310 AliESDMuonGlobalTrack *myESDTrack = event->NewMuonGlobalTrack();
311 myESDTrack -> SetPxPyPz(newTrack->Px(), newTrack->Py(), newTrack->Pz());
026547c6 312
313// waiting for the commit of the new version of AliESDMuonGlobalTrack...
314
f7cc8591 315 myESDTrack -> SetLabel(newTrack->GetMCLabel());
316 myESDTrack -> SetChi2OverNdf(newTrack->GetChi2OverNdf());
317 myESDTrack -> SetCharge(newTrack->GetCharge());
318 myESDTrack -> SetMatchTrigger(newTrack->GetMatchTrigger());
319 myESDTrack -> SetNMFTClusters(newTrack->GetNMFTClusters());
320 myESDTrack -> SetNWrongMFTClustersMC(newTrack->GetNWrongClustersMC());
321 myESDTrack -> SetFirstTrackingPoint(newTrack->GetMFTCluster(0)->GetX(), newTrack->GetMFTCluster(0)->GetY(), newTrack->GetMFTCluster(0)->GetZ());
322 myESDTrack -> SetXYAtVertex(newTrack->GetOffsetX(vertex[0], vertex[2]), newTrack->GetOffsetX(vertex[1], vertex[2]));
323 myESDTrack -> SetRAtAbsorberEnd(newTrack->GetRAtAbsorberEnd());
324 myESDTrack -> SetChi2MatchTrigger(esdTrack->GetChi2MatchTrigger());
325 myESDTrack -> SetMuonClusterMap(esdTrack->GetMuonClusterMap());
326 myESDTrack -> SetHitsPatternInTrigCh(esdTrack->GetHitsPatternInTrigCh());
327 myESDTrack -> SetHitsPatternInTrigChTrk(esdTrack->GetHitsPatternInTrigChTrk());
328 myESDTrack -> Connected(esdTrack->IsConnected());
4cc511f4 329
e21f8bf5 330 //---------------------------------------------------------------------------------
4cc511f4
AU
331
332 }
333
4cc511f4
AU
334 fFinalBestCandidate = NULL;
335
336 }
337
e21f8bf5 338 outputTreeMuonGlobalTracks -> Fill();
339
4cc511f4 340 Int_t myEventID = 0;
4cc511f4
AU
341 while (outputFileMuonGlobalTracks->cd(Form("Event%d",myEventID))) myEventID++;
342 outputFileMuonGlobalTracks -> mkdir(Form("Event%d",myEventID));
343 outputFileMuonGlobalTracks -> cd(Form("Event%d",myEventID));
344 outputTreeMuonGlobalTracks -> Write();
345 outputFileMuonGlobalTracks -> Close();
346
e21f8bf5 347 muonForwardTracks -> Delete();
348 delete muonForwardTracks;
349
4cc511f4
AU
350 return 0;
351
352}
353
354//=========================================================================================================================================
355
356void AliMFTTrackerMU::SeparateFrontBackClusters() {
357
358 for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
359 fMFTClusterArrayFront[iPlane]->Delete();
360 fMFTClusterArrayBack[iPlane] ->Delete();
361 for (Int_t iCluster=0; iCluster<fMFTClusterArray[iPlane]->GetEntries(); iCluster++) {
362 AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArray[iPlane]->At(iCluster);
363 if (TMath::Abs(cluster->GetZ())<TMath::Abs(fSegmentation->GetPlane(iPlane)->GetZCenter())) {
364 new ((*fMFTClusterArrayFront[iPlane])[fMFTClusterArrayFront[iPlane]->GetEntries()]) AliMFTCluster(*cluster);
365 }
366 else {
367 new ((*fMFTClusterArrayBack[iPlane])[fMFTClusterArrayBack[iPlane]->GetEntries()]) AliMFTCluster(*cluster);
368 }
369 }
370 }
371
372}
373
374//==========================================================================================================================================
375
376Int_t AliMFTTrackerMU::FindClusterInPlane(Int_t planeId) {
377
4cc511f4
AU
378 // !!!!!!!!! coordinates and errors on the interaction vertex should be taken from the event itself (ITS) if available
379
380 // propagate track to plane #planeId (both to front and back active sensors)
381 // look for compatible clusters
382 // update TrackParam at found cluster (if any) using Kalman Filter
383
384 AliMUONTrackParam currentParamFront, currentParamBack, currentParamForResearchFront, currentParamForResearchBack;
385
386 if (planeId == fNPlanesMFT-1) { // last plane of the telecope
387 currentParamFront = (*((AliMUONTrackParam*)(fMUONTrack->GetTrackParamAtCluster()->First())));
388 currentParamBack = (*((AliMUONTrackParam*)(fMUONTrack->GetTrackParamAtCluster()->First())));
389 currentParamForResearchFront = currentParamFront;
390 currentParamForResearchBack = currentParamBack;
391 Double_t xExtrap = gRandom->Gaus(0,fVertexErrorX);
392 Double_t yExtrap = gRandom->Gaus(0,fVertexErrorY);
393 Double_t zExtrap = gRandom->Gaus(0,fVertexErrorZ);
394 if (fBransonCorrection) {
395 AliMUONTrackExtrap::ExtrapToVertex(&currentParamFront, xExtrap, yExtrap, zExtrap, fVertexErrorX, fVertexErrorY);
396 AliMUONTrackExtrap::ExtrapToVertex(&currentParamBack, xExtrap, yExtrap, zExtrap, fVertexErrorX, fVertexErrorY);
397 }
398 else {
399 AliMUONTrackExtrap::ExtrapToVertexWithoutBranson(&currentParamFront, zExtrap);
400 AliMUONTrackExtrap::ExtrapToVertexWithoutBranson(&currentParamBack, zExtrap);
401 }
402 AliMUONTrackExtrap::ExtrapToVertex(&currentParamForResearchFront, xExtrap, yExtrap, zExtrap, fVertexErrorX, fVertexErrorY);
403 AliMUONTrackExtrap::ExtrapToVertex(&currentParamForResearchBack, xExtrap, yExtrap, zExtrap, fVertexErrorX, fVertexErrorY);
404 }
405 else { // MFT planes others than the last one: mult. scattering correction because of the upstream MFT planes is performed
406 currentParamFront = (*((AliMUONTrackParam*)(fCurrentTrack->GetTrackParamAtCluster()->First())));
407 currentParamBack = (*((AliMUONTrackParam*)(fCurrentTrack->GetTrackParamAtCluster()->First())));
408 currentParamForResearchFront = currentParamFront;
409 currentParamForResearchBack = currentParamBack;
410 AliMUONTrackExtrap::AddMCSEffect(&currentParamFront, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
411 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeFront())/fRadLengthSi,-1.);
412 AliMUONTrackExtrap::AddMCSEffect(&currentParamForResearchFront,(fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
413 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeFront())/fRadLengthSi,-1.);
414 AliMUONTrackExtrap::AddMCSEffect(&currentParamBack, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
415 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeBack())/fRadLengthSi,-1.);
416 AliMUONTrackExtrap::AddMCSEffect(&currentParamForResearchBack, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
417 fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeBack())/fRadLengthSi,-1.);
418 }
419 // for all planes: extrapolation to the Z of the plane
420 AliMUONTrackExtrap::ExtrapToZCov(&currentParamFront, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveFront());
421 AliMUONTrackExtrap::ExtrapToZCov(&currentParamForResearchFront, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveFront());
422 AliMUONTrackExtrap::ExtrapToZCov(&currentParamBack, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveBack());
423 AliMUONTrackExtrap::ExtrapToZCov(&currentParamForResearchBack, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveBack());
424
425 //---------------------------------------------------------------------------------------
426
427 TMatrixD covFront(5,5); covFront = currentParamForResearchFront.GetCovariances();
428 TMatrixD covBack(5,5); covBack = currentParamForResearchBack.GetCovariances();
429
430 Double_t squaredError_X_Front = covFront(0,0);
431 Double_t squaredError_Y_Front = covFront(2,2);
432 Double_t squaredError_X_Back = covBack(0,0);
433 Double_t squaredError_Y_Back = covBack(2,2);
434
435 Double_t corrFact = 1.0;
436
437 Double_t researchRadiusFront = TMath::Sqrt(squaredError_X_Front + squaredError_Y_Front);
438 Double_t researchRadiusBack = TMath::Sqrt(squaredError_X_Back + squaredError_Y_Back);
439 if (0.5*(researchRadiusFront+researchRadiusBack)<fMinResearchRadiusAtPlane[planeId]) {
440 corrFact = fMinResearchRadiusAtPlane[planeId]/(0.5*(researchRadiusFront+researchRadiusBack));
441 }
442
443 //---------------------------------------------------------------------------------------
444
445 Double_t chi2cut = 2.*fScaleSigmaClusterCut*fScaleSigmaClusterCut*fSigmaClusterCut*fSigmaClusterCut; // depends on the number of variables (here, 2)
446
447 // Analyizing the clusters: FRONT ACTIVE ELEMENTS
448
449 Int_t nClustersFront = fMFTClusterArrayFront[planeId]->GetEntries();
450 AliDebug(2, Form("There are %3d clusters in plane %02d FRONT\n", nClustersFront, planeId));
451
452 for (Int_t iCluster=0; iCluster<nClustersFront; iCluster++) {
453
454 Bool_t isGoodChi2 = kFALSE;
455
456 AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArrayFront[planeId]->At(iCluster);
457 Double_t chi2 = (1./(corrFact*corrFact)) * TryOneCluster(currentParamForResearchFront, cluster); // describes the compatibility between the track and the cluster
458 if (chi2<chi2cut) isGoodChi2 = kTRUE;
459
460 if (isGoodChi2) {
461 AliDebug(3, Form("accepting cluster: chi2=%f (cut = %f)\n", chi2, chi2cut));
462 AliMuonForwardTrack *newTrack = new ((*fCandidateTracks)[fCandidateTracks->GetEntriesFast()]) AliMuonForwardTrack(*fCurrentTrack);
463 if (fCandidateTracks->GetEntriesFast() > fMaxNCandidates) return kDiverged;
464 newTrack->AddTrackParamAtMFTCluster(currentParamFront, *cluster); // creating new track param and attaching the cluster
465 AliDebug(2, Form("After plane %02d: newTrack->GetNMFTClusters() = %d (fCurrentTrack->GetNMFTClusters() = %d)",
466 planeId, newTrack->GetNMFTClusters(), fCurrentTrack->GetNMFTClusters()));
467 newTrack->SetPlaneExists(planeId);
468 }
469 else AliDebug(3, Form("discarding cluster: chi2=%f (cut = %f)\n", chi2, chi2cut));
470
471 }
472
473 // Analyizing the clusters: BACK ACTIVE ELEMENTS
474
475 Int_t nClustersBack = fMFTClusterArrayBack[planeId]->GetEntries();
476 AliDebug(2, Form("There are %3d clusters in plane %02d BACK\n", nClustersBack, planeId));
477
478 for (Int_t iCluster=0; iCluster<nClustersBack; iCluster++) {
479
480 Bool_t isGoodChi2 = kFALSE;
481
482 AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArrayBack[planeId]->At(iCluster);
483 Double_t chi2 = (1./(corrFact*corrFact)) * TryOneCluster(currentParamForResearchBack, cluster); // describes the compatibility between the track and the cluster
484 if (chi2<chi2cut) isGoodChi2 = kTRUE;
485
486 if (isGoodChi2) {
487 AliDebug(3,Form("accepting cluster: chi2=%f (cut = %f)\n", chi2, chi2cut));
488 AliMuonForwardTrack *newTrack = new ((*fCandidateTracks)[fCandidateTracks->GetEntriesFast()]) AliMuonForwardTrack(*fCurrentTrack);
489 if (fCandidateTracks->GetEntriesFast() > fMaxNCandidates) return kDiverged;
490 newTrack->AddTrackParamAtMFTCluster(currentParamBack, *cluster); // creating new track param and attaching the cluster
491 AliDebug(2, Form("After plane %02d: newTrack->GetNMFTClusters() = %d (fCurrentTrack->GetNMFTClusters() = %d)",
492 planeId, newTrack->GetNMFTClusters(), fCurrentTrack->GetNMFTClusters()));
493 newTrack->SetPlaneExists(planeId);
494 }
495 else AliDebug(3,Form("discarding cluster: chi2=%f (cut = %f)\n", chi2, chi2cut));
496
497 }
498
499 //---------------------------------------------------------------------------------------------
500
501 return kConverged;
502
503}
504
505//==========================================================================================================================================
506
507Double_t AliMFTTrackerMU::TryOneCluster(const AliMUONTrackParam &trackParam, AliMFTCluster *cluster) {
508
509 // Test the compatibility between the track and the cluster (using trackParam's covariance matrix):
510 // return the corresponding Chi2
511 // assume the track parameters are given at the Z of the cluster
512
513 // Set differences between trackParam and cluster in the bending and non bending directions
514 Double_t dX = cluster->GetX() - trackParam.GetNonBendingCoor();
515 Double_t dY = cluster->GetY() - trackParam.GetBendingCoor();
516 AliDebug(3,Form("dX = %f, dY = %f\n", dX, dY));
517
518 // Calculate errors and covariances
519 const TMatrixD& kParamCov = trackParam.GetCovariances();
520 Double_t sigmaX2 = kParamCov(0,0) + cluster->GetErrX2();
521 Double_t sigmaY2 = kParamCov(2,2) + cluster->GetErrY2();
522 AliDebug(3, Form("dX2 = %f, dY2 = %f\n", sigmaX2, sigmaY2));
523 Double_t covXY = kParamCov(0,2);
524 Double_t det = sigmaX2 * sigmaY2 - covXY * covXY;
525
526 // Compute chi2
527 if (det==0.) return 1.e10;
528 return (dX*dX*sigmaY2 + dY*dY*sigmaX2 - 2.*dX*dY*covXY) / det;
529
530}
531
532//=========================================================================================================================================
533