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"
44 ClassImp(AliITStrackerSA)
46 //____________________________________________________________________________
47 AliITStrackerSA::AliITStrackerSA():AliITStrackerMI(),
67 // Default constructor
71 //____________________________________________________________________________
72 AliITStrackerSA::AliITStrackerSA(const Char_t *geom):AliITStrackerMI(0),
93 // Standard constructor (Vertex is known and passed to this obj.)
95 AliWarning("\"geom\" is actually a dummy argument !");
103 //____________________________________________________________________________
104 AliITStrackerSA::AliITStrackerSA(const Char_t *geom, AliESDVertex *vert):AliITStrackerMI(0),
125 // Standard constructor (Vertex is known and passed to this obj.)
127 AliWarning("\"geom\" is actually a dummy argument !");
133 //____________________________________________________________________________
134 AliITStrackerSA::AliITStrackerSA(const Char_t *geom, AliITSVertexer *vertexer):AliITStrackerMI(0),
155 // Standard constructor (Vertex is unknown - vertexer is passed to this obj)
157 AliWarning("\"geom\" is actually a dummy argument !");
160 fVertexer = vertexer;
164 //____________________________________________________________________________
165 AliITStrackerSA::AliITStrackerSA(const AliITStrackerSA& tracker):AliITStrackerMI(),
166 fPhiEstimate(tracker.fPhiEstimate),
167 fITSStandAlone(tracker.fITSStandAlone),
168 fLambdac(tracker.fLambdac),
169 fPhic(tracker.fPhic),
170 fCoef1(tracker.fCoef1),
171 fCoef2(tracker.fCoef2),
172 fCoef3(tracker.fCoef3),
173 fNloop(tracker.fNloop),
174 fPhiWin(tracker.fPhiWin),
175 fLambdaWin(tracker.fLambdaWin),
176 fVert(tracker.fVert),
177 fVertexer(tracker.fVertexer),
178 fListOfTracks(tracker.fListOfTracks),
179 fListOfSATracks(tracker.fListOfSATracks),
180 fITSclusters(tracker.fITSclusters),
181 fSixPoints(tracker.fSixPoints),
182 fOuterStartLayer(tracker.fOuterStartLayer),
183 fCluLayer(tracker.fCluLayer),
184 fCluCoord(tracker.fCluCoord) {
186 for(Int_t i=0;i<2;i++){
187 fPoint1[i]=tracker.fPoint1[i];
188 fPoint2[i]=tracker.fPoint2[i];
189 fPoint3[i]=tracker.fPoint3[i];
190 fPointc[i]=tracker.fPointc[i];
192 if(tracker.fVertexer && tracker.fVert){
193 fVert = new AliESDVertex(*tracker.fVert);
196 fVert = tracker.fVert;
198 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
199 fCluLayer[i] = tracker.fCluLayer[i];
200 fCluCoord[i] = tracker.fCluCoord[i];
203 //______________________________________________________________________
204 AliITStrackerSA& AliITStrackerSA::operator=(const AliITStrackerSA& source){
205 // Assignment operator.
206 this->~AliITStrackerSA();
207 new(this) AliITStrackerSA(source);
212 //____________________________________________________________________________
213 AliITStrackerSA::~AliITStrackerSA(){
215 // if fVertexer is not null, the AliESDVertex obj. is owned by this class
216 // and is deleted here
218 if(fVert)delete fVert;
223 if(fPhiWin)delete []fPhiWin;
224 if(fLambdaWin)delete []fLambdaWin;
225 fListOfTracks->Delete();
226 delete fListOfTracks;
227 fListOfSATracks->Delete();
228 delete fListOfSATracks;
230 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
232 fCluLayer[i]->Delete();
239 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
241 fCluCoord[i]->Delete();
250 //____________________________________________________________________________
251 Int_t AliITStrackerSA::Clusters2Tracks(AliESDEvent *event){
252 // This method is used to find and fit the tracks. By default the corresponding
253 // method in the parent class is invoked. In this way a combined tracking
254 // TPC+ITS is performed. If the flag fITSStandAlone is true, the tracking
255 // is done in the ITS only. In the standard reconstruction chain this option
256 // can be set via AliReconstruction::SetOption("ITS","onlyITS")
259 rc=AliITStrackerMI::Clusters2Tracks(event);
262 AliDebug(1,"Stand Alone flag set: doing tracking in ITS alone\n");
264 if(!rc) rc=FindTracks(event);
268 //____________________________________________________________________________
269 void AliITStrackerSA::Init(){
270 // Reset all data members
272 for(Int_t i=0;i<3;i++){fPoint1[i]=0;fPoint2[i]=0;fPoint3[i]=0;}
282 Int_t nLoops=AliITSReconstructor::GetRecoParam()->GetNLoopsSA();
284 SetFixedWindowSizes();
286 Double_t phimin=AliITSReconstructor::GetRecoParam()->GetMinPhiSA();
287 Double_t phimax=AliITSReconstructor::GetRecoParam()->GetMaxPhiSA();
288 Double_t lambmin=AliITSReconstructor::GetRecoParam()->GetMinLambdaSA();
289 Double_t lambmax=AliITSReconstructor::GetRecoParam()->GetMaxLambdaSA();
290 SetCalculatedWindowSizes(nLoops,phimin,phimax,lambmin,lambmax);
294 SetOuterStartLayer(0);
296 fListOfTracks=new TObjArray(0,0);
297 fListOfSATracks=new TObjArray(0,0);
301 //_______________________________________________________________________
302 void AliITStrackerSA::ResetForFinding(){
303 // Reset data members used in all loops during track finding
305 for(Int_t i=0;i<3;i++){fPoint1[i]=0;fPoint2[i]=0;fPoint3[i]=0;}
313 fListOfTracks->Delete();
314 fListOfSATracks->Delete();
319 //______________________________________________________________________
320 Int_t AliITStrackerSA::FindTracks(AliESDEvent* event){
322 // Track finder using the ESD object
327 Fatal("FindTracks","ITS cluster tree is not accessed - Abort!!!\n Please use method SetClusterTree to pass the pointer to the tree\n");
330 //Reads event and mark clusters of traks already found, with flag kITSin
331 Int_t nentr=event->GetNumberOfTracks();
332 if(AliITSReconstructor::GetRecoParam()->GetSAUseAllClusters()==kFALSE) {
334 AliESDtrack *track=event->GetTrack(nentr);
335 if (track->GetStatus()&AliESDtrack::kITSin==AliESDtrack::kITSin){
337 Int_t ncl = track->GetITSclusters(idx);
338 for(Int_t k=0;k<ncl;k++){
339 AliITSRecPoint* cll = (AliITSRecPoint*)GetCluster(idx[k]);
340 cll->SetBit(kSAflag);
346 Double_t primaryVertex[3];
347 event->GetVertex()->GetXYZ(primaryVertex);
348 //Creates TClonesArray with clusters for each layer. The clusters already used
349 //by AliITStrackerMI are not considered
350 Int_t nclusters[AliITSgeomTGeo::kNLayers]={0,0,0,0,0,0};
351 Int_t dmar[AliITSgeomTGeo::kNLayers]={0,0,0,0,0,0};
352 if (fCluLayer == 0) {
353 fCluLayer = new TClonesArray*[AliITSgeomTGeo::kNLayers];
354 fCluCoord = new TClonesArray*[AliITSgeomTGeo::kNLayers];
355 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
360 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
361 AliITSlayer &layer=fgLayers[i];
362 if (!AliITSReconstructor::GetRecoParam()->GetLayersToSkip(i)) {
363 for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
364 AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
365 if(cls->TestBit(kSAflag)==kTRUE) continue; //clusters used by TPC prol.
366 if(cls->GetQ()==0) continue; //fake clusters dead zones
372 fCluLayer[i] = new TClonesArray("AliITSRecPoint",nclusters[i]);
374 fCluCoord[i] = new TClonesArray("AliITSclusterTable",nclusters[i]);
377 for(Int_t ilay=0;ilay<AliITSgeomTGeo::GetNLayers();ilay++){
378 TClonesArray &clulay = *fCluLayer[ilay];
379 TClonesArray &clucoo = *fCluCoord[ilay];
380 AliITSlayer &layer=fgLayers[ilay];
381 if (!AliITSReconstructor::GetRecoParam()->GetLayersToSkip(ilay)) {
382 for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
383 AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
384 if(cls->TestBit(kSAflag)==kTRUE) continue;
385 if(cls->GetQ()==0) continue;
386 Double_t phi=0;Double_t lambda=0;
387 Float_t x=0;Float_t y=0;Float_t z=0;
388 Float_t sx=0;Float_t sy=0;Float_t sz=0;
389 GetCoorAngles(cls,phi,lambda,x,y,z,primaryVertex);
390 GetCoorErrors(cls,sx,sy,sz);
391 new (clulay[dmar[ilay]]) AliITSRecPoint(*cls);
392 new (clucoo[dmar[ilay]]) AliITSclusterTable(x,y,z,sx,sy,sz,phi,lambda,cli);
401 Int_t minNPoints = (fSixPoints ? AliITSgeomTGeo::GetNLayers() : AliITSgeomTGeo::GetNLayers()-1);
402 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
403 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(i)) {
408 static Int_t nClusLay[AliITSgeomTGeo::kNLayers];//counter for clusters on each layer
410 //loop on different minNPoints
411 Int_t minMinNPoints=minNPoints;
412 if(AliITSReconstructor::GetRecoParam()->GetSAOnePointTracks()) minMinNPoints=2;
413 for(Int_t iMinNPoints=minNPoints; iMinNPoints>=minMinNPoints; iMinNPoints--) {
414 //loop on the different windows
415 for(Int_t nloop=0;nloop<fNloop;nloop++){
416 for(Int_t ncl=0;ncl<fCluLayer[0]->GetEntries();ncl++){ //loop starting from layer 0
421 AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[0]->At(ncl);
424 if (cl->GetQ()<=0) continue;
426 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(0,ncl);
427 fPhic = arr->GetPhi();
428 fLambdac = arr->GetLambda();
429 if (TMath::Abs(fLambdac)>0.26*TMath::Pi()) continue;
430 fPhiEstimate = fPhic;
431 AliITStrackSA* trs = new AliITStrackSA();
432 fPoint1[0]=primaryVertex[0];
433 fPoint1[1]=primaryVertex[1];
436 fPoint2[0]=arr->GetX();
437 fPoint2[1]=arr->GetY();
438 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) nClusLay[i]=0;
439 nClusLay[0] = SearchClusters(0,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
440 nClusLay[1] = SearchClusters(1,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
443 fPoint3[0] = fPointc[0];
444 fPoint3[1] = fPointc[1];
446 nClusLay[2] = SearchClusters(2,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
447 if(nClusLay[1]==0 && nClusLay[2]==0) pflag=0;
448 if(nClusLay[2]!=0 && nClusLay[1]!=0){ pflag=1; UpdatePoints();}
449 if(nClusLay[2]!=0 && nClusLay[1]==0){
451 fPoint3[0]=fPointc[0];
452 fPoint3[1]=fPointc[1];
455 nClusLay[3] = SearchClusters(3,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
457 if(nClusLay[3]!=0) UpdatePoints();
458 nClusLay[4] = SearchClusters(4,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
460 if(nClusLay[4]!=0) UpdatePoints();
461 nClusLay[5] = SearchClusters(5,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
465 //check of the candidate track
466 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers();nnp++) {
467 if(nClusLay[nnp]!=0) layOK+=1;
470 if(layOK>=iMinNPoints) {
471 AliITStrackV2* tr2 = 0;
472 tr2 = FitTrack(trs,primaryVertex);
475 AliESDtrack outtrack;
476 outtrack.UpdateTrackParams(tr2,AliESDtrack::kITSin);
477 event->AddTrack(&outtrack);
481 }//end loop on clusters of layer1
482 }//end loop on windows
483 }//end loop on min points
488 //if 5/6 points are required, second loop starting
489 //from second layer (SPD2), to find tracks with point of
492 //printf("looking from SPD2\n");
493 // counter for clusters on each layer
494 for(Int_t nloop=0;nloop<fNloop;nloop++){
495 Int_t ncl2=fCluLayer[1]->GetEntries();
496 while(ncl2--){ //loop starting from layer 2
499 AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[1]->At(ncl2);
502 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(1,ncl2);
503 fPhic = arr->GetPhi();
504 fLambdac = arr->GetLambda();
505 fPhiEstimate = fPhic;
507 AliITStrackSA* trs = new AliITStrackSA();
508 fPoint1[0]=primaryVertex[0];
509 fPoint1[1]=primaryVertex[1];
511 fPoint2[0]=arr->GetX();
512 fPoint2[1]=arr->GetY();
513 for(Int_t kk=0;kk<AliITSgeomTGeo::GetNLayers();kk++) nClusLay[kk] = 0;
514 nClusLay[0] = SearchClusters(1,fPhiWin[nloop],fLambdaWin[nloop],
515 trs,primaryVertex[2],pflag);
516 nClusLay[1] = SearchClusters(2,fPhiWin[nloop],fLambdaWin[nloop],
517 trs,primaryVertex[2],pflag);
520 fPoint3[0]=fPointc[0];
521 fPoint3[1]=fPointc[1];
523 nClusLay[2]= SearchClusters(3,fPhiWin[nloop],fLambdaWin[nloop],
524 trs,primaryVertex[2],pflag);
529 nClusLay[3]= SearchClusters(4,fPhiWin[nloop],fLambdaWin[nloop],
530 trs,primaryVertex[2],pflag);
535 nClusLay[4]=SearchClusters(5,fPhiWin[nloop],fLambdaWin[nloop],
536 trs,primaryVertex[2],pflag);
539 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-1;nnp++){
540 if(nClusLay[nnp]!=0) layOK+=1;
542 if(layOK>=minNPoints){ // 5/6
543 AliITStrackV2* tr2 = 0;
544 tr2 = FitTrack(trs,primaryVertex);
547 AliESDtrack outtrack;
548 outtrack.UpdateTrackParams(tr2,AliESDtrack::kITSin);
549 event->AddTrack(&outtrack);
555 }//end loop on clusters of layer2
560 // search for tracks starting from SPD2, SDD1, SDD2, SSD2
561 // for cosmics (A. Dainese 31.07.07)
562 if(fOuterStartLayer>0) {
563 for(Int_t innLay=1; innLay<=fOuterStartLayer; innLay++) {
564 //printf("Searching from layer %d outward\n",innLay);
565 minNPoints=AliITSgeomTGeo::GetNLayers()-innLay;
566 for(Int_t i=innLay;i<AliITSgeomTGeo::GetNLayers();i++)
567 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(i))
569 // counter for clusters on each layer
571 for(Int_t nloop=0;nloop<fNloop;nloop++){
572 Int_t nclInnLay=fCluLayer[innLay]->GetEntries();
573 while(nclInnLay--){ //loop starting from layer innLay
576 AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[innLay]->At(nclInnLay);
579 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(innLay,nclInnLay);
580 fPhic = arr->GetPhi();
581 fLambdac = arr->GetLambda();
582 fPhiEstimate = fPhic;
584 AliITStrackSA* trs = new AliITStrackSA();
585 fPoint1[0]=primaryVertex[0];
586 fPoint1[1]=primaryVertex[1];
587 fPoint2[0]=arr->GetX();
588 fPoint2[1]=arr->GetY();
591 for(kk=0;kk<AliITSgeomTGeo::GetNLayers();kk++) nClusLay[kk] = 0;
594 nClusLay[kk] = SearchClusters(innLay,fPhiWin[nloop],fLambdaWin[nloop],
595 trs,primaryVertex[2],pflag);
596 for(Int_t nextLay=innLay+1; nextLay<AliITSgeomTGeo::GetNLayers(); nextLay++) {
598 nClusLay[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
599 trs,primaryVertex[2],pflag);
603 fPoint3[0]=fPointc[0];
604 fPoint3[1]=fPointc[1];
612 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-innLay;nnp++){
613 if(nClusLay[nnp]!=0) layOK+=1;
615 if(layOK>=minNPoints){
616 AliITStrackV2* tr2 = 0;
617 tr2 = FitTrack(trs,primaryVertex);
621 AliESDtrack outtrack;
622 outtrack.UpdateTrackParams(tr2,AliESDtrack::kITSin);
623 event->AddTrack(&outtrack);
629 }//end loop on clusters of innLay
630 } //end loop on window sizes
632 } //end loop on innLay
633 } //end if(fOuterStartLayer>0)
636 // search for 1-point tracks, only for cosmics
637 // (A.Dainese 21.03.08)
638 if(AliITSReconstructor::GetRecoParam()->GetSAOnePointTracks() &&
639 TMath::Abs(event->GetMagneticField())<0.01) {
640 for(Int_t innLay=0; innLay<=fOuterStartLayer; innLay++) {
641 // counter for clusters on each layer
643 for(Int_t nloop=0;nloop<fNloop;nloop++){
644 Int_t nclInnLay=fCluLayer[innLay]->GetEntries();
645 while(nclInnLay--){ //loop starting from layer innLay
648 AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[innLay]->At(nclInnLay);
651 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(innLay,nclInnLay);
652 fPhic = arr->GetPhi();
653 fLambdac = arr->GetLambda();
654 fPhiEstimate = fPhic;
656 AliITStrackSA* trs = new AliITStrackSA();
657 fPoint1[0]=primaryVertex[0];
658 fPoint1[1]=primaryVertex[1];
659 fPoint2[0]=arr->GetX();
660 fPoint2[1]=arr->GetY();
663 for(kk=0;kk<AliITSgeomTGeo::GetNLayers();kk++) nClusLay[kk] = 0;
666 nClusLay[kk] = SearchClusters(innLay,fPhiWin[nloop],fLambdaWin[nloop],
667 trs,primaryVertex[2],pflag);
668 for(Int_t nextLay=innLay+1; nextLay<AliITSgeomTGeo::GetNLayers(); nextLay++) {
670 nClusLay[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
671 trs,primaryVertex[2],pflag);
675 fPoint3[0]=fPointc[0];
676 fPoint3[1]=fPointc[1];
684 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-innLay;nnp++){
685 if(nClusLay[nnp]!=0) layOK+=1;
688 AliITStrackV2* tr2 = 0;
689 Bool_t onePoint = kTRUE;
690 tr2 = FitTrack(trs,primaryVertex,onePoint);
693 AliESDtrack outtrack;
694 outtrack.UpdateTrackParams(tr2,AliESDtrack::kITSin);
695 event->AddTrack(&outtrack);
701 }//end loop on clusters of innLay
702 } //end loop on window sizes
704 } //end loop on innLay
705 } // end search 1-point tracks
707 Info("FindTracks","Number of found tracks: %d",event->GetNumberOfTracks());
712 //________________________________________________________________________
714 AliITStrackV2* AliITStrackerSA::FitTrack(AliITStrackSA* tr,Double_t *primaryVertex,Bool_t onePoint) {
715 //fit of the found track (most general case, also <6 points, layers missing)
716 // A.Dainese 16.11.07
719 const Int_t kMaxClu=AliITStrackSA::kMaxNumberOfClusters;
721 static Int_t firstmod[AliITSgeomTGeo::kNLayers];
723 static Int_t clind[AliITSgeomTGeo::kNLayers][kMaxClu];
724 static Int_t clmark[AliITSgeomTGeo::kNLayers][kMaxClu];
725 static Int_t nnn[AliITSgeomTGeo::kNLayers];
726 static Int_t kkk[AliITSgeomTGeo::kNLayers];
727 static Int_t end[AliITSgeomTGeo::kNLayers];
728 static AliITSRecPoint *listlayer[AliITSgeomTGeo::kNLayers][kMaxClu];
730 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
731 firstmod[i]=AliITSgeomTGeo::GetModuleIndex(i+1,1,1);
735 for(Int_t j=0;j<kMaxClu; j++){
743 Int_t nclusters = tr->GetNumberOfClustersSA();
744 for(Int_t ncl=0;ncl<nclusters;ncl++){
745 Int_t index = tr->GetClusterIndexSA(ncl);
746 AliITSRecPoint* cl = (AliITSRecPoint*)GetCluster(index);
747 if(cl->TestBit(kSAflag)==kTRUE) cl->ResetBit(kSAflag);
748 Int_t lay = (index & 0xf0000000) >> 28;
749 Int_t nInLay=end[lay];
750 listlayer[lay][nInLay]=cl;
752 clind[lay][ind]=index;
756 for(Int_t nlay=0;nlay<AliITSgeomTGeo::GetNLayers();nlay++){
757 for(Int_t ncl=0;ncl<tr->GetNumberOfMarked(nlay);ncl++){
758 Int_t mark = tr->GetClusterMark(nlay,ncl);
760 clmark[nlay][ind]=mark;
765 Int_t firstLay=-1,secondLay=-1;
766 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
772 } else if(secondLay==-1) {
778 if(firstLay==-1 || (secondLay==-1 && !onePoint)) return 0;
780 for(Int_t l0=0;l0<end[0];l0++){ //loop on layer 1
781 AliITSRecPoint* cl0 = (AliITSRecPoint*)listlayer[0][l0];
782 for(Int_t l1=0;l1<end[1];l1++){ //loop on layer 2
783 AliITSRecPoint* cl1 = (AliITSRecPoint*)listlayer[1][l1];
784 for(Int_t l2=0;l2<end[2];l2++){ //loop on layer 3
785 AliITSRecPoint* cl2 = (AliITSRecPoint*)listlayer[2][l2];
786 for(Int_t l3=0;l3<end[3];l3++){ //loop on layer 4
787 AliITSRecPoint* cl3 = (AliITSRecPoint*)listlayer[3][l3];
788 for(Int_t l4=0;l4<end[4];l4++){ //loop on layer 5
789 AliITSRecPoint* cl4 = (AliITSRecPoint*)listlayer[4][l4];
790 for(Int_t l5=0;l5<end[5];l5++){ //loop on layer 6
791 AliITSRecPoint* cl5 = (AliITSRecPoint*)listlayer[5][l5];
794 Double_t x1,y1,z1,sx1,sy1,sz1;
795 Double_t x2,y2,z2,sx2,sy2,sz2;
796 AliITSRecPoint* p1=0;
797 AliITSRecPoint* p2=0;
798 Int_t index1=0,index2=0;
804 index1=clind[0][l0];mrk1=clmark[0][l0];
808 index1=clind[1][l1];mrk1=clmark[1][l1];
812 index1=clind[2][l2];mrk1=clmark[2][l2];
816 index1=clind[3][l3];mrk1=clmark[3][l3];
820 index1=clind[4][l4];mrk1=clmark[4][l4];
827 index2=clind[1][l1];mrk2=clmark[1][l1];
831 index2=clind[2][l2];mrk2=clmark[2][l2];
835 index2=clind[3][l3];mrk2=clmark[3][l3];
839 index2=clind[4][l4];mrk2=clmark[4][l4];
843 index2=clind[5][l5];mrk2=clmark[5][l5];
851 Int_t module1 = p1->GetDetectorIndex()+firstmod[firstLay];
852 Int_t layer,ladder,detector;
853 AliITSgeomTGeo::GetModuleId(module1,layer,ladder,detector);
854 Float_t yclu1 = p1->GetY();
855 Float_t zclu1 = p1->GetZ();
856 Double_t cv=0,tgl2=0,phi2=0;
859 AliITSclusterTable* arr1 = (AliITSclusterTable*)GetClusterCoord(firstLay,cln1);
869 AliITSclusterTable* arr2 = (AliITSclusterTable*)GetClusterCoord(secondLay,cln2);
876 cv = Curvature(primaryVertex[0],primaryVertex[1],x1,y1,x2,y2);
877 tgl2 = (z2-z1)/TMath::Sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
878 phi2 = TMath::ATan2((y2-y1),(x2-x1));
879 } else { // special case of 1-point tracks, only for cosmics (B=0)
880 x2 = primaryVertex[0];
881 y2 = primaryVertex[1];
882 z2 = primaryVertex[2];
884 tgl2 = (z1-z2)/TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
885 phi2 = TMath::ATan2((y1-y2),(x1-x2));
889 AliITStrackSA* trac = new AliITStrackSA(layer,ladder,detector,yclu1,zclu1,phi2,tgl2,cv,1);
893 trac->AddClusterV2(5,(clind[5][l5] & 0x0fffffff)>>0);
894 trac->AddClusterMark(5,clmark[5][l5]);
897 trac->AddClusterV2(4,(clind[4][l4] & 0x0fffffff)>>0);
898 trac->AddClusterMark(4,clmark[4][l4]);
901 trac->AddClusterV2(3,(clind[3][l3] & 0x0fffffff)>>0);
902 trac->AddClusterMark(3,clmark[3][l3]);
905 trac->AddClusterV2(2,(clind[2][l2] & 0x0fffffff)>>0);
906 trac->AddClusterMark(2,clmark[2][l2]);
909 trac->AddClusterV2(1,(clind[1][l1] & 0x0fffffff)>>0);
910 trac->AddClusterMark(1,clmark[1][l1]);
913 trac->AddClusterV2(0,(clind[0][l0] & 0x0fffffff)>>0);
914 trac->AddClusterMark(0,clmark[0][l0]);
917 //fit with Kalman filter using AliITStrackerMI::RefitAt()
918 AliITStrackMI* ot = new AliITStrackSA(*trac);
920 ot->ResetCovariance(10.);
923 if(RefitAt(AliITSRecoParam::GetrInsideITSscreen(),ot,trac)){ //fit from layer 1 to layer 6
924 AliITStrackMI *otrack2 = new AliITStrackMI(*ot);
925 otrack2->ResetCovariance(10.);
926 otrack2->ResetClusters();
927 //fit from layer 6 to layer 1
928 if(RefitAt(AliITSRecoParam::GetrInsideSPD1(),otrack2,ot)) {
929 fListOfTracks->AddLast(otrack2);
930 fListOfSATracks->AddLast(trac);
949 if(fListOfTracks->GetEntries()==0) return 0;
951 Int_t lowchi2 = FindTrackLowChiSquare();
952 AliITStrackV2* otrack =(AliITStrackV2*)fListOfTracks->At(lowchi2);
953 AliITStrackSA* trsa = (AliITStrackSA*)fListOfSATracks->At(lowchi2);
955 if(otrack==0) return 0;
957 Int_t indexc[AliITSgeomTGeo::kNLayers];
958 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) indexc[i]=0;
959 for(Int_t nind=0;nind<otrack->GetNumberOfClusters();nind++){
960 indexc[nind] = otrack->GetClusterIndex(nind);
963 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
964 if(i<otrack->GetNumberOfClusters()) {
965 AliITSRecPoint* cl = (AliITSRecPoint*)GetCluster(indexc[i]);
966 labl[i][0]=cl->GetLabel(0);
967 labl[i][1]=cl->GetLabel(1);
968 labl[i][2]=cl->GetLabel(2);
976 CookLabel(otrack,0.); //MI change - to see fake ratio
978 Int_t label=FindLabel(labl[0][0],labl[1][0],labl[2][0],labl[3][0],labl[4][0],labl[5][0]);
980 for(Int_t i=0;i<otrack->GetNumberOfClusters();i++)
981 if(labl[i][0]==label || labl[i][1]==label || labl[i][2]==label) lflag++;
983 if(lflag<otrack->GetNumberOfClusters()) label = -label;
984 otrack->SetLabel(label);
986 //remove clusters of found track
987 for(Int_t nlay=0;nlay<AliITSgeomTGeo::GetNLayers();nlay++){
988 for(Int_t cln=0;cln<trsa->GetNumberOfMarked(nlay);cln++){
989 Int_t index = trsa->GetClusterMark(nlay,cln);
990 fCluLayer[nlay]->RemoveAt(index);
991 RemoveClusterCoord(nlay,index);
992 fCluLayer[nlay]->Compress();
1002 //_______________________________________________________
1003 Int_t AliITStrackerSA::SearchClusters(Int_t layer,Double_t phiwindow,Double_t lambdawindow, AliITStrackSA* trs,Double_t /*zvertex*/,Int_t pflag){
1004 //function used to to find the clusters associated to the track
1006 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(layer)) return 0;
1009 AliITSlayer &lay = fgLayers[layer];
1010 Double_t r=lay.GetR();
1012 Float_t cx1,cx2,cy1,cy2;
1013 FindEquation(fPoint1[0],fPoint1[1],fPoint2[0],fPoint2[1],fPoint3[0],fPoint3[1],fCoef1,fCoef2,fCoef3);
1014 if (FindIntersection(fCoef1,fCoef2,fCoef3,-r*r,cx1,cy1,cx2,cy2)==0)
1016 Double_t fi1=TMath::ATan2(cy1-fPoint1[1],cx1-fPoint1[0]);
1017 Double_t fi2=TMath::ATan2(cy2-fPoint1[1],cx2-fPoint1[0]);
1018 fPhiEstimate=ChoosePoint(fi1,fi2,fPhic);
1022 Int_t ncl = fCluLayer[layer]->GetEntries();
1023 for (Int_t index=0; index<ncl; index++) {
1024 AliITSRecPoint *c = (AliITSRecPoint*)fCluLayer[layer]->At(index);
1026 if (c->GetQ()<=0) continue;
1028 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(layer,index);
1029 Double_t phi = arr->GetPhi();
1030 if (TMath::Abs(phi-fPhiEstimate)>phiwindow) continue;
1032 Double_t lambda = arr->GetLambda();
1033 if (TMath::Abs(lambda-fLambdac)>lambdawindow) continue;
1035 if(trs->GetNumberOfClustersSA()==trs->GetMaxNumberOfClusters()) return 0;
1036 if(trs->GetNumberOfMarked(layer)==trs->GetMaxNMarkedPerLayer()) return 0;
1037 Int_t orind = arr->GetOrInd();
1038 trs->AddClusterSA(layer,orind);
1039 trs->AddClusterMark(layer,index);
1045 fPointc[0]=arr->GetX();
1046 fPointc[1]=arr->GetY();
1052 //________________________________________________________________
1053 void AliITStrackerSA::UpdatePoints(){
1054 //update of points for the estimation of the curvature
1056 fPoint2[0]=fPoint3[0];
1057 fPoint2[1]=fPoint3[1];
1058 fPoint3[0]=fPointc[0];
1059 fPoint3[1]=fPointc[1];
1064 //___________________________________________________________________
1065 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){
1067 //given (x,y) of three recpoints (in global coordinates)
1068 //returns the parameters a,b,c of circonference x*x + y*y +a*x + b*y +c
1070 Float_t den = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1);
1071 if(den==0) return 0;
1072 a = ((y3-y1)*(x2*x2+y2*y2-x1*x1-y1*y1)-(y2-y1)*(x3*x3+y3*y3-x1*x1-y1*y1))/den;
1073 b = -(x2*x2-x1*x1+y2*y2-y1*y1+a*(x2-x1))/(y2-y1);
1074 c = -x1*x1-y1*y1-a*x1-b*y1;
1077 //__________________________________________________________________________
1078 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){
1080 //Finds the intersection between the circonference of the track and the circonference centered in (0,0) represented by one layer
1081 //c2 is -rlayer*rlayer
1085 Double_t aA = (b1*b1)/(a1*a1)+1;
1086 Double_t bB = (-2*m*b1/(a1*a1));
1087 Double_t cC = c2+(m*m)/(a1*a1);
1088 Double_t dD = bB*bB-4*aA*cC;
1091 y1 = (-bB+TMath::Sqrt(dD))/(2*aA);
1092 y2 = (-bB-TMath::Sqrt(dD))/(2*aA);
1093 x1 = (c2-c1-b1*y1)/a1;
1094 x2 = (c2-c1-b1*y2)/a1;
1098 //____________________________________________________________________
1099 Double_t AliITStrackerSA::Curvature(Double_t x1,Double_t y1,Double_t
1100 x2,Double_t y2,Double_t x3,Double_t y3){
1102 //calculates the curvature of track
1103 Double_t den = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1);
1104 if(den==0) return 0;
1105 Double_t a = ((y3-y1)*(x2*x2+y2*y2-x1*x1-y1*y1)-(y2-y1)*(x3*x3+y3*y3-x1*x1-y1*y1))/den;
1106 Double_t b = -(x2*x2-x1*x1+y2*y2-y1*y1+a*(x2-x1))/(y2-y1);
1107 Double_t c = -x1*x1-y1*y1-a*x1-b*y1;
1110 if((a*a+b*b-4*c)<0) return 0;
1111 Double_t rad = TMath::Sqrt(a*a+b*b-4*c)/2.;
1112 if(rad==0) return 0;
1114 if((x1>0 && y1>0 && x1<xc)) rad*=-1;
1115 if((x1<0 && y1>0 && x1<xc)) rad*=-1;
1116 // if((x1<0 && y1<0 && x1<xc)) rad*=-1;
1117 // if((x1>0 && y1<0 && x1<xc)) rad*=-1;
1124 //____________________________________________________________________
1125 Double_t AliITStrackerSA::ChoosePoint(Double_t p1, Double_t p2, Double_t pp){
1127 //Returns the point closest to pp
1129 Double_t diff1 = p1-pp;
1130 Double_t diff2 = p2-pp;
1132 if(TMath::Abs(diff1)<TMath::Abs(diff2)) fPhiEstimate=p1;
1133 else fPhiEstimate=p2;
1134 return fPhiEstimate;
1139 //_________________________________________________________________
1140 Int_t AliITStrackerSA::FindTrackLowChiSquare() const {
1141 // returns track with lowest chi square
1142 Int_t dim=fListOfTracks->GetEntries();
1143 if(dim<=1) return 0;
1144 AliITStrackV2* trk = (AliITStrackV2*)fListOfTracks->At(0);
1145 Double_t minChi2=trk->GetChi2();
1147 for(Int_t i=1;i<dim;i++){
1148 AliITStrackV2* trk = (AliITStrackV2*)fListOfTracks->At(i);
1149 Double_t chi2=trk->GetChi2();
1158 //__________________________________________________________
1159 Int_t AliITStrackerSA::FindLabel(Int_t l0, Int_t l1, Int_t l2, Int_t l3, Int_t l4, Int_t l5){
1161 //function used to determine the track label
1163 Int_t lb[6] = {l0,l1,l2,l3,l4,l5};
1164 Int_t aa[6]={1,1,1,1,1,1};
1167 Int_t k=0;Int_t w=0;Int_t num=6;
1168 for(Int_t i=5;i>=0;i--) if(lb[i]==-1) num=i;
1172 for(Int_t i=k+1;i<num;i++){
1174 if(lb[k]==lb[i] && aa[k]!=0){
1185 for(Int_t j=0;j<6;j++){
1198 if(num<1) return -1;
1202 //_____________________________________________________________________________
1203 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,
1204 Int_t gl12, Int_t gl13, Int_t gl14,Int_t gl15, Int_t gl16, Int_t gl17, Int_t gl18, Int_t minNPoints){
1207 //function used to assign label to the found track. If track is fake, the label is negative
1209 Int_t lb0[6] = {gl1,gl2,gl3,gl4,gl5,gl6};
1210 Int_t lb1[6] = {gl7,gl8,gl9,gl10,gl11,gl12};
1211 Int_t lb2[6] = {gl13,gl14,gl15,gl16,gl17,gl18};
1212 Int_t ll=FindLabel(lb0[0],lb0[1],lb0[2],lb0[3],lb0[4],lb0[5]);
1213 Int_t lflag=0;Int_t num=6;
1214 if(lb0[5]==-1 && lb1[5]==-1 && lb2[5]==-1) num=5;
1216 for(Int_t i=0;i<num;i++){
1217 if(lb0[i]==ll || lb1[i]==ll || lb2[i]==ll) lflag+=1;
1220 if(lflag>=minNPoints) return ll;
1225 //_____________________________________________________________________________
1226 void AliITStrackerSA::SetCalculatedWindowSizes(Int_t n, Float_t phimin, Float_t phimax, Float_t lambdamin, Float_t lambdamax){
1227 // Set sizes of the phi and lambda windows used for track finding
1229 if(fPhiWin) delete [] fPhiWin;
1230 if(fLambdaWin) delete [] fLambdaWin;
1231 fPhiWin = new Double_t[fNloop];
1232 fLambdaWin = new Double_t[fNloop];
1233 Float_t stepPhi=(phimax-phimin)/(Float_t)(fNloop-1);
1234 Float_t stepLambda=(lambdamax-lambdamin)/(Float_t)(fNloop-1);
1235 for(Int_t k=0;k<fNloop;k++){
1236 Float_t phi=phimin+k*stepPhi;
1237 Float_t lam=lambdamin+k*stepLambda;
1242 //_____________________________________________________________________________
1243 void AliITStrackerSA::SetFixedWindowSizes(Int_t n, Double_t *phi, Double_t *lam){
1244 // Set sizes of the phi and lambda windows used for track finding
1246 if(phi){ // user defined values
1247 fPhiWin = new Double_t[fNloop];
1248 fLambdaWin = new Double_t[fNloop];
1249 for(Int_t k=0;k<fNloop;k++){
1251 fLambdaWin[k]=lam[k];
1254 else { // default values
1256 Double_t phid[33] = {0.002,0.003,0.004,0.0045,0.0047,
1257 0.005,0.0053,0.0055,
1258 0.006,0.0063,0.0065,0.007,0.0073,0.0075,0.0077,
1259 0.008,0.0083,0.0085,0.0087,0.009,0.0095,0.0097,
1260 0.01,0.0105,0.011,0.0115,0.012,0.0125,0.013,0.0135,0.0140,0.0145};
1261 Double_t lambdad[33] = {0.003,0.004,0.005,0.005,0.005,
1263 0.006,0.006,0.006,0.007,0.007,0.007,0.007,
1264 0.007,0.007,0.007,0.007,0.007,0.007,0.007,
1265 0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008};
1272 fPhiWin = new Double_t[fNloop];
1273 fLambdaWin = new Double_t[fNloop];
1275 Double_t factor=AliITSReconstructor::GetRecoParam()->GetFactorSAWindowSizes(); // possibility to enlarge windows for cosmics reco with large misalignments (A.Dainese)
1277 for(Int_t k=0;k<fNloop;k++){
1278 fPhiWin[k]=phid[k]*factor;
1279 fLambdaWin[k]=lambdad[k]*factor;
1285 //_______________________________________________________________________
1286 void AliITStrackerSA::GetCoorAngles(AliITSRecPoint* cl,Double_t &phi,Double_t &lambda, Float_t &x, Float_t &y,Float_t &z,Double_t* vertex){
1287 //Returns values of phi (azimuthal) and lambda angles for a given cluster
1289 Double_t rot[9]; fGeom->GetRotMatrix(module,rot);
1290 Int_t lay,lad,det; fGeom->GetModuleId(module,lay,lad,det);
1291 Float_t tx,ty,tz; fGeom->GetTrans(lay,lad,det,tx,ty,tz);
1293 Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
1294 Double_t phi1=TMath::Pi()/2+alpha;
1295 if (lay==1) phi1+=TMath::Pi();
1297 Float_t cp=TMath::Cos(phi1), sp=TMath::Sin(phi1);
1298 Float_t r=tx*cp+ty*sp;
1300 xyz= r*cp - cl->GetY()*sp;
1301 y= r*sp + cl->GetY()*cp;
1305 cl->GetGlobalXYZ(xyz);
1310 phi=TMath::ATan2(y-vertex[1],x-vertex[0]);
1311 lambda=TMath::ATan2(z-vertex[2],TMath::Sqrt((x-vertex[0])*(x-vertex[0])+(y-vertex[1])*(y-vertex[1])));
1314 //________________________________________________________________________
1315 void AliITStrackerSA::GetCoorErrors(AliITSRecPoint* cl,Float_t &sx,Float_t &sy, Float_t &sz){
1317 //returns sigmax, y, z of cluster in global coordinates
1319 Double_t rot[9]; fGeom->GetRotMatrix(module,rot);
1321 AliITSgeomTGeo::GetModuleId(module,lay,lad,det);
1323 Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
1324 Double_t phi=TMath::Pi()/2+alpha;
1325 if (lay==1) phi+=TMath::Pi();
1327 Float_t cp=TMath::Cos(phi), sp=TMath::Sin(phi);
1330 cl->GetGlobalCov(covm);
1331 sx=TMath::Sqrt(covm[0]);
1332 sy=TMath::Sqrt(covm[3]);
1333 sz=TMath::Sqrt(covm[5]);
1335 sx = TMath::Sqrt(sp*sp*cl->GetSigmaY2());
1336 sy = TMath::Sqrt(cp*cp*cl->GetSigmaY2());
1337 sz = TMath::Sqrt(cl->GetSigmaZ2());