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 ///////////////////////////////////////////////////////////////////////////////
20 // The standard TRD tracker //
22 ///////////////////////////////////////////////////////////////////////////////
24 #include <Riostream.h>
28 #include <TObjArray.h>
30 #include "AliTRDgeometry.h"
31 #include "AliTRDparameter.h"
32 #include "AliTRDpadPlane.h"
33 #include "AliTRDgeometryDetail.h"
34 #include "AliTRDcluster.h"
35 #include "AliTRDtrack.h"
38 #include "TTreeStream.h"
40 #include "AliTRDtracker.h"
44 ClassImp(AliTRDtracker)
46 const Float_t AliTRDtracker::fgkSeedDepth = 0.5;
47 const Float_t AliTRDtracker::fgkSeedStep = 0.10;
48 const Float_t AliTRDtracker::fgkSeedGap = 0.25;
50 const Float_t AliTRDtracker::fgkMaxSeedDeltaZ12 = 40.;
51 const Float_t AliTRDtracker::fgkMaxSeedDeltaZ = 25.;
52 const Float_t AliTRDtracker::fgkMaxSeedC = 0.0052;
53 const Float_t AliTRDtracker::fgkMaxSeedTan = 1.2;
54 const Float_t AliTRDtracker::fgkMaxSeedVertexZ = 150.;
56 const Double_t AliTRDtracker::fgkSeedErrorSY = 0.2;
57 const Double_t AliTRDtracker::fgkSeedErrorSY3 = 2.5;
58 const Double_t AliTRDtracker::fgkSeedErrorSZ = 0.1;
60 const Float_t AliTRDtracker::fgkMinClustersInSeed = 0.7;
62 const Float_t AliTRDtracker::fgkMinClustersInTrack = 0.5;
63 const Float_t AliTRDtracker::fgkMinFractionOfFoundClusters = 0.8;
65 const Float_t AliTRDtracker::fgkSkipDepth = 0.3;
66 const Float_t AliTRDtracker::fgkLabelFraction = 0.8;
67 const Float_t AliTRDtracker::fgkWideRoad = 20.;
69 const Double_t AliTRDtracker::fgkMaxChi2 = 12.;
71 // const Double_t AliTRDtracker::fgkOffset = -0.012;
72 // const Double_t AliTRDtracker::fgkOffsetX = 0.35;
73 // const Double_t AliTRDtracker::fgkCoef = 0.00;
74 // const Double_t AliTRDtracker::fgkMean = 8.;
75 // const Double_t AliTRDtracker::fgkDriftCorrection = 1.07;
76 // const Double_t AliTRDtracker::fgkExB = 0.072;
78 const Double_t AliTRDtracker::fgkOffset = -0.015;
79 const Double_t AliTRDtracker::fgkOffsetX = 0.26; // "time offset"
80 const Double_t AliTRDtracker::fgkCoef = 0.0096; // angular shift
81 const Double_t AliTRDtracker::fgkMean = 0.;
82 const Double_t AliTRDtracker::fgkDriftCorrection = 1.04; // drift coefficient correction
83 const Double_t AliTRDtracker::fgkExB = 0.072; // ExB angle - for error parameterization
86 // poscorrection = fgkCoef*(GetLocalTimeBin() - fgkMean)+fgkOffset;
88 const Int_t AliTRDtracker::fgkFirstPlane = 5;
89 const Int_t AliTRDtracker::fgkLastPlane = 17;
91 //____________________________________________________________________
92 AliTRDtracker::AliTRDtracker():AliTracker(),
103 fTimeBinsPerPlane(0),
106 fAddTRDseeds(kFALSE),
109 // Default constructor
111 for(Int_t i=0;i<kTrackingSectors;i++) fTrSec[i]=0;
112 for(Int_t j=0;j<5;j++)
113 for(Int_t k=0;k<18;k++) fHoles[j][k]=kFALSE;
116 //____________________________________________________________________
117 AliTRDtracker::AliTRDtracker(const TFile *geomfile):AliTracker()
123 //Float_t fTzero = 0;
125 fAddTRDseeds = kFALSE;
129 TDirectory *savedir=gDirectory;
130 TFile *in=(TFile*)geomfile;
132 printf("AliTRDtracker::AliTRDtracker(): geometry file is not open!\n");
133 printf(" DETAIL TRD geometry and DEFAULT TRD parameter will be used\n");
138 fGeom = (AliTRDgeometry*) in->Get("TRDgeometry");
139 fPar = (AliTRDparameter*) in->Get("TRDparameter");
144 // fTzero = geo->GetT0();
145 // printf("Found geometry version %d on file \n", fGeom->IsVersion());
148 printf("AliTRDtracker::AliTRDtracker(): can't find TRD geometry!\n");
149 //printf("The DETAIL TRD geometry will be used\n");
150 //fGeom = new AliTRDgeometryDetail();
151 fGeom = new AliTRDgeometryDetail();
152 fGeom->SetPHOShole();
153 fGeom->SetRICHhole();
157 printf("AliTRDtracker::AliTRDtracker(): can't find TRD parameter!\n");
158 printf("The DEFAULT TRD parameter will be used\n");
159 fPar = new AliTRDparameter("Pica","Vyjebana");
161 fPar = new AliTRDparameter("Pica","Vyjebana");
167 // fGeom->SetT0(fTzero);
170 fClusters = new TObjArray(2000);
172 fSeeds = new TObjArray(2000);
174 fTracks = new TObjArray(1000);
176 for(Int_t geomS = 0; geomS < kTrackingSectors; geomS++) {
177 Int_t trS = CookSectorIndex(geomS);
178 fTrSec[trS] = new AliTRDtrackingSector(fGeom, geomS, fPar);
179 for (Int_t icham=0;icham<AliTRDgeometry::kNcham; icham++){
180 fHoles[icham][trS]=fGeom->IsHole(0,icham,geomS);
183 AliTRDpadPlane *padPlane = fPar->GetPadPlane(0,0);
184 Float_t tiltAngle = TMath::Abs(padPlane->GetTiltingAngle());
185 // Float_t tiltAngle = TMath::Abs(fPar->GetTiltingAngle());
186 if(tiltAngle < 0.1) {
193 if(fNoTilt && (tiltAngle > 0.1)) fSY2corr = fSY2corr + tiltAngle * 0.05;
196 // calculate max gap on track
198 Double_t dxAmp = (Double_t) fGeom->CamHght(); // Amplification region
199 Double_t dxDrift = (Double_t) fGeom->CdrHght(); // Drift region
201 Double_t dx = fgkDriftCorrection*(Double_t) fPar->GetDriftVelocity()
202 / fPar->GetSamplingFrequency();
204 Int_t tbAmp = fPar->GetTimeBefore();
205 Int_t maxAmp = (Int_t) ((dxAmp+0.000001)/dx);
206 if(kTRUE) maxAmp = 0; // intentional until we change the parameter class
207 Int_t tbDrift = fPar->GetTimeMax();
208 Int_t maxDrift = (Int_t) ((dxDrift+0.000001)/dx)+4; // MI change - take also last time bins
210 tbDrift = TMath::Min(tbDrift,maxDrift);
211 tbAmp = TMath::Min(tbAmp,maxAmp);
213 fTimeBinsPerPlane = tbAmp + tbDrift;
214 fMaxGap = (Int_t) (fTimeBinsPerPlane * fGeom->Nplan() * fgkSkipDepth);
218 fDebugStreamer = new TTreeSRedirector("TRDdebug.root");
223 //___________________________________________________________________
224 AliTRDtracker::~AliTRDtracker()
227 // Destructor of AliTRDtracker
245 for(Int_t geomS = 0; geomS < kTrackingSectors; geomS++) {
246 delete fTrSec[geomS];
248 if (fDebugStreamer) {
249 //fDebugStreamer->Close();
250 delete fDebugStreamer;
254 //_____________________________________________________________________
256 Bool_t AliTRDtracker::AdjustSector(AliTRDtrack *track) {
258 // Rotates the track when necessary
261 Double_t alpha = AliTRDgeometry::GetAlpha();
262 Double_t y = track->GetY();
263 Double_t ymax = track->GetX()*TMath::Tan(0.5*alpha);
265 //Int_t ns = AliTRDgeometry::kNsect;
266 //Int_t s=Int_t(track->GetAlpha()/alpha)%ns;
270 if (!track->Rotate(alpha)) return kFALSE;
271 } else if (y <-ymax) {
273 if (!track->Rotate(-alpha)) return kFALSE;
279 //_____________________________________________________________________
280 inline Double_t f1trd(Double_t x1,Double_t y1,
281 Double_t x2,Double_t y2,
282 Double_t x3,Double_t y3)
285 // Initial approximation of the track curvature
287 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
288 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
289 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
290 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
291 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
293 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
295 return -xr*yr/sqrt(xr*xr+yr*yr);
298 //_____________________________________________________________________
299 inline Double_t f2trd(Double_t x1,Double_t y1,
300 Double_t x2,Double_t y2,
301 Double_t x3,Double_t y3)
304 // Initial approximation of the track curvature times X coordinate
305 // of the center of curvature
308 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
309 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
310 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
311 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
312 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
314 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
316 return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr);
319 //_____________________________________________________________________
320 inline Double_t f3trd(Double_t x1,Double_t y1,
321 Double_t x2,Double_t y2,
322 Double_t z1,Double_t z2)
325 // Initial approximation of the tangent of the track dip angle
328 return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
332 AliTRDcluster * AliTRDtracker::GetCluster(AliTRDtrack * track, Int_t plane, Int_t timebin, UInt_t &index){
334 //try to find cluster in the backup list
336 AliTRDcluster * cl =0;
337 UInt_t *indexes = track->GetBackupIndexes();
338 for (UInt_t i=0;i<kMaxTimeBinIndex;i++){
339 if (indexes[i]==0) break;
340 AliTRDcluster * cli = (AliTRDcluster*)fClusters->UncheckedAt(indexes[i]);
342 if (cli->GetLocalTimeBin()!=timebin) continue;
343 Int_t iplane = fGeom->GetPlane(cli->GetDetector());
354 Int_t AliTRDtracker::GetLastPlane(AliTRDtrack * track){
356 //return last updated plane
358 UInt_t *indexes = track->GetBackupIndexes();
359 for (UInt_t i=0;i<kMaxTimeBinIndex;i++){
360 AliTRDcluster * cli = (AliTRDcluster*)fClusters->UncheckedAt(indexes[i]);
362 Int_t iplane = fGeom->GetPlane(cli->GetDetector());
363 if (iplane>lastplane) {
369 //___________________________________________________________________
370 Int_t AliTRDtracker::Clusters2Tracks(AliESD* event)
373 // Finds tracks within the TRD. The ESD event is expected to contain seeds
374 // at the outer part of the TRD. The seeds
375 // are found within the TRD if fAddTRDseeds is TRUE.
376 // The tracks are propagated to the innermost time bin
377 // of the TRD and the ESD event is updated
380 Int_t timeBins = fTrSec[0]->GetNumberOfTimeBins();
381 Float_t foundMin = fgkMinClustersInTrack * timeBins;
384 Int_t innerTB = fTrSec[0]->GetInnerTimeBin();
386 Int_t n = event->GetNumberOfTracks();
387 for (Int_t i=0; i<n; i++) {
388 AliESDtrack* seed=event->GetTrack(i);
389 ULong_t status=seed->GetStatus();
390 if ( (status & AliESDtrack::kTRDout ) == 0 ) continue;
391 if ( (status & AliESDtrack::kTRDin) != 0 ) continue;
394 AliTRDtrack* seed2 = new AliTRDtrack(*seed);
395 //seed2->ResetCovariance();
396 AliTRDtrack *pt = new AliTRDtrack(*seed2,seed2->GetAlpha());
398 FollowProlongation(t, innerTB);
399 if (t.GetNumberOfClusters() >= foundMin) {
401 CookLabel(pt, 1-fgkLabelFraction);
405 // cout<<found<<'\r';
407 if(PropagateToTPC(t)) {
408 seed->UpdateTrackParams(pt, AliESDtrack::kTRDin);
414 cout<<"Number of loaded seeds: "<<nseed<<endl;
415 cout<<"Number of found tracks from loaded seeds: "<<found<<endl;
417 // after tracks from loaded seeds are found and the corresponding
418 // clusters are used, look for additional seeds from TRD
421 // Find tracks for the seeds in the TRD
422 Int_t timeBins = fTrSec[0]->GetNumberOfTimeBins();
424 Int_t nSteps = (Int_t) (fgkSeedDepth / fgkSeedStep);
425 Int_t gap = (Int_t) (timeBins * fgkSeedGap);
426 Int_t step = (Int_t) (timeBins * fgkSeedStep);
428 // make a first turn with tight cut on initial curvature
429 for(Int_t turn = 1; turn <= 2; turn++) {
431 nSteps = (Int_t) (fgkSeedDepth / (3*fgkSeedStep));
432 step = (Int_t) (timeBins * (3*fgkSeedStep));
434 for(Int_t i=0; i<nSteps; i++) {
435 Int_t outer=timeBins-1-i*step;
436 Int_t inner=outer-gap;
438 nseed=fSeeds->GetEntriesFast();
440 MakeSeeds(inner, outer, turn);
442 nseed=fSeeds->GetEntriesFast();
443 // printf("\n turn %d, step %d: number of seeds for TRD inward %d\n",
446 for (Int_t i=0; i<nseed; i++) {
447 AliTRDtrack *pt=(AliTRDtrack*)fSeeds->UncheckedAt(i), &t=*pt;
448 FollowProlongation(t,innerTB);
449 if (t.GetNumberOfClusters() >= foundMin) {
451 CookLabel(pt, 1-fgkLabelFraction);
454 // cout<<found<<'\r';
455 if(PropagateToTPC(t)) {
457 track.UpdateTrackParams(pt,AliESDtrack::kTRDin);
458 event->AddTrack(&track);
459 // track.SetTRDtrack(new AliTRDtrack(*pt));
462 delete fSeeds->RemoveAt(i);
469 cout<<"Total number of found tracks: "<<found<<endl;
476 //_____________________________________________________________________________
477 Int_t AliTRDtracker::PropagateBack(AliESD* event) {
479 // Gets seeds from ESD event. The seeds are AliTPCtrack's found and
480 // backpropagated by the TPC tracker. Each seed is first propagated
481 // to the TRD, and then its prolongation is searched in the TRD.
482 // If sufficiently long continuation of the track is found in the TRD
483 // the track is updated, otherwise it's stored as originaly defined
484 // by the TPC tracker.
488 Float_t foundMin = 20;
489 Int_t n = event->GetNumberOfTracks();
492 Float_t *quality =new Float_t[n];
493 Int_t *index =new Int_t[n];
494 for (Int_t i=0; i<n; i++) {
495 AliESDtrack* seed=event->GetTrack(i);
496 Double_t covariance[15];
497 seed->GetExternalCovariance(covariance);
498 quality[i] = covariance[0]+covariance[2];
500 TMath::Sort(n,quality,index,kFALSE);
502 for (Int_t i=0; i<n; i++) {
503 // AliESDtrack* seed=event->GetTrack(i);
504 AliESDtrack* seed=event->GetTrack(index[i]);
506 ULong_t status=seed->GetStatus();
507 if ( (status & AliESDtrack::kTPCout ) == 0 ) continue;
508 if ( (status & AliESDtrack::kTRDout) != 0 ) continue;
510 Int_t lbl = seed->GetLabel();
511 AliTRDtrack *track = new AliTRDtrack(*seed);
512 track->SetSeedLabel(lbl);
513 seed->UpdateTrackParams(track, AliESDtrack::kTRDbackup); //make backup
515 Float_t p4 = track->GetC();
517 Int_t expectedClr = FollowBackProlongationG(*track);
519 // only debug purpose
520 if (track->GetNumberOfClusters()<expectedClr/3){
521 AliTRDtrack *track1 = new AliTRDtrack(*seed);
522 track1->SetSeedLabel(lbl);
523 FollowBackProlongation(*track1);
524 AliTRDtrack *track2= new AliTRDtrack(*seed);
525 track->SetSeedLabel(lbl);
526 FollowBackProlongation(*track2);
531 if (TMath::Abs(track->GetC()-p4)/TMath::Abs(p4)<0.2 || TMath::Abs(track->GetPt())>0.8 ) {
533 //make backup for back propagation
535 Int_t foundClr = track->GetNumberOfClusters();
536 if (foundClr >= foundMin) {
538 CookdEdxTimBin(*track);
539 CookLabel(track, 1-fgkLabelFraction);
540 if(track->GetChi2()/track->GetNumberOfClusters()<4) { // sign only gold tracks
541 if (seed->GetKinkIndex(0)==0&&TMath::Abs(track->GetPt())<1.5 ) UseClusters(track);
543 Bool_t isGold = kFALSE;
545 if (track->GetChi2()/track->GetNumberOfClusters()<5) { //full gold track
546 // seed->UpdateTrackParams(track, AliESDtrack::kTRDbackup);
547 if (track->GetBackupTrack()) seed->UpdateTrackParams(track->GetBackupTrack(), AliESDtrack::kTRDbackup);
550 if (!isGold && track->GetNCross()==0&&track->GetChi2()/track->GetNumberOfClusters()<7){ //almost gold track
551 // seed->UpdateTrackParams(track, AliESDtrack::kTRDbackup);
552 if (track->GetBackupTrack()) seed->UpdateTrackParams(track->GetBackupTrack(), AliESDtrack::kTRDbackup);
555 if (!isGold && track->GetBackupTrack()){
556 if (track->GetBackupTrack()->GetNumberOfClusters()>foundMin&&
557 (track->GetBackupTrack()->GetChi2()/(track->GetBackupTrack()->GetNumberOfClusters()+1))<7){
558 seed->UpdateTrackParams(track->GetBackupTrack(), AliESDtrack::kTRDbackup);
562 if (track->StatusForTOF()>0 &&track->fNCross==0 && Float_t(track->fN)/Float_t(track->fNExpected)>0.4){
563 seed->UpdateTrackParams(track, AliESDtrack::kTRDbackup);
569 // Debug part of tracking
570 TTreeSRedirector& cstream = *fDebugStreamer;
571 Int_t eventNr = event->GetEventNumber();
572 if (track->GetBackupTrack()){
574 "EventNr="<<eventNr<<
577 "trdback.="<<track->GetBackupTrack()<<
581 "EventNr="<<eventNr<<
588 //Propagation to the TOF (I.Belikov)
589 if (track->GetStop()==kFALSE){
592 Double_t c2=track->GetC()*xtof - track->GetEta();
593 if (TMath::Abs(c2)>=0.99) {
597 Double_t xTOF0 = 365. ;
598 PropagateToOuterPlane(*track,xTOF0);
600 //energy losses taken to the account - check one more time
601 c2=track->GetC()*xtof - track->GetEta();
602 if (TMath::Abs(c2)>=0.99) {
608 Double_t ymax=xtof*TMath::Tan(0.5*AliTRDgeometry::GetAlpha());
609 Double_t y=track->GetYat(xtof);
611 if (!track->Rotate(AliTRDgeometry::GetAlpha())) {
615 } else if (y <-ymax) {
616 if (!track->Rotate(-AliTRDgeometry::GetAlpha())) {
622 if (track->PropagateTo(xtof)) {
623 seed->UpdateTrackParams(track, AliESDtrack::kTRDout);
624 for (Int_t i=0;i<kNPlane;i++) {
625 seed->SetTRDsignals(track->GetPIDsignals(i),i);
626 seed->SetTRDTimBin(track->GetPIDTimBin(i),i);
628 // seed->SetTRDtrack(new AliTRDtrack(*track));
629 if (track->GetNumberOfClusters()>foundMin) found++;
632 if (track->GetNumberOfClusters()>15&&track->GetNumberOfClusters()>0.5*expectedClr){
633 seed->UpdateTrackParams(track, AliESDtrack::kTRDout);
634 //seed->SetStatus(AliESDtrack::kTRDStop);
635 for (Int_t i=0;i<kNPlane;i++) {
636 seed->SetTRDsignals(track->GetPIDsignals(i),i);
637 seed->SetTRDTimBin(track->GetPIDTimBin(i),i);
639 //seed->SetTRDtrack(new AliTRDtrack(*track));
643 seed->SetTRDQuality(track->StatusForTOF());
644 seed->SetTRDBudget(track->fBudget[0]);
648 //End of propagation to the TOF
649 //if (foundClr>foundMin)
650 // seed->UpdateTrackParams(track, AliESDtrack::kTRDout);
655 cerr<<"Number of seeds: "<<fNseeds<<endl;
656 cerr<<"Number of back propagated TRD tracks: "<<found<<endl;
658 // MakeSeedsMI(3,5); //new seeding
661 fSeeds->Clear(); fNseeds=0;
669 //_____________________________________________________________________________
670 Int_t AliTRDtracker::RefitInward(AliESD* event)
673 // Refits tracks within the TRD. The ESD event is expected to contain seeds
674 // at the outer part of the TRD.
675 // The tracks are propagated to the innermost time bin
676 // of the TRD and the ESD event is updated
677 // Origin: Thomas KUHR (Thomas.Kuhr@cern.ch)
680 Int_t timeBins = fTrSec[0]->GetNumberOfTimeBins();
681 Float_t foundMin = fgkMinClustersInTrack * timeBins;
684 Int_t innerTB = fTrSec[0]->GetInnerTimeBin();
687 Int_t n = event->GetNumberOfTracks();
688 for (Int_t i=0; i<n; i++) {
689 AliESDtrack* seed=event->GetTrack(i);
690 new(&seed2) AliTRDtrack(*seed);
691 if (seed2.GetX()<270){
692 seed->UpdateTrackParams(&seed2, AliESDtrack::kTRDbackup); // backup TPC track - only update
696 ULong_t status=seed->GetStatus();
697 if ( (status & AliESDtrack::kTRDout ) == 0 ) {
700 if ( (status & AliESDtrack::kTRDin) != 0 ) {
704 // if (1/seed2.Get1Pt()>1.5&& seed2.GetX()>260.) {
705 // Double_t oldx = seed2.GetX();
706 // seed2.PropagateTo(500.);
707 // seed2.ResetCovariance(1.);
708 // seed2.PropagateTo(oldx);
711 // seed2.ResetCovariance(5.);
714 AliTRDtrack *pt = new AliTRDtrack(seed2,seed2.GetAlpha());
715 UInt_t * indexes2 = seed2.GetIndexes();
716 for (Int_t i=0;i<kNPlane;i++) {
717 pt->SetPIDsignals(seed2.GetPIDsignals(i),i);
718 pt->SetPIDTimBin(seed2.GetPIDTimBin(i),i);
721 UInt_t * indexes3 = pt->GetBackupIndexes();
722 for (Int_t i=0;i<200;i++) {
723 if (indexes2[i]==0) break;
724 indexes3[i] = indexes2[i];
726 //AliTRDtrack *pt = seed2;
728 FollowProlongationG(t, innerTB);
729 if (t.GetNumberOfClusters() >= foundMin) {
731 //CookLabel(pt, 1-fgkLabelFraction);
736 // cout<<found<<'\r';
738 if(PropagateToTPC(t)) {
739 seed->UpdateTrackParams(pt, AliESDtrack::kTRDrefit);
740 for (Int_t i=0;i<kNPlane;i++) {
741 seed->SetTRDsignals(pt->GetPIDsignals(i),i);
742 seed->SetTRDTimBin(pt->GetPIDTimBin(i),i);
745 //if not prolongation to TPC - propagate without update
746 AliTRDtrack* seed2 = new AliTRDtrack(*seed);
747 seed2->ResetCovariance(5.);
748 AliTRDtrack *pt2 = new AliTRDtrack(*seed2,seed2->GetAlpha());
750 if (PropagateToTPC(*pt2)) {
751 pt2->CookdEdx(0.,1.);
752 CookdEdxTimBin(*pt2);
753 seed->UpdateTrackParams(pt2, AliESDtrack::kTRDrefit);
754 for (Int_t i=0;i<kNPlane;i++) {
755 seed->SetTRDsignals(pt2->GetPIDsignals(i),i);
756 seed->SetTRDTimBin(pt2->GetPIDTimBin(i),i);
764 cout<<"Number of loaded seeds: "<<nseed<<endl;
765 cout<<"Number of found tracks from loaded seeds: "<<found<<endl;
772 //---------------------------------------------------------------------------
773 Int_t AliTRDtracker::FollowProlongation(AliTRDtrack& t, Int_t rf)
775 // Starting from current position on track=t this function tries
776 // to extrapolate the track up to timeBin=0 and to confirm prolongation
777 // if a close cluster is found. Returns the number of clusters
778 // expected to be found in sensitive layers
780 Float_t wIndex, wTB, wChi2;
781 Float_t wYrt, wYclosest, wYcorrect, wYwindow;
782 Float_t wZrt, wZclosest, wZcorrect, wZwindow;
783 Float_t wPx, wPy, wPz, wC;
785 Float_t wSigmaC2, wSigmaTgl2, wSigmaY2, wSigmaZ2;
786 Int_t lastplane = GetLastPlane(&t);
787 Double_t dxsample = fgkDriftCorrection*(Double_t) fPar->GetDriftVelocity()
788 / fPar->GetSamplingFrequency();
789 Int_t trackIndex = t.GetLabel();
791 Int_t ns=Int_t(2*TMath::Pi()/AliTRDgeometry::GetAlpha()+0.5);
793 Int_t tryAgain=fMaxGap;
795 Double_t alpha=t.GetAlpha();
796 alpha = TVector2::Phi_0_2pi(alpha);
798 Int_t s=Int_t(alpha/AliTRDgeometry::GetAlpha())%AliTRDgeometry::kNsect;
799 Double_t radLength, rho, x, dx, y, ymax, z;
801 Int_t expectedNumberOfClusters = 0;
802 Bool_t lookForCluster;
804 alpha=AliTRDgeometry::GetAlpha(); // note: change in meaning
807 for (Int_t nr=fTrSec[0]->GetLayerNumber(t.GetX()); nr>rf; nr--) {
809 y = t.GetY(); z = t.GetZ();
811 // first propagate to the inner surface of the current time bin
812 fTrSec[s]->GetLayer(nr)->GetPropagationParameters(y,z,dx,rho,radLength,lookForCluster);
813 x = fTrSec[s]->GetLayer(nr)->GetX()-dx/2; y = t.GetY(); z = t.GetZ();
814 if(!t.PropagateTo(x,radLength,rho)) break;
816 ymax = x*TMath::Tan(0.5*alpha);
819 if (!t.Rotate(alpha)) break;
820 if(!t.PropagateTo(x,radLength,rho)) break;
821 } else if (y <-ymax) {
823 if (!t.Rotate(-alpha)) break;
824 if(!t.PropagateTo(x,radLength,rho)) break;
827 y = t.GetY(); z = t.GetZ();
829 // now propagate to the middle plane of the next time bin
830 fTrSec[s]->GetLayer(nr-1)->GetPropagationParameters(y,z,dx,rho,radLength,lookForCluster);
831 x = fTrSec[s]->GetLayer(nr-1)->GetX(); y = t.GetY(); z = t.GetZ();
832 if(!t.PropagateTo(x,radLength,rho)) break;
834 ymax = x*TMath::Tan(0.5*alpha);
837 if (!t.Rotate(alpha)) break;
838 if(!t.PropagateTo(x,radLength,rho)) break;
839 } else if (y <-ymax) {
841 if (!t.Rotate(-alpha)) break;
842 if(!t.PropagateTo(x,radLength,rho)) break;
848 expectedNumberOfClusters++;
849 wIndex = (Float_t) t.GetLabel();
852 AliTRDpropagationLayer& timeBin=*(fTrSec[s]->GetLayer(nr-1));
854 Double_t sy2=ExpectedSigmaY2(x,t.GetTgl(),t.GetPt());
855 Double_t sz2=ExpectedSigmaZ2(x,t.GetTgl());
858 if((t.GetSigmaY2() + sy2) > 0) road=10.*sqrt(t.GetSigmaY2() + sy2);
859 else return expectedNumberOfClusters;
863 wYwindow = (Float_t) road;
864 t.GetPxPyPz(px,py,pz);
868 wC = (Float_t) t.GetC();
869 wSigmaC2 = (Float_t) t.GetSigmaC2();
870 wSigmaTgl2 = (Float_t) t.GetSigmaTgl2();
871 wSigmaY2 = (Float_t) t.GetSigmaY2();
872 wSigmaZ2 = (Float_t) t.GetSigmaZ2();
879 Double_t maxChi2=fgkMaxChi2;
881 wYclosest = 12345678;
882 wYcorrect = 12345678;
883 wZclosest = 12345678;
884 wZcorrect = 12345678;
885 wZwindow = TMath::Sqrt(2.25 * 12 * sz2);
887 // Find the closest correct cluster for debugging purposes
888 if (timeBin&&fVocal) {
889 Float_t minDY = 1000000;
890 for (Int_t i=0; i<timeBin; i++) {
891 AliTRDcluster* c=(AliTRDcluster*)(timeBin[i]);
892 if((c->GetLabel(0) != trackIndex) &&
893 (c->GetLabel(1) != trackIndex) &&
894 (c->GetLabel(2) != trackIndex)) continue;
895 if(TMath::Abs(c->GetY() - y) > minDY) continue;
896 minDY = TMath::Abs(c->GetY() - y);
897 wYcorrect = c->GetY();
898 wZcorrect = c->GetZ();
900 Double_t h01 = GetTiltFactor(c);
901 wChi2 = t.GetPredictedChi2(c, h01);
905 // Now go for the real cluster search
909 //find cluster in history
912 AliTRDcluster * cl0 = timeBin[0];
916 Int_t plane = fGeom->GetPlane(cl0->GetDetector());
917 if (plane>lastplane) continue;
918 Int_t timebin = cl0->GetLocalTimeBin();
919 AliTRDcluster * cl2= GetCluster(&t,plane, timebin,index);
922 Double_t h01 = GetTiltFactor(cl);
923 maxChi2=t.GetPredictedChi2(cl,h01);
925 if ((!cl) && road>fgkWideRoad) {
926 //if (t.GetNumberOfClusters()>4)
927 // cerr<<t.GetNumberOfClusters()
928 // <<"FindProlongation warning: Too broad road !\n";
934 wYclosest = cl->GetY();
935 wZclosest = cl->GetZ();
936 Double_t h01 = GetTiltFactor(cl);
938 //if (cl->GetNPads()<5)
939 t.SetSampledEdx(TMath::Abs(cl->GetQ()/dxsample));
940 Int_t det = cl->GetDetector();
941 Int_t plane = fGeom->GetPlane(det);
943 if(!t.UpdateMI(cl,maxChi2,index,h01,plane)) {
944 //if(!t.Update(cl,maxChi2,index,h01)) {
945 //if(!tryAgain--) return 0;
947 else tryAgain=fMaxGap;
950 //if (tryAgain==0) break;
956 return expectedNumberOfClusters;
964 //---------------------------------------------------------------------------
965 Int_t AliTRDtracker::FollowProlongationG(AliTRDtrack& t, Int_t rf)
967 // Starting from current position on track=t this function tries
968 // to extrapolate the track up to timeBin=0 and to confirm prolongation
969 // if a close cluster is found. Returns the number of clusters
970 // expected to be found in sensitive layers
971 // GeoManager used to estimate mean density
973 Int_t lastplane = GetLastPlane(&t);
974 Int_t tryAgain=fMaxGap;
975 Double_t alpha=t.GetAlpha();
976 alpha = TVector2::Phi_0_2pi(alpha);
977 Double_t radLength, rho, x, dx;
979 Int_t expectedNumberOfClusters = 0;
980 Double_t dxsample = fgkDriftCorrection*(Double_t) fPar->GetDriftVelocity()
981 / fPar->GetSamplingFrequency();
984 alpha=AliTRDgeometry::GetAlpha(); // note: change in meaning
985 Double_t tanmax = TMath::Tan(0.5*alpha);
987 for (Int_t nr=fTrSec[0]->GetLayerNumber(t.GetX()); nr>rf; nr--) {
989 // propagate track in non active layers
991 if (!(fTrSec[0]->GetLayer(nr)->IsSensitive())){
992 Double_t xyz0[3],xyz1[3],param[7],x,y,z;
993 t.GetGlobalXYZ(xyz0[0],xyz0[1],xyz0[2]); //starting global position
994 while (nr >rf && (!(fTrSec[0]->GetLayer(nr)->IsSensitive()))){
995 x = fTrSec[0]->GetLayer(nr)->GetX();
997 if (!t.GetProlongation(x,y,z)) break;
998 if (TMath::Abs(y)>x*tanmax){
1004 x = fTrSec[0]->GetLayer(nr)->GetX();
1005 if (!t.GetProlongation(x,y,z)) break;
1007 // minimal mean and maximal budget scan
1008 Float_t minbudget =10000;
1009 Float_t meanbudget =0;
1010 Float_t maxbudget =-1;
1011 // Float_t normbudget =0;
1012 // for (Int_t idy=-1;idy<=1;idy++)
1013 // for (Int_t idz=-1;idz<=1;idz++){
1014 for (Int_t idy=0;idy<1;idy++)
1015 for (Int_t idz=0;idz<1;idz++){
1016 Double_t y2 = y+idy*TMath::Min(TMath::Sqrt(t.GetSigmaY2()),1.);
1017 Double_t z2 = z+idz*TMath::Min(TMath::Sqrt(t.GetSigmaY2()),1.);
1018 xyz1[0] = x*TMath::Cos(t.GetAlpha())-y2*TMath::Sin(t.GetAlpha());
1019 xyz1[1] = +x*TMath::Sin(t.GetAlpha())+y2*TMath::Cos(t.GetAlpha());
1021 AliKalmanTrack::MeanMaterialBudget(xyz0,xyz1,param);
1022 Float_t budget = param[0]*param[4];
1024 if (budget<minbudget) minbudget=budget;
1025 if (budget>maxbudget) maxbudget=budget;
1027 t.fBudget[0]+=minbudget;
1028 t.fBudget[1]+=meanbudget/9.;
1029 t.fBudget[2]+=minbudget;
1032 xyz1[0] = x*TMath::Cos(t.GetAlpha())-y*TMath::Sin(t.GetAlpha());
1033 xyz1[1] = +x*TMath::Sin(t.GetAlpha())+y*TMath::Cos(t.GetAlpha());
1035 AliKalmanTrack::MeanMaterialBudget(xyz0,xyz1,param);
1037 t.PropagateTo(x,param[1],param[0]);
1038 t.GetGlobalXYZ(xyz0[0],xyz0[1],xyz0[2]); //end global position
1044 // stop tracking for highly inclined tracks
1045 if (!AdjustSector(&t)) break;
1046 if (TMath::Abs(t.GetSnp())>0.95) break;
1048 // propagate and update track in active layers
1050 Int_t nr0 = nr; //first active layer
1051 if (nr >rf && (fTrSec[0]->GetLayer(nr)->IsSensitive())){
1052 Double_t xyz0[3],xyz1[3],param[7],x,y,z;
1053 t.GetGlobalXYZ(xyz0[0],xyz0[1],xyz0[2]); //starting global position
1054 while (nr >rf && ((fTrSec[0]->GetLayer(nr)->IsSensitive()))){
1055 x = fTrSec[0]->GetLayer(nr)->GetX();
1057 if (!t.GetProlongation(x,y,z)) break;
1058 if (TMath::Abs(y)>x*tanmax){
1064 x = fTrSec[0]->GetLayer(nr)->GetX();
1065 if (!t.GetProlongation(x,y,z)) break;
1066 xyz1[0] = x*TMath::Cos(t.GetAlpha())-y*TMath::Sin(t.GetAlpha());
1067 xyz1[1] = +x*TMath::Sin(t.GetAlpha())+y*TMath::Cos(t.GetAlpha());
1069 // end global position
1070 AliKalmanTrack::MeanMaterialBudget(xyz0,xyz1,param);
1072 radLength = param[1]; // get mean propagation parameters
1075 // propagate and update
1077 // short tracklet - do not update - edge effect
1078 x = fTrSec[0]->GetLayer(nr)->GetX();
1079 t.PropagateTo(x,radLength,rho);
1083 sector = t.GetSector();
1086 for (Int_t ilayer=nr0;ilayer>=nr;ilayer--) {
1087 expectedNumberOfClusters++;
1089 if (t.fX>345) t.fNExpectedLast++;
1090 AliTRDpropagationLayer& timeBin=*(fTrSec[sector]->GetLayer(ilayer));
1091 AliTRDcluster *cl=0;
1093 Double_t maxChi2=fgkMaxChi2;
1094 dx = (fTrSec[sector]->GetLayer(ilayer+1))->GetX()-timeBin.GetX();
1096 t.PropagateTo(x,radLength,rho);
1097 // Now go for the real cluster search
1099 AliTRDcluster * cl0 = timeBin[0];
1100 if (!cl0) continue; // no clusters in given time bin
1101 Int_t plane = fGeom->GetPlane(cl0->GetDetector());
1102 if (plane>lastplane) continue;
1103 Int_t timebin = cl0->GetLocalTimeBin();
1104 AliTRDcluster * cl2= GetCluster(&t,plane, timebin,index);
1108 Double_t h01 = GetTiltFactor(cl);
1109 maxChi2=t.GetPredictedChi2(cl,h01);
1113 // if (cl->GetNPads()<5)
1114 t.SetSampledEdx(TMath::Abs(cl->GetQ()/dxsample));
1115 Double_t h01 = GetTiltFactor(cl);
1116 Int_t det = cl->GetDetector();
1117 Int_t plane = fGeom->GetPlane(det);
1120 t.fChi2Last+=maxChi2;
1122 if(!t.UpdateMI(cl,maxChi2,index,h01,plane)) {
1123 if(!t.Update(cl,maxChi2,index,h01)) {
1124 //if(!tryAgain--) return 0;
1127 else tryAgain=fMaxGap;
1133 return expectedNumberOfClusters;
1138 //___________________________________________________________________
1140 Int_t AliTRDtracker::FollowBackProlongation(AliTRDtrack& t)
1142 // Starting from current radial position of track <t> this function
1143 // extrapolates the track up to outer timebin and in the sensitive
1144 // layers confirms prolongation if a close cluster is found.
1145 // Returns the number of clusters expected to be found in sensitive layers
1147 Int_t tryAgain=fMaxGap;
1149 Double_t alpha=t.GetAlpha();
1150 TVector2::Phi_0_2pi(alpha);
1154 Int_t clusters[1000];
1155 for (Int_t i=0;i<1000;i++) clusters[i]=-1;
1157 Int_t outerTB = fTrSec[0]->GetOuterTimeBin();
1158 //Double_t radLength, rho, x, dx, y, ymax = 0, z;
1159 Double_t radLength, rho, x, dx, y, z;
1160 Bool_t lookForCluster;
1161 Double_t dxsample = fgkDriftCorrection*(Double_t) fPar->GetDriftVelocity()
1162 / fPar->GetSamplingFrequency();
1164 Int_t expectedNumberOfClusters = 0;
1167 alpha=AliTRDgeometry::GetAlpha(); // note: change in meaning
1172 AliTRDtracklet tracklet;
1174 for (nr=fTrSec[0]->GetLayerNumber(t.GetX()); nr<outerTB+1; nr++) {
1177 // first propagate to the outer surface of the current time bin
1180 fTrSec[s]->GetLayer(nr)->GetPropagationParameters(y,z,dx,rho,radLength,lookForCluster);
1181 x = fTrSec[s]->GetLayer(nr)->GetX()+dx/2;
1185 if(!t.PropagateTo(x,radLength,rho)) break;
1187 // MI -fix untill correct material desription will be implemented
1189 //Int_t nrotate = t.GetNRotate();
1190 if (!AdjustSector(&t)) break;
1197 // now propagate to the middle plane of the next time bin
1198 fTrSec[s]->GetLayer(nr+1)->GetPropagationParameters(y,z,dx,rho,radLength,lookForCluster);
1199 // if (nrotate!=t.GetNRotate()){
1200 // rho = 1000*2.7; radLength = 24.01; //TEMPORARY - aluminium in between z - will be detected using GeoModeler in future versions
1202 x = fTrSec[s]->GetLayer(nr+1)->GetX();
1203 if(!t.PropagateTo(x,radLength,rho)) break;
1204 if (!AdjustSector(&t)) break;
1206 // if(!t.PropagateTo(x,radLength,rho)) break;
1208 if (TMath::Abs(t.GetSnp())>0.95) break;
1213 if(lookForCluster) {
1214 if (clusters[nr]==-1) {
1215 Float_t ncl = FindClusters(s,nr,nr+30,&t,clusters,tracklet);
1216 ratio0 = ncl/Float_t(fTimeBinsPerPlane);
1217 Float_t ratio1 = Float_t(t.fN+1)/Float_t(t.fNExpected+1.);
1218 if (tracklet.GetChi2()<18.&&ratio0>0.8 && ratio1>0.6 && ratio0+ratio1>1.5 && t.GetNCross()==0 && TMath::Abs(t.GetSnp())<0.85&&t.fN>20){
1219 t.MakeBackupTrack(); // make backup of the track until is gold
1222 // t.PropagateTo(tracklet.GetX());
1223 // t.UpdateMI(tracklet);
1224 // nr = fTrSec[0]->GetLayerNumber(t.GetX())+1;
1229 expectedNumberOfClusters++;
1231 if (t.fX>345) t.fNExpectedLast++;
1233 AliTRDpropagationLayer& timeBin=*(fTrSec[s]->GetLayer(nr+1));
1234 Double_t sy2=ExpectedSigmaY2(t.GetX(),t.GetTgl(),t.GetPt());
1235 if((t.GetSigmaY2() + sy2) < 0) {
1236 printf("problem\n");
1239 Double_t road = 10.*sqrt(t.GetSigmaY2() + sy2);
1241 if (road>fgkWideRoad) {
1245 AliTRDcluster *cl=0;
1247 Double_t maxChi2=fgkMaxChi2;
1249 // Now go for the real cluster search
1253 if (clusters[nr+1]>0) {
1254 index = clusters[nr+1];
1255 cl = (AliTRDcluster*)GetCluster(index);
1256 Double_t h01 = GetTiltFactor(cl);
1257 maxChi2=t.GetPredictedChi2(cl,h01);
1261 // if (cl->GetNPads()<5)
1262 t.SetSampledEdx(TMath::Abs(cl->GetQ()/dxsample));
1263 Double_t h01 = GetTiltFactor(cl);
1264 Int_t det = cl->GetDetector();
1265 Int_t plane = fGeom->GetPlane(det);
1268 t.fChi2Last+=maxChi2;
1270 if(!t.UpdateMI(cl,maxChi2,index,h01,plane)) {
1271 if(!t.Update(cl,maxChi2,index,h01)) {
1272 //if(!tryAgain--) return 0;
1275 else tryAgain=fMaxGap;
1278 if (cl->GetLocalTimeBin()==1&&t.fN>20 && float(t.fChi2)/float(t.fN)<5){
1279 Float_t ratio1 = Float_t(t.fN)/Float_t(t.fNExpected);
1280 if (tracklet.GetChi2()<18&&ratio0>0.8&&ratio1>0.6 &&ratio0+ratio1>1.5 && t.GetNCross()==0 && TMath::Abs(t.GetSnp())<0.85){
1281 t.MakeBackupTrack(); // make backup of the track until is gold
1287 // if (tryAgain==0) break;
1297 return expectedNumberOfClusters;
1301 //___________________________________________________________________
1302 Int_t AliTRDtracker::FollowBackProlongationG(AliTRDtrack& t)
1305 // Starting from current radial position of track <t> this function
1306 // extrapolates the track up to outer timebin and in the sensitive
1307 // layers confirms prolongation if a close cluster is found.
1308 // Returns the number of clusters expected to be found in sensitive layers
1309 // Use GEO manager for material Description
1310 Int_t tryAgain=fMaxGap;
1312 Double_t alpha=t.GetAlpha();
1313 TVector2::Phi_0_2pi(alpha);
1315 Int_t clusters[1000];
1316 for (Int_t i=0;i<1000;i++) clusters[i]=-1;
1317 Double_t dxsample = fgkDriftCorrection*(Double_t) fPar->GetDriftVelocity()
1318 / fPar->GetSamplingFrequency();
1319 Int_t outerTB = fTrSec[0]->GetOuterTimeBin();
1320 Double_t radLength, rho, x, dx; //y, z;
1322 Int_t expectedNumberOfClusters = 0;
1325 alpha=AliTRDgeometry::GetAlpha(); // note: change in meaning
1326 Double_t tanmax = TMath::Tan(0.5*alpha);
1329 AliTRDtracklet tracklet;
1333 for (nr=fTrSec[0]->GetLayerNumber(t.GetX()); nr<outerTB+1; nr++) {
1335 // propagate track in non active layers
1337 if (!(fTrSec[0]->GetLayer(nr)->IsSensitive())){
1338 Double_t xyz0[3],xyz1[3],param[7],x,y,z;
1339 t.GetGlobalXYZ(xyz0[0],xyz0[1],xyz0[2]); //starting global position
1340 while (nr <outerTB && (!(fTrSec[0]->GetLayer(nr)->IsSensitive()))){
1341 x = fTrSec[0]->GetLayer(nr)->GetX();
1343 if (!t.GetProlongation(x,y,z)) break;
1344 if (TMath::Abs(y)>x*tanmax){
1350 x = fTrSec[0]->GetLayer(nr)->GetX();
1351 if (!t.GetProlongation(x,y,z)) break;
1352 // minimal mean and maximal budget scan
1353 Float_t minbudget =10000;
1354 Float_t meanbudget =0;
1355 Float_t maxbudget =-1;
1356 // Float_t normbudget =0;
1357 // for (Int_t idy=-1;idy<=1;idy++)
1358 // for (Int_t idz=-1;idz<=1;idz++){
1359 for (Int_t idy=0;idy<1;idy++)
1360 for (Int_t idz=0;idz<1;idz++){
1361 Double_t y2 = y+idy*TMath::Min(TMath::Sqrt(t.GetSigmaY2()),1.);
1362 Double_t z2 = z+idz*TMath::Min(TMath::Sqrt(t.GetSigmaY2()),1.);
1364 xyz1[0] = x*TMath::Cos(t.GetAlpha())-y2*TMath::Sin(t.GetAlpha());
1365 xyz1[1] = +x*TMath::Sin(t.GetAlpha())+y2*TMath::Cos(t.GetAlpha());
1367 AliKalmanTrack::MeanMaterialBudget(xyz0,xyz1,param);
1368 Float_t budget = param[0]*param[4];
1370 if (budget<minbudget) minbudget=budget;
1371 if (budget>maxbudget) maxbudget=budget;
1373 t.fBudget[0]+=minbudget;
1374 t.fBudget[1]+=meanbudget/9.;
1375 t.fBudget[2]+=minbudget;
1377 xyz1[0] = x*TMath::Cos(t.GetAlpha())-y*TMath::Sin(t.GetAlpha());
1378 xyz1[1] = +x*TMath::Sin(t.GetAlpha())+y*TMath::Cos(t.GetAlpha());
1380 AliKalmanTrack::MeanMaterialBudget(xyz0,xyz1,param);
1381 t.PropagateTo(x,param[1],param[0]);
1382 t.GetGlobalXYZ(xyz0[0],xyz0[1],xyz0[2]); //end global position
1388 // stop tracking for highly inclined tracks
1389 if (!AdjustSector(&t)) break;
1390 if (TMath::Abs(t.GetSnp())>0.95) break;
1392 // propagate and update track in active layers
1394 Int_t nr0 = nr; //first active layer
1395 if (nr <outerTB && (fTrSec[0]->GetLayer(nr)->IsSensitive())){
1396 Double_t xyz0[3],xyz1[3],param[7],x,y,z;
1397 t.GetGlobalXYZ(xyz0[0],xyz0[1],xyz0[2]); //starting global position
1398 while (nr <outerTB && ((fTrSec[0]->GetLayer(nr)->IsSensitive()))){
1399 x = fTrSec[0]->GetLayer(nr)->GetX();
1401 if (!t.GetProlongation(x,y,z)) break;
1402 if (TMath::Abs(y)>(x*tanmax)){
1407 x = fTrSec[0]->GetLayer(nr)->GetX();
1408 if (!t.GetProlongation(x,y,z)) break;
1409 // minimal mean and maximal budget scan
1410 Float_t minbudget =10000;
1411 Float_t meanbudget =0;
1412 Float_t maxbudget =-1;
1413 // Float_t normbudget =0;
1414 // for (Int_t idy=-1;idy<=1;idy++)
1415 // for (Int_t idz=-1;idz<=1;idz++){
1416 for (Int_t idy=0;idy<1;idy++)
1417 for (Int_t idz=0;idz<1;idz++){
1418 Double_t y2 = y+idy*TMath::Min(TMath::Sqrt(t.GetSigmaY2()),1.);
1419 Double_t z2 = z+idz*TMath::Min(TMath::Sqrt(t.GetSigmaY2()),1.);
1421 xyz1[0] = x*TMath::Cos(t.GetAlpha())-y2*TMath::Sin(t.GetAlpha());
1422 xyz1[1] = +x*TMath::Sin(t.GetAlpha())+y2*TMath::Cos(t.GetAlpha());
1424 AliKalmanTrack::MeanMaterialBudget(xyz0,xyz1,param);
1425 Float_t budget = param[0]*param[4];
1427 if (budget<minbudget) minbudget=budget;
1428 if (budget>maxbudget) maxbudget=budget;
1430 t.fBudget[0]+=minbudget;
1431 t.fBudget[1]+=meanbudget/9.;
1432 t.fBudget[2]+=minbudget;
1434 xyz1[0] = x*TMath::Cos(t.GetAlpha())-y*TMath::Sin(t.GetAlpha());
1435 xyz1[1] = +x*TMath::Sin(t.GetAlpha())+y*TMath::Cos(t.GetAlpha());
1437 // end global position
1438 AliKalmanTrack::MeanMaterialBudget(xyz0,xyz1,param);
1440 radLength = param[1]; // get mean propagation parameters
1445 // short tracklet - do not update - edge effect
1446 x = fTrSec[0]->GetLayer(nr+1)->GetX();
1447 t.PropagateTo(x,radLength,rho);
1453 sector = t.GetSector();
1454 Float_t ncl = FindClusters(sector,nr0,nr,&t,clusters,tracklet);
1455 if (tracklet.GetN()-2*tracklet.GetNCross()<10) continue;
1456 ratio0 = ncl/Float_t(fTimeBinsPerPlane);
1457 Float_t ratio1 = Float_t(t.fN+1)/Float_t(t.fNExpected+1.);
1458 if (tracklet.GetChi2()<18.&&ratio0>0.8 && ratio1>0.6 && ratio0+ratio1>1.5 && t.GetNCross()==0 && TMath::Abs(t.GetSnp())<0.85&&t.fN>20){
1459 t.MakeBackupTrack(); // make backup of the track until is gold
1463 for (Int_t ilayer=nr0;ilayer<=nr;ilayer++) {
1464 expectedNumberOfClusters++;
1466 if (t.fX>345) t.fNExpectedLast++;
1467 AliTRDpropagationLayer& timeBin=*(fTrSec[sector]->GetLayer(ilayer));
1468 AliTRDcluster *cl=0;
1470 Double_t maxChi2=fgkMaxChi2;
1471 dx = (fTrSec[sector]->GetLayer(ilayer-1))->GetX()-timeBin.GetX();
1473 t.PropagateTo(x,radLength,rho);
1474 // Now go for the real cluster search
1476 if (clusters[ilayer]>0) {
1477 index = clusters[ilayer];
1478 cl = (AliTRDcluster*)GetCluster(index);
1479 Double_t h01 = GetTiltFactor(cl);
1480 maxChi2=t.GetPredictedChi2(cl,h01);
1484 // if (cl->GetNPads()<5)
1485 t.SetSampledEdx(TMath::Abs(cl->GetQ()/dxsample));
1486 Double_t h01 = GetTiltFactor(cl);
1487 Int_t det = cl->GetDetector();
1488 Int_t plane = fGeom->GetPlane(det);
1491 t.fChi2Last+=maxChi2;
1493 if(!t.UpdateMI(cl,maxChi2,index,h01,plane)) {
1494 if(!t.Update(cl,maxChi2,index,h01)) {
1495 //if(!tryAgain--) return 0;
1498 else tryAgain=fMaxGap;
1501 if (cl->GetLocalTimeBin()==1&&t.fN>20 && float(t.fChi2)/float(t.fN)<5){
1502 Float_t ratio1 = Float_t(t.fN)/Float_t(t.fNExpected);
1503 if (tracklet.GetChi2()<18&&ratio0>0.8&&ratio1>0.6 &&ratio0+ratio1>1.5 && t.GetNCross()==0 && TMath::Abs(t.GetSnp())<0.85){
1504 t.MakeBackupTrack(); // make backup of the track until is gold
1507 // reset material budget if 2 consecutive gold
1509 if (t.fTracklets[plane].GetN()+t.fTracklets[plane-1].GetN()>20){
1521 return expectedNumberOfClusters;
1524 //---------------------------------------------------------------------------
1525 Int_t AliTRDtracker::Refit(AliTRDtrack& t, Int_t rf)
1527 // Starting from current position on track=t this function tries
1528 // to extrapolate the track up to timeBin=0 and to reuse already
1529 // assigned clusters. Returns the number of clusters
1530 // expected to be found in sensitive layers
1531 // get indices of assigned clusters for each layer
1532 // Origin: Thomas KUHR (Thomas.Kuhr@cern.ch)
1533 Double_t dxsample = fgkDriftCorrection*(Double_t) fPar->GetDriftVelocity()
1534 / fPar->GetSamplingFrequency();
1536 for (Int_t i = 0; i < 90; i++) iCluster[i] = 0;
1537 for (Int_t i = 0; i < t.GetNumberOfClusters(); i++) {
1538 Int_t index = t.GetClusterIndex(i);
1539 AliTRDcluster *cl=(AliTRDcluster*) GetCluster(index);
1541 Int_t detector=cl->GetDetector();
1542 Int_t localTimeBin=cl->GetLocalTimeBin();
1543 Int_t sector=fGeom->GetSector(detector);
1544 Int_t plane=fGeom->GetPlane(detector);
1546 Int_t trackingSector = CookSectorIndex(sector);
1548 Int_t gtb = fTrSec[trackingSector]->CookTimeBinIndex(plane,localTimeBin);
1549 if(gtb < 0) continue;
1550 Int_t layer = fTrSec[trackingSector]->GetLayerNumber(gtb);
1551 iCluster[layer] = index;
1555 Int_t ns=Int_t(2*TMath::Pi()/AliTRDgeometry::GetAlpha()+0.5);
1557 Double_t alpha=t.GetAlpha();
1558 alpha = TVector2::Phi_0_2pi(alpha);
1560 Int_t s=Int_t(alpha/AliTRDgeometry::GetAlpha())%AliTRDgeometry::kNsect;
1561 Double_t radLength, rho, x, dx, y, ymax, z;
1563 Int_t expectedNumberOfClusters = 0;
1564 Bool_t lookForCluster;
1566 alpha=AliTRDgeometry::GetAlpha(); // note: change in meaning
1569 for (Int_t nr=fTrSec[0]->GetLayerNumber(t.GetX()); nr>rf; nr--) {
1571 y = t.GetY(); z = t.GetZ();
1573 // first propagate to the inner surface of the current time bin
1574 fTrSec[s]->GetLayer(nr)->GetPropagationParameters(y,z,dx,rho,radLength,lookForCluster);
1575 x = fTrSec[s]->GetLayer(nr)->GetX()-dx/2; y = t.GetY(); z = t.GetZ();
1576 if(!t.PropagateTo(x,radLength,rho)) break;
1578 ymax = x*TMath::Tan(0.5*alpha);
1581 if (!t.Rotate(alpha)) break;
1582 if(!t.PropagateTo(x,radLength,rho)) break;
1583 } else if (y <-ymax) {
1585 if (!t.Rotate(-alpha)) break;
1586 if(!t.PropagateTo(x,radLength,rho)) break;
1589 y = t.GetY(); z = t.GetZ();
1591 // now propagate to the middle plane of the next time bin
1592 fTrSec[s]->GetLayer(nr-1)->GetPropagationParameters(y,z,dx,rho,radLength,lookForCluster);
1593 x = fTrSec[s]->GetLayer(nr-1)->GetX(); y = t.GetY(); z = t.GetZ();
1594 if(!t.PropagateTo(x,radLength,rho)) break;
1596 ymax = x*TMath::Tan(0.5*alpha);
1599 if (!t.Rotate(alpha)) break;
1600 if(!t.PropagateTo(x,radLength,rho)) break;
1601 } else if (y <-ymax) {
1603 if (!t.Rotate(-alpha)) break;
1604 if(!t.PropagateTo(x,radLength,rho)) break;
1607 if(lookForCluster) expectedNumberOfClusters++;
1609 // use assigned cluster
1610 if (!iCluster[nr-1]) continue;
1611 AliTRDcluster *cl=(AliTRDcluster*)GetCluster(iCluster[nr-1]);
1612 Double_t h01 = GetTiltFactor(cl);
1613 Double_t chi2=t.GetPredictedChi2(cl, h01);
1614 //if (cl->GetNPads()<5)
1615 t.SetSampledEdx(TMath::Abs(cl->GetQ()/dxsample));
1617 //t.SetSampledEdx(cl->GetQ()/dx,t.GetNumberOfClusters());
1618 t.Update(cl,chi2,iCluster[nr-1],h01);
1621 return expectedNumberOfClusters;
1624 //___________________________________________________________________
1626 Int_t AliTRDtracker::PropagateToOuterPlane(AliTRDtrack& t, Double_t xToGo)
1628 // Starting from current radial position of track <t> this function
1629 // extrapolates the track up to radial position <xToGo>.
1630 // Returns 1 if track reaches the plane, and 0 otherwise
1632 Int_t ns=Int_t(2*TMath::Pi()/AliTRDgeometry::GetAlpha()+0.5);
1634 Double_t alpha=t.GetAlpha();
1636 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
1637 if (alpha < 0. ) alpha += 2.*TMath::Pi();
1639 Int_t s=Int_t(alpha/AliTRDgeometry::GetAlpha())%AliTRDgeometry::kNsect;
1641 Bool_t lookForCluster;
1642 Double_t radLength, rho, x, dx, y, ymax, z;
1646 alpha=AliTRDgeometry::GetAlpha(); // note: change in meaning
1648 Int_t plToGo = fTrSec[0]->GetLayerNumber(xToGo);
1650 for (Int_t nr=fTrSec[0]->GetLayerNumber(x); nr<plToGo; nr++) {
1652 y = t.GetY(); z = t.GetZ();
1654 // first propagate to the outer surface of the current time bin
1655 fTrSec[s]->GetLayer(nr)->GetPropagationParameters(y,z,dx,rho,radLength,lookForCluster);
1656 x = fTrSec[s]->GetLayer(nr)->GetX()+dx/2; y = t.GetY(); z = t.GetZ();
1657 if(!t.PropagateTo(x,radLength,rho)) return 0;
1659 ymax = x*TMath::Tan(0.5*alpha);
1662 if (!t.Rotate(alpha)) return 0;
1663 } else if (y <-ymax) {
1665 if (!t.Rotate(-alpha)) return 0;
1667 if(!t.PropagateTo(x,radLength,rho)) return 0;
1669 y = t.GetY(); z = t.GetZ();
1671 // now propagate to the middle plane of the next time bin
1672 fTrSec[s]->GetLayer(nr+1)->GetPropagationParameters(y,z,dx,rho,radLength,lookForCluster);
1673 x = fTrSec[s]->GetLayer(nr+1)->GetX(); y = t.GetY(); z = t.GetZ();
1674 if(!t.PropagateTo(x,radLength,rho)) return 0;
1676 ymax = x*TMath::Tan(0.5*alpha);
1679 if (!t.Rotate(alpha)) return 0;
1680 } else if (y <-ymax) {
1682 if (!t.Rotate(-alpha)) return 0;
1684 if(!t.PropagateTo(x,radLength,rho)) return 0;
1689 //___________________________________________________________________
1691 Int_t AliTRDtracker::PropagateToTPC(AliTRDtrack& t)
1693 // Starting from current radial position of track <t> this function
1694 // extrapolates the track up to radial position of the outermost
1695 // padrow of the TPC.
1696 // Returns 1 if track reaches the TPC, and 0 otherwise
1698 //Int_t ns=Int_t(2*TMath::Pi()/AliTRDgeometry::GetAlpha()+0.5);
1700 Double_t alpha=t.GetAlpha();
1701 alpha = TVector2::Phi_0_2pi(alpha);
1703 Int_t s=Int_t(alpha/AliTRDgeometry::GetAlpha())%AliTRDgeometry::kNsect;
1705 Bool_t lookForCluster;
1706 Double_t radLength, rho, x, dx, y, /*ymax,*/ z;
1710 alpha=AliTRDgeometry::GetAlpha(); // note: change in meaning
1711 Int_t plTPC = fTrSec[0]->GetLayerNumber(246.055);
1713 for (Int_t nr=fTrSec[0]->GetLayerNumber(x); nr>plTPC; nr--) {
1718 // first propagate to the outer surface of the current time bin
1719 fTrSec[s]->GetLayer(nr)->GetPropagationParameters(y,z,dx,rho,radLength,lookForCluster);
1720 x = fTrSec[s]->GetLayer(nr)->GetX()-dx/2;
1722 if(!t.PropagateTo(x,radLength,rho)) return 0;
1724 if(!t.PropagateTo(x,radLength,rho)) return 0;
1729 // now propagate to the middle plane of the next time bin
1730 fTrSec[s]->GetLayer(nr-1)->GetPropagationParameters(y,z,dx,rho,radLength,lookForCluster);
1731 x = fTrSec[s]->GetLayer(nr-1)->GetX();
1733 if(!t.PropagateTo(x,radLength,rho)) return 0;
1735 if(!t.PropagateTo(x,radLength,rho)) return 0;
1740 //_____________________________________________________________________________
1741 Int_t AliTRDtracker::LoadClusters(TTree *cTree)
1743 // Fills clusters into TRD tracking_sectors
1744 // Note that the numbering scheme for the TRD tracking_sectors
1745 // differs from that of TRD sectors
1746 cout<<"\n Read Sectors clusters"<<endl;
1747 if (ReadClusters(fClusters,cTree)) {
1748 Error("LoadClusters","Problem with reading the clusters !");
1751 Int_t ncl=fClusters->GetEntriesFast();
1753 cout<<"\n LoadSectors: sorting "<<ncl<<" clusters"<<endl;
1756 for (Int_t ichamber=0;ichamber<5;ichamber++)
1757 for (Int_t isector=0;isector<18;isector++){
1758 fHoles[ichamber][isector]=kTRUE;
1763 // printf("\r %d left ",ncl);
1764 AliTRDcluster *c=(AliTRDcluster*)fClusters->UncheckedAt(ncl);
1765 Int_t detector=c->GetDetector();
1766 Int_t localTimeBin=c->GetLocalTimeBin();
1767 Int_t sector=fGeom->GetSector(detector);
1768 Int_t plane=fGeom->GetPlane(detector);
1770 Int_t trackingSector = CookSectorIndex(sector);
1771 if (c->GetLabel(0)>0){
1772 Int_t chamber = fGeom->GetChamber(detector);
1773 fHoles[chamber][trackingSector]=kFALSE;
1776 Int_t gtb = fTrSec[trackingSector]->CookTimeBinIndex(plane,localTimeBin);
1777 if(gtb < 0) continue;
1778 Int_t layer = fTrSec[trackingSector]->GetLayerNumber(gtb);
1781 fTrSec[trackingSector]->GetLayer(layer)->InsertCluster(c,index);
1787 for (Int_t isector=0;isector<18;isector++){
1788 for (Int_t ichamber=0;ichamber<5;ichamber++)
1789 if (fHoles[ichamber][isector]!=fGeom->IsHole(0,ichamber,17-isector))
1790 printf("Problem \t%d\t%d\t%d\t%d\n",isector,ichamber,fHoles[ichamber][isector],
1791 fGeom->IsHole(0,ichamber,17-isector));
1797 //_____________________________________________________________________________
1798 void AliTRDtracker::UnloadClusters()
1801 // Clears the arrays of clusters and tracks. Resets sectors and timebins
1806 nentr = fClusters->GetEntriesFast();
1807 for (i = 0; i < nentr; i++) delete fClusters->RemoveAt(i);
1810 nentr = fSeeds->GetEntriesFast();
1811 for (i = 0; i < nentr; i++) delete fSeeds->RemoveAt(i);
1813 nentr = fTracks->GetEntriesFast();
1814 for (i = 0; i < nentr; i++) delete fTracks->RemoveAt(i);
1816 Int_t nsec = AliTRDgeometry::kNsect;
1818 for (i = 0; i < nsec; i++) {
1819 for(Int_t pl = 0; pl < fTrSec[i]->GetNumberOfLayers(); pl++) {
1820 fTrSec[i]->GetLayer(pl)->Clear();
1826 //__________________________________________________________________________
1827 void AliTRDtracker::MakeSeeds(Int_t inner, Int_t outer, Int_t turn)
1829 // Creates track seeds using clusters in timeBins=i1,i2
1832 cerr<<"MakeSeeds: turn "<<turn<<" exceeds the limit of 2"<<endl;
1836 Double_t x[5], c[15];
1837 Int_t maxSec=AliTRDgeometry::kNsect;
1839 Double_t alpha=AliTRDgeometry::GetAlpha();
1840 Double_t shift=AliTRDgeometry::GetAlpha()/2.;
1841 Double_t cs=cos(alpha), sn=sin(alpha);
1842 Double_t cs2=cos(2.*alpha), sn2=sin(2.*alpha);
1845 Int_t i2 = fTrSec[0]->GetLayerNumber(inner);
1846 Int_t i1 = fTrSec[0]->GetLayerNumber(outer);
1848 Double_t x1 =fTrSec[0]->GetX(i1);
1849 Double_t xx2=fTrSec[0]->GetX(i2);
1851 for (Int_t ns=0; ns<maxSec; ns++) {
1853 Int_t nl2 = *(fTrSec[(ns-2+maxSec)%maxSec]->GetLayer(i2));
1854 Int_t nl=(*fTrSec[(ns-1+maxSec)%maxSec]->GetLayer(i2));
1855 Int_t nm=(*fTrSec[ns]->GetLayer(i2));
1856 Int_t nu=(*fTrSec[(ns+1)%maxSec]->GetLayer(i2));
1857 Int_t nu2=(*fTrSec[(ns+2)%maxSec]->GetLayer(i2));
1859 AliTRDpropagationLayer& r1=*(fTrSec[ns]->GetLayer(i1));
1861 for (Int_t is=0; is < r1; is++) {
1862 Double_t y1=r1[is]->GetY(), z1=r1[is]->GetZ();
1864 for (Int_t js=0; js < nl2+nl+nm+nu+nu2; js++) {
1866 const AliTRDcluster *cl;
1867 Double_t x2, y2, z2;
1868 Double_t x3=0., y3=0.;
1871 if(turn != 2) continue;
1872 AliTRDpropagationLayer& r2=*(fTrSec[(ns-2+maxSec)%maxSec]->GetLayer(i2));
1874 y2=cl->GetY(); z2=cl->GetZ();
1879 else if (js<nl2+nl) {
1880 if(turn != 1) continue;
1881 AliTRDpropagationLayer& r2=*(fTrSec[(ns-1+maxSec)%maxSec]->GetLayer(i2));
1883 y2=cl->GetY(); z2=cl->GetZ();
1888 else if (js<nl2+nl+nm) {
1889 if(turn != 1) continue;
1890 AliTRDpropagationLayer& r2=*(fTrSec[ns]->GetLayer(i2));
1892 x2=xx2; y2=cl->GetY(); z2=cl->GetZ();
1894 else if (js<nl2+nl+nm+nu) {
1895 if(turn != 1) continue;
1896 AliTRDpropagationLayer& r2=*(fTrSec[(ns+1)%maxSec]->GetLayer(i2));
1897 cl=r2[js-nl2-nl-nm];
1898 y2=cl->GetY(); z2=cl->GetZ();
1904 if(turn != 2) continue;
1905 AliTRDpropagationLayer& r2=*(fTrSec[(ns+2)%maxSec]->GetLayer(i2));
1906 cl=r2[js-nl2-nl-nm-nu];
1907 y2=cl->GetY(); z2=cl->GetZ();
1913 if(TMath::Abs(z1-z2) > fgkMaxSeedDeltaZ12) continue;
1915 Double_t zz=z1 - z1/x1*(x1-x2);
1917 if (TMath::Abs(zz-z2)>fgkMaxSeedDeltaZ) continue;
1919 Double_t d=(x2-x1)*(0.-y2)-(0.-x2)*(y2-y1);
1920 if (d==0.) {cerr<<"TRD MakeSeeds: Straight seed !\n"; continue;}
1924 x[4]=f1trd(x1,y1,x2,y2,x3,y3);
1926 if (TMath::Abs(x[4]) > fgkMaxSeedC) continue;
1928 x[2]=f2trd(x1,y1,x2,y2,x3,y3);
1930 if (TMath::Abs(x[4]*x1-x[2]) >= 0.99999) continue;
1932 x[3]=f3trd(x1,y1,x2,y2,z1,z2);
1934 if (TMath::Abs(x[3]) > fgkMaxSeedTan) continue;
1936 Double_t a=asin(x[2]);
1937 Double_t zv=z1 - x[3]/x[4]*(a+asin(x[4]*x1-x[2]));
1939 if (TMath::Abs(zv)>fgkMaxSeedVertexZ) continue;
1941 Double_t sy1=r1[is]->GetSigmaY2(), sz1=r1[is]->GetSigmaZ2();
1942 Double_t sy2=cl->GetSigmaY2(), sz2=cl->GetSigmaZ2();
1943 Double_t sy3=fgkSeedErrorSY3, sy=fgkSeedErrorSY, sz=fgkSeedErrorSZ;
1946 Double_t h01 = GetTiltFactor(r1[is]);
1947 Double_t xuFactor = 100.;
1953 sy1=sy1+sz1*h01*h01;
1954 Double_t syz=sz1*(-h01);
1955 // end of tilt changes
1957 Double_t f40=(f1trd(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
1958 Double_t f42=(f1trd(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
1959 Double_t f43=(f1trd(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
1960 Double_t f20=(f2trd(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
1961 Double_t f22=(f2trd(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
1962 Double_t f23=(f2trd(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
1963 Double_t f30=(f3trd(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
1964 Double_t f31=(f3trd(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
1965 Double_t f32=(f3trd(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
1966 Double_t f34=(f3trd(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
1970 // c[1]=0.; c[2]=sz1;
1971 c[1]=syz; c[2]=sz1*xuFactor;
1972 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
1973 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
1974 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
1975 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
1976 c[13]=f30*sy1*f40+f32*sy2*f42;
1977 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
1979 UInt_t index=r1.GetIndex(is);
1981 AliTRDtrack *track=new AliTRDtrack(r1[is],index,x,c,x1,ns*alpha+shift);
1983 Int_t rc=FollowProlongation(*track, i2);
1986 (track->GetNumberOfClusters() <
1987 (outer-inner)*fgkMinClustersInSeed)) delete track;
1989 fSeeds->AddLast(track); fNseeds++;
1990 // cerr<<"\r found seed "<<fNseeds;
1996 //__________________________________________________________________________
1997 void AliTRDtracker::MakeSeedsMI(Int_t /*inner*/, Int_t /*outer*/)
2000 // Creates seeds using clusters between position inner plane and outer plane
2003 const Double_t maxtheta = 2;
2004 const Double_t maxphi = 1.5;
2005 Int_t maxSec=AliTRDgeometry::kNsect;
2008 // find the maximal and minimal layer for the planes
2009 // fucking "object oriented" geometry - find the time bin range for different planes
2012 for (Int_t i=0;i<6;i++){layers[i][0]=10000; layers[i][1]=0;}
2014 for (Int_t ns=0;ns<maxSec;ns++){
2015 for (Int_t ilayer=0;ilayer<fTrSec[ns]->GetNumberOfLayers();ilayer++){
2016 AliTRDpropagationLayer& layer=*(fTrSec[ns]->GetLayer(ilayer));
2017 if (layer==0) continue;
2018 Int_t det = layer[0]->GetDetector();
2019 Int_t plane = fGeom->GetPlane(det);
2020 if (ilayer<layers[plane][0]) layers[plane][0] = ilayer;
2021 if (ilayer>layers[plane][1]) layers[plane][1] = ilayer;
2026 Int_t ilayer1 = layers[5][1]; // time bin in mplification region
2027 Int_t ilayer2 = layers[3][1]; //
2028 Int_t ilayerM = layers[4][1]; //
2030 Double_t x1 = fTrSec[0]->GetX(ilayer1);
2031 Double_t x2 = fTrSec[0]->GetX(ilayer2);
2032 Double_t xm = fTrSec[0]->GetX(ilayerM);
2033 Double_t dist = x2-x1;
2034 // Int_t indexes1[20];
2035 //Int_t indexes2[20];
2036 AliTRDcluster *clusters1[15],*clusters2[15],*clustersM[15];
2039 for (Int_t ns=0; ns<maxSec; ns++) {
2040 AliTRDpropagationLayer& layer1=*(fTrSec[ns]->GetLayer(ilayer1)); //select propagation layers
2041 AliTRDpropagationLayer& layer2=*(fTrSec[ns]->GetLayer(ilayer2));
2043 for (Int_t icl1=0;icl1<layer1;icl1++){
2044 AliTRDcluster *cl1 = layer1[icl1];
2046 Double_t y1 = cl1->GetY();
2047 Double_t z1 = cl1->GetZ();
2049 for (Int_t icl2=0;icl2<layer2;icl2++){
2050 AliTRDcluster *cl2 = layer2[icl2];
2052 Double_t y2 = cl2->GetY();
2053 Double_t z2 = cl2->GetZ();
2054 Double_t tanphi = (y2-y1)/dist;
2055 Double_t tantheta = (z2-z1)/dist;
2056 if (TMath::Abs(tanphi)>maxphi) continue;
2057 if (TMath::Abs(tantheta)>maxtheta) continue;
2061 Double_t road = 0.5+TMath::Abs(tanphi)*1;
2063 Double_t sum1=0, sumx1=0,sum2x1=0,sumxy1=0, sumy1=0;
2064 Double_t sum2=0, sumx2=0,sum2x2=0,sumxy2=0, sumy2=0;
2066 for (Int_t dlayer=1;dlayer<15;dlayer++){
2067 clusters1[dlayer]=0;
2068 clusters2[dlayer]=0;
2069 AliTRDpropagationLayer& layer1C=*(fTrSec[ns]->GetLayer(ilayer1-dlayer)); //select propagation layers
2070 AliTRDpropagationLayer& layer2C=*(fTrSec[ns]->GetLayer(ilayer2-dlayer)); //
2071 Double_t yy1 = y1+(tanphi) *(layer1C.GetX()-x1);
2072 Double_t zz1 = z1+(tantheta)*(layer1C.GetX()-x1);
2073 Double_t yy2 = y1+(tanphi) *(layer2C.GetX()-x1);
2074 Double_t zz2 = z1+(tantheta)*(layer2C.GetX()-x1);
2075 Int_t index1 = layer1C.FindNearestCluster(yy1,zz1,road);
2076 Int_t index2 = layer2C.FindNearestCluster(yy2,zz2,road);
2078 clusters1[dlayer]= (AliTRDcluster*)GetCluster(index1);
2081 Double_t dx = layer1C.GetX()-x1;
2084 sumxy1+=dx*clusters1[dlayer]->GetY();
2085 sumy1 +=clusters1[dlayer]->GetY();
2088 clusters2[dlayer]= (AliTRDcluster*)GetCluster(index2);
2091 Double_t dx = layer2C.GetX()-x2;
2094 sumxy2+=dx*clusters2[dlayer]->GetY();
2095 sumy2 +=clusters2[dlayer]->GetY();
2098 if (sum1<10) continue;
2099 if (sum2<10) continue;
2101 Double_t det1 = sum1*sum2x1-sumx1*sumx1;
2102 Double_t angle1 = (sum1*sumxy1-sumx1*sumy1)/det1;
2103 Double_t pos1 = (sum2x1*sumy1-sumx1*sumxy1)/det1; // at x1
2105 Double_t det2 = sum2*sum2x2-sumx2*sumx2;
2106 Double_t angle2 = (sum2*sumxy2-sumx2*sumy2)/det2;
2107 Double_t pos2 = (sum2x2*sumy2-sumx2*sumxy2)/det2; // at x2
2111 Double_t sumM=0, sumxM=0,sum2xM=0,sumxyM=0, sumyM=0;
2113 for (Int_t dlayer=1;dlayer<15;dlayer++){
2114 clustersM[dlayer]=0;
2115 AliTRDpropagationLayer& layerM=*(fTrSec[ns]->GetLayer(ilayerM-dlayer)); //select propagation layers
2116 Double_t yyM = y1+(tanphi) *(layerM.GetX()-x1);
2117 Double_t zzM = z1+(tantheta)*(layerM.GetX()-x1);
2118 Int_t indexM = layerM.FindNearestCluster(yyM,zzM,road);
2120 clustersM[dlayer]= (AliTRDcluster*)GetCluster(indexM);
2123 Double_t dx = layerM.GetX()-xm;
2126 sumxyM+=dx*clustersM[dlayer]->GetY();
2127 sumyM +=clustersM[dlayer]->GetY();
2130 Double_t detM = sumM*sum2xM-sumxM*sumxM;
2131 Double_t posM=0, angleM=0;
2132 if (TMath::Abs(detM)>0.0000001){
2133 angleM = (sumM*sumxyM-sumxM*sumyM)/detM;
2134 posM = (sum2xM*sumyM-sumxM*sumxyM)/detM; // at xm
2139 TTreeSRedirector& cstream = *fDebugStreamer;
2148 "Theta="<<tantheta<<
2162 //_____________________________________________________________________________
2163 Int_t AliTRDtracker::ReadClusters(TObjArray *array, TTree *ClusterTree) const
2166 // Reads AliTRDclusters (option >= 0) or AliTRDrecPoints (option < 0)
2167 // from the file. The names of the cluster tree and branches
2168 // should match the ones used in AliTRDclusterizer::WriteClusters()
2170 Int_t nsize = Int_t(ClusterTree->GetTotBytes()/(sizeof(AliTRDcluster)));
2171 TObjArray *clusterArray = new TObjArray(nsize+1000);
2173 TBranch *branch=ClusterTree->GetBranch("TRDcluster");
2175 Error("ReadClusters","Can't get the branch !");
2178 branch->SetAddress(&clusterArray);
2180 Int_t nEntries = (Int_t) ClusterTree->GetEntries();
2181 // printf("found %d entries in %s.\n",nEntries,ClusterTree->GetName());
2183 // Loop through all entries in the tree
2185 AliTRDcluster *c = 0;
2187 for (Int_t iEntry = 0; iEntry < nEntries; iEntry++) {
2190 nbytes += ClusterTree->GetEvent(iEntry);
2192 // Get the number of points in the detector
2193 Int_t nCluster = clusterArray->GetEntriesFast();
2194 // printf("\r Read %d clusters from entry %d", nCluster, iEntry);
2196 // Loop through all TRD digits
2197 for (Int_t iCluster = 0; iCluster < nCluster; iCluster++) {
2198 c = (AliTRDcluster*)clusterArray->UncheckedAt(iCluster);
2199 // if (c->GetNPads()>3&&(iCluster%3>0)) {
2200 // delete clusterArray->RemoveAt(iCluster);
2203 // AliTRDcluster *co = new AliTRDcluster(*c); //remove unnecesary coping - + clusters are together in memory
2204 AliTRDcluster *co = c;
2205 co->SetSigmaY2(c->GetSigmaY2() * fSY2corr);
2206 Int_t ltb = co->GetLocalTimeBin();
2207 if(ltb == 19) co->SetSigmaZ2(c->GetSigmaZ2());
2208 else if(fNoTilt) co->SetSigmaZ2(c->GetSigmaZ2() * fSZ2corr);
2210 // delete clusterArray->RemoveAt(iCluster);
2211 clusterArray->RemoveAt(iCluster);
2214 // cout<<"Allocated"<<nsize<<"\tLoaded"<<array->GetEntriesFast()<<"\n";
2216 delete clusterArray;
2221 //__________________________________________________________________
2222 void AliTRDtracker::CookLabel(AliKalmanTrack* pt, Float_t wrong) const
2225 // This cooks a label. Mmmmh, smells good...
2228 Int_t label=123456789, index, i, j;
2229 Int_t ncl=pt->GetNumberOfClusters();
2230 const Int_t kRange = fTrSec[0]->GetOuterTimeBin()+1;
2234 // Int_t s[kRange][2];
2235 Int_t **s = new Int_t* [kRange];
2236 for (i=0; i<kRange; i++) {
2237 s[i] = new Int_t[2];
2239 for (i=0; i<kRange; i++) {
2245 for (i=0; i<ncl; i++) {
2246 index=pt->GetClusterIndex(i);
2247 AliTRDcluster *c=(AliTRDcluster*)fClusters->UncheckedAt(index);
2253 for (i=0; i<ncl; i++) {
2254 index=pt->GetClusterIndex(i);
2255 AliTRDcluster *c=(AliTRDcluster*)fClusters->UncheckedAt(index);
2256 for (Int_t k=0; k<3; k++) {
2257 label=c->GetLabel(k);
2258 labelAdded=kFALSE; j=0;
2260 while ( (!labelAdded) && ( j < kRange ) ) {
2261 if (s[j][0]==label || s[j][1]==0) {
2275 for (i=0; i<kRange; i++) {
2277 max=s[i][1]; label=s[i][0];
2281 for (i=0; i<kRange; i++) {
2287 if ((1.- Float_t(max)/ncl) > wrong) label=-label;
2289 pt->SetLabel(label);
2294 //__________________________________________________________________
2295 void AliTRDtracker::UseClusters(const AliKalmanTrack* t, Int_t from) const
2298 // Use clusters, but don't abuse them!
2301 Int_t ncl=t->GetNumberOfClusters();
2302 for (Int_t i=from; i<ncl; i++) {
2303 Int_t index = t->GetClusterIndex(i);
2304 AliTRDcluster *c=(AliTRDcluster*)fClusters->UncheckedAt(index);
2310 //_____________________________________________________________________
2311 Double_t AliTRDtracker::ExpectedSigmaY2(Double_t , Double_t , Double_t ) const
2313 // Parametrised "expected" error of the cluster reconstruction in Y
2315 Double_t s = 0.08 * 0.08;
2319 //_____________________________________________________________________
2320 Double_t AliTRDtracker::ExpectedSigmaZ2(Double_t , Double_t ) const
2322 // Parametrised "expected" error of the cluster reconstruction in Z
2324 Double_t s = 9 * 9 /12.;
2328 //_____________________________________________________________________
2329 Double_t AliTRDtracker::GetX(Int_t sector, Int_t plane, Int_t localTB) const
2332 // Returns radial position which corresponds to time bin <localTB>
2333 // in tracking sector <sector> and plane <plane>
2336 Int_t index = fTrSec[sector]->CookTimeBinIndex(plane, localTB);
2337 Int_t pl = fTrSec[sector]->GetLayerNumber(index);
2338 return fTrSec[sector]->GetLayer(pl)->GetX();
2343 //_______________________________________________________
2344 AliTRDtracker::AliTRDpropagationLayer::AliTRDpropagationLayer(Double_t x,
2345 Double_t dx, Double_t rho, Double_t radLength, Int_t tbIndex)
2348 // AliTRDpropagationLayer constructor
2351 fN = 0; fX = x; fdX = dx; fRho = rho; fX0 = radLength;
2352 fClusters = NULL; fIndex = NULL; fTimeBinIndex = tbIndex;
2355 for(Int_t i=0; i < (Int_t) kZones; i++) {
2356 fZc[i]=0; fZmax[i] = 0;
2361 if(fTimeBinIndex >= 0) {
2362 fClusters = new AliTRDcluster*[kMaxClusterPerTimeBin];
2363 fIndex = new UInt_t[kMaxClusterPerTimeBin];
2366 for (Int_t i=0;i<5;i++) fIsHole[i] = kFALSE;
2377 //_______________________________________________________
2378 void AliTRDtracker::AliTRDpropagationLayer::SetHole(
2379 Double_t Zmax, Double_t Ymax, Double_t rho,
2380 Double_t radLength, Double_t Yc, Double_t Zc)
2383 // Sets hole in the layer
2391 fHoleX0 = radLength;
2395 //_______________________________________________________
2396 AliTRDtracker::AliTRDtrackingSector::AliTRDtrackingSector(AliTRDgeometry* geo, Int_t gs, AliTRDparameter* par)
2399 // AliTRDtrackingSector Constructor
2401 AliTRDpadPlane *padPlane = 0;
2409 // get holes description from geometry
2410 Bool_t holes[AliTRDgeometry::kNcham];
2411 //printf("sector\t%d\t",gs);
2412 for (Int_t icham=0; icham<AliTRDgeometry::kNcham;icham++){
2413 holes[icham] = fGeom->IsHole(0,icham,gs);
2414 //printf("%d",holes[icham]);
2418 for(UInt_t i=0; i < kMaxTimeBinIndex; i++) fTimeBinIndex[i] = -1;
2421 AliTRDpropagationLayer* ppl;
2423 Double_t x, xin, xout, dx, rho, radLength;
2426 // set time bins in the gas of the TPC
2428 xin = 246.055; xout = 254.055; steps = 20; dx = (xout-xin)/steps;
2429 rho = 0.9e-3; radLength = 28.94;
2431 for(Int_t i=0; i<steps; i++) {
2432 x = xin + i*dx + dx/2;
2433 ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,-1);
2437 // set time bins in the outer field cage vessel
2439 dx = 50e-4; xin = xout; xout = xin + dx; rho = 1.71; radLength = 44.77; // Tedlar
2440 ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
2443 dx = 0.02; xin = xout; xout = xin + dx; rho = 1.45; radLength = 44.86; // prepreg
2444 ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
2447 dx = 2.; xin = xout; xout = xin + dx; rho = 1.45*0.02; radLength = 41.28; // Nomex
2448 steps = 5; dx = (xout - xin)/steps;
2449 for(Int_t i=0; i<steps; i++) {
2450 x = xin + i*dx + dx/2;
2451 ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,-1);
2455 dx = 0.02; xin = xout; xout = xin + dx; rho = 1.45; radLength = 44.86; // prepreg
2456 ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
2459 dx = 50e-4; xin = xout; xout = xin + dx; rho = 1.71; radLength = 44.77; // Tedlar
2460 ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
2464 // set time bins in CO2
2466 xin = xout; xout = 275.0;
2467 steps = 50; dx = (xout - xin)/steps;
2468 rho = 1.977e-3; radLength = 36.2;
2470 for(Int_t i=0; i<steps; i++) {
2471 x = xin + i*dx + dx/2;
2472 ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,-1);
2476 // set time bins in the outer containment vessel
2478 dx = 50e-4; xin = xout; xout = xin + dx; rho = 2.7; radLength = 24.01; // Al
2479 ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
2482 dx = 50e-4; xin = xout; xout = xin + dx; rho = 1.71; radLength = 44.77; // Tedlar
2483 ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
2486 dx = 0.06; xin = xout; xout = xin + dx; rho = 1.45; radLength = 44.86; // prepreg
2487 ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
2490 dx = 3.; xin = xout; xout = xin + dx; rho = 1.45*0.02; radLength = 41.28; // Nomex
2491 steps = 10; dx = (xout - xin)/steps;
2492 for(Int_t i=0; i<steps; i++) {
2493 x = xin + i*dx + dx/2;
2494 ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,-1);
2498 dx = 0.06; xin = xout; xout = xin + dx; rho = 1.45; radLength = 44.86; // prepreg
2499 ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
2502 dx = 50e-4; xin = xout; xout = xin + dx; rho = 1.71; radLength = 44.77; // Tedlar
2503 ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
2506 dx = 50e-4; xin = xout; xout = xin + dx; rho = 2.7; radLength = 24.01; // Al
2507 ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
2510 Double_t xtrd = (Double_t) fGeom->Rmin();
2512 // add layers between TPC and TRD (Air temporarily)
2513 xin = xout; xout = xtrd;
2514 steps = 50; dx = (xout - xin)/steps;
2515 rho = 1.2e-3; radLength = 36.66;
2517 for(Int_t i=0; i<steps; i++) {
2518 x = xin + i*dx + dx/2;
2519 ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,-1);
2524 // Double_t alpha=AliTRDgeometry::GetAlpha();
2526 // add layers for each of the planes
2528 Double_t dxRo = (Double_t) fGeom->CroHght(); // Rohacell
2529 Double_t dxSpace = (Double_t) fGeom->Cspace(); // Spacing between planes
2530 Double_t dxAmp = (Double_t) fGeom->CamHght(); // Amplification region
2531 Double_t dxDrift = (Double_t) fGeom->CdrHght(); // Drift region
2532 Double_t dxRad = (Double_t) fGeom->CraHght(); // Radiator
2533 Double_t dxTEC = dxRad + dxDrift + dxAmp + dxRo;
2534 Double_t dxPlane = dxTEC + dxSpace;
2537 const Int_t kNchambers = AliTRDgeometry::Ncham();
2540 Double_t ymaxsensitive=0;
2541 Double_t *zc = new Double_t[kNchambers];
2542 Double_t *zmax = new Double_t[kNchambers];
2543 Double_t *zmaxsensitive = new Double_t[kNchambers];
2544 // Double_t holeZmax = 1000.; // the whole sector is missing
2546 for(Int_t plane = 0; plane < AliTRDgeometry::Nplan(); plane++) {
2549 xin = xtrd + plane * dxPlane; xout = xin + dxRad;
2550 steps = 12; dx = (xout - xin)/steps; rho = 0.074; radLength = 40.6;
2551 for(Int_t i=0; i<steps; i++) {
2552 x = xin + i*dx + dx/2;
2553 ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,-1);
2557 ymax = fGeom->GetChamberWidth(plane)/2.;
2558 // Modidified for new pad plane class, 22.04.05 (C.B.)
2559 // ymaxsensitive = (fPar->GetColPadSize(plane)*fPar->GetColMax(plane)-4)/2.;
2560 padPlane = fPar->GetPadPlane(plane,0);
2561 ymaxsensitive = (padPlane->GetColSize(1)*padPlane->GetNcols()-4)/2.;
2563 // ymaxsensitive = (fPar->GetColPadSize(plane)*fPar->GetColMax(plane)-4)/2.;
2565 for(Int_t ch = 0; ch < kNchambers; ch++) {
2566 zmax[ch] = fGeom->GetChamberLength(plane,ch)/2;
2568 // Modidified for new pad plane class, 22.04.05 (C.B.)
2569 //Float_t pad = fPar->GetRowPadSize(plane,ch,0);
2570 Float_t pad = padPlane->GetRowSize(1);
2571 //Float_t pad = fPar->GetRowPadSize(plane,ch,0);
2572 Float_t row0 = fPar->GetRow0(plane,ch,0);
2573 Int_t nPads = fPar->GetRowMax(plane,ch,0);
2574 zmaxsensitive[ch] = Float_t(nPads)*pad/2.;
2575 // zc[ch] = (pad * nPads)/2 + row0 - pad/2;
2576 // zc[ch] = (pad * nPads)/2 + row0;
2577 zc[ch] = -(pad * nPads)/2 + row0;
2578 //zc[ch] = row0+zmax[ch]-AliTRDgeometry::RpadW();
2582 dx = fgkDriftCorrection*fPar->GetDriftVelocity()
2583 / fPar->GetSamplingFrequency();
2584 rho = 0.00295 * 0.85; radLength = 11.0;
2586 Double_t x0 = (Double_t) fPar->GetTime0(plane);
2587 Double_t xbottom = x0 - dxDrift;
2588 Double_t xtop = x0 + dxAmp;
2590 // Amplification region
2591 steps = (Int_t) (dxAmp/dx);
2593 for(tb = 0; tb < steps; tb++) {
2594 x = x0 + tb * dx + dx/2+ fgkOffsetX;
2595 tbIndex = CookTimeBinIndex(plane, -tb-1);
2596 ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,tbIndex);
2597 ppl->SetYmax(ymax,ymaxsensitive);
2598 ppl->SetZ(zc, zmax, zmaxsensitive);
2599 ppl->SetHoles(holes);
2602 tbIndex = CookTimeBinIndex(plane, -steps);
2603 x = (x + dx/2 + xtop)/2;
2605 ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,tbIndex);
2606 ppl->SetYmax(ymax,ymaxsensitive);
2607 ppl->SetZ(zc, zmax,zmaxsensitive);
2608 ppl->SetHoles(holes);
2613 dx = fgkDriftCorrection*fPar->GetDriftVelocity()
2614 / fPar->GetSamplingFrequency();
2615 steps = (Int_t) (dxDrift/dx)+3;
2617 for(tb = 0; tb < steps; tb++) {
2618 x = x0 - tb * dx - dx/2 + fgkOffsetX; //temporary fix - fix it the parameters
2619 tbIndex = CookTimeBinIndex(plane, tb);
2621 ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,tbIndex);
2622 ppl->SetYmax(ymax,ymaxsensitive);
2623 ppl->SetZ(zc, zmax, zmaxsensitive);
2624 ppl->SetHoles(holes);
2627 tbIndex = CookTimeBinIndex(plane, steps);
2628 x = (x - dx/2 + xbottom)/2;
2630 ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,tbIndex);
2631 ppl->SetYmax(ymax,ymaxsensitive);
2632 ppl->SetZ(zc, zmax, zmaxsensitive);
2633 ppl->SetHoles(holes);
2637 xin = xtop; dx = 0.025; xout = xin + dx; rho = 1.7; radLength = 33.0;
2638 ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
2639 ppl->SetYmax(ymax,ymaxsensitive);
2640 ppl->SetZ(zc, zmax,zmax);
2641 ppl->SetHoles(holes);
2645 xin = xout; xout = xtrd + (plane + 1) * dxPlane - dxSpace;
2646 steps = 5; dx = (xout - xin)/steps; rho = 0.074; radLength = 40.6;
2647 for(Int_t i=0; i<steps; i++) {
2648 x = xin + i*dx + dx/2;
2649 ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,-1);
2650 ppl->SetYmax(ymax,ymaxsensitive);
2651 ppl->SetZ(zc, zmax,zmax);
2652 ppl->SetHoles(holes);
2656 // Space between the chambers, air
2657 xin = xout; xout = xtrd + (plane + 1) * dxPlane;
2658 steps = 5; dx = (xout - xin)/steps; rho = 1.29e-3; radLength = 36.66;
2659 for(Int_t i=0; i<steps; i++) {
2660 x = xin + i*dx + dx/2;
2661 ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,-1);
2666 // Space between the TRD and RICH
2667 Double_t xRICH = 500.;
2668 xin = xout; xout = xRICH;
2669 steps = 200; dx = (xout - xin)/steps; rho = 1.29e-3; radLength = 36.66;
2670 for(Int_t i=0; i<steps; i++) {
2671 x = xin + i*dx + dx/2;
2672 ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,-1);
2679 delete [] zmaxsensitive;
2683 //______________________________________________________
2685 Int_t AliTRDtracker::AliTRDtrackingSector::CookTimeBinIndex(Int_t plane, Int_t localTB) const
2688 // depending on the digitization parameters calculates "global"
2689 // time bin index for timebin <localTB> in plane <plane>
2692 Double_t dxAmp = (Double_t) fGeom->CamHght(); // Amplification region
2693 Double_t dxDrift = (Double_t) fGeom->CdrHght(); // Drift region
2695 Double_t dx = fgkDriftCorrection*(Double_t) fPar->GetDriftVelocity()
2696 / fPar->GetSamplingFrequency();
2698 Int_t tbAmp = fPar->GetTimeBefore();
2699 Int_t maxAmp = (Int_t) ((dxAmp+0.000001)/dx);
2700 if(kTRUE) maxAmp = 0; // intentional until we change parameter class
2701 Int_t tbDrift = fPar->GetTimeMax();
2702 Int_t maxDrift = (Int_t) ((dxDrift+0.000001)/dx)+4; // MI change - take also last time bins
2704 Int_t tbPerPlane = TMath::Min(tbAmp,maxAmp) + TMath::Min(tbDrift,maxDrift);
2706 Int_t gtb = (plane+1) * tbPerPlane - localTB - 1 - TMath::Min(tbAmp,maxAmp);
2709 (TMath::Abs(localTB) > TMath::Min(tbAmp,maxAmp))) return -1;
2710 if(localTB >= TMath::Min(tbDrift,maxDrift)) return -1;
2717 //______________________________________________________
2719 void AliTRDtracker::AliTRDtrackingSector::MapTimeBinLayers()
2722 // For all sensitive time bins sets corresponding layer index
2723 // in the array fTimeBins
2728 for(Int_t i = 0; i < fN; i++) {
2729 index = fLayers[i]->GetTimeBinIndex();
2731 // printf("gtb %d -> pl %d -> x %f \n", index, i, fLayers[i]->GetX());
2733 if(index < 0) continue;
2734 if(index >= (Int_t) kMaxTimeBinIndex) {
2735 printf("*** AliTRDtracker::MapTimeBinLayers: \n");
2736 printf(" index %d exceeds allowed maximum of %d!\n",
2737 index, kMaxTimeBinIndex-1);
2740 fTimeBinIndex[index] = i;
2743 Double_t x1, dx1, x2, dx2, gap;
2745 for(Int_t i = 0; i < fN-1; i++) {
2746 x1 = fLayers[i]->GetX();
2747 dx1 = fLayers[i]->GetdX();
2748 x2 = fLayers[i+1]->GetX();
2749 dx2 = fLayers[i+1]->GetdX();
2750 gap = (x2 - dx2/2) - (x1 + dx1/2);
2751 // if(gap < -0.01) {
2752 // printf("*** warning: layers %d and %d are overlayed:\n",i,i+1);
2753 // printf(" %f + %f + %f > %f\n", x1, dx1/2, dx2/2, x2);
2756 // printf("*** warning: layers %d and %d have a large gap:\n",i,i+1);
2757 // printf(" (%f - %f) - (%f + %f) = %f\n",
2758 // x2, dx2/2, x1, dx1, gap);
2764 //______________________________________________________
2767 Int_t AliTRDtracker::AliTRDtrackingSector::GetLayerNumber(Double_t x) const
2770 // Returns the number of time bin which in radial position is closest to <x>
2773 if(x >= fLayers[fN-1]->GetX()) return fN-1;
2774 if(x <= fLayers[0]->GetX()) return 0;
2776 Int_t b=0, e=fN-1, m=(b+e)/2;
2777 for (; b<e; m=(b+e)/2) {
2778 if (x > fLayers[m]->GetX()) b=m+1;
2781 if(TMath::Abs(x - fLayers[m]->GetX()) >
2782 TMath::Abs(x - fLayers[m+1]->GetX())) return m+1;
2787 //______________________________________________________
2789 Int_t AliTRDtracker::AliTRDtrackingSector::GetInnerTimeBin() const
2792 // Returns number of the innermost SENSITIVE propagation layer
2795 return GetLayerNumber(0);
2798 //______________________________________________________
2800 Int_t AliTRDtracker::AliTRDtrackingSector::GetOuterTimeBin() const
2803 // Returns number of the outermost SENSITIVE time bin
2806 return GetLayerNumber(GetNumberOfTimeBins() - 1);
2809 //______________________________________________________
2811 Int_t AliTRDtracker::AliTRDtrackingSector::GetNumberOfTimeBins() const
2814 // Returns number of SENSITIVE time bins
2818 for(tb = kMaxTimeBinIndex-1; tb >=0; tb--) {
2819 layer = GetLayerNumber(tb);
2825 //______________________________________________________
2827 void AliTRDtracker::AliTRDtrackingSector::InsertLayer(AliTRDpropagationLayer* pl)
2830 // Insert layer <pl> in fLayers array.
2831 // Layers are sorted according to X coordinate.
2833 if ( fN == ((Int_t) kMaxLayersPerSector)) {
2834 printf("AliTRDtrackingSector::InsertLayer(): Too many layers !\n");
2837 if (fN==0) {fLayers[fN++] = pl; return;}
2838 Int_t i=Find(pl->GetX());
2840 memmove(fLayers+i+1 ,fLayers+i,(fN-i)*sizeof(AliTRDpropagationLayer*));
2841 fLayers[i]=pl; fN++;
2845 //______________________________________________________
2847 Int_t AliTRDtracker::AliTRDtrackingSector::Find(Double_t x) const
2850 // Returns index of the propagation layer nearest to X
2853 if (x <= fLayers[0]->GetX()) return 0;
2854 if (x > fLayers[fN-1]->GetX()) return fN;
2855 Int_t b=0, e=fN-1, m=(b+e)/2;
2856 for (; b<e; m=(b+e)/2) {
2857 if (x > fLayers[m]->GetX()) b=m+1;
2867 //______________________________________________________
2868 void AliTRDtracker::AliTRDpropagationLayer::SetZ(Double_t* center, Double_t *w, Double_t *wsensitive )
2871 // set centers and the width of sectors
2872 for (Int_t icham=0;icham< AliTRDgeometry::kNcham;icham++){
2873 fZc[icham] = center[icham];
2874 fZmax[icham] = w[icham];
2875 fZmaxSensitive[icham] = wsensitive[icham];
2876 // printf("chamber\t%d\tzc\t%f\tzmax\t%f\tzsens\t%f\n",icham,fZc[icham],fZmax[icham],fZmaxSensitive[icham]);
2879 //______________________________________________________
2881 void AliTRDtracker::AliTRDpropagationLayer::SetHoles(Bool_t *holes)
2884 // set centers and the width of sectors
2886 for (Int_t icham=0;icham< AliTRDgeometry::kNcham;icham++){
2887 fIsHole[icham] = holes[icham];
2888 if (holes[icham]) fHole = kTRUE;
2894 Bool_t AliTRDtracker::AliTRDpropagationLayer::GetPropagationParameters(
2895 Double_t y, Double_t z, Double_t &dx, Double_t &rho, Double_t &radLength,
2896 Bool_t &lookForCluster) const
2899 // Returns radial step <dx>, density <rho>, rad. length <radLength>,
2900 // and sensitivity <lookForCluster> in point <y,z>
2903 Double_t alpha = AliTRDgeometry::GetAlpha();
2904 Double_t ymax = fX*TMath::Tan(0.5*alpha);
2910 lookForCluster = kFALSE;
2911 Bool_t cross =kFALSE;
2914 if ( (ymax-TMath::Abs(y))<3.){ //cross material
2920 // check dead regions in sensitive volume
2923 for(Int_t ch = 0; ch < (Int_t) kZones; ch++) {
2924 if (TMath::Abs(z - fZc[ch]) > fZmax[ch]) continue; //not in given zone
2926 if (TMath::Abs(z - fZc[ch]) < fZmaxSensitive[ch]){
2927 if (fTimeBinIndex>=0) lookForCluster = !(fIsHole[zone]);
2928 if(TMath::Abs(y) > fYmaxSensitive){
2929 lookForCluster = kFALSE;
2931 if (fIsHole[zone]) {
2937 cross = kTRUE; rho = 2.7; radLength = 24.01; //aluminium in between
2941 if (fTimeBinIndex>=0) return cross;
2945 if (fHole==kFALSE) return cross;
2947 for(Int_t ch = 0; ch < (Int_t) kZones; ch++) {
2948 if (TMath::Abs(z - fZc[ch]) < fZmax[ch]){
2959 Int_t AliTRDtracker::AliTRDpropagationLayer::GetZone( Double_t z) const
2963 if (fTimeBinIndex < 0) return -20; //unknown
2964 Int_t zone=-10; // dead zone
2965 for(Int_t ch = 0; ch < (Int_t) kZones; ch++) {
2966 if(TMath::Abs(z - fZc[ch]) < fZmax[ch])
2973 //______________________________________________________
2975 void AliTRDtracker::AliTRDpropagationLayer::InsertCluster(AliTRDcluster* c,
2978 // Insert cluster in cluster array.
2979 // Clusters are sorted according to Y coordinate.
2981 if(fTimeBinIndex < 0) {
2982 printf("*** attempt to insert cluster into non-sensitive time bin!\n");
2986 if (fN== (Int_t) kMaxClusterPerTimeBin) {
2987 printf("AliTRDpropagationLayer::InsertCluster(): Too many clusters !\n");
2990 if (fN==0) {fIndex[0]=index; fClusters[fN++]=c; return;}
2991 Int_t i=Find(c->GetY());
2992 memmove(fClusters+i+1 ,fClusters+i,(fN-i)*sizeof(AliTRDcluster*));
2993 memmove(fIndex +i+1 ,fIndex +i,(fN-i)*sizeof(UInt_t));
2994 fIndex[i]=index; fClusters[i]=c; fN++;
2997 //______________________________________________________
2999 Int_t AliTRDtracker::AliTRDpropagationLayer::Find(Double_t y) const {
3001 // Returns index of the cluster nearest in Y
3003 if (y <= fClusters[0]->GetY()) return 0;
3004 if (y > fClusters[fN-1]->GetY()) return fN;
3005 Int_t b=0, e=fN-1, m=(b+e)/2;
3006 for (; b<e; m=(b+e)/2) {
3007 if (y > fClusters[m]->GetY()) b=m+1;
3013 Int_t AliTRDtracker::AliTRDpropagationLayer::FindNearestCluster(Double_t y, Double_t z, Double_t maxroad) const
3016 // Returns index of the cluster nearest to the given y,z
3020 Double_t mindist = maxroad;
3021 Float_t padlength =-1;
3023 for (Int_t i=Find(y-maxroad); i<maxn; i++) {
3024 AliTRDcluster* c=(AliTRDcluster*)(fClusters[i]);
3026 padlength = TMath::Sqrt(c->GetSigmaZ2()*12);
3029 if (c->GetY() > y+maxroad) break;
3030 if((c->GetZ()-z)*(c->GetZ()-z) > padlength*0.75) continue;
3031 if (TMath::Abs(c->GetY()-y)<mindist){
3032 mindist = TMath::Abs(c->GetY()-y);
3033 index = GetIndex(i);
3040 //---------------------------------------------------------
3042 Double_t AliTRDtracker::GetTiltFactor(const AliTRDcluster* c) {
3044 // Returns correction factor for tilted pads geometry
3046 Int_t det = c->GetDetector();
3047 Int_t plane = fGeom->GetPlane(det);
3048 AliTRDpadPlane *padPlane = fPar->GetPadPlane(plane,0);
3049 Double_t h01 = TMath::Tan(-TMath::Pi() / 180.0 * padPlane->GetTiltingAngle());
3051 if(fNoTilt) h01 = 0;
3056 void AliTRDtracker::CookdEdxTimBin(AliTRDtrack& TRDtrack)
3058 // *** ADDED TO GET MORE INFORMATION FOR TRD PID ---- PS
3059 // This is setting fdEdxPlane and fTimBinPlane
3060 // Sums up the charge in each plane for track TRDtrack and also get the
3061 // Time bin for Max. Cluster
3062 // Prashant Shukla (shukla@physi.uni-heidelberg.de)
3064 // const Int_t kNPlane = AliTRDgeometry::Nplan();
3065 // const Int_t kNPlane = 6;
3066 Double_t clscharge[kNPlane], maxclscharge[kNPlane];
3067 Int_t nCluster[kNPlane], timebin[kNPlane];
3069 //Initialization of cluster charge per plane.
3070 for (Int_t iPlane = 0; iPlane < kNPlane; iPlane++) {
3071 clscharge[iPlane] = 0.0;
3072 nCluster[iPlane] = 0;
3073 timebin[iPlane] = -1;
3074 maxclscharge[iPlane] = 0.0;
3077 // Loop through all clusters associated to track TRDtrack
3078 Int_t nClus = TRDtrack.GetNumberOfClusters(); // from Kalmantrack
3079 for (Int_t iClus = 0; iClus < nClus; iClus++) {
3080 Double_t charge = TRDtrack.GetClusterdQdl(iClus);
3081 Int_t index = TRDtrack.GetClusterIndex(iClus);
3082 AliTRDcluster *TRDcluster = (AliTRDcluster *) GetCluster(index);
3083 if (!TRDcluster) continue;
3084 Int_t tb = TRDcluster->GetLocalTimeBin();
3086 Int_t detector = TRDcluster->GetDetector();
3087 Int_t iPlane = fGeom->GetPlane(detector);
3088 clscharge[iPlane] = clscharge[iPlane]+charge;
3089 if(charge > maxclscharge[iPlane]) {
3090 maxclscharge[iPlane] = charge;
3091 timebin[iPlane] = tb;
3094 } // end of loop over cluster
3096 // Setting the fdEdxPlane and fTimBinPlane variabales
3097 Double_t Total_ch = 0;
3098 for (Int_t iPlane = 0; iPlane < kNPlane; iPlane++) {
3099 // Quality control of TRD track.
3100 if (nCluster[iPlane]<= 5) {
3101 clscharge[iPlane]=0.0;
3104 if (nCluster[iPlane]) clscharge[iPlane] /= nCluster[iPlane];
3105 TRDtrack.SetPIDsignals(clscharge[iPlane], iPlane);
3106 TRDtrack.SetPIDTimBin(timebin[iPlane], iPlane);
3107 Total_ch= Total_ch+clscharge[iPlane];
3110 // Int_t nc=TRDtrack.GetNumberOfClusters();
3112 // for (i=0; i<nc; i++) dedx += TRDtrack.GetClusterdQdl(i);
3114 // for (Int_t iPlane = 0; iPlane < kNPlane; iPlane++) {
3115 // TRDtrack.SetPIDsignals(dedx, iPlane);
3116 // TRDtrack.SetPIDTimBin(timbin[iPlane], iPlane);
3119 } // end of function
3122 Int_t AliTRDtracker::FindClusters(Int_t sector, Int_t t0, Int_t t1, AliTRDtrack * track, Int_t *clusters,AliTRDtracklet&tracklet)
3126 // try to find nearest clusters to the track in timebins from t0 to t1
3130 // correction coeficients - depends on TRD parameters - to be changed according it
3133 Double_t x[100],yt[100],zt[100];
3134 Double_t xmean=0; //reference x
3135 Double_t dz[10][100],dy[10][100];
3136 Float_t zmean[100], nmean[100];
3138 Int_t indexes[10][100]; // indexes of the clusters in the road
3139 AliTRDcluster *cl[10][100]; // pointers to the clusters in the road
3140 Int_t best[10][100]; // index of best matching cluster
3143 TClonesArray array0("AliTRDcluster",1);
3144 TClonesArray array1("AliTRDcluster",1);
3145 for (Int_t it=0;it<=t1-t0; it++){
3153 for (Int_t ih=0;ih<10;ih++){
3154 indexes[ih][it]=-2; //reset indexes1
3162 Double_t x0 = track->GetX();
3163 Double_t sigmaz = TMath::Sqrt(track->GetSigmaZ2());
3168 Float_t padlength=0;
3169 AliTRDtrack track2(*track);
3170 Float_t snpy = track->GetSnp();
3171 Float_t tany = TMath::Sqrt(snpy*snpy/(1.-snpy*snpy));
3172 if (snpy<0) tany*=-1;
3174 Double_t sy2=ExpectedSigmaY2(x0,track->GetTgl(),track->GetPt());
3175 Double_t sz2=ExpectedSigmaZ2(x0,track->GetTgl());
3176 Double_t road = 15.*sqrt(track->GetSigmaY2() + sy2);
3177 if (road>6.) road=6.;
3180 for (Int_t it=0;it<t1-t0;it++){
3181 Double_t maxChi2[2]={fgkMaxChi2,fgkMaxChi2};
3182 AliTRDpropagationLayer& timeBin=*(fTrSec[sector]->GetLayer(it+t0));
3183 if (timeBin==0) continue; // no indexes1
3184 Int_t maxn = timeBin;
3185 x[it] = timeBin.GetX();
3186 track2.PropagateTo(x[it]);
3187 yt[it] = track2.GetY();
3188 zt[it] = track2.GetZ();
3190 Double_t y=yt[it],z=zt[it];
3191 Double_t chi2 =1000000;
3194 // find 2 nearest cluster at given time bin
3197 for (Int_t i=timeBin.Find(y-road); i<maxn; i++) {
3198 AliTRDcluster* c=(AliTRDcluster*)(timeBin[i]);
3199 h01 = GetTiltFactor(c);
3201 Int_t det = c->GetDetector();
3202 plane = fGeom->GetPlane(det);
3203 padlength = TMath::Sqrt(c->GetSigmaZ2()*12.);
3205 // if (c->GetLocalTimeBin()==0) continue;
3206 if (c->GetY() > y+road) break;
3207 if((c->GetZ()-z)*(c->GetZ()-z) > 12. * sz2) continue;
3209 Double_t dist = TMath::Abs(c->GetZ()-z);
3210 if (dist> (0.5*padlength+6.*sigmaz)) continue; // 6 sigma boundary cut
3213 if (dist> (0.5*padlength-sigmaz)){ // sigma boundary cost function
3214 cost = (dist-0.5*padlength)/(2.*sigmaz);
3215 if (cost>-1) cost= (cost+1.)*(cost+1.);
3218 // Int_t label = TMath::Abs(track->GetLabel());
3219 // if (c->GetLabel(0)!=label && c->GetLabel(1)!=label&&c->GetLabel(2)!=label) continue;
3220 chi2=track2.GetPredictedChi2(c,h01)+cost;
3223 if (chi2 > maxChi2[1]) continue;
3225 for (Int_t ih=2;ih<9; ih++){ //store the clusters in the road
3228 indexes[ih][it] =timeBin.GetIndex(i); // index - 9 - reserved for outliers
3233 if (chi2 <maxChi2[0]){
3234 maxChi2[1] = maxChi2[0];
3236 indexes[1][it] = indexes[0][it];
3237 cl[1][it] = cl[0][it];
3238 indexes[0][it] = timeBin.GetIndex(i);
3244 indexes[1][it] =timeBin.GetIndex(i);
3252 if (nfound<4) return 0;
3253 xmean /=Float_t(nfound); // middle x
3254 track2.PropagateTo(xmean); // propagate track to the center
3256 // choose one of the variants
3262 Double_t sumdy2 = 0;
3272 Double_t moffset[10]; // mean offset
3273 Double_t mean[10]; // mean value
3274 Double_t angle[10]; // angle
3276 Double_t smoffset[10]; // sigma of mean offset
3277 Double_t smean[10]; // sigma of mean value
3278 Double_t sangle[10]; // sigma of angle
3279 Double_t smeanangle[10]; // correlation
3281 Double_t sigmas[10];
3282 Double_t tchi2s[10]; // chi2s for tracklet
3286 for (Int_t it=0;it<t1-t0;it++){
3287 if (!cl[0][it]) continue;
3288 for (Int_t dt=-3;dt<=3;dt++){
3289 if (it+dt<0) continue;
3290 if (it+dt>t1-t0) continue;
3291 if (!cl[0][it+dt]) continue;
3292 zmean[it]+=cl[0][it+dt]->GetZ();
3295 zmean[it]/=nmean[it];
3298 for (Int_t it=0; it<t1-t0;it++){
3300 for (Int_t ih=0;ih<10;ih++){
3303 if (!cl[ih][it]) continue;
3304 Float_t poscor = fgkCoef*(cl[ih][it]->GetLocalTimeBin() - fgkMean)+fgkOffset;
3305 dz[ih][it] = cl[ih][it]->GetZ()- zt[it]; // calculate distance from track in z
3306 dy[ih][it] = cl[ih][it]->GetY()+ dz[ih][it]*h01 - poscor -yt[it]; // in y
3309 if (!cl[0][it]) continue;
3310 if (TMath::Abs(cl[0][it]->GetZ()-zmean[it])> padlength*0.8 &&cl[1][it])
3311 if (TMath::Abs(cl[1][it]->GetZ()-zmean[it])< padlength*0.5){
3316 // iterative choosing of "best path"
3319 Int_t label = TMath::Abs(track->GetLabel());
3322 for (Int_t iter=0;iter<9;iter++){
3325 sumz = 0; sum=0; sumdy=0;sumdy2=0;sumx=0;sumx2=0;sumxy=0;mpads=0; ngood[iter]=0; nbad[iter]=0;
3327 for (Int_t it=0;it<t1-t0;it++){
3328 if (!cl[best[iter][it]][it]) continue;
3329 //calculates pad-row changes
3330 Double_t zbefore= cl[best[iter][it]][it]->GetZ();
3331 Double_t zafter = cl[best[iter][it]][it]->GetZ();
3332 for (Int_t itd = it-1; itd>=0;itd--) {
3333 if (cl[best[iter][itd]][itd]) {
3334 zbefore= cl[best[iter][itd]][itd]->GetZ();
3338 for (Int_t itd = it+1; itd<t1-t0;itd++) {
3339 if (cl[best[iter][itd]][itd]) {
3340 zafter= cl[best[iter][itd]][itd]->GetZ();
3344 if (TMath::Abs(cl[best[iter][it]][it]->GetZ()-zbefore)>0.1&&TMath::Abs(cl[best[iter][it]][it]->GetZ()-zafter)>0.1) changes[iter]++;
3346 Double_t dx = x[it]-xmean; // distance to reference x
3347 sumz += cl[best[iter][it]][it]->GetZ();
3349 sumdy += dy[best[iter][it]][it];
3350 sumdy2+= dy[best[iter][it]][it]*dy[best[iter][it]][it];
3353 sumxy += dx*dy[best[iter][it]][it];
3354 mpads += cl[best[iter][it]][it]->GetNPads();
3355 if (cl[best[iter][it]][it]->GetLabel(0)==label || cl[best[iter][it]][it]->GetLabel(1)==label||cl[best[iter][it]][it]->GetLabel(2)==label){
3363 // calculates line parameters
3365 Double_t det = sum*sumx2-sumx*sumx;
3366 angle[iter] = (sum*sumxy-sumx*sumdy)/det;
3367 mean[iter] = (sumx2*sumdy-sumx*sumxy)/det;
3368 meanz[iter] = sumz/sum;
3369 moffset[iter] = sumdy/sum;
3370 mpads /= sum; // mean number of pads
3373 Double_t sigma2 = 0; // normalized residuals - for line fit
3374 Double_t sigma1 = 0; // normalized residuals - constant fit
3376 for (Int_t it=0;it<t1-t0;it++){
3377 if (!cl[best[iter][it]][it]) continue;
3378 Double_t dx = x[it]-xmean;
3379 Double_t ytr = mean[iter]+angle[iter]*dx;
3380 sigma2 += (dy[best[iter][it]][it]-ytr)*(dy[best[iter][it]][it]-ytr);
3381 sigma1 += (dy[best[iter][it]][it]-moffset[iter])*(dy[best[iter][it]][it]-moffset[iter]);
3384 sigma2 /=(sum-2); // normalized residuals
3385 sigma1 /=(sum-1); // normalized residuals
3387 smean[iter] = sigma2*(sumx2/det); // estimated error2 of mean
3388 sangle[iter] = sigma2*(sum/det); // estimated error2 of angle
3389 smeanangle[iter] = sigma2*(-sumx/det); // correlation
3392 sigmas[iter] = TMath::Sqrt(sigma1); //
3393 smoffset[iter]= (sigma1/sum)+0.01*0.01; // sigma of mean offset + unisochronity sigma
3395 // iterative choosing of "better path"
3397 for (Int_t it=0;it<t1-t0;it++){
3398 if (!cl[best[iter][it]][it]) continue;
3400 Double_t sigmatr2 = smoffset[iter]+0.5*tany*tany; //add unisochronity + angular effect contribution
3401 Double_t sweight = 1./sigmatr2+1./track->fCyy;
3402 Double_t weighty = (moffset[iter]/sigmatr2)/sweight; // weighted mean
3403 Double_t sigmacl = TMath::Sqrt(sigma1*sigma1+track->fCyy); //
3404 Double_t mindist=100000;
3406 for (Int_t ih=0;ih<10;ih++){
3407 if (!cl[ih][it]) break;
3408 Double_t dist2 = (dy[ih][it]-weighty)/sigmacl;
3409 dist2*=dist2; //chi2 distance
3415 best[iter+1][it]=ihbest;
3418 // update best hypothesy if better chi2 according tracklet position and angle
3420 Double_t sy2 = smean[iter] + track->fCyy;
3421 Double_t sa2 = sangle[iter] + track->fCee;
3422 Double_t say = track->fCey;
3423 // Double_t chi20 = mean[bestiter]*mean[bestiter]/sy2+angle[bestiter]*angle[bestiter]/sa2;
3424 // Double_t chi21 = mean[iter]*mean[iter]/sy2+angle[iter]*angle[iter]/sa2;
3426 Double_t detchi = sy2*sa2-say*say;
3427 Double_t invers[3] = {sa2/detchi, sy2/detchi, -say/detchi}; //inverse value of covariance matrix
3429 Double_t chi20 = mean[bestiter]*mean[bestiter]*invers[0]+angle[bestiter]*angle[bestiter]*invers[1]+
3430 2.*mean[bestiter]*angle[bestiter]*invers[2];
3431 Double_t chi21 = mean[iter]*mean[iter]*invers[0]+angle[iter]*angle[iter]*invers[1]+
3432 2*mean[iter]*angle[iter]*invers[2];
3433 tchi2s[iter] =chi21;
3435 if (changes[iter]<=changes[bestiter] && chi21<chi20) {
3442 Double_t sigma2 = sigmas[0]; // choose as sigma from 0 iteration
3443 Short_t maxpos = -1;
3444 Float_t maxcharge = 0;
3445 Short_t maxpos4 = -1;
3446 Float_t maxcharge4 = 0;
3447 Short_t maxpos5 = -1;
3448 Float_t maxcharge5 = 0;
3450 //if (tchi2s[bestiter]>25.) sigma2*=tchi2s[bestiter]/25.;
3451 //if (tchi2s[bestiter]>25.) sigma2=1000.; // dont'accept
3453 Double_t expectederr = sigma2*sigma2+0.01*0.01;
3454 if (mpads>3.5) expectederr += (mpads-3.5)*0.04;
3455 if (changes[bestiter]>1) expectederr+= changes[bestiter]*0.01;
3456 expectederr+=(0.03*(tany-fgkExB)*(tany-fgkExB))*15;
3457 // if (tchi2s[bestiter]>18.) expectederr*= tchi2s[bestiter]/18.;
3458 //expectederr+=10000;
3459 for (Int_t it=0;it<t1-t0;it++){
3460 if (!cl[best[bestiter][it]][it]) continue;
3461 Float_t poscor = fgkCoef*(cl[best[bestiter][it]][it]->GetLocalTimeBin() - fgkMean)+fgkOffset;
3462 cl[best[bestiter][it]][it]->SetSigmaY2(expectederr); // set cluster error
3463 if (!cl[best[bestiter][it]][it]->IsUsed()){
3464 cl[best[bestiter][it]][it]->SetY( cl[best[bestiter][it]][it]->GetY()-poscor); // ExB corrction correction
3465 cl[best[bestiter][it]][it]->Use();
3468 // time bins with maximal charge
3469 if (TMath::Abs(cl[best[bestiter][it]][it]->GetQ())> maxcharge){
3470 maxcharge = TMath::Abs(cl[best[bestiter][it]][it]->GetQ());
3471 maxpos = cl[best[bestiter][it]][it]->GetLocalTimeBin();
3474 if (TMath::Abs(cl[best[bestiter][it]][it]->GetQ())> maxcharge4){
3475 if (cl[best[bestiter][it]][it]->GetLocalTimeBin()>=4){
3476 maxcharge4 = TMath::Abs(cl[best[bestiter][it]][it]->GetQ());
3477 maxpos4 = cl[best[bestiter][it]][it]->GetLocalTimeBin();
3480 if (TMath::Abs(cl[best[bestiter][it]][it]->GetQ())> maxcharge5){
3481 if (cl[best[bestiter][it]][it]->GetLocalTimeBin()>=5){
3482 maxcharge5 = TMath::Abs(cl[best[bestiter][it]][it]->GetQ());
3483 maxpos5 = cl[best[bestiter][it]][it]->GetLocalTimeBin();
3486 clusters[it+t0] = indexes[best[bestiter][it]][it];
3489 // set tracklet parameters
3491 Double_t trackleterr2 = smoffset[bestiter]+0.01*0.01;
3492 if (mpads>3.5) trackleterr2 += (mpads-3.5)*0.04;
3493 trackleterr2+= changes[bestiter]*0.01;
3494 trackleterr2*= TMath::Max(14.-nfound,1.);
3495 trackleterr2+= 0.2*(tany-fgkExB)*(tany-fgkExB);
3497 tracklet.Set(xmean, track2.GetY()+moffset[bestiter], meanz[bestiter], track2.GetAlpha(), trackleterr2); //set tracklet parameters
3498 tracklet.SetTilt(h01);
3499 tracklet.SetP0(mean[bestiter]);
3500 tracklet.SetP1(angle[bestiter]);
3501 tracklet.SetN(nfound);
3502 tracklet.SetNCross(changes[bestiter]);
3503 tracklet.SetPlane(plane);
3504 tracklet.SetSigma2(expectederr);
3505 tracklet.SetChi2(tchi2s[bestiter]);
3506 tracklet.SetMaxPos(maxpos,maxpos4,maxpos5);
3507 track->fTracklets[plane] = tracklet;
3508 track->fNWrong+=nbad[0];
3512 TTreeSRedirector& cstream = *fDebugStreamer;
3513 AliTRDcluster dummy;
3517 for (Int_t it=0;it<t1-t0;it++){
3518 dy0[it] = dy[0][it];
3519 dyb[it] = dy[best[bestiter][it]][it];
3521 new(array0[it]) AliTRDcluster(*cl[0][it]);
3524 new(array0[it]) AliTRDcluster(dummy);
3526 if(cl[best[bestiter][it]][it]) {
3527 new(array1[it]) AliTRDcluster(*cl[best[bestiter][it]][it]);
3530 new(array1[it]) AliTRDcluster(dummy);
3533 TGraph graph0(t1-t0,x,dy0);
3534 TGraph graph1(t1-t0,x,dyb);
3535 TGraph graphy(t1-t0,x,yt);
3536 TGraph graphz(t1-t0,x,zt);
3539 cstream<<"tracklet"<<
3540 "track.="<<track<< // track parameters
3541 "tany="<<tany<< // tangent of the local track angle
3542 "xmean="<<xmean<< // xmean - reference x of tracklet
3543 "tilt="<<h01<< // tilt angle
3544 "nall="<<nall<< // number of foundable clusters
3545 "nfound="<<nfound<< // number of found clusters
3546 "clfound="<<clfound<< // total number of found clusters in road
3547 "mpads="<<mpads<< // mean number of pads per cluster
3548 "plane="<<plane<< // plane number
3549 "road="<<road<< // the width of the used road
3550 "graph0.="<<&graph0<< // x - y = dy for closest cluster
3551 "graph1.="<<&graph1<< // x - y = dy for second closest cluster
3552 "graphy.="<<&graphy<< // y position of the track
3553 "graphz.="<<&graphz<< // z position of the track
3554 "fCl.="<<&array0<< // closest cluster
3555 "fCl2.="<<&array1<< // second closest cluster
3556 "maxpos="<<maxpos<< // maximal charge postion
3557 "maxcharge="<<maxcharge<< // maximal charge
3558 "maxpos4="<<maxpos4<< // maximal charge postion - after bin 4
3559 "maxcharge4="<<maxcharge4<< // maximal charge - after bin 4
3560 "maxpos5="<<maxpos5<< // maximal charge postion - after bin 5
3561 "maxcharge5="<<maxcharge5<< // maximal charge - after bin 5
3563 "bestiter="<<bestiter<< // best iteration number
3564 "tracklet.="<<&tracklet<< // corrspond to the best iteration
3565 "tchi20="<<tchi2s[0]<< // chi2 of cluster in the 0 iteration
3566 "tchi2b="<<tchi2s[bestiter]<< // chi2 of cluster in the best iteration
3567 "sigmas0="<<sigmas[0]<< // residuals sigma
3568 "sigmasb="<<sigmas[bestiter]<< // residulas sigma
3570 "ngood0="<<ngood[0]<< // number of good clusters in 0 iteration
3571 "nbad0="<<nbad[0]<< // number of bad clusters in 0 iteration
3572 "ngoodb="<<ngood[bestiter]<< // in best iteration
3573 "nbadb="<<nbad[bestiter]<< // in best iteration
3575 "changes0="<<changes[0]<< // changes of pardrows in iteration number 0
3576 "changesb="<<changes[bestiter]<< // changes of pardrows in best iteration
3578 "moffset0="<<moffset[0]<< // offset fixing angle in iter=0
3579 "smoffset0="<<smoffset[0]<< // sigma of offset fixing angle in iter=0
3580 "moffsetb="<<moffset[bestiter]<< // offset fixing angle in iter=best
3581 "smoffsetb="<<smoffset[bestiter]<< // sigma of offset fixing angle in iter=best
3583 "mean0="<<mean[0]<< // mean dy in iter=0;
3584 "smean0="<<smean[0]<< // sigma of mean dy in iter=0
3585 "meanb="<<mean[bestiter]<< // mean dy in iter=best
3586 "smeanb="<<smean[bestiter]<< // sigma of mean dy in iter=best
3588 "angle0="<<angle[0]<< // angle deviation in the iteration number 0
3589 "sangle0="<<sangle[0]<< // sigma of angular deviation in iteration number 0
3590 "angleb="<<angle[bestiter]<< // angle deviation in the best iteration
3591 "sangleb="<<sangle[bestiter]<< // sigma of angle deviation in the best iteration
3593 "expectederr="<<expectederr<< // expected error of cluster position