1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 #include <stdlib.h> // for exit()
19 #include <Riostream.h>
20 #include <TClonesArray.h>
24 #include "AliMUONTrackK.h"
25 #include "AliCallf77.h"
27 #include "AliMUONChamber.h"
28 #include "AliMUONTrackReconstructor.h"
30 #include "AliMUONSegment.h"
31 #include "AliMUONHitForRec.h"
32 #include "AliMUONRawCluster.h"
33 #include "AliMUONTrackParam.h"
37 const Int_t AliMUONTrackK::fgkSize = 5;
38 const Int_t AliMUONTrackK::fgkNSigma = 12;
39 const Double_t AliMUONTrackK::fgkChi2max = 100;
40 const Int_t AliMUONTrackK::fgkTriesMax = 10000;
41 const Double_t AliMUONTrackK::fgkEpsilon = 0.002;
43 void mnvertLocal(Double_t* a, Int_t l, Int_t m, Int_t n, Int_t& ifail); // from AliMUONTrack
44 //void mnvertLocalK(Double_t* a, Int_t l, Int_t m, Int_t n, Int_t& ifail);
46 ClassImp(AliMUONTrackK) // Class implementation in ROOT context
48 Int_t AliMUONTrackK::fgDebug = -1;
49 Int_t AliMUONTrackK::fgNOfPoints = 0;
50 AliMUON* AliMUONTrackK::fgMUON = NULL;
51 AliMUONTrackReconstructor* AliMUONTrackK::fgTrackReconstructor = NULL;
52 TClonesArray* AliMUONTrackK::fgHitForRec = NULL;
53 //FILE *lun1 = fopen("window.dat","w");
55 //__________________________________________________________________________
56 AliMUONTrackK::AliMUONTrackK()
60 // Default constructor
62 fgTrackReconstructor = NULL; // pointer to event reconstructor
63 fgMUON = NULL; // pointer to Muon module
64 fgHitForRec = NULL; // pointer to points
65 fgNOfPoints = 0; // number of points
70 fTrackPar = fTrackParNew = NULL;
71 fCovariance = fWeight = NULL;
73 fParExtrap = fParFilter = fParSmooth = NULL;
74 fCovExtrap = fCovFilter = NULL;
76 fSteps = NULL; fNSteps = 0;
83 //__________________________________________________________________________
84 AliMUONTrackK::AliMUONTrackK(AliMUONTrackReconstructor *TrackReconstructor, TClonesArray *hitForRec)
90 if (!TrackReconstructor) return;
91 fgTrackReconstructor = TrackReconstructor; // pointer to event reconstructor
92 fgMUON = (AliMUON*) gAlice->GetModule("MUON"); // pointer to Muon module
93 fgHitForRec = hitForRec; // pointer to points
94 fgNOfPoints = fgHitForRec->GetEntriesFast(); // number of points
100 fTrackPar = fTrackParNew = NULL;
101 fCovariance = fWeight = NULL;
103 fParExtrap = fParFilter = fParSmooth = NULL;
104 fCovExtrap = fCovFilter = NULL;
106 fSteps = NULL; fNSteps = 0;
111 //__________________________________________________________________________
112 AliMUONTrackK::AliMUONTrackK(AliMUONSegment *segment)
114 : AliMUONTrack(segment, segment, fgTrackReconstructor)
116 // Constructor from a segment
118 AliMUONHitForRec *hit1, *hit2;
119 AliMUONRawCluster *clus;
120 TClonesArray *rawclusters;
122 fStartSegment = segment;
125 // Pointers to hits from the segment
126 hit1 = segment->GetHitForRec1();
127 hit2 = segment->GetHitForRec2();
128 hit1->SetNTrackHits(hit1->GetNTrackHits()+1); // mark hit as being on track
129 hit2->SetNTrackHits(hit2->GetNTrackHits()+1); // mark hit as being on track
130 // check sorting in Z
131 if (TMath::Abs(hit1->GetZ()) > TMath::Abs(hit2->GetZ())) {
133 hit2 = segment->GetHitForRec1();
135 // memory allocation for the TObjArray of pointers to reconstructed TrackHit's
136 fTrackHitsPtr = new TObjArray(13);
140 fTrackPar = new TMatrixD(fgkSize,1); // track parameters
141 fTrackParNew = new TMatrixD(fgkSize,1); // track parameters
142 fCovariance = new TMatrixD(fgkSize,fgkSize); // covariance matrix
143 fWeight = new TMatrixD(fgkSize,fgkSize); // weight matrix (inverse of covariance)
145 // Fill array of track parameters
146 if (hit1->GetChamberNumber() > 7) {
147 // last tracking station
148 (*fTrackPar)(0,0) = hit1->GetBendingCoor(); // y
149 (*fTrackPar)(1,0) = hit1->GetNonBendingCoor(); // x
150 fPosition = hit1->GetZ(); // z
151 fTrackHitsPtr->Add(hit2); // add hit 2
152 fTrackHitsPtr->Add(hit1); // add hit 1
153 //AZ(Z->-Z) fTrackDir = -1;
156 // last but one tracking station
157 (*fTrackPar)(0,0) = hit2->GetBendingCoor(); // y
158 (*fTrackPar)(1,0) = hit2->GetNonBendingCoor(); // x
159 fPosition = hit2->GetZ(); // z
160 fTrackHitsPtr->Add(hit1); // add hit 1
161 fTrackHitsPtr->Add(hit2); // add hit 2
162 //AZ(Z->-Z) fTrackDir = 1;
165 dZ = hit2->GetZ() - hit1->GetZ();
166 dY = hit2->GetBendingCoor() - hit1->GetBendingCoor();
167 dX = hit2->GetNonBendingCoor() - hit1->GetNonBendingCoor();
168 (*fTrackPar)(2,0) = TMath::ATan2(dY,dZ); // alpha
169 if ((*fTrackPar)(2,0) < 0.) (*fTrackPar)(2,0) += 2*TMath::Pi(); // from 0 to 2*pi
170 (*fTrackPar)(3,0) = TMath::ATan2(-dX,dZ/TMath::Cos((*fTrackPar)(2,0))); // beta
171 (*fTrackPar)(2,0) -= TMath::Pi();
172 (*fTrackPar)(4,0) = 1/fgTrackReconstructor->GetBendingMomentumFromImpactParam(segment->GetBendingImpact()); // 1/Pt
173 (*fTrackPar)(4,0) *= TMath::Cos((*fTrackPar)(3,0)); // 1/p
174 // Evaluate covariance (and weight) matrix
178 fParExtrap = new TObjArray(15);
179 fParFilter = new TObjArray(15);
180 fCovExtrap = new TObjArray(15);
181 fCovFilter = new TObjArray(15);
182 fJacob = new TObjArray(15);
183 fSteps = new TArrayD(15);
185 fChi2Array = new TArrayD(13);
189 if (fgDebug < 0 ) return;
190 cout << fgTrackReconstructor->GetBendingMomentumFromImpactParam(segment->GetBendingImpact()) << " " << 1/(*fTrackPar)(4,0) << " ";
191 if (fgTrackReconstructor->GetRecTrackRefHits()) {
192 // from track ref. hits
193 cout << ((AliMUONHitForRec*)((*fTrackHitsPtr)[0]))->GetTTRTrack() << "<-->" << ((AliMUONHitForRec*)((*fTrackHitsPtr)[1]))->GetTTRTrack() << " @ " << fStartSegment->GetHitForRec1()->GetChamberNumber() << endl;
196 for (Int_t i=0; i<2; i++) {
197 hit1 = (AliMUONHitForRec*) ((*fTrackHitsPtr)[i]);
198 rawclusters = fgTrackReconstructor->GetMUONData()->RawClusters(hit1->GetChamberNumber());
199 clus = (AliMUONRawCluster*) rawclusters->UncheckedAt(hit1->GetHitNumber());
200 cout << clus->GetTrack(1);
201 if (clus->GetTrack(2) != -1) cout << " " << clus->GetTrack(2);
202 if (i == 0) cout << " <--> ";
204 cout << " @ " << fStartSegment->GetHitForRec1()->GetChamberNumber() << endl;
208 //__________________________________________________________________________
209 AliMUONTrackK::~AliMUONTrackK()
214 delete fTrackHitsPtr; // delete the TObjArray of pointers to TrackHit's
215 fTrackHitsPtr = NULL;
218 delete fTrackPar; delete fTrackParNew; delete fCovariance;
222 if (fSteps) delete fSteps;
223 if (fChi2Array) delete fChi2Array;
224 if (fChi2Smooth) delete fChi2Smooth;
225 if (fParSmooth) {fParSmooth->Delete(); delete fParSmooth; }
226 // Delete only matrices not shared by several tracks
227 if (!fParExtrap) return;
230 for (Int_t i=0; i<fNSteps; i++) {
231 //if (fParExtrap->UncheckedAt(i)->GetUniqueID() > 1)
232 // fParExtrap->UncheckedAt(i)->SetUniqueID(fParExtrap->RemoveAt(i)->GetUniqueID()-1);
233 id = fParExtrap->UncheckedAt(i)->GetUniqueID();
235 fParExtrap->UncheckedAt(i)->SetUniqueID(id-1);
236 fParExtrap->RemoveAt(i);
238 //if (fParFilter->UncheckedAt(i)->GetUniqueID() > 1)
239 // fParFilter->UncheckedAt(i)->SetUniqueID(fParFilter->RemoveAt(i)->GetUniqueID()-1);
240 id = fParFilter->UncheckedAt(i)->GetUniqueID();
242 fParFilter->UncheckedAt(i)->SetUniqueID(id-1);
243 fParFilter->RemoveAt(i);
245 //if (fCovExtrap->UncheckedAt(i)->GetUniqueID() > 1)
246 // fCovExtrap->UncheckedAt(i)->SetUniqueID(fCovExtrap->RemoveAt(i)->GetUniqueID()-1);
247 id = fCovExtrap->UncheckedAt(i)->GetUniqueID();
249 fCovExtrap->UncheckedAt(i)->SetUniqueID(id-1);
250 fCovExtrap->RemoveAt(i);
253 //if (fCovFilter->UncheckedAt(i)->GetUniqueID() > 1)
254 // fCovFilter->UncheckedAt(i)->SetUniqueID(fCovFilter->RemoveAt(i)->GetUniqueID()-1);
255 id = fCovFilter->UncheckedAt(i)->GetUniqueID();
257 fCovFilter->UncheckedAt(i)->SetUniqueID(id-1);
258 fCovFilter->RemoveAt(i);
260 //if (fJacob->UncheckedAt(i)->GetUniqueID() > 1)
261 // fJacob->UncheckedAt(i)->SetUniqueID(fJacob->RemoveAt(i)->GetUniqueID()-1);
262 id = fJacob->UncheckedAt(i)->GetUniqueID();
264 fJacob->UncheckedAt(i)->SetUniqueID(id-1);
269 for (Int_t i=0; i<fNSteps; i++) {
270 if (fParExtrap->UncheckedAt(i)) ((TMatrixD*)fParExtrap->UncheckedAt(i))->Delete();
271 if (fParFilter->UncheckedAt(i)) ((TMatrixD*)fParFilter->UncheckedAt(i))->Delete();
272 if (fCovExtrap->UncheckedAt(i)) ((TMatrixD*)fCovExtrap->UncheckedAt(i))->Delete();
273 cout << fCovFilter->UncheckedAt(i) << " " << (*fSteps)[i] << endl;
274 if (fCovFilter->UncheckedAt(i)) ((TMatrixD*)fCovFilter->UncheckedAt(i))->Delete();
275 if (fJacob->UncheckedAt(i)) ((TMatrixD*)fJacob->UncheckedAt(i))->Delete();
278 fParExtrap->Delete(); fParFilter->Delete();
279 fCovExtrap->Delete(); fCovFilter->Delete();
281 delete fParExtrap; delete fParFilter;
282 delete fCovExtrap; delete fCovFilter;
286 //__________________________________________________________________________
287 AliMUONTrackK::AliMUONTrackK (const AliMUONTrackK& source)
288 //AZ: TObject(source)
289 : AliMUONTrack(source)
291 // Protected copy constructor
292 AliFatal("Not implemented.");
295 //__________________________________________________________________________
296 AliMUONTrackK & AliMUONTrackK::operator=(const AliMUONTrackK& source)
298 // Assignment operator
300 if(&source == this) return *this;
302 // base class assignement
303 //AZ TObject::operator=(source);
304 AliMUONTrack::operator=(source);
306 fStartSegment = source.fStartSegment;
307 fNTrackHits = source.fNTrackHits;
308 fChi2 = source.fChi2;
309 fPosition = source.fPosition;
310 fPositionNew = source.fPositionNew;
311 fTrackDir = source.fTrackDir;
312 fBPFlag = source.fBPFlag;
313 fRecover = source.fRecover;
314 fSkipHit = source.fSkipHit;
317 fTrackHitsPtr = new TObjArray(*source.fTrackHitsPtr);
318 //source.fTrackHitsPtr->Dump();
319 //fTrackHitsPtr->Dump();
321 fTrackPar = new TMatrixD(*source.fTrackPar); // track parameters
322 fTrackParNew = new TMatrixD(*source.fTrackParNew); // track parameters
323 fCovariance = new TMatrixD(*source.fCovariance); // covariance matrix
324 fWeight = new TMatrixD(*source.fWeight); // weight matrix (inverse of covariance)
327 fParExtrap = new TObjArray(*source.fParExtrap);
328 fParFilter = new TObjArray(*source.fParFilter);
329 fCovExtrap = new TObjArray(*source.fCovExtrap);
330 fCovFilter = new TObjArray(*source.fCovFilter);
331 fJacob = new TObjArray(*source.fJacob);
332 fSteps = new TArrayD(*source.fSteps);
333 fNSteps = source.fNSteps;
335 if (source.fChi2Array) fChi2Array = new TArrayD(*source.fChi2Array);
339 for (Int_t i=0; i<fParExtrap->GetEntriesFast(); i++) {
340 fParExtrap->UncheckedAt(i)->SetUniqueID(fParExtrap->UncheckedAt(i)->GetUniqueID()+1);
341 fParFilter->UncheckedAt(i)->SetUniqueID(fParFilter->UncheckedAt(i)->GetUniqueID()+1);
342 fCovExtrap->UncheckedAt(i)->SetUniqueID(fCovExtrap->UncheckedAt(i)->GetUniqueID()+1);
343 fCovFilter->UncheckedAt(i)->SetUniqueID(fCovFilter->UncheckedAt(i)->GetUniqueID()+1);
344 fJacob->UncheckedAt(i)->SetUniqueID(fJacob->UncheckedAt(i)->GetUniqueID()+1);
349 //__________________________________________________________________________
350 void AliMUONTrackK::EvalCovariance(Double_t dZ)
352 // Evaluate covariance (and weight) matrix for track candidate
353 Double_t sigmaB, sigmaNonB, tanA, tanB, dAdY, rad, dBdX, dBdY;
356 sigmaB = fgTrackReconstructor->GetBendingResolution(); // bending resolution
357 sigmaNonB = fgTrackReconstructor->GetNonBendingResolution(); // non-bending resolution
359 (*fWeight)(0,0) = sigmaB*sigmaB; // <yy>
361 (*fWeight)(1,1) = sigmaNonB*sigmaNonB; // <xx>
363 tanA = TMath::Tan((*fTrackPar)(2,0));
364 dAdY = 1/(1+tanA*tanA)/dZ;
365 (*fWeight)(2,2) = dAdY*dAdY*(*fWeight)(0,0)*2; // <aa>
366 (*fWeight)(0,2) = dAdY*(*fWeight)(0,0); // <ya>
367 (*fWeight)(2,0) = (*fWeight)(0,2);
369 rad = dZ/TMath::Cos((*fTrackPar)(2,0));
370 tanB = TMath::Tan((*fTrackPar)(3,0));
371 dBdX = 1/(1+tanB*tanB)/rad;
373 (*fWeight)(3,3) = dBdX*dBdX*(*fWeight)(1,1)*2; // <bb>
374 (*fWeight)(1,3) = dBdX*(*fWeight)(1,1); // <xb>
375 (*fWeight)(3,1) = (*fWeight)(1,3);
377 //(*fWeight)(4,4) = ((*fTrackPar)(4,0)*0.2)*((*fTrackPar)(4,0)*0.2); // error 20%
378 (*fWeight)(4,4) = ((*fTrackPar)(4,0)*0.5)*((*fTrackPar)(4,0)*0.5); // error 50%
380 // check whether the Invert method returns flag if matrix cannot be inverted,
381 // and do not calculate the Determinant in that case !!!!
382 if (fWeight->Determinant() != 0) {
383 // fWeight->Invert();
385 //mnvertLocalK(&((*fWeight)(0,0)), fgkSize,fgkSize,fgkSize,ifailWeight);
386 mnvertLocal(&((*fWeight)(0,0)), fgkSize,fgkSize,fgkSize,ifail);
388 AliWarning(" Determinant fWeight=0:");
393 //__________________________________________________________________________
394 Bool_t AliMUONTrackK::KalmanFilter(Int_t ichamBeg, Int_t ichamEnd, Bool_t Back, Double_t zDipole1, Double_t zDipole2)
396 // Follows track through detector stations
397 Bool_t miss, success;
398 Int_t ichamb, iFB, iMin, iMax, dChamb, ichambOK;
399 Int_t ihit, firstIndx, lastIndx, currIndx;
400 Double_t zEnd, dChi2;
401 AliMUONHitForRec *hitAdd, *firstHit, *lastHit, *hit;
402 AliMUONRawCluster *clus;
403 TClonesArray *rawclusters;
404 hit = 0; clus = 0; rawclusters = 0;
406 miss = success = kTRUE;
408 //iFB = (ichamEnd == ichamBeg) ? fTrackDir : TMath::Sign(1,ichamEnd-ichamBeg);
409 iFB = (ichamEnd == ichamBeg) ? -fTrackDir : TMath::Sign(1,ichamEnd-ichamBeg);
410 iMin = TMath::Min(ichamEnd,ichamBeg);
411 iMax = TMath::Max(ichamEnd,ichamBeg);
418 if (((AliMUONHitForRec*)fTrackHitsPtr->First())->GetChamberNumber() != ichamb) currIndx = 0;
419 } else if (fRecover) {
420 hit = GetHitLastOk();
421 currIndx = fTrackHitsPtr->IndexOf(hit);
422 if (currIndx < 0) hit = fStartSegment->GetHitForRec1(); // for station 3
424 ichamb = hit->GetChamberNumber();
425 if (hit == fSkipHit || fRecover == 2 && currIndx >= 0) {
426 // start from the last point or outlier
427 // remove the skipped hit
428 fTrackHitsPtr->Remove(fSkipHit); // remove hit
430 fSkipHit->SetNTrackHits(fSkipHit->GetNTrackHits()-1); // unmark hit
435 ichambOK = ((AliMUONHitForRec*)((*fTrackHitsPtr)[fNTrackHits-1]))->GetChamberNumber();
436 //if (ichambOK >= 8 && ((AliMUONHitForRec*)((*fTrackHitsPtr)[0]))->GetChamberNumber() == 6) ichambOK = 6;
437 currIndx = fgHitForRec->IndexOf(fSkipHit);
440 fTrackHitsPtr->Compress();
442 } // if (hit == fSkipHit)
443 else if (currIndx < 0) currIndx = fTrackHitsPtr->IndexOf(hit);
444 } // else if (fRecover)
446 // Get indices of the 1'st and last hits on the track candidate
447 firstHit = (AliMUONHitForRec*) fTrackHitsPtr->First();
448 lastHit = (AliMUONHitForRec*) fTrackHitsPtr->Last();
449 firstIndx = fgHitForRec->IndexOf(firstHit);
450 lastIndx = fgHitForRec->IndexOf(lastHit);
451 currIndx = TMath::Abs (TMath::Max(firstIndx*iFB,lastIndx*iFB));
454 while (ichamb>=iMin && ichamb<=iMax) {
455 // Find the closest hit in Z, not belonging to the current plane
458 if (currIndx < fNTrackHits) {
459 hitAdd = (AliMUONHitForRec*) fTrackHitsPtr->UncheckedAt(currIndx);
460 zEnd = hitAdd->GetZ();
461 //AZ(z->-z) } else zEnd = -9999;
464 //AZ(Z->-Z) zEnd = -9999;
466 for (ihit=currIndx+iFB; ihit>=0 && ihit<fgNOfPoints; ihit+=iFB) {
467 hitAdd = (AliMUONHitForRec*) ((*fgHitForRec)[ihit]);
468 //if (TMath::Abs(hitAdd->GetZ()-fPosition) > 0.1) {
469 if (TMath::Abs(hitAdd->GetZ()-fPosition) > 0.5) {
470 zEnd = hitAdd->GetZ();
476 //AZ(Z->-Z) if (zEnd<-999 && ichamb==ichamEnd) endOfProp = 1; // end-of-propagation
477 if (zEnd>999 && ichamb==ichamEnd) endOfProp = 1; // end-of-propagation
479 // Check if there is a chamber without hits
480 if (zEnd>999 || TMath::Abs(hitAdd->GetChamberNumber()-ichamb) > 1) {
481 if (!Back && zEnd<999) currIndx -= iFB;
483 zEnd = (&(fgMUON->Chamber(ichamb)))->Z();
486 ichamb = hitAdd->GetChamberNumber();
490 if (ichamb<iMin || ichamb>iMax) break;
491 // Check for missing station
493 dChamb = TMath::Abs(ichamb-ichambOK);
494 //cout << dChamb << " " << ichambOK << " " << fgNOfPoints << endl;
495 Int_t dStatMiss = TMath::Abs (ichamb/2 - ichambOK/2);
496 if (zEnd > 999) dStatMiss++;
498 // missing station - abandon track
499 //cout << dChamb << " " << ichambOK << " " << fgNOfPoints << " " << 1/(*fTrackPar)(4,0) << endl;
501 for (Int_t i1=0; i1<fgNOfPoints; i1++) {
502 cout << " Hit #" << ((AliMUONHitForRec*)((*fgHitForRec)[i1]))->GetChamberNumber() << " ";
503 cout << ((AliMUONHitForRec*)((*fgHitForRec)[i1]))->GetBendingCoor() << " ";
504 cout << ((AliMUONHitForRec*)((*fgHitForRec)[i1]))->GetNonBendingCoor() << " ";
505 cout << ((AliMUONHitForRec*)((*fgHitForRec)[i1]))->GetZ() << " " << " ";
506 cout << ((AliMUONHitForRec*)((*fgHitForRec)[i1]))->GetTTRTrack() << endl;
509 cout << fNTrackHits << endl;
510 for (Int_t i1=0; i1<fNTrackHits; i1++) {
511 hit = (AliMUONHitForRec*) ((*fTrackHitsPtr)[i1]);
512 printf(" * %d %10.4f %10.4f %10.4f",
513 hit->GetChamberNumber(), hit->GetBendingCoor(),
514 hit->GetNonBendingCoor(), hit->GetZ());
515 if (fgTrackReconstructor->GetRecTrackRefHits()) {
516 // from track ref. hits
517 printf(" %3d %3d \n", hit->GetTrackRefSignal(), hit->GetTTRTrack());
520 rawclusters = fgTrackReconstructor->GetMUONData()->RawClusters(hit->GetChamberNumber());
521 clus = (AliMUONRawCluster*) rawclusters->UncheckedAt(hit->GetHitNumber());
522 printf("%3d", clus->GetTrack(1)-1);
523 if (clus->GetTrack(2) != 0) printf("%3d \n", clus->GetTrack(2)-1);
527 } // if (fgDebug >= 10)
528 if (fNTrackHits>2 && fRecover==0) Recover(); // try to recover track later
530 } // if (dStatMiss > 1)
532 if (endOfProp != 0) break;
534 // propagate to the found Z
536 // Check if track steps into dipole
537 //AZ(z->-z) if (fPosition>zDipole2 && zEnd<zDipole2) {
538 if (fPosition<zDipole2 && zEnd>zDipole2) {
539 //LinearPropagation(zDipole2-zBeg);
540 ParPropagation(zDipole2);
541 MSThin(1); // multiple scattering in the chamber
542 WeightPropagation(zDipole2, kTRUE); // propagate weight matrix
543 fPosition = fPositionNew;
544 *fTrackPar = *fTrackParNew;
545 //MagnetPropagation(zEnd);
546 ParPropagation(zEnd);
547 WeightPropagation(zEnd, kTRUE);
548 fPosition = fPositionNew;
550 // Check if track steps out of dipole
551 //AZ(z->-z) else if (fPosition>zDipole1 && zEnd<zDipole1) {
552 else if (fPosition<zDipole1 && zEnd>zDipole1) {
553 //MagnetPropagation(zDipole1-zBeg);
554 ParPropagation(zDipole1);
555 MSThin(1); // multiple scattering in the chamber
556 WeightPropagation(zDipole1, kTRUE);
557 fPosition = fPositionNew;
558 *fTrackPar = *fTrackParNew;
559 //LinearPropagation(zEnd-zDipole1);
560 ParPropagation(zEnd);
561 WeightPropagation(zEnd, kTRUE);
562 fPosition = fPositionNew;
564 ParPropagation(zEnd);
565 //MSThin(1); // multiple scattering in the chamber
566 if (TMath::Abs(zEnd-fPosition) > 5) MSThin(1); // multiple scattering in the chamber
567 WeightPropagation(zEnd, kTRUE);
568 fPosition = fPositionNew;
572 if (fRecover != 0 && hitAdd == fSkipHit && !miss) {
573 // recovered track - remove the hit
575 ichamb = fSkipHit->GetChamberNumber();
576 // remove the skipped hit
577 fTrackHitsPtr->Remove(fSkipHit);
579 fSkipHit->SetNTrackHits(fSkipHit->GetNTrackHits()-1); // unmark hit
582 ichambOK = ((AliMUONHitForRec*)((*fTrackHitsPtr)[fNTrackHits-1]))->GetChamberNumber();
583 currIndx = fgHitForRec->IndexOf(fSkipHit);
587 // backward propagator
589 TMatrixD pointWeight(fgkSize,fgkSize);
590 TMatrixD point(fgkSize,1);
591 TMatrixD trackParTmp = point;
592 point(0,0) = hitAdd->GetBendingCoor();
593 point(1,0) = hitAdd->GetNonBendingCoor();
594 pointWeight(0,0) = 1/hitAdd->GetBendingReso2();
595 pointWeight(1,1) = 1/hitAdd->GetNonBendingReso2();
596 TryPoint(point,pointWeight,trackParTmp,dChi2);
597 *fTrackPar = trackParTmp;
598 *fWeight += pointWeight;
599 //AZ(z->-z) if (fTrackDir < 0) AddMatrices (this, dChi2, hitAdd);
600 if (fTrackDir > 0) AddMatrices (this, dChi2, hitAdd);
601 fChi2 += dChi2; // Chi2
602 } else *fTrackPar = *fTrackParNew; // adjust end point to the last hit
603 if (ichamb==ichamEnd) break;
606 // forward propagator
607 if (miss || !FindPoint(ichamb,zEnd,currIndx,iFB,hitAdd)) {
609 *fTrackPar = *fTrackParNew;
612 fTrackHitsPtr->Add(hitAdd); // add hit
614 hitAdd->SetNTrackHits(hitAdd->GetNTrackHits()+1); // mark hit as being on track
616 currIndx = fgHitForRec->IndexOf(hitAdd); // Check
620 if (fgDebug > 0) cout << fNTrackHits << " " << fChi2 << " " << 1/(*fTrackPar)(4,0) << " " << fPosition << endl;
621 if (1/TMath::Abs((*fTrackPar)(4,0)) < fgTrackReconstructor->GetMinBendingMomentum()) success = kFALSE; // p < p_min
625 //__________________________________________________________________________
626 void AliMUONTrackK::ParPropagation(Double_t zEnd)
628 // Propagation of track parameters to zEnd
630 Double_t dZ, step, distance, charge;
631 Double_t vGeant3[7], vGeant3New[7];
632 AliMUONTrackParam trackParam;
635 // First step using linear extrapolation
636 dZ = zEnd - fPosition;
637 fPositionNew = fPosition;
638 *fTrackParNew = *fTrackPar;
639 if (dZ == 0) return; //AZ ???
640 iFB = (Int_t)TMath::Sign(Double_t(1.0),dZ);
641 step = dZ/TMath::Cos((*fTrackPar)(2,0))/TMath::Cos((*fTrackPar)(3,0)); // linear estimate
642 //AZ(z->-z) charge = iFB*TMath::Sign(Double_t(1.0),(*fTrackPar)(4,0));
643 charge = -iFB*TMath::Sign(Double_t(1.0),(*fTrackPar)(4,0));
644 SetGeantParam(vGeant3,iFB);
645 //fTrackParNew->Print();
649 step = TMath::Abs(step);
650 // Propagate parameters
651 trackParam.ExtrapOneStepRungekutta(charge,step,vGeant3,vGeant3New);
652 //extrap_onestep_rungekutta(charge,step,vGeant3,vGeant3New);
653 distance = zEnd - vGeant3New[2];
654 step *= dZ/(vGeant3New[2]-fPositionNew);
656 } while (distance*iFB < 0 && TMath::Abs(distance) > fgkEpsilon);
658 GetFromGeantParam(vGeant3New,iFB);
659 //fTrackParNew->Print();
661 // Position adjustment (until within tolerance)
662 while (TMath::Abs(distance) > fgkEpsilon) {
663 dZ = zEnd - fPositionNew;
664 iFB = (Int_t)TMath::Sign(Double_t(1.0),dZ);
665 step = dZ/TMath::Cos((*fTrackParNew)(2,0))/TMath::Cos((*fTrackParNew)(3,0));
666 step = TMath::Abs(step);
667 SetGeantParam(vGeant3,iFB);
670 // Propagate parameters
671 trackParam.ExtrapOneStepRungekutta(charge,step,vGeant3,vGeant3New);
672 //extrap_onestep_rungekutta(charge,step,vGeant3,vGeant3New);
673 distance = zEnd - vGeant3New[2];
676 if (nTries > fgkTriesMax) {
677 cout << " ***** ParPropagation: too many tries " << nTries << endl;
678 AliFatal("Too many tries.");
680 } while (distance*iFB < 0);
682 GetFromGeantParam(vGeant3New,iFB);
684 //cout << nTries << endl;
685 //fTrackParNew->Print();
689 //__________________________________________________________________________
690 void AliMUONTrackK::WeightPropagation(void)
692 // Propagation of the weight matrix
693 // W = DtWD, where D is Jacobian
695 // !!! not implemented TMatrixD weight1(*fJacob,TMatrixD::kAtBA,*fWeight); // DtWD
696 TMatrixD weight1(*fWeight,TMatrixD::kMult,*fJacob); // WD
697 *fWeight = TMatrixD(*fJacob,TMatrixD::kTransposeMult,weight1); // DtWD
701 //__________________________________________________________________________
702 void AliMUONTrackK::WeightPropagation(Double_t zEnd, Bool_t smooth)
704 // Propagation of the weight matrix
705 // W = DtWD, where D is Jacobian
709 TMatrixD jacob(fgkSize,fgkSize);
712 // Save initial and propagated parameters
713 TMatrixD trackPar0 = *fTrackPar;
714 TMatrixD trackParNew0 = *fTrackParNew;
716 // Get covariance matrix
717 *fCovariance = *fWeight;
718 // check whether the Invert method returns flag if matrix cannot be inverted,
719 // and do not calculate the Determinant in that case !!!!
720 if (fCovariance->Determinant() != 0) {
721 // fCovariance->Invert();
723 mnvertLocal(&((*fCovariance)(0,0)), fgkSize,fgkSize,fgkSize,ifail);
724 //fCovariance->Print();
726 AliWarning(" Determinant fCovariance=0:");
729 // Loop over parameters to find change of the propagated vs initial ones
730 for (i=0; i<fgkSize; i++) {
731 dPar = TMath::Sqrt((*fCovariance)(i,i));
732 *fTrackPar = trackPar0;
733 if (i == 4) dPar *= TMath::Sign(1.,-trackPar0(4,0)); // 1/p
734 (*fTrackPar)(i,0) += dPar;
735 ParPropagation(zEnd);
736 for (j=0; j<fgkSize; j++) {
737 jacob(j,i) = ((*fTrackParNew)(j,0)-trackParNew0(j,0))/dPar;
741 //trackParNew0.Print();
742 //TMatrixD par1(jacob,TMatrixD::kMult,trackPar0); //
744 TMatrixD jacob0 = jacob;
745 if (jacob.Determinant() != 0) {
748 AliWarning(" Determinant jacob=0:");
750 TMatrixD weight1(*fWeight,TMatrixD::kMult,jacob); // WD
751 *fWeight = TMatrixD(jacob,TMatrixD::kTransposeMult,weight1); // DtWD
753 // Restore initial and propagated parameters
754 *fTrackPar = trackPar0;
755 *fTrackParNew = trackParNew0;
758 if (!smooth) return; // do not use smoother
759 //AZ(z->-z) if (fTrackDir > 0) return; // only for propagation towards int. point
760 if (fTrackDir < 0) return; // only for propagation towards int. point
761 TMatrixD *tmp = new TMatrixD(*fTrackParNew); // extrapolated parameters
762 fParExtrap->Add(tmp);
764 tmp = new TMatrixD(*fTrackParNew); // filtered parameters (if no measurement will be found)
765 fParFilter->Add(tmp);
767 *fCovariance = *fWeight;
768 if (fCovariance->Determinant() != 0) {
770 mnvertLocal(&((*fCovariance)(0,0)), fgkSize,fgkSize,fgkSize,ifail);
772 AliWarning(" Determinant fCovariance=0:");
774 tmp = new TMatrixD(*fCovariance); // extrapolated covariance
775 fCovExtrap->Add(tmp);
777 tmp = new TMatrixD(*fCovariance); // filtered covariance (if no measurement will be found)
778 fCovFilter->Add(tmp);
780 tmp = new TMatrixD(jacob0); // Jacobian
783 if (fSteps->fN <= fNSteps) fSteps->Set(fSteps->fN+10);
784 fSteps->AddAt(fPositionNew,fNSteps++);
785 if (fgDebug > 0) cout << " WeightPropagation " << fNSteps << " " << fPositionNew << endl;
789 //__________________________________________________________________________
790 Bool_t AliMUONTrackK::FindPoint(Int_t ichamb, Double_t zEnd, Int_t currIndx, Int_t iFB, AliMUONHitForRec *&hitAdd)
792 // Picks up point within a window for the chamber No ichamb
793 // Split the track if there are more than 1 hit
794 Int_t ihit, nRecTracks;
795 Double_t windowB, windowNonB, dChi2Tmp=0, dChi2, y, x, savePosition=0;
796 TClonesArray *trackPtr;
797 AliMUONHitForRec *hit, *hitLoop;
798 AliMUONTrackK *trackK;
801 //sigmaB = fgTrackReconstructor->GetBendingResolution(); // bending resolution
802 //sigmaNonB = fgTrackReconstructor->GetNonBendingResolution(); // non-bending resolution
803 *fCovariance = *fWeight;
804 // check whether the Invert method returns flag if matrix cannot be inverted,
805 // and do not calculate the Determinant in that case !!!!
806 if (fCovariance->Determinant() != 0) {
807 // fCovariance->Invert();
809 mnvertLocal(&((*fCovariance)(0,0)), fgkSize,fgkSize,fgkSize,ifail);
811 AliWarning(" Determinant fCovariance=0:");
813 //windowB = fgkNSigma*TMath::Sqrt((*fCovariance)(0,0)+sigmaB*sigmaB);
814 //windowNonB = fgkNSigma*TMath::Sqrt((*fCovariance)(1,1)+sigmaNonB*sigmaNonB);
815 // Loop over all hits and take hits from the chamber
816 TMatrixD pointWeight(fgkSize,fgkSize);
817 TMatrixD saveWeight = pointWeight;
818 TMatrixD pointWeightTmp = pointWeight;
819 TMatrixD point(fgkSize,1);
820 TMatrixD trackPar = point;
821 TMatrixD trackParTmp = point;
824 zLast = ((AliMUONHitForRec*)fTrackHitsPtr->Last())->GetZ();
826 for (ihit=currIndx; ihit>=0 && ihit<fgNOfPoints; ihit+=iFB) {
827 hit = (AliMUONHitForRec*) ((*fgHitForRec)[ihit]);
828 if (hit->GetChamberNumber() == ichamb) {
829 //if (TMath::Abs(hit->GetZ()-zEnd) < 0.1) {
830 if (TMath::Abs(hit->GetZ()-zEnd) < 0.5) {
831 //if (TMath::Abs(hit->GetZ()-zEnd) > 0.1) {
832 if (TMath::Abs(hit->GetZ()-zEnd) > 0.05) {
833 // adjust position: for multiple hits in the chamber
834 // (mostly (only?) for GEANT hits)
835 cout << " ******* adjust " << zEnd << " " << hit->GetZ() << endl;
837 *fTrackPar = *fTrackParNew;
838 ParPropagation(zEnd);
839 WeightPropagation(zEnd, kTRUE);
840 fPosition = fPositionNew;
841 *fTrackPar = *fTrackParNew;
843 *fCovariance = *fWeight;
844 if (fCovariance->Determinant() != 0) {
846 mnvertLocal(&((*fCovariance)(0,0)), fgkSize,fgkSize,fgkSize,ifail);
848 AliWarning(" Determinant fCovariance=0:" );
851 y = hit->GetBendingCoor();
852 x = hit->GetNonBendingCoor();
853 windowB = fgkNSigma*TMath::Sqrt((*fCovariance)(0,0)+hit->GetBendingReso2());
854 windowNonB = fgkNSigma*TMath::Sqrt((*fCovariance)(1,1)+hit->GetNonBendingReso2());
856 // windowB = TMath::Min (windowB,5.);
857 if (fgkNSigma > 6) windowB = TMath::Min (windowB,5.);
859 if (TMath::Abs(hit->GetZ()-zLast) < 50) {
860 windowB = TMath::Min (windowB,0.5);
861 windowNonB = TMath::Min (windowNonB,3.);
862 } else if (TMath::Abs(hit->GetZ()-zLast) < 200) {
863 windowB = TMath::Min (windowB,1.5);
864 windowNonB = TMath::Min (windowNonB,3.);
865 } else if (TMath::Abs(hit->GetZ()-zLast) < 350) {
866 windowB = TMath::Min (windowB,4.);
867 windowNonB = TMath::Min (windowNonB,6.);
873 if (TMath::Abs(hit->GetZ()-zLast) < 50) {
874 windowB = 5*TMath::Sqrt((*fCovariance)(0,0)+hit->GetBendingReso2());
875 windowNonB = 5*TMath::Sqrt((*fCovariance)(1,1)+hit->GetNonBendingReso2());
877 windowB = fgkNSigma*TMath::Sqrt((*fCovariance)(0,0)+hit->GetBendingReso2());
878 windowNonB = fgkNSigma*TMath::Sqrt((*fCovariance)(1,1)+hit->GetNonBendingReso2());
882 //cout << TMath::Abs((*fTrackParNew)(0,0)-y) << " " << windowB << " " << TMath::Abs((*fTrackParNew)(1,0)-x) << " " << windowNonB << " " << zEnd << endl;
883 if (TMath::Abs((*fTrackParNew)(0,0)-y) <= windowB &&
884 TMath::Abs((*fTrackParNew)(1,0)-x) <= windowNonB) {
885 //if (TMath::Abs((*fTrackParNew)(0,0)-y) <= windowB &&
886 // TMath::Abs((*fTrackParNew)(1,0)-x) <= windowNonB &&
887 // hit->GetTrackRefSignal() == 1) { // just for test
888 // Vector of measurements and covariance matrix
889 //fprintf(lun1,"%3d %3d %10.4f %10.4f \n", gAlice->GetEvNumber(), ichamb, x, y);
893 pointWeight(0,0) = 1/hit->GetBendingReso2();
894 pointWeight(1,1) = 1/hit->GetNonBendingReso2();
895 TryPoint(point,pointWeight,trackPar,dChi2);
896 if (TMath::Abs(1./(trackPar)(4,0)) < fgTrackReconstructor->GetMinBendingMomentum()) continue; // p < p_min - next hit
899 //if (nHitsOK > -1) {
901 // Save current members
902 saveWeight = *fWeight;
903 savePosition = fPosition;
904 // temporary storage for the current track
906 trackParTmp = trackPar;
907 pointWeightTmp = pointWeight;
910 // branching: create a new track
911 trackPtr = fgTrackReconstructor->GetRecTracksPtr();
912 nRecTracks = fgTrackReconstructor->GetNRecTracks();
913 trackK = new ((*trackPtr)[nRecTracks]) AliMUONTrackK(NULL, NULL);
915 fgTrackReconstructor->SetNRecTracks(nRecTracks+1);
916 if (fgDebug > 0) cout << " ******** New track: " << ichamb << " " << hit->GetTTRTrack() << " " << 1/(trackPar)(4,0) << " " << hit->GetBendingCoor() << " " << hit->GetNonBendingCoor() << " " << fNTrackHits << " " << nRecTracks << endl;
917 trackK->fRecover = 0;
918 *(trackK->fTrackPar) = trackPar;
919 *(trackK->fWeight) += pointWeight;
920 trackK->fChi2 += dChi2;
923 *(trackK->fCovariance) = *(trackK->fWeight);
924 if (trackK->fCovariance->Determinant() != 0) {
926 mnvertLocal(&((*(trackK->fCovariance))(0,0)), fgkSize,fgkSize,fgkSize,ifail);
928 cout << (*(trackK->fCovariance))(0,0) << " " << (*(trackK->fCovariance))(1,1) << " " << (*fCovariance)(0,0) << " " << (*fCovariance)(1,1) << endl;
930 // Add filtered matrices for the smoother
931 //AZ(z->-z) if (fTrackDir < 0) {
933 if (nHitsOK > 2) { // check for position adjustment
934 for (Int_t i=trackK->fNSteps-1; i>=0; i--) {
935 if (TMath::Abs(hit->GetZ()-(*trackK->fSteps)[i]) > 0.1) {
936 //if (TMath::Abs(hit->GetZ()-(trackK->fSteps)[i]) > 0.1) {
937 RemoveMatrices(trackK);
938 cout << " *** Position adjustment 1 " << hit->GetZ() << " "
939 << (*trackK->fSteps)[i] << endl;
940 AliFatal(" Position adjustment 1.");
945 AddMatrices (trackK, dChi2, hit);
947 // Mark hits as being on 2 tracks
948 for (Int_t i=0; i<fNTrackHits; i++) {
949 hitLoop = (AliMUONHitForRec*) ((*fTrackHitsPtr)[i]);
950 hitLoop->SetNTrackHits(hitLoop->GetNTrackHits()+1);
953 cout << hitLoop->GetChamberNumber() << " ";
954 cout << hitLoop->GetBendingCoor() << " ";
955 cout << hitLoop->GetNonBendingCoor() << " ";
956 cout << hitLoop->GetZ() << " " << " ";
957 cout << hitLoop->GetTrackRefSignal() << " " << " ";
958 cout << hitLoop->GetTTRTrack() << endl;
959 printf(" ** %d %10.4f %10.4f %10.4f %d %d \n",
960 hitLoop->GetChamberNumber(), hitLoop->GetBendingCoor(),
961 hitLoop->GetNonBendingCoor(), hitLoop->GetZ(),
962 hitLoop->GetTrackRefSignal(), hitLoop->GetTTRTrack());
966 trackK->fTrackHitsPtr->Add(hit); // add hit
967 trackK->fNTrackHits ++;
968 hit->SetNTrackHits(hit->GetNTrackHits()+1); // mark hit as being on track
971 //AZ(z->-z) trackK->fTrackDir = -1;
972 trackK->fTrackDir = 1;
973 trackK->fBPFlag = kTRUE;
978 } else break; // different chamber
979 } // for (ihit=currIndx;
982 *fTrackPar = trackParTmp;
983 *fWeight = saveWeight;
984 *fWeight += pointWeightTmp;
985 fChi2 += dChi2Tmp; // Chi2
986 fPosition = savePosition;
987 // Add filtered matrices for the smoother
988 //AZ(z->-z) if (fTrackDir < 0) {
990 for (Int_t i=fNSteps-1; i>=0; i--) {
991 if (TMath::Abs(fPosition-(*fSteps)[i]) > 0.1) {
992 //if (TMath::Abs(fPosition-fSteps[i]) > 0.1) {
993 RemoveMatrices(this);
994 if (fgDebug > 0) cout << " *** Position adjustment 2 " << fPosition << " " << (*fSteps)[i] << endl;
997 } // for (Int_t i=fNSteps-1;
998 AddMatrices (this, dChi2Tmp, hitAdd);
1001 for (Int_t i=0; i<fNSteps; i++) cout << (*fSteps)[i] << " "; cout << endl;
1002 for (Int_t i=0; i<trackK->fNSteps; i++) cout << (*trackK->fSteps)[i] << " "; cout << endl;
1005 } // if (fTrackDir > 0)
1010 //__________________________________________________________________________
1011 void AliMUONTrackK::TryPoint(TMatrixD &point, const TMatrixD &pointWeight, TMatrixD &trackParTmp, Double_t &dChi2)
1013 // Adds a measurement point (modifies track parameters and computes
1016 // Solving linear system (W+U)p' = U(m-p) + (W+U)p
1017 TMatrixD wu = *fWeight;
1018 wu += pointWeight; // W+U
1019 trackParTmp = point;
1020 trackParTmp -= *fTrackParNew; // m-p
1021 TMatrixD right(pointWeight,TMatrixD::kMult,trackParTmp); // U(m-p)
1022 TMatrixD right1(wu,TMatrixD::kMult,*fTrackParNew); // (W+U)p
1023 right += right1; // U(m-p) + (W+U)p
1025 // check whether the Invert method returns flag if matrix cannot be inverted,
1026 // and do not calculate the Determinant in that case !!!!
1027 if (wu.Determinant() != 0) {
1030 mnvertLocal(&((wu)(0,0)), fgkSize,fgkSize,fgkSize,ifail);
1032 AliWarning(" Determinant wu=0:");
1034 trackParTmp = TMatrixD(wu,TMatrixD::kMult,right);
1036 right1 = trackParTmp;
1037 right1 -= point; // p'-m
1038 point = trackParTmp;
1039 point -= *fTrackParNew; // p'-p
1040 right = TMatrixD(*fWeight,TMatrixD::kMult,point); // W(p'-p)
1041 TMatrixD value(point,TMatrixD::kTransposeMult,right); // (p'-p)'W(p'-p)
1043 right = TMatrixD(pointWeight,TMatrixD::kMult,right1); // U(p'-m)
1044 value = TMatrixD(right1,TMatrixD::kTransposeMult,right); // (p'-m)'U(p'-m)
1045 dChi2 += value(0,0);
1049 //__________________________________________________________________________
1050 void AliMUONTrackK::MSThin(Int_t sign)
1052 // Adds multiple scattering in a thin layer (only angles are affected)
1053 Double_t cosAlph, cosBeta, momentum, velo, path, theta0;
1055 // check whether the Invert method returns flag if matrix cannot be inverted,
1056 // and do not calculate the Determinant in that case !!!!
1057 if (fWeight->Determinant() != 0) {
1058 //fWeight->Invert(); // covariance
1061 mnvertLocal(&((*fWeight)(0,0)), fgkSize,fgkSize,fgkSize,ifail);
1063 AliWarning(" Determinant fWeight=0:");
1066 cosAlph = TMath::Cos((*fTrackParNew)(2,0));
1067 cosBeta = TMath::Cos((*fTrackParNew)(3,0));
1068 momentum = 1/(*fTrackParNew)(4,0); // particle momentum
1069 //velo = momentum/TMath::Sqrt(momentum*momentum+muonMass*muonMass); // velocity/c for muon hypothesis
1070 velo = 1; // relativistic
1071 path = TMath::Abs(fgTrackReconstructor->GetChamberThicknessInX0()/cosAlph/cosBeta); // path length
1072 theta0 = 0.0136/velo/momentum*TMath::Sqrt(path)*(1+0.038*TMath::Log(path)); // projected scattering angle
1074 (*fWeight)(2,2) += sign*theta0/cosBeta*theta0/cosBeta; // alpha
1075 (*fWeight)(3,3) += sign*theta0*theta0; // beta
1076 //fWeight->Invert(); // weight
1079 mnvertLocal(&((*fWeight)(0,0)), fgkSize,fgkSize,fgkSize,ifail);
1083 //__________________________________________________________________________
1084 void AliMUONTrackK::StartBack(void)
1086 // Starts backpropagator
1090 for (Int_t i=0; i<fgkSize; i++) {
1091 for (Int_t j=0; j<fgkSize; j++) {
1092 if (j==i) (*fWeight)(i,i) /= 100;
1093 //if (j==i) (*fWeight)(i,i) /= fNTrackHits*fNTrackHits;
1094 else (*fWeight)(j,i) = 0;
1097 // Sort hits on track in descending order in abs(z)
1098 SortHits(0, fTrackHitsPtr);
1101 //__________________________________________________________________________
1102 void AliMUONTrackK::SortHits(Int_t iflag, TObjArray *array)
1104 // Sort hits in Z if the seed segment in the last but one station
1105 // (if iflag==0 in descending order in abs(z), if !=0 - unsort)
1107 if (iflag && ((AliMUONHitForRec*)(array->UncheckedAt(0)))->GetChamberNumber() == 6) return;
1108 Double_t z = 0, zmax = TMath::Abs(((AliMUONHitForRec*)(array->UncheckedAt(0)))->GetZ());
1109 Int_t i = 1, entries = array->GetEntriesFast();
1110 for ( ; i<entries; i++) {
1112 if (((AliMUONHitForRec*)(array->UncheckedAt(i)))->GetChamberNumber() == 6) break;
1114 z = TMath::Abs(((AliMUONHitForRec*)(array->UncheckedAt(i)))->GetZ());
1115 if (z < zmax) break;
1117 if (fgDebug >= 10) cout << " " << zmax << " " << z << " " << i << endl;
1121 for (Int_t j=0; j<=(i-1)/2; j++) {
1122 TObject *hit = array->UncheckedAt(j);
1123 array->AddAt(array->UncheckedAt(i-j),j);
1124 array->AddAt(hit,i-j);
1126 if (fgDebug >= 10) {
1127 for (i=0; i<entries; i++)
1128 cout << ((AliMUONHitForRec*)(array->UncheckedAt(i)))->GetZ() << " ";
1129 cout << " - Sort" << endl;
1133 //__________________________________________________________________________
1134 void AliMUONTrackK::SetGeantParam(Double_t *VGeant3, Int_t iFB)
1136 // Set vector of Geant3 parameters pointed to by "VGeant3"
1137 // from track parameters
1139 VGeant3[0] = (*fTrackParNew)(1,0); // X
1140 VGeant3[1] = (*fTrackParNew)(0,0); // Y
1141 VGeant3[2] = fPositionNew; // Z
1142 VGeant3[3] = iFB*TMath::Sin((*fTrackParNew)(3,0)); // Px/Ptot
1143 VGeant3[4] = iFB*TMath::Cos((*fTrackParNew)(3,0))*TMath::Sin((*fTrackParNew)(2,0)); // Py/Ptot
1144 VGeant3[5] = iFB*TMath::Sqrt(1.0-VGeant3[3]*VGeant3[3]-VGeant3[4]*VGeant3[4]); // Pz/Ptot
1145 VGeant3[6] = 1/TMath::Abs((*fTrackParNew)(4,0)); // Ptot
1148 //__________________________________________________________________________
1149 void AliMUONTrackK::GetFromGeantParam(Double_t *VGeant3, Int_t iFB)
1151 // Get track parameters from vector of Geant3 parameters pointed
1154 fPositionNew = VGeant3[2]; // Z
1155 (*fTrackParNew)(0,0) = VGeant3[1]; // Y
1156 (*fTrackParNew)(1,0) = VGeant3[0]; // X
1157 (*fTrackParNew)(3,0) = TMath::ASin(iFB*VGeant3[3]); // beta
1158 (*fTrackParNew)(2,0) = TMath::ASin(iFB*VGeant3[4]/TMath::Cos((*fTrackParNew)(3,0))); // alpha
1159 (*fTrackParNew)(4,0) = 1/VGeant3[6]*TMath::Sign(Double_t(1.0),(*fTrackPar)(4,0)); // 1/Ptot
1162 //__________________________________________________________________________
1163 void AliMUONTrackK::SetTrackQuality(Int_t iChi2)
1165 // Computes "track quality" from Chi2 (if iChi2==0) or vice versa
1168 cout << " ***** Too high Chi2: " << fChi2 << endl;
1171 if (iChi2 == 0) fChi2 = fNTrackHits + (500.-fChi2)/501;
1172 else fChi2 = 500 - (fChi2-fNTrackHits)*501;
1175 //__________________________________________________________________________
1176 Int_t AliMUONTrackK::Compare(const TObject* trackK) const
1178 // "Compare" function to sort with decreasing "track quality".
1179 // Returns +1 (0, -1) if quality of current track
1180 // is smaller than (equal to, larger than) quality of trackK
1182 if (fChi2 < ((AliMUONTrackK*)trackK)->fChi2) return(+1);
1183 else if (fChi2 == ((AliMUONTrackK*)trackK)->fChi2) return(0);
1187 //__________________________________________________________________________
1188 Bool_t AliMUONTrackK::KeepTrack(AliMUONTrackK* track0) const
1190 // Check whether or not to keep current track
1191 // (keep, if it has less than half of common hits with track0)
1192 Int_t hitsInCommon, nHits0, i, j, nTrackHits2;
1193 AliMUONHitForRec *hit0, *hit1;
1196 nHits0 = track0->fNTrackHits;
1197 nTrackHits2 = fNTrackHits/2;
1199 for (i=0; i<nHits0; i++) {
1200 // Check if hit belongs to several tracks
1201 hit0 = (AliMUONHitForRec*) (*track0->fTrackHitsPtr)[i];
1202 if (hit0->GetNTrackHits() == 1) continue;
1203 for (j=0; j<fNTrackHits; j++) {
1204 hit1 = (AliMUONHitForRec*) (*fTrackHitsPtr)[j];
1205 if (hit1->GetNTrackHits() == 1) continue;
1208 if (hitsInCommon >= nTrackHits2) return kFALSE;
1216 //__________________________________________________________________________
1217 void AliMUONTrackK::Kill(void)
1219 // Kill track candidate
1221 AliMUONHitForRec *hit;
1223 if (fTrackHitsPtr) {
1224 // Remove track mark from hits
1225 for (i=0; i<fNTrackHits; i++) {
1226 hit = (AliMUONHitForRec*) (*fTrackHitsPtr)[i];
1227 hit->SetNTrackHits(hit->GetNTrackHits()-1);
1230 fgTrackReconstructor->GetRecTracksPtr()->Remove(this);
1233 //__________________________________________________________________________
1234 void AliMUONTrackK::FillMUONTrack(void)
1236 // Compute track parameters at hit positions (as for AliMUONTrack)
1238 // Set number of hits per track
1239 ((AliMUONTrack*)this)->SetNTrackHits(fNTrackHits);
1241 // Set track parameters at vertex
1242 AliMUONTrackParam trackParam;
1243 SetTrackParam(&trackParam, fTrackPar, fPosition);
1244 ((AliMUONTrack*)this)->SetTrackParamAtVertex(&trackParam);
1246 // Set track parameters at hits
1247 for (Int_t i = fNTrackHits-1; i>=0; i--) {
1248 if ((*fChi2Smooth)[i] < 0) {
1249 // Propagate through last chambers
1250 trackParam.ExtrapToZ(((AliMUONHitForRec*)((*fTrackHitsPtr)[i]))->GetZ());
1253 SetTrackParam(&trackParam, (TMatrixD*)fParSmooth->UncheckedAt(i), ((AliMUONHitForRec*)((*fTrackHitsPtr)[i]))->GetZ());
1255 ((AliMUONTrack*)this)->AddTrackParamAtHit(&trackParam);
1256 // Fill array of HitForRec's
1257 ((AliMUONTrack*)this)->AddHitForRecAtHit((AliMUONHitForRec*)fTrackHitsPtr->UncheckedAt(i));
1261 //__________________________________________________________________________
1262 void AliMUONTrackK::SetTrackParam(AliMUONTrackParam *trackParam, TMatrixD *par, Double_t z)
1264 // Fill AliMUONTrackParam object
1266 trackParam->SetBendingCoor((*par)(0,0));
1267 trackParam->SetNonBendingCoor((*par)(1,0));
1268 trackParam->SetBendingSlope(TMath::Tan((*par)(2,0)));
1269 trackParam->SetNonBendingSlope(TMath::Tan((*par)(3,0))/TMath::Cos((*par)(2,0)));
1270 trackParam->SetInverseBendingMomentum((*par)(4,0)/TMath::Cos((*par)(3,0)));
1271 trackParam->SetZ(z);
1274 //__________________________________________________________________________
1275 void AliMUONTrackK::Branson(void)
1277 // Propagates track to the vertex thru absorber using Branson correction
1278 // (makes use of the AliMUONTrackParam class)
1280 //AliMUONTrackParam *trackParam = new AliMUONTrackParam();
1281 AliMUONTrackParam trackParam = AliMUONTrackParam();
1283 trackParam->SetBendingCoor((*fTrackPar)(0,0));
1284 trackParam->SetNonBendingCoor((*fTrackPar)(1,0));
1285 trackParam->SetBendingSlope(TMath::Tan((*fTrackPar)(2,0)));
1286 trackParam->SetNonBendingSlope(TMath::Tan((*fTrackPar)(3,0))/TMath::Cos((*fTrackPar)(2,0)));
1287 trackParam->SetInverseBendingMomentum((*fTrackPar)(4,0)/TMath::Cos((*fTrackPar)(3,0)));
1288 trackParam->SetZ(fPosition);
1290 SetTrackParam(&trackParam, fTrackPar, fPosition);
1292 trackParam.ExtrapToVertex(Double_t(0.), Double_t(0.), Double_t(0.));
1293 //trackParam.ExtrapToVertex();
1295 (*fTrackPar)(0,0) = trackParam.GetBendingCoor();
1296 (*fTrackPar)(1,0) = trackParam.GetNonBendingCoor();
1297 (*fTrackPar)(2,0) = TMath::ATan(trackParam.GetBendingSlope());
1298 (*fTrackPar)(3,0) = TMath::ATan(TMath::Cos((*fTrackPar)(2,0))*trackParam.GetNonBendingSlope());
1299 (*fTrackPar)(4,0) = TMath::Cos((*fTrackPar)(3,0))*trackParam.GetInverseBendingMomentum();
1300 fPosition = trackParam.GetZ();
1301 //delete trackParam;
1302 cout << 1/(*fTrackPar)(4,0) << " " << fPosition << " " << (*fTrackPar)(0,0) << endl;
1304 // Get covariance matrix
1305 *fCovariance = *fWeight;
1306 if (fCovariance->Determinant() != 0) {
1308 mnvertLocal(&((*fCovariance)(0,0)), fgkSize,fgkSize,fgkSize,ifail);
1310 AliWarning(" Determinant fCovariance=0:");
1314 //__________________________________________________________________________
1315 void AliMUONTrackK::GoToZ(Double_t zEnd)
1317 // Propagates track to given Z
1319 ParPropagation(zEnd);
1320 MSThin(1); // multiple scattering in the chamber
1321 WeightPropagation(zEnd, kFALSE);
1322 fPosition = fPositionNew;
1323 *fTrackPar = *fTrackParNew;
1326 //__________________________________________________________________________
1327 void AliMUONTrackK::GoToVertex(Int_t iflag)
1330 // Propagates track to the vertex
1331 // All material constants are taken from AliRoot
1333 static Double_t x01[5] = { 24.282, // C
1338 // inner part theta < 3 degrees
1339 static Double_t x02[5] = { 30413, // Air
1344 // z positions of the materials inside the absober outer part theta > 3 degres
1345 static Double_t zPos[10] = {-90, -105, -315, -443, -468};
1347 Double_t dZ, r0Norm, x0, deltaP, dChi2, pTotal, pOld;
1348 AliMUONHitForRec *hit;
1349 AliMUONRawCluster *clus;
1350 TClonesArray *rawclusters;
1352 // First step to the rear end of the absorber
1353 //AZ(z->-z) Double_t zRear = 503;
1354 Double_t zRear = -503;
1356 Double_t tan3 = TMath::Tan(3./180*TMath::Pi());
1358 // Go through absorber
1359 pOld = 1/(*fTrackPar)(4,0);
1360 Double_t r0Rear = (*fTrackPar)(0,0)*(*fTrackPar)(0,0) +
1361 (*fTrackPar)(1,0)*(*fTrackPar)(1,0);
1362 r0Rear = TMath::Sqrt(r0Rear)/TMath::Abs(fPosition)/tan3;
1364 Double_t p0, cos25, cos60;
1365 if (!iflag) goto vertex;
1367 for (Int_t i=4; i>=0; i--) {
1368 ParPropagation(zPos[i]);
1369 WeightPropagation(zPos[i], kFALSE);
1370 dZ = TMath::Abs (fPositionNew-fPosition);
1371 if (r0Norm > 1) x0 = x01[i];
1373 MSLine(dZ,x0); // multiple scattering in the medium (linear approximation)
1374 fPosition = fPositionNew;
1375 *fTrackPar = *fTrackParNew;
1376 r0Norm = (*fTrackPar)(0,0)*(*fTrackPar)(0,0) +
1377 (*fTrackPar)(1,0)*(*fTrackPar)(1,0);
1378 r0Norm = TMath::Sqrt(r0Norm)/TMath::Abs(fPosition)/tan3;
1380 // Correct momentum for energy losses
1381 pTotal = 1/TMath::Abs((*fTrackPar)(4,0));
1383 cos25 = TMath::Cos(2.5/180*TMath::Pi());
1384 cos60 = TMath::Cos(6.0/180*TMath::Pi());
1385 for (Int_t j=0; j<1; j++) {
1389 deltaP = 2.164 + 0.145e-1*p0 - 0.417e-3*p0*p0;
1391 deltaP = 2.275 + 0.102e-2*p0 - 0.674e-6*p0*p0;
1395 deltaP = 2.581 + 0.188e-1*p0 - 0.398e-3*p0*p0;
1397 deltaP = 2.727 + 0.356e-2*p0 + 0.242e-5*p0*p0;
1405 deltaP = 2.737 + 0.0494*p0 - 0.001123*p0*p0;
1407 deltaP = 3.0643 + 0.01346*p0;
1413 deltaP = 2.1380 + 0.0351*p0 - 0.000853*p0*p0;
1415 deltaP = 2.407 + 0.00702*p0;
1424 deltaP = 2.439 + 0.806e-1*p0 - 0.500e-2*p0*p0 + 0.106e-3*p0*p0*p0;
1426 deltaP = 2.767 + 0.742e-2*p0 - 0.196e-4*p0*p0 + 0.403e-7*p0*p0*p0;
1433 deltaP = 2.209 + 0.800e-2*p0;
1435 deltaP = 2.285 + 0.141e-2*p0 - 0.446e-6*p0*p0;
1445 deltaP = 2.5938 + 0.0570 * p0 - 0.001151 * p0 * p0;
1447 deltaP = 3.0714 + 0.011767 * p0;
1451 deltaP = 2.1207 + 0.05478 * p0 - 0.00145079 * p0 * p0;
1453 deltaP = 2.6069 + 0.0051705 * p0;
1459 p0 = pTotal + deltaP/TMath::Abs(TMath::Cos((*fTrackPar)(2,0))/TMath::Cos((*fTrackPar)(3,0)));
1461 (*fTrackPar)(4,0) = 1/p0*TMath::Sign((Double_t)1.,(*fTrackPar)(4,0));
1465 ParPropagation((Double_t)0.);
1466 WeightPropagation((Double_t)0., kFALSE);
1467 fPosition = fPositionNew;
1468 //*fTrackPar = *fTrackParNew;
1469 // Add vertex as a hit
1470 TMatrixD pointWeight(fgkSize,fgkSize);
1471 TMatrixD point(fgkSize,1);
1472 TMatrixD trackParTmp = point;
1473 point(0,0) = 0; // vertex coordinate - should be taken somewhere
1474 point(1,0) = 0; // vertex coordinate - should be taken somewhere
1475 pointWeight(0,0) = 1/1.e-3/1.e-3; // 10 um error
1476 pointWeight(1,1) = 1/1.e-3/1.e-3; // 10 um error
1477 TryPoint(point,pointWeight,trackParTmp,dChi2);
1478 *fTrackPar = trackParTmp;
1479 *fWeight += pointWeight;
1480 fChi2 += dChi2; // Chi2
1481 if (fgDebug < 0) return; // no output
1483 cout << pOld << " " << 1/(*fTrackPar)(4,0) << " " << dChi2 << " " << fChi2 << " " << fNTrackHits << endl;
1484 for (Int_t i1=0; i1<fNTrackHits; i1++) {
1485 hit = (AliMUONHitForRec*) ((*fTrackHitsPtr)[i1]);
1486 printf ("%4d", hit->GetChamberNumber());
1490 for (Int_t i1=0; i1<fNTrackHits; i1++) {
1491 hit = (AliMUONHitForRec*) ((*fTrackHitsPtr)[i1]);
1492 //cout << ((AliMUONHitForRec*)((*fTrackHitsPtr)[i1]))->GetHitNumber() << " ";
1493 //cout << ((AliMUONHitForRec*)((*fTrackHitsPtr)[i1]))->GetZ() << " ";
1494 printf ("%4d", fgHitForRec->IndexOf(hit));
1498 if (fgTrackReconstructor->GetRecTrackRefHits()) {
1499 // from track ref. hits
1500 for (Int_t i1=0; i1<fNTrackHits; i1++) {
1501 hit = (AliMUONHitForRec*) ((*fTrackHitsPtr)[i1]);
1502 cout << hit->GetTTRTrack() + hit->GetTrackRefSignal()*10000 << " ";
1505 // from raw clusters
1506 for (Int_t i1=0; i1<fNTrackHits; i1++) {
1507 hit = (AliMUONHitForRec*) ((*fTrackHitsPtr)[i1]);
1508 rawclusters = fgTrackReconstructor->GetMUONData()->RawClusters(hit->GetChamberNumber());
1509 clus = (AliMUONRawCluster*) rawclusters->UncheckedAt(hit->GetHitNumber());
1510 printf ("%4d", clus->GetTrack(1));
1513 for (Int_t i1=0; i1<fNTrackHits; i1++) {
1514 hit = (AliMUONHitForRec*) ((*fTrackHitsPtr)[i1]);
1515 rawclusters = fgTrackReconstructor->GetMUONData()->RawClusters(hit->GetChamberNumber());
1516 clus = (AliMUONRawCluster*) rawclusters->UncheckedAt(hit->GetHitNumber());
1517 if (clus->GetTrack(2) != -1) printf ("%4d", clus->GetTrack(2));
1518 else printf ("%4s", " ");
1522 for (Int_t i1=0; i1<fNTrackHits; i1++) {
1523 //cout << ((AliMUONHitForRec*)((*fTrackHitsPtr)[i1]))->GetHitNumber() << " ";
1524 cout << ((AliMUONHitForRec*)((*fTrackHitsPtr)[i1]))->GetZ() << " ";
1525 //cout << fgHitForRec->IndexOf(((AliMUONHitForRec*)((*fTrackHitsPtr)[i1]))) << " ";
1528 for (Int_t i1=0; i1<fNTrackHits; i1++) printf("%8.4f", (*fChi2Smooth)[i1]);
1530 cout << "---------------------------------------------------" << endl;
1532 // Get covariance matrix
1533 /* Not needed - covariance matrix is not interesting to anybody
1534 *fCovariance = *fWeight;
1535 if (fCovariance->Determinant() != 0) {
1536 // fCovariance->Invert();
1538 mnvertLocal(&((*fCovariance)(0,0)), fgkSize,fgkSize,fgkSize,ifail);
1540 AliWarning(" Determinant fCovariance=0:" );
1545 //__________________________________________________________________________
1546 void AliMUONTrackK::MSLine(Double_t dZ, Double_t x0)
1548 // Adds multiple scattering in a thick layer for linear propagation
1550 Double_t cosAlph = TMath::Cos((*fTrackPar)(2,0));
1551 Double_t tanAlph = TMath::Tan((*fTrackPar)(2,0));
1552 Double_t cosBeta = TMath::Cos((*fTrackPar)(3,0));
1554 sinBeta = TMath::Sin((*fTrackPar)(3,0));
1555 Double_t tanBeta = TMath::Tan((*fTrackPar)(3,0));
1556 Double_t momentum = 1/(*fTrackPar)(4,0);
1557 Double_t velo = 1; // relativistic velocity
1558 Double_t step = TMath::Abs(dZ/cosAlph/cosBeta); // step length
1560 // Projected scattering angle
1561 Double_t theta0 = 0.0136/velo/momentum/TMath::Sqrt(x0)*(1+0.038*TMath::Log(step/x0));
1562 Double_t theta02 = theta0*theta0;
1563 Double_t dl2 = step*step/2*theta02;
1564 Double_t dl3 = dl2*step*2/3;
1567 Double_t dYdT = 1/cosAlph;
1568 Double_t dYdB = 0; //(*fTrackPar)(2,0)*sinBeta/cosAlph;
1569 Double_t dXdT = tanAlph*tanBeta;
1570 //Double_t dXdB = (1+(*fTrackPar)(2,0)*tanAlph*sinBeta*sinBeta)/cosBeta;
1571 Double_t dXdB = 1/cosBeta;
1572 Double_t dAdT = 1/cosBeta;
1573 Double_t dAdB = 0; //(*fTrackPar)(2,0)*tanBeta;
1575 // Get covariance matrix
1576 *fCovariance = *fWeight;
1577 if (fCovariance->Determinant() != 0) {
1578 // fCovariance->Invert();
1580 mnvertLocal(&((*fCovariance)(0,0)), fgkSize,fgkSize,fgkSize,ifail);
1582 AliWarning(" Determinant fCovariance=0:" );
1585 (*fCovariance)(0,0) += dl3*(dYdT*dYdT+dYdB*dYdB); // <yy>
1586 (*fCovariance)(1,1) += dl3*(dXdT*dXdT+dXdB*dXdB); // <xx>
1587 (*fCovariance)(2,2) += theta02*step*(dAdT*dAdT+dAdB*dAdB); // <aa>
1588 (*fCovariance)(3,3) += theta02*step; // <bb>
1590 (*fCovariance)(0,1) += dl3*(dYdT*dXdT+dYdB*dXdB); // <yx>
1591 (*fCovariance)(1,0) = (*fCovariance)(0,1);
1593 (*fCovariance)(0,2) += dl2*(dYdT*dAdT+dYdB*dAdB); // <ya>
1594 (*fCovariance)(2,0) = (*fCovariance)(0,2);
1596 (*fCovariance)(0,3) += dl2*dYdB; // <yb>
1597 (*fCovariance)(3,0) = (*fCovariance)(0,3);
1599 (*fCovariance)(1,2) += dl2*(-dXdT*dAdT+dXdB*dAdB); // <xa>
1600 (*fCovariance)(2,1) = (*fCovariance)(1,2);
1602 (*fCovariance)(1,3) += dl2*dXdB; // <xb>
1603 (*fCovariance)(3,1) = (*fCovariance)(1,3);
1605 (*fCovariance)(2,3) += theta02*step*dAdB; // <ab>
1606 (*fCovariance)(3,2) = (*fCovariance)(2,3);
1608 // Get weight matrix
1609 *fWeight = *fCovariance;
1610 if (fWeight->Determinant() != 0) {
1611 // fWeight->Invert();
1613 mnvertLocal(&((*fWeight)(0,0)), fgkSize,fgkSize,fgkSize,ifail);
1615 AliWarning(" Determinant fWeight=0:");
1619 //__________________________________________________________________________
1620 Bool_t AliMUONTrackK::Recover(void)
1622 // Adds new failed track(s) which can be tried to be recovered
1624 TClonesArray *trackPtr;
1625 AliMUONTrackK *trackK;
1627 if (fgDebug > 0) cout << " ******** Enter Recover " << endl;
1628 trackPtr = fgTrackReconstructor->GetRecTracksPtr();
1630 // Remove hit with the highest chi2
1633 for (Int_t i=0; i<fNTrackHits; i++) {
1634 chi2 = fChi2Smooth ? (*fChi2Smooth)[i] : (*fChi2Array)[i];
1635 printf("%10.4f", chi2);
1638 for (Int_t i=0; i<fNTrackHits; i++) {
1639 printf("%10d", ((AliMUONHitForRec*)fTrackHitsPtr->UncheckedAt(i))->GetChamberNumber());
1643 Double_t chi2max = 0;
1645 for (Int_t i=0; i<fNTrackHits; i++) {
1646 chi2 = fChi2Smooth ? (*fChi2Smooth)[i] : (*fChi2Array)[i];
1647 if (chi2 < chi2max) continue;
1651 //if (chi2max < 10) return kFALSE; // !!!
1652 //if (chi2max < 25) imax = fNTrackHits - 1;
1653 if (chi2max < 15) imax = fNTrackHits - 1; // discard the last point
1654 // Check if the outlier is not from the seed segment
1655 AliMUONHitForRec *skipHit = (AliMUONHitForRec*) fTrackHitsPtr->UncheckedAt(imax);
1656 if (skipHit == fStartSegment->GetHitForRec1() || skipHit == fStartSegment->GetHitForRec2()) {
1657 //DropBranches(fStartSegment); // drop all tracks with the same seed segment
1658 return kFALSE; // to be changed probably
1661 // Make a copy of track hit collection
1662 TObjArray *hits = new TObjArray(*fTrackHitsPtr);
1666 // Hits after the found one will be removed
1667 if (GetStation0() == 3 && skipHit->GetChamberNumber() > 7) {
1668 SortHits(1, fTrackHitsPtr); // unsort hits
1669 imax = fTrackHitsPtr->IndexOf(skipHit);
1671 Int_t nTrackHits = fNTrackHits;
1672 for (Int_t i=imax+1; i<nTrackHits; i++) {
1673 AliMUONHitForRec *hit = (AliMUONHitForRec*) fTrackHitsPtr->UncheckedAt(i);
1674 fTrackHitsPtr->Remove(hit);
1675 hit->SetNTrackHits(hit->GetNTrackHits()-1); // unmark hit
1679 // Check if the track candidate doesn't exist yet
1680 if (ExistDouble()) { delete hits; return kFALSE; }
1682 //DropBranches(imax0, hits); // drop branches downstream the discarded hit
1685 nRecTracks = fgTrackReconstructor->GetNRecTracks();
1686 skipHit = (AliMUONHitForRec*) ((*fTrackHitsPtr)[fNTrackHits-1]);
1687 // Remove all saved steps and smoother matrices after the skipped hit
1688 RemoveMatrices(skipHit->GetZ());
1690 //AZ(z->-z) if (skipHit->GetZ() > fStartSegment->GetHitForRec2()->GetZ() || !fNSteps) {
1691 if (TMath::Abs(skipHit->GetZ()) > TMath::Abs(fStartSegment->GetHitForRec2()->GetZ()) || !fNSteps) {
1692 // Propagation toward high Z or skipped hit next to segment -
1693 // start track from segment
1694 trackK = new ((*trackPtr)[nRecTracks]) AliMUONTrackK(fStartSegment);
1695 fgTrackReconstructor->SetNRecTracks(nRecTracks+1);
1696 trackK->fRecover = 1;
1697 trackK->fSkipHit = skipHit;
1698 trackK->fNTrackHits = fNTrackHits;
1699 delete trackK->fTrackHitsPtr; // not efficient ?
1700 trackK->fTrackHitsPtr = new TObjArray(*fTrackHitsPtr);
1701 if (fgDebug > 0) cout << nRecTracks << " " << trackK->fRecover << endl;
1705 trackK = new ((*trackPtr)[nRecTracks]) AliMUONTrackK(NULL, NULL);
1707 fgTrackReconstructor->SetNRecTracks(nRecTracks+1);
1708 //AZ(z->-z) trackK->fTrackDir = -1;
1709 trackK->fTrackDir = 1;
1710 trackK->fRecover = 1;
1711 trackK->fSkipHit = skipHit;
1712 Int_t iD = trackK->fParFilter->Last()->GetUniqueID();
1714 trackK->fParFilter->Last()->SetUniqueID(iD-1);
1715 CreateMatrix(trackK->fParFilter);
1717 trackK->fParFilter->Last()->SetUniqueID(iD);
1719 *((TMatrixD*)trackK->fParFilter->Last()) = *((TMatrixD*)fParExtrap->Last());
1720 *(trackK->fTrackPar) = *((TMatrixD*)trackK->fParFilter->Last());
1721 iD = trackK->fCovFilter->Last()->GetUniqueID();
1723 trackK->fCovFilter->Last()->SetUniqueID(iD-1);
1724 CreateMatrix(trackK->fCovFilter);
1726 trackK->fCovFilter->Last()->SetUniqueID(iD);
1728 *((TMatrixD*)trackK->fCovFilter->Last()) = *((TMatrixD*)fCovExtrap->Last());
1729 *(trackK->fWeight) = *((TMatrixD*)trackK->fCovFilter->Last());
1730 if (trackK->fWeight->Determinant() != 0) {
1732 mnvertLocal(&((*(trackK->fWeight))(0,0)), fgkSize,fgkSize,fgkSize,ifail);
1734 AliWarning(" Determinant fWeight=0:");
1736 trackK->fPosition = trackK->fPositionNew = (*fSteps)[fNSteps-1];
1738 for (Int_t i=0; i<fNTrackHits-1; i++) trackK->fChi2 += (*fChi2Array)[i];
1739 if (fgDebug > 0) cout << nRecTracks << " " << trackK->fRecover << endl;
1743 //__________________________________________________________________________
1744 void AliMUONTrackK::AddMatrices(AliMUONTrackK *trackK, Double_t dChi2, AliMUONHitForRec *hitAdd)
1746 // Adds matrices for the smoother and keep Chi2 for the point
1748 //trackK->fParFilter->Last()->Print();
1749 Int_t iD = trackK->fParFilter->Last()->GetUniqueID();
1751 trackK->fParFilter->Last()->SetUniqueID(iD-1);
1752 CreateMatrix(trackK->fParFilter);
1755 *((TMatrixD*)(trackK->fParFilter->Last())) = *(trackK->fTrackPar);
1756 trackK->fParFilter->Last()->SetUniqueID(iD);
1758 cout << " Add matrices" << " " << fPosition << " " << dChi2 << " " << fgHitForRec->IndexOf(hitAdd) << endl;
1759 //trackK->fTrackPar->Print();
1760 //trackK->fTrackParNew->Print();
1761 trackK->fParFilter->Last()->Print();
1762 cout << " Add matrices" << endl;
1765 *(trackK->fCovariance) = *(trackK->fWeight);
1766 if (trackK->fCovariance->Determinant() != 0) {
1768 mnvertLocal(&((*(trackK->fCovariance))(0,0)), fgkSize,fgkSize,fgkSize,ifail);
1770 AliWarning(" Determinant fCovariance=0:");
1772 iD = trackK->fCovFilter->Last()->GetUniqueID();
1774 trackK->fCovFilter->Last()->SetUniqueID(iD-1);
1775 CreateMatrix(trackK->fCovFilter);
1778 *((TMatrixD*)(trackK->fCovFilter->Last())) = *(trackK->fCovariance);
1779 trackK->fCovFilter->Last()->SetUniqueID(iD);
1781 // Save Chi2-increment for point
1782 Int_t indx = trackK->fTrackHitsPtr->IndexOf(hitAdd);
1783 if (indx < 0) indx = fNTrackHits;
1784 if (trackK->fChi2Array->fN <= indx) trackK->fChi2Array->Set(indx+10);
1785 trackK->fChi2Array->AddAt(dChi2,indx);
1788 //__________________________________________________________________________
1789 void AliMUONTrackK::CreateMatrix(TObjArray *objArray)
1791 // Create new matrix and add it to TObjArray
1793 TMatrixD *matrix = (TMatrixD*) objArray->First();
1794 TMatrixD *tmp = new TMatrixD(*matrix);
1795 objArray->AddAtAndExpand(tmp,objArray->GetLast());
1796 //cout << " !!! " << tmp << " " << tmp->GetUniqueID() << " " << tmp->GetNoElements() << endl;
1799 //__________________________________________________________________________
1800 void AliMUONTrackK::RemoveMatrices(Double_t zEnd)
1802 // Remove matrices (and saved steps) in the smoother part with abs(z) < abs(zEnd)
1804 for (Int_t i=fNSteps-1; i>=0; i--) {
1805 if (fgDebug > 1) printf("%10.4f %10.4f \n", (*fSteps)[i], zEnd);
1806 if (TMath::Abs((*fSteps)[i]) > TMath::Abs(zEnd) - 0.01) break;
1807 RemoveMatrices(this);
1808 } // for (Int_t i=fNSteps-1;
1811 //__________________________________________________________________________
1812 void AliMUONTrackK::RemoveMatrices(AliMUONTrackK* trackK)
1814 // Remove last saved matrices and steps in the smoother part
1817 Int_t i = trackK->fNSteps;
1820 // Delete only matrices not shared by several tracks
1821 id = trackK->fParExtrap->Last()->GetUniqueID();
1823 trackK->fParExtrap->Last()->SetUniqueID(id-1);
1824 trackK->fParExtrap->RemoveAt(i);
1826 else ((TMatrixD*)(trackK->fParExtrap->RemoveAt(i)))->Delete();
1827 id = fParFilter->Last()->GetUniqueID();
1829 trackK->fParFilter->Last()->SetUniqueID(id-1);
1830 trackK->fParFilter->RemoveAt(i);
1832 else ((TMatrixD*)(trackK->fParFilter->RemoveAt(i)))->Delete();
1833 id = trackK->fCovExtrap->Last()->GetUniqueID();
1835 trackK->fCovExtrap->Last()->SetUniqueID(id-1);
1836 trackK->fCovExtrap->RemoveAt(i);
1838 else ((TMatrixD*)(trackK->fCovExtrap->RemoveAt(i)))->Delete();
1839 id = trackK->fCovFilter->Last()->GetUniqueID();
1841 trackK->fCovFilter->Last()->SetUniqueID(id-1);
1842 trackK->fCovFilter->RemoveAt(i);
1844 else ((TMatrixD*)(trackK->fCovFilter->RemoveAt(i)))->Delete();
1845 id = trackK->fJacob->Last()->GetUniqueID();
1847 trackK->fJacob->Last()->SetUniqueID(id-1);
1848 trackK->fJacob->RemoveAt(i);
1850 else ((TMatrixD*)(trackK->fJacob->RemoveAt(i)))->Delete();
1853 //__________________________________________________________________________
1854 Bool_t AliMUONTrackK::Smooth(void)
1857 Int_t ihit = fNTrackHits - 1;
1858 AliMUONHitForRec *hit = (AliMUONHitForRec*) (*fTrackHitsPtr)[ihit];
1859 fChi2Smooth = new TArrayD(fNTrackHits);
1860 fChi2Smooth->Reset(-1);
1862 fParSmooth = new TObjArray(15);
1863 fParSmooth->Clear();
1866 cout << " ******** Enter Smooth " << endl;
1867 cout << (*fSteps)[fNSteps-1] << " " << fPosition << " " << fPositionNew << endl;
1869 for (Int_t i=fNSteps-1; i>=0; i--) cout << (*fSteps)[i] << " ";
1871 for (Int_t i=fNSteps-1; i>=0; i--) {cout << i << " " << (*fSteps)[i]; ((TMatrixD*)fParFilter->UncheckedAt(i))->Print(); ((TMatrixD*)fParExtrap->UncheckedAt(i))->Print(); ((TMatrixD*)fJacob->UncheckedAt(i))->Print();}
1873 for (Int_t i=ihit; i>=0; i--) cout << ((AliMUONHitForRec*)(*fTrackHitsPtr)[i])->GetZ() << " ";
1877 // Find last point corresponding to the last hit
1878 Int_t iLast = fNSteps - 1;
1879 for ( ; iLast>=0; iLast--) {
1880 //AZ(z->-z) if ((*fSteps)[iLast] + 0.01 > ((AliMUONHitForRec*)(*fTrackHitsPtr)[fNTrackHits-1])->GetZ()) break;
1881 if (TMath::Abs((*fSteps)[iLast]) + 0.01 > TMath::Abs(((AliMUONHitForRec*)(*fTrackHitsPtr)[fNTrackHits-1])->GetZ())) break;
1884 TMatrixD parSmooth = *((TMatrixD*)(fParFilter->UncheckedAt(iLast))); // last filtered = first smoothed
1886 TMatrixD covSmooth = *((TMatrixD*)(fCovFilter->UncheckedAt(iLast))); // last filtered = first smoothed
1887 TMatrixD tmp=covSmooth, weight=covSmooth, gain = covSmooth;
1888 TMatrixD tmpPar = *fTrackPar;
1889 //parSmooth.Print(); ((TMatrixD*)(fParExtrap->Last()))->Print();
1892 Double_t chi2max = 0;
1893 for (Int_t i=iLast+1; i>0; i--) {
1894 if (i == iLast + 1) goto L33; // temporary fix
1896 // Smoother gain matrix
1897 weight = *((TMatrixD*)(fCovExtrap->UncheckedAt(i)));
1898 if (weight.Determinant() != 0) {
1900 mnvertLocal(&(weight(0,0)), fgkSize,fgkSize,fgkSize,ifail);
1902 AliWarning(" Determinant weight=0:");
1905 tmp = TMatrixD(*((TMatrixD*)(fJacob->UncheckedAt(i))),TMatrixD::kTransposeMult,weight);
1906 gain = TMatrixD(*((TMatrixD*)(fCovFilter->UncheckedAt(i-1))),TMatrixD::kMult,tmp);
1907 //cout << (*fSteps)[i-1] << " " << (*fSteps)[i] << endl; gain.Print();
1909 // Smoothed parameter vector
1910 //((TMatrixD*)(fParExtrap->UncheckedAt(i)))->Dump();
1911 parSmooth -= *((TMatrixD*)(fParExtrap->UncheckedAt(i)));
1912 tmpPar = *((TMatrixD*)(fParFilter->UncheckedAt(i-1)));
1913 tmpPar += TMatrixD(gain,TMatrixD::kMult,parSmooth);
1916 // Smoothed covariance
1917 covSmooth -= *((TMatrixD*)(fCovExtrap->UncheckedAt(i)));
1918 weight = TMatrixD(TMatrixD::kTransposed,gain);
1919 tmp = TMatrixD(covSmooth,TMatrixD::kMult,weight);
1920 covSmooth = *((TMatrixD*)(fCovFilter->UncheckedAt(i-1)));
1921 covSmooth += TMatrixD(gain,TMatrixD::kMult,tmp);
1923 // Check if there was a measurement at given z
1925 for ( ; ihit>=0; ihit--) {
1926 hit = (AliMUONHitForRec*) (*fTrackHitsPtr)[ihit];
1927 if (TMath::Abs(hit->GetZ()-(*fSteps)[i-1]) < 0.1) { found = kTRUE; break; }
1928 //AZ(z->-z) else if (ihit < fNTrackHits-1 && hit->GetZ() > (*fSteps)[i-1]) { ihit++; break; }
1929 else if (ihit < fNTrackHits-1 && TMath::Abs(hit->GetZ()) > TMath::Abs((*fSteps)[i-1])) { ihit++; break; }
1931 if (!found) continue; // no measurement - skip the rest
1932 else if (fgDebug > 1) cout << i << " " << ihit << " " << hit->GetZ() << endl;
1933 if (ihit == 0) continue; // the first hit - skip the rest
1936 // Smoothed residuals
1938 tmpPar(0,0) = hit->GetBendingCoor() - parSmooth(0,0); // bending coordinate
1939 tmpPar(1,0) = hit->GetNonBendingCoor() - parSmooth(1,0); // non-bending coordinate
1941 cout << hit->GetBendingCoor() << " " << parSmooth(0,0) << " " << tmpPar(0,0) << endl;
1942 cout << hit->GetNonBendingCoor() << " " << parSmooth(1,0) << " " << tmpPar(1,0) << endl;
1944 // Cov. matrix of smoothed residuals
1946 tmp(0,0) = hit->GetBendingReso2() - covSmooth(0,0);
1947 tmp(1,1) = hit->GetNonBendingReso2() - covSmooth(1,1);
1948 tmp(0,1) = tmp(1,0) = -covSmooth(0,1);
1949 tmp(2,2) = tmp(3,3) = tmp(4,4) = 1;
1951 // Calculate Chi2 of smoothed residuals
1952 if (tmp.Determinant() != 0) {
1954 mnvertLocal(&(tmp(0,0)), fgkSize,fgkSize,fgkSize,ifail);
1956 AliWarning(" Determinant tmp=0:");
1958 TMatrixD vector(tmp,TMatrixD::kMult,tmpPar);
1959 TMatrixD chi2(tmpPar,TMatrixD::kTransposeMult,vector);
1960 if (fgDebug > 1) chi2.Print();
1961 (*fChi2Smooth)[ihit] = chi2(0,0);
1962 if (chi2(0,0) > chi2max) chi2max = chi2(0,0);
1964 if (chi2(0,0) < 0) {
1965 chi2.Print(); cout << " chi2 < 0 " << i << " " << iLast << endl;
1966 //AliFatal("chi2 < 0.");
1968 // Save smoothed parameters
1969 TMatrixD *par = new TMatrixD(parSmooth);
1970 fParSmooth->AddAtAndExpand(par, ihit);
1972 } // for (Int_t i=iLast+1;
1974 //if (chi2max > 16) {
1975 //if (chi2max > 25) {
1976 //if (chi2max > 50) {
1977 //if (chi2max > 100) {
1978 if (chi2max > fgkChi2max) {
1979 //if (Recover()) DropBranches();
1987 //__________________________________________________________________________
1988 void AliMUONTrackK::Outlier()
1990 // Adds new track with removed hit having the highest chi2
1993 cout << " ******** Enter Outlier " << endl;
1994 for (Int_t i=0; i<fNTrackHits; i++) printf("%10.4f", (*fChi2Smooth)[i]);
1996 for (Int_t i=0; i<fNTrackHits; i++) {
1997 printf("%10d", ((AliMUONHitForRec*)fTrackHitsPtr->UncheckedAt(i))->GetChamberNumber());
2002 Double_t chi2max = 0;
2004 for (Int_t i=0; i<fNTrackHits; i++) {
2005 if ((*fChi2Smooth)[i] < chi2max) continue;
2006 chi2max = (*fChi2Smooth)[i];
2009 // Check if the outlier is not from the seed segment
2010 AliMUONHitForRec *hit = (AliMUONHitForRec*) fTrackHitsPtr->UncheckedAt(imax);
2011 if (hit == fStartSegment->GetHitForRec1() || hit == fStartSegment->GetHitForRec2()) return; // to be changed probably
2013 // Check for missing station
2016 if (((AliMUONHitForRec*)fTrackHitsPtr->UncheckedAt(1))->GetChamberNumber() < 8) ok--;
2017 } else if (imax == fNTrackHits-1) {
2018 if (((AliMUONHitForRec*)fTrackHitsPtr->UncheckedAt(fNTrackHits-2))->GetChamberNumber() > 1) ok--;
2020 else if (((AliMUONHitForRec*)fTrackHitsPtr->UncheckedAt(imax-1))->GetChamberNumber()/2 - ((AliMUONHitForRec*)fTrackHitsPtr->UncheckedAt(imax+1))->GetChamberNumber()/2 > 1) ok--;
2021 if (!ok) { Recover(); return; } // try to recover track
2022 //AZ if (!ok) { if (fgDebug >= 0) cout << imax << endl; DropBranches(imax, 0); return; }
2024 // Remove saved steps and smoother matrices after the outlier
2025 RemoveMatrices(hit->GetZ());
2027 // Check for possible double track candidates
2028 //if (ExistDouble(hit)) return;
2030 TClonesArray *trackPtr = fgTrackReconstructor->GetRecTracksPtr();
2031 Int_t nRecTracks = fgTrackReconstructor->GetNRecTracks();
2033 AliMUONTrackK *trackK = 0;
2034 if (!fNSteps || GetStation0() == 3 && hit->GetChamberNumber() > 7) {
2035 // start track from segment
2036 trackK = new ((*trackPtr)[nRecTracks]) AliMUONTrackK(fStartSegment);
2037 fgTrackReconstructor->SetNRecTracks(nRecTracks+1);
2038 trackK->fRecover = 2;
2039 trackK->fSkipHit = hit;
2040 trackK->fNTrackHits = fNTrackHits;
2041 delete trackK->fTrackHitsPtr; // not efficient ?
2042 trackK->fTrackHitsPtr = new TObjArray(*fTrackHitsPtr);
2043 if (GetStation0() == 3) trackK->SortHits(1, trackK->fTrackHitsPtr);
2044 if (fgDebug > 0) cout << nRecTracks << " Outlier" << endl;
2047 trackK = new ((*trackPtr)[nRecTracks]) AliMUONTrackK(NULL, NULL);
2049 fgTrackReconstructor->SetNRecTracks(nRecTracks+1);
2050 //AZ(z->-z) trackK->fTrackDir = -1;
2051 trackK->fTrackDir = 1;
2052 trackK->fRecover = 2;
2053 trackK->fSkipHit = hit;
2054 Int_t iD = trackK->fParFilter->Last()->GetUniqueID();
2056 trackK->fParFilter->Last()->SetUniqueID(iD-1);
2057 CreateMatrix(trackK->fParFilter);
2059 trackK->fParFilter->Last()->SetUniqueID(iD);
2061 *((TMatrixD*)trackK->fParFilter->Last()) = *((TMatrixD*)fParExtrap->Last());
2062 *(trackK->fTrackPar) = *((TMatrixD*)trackK->fParFilter->Last());
2063 iD = trackK->fCovFilter->Last()->GetUniqueID();
2065 trackK->fCovFilter->Last()->SetUniqueID(iD-1);
2066 CreateMatrix(trackK->fCovFilter);
2068 trackK->fCovFilter->Last()->SetUniqueID(iD);
2070 *((TMatrixD*)trackK->fCovFilter->Last()) = *((TMatrixD*)fCovExtrap->Last());
2071 *(trackK->fWeight) = *((TMatrixD*)trackK->fCovFilter->Last());
2072 if (trackK->fWeight->Determinant() != 0) {
2074 mnvertLocal(&((*(trackK->fWeight))(0,0)), fgkSize,fgkSize,fgkSize,ifail);
2076 AliWarning(" Determinant fWeight=0:");
2078 trackK->fPosition = trackK->fPositionNew = (*fSteps)[fNSteps-1];
2080 for (Int_t i=0; i<fNTrackHits-1; i++) trackK->fChi2 += (*fChi2Array)[i];
2081 if (fgDebug > 0) cout << nRecTracks << " Outlier " << trackK->fChi2 << endl;
2084 //__________________________________________________________________________
2085 Double_t AliMUONTrackK::GetChi2PerPoint(Int_t iPoint) const
2087 // Return Chi2 at point
2088 return fChi2Smooth ? (*fChi2Smooth)[iPoint] : (*fChi2Array)[iPoint];
2092 //__________________________________________________________________________
2093 void AliMUONTrackK::Print(FILE *lun) const
2095 // Print out track information
2098 AliMUONHitForRec *hit = 0;
2099 if (fgTrackReconstructor->GetRecTrackRefHits()) {
2100 // from track ref. hits
2101 for (Int_t j=0; j<fNTrackHits; j++) {
2102 hit = (AliMUONHitForRec*) fTrackHitsPtr->UncheckedAt(j);
2103 if (hit->GetTTRTrack() > 1) { flag = 0; break; }
2105 for (Int_t j=0; j<fNTrackHits; j++) {
2106 printf("%10.4f", GetChi2PerPoint(j));
2107 if (GetChi2PerPoint(j) > -0.1) {
2108 hit = (AliMUONHitForRec*) fTrackHitsPtr->UncheckedAt(j);
2109 fprintf(lun,"%3d %3d %10.4f", gAlice->GetEvNumber(), hit->GetChamberNumber(), GetChi2PerPoint(j));
2110 fprintf(lun, "%3d %3d %3d \n", hit->GetTrackRefSignal(), hit->GetTTRTrack(), flag);
2115 // from raw clusters
2116 AliMUONRawCluster *clus = 0;
2117 TClonesArray *rawclusters = 0;
2118 for (Int_t i1=0; i1<fNTrackHits; i1++) {
2119 hit = (AliMUONHitForRec*) ((*fTrackHitsPtr)[i1]);
2120 rawclusters = fgTrackReconstructor->GetMUONData()->RawClusters(hit->GetChamberNumber());
2121 clus = (AliMUONRawCluster*) rawclusters->UncheckedAt(hit->GetHitNumber());
2122 if (TMath::Abs(clus->GetTrack(1)-1) < 2) {
2123 if (clus->GetTrack(2)) flag = 2;
2126 if (clus->GetTrack(2) && TMath::Abs(clus->GetTrack(2)-1) < 2) {
2133 Int_t sig[2]={1,1}, tid[2]={0};
2134 for (Int_t i1=0; i1<fNTrackHits; i1++) {
2135 if (GetChi2PerPoint(i1) < -0.1) continue;
2136 hit = (AliMUONHitForRec*) ((*fTrackHitsPtr)[i1]);
2137 rawclusters = fgTrackReconstructor->GetMUONData()->RawClusters(hit->GetChamberNumber());
2138 clus = (AliMUONRawCluster*) rawclusters->UncheckedAt(hit->GetHitNumber());
2139 for (Int_t j=0; j<2; j++) {
2140 tid[j] = clus->GetTrack(j+1) - 1;
2141 if (clus->GetTrack(j+1) < 0) { sig[j] = 0; tid[j] = 999; }
2143 fprintf(lun,"%3d %3d %10.4f", gAlice->GetEvNumber(), hit->GetChamberNumber(), GetChi2PerPoint(i1));
2144 if (!(clus->GetTrack(2))) fprintf(lun, "%3d %3d", sig[0], tid[0]); // simple cluster
2145 else { // track overlap
2146 fprintf(lun, "%3d %3d", TMath::Max(sig[0],sig[1]), TMath::Min(tid[0],tid[1]));
2147 //if (tid[0] < 2) flag *= 2;
2148 //else if (tid[1] < 2) flag *= 3;
2150 fprintf (lun, "%3d \n", flag);
2155 //__________________________________________________________________________
2156 void AliMUONTrackK::DropBranches(Int_t imax, TObjArray *hits)
2158 // Drop branches downstream of the skipped hit
2160 TClonesArray *trackPtr;
2161 AliMUONTrackK *trackK;
2163 trackPtr = fgTrackReconstructor->GetRecTracksPtr();
2164 nRecTracks = fgTrackReconstructor->GetNRecTracks();
2165 Int_t icand = trackPtr->IndexOf(this);
2166 if (!hits) hits = fTrackHitsPtr;
2168 // Check if the track candidate doesn't exist yet
2169 for (Int_t i=icand+1; i<nRecTracks; i++) {
2170 trackK = (AliMUONTrackK*) ((*trackPtr)[i]);
2171 if (trackK->fNTrackHits == 2 && trackK->GetRecover() == 0) continue;
2172 if (trackK->GetRecover() < 0) continue;
2174 if (trackK->fNTrackHits >= imax + 1) {
2175 for (Int_t j=0; j<=imax; j++) {
2176 //if (j != fNTrackHits-1 && (*trackK->fTrackHitsPtr)[j] != (*fTrackHitsPtr)[j]) break;
2177 if ((*trackK->fTrackHitsPtr)[j] != (*hits)[j]) break;
2179 if (hits != fTrackHitsPtr) {
2180 // Drop all branches downstream the hit (for Recover)
2181 trackK->SetRecover(-1);
2182 if (fgDebug >= 0 )cout << " Recover " << i << endl;
2185 // Check if the removal of the hit breaks the track
2188 if (((AliMUONHitForRec*)trackK->fTrackHitsPtr->UncheckedAt(1))->GetChamberNumber() < 8) ok--; }
2189 else if (imax == trackK->fNTrackHits-1) continue;
2190 // else if (imax == trackK->fNTrackHits-1) {
2191 //if (((AliMUONHitForRec*)trackK->fTrackHitsPtr->UncheckedAt(trackK->fNTrackHits-2))->GetChamberNumber() > 1) ok--;
2193 else if (((AliMUONHitForRec*)trackK->fTrackHitsPtr->UncheckedAt(imax-1))->GetChamberNumber()/2 - ((AliMUONHitForRec*)trackK->fTrackHitsPtr->UncheckedAt(imax+1))->GetChamberNumber()/2 > 1) ok--;
2194 if (!ok) trackK->SetRecover(-1);
2196 } // for (Int_t j=0;
2198 } // for (Int_t i=0;
2201 //__________________________________________________________________________
2202 void AliMUONTrackK::DropBranches(AliMUONSegment *segment)
2204 // Drop all candidates with the same seed segment
2206 TClonesArray *trackPtr;
2207 AliMUONTrackK *trackK;
2209 trackPtr = fgTrackReconstructor->GetRecTracksPtr();
2210 nRecTracks = fgTrackReconstructor->GetNRecTracks();
2211 Int_t icand = trackPtr->IndexOf(this);
2213 for (Int_t i=icand+1; i<nRecTracks; i++) {
2214 trackK = (AliMUONTrackK*) ((*trackPtr)[i]);
2215 if (trackK->fNTrackHits == 2 && trackK->GetRecover() == 0) continue;
2216 if (trackK->GetRecover() < 0) continue;
2217 if (trackK->fStartSegment == segment) trackK->SetRecover(-1);
2219 if (fgDebug >= 0) cout << " Drop segment " << endl;
2222 //__________________________________________________________________________
2223 AliMUONHitForRec* AliMUONTrackK::GetHitLastOk(void)
2225 // Return the hit where track stopped
2227 if (!fNSteps) return (AliMUONHitForRec*)((*fTrackHitsPtr)[1]);
2231 //__________________________________________________________________________
2232 Int_t AliMUONTrackK::GetStation0(void)
2234 // Return seed station number
2235 return fStartSegment->GetHitForRec1()->GetChamberNumber() / 2;
2238 //__________________________________________________________________________
2239 Bool_t AliMUONTrackK::ExistDouble(AliMUONHitForRec *hit)
2241 // Check if the track will make a double after outlier removal
2243 TClonesArray *trackPtr = fgTrackReconstructor->GetRecTracksPtr();
2244 Int_t nRecTracks = fgTrackReconstructor->GetNRecTracks();
2245 TObjArray *hitArray = new TObjArray(*fTrackHitsPtr);
2246 TObjArray *hitArray1 = new TObjArray(*hitArray);
2247 hitArray1->Remove(hit);
2248 hitArray1->Compress();
2250 Bool_t same = kFALSE;
2251 for (Int_t i=0; i<nRecTracks; i++) {
2252 AliMUONTrackK *trackK = (AliMUONTrackK*) ((*trackPtr)[i]);
2253 if (trackK->fNTrackHits == 2 && trackK->GetRecover() == 0) continue;
2254 if (trackK == this) continue;
2255 if (trackK->fNTrackHits == fNTrackHits || trackK->fNTrackHits == fNTrackHits-1) {
2256 TObjArray *hits = new TObjArray(*trackK->fTrackHitsPtr);
2258 if (trackK->fNTrackHits == fNTrackHits) {
2259 for (Int_t j=0; j<fNTrackHits; j++) {
2260 if (hits->UncheckedAt(j) != hitArray->UncheckedAt(j)) { same = kFALSE; break; }
2262 if (same) { delete hits; break; }
2263 if (trackK->fSkipHit) {
2264 TObjArray *hits1 = new TObjArray(*hits);
2265 if (hits1->Remove(trackK->fSkipHit) > 0) {
2268 for (Int_t j=0; j<fNTrackHits-1; j++) {
2269 if (hits1->UncheckedAt(j) != hitArray1->UncheckedAt(j)) { same = kFALSE; break; }
2271 if (same) { delete hits1; break; }
2276 // Check with removed outlier
2278 for (Int_t j=0; j<fNTrackHits-1; j++) {
2279 if (hits->UncheckedAt(j) != hitArray1->UncheckedAt(j)) { same = kFALSE; break; }
2281 if (same) { delete hits; break; }
2285 } // for (Int_t i=0; i<nRecTracks;
2286 delete hitArray; delete hitArray1;
2287 if (same && fgDebug >= 0) cout << " Same" << endl;
2291 //__________________________________________________________________________
2292 Bool_t AliMUONTrackK::ExistDouble(void)
2294 // Check if the track will make a double after recovery
2296 TClonesArray *trackPtr = fgTrackReconstructor->GetRecTracksPtr();
2297 Int_t nRecTracks = fgTrackReconstructor->GetNRecTracks();
2299 TObjArray *hitArray = new TObjArray(*fTrackHitsPtr);
2300 if (GetStation0() == 3) SortHits(0, hitArray); // sort
2301 //if (GetStation0() == 3) SortHits(1, hitArray); // unsort
2303 Bool_t same = kFALSE;
2304 for (Int_t i=0; i<nRecTracks; i++) {
2305 AliMUONTrackK *trackK = (AliMUONTrackK*) ((*trackPtr)[i]);
2306 if (trackK->fNTrackHits == 2 && trackK->GetRecover() == 0) continue;
2307 if (trackK == this) continue;
2308 //AZ if (trackK->GetRecover() < 0) continue; //
2309 if (trackK->fNTrackHits >= fNTrackHits) {
2310 TObjArray *hits = new TObjArray(*trackK->fTrackHitsPtr);
2311 if (trackK->GetStation0() == 3) SortHits(0, hits); // sort
2312 //if (trackK->GetStation0() == 3) SortHits(1, hits); // unsort
2313 for (Int_t j=0; j<fNTrackHits; j++) {
2314 //cout << fNTrackHits << " " << i << " " << j << " " << (*hitArray)[j] << " " << (*hits)[j] << " " << trackK->fSkipHit << endl;
2315 if (j != fNTrackHits-1 && (*hitArray)[j] != (*hits)[j]) break;
2316 if (j == fNTrackHits-1) {
2317 if (trackK->fSkipHit && TMath::Abs(((AliMUONHitForRec*)((*hitArray)[j]))->GetZ()-trackK->fSkipHit->GetZ()) < 0.5) same = kTRUE;
2318 //if (trackK->fNTrackHits > fNTrackHits &&
2319 //if (trackK->fSkipHit) cout << ((AliMUONHitForRec*)((*hitArray)[j]))->GetZ() << " " << trackK->fSkipHit->GetZ() << endl;
2321 } // for (Int_t j=0;
2325 } // for (Int_t i=0;