1 /**************************************************************************
2 * Copyright(c) 1998-2003, 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 ////////////////////////////////////////////////////
19 // Stand alone tracker class //
20 // Origin: Elisabetta Crescio //
21 // e-mail: crescio@to.infn.it //
22 // tracks are saved as AliITStrackV2 objects //
23 ////////////////////////////////////////////////////
29 #include <TObjArray.h>
32 #include "AliESDEvent.h"
33 #include "AliESDVertex.h"
34 #include "AliESDtrack.h"
35 #include "AliITSVertexer.h"
36 #include "AliITSclusterTable.h"
37 #include "AliITSRecPoint.h"
38 #include "AliITSgeomTGeo.h"
39 #include "AliITStrackSA.h"
40 #include "AliITStrackerSA.h"
41 #include "AliITSReconstructor.h"
45 ClassImp(AliITStrackerSA)
47 //____________________________________________________________________________
48 AliITStrackerSA::AliITStrackerSA():AliITStrackerMI(),
71 // Default constructor
75 //____________________________________________________________________________
76 AliITStrackerSA::AliITStrackerSA(const Char_t *geom):AliITStrackerMI(0),
100 // Standard constructor (Vertex is known and passed to this obj.)
102 AliWarning("\"geom\" is actually a dummy argument !");
110 //____________________________________________________________________________
111 AliITStrackerSA::AliITStrackerSA(const Char_t *geom, AliESDVertex *vert):AliITStrackerMI(0),
135 // Standard constructor (Vertex is known and passed to this obj.)
137 AliWarning("\"geom\" is actually a dummy argument !");
143 //____________________________________________________________________________
144 AliITStrackerSA::AliITStrackerSA(const Char_t *geom, AliITSVertexer *vertexer):AliITStrackerMI(0),
168 // Standard constructor (Vertex is unknown - vertexer is passed to this obj)
170 AliWarning("\"geom\" is actually a dummy argument !");
173 fVertexer = vertexer;
177 //____________________________________________________________________________
178 AliITStrackerSA::AliITStrackerSA(const AliITStrackerSA& tracker):AliITStrackerMI(),
179 fPhiEstimate(tracker.fPhiEstimate),
180 fITSStandAlone(tracker.fITSStandAlone),
181 fLambdac(tracker.fLambdac),
182 fPhic(tracker.fPhic),
183 fCoef1(tracker.fCoef1),
184 fCoef2(tracker.fCoef2),
185 fCoef3(tracker.fCoef3),
186 fNloop(tracker.fNloop),
187 fPhiWin(tracker.fPhiWin),
188 fLambdaWin(tracker.fLambdaWin),
189 fVert(tracker.fVert),
190 fVertexer(tracker.fVertexer),
191 fListOfTracks(tracker.fListOfTracks),
192 fListOfSATracks(tracker.fListOfSATracks),
193 fITSclusters(tracker.fITSclusters),
194 fInwardFlag(tracker.fInwardFlag),
195 fOuterStartLayer(tracker.fOuterStartLayer),
196 fInnerStartLayer(tracker.fInnerStartLayer),
197 fMinNPoints(tracker.fMinNPoints),
198 fMinQ(tracker.fMinQ),
199 fCluLayer(tracker.fCluLayer),
200 fCluCoord(tracker.fCluCoord) {
202 for(Int_t i=0;i<2;i++){
203 fPoint1[i]=tracker.fPoint1[i];
204 fPoint2[i]=tracker.fPoint2[i];
205 fPoint3[i]=tracker.fPoint3[i];
206 fPointc[i]=tracker.fPointc[i];
208 if(tracker.fVertexer && tracker.fVert){
209 fVert = new AliESDVertex(*tracker.fVert);
212 fVert = tracker.fVert;
214 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
215 fCluLayer[i] = tracker.fCluLayer[i];
216 fCluCoord[i] = tracker.fCluCoord[i];
219 //______________________________________________________________________
220 AliITStrackerSA& AliITStrackerSA::operator=(const AliITStrackerSA& source){
221 // Assignment operator.
222 this->~AliITStrackerSA();
223 new(this) AliITStrackerSA(source);
228 //____________________________________________________________________________
229 AliITStrackerSA::~AliITStrackerSA(){
231 // if fVertexer is not null, the AliESDVertex obj. is owned by this class
232 // and is deleted here
234 if(fVert)delete fVert;
239 if(fPhiWin)delete []fPhiWin;
240 if(fLambdaWin)delete []fLambdaWin;
241 fListOfTracks->Delete();
242 delete fListOfTracks;
243 fListOfSATracks->Delete();
244 delete fListOfSATracks;
246 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
248 fCluLayer[i]->Delete();
255 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
257 fCluCoord[i]->Delete();
266 //____________________________________________________________________________
267 Int_t AliITStrackerSA::Clusters2Tracks(AliESDEvent *event){
268 // This method is used to find and fit the tracks. By default the corresponding
269 // method in the parent class is invoked. In this way a combined tracking
270 // TPC+ITS is performed. If the flag fITSStandAlone is true, the tracking
271 // is done in the ITS only. In the standard reconstruction chain this option
272 // can be set via AliReconstruction::SetOption("ITS","onlyITS")
275 rc=AliITStrackerMI::Clusters2Tracks(event);
278 AliDebug(1,"Stand Alone flag set: doing tracking in ITS alone\n");
281 rc=FindTracks(event,kFALSE);
282 if(AliITSReconstructor::GetRecoParam()->GetSAUseAllClusters()==kTRUE) {
283 rc=FindTracks(event,kTRUE);
290 //____________________________________________________________________________
291 void AliITStrackerSA::Init(){
292 // Reset all data members
294 for(Int_t i=0;i<3;i++){fPoint1[i]=0;fPoint2[i]=0;fPoint3[i]=0;}
304 Int_t nLoops=AliITSReconstructor::GetRecoParam()->GetNLoopsSA();
306 SetFixedWindowSizes();
308 Double_t phimin=AliITSReconstructor::GetRecoParam()->GetMinPhiSA();
309 Double_t phimax=AliITSReconstructor::GetRecoParam()->GetMaxPhiSA();
310 Double_t lambmin=AliITSReconstructor::GetRecoParam()->GetMinLambdaSA();
311 Double_t lambmax=AliITSReconstructor::GetRecoParam()->GetMaxLambdaSA();
312 SetCalculatedWindowSizes(nLoops,phimin,phimax,lambmin,lambmax);
314 fMinQ=AliITSReconstructor::GetRecoParam()->GetSAMinClusterCharge();
316 SetOuterStartLayer(1);
318 fListOfTracks=new TClonesArray("AliITStrackMI",100);
319 fListOfSATracks=new TClonesArray("AliITStrackSA",100);
324 //_______________________________________________________________________
325 void AliITStrackerSA::ResetForFinding(){
326 // Reset data members used in all loops during track finding
328 for(Int_t i=0;i<3;i++){fPoint1[i]=0;fPoint2[i]=0;fPoint3[i]=0;}
336 fListOfTracks->Clear();
337 fListOfSATracks->Clear();
342 //______________________________________________________________________
343 Int_t AliITStrackerSA::FindTracks(AliESDEvent* event, Bool_t useAllClusters){
345 // Track finder using the ESD object
347 AliDebug(2,Form(" field is %f",event->GetMagneticField()));
348 AliDebug(2,Form("SKIPPING %d %d %d %d %d %d",ForceSkippingOfLayer(0),ForceSkippingOfLayer(1),ForceSkippingOfLayer(2),ForceSkippingOfLayer(3),ForceSkippingOfLayer(4),ForceSkippingOfLayer(5)));
351 Fatal("FindTracks","ITS cluster tree is not accessed - Abort!!!\n Please use method SetClusterTree to pass the pointer to the tree\n");
354 //Reads event and mark clusters of traks already found, with flag kITSin
355 Int_t nentr=event->GetNumberOfTracks();
356 if(!useAllClusters) {
358 AliESDtrack *track=event->GetTrack(nentr);
359 if ((track->GetStatus()&AliESDtrack::kITSin) == AliESDtrack::kITSin){
361 Int_t ncl = track->GetITSclusters(idx);
362 for(Int_t k=0;k<ncl;k++){
363 AliITSRecPoint* cll = (AliITSRecPoint*)GetCluster(idx[k]);
364 cll->SetBit(kSAflag);
370 AliESDtrack *track=event->GetTrack(nentr);
371 if ((track->GetStatus()&AliESDtrack::kITSin) == AliESDtrack::kITSin){
373 Int_t ncl = track->GetITSclusters(idx);
374 for(Int_t k=0;k<ncl;k++){
375 AliITSRecPoint* cll = (AliITSRecPoint*)GetCluster(idx[k]);
376 cll->ResetBit(kSAflag);
382 Double_t primaryVertex[3];
383 event->GetVertex()->GetXYZ(primaryVertex);
384 //Creates TClonesArray with clusters for each layer. The clusters already used
385 //by AliITStrackerMI are not considered
386 Int_t nclusters[AliITSgeomTGeo::kNLayers]={0,0,0,0,0,0};
387 Int_t dmar[AliITSgeomTGeo::kNLayers]={0,0,0,0,0,0};
388 if (fCluLayer == 0) {
389 fCluLayer = new TClonesArray*[AliITSgeomTGeo::kNLayers];
390 fCluCoord = new TClonesArray*[AliITSgeomTGeo::kNLayers];
391 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
396 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
397 AliITSlayer &layer=fgLayers[i];
398 if (!ForceSkippingOfLayer(i)) {
399 for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
400 AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
401 if(cls->TestBit(kSAflag)==kTRUE) continue; //clusters used by TPC prol.
402 if(cls->GetQ()==0) continue; //fake clusters dead zones
403 if(i>1 && cls->GetQ()<=fMinQ) continue; // cut on SDD and SSD cluster charge
409 fCluLayer[i] = new TClonesArray("AliITSRecPoint",nclusters[i]);
411 fCluLayer[i]->Delete();
412 fCluLayer[i]->Expand(nclusters[i]);
415 fCluCoord[i] = new TClonesArray("AliITSclusterTable",nclusters[i]);
417 fCluCoord[i]->Delete();
418 fCluCoord[i]->Expand(nclusters[i]);
422 for(Int_t ilay=0;ilay<AliITSgeomTGeo::GetNLayers();ilay++){
423 TClonesArray &clulay = *fCluLayer[ilay];
424 TClonesArray &clucoo = *fCluCoord[ilay];
425 AliITSlayer &layer=fgLayers[ilay];
426 if (!ForceSkippingOfLayer(ilay)) {
427 for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
428 AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
429 if(cls->TestBit(kSAflag)==kTRUE) continue;
430 if(cls->GetQ()==0) continue;
431 if(ilay>1 && cls->GetQ()<=fMinQ) continue;
432 Double_t phi=0;Double_t lambda=0;
433 Float_t x=0;Float_t y=0;Float_t z=0;
434 Float_t sx=0;Float_t sy=0;Float_t sz=0;
435 GetCoorAngles(cls,phi,lambda,x,y,z,primaryVertex);
436 GetCoorErrors(cls,sx,sy,sz);
437 new (clulay[dmar[ilay]]) AliITSRecPoint(*cls);
438 new (clucoo[dmar[ilay]]) AliITSclusterTable(x,y,z,sx,sy,sz,phi,lambda,cli);
447 static Int_t nClusLay[AliITSgeomTGeo::kNLayers];//counter for clusters on each layer
448 Int_t startLayForSeed=0;
449 Int_t lastLayForSeed=fOuterStartLayer;
450 Int_t nSeedSteps=lastLayForSeed-startLayForSeed;
453 startLayForSeed=AliITSgeomTGeo::GetNLayers()-1;
454 lastLayForSeed=fInnerStartLayer;
455 nSeedSteps=startLayForSeed-lastLayForSeed;
459 // loop on minimum number of points
460 for(Int_t iMinNPoints=AliITSgeomTGeo::GetNLayers(); iMinNPoints>=fMinNPoints; iMinNPoints--) {
462 // loop on starting layer for track finding
463 for(Int_t iSeedLay=0; iSeedLay<=nSeedSteps; iSeedLay++) {
464 Int_t theLay=startLayForSeed+iSeedLay*seedStep;
465 if(ForceSkippingOfLayer(theLay)) continue;
466 Int_t minNPoints=iMinNPoints-theLay;
467 if(fInwardFlag) minNPoints=iMinNPoints-(AliITSgeomTGeo::GetNLayers()-1-theLay);
468 for(Int_t i=theLay+1;i<AliITSgeomTGeo::GetNLayers();i++)
469 if(ForceSkippingOfLayer(i))
471 if(minNPoints<fMinNPoints) continue;
473 // loop on phi and lambda window size
474 for(Int_t nloop=0;nloop<fNloop;nloop++){
475 Int_t nclTheLay=fCluLayer[theLay]->GetEntries();
478 Bool_t useRP=SetFirstPoint(theLay,nclTheLay,primaryVertex);
484 for(kk=0;kk<AliITSgeomTGeo::GetNLayers();kk++) nClusLay[kk] = 0;
487 nClusLay[kk] = SearchClusters(theLay,fPhiWin[nloop],fLambdaWin[nloop],
488 &trs,primaryVertex[2],pflag);
489 Int_t nextLay=theLay+seedStep;
493 nClusLay[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
494 &trs,primaryVertex[2],pflag);
498 fPoint3[0]=fPointc[0];
499 fPoint3[1]=fPointc[1];
505 if(nextLay<0 || nextLay==6) goon=kFALSE;
511 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-theLay;nnp++){
512 if(nClusLay[nnp]!=0) layOK+=1;
515 for(Int_t nnp=theLay; nnp>=0; nnp--){
516 if(nClusLay[nnp]!=0) layOK+=1;
519 if(layOK>=minNPoints){
520 AliDebug(2,Form("---NPOINTS: %d; MAP: %d %d %d %d %d %d\n",layOK,nClusLay[0],nClusLay[1],nClusLay[2],nClusLay[3],nClusLay[4],nClusLay[5]));
521 AliITStrackV2* tr2 = 0;
522 tr2 = FitTrack(&trs,primaryVertex);
526 AliDebug(2,Form("---NPOINTS fit: %d\n",tr2->GetNumberOfClusters()));
528 StoreTrack(tr2,event,useAllClusters);
533 }//end loop on clusters of theLay
534 } //end loop on window sizes
535 } //end loop on theLay
536 }//end loop on min points
538 // search for 1-point tracks in SPD, only for cosmics
539 // (A.Dainese 21.03.08)
540 if(AliITSReconstructor::GetRecoParam()->GetSAOnePointTracks() &&
541 TMath::Abs(event->GetMagneticField())<0.01) {
542 Int_t outerLayer=1; // only SPD
543 for(Int_t innLay=0; innLay<=TMath::Min(1,fOuterStartLayer); innLay++) {
544 // counter for clusters on each layer
546 for(Int_t nloop=0;nloop<fNloop;nloop++){
547 Int_t nclInnLay=fCluLayer[innLay]->GetEntries();
548 while(nclInnLay--){ //loop starting from layer innLay
550 Bool_t useRP=SetFirstPoint(innLay,nclInnLay,primaryVertex);
556 for(kk=0;kk<AliITSgeomTGeo::GetNLayers();kk++) nClusLay[kk] = 0;
559 nClusLay[kk] = SearchClusters(innLay,fPhiWin[nloop],fLambdaWin[nloop],
560 &trs,primaryVertex[2],pflag);
561 for(Int_t nextLay=innLay+1; nextLay<=outerLayer; nextLay++) {
563 nClusLay[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
564 &trs,primaryVertex[2],pflag);
568 fPoint3[0]=fPointc[0];
569 fPoint3[1]=fPointc[1];
577 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-innLay;nnp++){
578 if(nClusLay[nnp]!=0) layOK+=1;
581 AliDebug(2,Form("----NPOINTS: %d; MAP: %d %d %d %d %d %d\n",layOK,nClusLay[0],nClusLay[1],nClusLay[2],nClusLay[3],nClusLay[4],nClusLay[5]));
582 AliITStrackV2* tr2 = 0;
583 Bool_t onePoint = kTRUE;
584 tr2 = FitTrack(&trs,primaryVertex,onePoint);
588 AliDebug(2,Form("----NPOINTS fit: %d\n",tr2->GetNumberOfClusters()));
590 StoreTrack(tr2,event,useAllClusters);
595 }//end loop on clusters of innLay
596 } //end loop on window sizes
598 } //end loop on innLay
599 } // end search 1-point tracks
601 if(!useAllClusters) AliInfo(Form("Number of found tracks: %d",event->GetNumberOfTracks()));
607 //________________________________________________________________________
609 AliITStrackV2* AliITStrackerSA::FitTrack(AliITStrackSA* tr,Double_t *primaryVertex,Bool_t onePoint) {
610 //fit of the found track (most general case, also <6 points, layers missing)
611 // A.Dainese 16.11.07
614 const Int_t kMaxClu=AliITStrackSA::kMaxNumberOfClusters;
616 static Int_t firstmod[AliITSgeomTGeo::kNLayers];
618 static Int_t clind[AliITSgeomTGeo::kNLayers][kMaxClu];
619 static Int_t clmark[AliITSgeomTGeo::kNLayers][kMaxClu];
620 static Int_t end[AliITSgeomTGeo::kNLayers];
621 static AliITSRecPoint *listlayer[AliITSgeomTGeo::kNLayers][kMaxClu];
623 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
624 firstmod[i]=AliITSgeomTGeo::GetModuleIndex(i+1,1,1);
626 for(Int_t j=0;j<kMaxClu; j++){
634 Int_t nclusters = tr->GetNumberOfClustersSA();
635 for(Int_t ncl=0;ncl<nclusters;ncl++){
636 Int_t index = tr->GetClusterIndexSA(ncl);
637 AliITSRecPoint* cl = (AliITSRecPoint*)GetCluster(index);
638 if(cl->TestBit(kSAflag)==kTRUE) cl->ResetBit(kSAflag);
639 Int_t lay = (index & 0xf0000000) >> 28;
640 Int_t nInLay=end[lay];
641 listlayer[lay][nInLay]=cl;
642 clind[lay][nInLay]=index;
646 for(Int_t nlay=0;nlay<AliITSgeomTGeo::GetNLayers();nlay++){
647 for(Int_t ncl=0;ncl<tr->GetNumberOfMarked(nlay);ncl++){
648 Int_t mark = tr->GetClusterMark(nlay,ncl);
649 clmark[nlay][ncl]=mark;
654 Int_t firstLay=-1,secondLay=-1;
655 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
661 } else if(secondLay==-1) {
667 if(firstLay==-1 || (secondLay==-1 && !onePoint)) return 0;
668 TClonesArray &arrMI= *fListOfTracks;
669 TClonesArray &arrSA= *fListOfSATracks;
670 Int_t nFoundTracks=0;
672 for(Int_t l0=0;l0<end[0];l0++){ //loop on layer 1
673 AliITSRecPoint* cl0 = (AliITSRecPoint*)listlayer[0][l0];
674 for(Int_t l1=0;l1<end[1];l1++){ //loop on layer 2
675 AliITSRecPoint* cl1 = (AliITSRecPoint*)listlayer[1][l1];
676 for(Int_t l2=0;l2<end[2];l2++){ //loop on layer 3
677 AliITSRecPoint* cl2 = (AliITSRecPoint*)listlayer[2][l2];
678 for(Int_t l3=0;l3<end[3];l3++){ //loop on layer 4
679 AliITSRecPoint* cl3 = (AliITSRecPoint*)listlayer[3][l3];
680 for(Int_t l4=0;l4<end[4];l4++){ //loop on layer 5
681 AliITSRecPoint* cl4 = (AliITSRecPoint*)listlayer[4][l4];
682 for(Int_t l5=0;l5<end[5];l5++){ //loop on layer 6
683 AliITSRecPoint* cl5 = (AliITSRecPoint*)listlayer[5][l5];
686 Double_t x1,y1,z1,sx1,sy1,sz1;
687 Double_t x2,y2,z2,sx2,sy2,sz2;
688 AliITSRecPoint* p1=0;
689 AliITSRecPoint* p2=0;
690 Int_t index1=0,index2=0;
696 index1=clind[0][l0];mrk1=clmark[0][l0];
700 index1=clind[1][l1];mrk1=clmark[1][l1];
704 index1=clind[2][l2];mrk1=clmark[2][l2];
708 index1=clind[3][l3];mrk1=clmark[3][l3];
712 index1=clind[4][l4];mrk1=clmark[4][l4];
719 index2=clind[1][l1];mrk2=clmark[1][l1];
723 index2=clind[2][l2];mrk2=clmark[2][l2];
727 index2=clind[3][l3];mrk2=clmark[3][l3];
731 index2=clind[4][l4];mrk2=clmark[4][l4];
735 index2=clind[5][l5];mrk2=clmark[5][l5];
743 Int_t module1 = p1->GetDetectorIndex()+firstmod[firstLay];
744 Int_t layer,ladder,detector;
745 AliITSgeomTGeo::GetModuleId(module1,layer,ladder,detector);
746 Float_t yclu1 = p1->GetY();
747 Float_t zclu1 = p1->GetZ();
748 Double_t cv=0,tgl2=0,phi2=0;
751 AliITSclusterTable* arr1 = (AliITSclusterTable*)GetClusterCoord(firstLay,cln1);
761 AliITSclusterTable* arr2 = (AliITSclusterTable*)GetClusterCoord(secondLay,cln2);
768 cv = Curvature(primaryVertex[0],primaryVertex[1],x1,y1,x2,y2);
769 tgl2 = (z2-z1)/TMath::Sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
770 phi2 = TMath::ATan2((y2-y1),(x2-x1));
771 } else { // special case of 1-point tracks, only for cosmics (B=0)
772 x2 = primaryVertex[0];
773 y2 = primaryVertex[1];
774 z2 = primaryVertex[2];
776 tgl2 = (z1-z2)/TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
777 phi2 = TMath::ATan2((y1-y2),(x1-x2));
781 AliITStrackSA trac(layer,ladder,detector,yclu1,zclu1,phi2,tgl2,cv,1);
785 trac.AddClusterV2(5,(clind[5][l5] & 0x0fffffff)>>0);
786 trac.AddClusterMark(5,clmark[5][l5]);
789 trac.AddClusterV2(4,(clind[4][l4] & 0x0fffffff)>>0);
790 trac.AddClusterMark(4,clmark[4][l4]);
793 trac.AddClusterV2(3,(clind[3][l3] & 0x0fffffff)>>0);
794 trac.AddClusterMark(3,clmark[3][l3]);
797 trac.AddClusterV2(2,(clind[2][l2] & 0x0fffffff)>>0);
798 trac.AddClusterMark(2,clmark[2][l2]);
801 trac.AddClusterV2(1,(clind[1][l1] & 0x0fffffff)>>0);
802 trac.AddClusterMark(1,clmark[1][l1]);
805 trac.AddClusterV2(0,(clind[0][l0] & 0x0fffffff)>>0);
806 trac.AddClusterMark(0,clmark[0][l0]);
809 //fit with Kalman filter using AliITStrackerMI::RefitAt()
810 AliITStrackSA ot(trac);
812 ot.ResetCovariance(10.);
815 // Propagate inside the innermost layer with a cluster
816 if(ot.Propagate(ot.GetX()-0.1*ot.GetX())) {
818 if(RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&ot,&trac)){ //fit from layer 1 to layer 6
819 AliITStrackMI otrack2(ot);
820 otrack2.ResetCovariance(10.);
821 otrack2.ResetClusters();
822 //fit from layer 6 to layer 1
823 if(RefitAt(AliITSRecoParam::GetrInsideSPD1(),&otrack2,&ot)) {
824 new(arrMI[nFoundTracks]) AliITStrackMI(otrack2);
825 new(arrSA[nFoundTracks]) AliITStrackSA(trac);
841 if(fListOfTracks->GetEntries()==0) return 0;
843 Int_t lowchi2 = FindTrackLowChiSquare();
844 AliITStrackV2* otrack =(AliITStrackV2*)fListOfTracks->At(lowchi2);
845 AliITStrackSA* trsa = (AliITStrackSA*)fListOfSATracks->At(lowchi2);
847 if(otrack==0) return 0;
849 Int_t indexc[AliITSgeomTGeo::kNLayers];
850 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) indexc[i]=0;
851 for(Int_t nind=0;nind<otrack->GetNumberOfClusters();nind++){
852 indexc[nind] = otrack->GetClusterIndex(nind);
855 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
856 if(i<otrack->GetNumberOfClusters()) {
857 AliITSRecPoint* cl = (AliITSRecPoint*)GetCluster(indexc[i]);
858 labl[i][0]=cl->GetLabel(0);
859 labl[i][1]=cl->GetLabel(1);
860 labl[i][2]=cl->GetLabel(2);
868 CookLabel(otrack,0.); //MI change - to see fake ratio
870 Int_t label=FindLabel(labl[0][0],labl[1][0],labl[2][0],labl[3][0],labl[4][0],labl[5][0]);
872 for(Int_t i=0;i<otrack->GetNumberOfClusters();i++)
873 if(labl[i][0]==label || labl[i][1]==label || labl[i][2]==label) lflag++;
875 if(lflag<otrack->GetNumberOfClusters()) label = -label;
876 otrack->SetLabel(label);
878 //remove clusters of found track
879 for(Int_t nlay=0;nlay<AliITSgeomTGeo::GetNLayers();nlay++){
880 for(Int_t cln=0;cln<trsa->GetNumberOfMarked(nlay);cln++){
881 Int_t index = trsa->GetClusterMark(nlay,cln);
882 fCluLayer[nlay]->RemoveAt(index);
883 RemoveClusterCoord(nlay,index);
884 fCluLayer[nlay]->Compress();
892 //_______________________________________________________
893 void AliITStrackerSA::StoreTrack(AliITStrackV2 *t,AliESDEvent *event, Bool_t pureSA) const
896 // Add new track to the ESD
898 AliESDtrack outtrack;
899 outtrack.UpdateTrackParams(t,AliESDtrack::kITSin);
900 if(pureSA) outtrack.SetStatus(AliESDtrack::kITSpureSA);
901 for(Int_t i=0;i<12;i++) {
902 outtrack.SetITSModuleIndex(i,t->GetModuleIndex(i));
904 Double_t sdedx[4]={0.,0.,0.,0.};
905 for(Int_t i=0; i<4; i++) sdedx[i]=t->GetSampledEdx(i);
906 outtrack.SetITSdEdxSamples(sdedx);
907 event->AddTrack(&outtrack);
913 //_______________________________________________________
914 Int_t AliITStrackerSA::SearchClusters(Int_t layer,Double_t phiwindow,Double_t lambdawindow, AliITStrackSA* trs,Double_t /*zvertex*/,Int_t pflag){
915 //function used to to find the clusters associated to the track
917 if(ForceSkippingOfLayer(layer)) return 0;
920 AliITSlayer &lay = fgLayers[layer];
921 Double_t r=lay.GetR();
923 Float_t cx1,cx2,cy1,cy2;
924 FindEquation(fPoint1[0],fPoint1[1],fPoint2[0],fPoint2[1],fPoint3[0],fPoint3[1],fCoef1,fCoef2,fCoef3);
925 if (FindIntersection(fCoef1,fCoef2,fCoef3,-r*r,cx1,cy1,cx2,cy2)==0)
927 Double_t fi1=TMath::ATan2(cy1-fPoint1[1],cx1-fPoint1[0]);
928 Double_t fi2=TMath::ATan2(cy2-fPoint1[1],cx2-fPoint1[0]);
929 fPhiEstimate=ChoosePoint(fi1,fi2,fPhic);
933 Int_t ncl = fCluLayer[layer]->GetEntries();
934 for (Int_t index=0; index<ncl; index++) {
935 AliITSRecPoint *c = (AliITSRecPoint*)fCluLayer[layer]->At(index);
937 if (c->GetQ()<=0) continue;
938 if(layer>1 && c->GetQ()<=fMinQ) continue;
940 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(layer,index);
941 Double_t phi = arr->GetPhi();
942 if (TMath::Abs(phi-fPhiEstimate)>phiwindow) continue;
944 Double_t lambda = arr->GetLambda();
945 if (TMath::Abs(lambda-fLambdac)>lambdawindow) continue;
947 if(trs->GetNumberOfClustersSA()==trs->GetMaxNumberOfClusters()) return 0;
948 if(trs->GetNumberOfMarked(layer)==trs->GetMaxNMarkedPerLayer()) return 0;
949 Int_t orind = arr->GetOrInd();
950 trs->AddClusterSA(layer,orind);
951 trs->AddClusterMark(layer,index);
957 fPointc[0]=arr->GetX();
958 fPointc[1]=arr->GetY();
964 //________________________________________________________________
965 Bool_t AliITStrackerSA::SetFirstPoint(Int_t lay, Int_t clu, Double_t* primaryVertex){
966 // Sets the first point (seed) for tracking
968 AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[lay]->At(clu);
969 if(!cl) return kFALSE;
970 if (cl->GetQ()<=0) return kFALSE;
971 if(lay>1 && cl->GetQ()<=fMinQ) return kFALSE;
973 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(lay,clu);
974 fPhic = arr->GetPhi();
975 fLambdac = arr->GetLambda();
976 fPhiEstimate = fPhic;
977 fPoint1[0]=primaryVertex[0];
978 fPoint1[1]=primaryVertex[1];
979 fPoint2[0]=arr->GetX();
980 fPoint2[1]=arr->GetY();
984 //________________________________________________________________
985 void AliITStrackerSA::UpdatePoints(){
986 //update of points for the estimation of the curvature
988 fPoint2[0]=fPoint3[0];
989 fPoint2[1]=fPoint3[1];
990 fPoint3[0]=fPointc[0];
991 fPoint3[1]=fPointc[1];
996 //___________________________________________________________________
997 Int_t AliITStrackerSA::FindEquation(Float_t x1, Float_t y1, Float_t x2, Float_t y2, Float_t x3, Float_t y3,Float_t& a, Float_t& b, Float_t& c){
999 //given (x,y) of three recpoints (in global coordinates)
1000 //returns the parameters a,b,c of circonference x*x + y*y +a*x + b*y +c
1002 Float_t den = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1);
1003 if(den==0) return 0;
1004 a = ((y3-y1)*(x2*x2+y2*y2-x1*x1-y1*y1)-(y2-y1)*(x3*x3+y3*y3-x1*x1-y1*y1))/den;
1005 b = -(x2*x2-x1*x1+y2*y2-y1*y1+a*(x2-x1))/(y2-y1);
1006 c = -x1*x1-y1*y1-a*x1-b*y1;
1009 //__________________________________________________________________________
1010 Int_t AliITStrackerSA::FindIntersection(Float_t a1, Float_t b1, Float_t c1, Float_t c2,Float_t& x1,Float_t& y1, Float_t& x2, Float_t& y2){
1012 //Finds the intersection between the circonference of the track and the circonference centered in (0,0) represented by one layer
1013 //c2 is -rlayer*rlayer
1017 Double_t aA = (b1*b1)/(a1*a1)+1;
1018 Double_t bB = (-2*m*b1/(a1*a1));
1019 Double_t cC = c2+(m*m)/(a1*a1);
1020 Double_t dD = bB*bB-4*aA*cC;
1023 y1 = (-bB+TMath::Sqrt(dD))/(2*aA);
1024 y2 = (-bB-TMath::Sqrt(dD))/(2*aA);
1025 x1 = (c2-c1-b1*y1)/a1;
1026 x2 = (c2-c1-b1*y2)/a1;
1030 //____________________________________________________________________
1031 Double_t AliITStrackerSA::Curvature(Double_t x1,Double_t y1,Double_t
1032 x2,Double_t y2,Double_t x3,Double_t y3){
1034 //calculates the curvature of track
1035 Double_t den = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1);
1036 if(den==0) return 0;
1037 Double_t a = ((y3-y1)*(x2*x2+y2*y2-x1*x1-y1*y1)-(y2-y1)*(x3*x3+y3*y3-x1*x1-y1*y1))/den;
1038 Double_t b = -(x2*x2-x1*x1+y2*y2-y1*y1+a*(x2-x1))/(y2-y1);
1039 Double_t c = -x1*x1-y1*y1-a*x1-b*y1;
1042 if((a*a+b*b-4*c)<0) return 0;
1043 Double_t rad = TMath::Sqrt(a*a+b*b-4*c)/2.;
1044 if(rad==0) return 0;
1046 if((x1>0 && y1>0 && x1<xc)) rad*=-1;
1047 if((x1<0 && y1>0 && x1<xc)) rad*=-1;
1048 // if((x1<0 && y1<0 && x1<xc)) rad*=-1;
1049 // if((x1>0 && y1<0 && x1<xc)) rad*=-1;
1056 //____________________________________________________________________
1057 Double_t AliITStrackerSA::ChoosePoint(Double_t p1, Double_t p2, Double_t pp){
1059 //Returns the point closest to pp
1061 Double_t diff1 = p1-pp;
1062 Double_t diff2 = p2-pp;
1064 if(TMath::Abs(diff1)<TMath::Abs(diff2)) fPhiEstimate=p1;
1065 else fPhiEstimate=p2;
1066 return fPhiEstimate;
1071 //_________________________________________________________________
1072 Int_t AliITStrackerSA::FindTrackLowChiSquare() const {
1073 // returns track with lowest chi square
1074 Int_t dim=fListOfTracks->GetEntries();
1075 if(dim<=1) return 0;
1076 AliITStrackV2* trk = (AliITStrackV2*)fListOfTracks->At(0);
1077 Double_t minChi2=trk->GetChi2();
1079 for(Int_t i=1;i<dim;i++){
1080 trk = (AliITStrackV2*)fListOfTracks->At(i);
1081 Double_t chi2=trk->GetChi2();
1090 //__________________________________________________________
1091 Int_t AliITStrackerSA::FindLabel(Int_t l0, Int_t l1, Int_t l2, Int_t l3, Int_t l4, Int_t l5){
1093 //function used to determine the track label
1095 Int_t lb[6] = {l0,l1,l2,l3,l4,l5};
1096 Int_t aa[6]={1,1,1,1,1,1};
1099 Int_t k=0;Int_t w=0;Int_t num=6;
1100 for(Int_t i=5;i>=0;i--) if(lb[i]==-1) num=i;
1104 for(Int_t i=k+1;i<num;i++){
1106 if(lb[k]==lb[i] && aa[k]!=0){
1117 for(Int_t j=0;j<6;j++){
1130 if(num<1) return -1;
1134 //_____________________________________________________________________________
1135 Int_t AliITStrackerSA::Label(Int_t gl1, Int_t gl2, Int_t gl3, Int_t gl4, Int_t gl5, Int_t gl6,Int_t gl7, Int_t gl8, Int_t gl9, Int_t gl10,Int_t gl11,
1136 Int_t gl12, Int_t gl13, Int_t gl14,Int_t gl15, Int_t gl16, Int_t gl17, Int_t gl18, Int_t minNPoints){
1139 //function used to assign label to the found track. If track is fake, the label is negative
1141 Int_t lb0[6] = {gl1,gl2,gl3,gl4,gl5,gl6};
1142 Int_t lb1[6] = {gl7,gl8,gl9,gl10,gl11,gl12};
1143 Int_t lb2[6] = {gl13,gl14,gl15,gl16,gl17,gl18};
1144 Int_t ll=FindLabel(lb0[0],lb0[1],lb0[2],lb0[3],lb0[4],lb0[5]);
1145 Int_t lflag=0;Int_t num=6;
1146 if(lb0[5]==-1 && lb1[5]==-1 && lb2[5]==-1) num=5;
1148 for(Int_t i=0;i<num;i++){
1149 if(lb0[i]==ll || lb1[i]==ll || lb2[i]==ll) lflag+=1;
1152 if(lflag>=minNPoints) return ll;
1157 //_____________________________________________________________________________
1158 void AliITStrackerSA::SetCalculatedWindowSizes(Int_t n, Float_t phimin, Float_t phimax, Float_t lambdamin, Float_t lambdamax){
1159 // Set sizes of the phi and lambda windows used for track finding
1161 if(fPhiWin) delete [] fPhiWin;
1162 if(fLambdaWin) delete [] fLambdaWin;
1163 fPhiWin = new Double_t[fNloop];
1164 fLambdaWin = new Double_t[fNloop];
1165 Float_t stepPhi=(phimax-phimin)/(Float_t)(fNloop-1);
1166 Float_t stepLambda=(lambdamax-lambdamin)/(Float_t)(fNloop-1);
1167 for(Int_t k=0;k<fNloop;k++){
1168 Float_t phi=phimin+k*stepPhi;
1169 Float_t lam=lambdamin+k*stepLambda;
1174 //_____________________________________________________________________________
1175 void AliITStrackerSA::SetFixedWindowSizes(Int_t n, Double_t *phi, Double_t *lam){
1176 // Set sizes of the phi and lambda windows used for track finding
1178 if(phi){ // user defined values
1179 fPhiWin = new Double_t[fNloop];
1180 fLambdaWin = new Double_t[fNloop];
1181 for(Int_t k=0;k<fNloop;k++){
1183 fLambdaWin[k]=lam[k];
1186 else { // default values
1188 Double_t phid[33] = {0.002,0.003,0.004,0.0045,0.0047,
1189 0.005,0.0053,0.0055,
1190 0.006,0.0063,0.0065,0.007,0.0073,0.0075,0.0077,
1191 0.008,0.0083,0.0085,0.0087,0.009,0.0095,0.0097,
1192 0.01,0.0105,0.011,0.0115,0.012,0.0125,0.013,0.0135,0.0140,0.0145};
1193 Double_t lambdad[33] = {0.003,0.004,0.005,0.005,0.005,
1195 0.006,0.006,0.006,0.007,0.007,0.007,0.007,
1196 0.007,0.007,0.007,0.007,0.007,0.007,0.007,
1197 0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008};
1204 fPhiWin = new Double_t[fNloop];
1205 fLambdaWin = new Double_t[fNloop];
1207 Double_t factor=AliITSReconstructor::GetRecoParam()->GetFactorSAWindowSizes(); // possibility to enlarge windows for cosmics reco with large misalignments (A.Dainese)
1209 for(Int_t k=0;k<fNloop;k++){
1210 fPhiWin[k]=phid[k]*factor;
1211 fLambdaWin[k]=lambdad[k]*factor;
1217 //_______________________________________________________________________
1218 void AliITStrackerSA::GetCoorAngles(AliITSRecPoint* cl,Double_t &phi,Double_t &lambda, Float_t &x, Float_t &y,Float_t &z,Double_t* vertex){
1219 //Returns values of phi (azimuthal) and lambda angles for a given cluster
1221 Double_t rot[9]; fGeom->GetRotMatrix(module,rot);
1222 Int_t lay,lad,det; fGeom->GetModuleId(module,lay,lad,det);
1223 Float_t tx,ty,tz; fGeom->GetTrans(lay,lad,det,tx,ty,tz);
1225 Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
1226 Double_t phi1=TMath::Pi()/2+alpha;
1227 if (lay==1) phi1+=TMath::Pi();
1229 Float_t cp=TMath::Cos(phi1), sp=TMath::Sin(phi1);
1230 Float_t r=tx*cp+ty*sp;
1232 xyz= r*cp - cl->GetY()*sp;
1233 y= r*sp + cl->GetY()*cp;
1237 cl->GetGlobalXYZ(xyz);
1242 phi=TMath::ATan2(y-vertex[1],x-vertex[0]);
1243 lambda=TMath::ATan2(z-vertex[2],TMath::Sqrt((x-vertex[0])*(x-vertex[0])+(y-vertex[1])*(y-vertex[1])));
1246 //________________________________________________________________________
1247 void AliITStrackerSA::GetCoorErrors(AliITSRecPoint* cl,Float_t &sx,Float_t &sy, Float_t &sz){
1249 //returns sigmax, y, z of cluster in global coordinates
1251 Double_t rot[9]; fGeom->GetRotMatrix(module,rot);
1253 AliITSgeomTGeo::GetModuleId(module,lay,lad,det);
1255 Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
1256 Double_t phi=TMath::Pi()/2+alpha;
1257 if (lay==1) phi+=TMath::Pi();
1259 Float_t cp=TMath::Cos(phi), sp=TMath::Sin(phi);
1262 cl->GetGlobalCov(covm);
1263 sx=TMath::Sqrt(covm[0]);
1264 sy=TMath::Sqrt(covm[3]);
1265 sz=TMath::Sqrt(covm[5]);
1267 sx = TMath::Sqrt(sp*sp*cl->GetSigmaY2());
1268 sy = TMath::Sqrt(cp*cp*cl->GetSigmaY2());
1269 sz = TMath::Sqrt(cl->GetSigmaZ2());