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(),
66 // Default constructor
70 //____________________________________________________________________________
71 AliITStrackerSA::AliITStrackerSA(const Char_t *geom):AliITStrackerMI(0),
91 // Standard constructor (Vertex is known and passed to this obj.)
93 AliWarning("\"geom\" is actually a dummy argument !");
101 //____________________________________________________________________________
102 AliITStrackerSA::AliITStrackerSA(const Char_t *geom, AliESDVertex *vert):AliITStrackerMI(0),
122 // Standard constructor (Vertex is known and passed to this obj.)
124 AliWarning("\"geom\" is actually a dummy argument !");
130 //____________________________________________________________________________
131 AliITStrackerSA::AliITStrackerSA(const Char_t *geom, AliITSVertexer *vertexer):AliITStrackerMI(0),
151 // Standard constructor (Vertex is unknown - vertexer is passed to this obj)
153 AliWarning("\"geom\" is actually a dummy argument !");
156 fVertexer = vertexer;
160 //____________________________________________________________________________
161 AliITStrackerSA::AliITStrackerSA(const AliITStrackerSA& tracker):AliITStrackerMI(),
162 fPhiEstimate(tracker.fPhiEstimate),
163 fITSStandAlone(tracker.fITSStandAlone),
164 fLambdac(tracker.fLambdac),
165 fPhic(tracker.fPhic),
166 fCoef1(tracker.fCoef1),
167 fCoef2(tracker.fCoef2),
168 fCoef3(tracker.fCoef3),
169 fNloop(tracker.fNloop),
170 fPhiWin(tracker.fPhiWin),
171 fLambdaWin(tracker.fLambdaWin),
172 fVert(tracker.fVert),
173 fVertexer(tracker.fVertexer),
174 fListOfTracks(tracker.fListOfTracks),
175 fITSclusters(tracker.fITSclusters),
176 fSixPoints(tracker.fSixPoints),
177 fOuterStartLayer(tracker.fOuterStartLayer),
178 fCluLayer(tracker.fCluLayer),
179 fCluCoord(tracker.fCluCoord) {
181 for(Int_t i=0;i<2;i++){
182 fPoint1[i]=tracker.fPoint1[i];
183 fPoint2[i]=tracker.fPoint2[i];
184 fPoint3[i]=tracker.fPoint3[i];
185 fPointc[i]=tracker.fPointc[i];
187 if(tracker.fVertexer && tracker.fVert){
188 fVert = new AliESDVertex(*tracker.fVert);
191 fVert = tracker.fVert;
193 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
194 fCluLayer[i] = tracker.fCluLayer[i];
195 fCluCoord[i] = tracker.fCluCoord[i];
198 //______________________________________________________________________
199 AliITStrackerSA& AliITStrackerSA::operator=(const AliITStrackerSA& source){
200 // Assignment operator.
201 this->~AliITStrackerSA();
202 new(this) AliITStrackerSA(source);
207 //____________________________________________________________________________
208 AliITStrackerSA::~AliITStrackerSA(){
210 // if fVertexer is not null, the AliESDVertex obj. is owned by this class
211 // and is deleted here
213 if(fVert)delete fVert;
218 if(fPhiWin)delete []fPhiWin;
219 if(fLambdaWin)delete []fLambdaWin;
220 fListOfTracks->Delete();
221 delete fListOfTracks;
223 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
225 fCluLayer[i]->Delete();
232 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
234 fCluCoord[i]->Delete();
243 //____________________________________________________________________________
244 Int_t AliITStrackerSA::Clusters2Tracks(AliESDEvent *event){
245 // This method is used to find and fit the tracks. By default the corresponding
246 // method in the parent class is invoked. In this way a combined tracking
247 // TPC+ITS is performed. If the flag fITSStandAlone is true, the tracking
248 // is done in the ITS only. In the standard reconstruction chain this option
249 // can be set via AliReconstruction::SetOption("ITS","onlyITS")
252 rc=AliITStrackerMI::Clusters2Tracks(event);
255 AliDebug(1,"Stand Alone flag set: doing tracking in ITS alone\n");
257 if(!rc) rc=FindTracks(event);
261 //____________________________________________________________________________
262 void AliITStrackerSA::Init(){
263 // Reset all data members
265 for(Int_t i=0;i<3;i++){fPoint1[i]=0;fPoint2[i]=0;fPoint3[i]=0;}
278 SetOuterStartLayer(0);
280 fListOfTracks=new TObjArray(0,0);
284 //_______________________________________________________________________
285 void AliITStrackerSA::ResetForFinding(){
286 // Reset data members used in all loops during track finding
288 for(Int_t i=0;i<3;i++){fPoint1[i]=0;fPoint2[i]=0;fPoint3[i]=0;}
296 fListOfTracks->Delete();
301 //______________________________________________________________________
302 Int_t AliITStrackerSA::FindTracks(AliESDEvent* event){
304 // Track finder using the ESD object
307 //controllare numero cluster sui layer1 e 2 (morti?)
308 //non trova tracce...controllare..
311 Fatal("FindTracks","ITS cluster tree is not accessed - Abort!!!\n Please use method SetClusterTree to pass the pointer to the tree\n");
316 //Reads event and mark clusters of traks already found, with flag kITSin
317 Int_t nentr=event->GetNumberOfTracks();
319 AliESDtrack *track=event->GetTrack(nentr);
320 if (track->GetStatus()&AliESDtrack::kITSin==AliESDtrack::kITSin){
322 Int_t ncl = track->GetITSclusters(idx);
323 for(Int_t k=0;k<ncl;k++){
324 AliITSRecPoint* cll = (AliITSRecPoint*)GetCluster(idx[k]);
325 cll->SetBit(kSAflag);
330 Double_t primaryVertex[3];
331 event->GetVertex()->GetXYZ(primaryVertex);
332 //Creates TClonesArray with clusters for each layer. The clusters already used
333 //by AliITStrackerMI are not considered
334 Int_t nclusters[6]={0,0,0,0,0,0};
335 Int_t dmar[6]={0,0,0,0,0,0};
336 if (fCluLayer == 0) {
337 fCluLayer = new TClonesArray*[AliITSgeomTGeo::GetNLayers()];
338 fCluCoord = new TClonesArray*[AliITSgeomTGeo::GetNLayers()];
339 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
344 Int_t * firstmod = new Int_t[AliITSgeomTGeo::GetNLayers()];
345 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
346 firstmod[i]=AliITSgeomTGeo::GetModuleIndex(i+1,1,1);
347 AliITSlayer &layer=fgLayers[i];
348 if (!AliITSReconstructor::GetRecoParam()->GetLayersToSkip(i)) {
349 for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
350 AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
351 if(cls->TestBit(kSAflag)==kTRUE) continue; //clusters used by TPC prol.
352 if(cls->GetQ()==0) continue; //fake clusters dead zones
358 fCluLayer[i] = new TClonesArray("AliITSRecPoint",nclusters[i]);
360 fCluCoord[i] = new TClonesArray("AliITSclusterTable",nclusters[i]);
363 for(Int_t ilay=0;ilay<AliITSgeomTGeo::GetNLayers();ilay++){
364 TClonesArray &clulay = *fCluLayer[ilay];
365 TClonesArray &clucoo = *fCluCoord[ilay];
366 AliITSlayer &layer=fgLayers[ilay];
367 if (!AliITSReconstructor::GetRecoParam()->GetLayersToSkip(ilay)) {
368 for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
369 AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
370 if(cls->TestBit(kSAflag)==kTRUE) continue;
371 if(cls->GetQ()==0) continue;
372 Double_t phi=0;Double_t lambda=0;
373 Float_t x=0;Float_t y=0;Float_t z=0;
374 Float_t sx=0;Float_t sy=0;Float_t sz=0;
375 GetCoorAngles(cls,phi,lambda,x,y,z,primaryVertex);
376 GetCoorErrors(cls,sx,sy,sz);
377 new (clulay[dmar[ilay]]) AliITSRecPoint(*cls);
378 new (clucoo[dmar[ilay]]) AliITSclusterTable(x,y,z,sx,sy,sz,phi,lambda,cli);
384 Int_t minNPoints = (fSixPoints ? AliITSgeomTGeo::GetNLayers() : AliITSgeomTGeo::GetNLayers()-1);
385 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
386 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(i)) {
393 //loop on the different windows
394 Int_t * nn = new Int_t[AliITSgeomTGeo::GetNLayers()];//counter for clusters on each layer
395 for(Int_t nloop=0;nloop<fNloop;nloop++){
396 for(Int_t ncl=0;ncl<fCluLayer[0]->GetEntries();ncl++){ //loop starting from layer 0
401 AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[0]->At(ncl);
404 if (cl->GetQ()<=0) continue;
406 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(0,ncl);
407 fPhic = arr->GetPhi();
408 fLambdac = arr->GetLambda();
409 if (TMath::Abs(fLambdac)>0.26*TMath::Pi()) continue;
410 fPhiEstimate = fPhic;
411 AliITStrackSA* trs = new AliITStrackSA();
412 fPoint1[0]=primaryVertex[0];
413 fPoint1[1]=primaryVertex[1];
416 fPoint2[0]=arr->GetX();
417 fPoint2[1]=arr->GetY();
418 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){ nn[i]=0;}
419 nn[0] = SearchClusters(0,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
420 nn[1] = SearchClusters(1,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
423 fPoint3[0] = fPointc[0];
424 fPoint3[1] = fPointc[1];
426 nn[2] = SearchClusters(2,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
427 if(nn[1]==0 && nn[2]==0) pflag=0;
428 if(nn[2]!=0 && nn[1]!=0){ pflag=1; UpdatePoints();}
429 if(nn[2]!=0 && nn[1]==0){
431 fPoint3[0]=fPointc[0];
432 fPoint3[1]=fPointc[1];
435 nn[3] = SearchClusters(3,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
437 if(nn[3]!=0) UpdatePoints();
438 nn[4] = SearchClusters(4,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
440 if(nn[4]!=0) UpdatePoints();
441 nn[5] = SearchClusters(5,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
445 //check of the candidate track
446 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers();nnp++) {
447 if(nn[nnp]!=0) layOK+=1;
450 if(layOK>=minNPoints){
451 AliITStrackV2* tr2 = 0;
452 tr2 = FitTrack(trs,primaryVertex);
455 AliESDtrack outtrack;
456 outtrack.UpdateTrackParams(tr2,AliESDtrack::kITSin);
457 event->AddTrack(&outtrack);
461 }//end loop on clusters of layer1
470 //if 5/6 points are required, second loop starting
471 //from second layer (SPD2), to find tracks with point of
474 //printf("looking from SPD2\n");
475 // counter for clusters on each layer
476 Int_t * nn = new Int_t[AliITSgeomTGeo::GetNLayers()-1];
477 for(Int_t nloop=0;nloop<fNloop;nloop++){
478 Int_t ncl2=fCluLayer[1]->GetEntries();
479 while(ncl2--){ //loop starting from layer 2
482 AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[1]->At(ncl2);
485 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(1,ncl2);
486 fPhic = arr->GetPhi();
487 fLambdac = arr->GetLambda();
488 fPhiEstimate = fPhic;
490 AliITStrackSA* trs = new AliITStrackSA();
491 fPoint1[0]=primaryVertex[0];
492 fPoint1[1]=primaryVertex[1];
494 fPoint2[0]=arr->GetX();
495 fPoint2[1]=arr->GetY();
496 for(Int_t kk=0;kk<AliITSgeomTGeo::GetNLayers()-1;kk++)nn[kk] = 0;
497 nn[0] = SearchClusters(1,fPhiWin[nloop],fLambdaWin[nloop],
498 trs,primaryVertex[2],pflag);
499 nn[1] = SearchClusters(2,fPhiWin[nloop],fLambdaWin[nloop],
500 trs,primaryVertex[2],pflag);
503 fPoint3[0]=fPointc[0];
504 fPoint3[1]=fPointc[1];
506 nn[2]= SearchClusters(3,fPhiWin[nloop],fLambdaWin[nloop],
507 trs,primaryVertex[2],pflag);
512 nn[3]= SearchClusters(4,fPhiWin[nloop],fLambdaWin[nloop],
513 trs,primaryVertex[2],pflag);
518 nn[4]=SearchClusters(5,fPhiWin[nloop],fLambdaWin[nloop],
519 trs,primaryVertex[2],pflag);
522 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-1;nnp++){
523 if(nn[nnp]!=0) fl+=1;
525 if(fl>=minNPoints){ // 5/6
526 AliITStrackV2* tr2 = 0;
527 tr2 = FitTrack(trs,primaryVertex);
530 AliESDtrack outtrack;
531 outtrack.UpdateTrackParams(tr2,AliESDtrack::kITSin);
532 event->AddTrack(&outtrack);
538 }//end loop on clusters of layer2
544 // search for tracks starting from SPD2, SDD1, SDD2, SSD2
545 // for cosmics (A. Dainese 31.07.07)
546 if(fOuterStartLayer>0) {
547 for(Int_t innLay=1; innLay<=fOuterStartLayer; innLay++) {
548 //printf("Searching from layer %d outward\n",innLay);
549 minNPoints=AliITSgeomTGeo::GetNLayers()-innLay;
550 for(Int_t i=innLay;i<AliITSgeomTGeo::GetNLayers();i++)
551 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(i))
553 // counter for clusters on each layer
554 Int_t * nn = new Int_t[AliITSgeomTGeo::GetNLayers()-innLay];
555 for(Int_t nloop=0;nloop<fNloop;nloop++){
556 Int_t nclInnLay=fCluLayer[innLay]->GetEntries();
557 while(nclInnLay--){ //loop starting from layer innLay
560 AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[innLay]->At(nclInnLay);
563 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(innLay,nclInnLay);
564 fPhic = arr->GetPhi();
565 fLambdac = arr->GetLambda();
566 fPhiEstimate = fPhic;
568 AliITStrackSA* trs = new AliITStrackSA();
569 fPoint1[0]=primaryVertex[0];
570 fPoint1[1]=primaryVertex[1];
571 fPoint2[0]=arr->GetX();
572 fPoint2[1]=arr->GetY();
575 for(kk=0;kk<AliITSgeomTGeo::GetNLayers()-innLay;kk++) nn[kk] = 0;
578 nn[kk] = SearchClusters(innLay,fPhiWin[nloop],fLambdaWin[nloop],
579 trs,primaryVertex[2],pflag);
580 for(Int_t nextLay=innLay+1; nextLay<AliITSgeomTGeo::GetNLayers(); nextLay++) {
582 nn[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
583 trs,primaryVertex[2],pflag);
587 fPoint3[0]=fPointc[0];
588 fPoint3[1]=fPointc[1];
596 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-innLay;nnp++){
597 if(nn[nnp]!=0) fl+=1;
600 AliITStrackV2* tr2 = 0;
601 tr2 = FitTrack(trs,primaryVertex);
605 AliESDtrack outtrack;
606 outtrack.UpdateTrackParams(tr2,AliESDtrack::kITSin);
607 event->AddTrack(&outtrack);
613 }//end loop on clusters of innLay
614 } //end loop on window sizes
617 } //end loop on innLay
618 } //end if(fOuterStartLayer>0)
622 Info("FindTracks","Number of found tracks: %d",event->GetNumberOfTracks());
627 //________________________________________________________________________
629 AliITStrackV2* AliITStrackerSA::FitTrack(AliITStrackSA* tr,Double_t *primaryVertex) {
630 //fit of the found track (most general case, also <6 points, layers missing)
631 // A.Dainese 16.11.07
634 Int_t * firstmod = new Int_t[AliITSgeomTGeo::GetNLayers()];
635 TObjArray** listlayer = new TObjArray*[AliITSgeomTGeo::GetNLayers()];
636 Int_t ** clind=new Int_t*[AliITSgeomTGeo::GetNLayers()];
637 Int_t ** clmark=new Int_t*[AliITSgeomTGeo::GetNLayers()];
638 Int_t * nnn = new Int_t[AliITSgeomTGeo::GetNLayers()];
639 Int_t * kkk = new Int_t[AliITSgeomTGeo::GetNLayers()];
641 const Int_t maxclu=AliITStrackSA::GetMaxNumberOfClusters();
643 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
644 firstmod[i]=AliITSgeomTGeo::GetModuleIndex(i+1,1,1);
645 listlayer[i] = new TObjArray(0,0);
648 clind[i]=new Int_t[maxclu];
649 clmark[i]=new Int_t[maxclu];
650 for(Int_t j=0;j<maxclu; j++){
657 Int_t nclusters = tr->GetNumberOfClustersSA();
658 for(Int_t ncl=0;ncl<nclusters;ncl++){
659 Int_t index = tr->GetClusterIndexSA(ncl);
660 AliITSRecPoint* cl = (AliITSRecPoint*)GetCluster(index);
661 if(cl->TestBit(kSAflag)==kTRUE) cl->ResetBit(kSAflag);
662 Int_t lay = (index & 0xf0000000) >> 28;
663 listlayer[lay]->AddLast(cl);
665 clind[lay][ind]=index;
669 for(Int_t nlay=0;nlay<AliITSgeomTGeo::GetNLayers();nlay++){
670 for(Int_t ncl=0;ncl<tr->GetNumberOfMarked(nlay);ncl++){
671 Int_t mark = tr->GetClusterMark(nlay,ncl);
673 clmark[nlay][ind]=mark;
679 Int_t firstLay=-1,secondLay=-1;
680 Int_t * end = new Int_t[AliITSgeomTGeo::GetNLayers()];
681 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
682 if(listlayer[i]->GetEntries()==0) {
685 end[i]=listlayer[i]->GetEntries();
688 } else if(secondLay==-1) {
694 if(firstLay==-1 || secondLay==-1) {
695 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
708 TClonesArray* listSA = new TClonesArray("AliITStrackSA");
709 TClonesArray &tri = *listSA;
712 for(Int_t l0=0;l0<end[0];l0++){ //loop on layer 1
713 AliITSRecPoint* cl0 = (AliITSRecPoint*)listlayer[0]->At(l0);
714 for(Int_t l1=0;l1<end[1];l1++){ //loop on layer 2
715 AliITSRecPoint* cl1 = (AliITSRecPoint*)listlayer[1]->At(l1);
716 for(Int_t l2=0;l2<end[2];l2++){ //loop on layer 3
717 AliITSRecPoint* cl2 = (AliITSRecPoint*)listlayer[2]->At(l2);
718 for(Int_t l3=0;l3<end[3];l3++){ //loop on layer 4
719 AliITSRecPoint* cl3 = (AliITSRecPoint*)listlayer[3]->At(l3);
720 for(Int_t l4=0;l4<end[4];l4++){ //loop on layer 5
721 AliITSRecPoint* cl4 = (AliITSRecPoint*)listlayer[4]->At(l4);
722 for(Int_t l5=0;l5<end[5];l5++){ //loop on layer 6
723 AliITSRecPoint* cl5 = (AliITSRecPoint*)listlayer[5]->At(l5);
726 Double_t x1,y1,z1,sx1,sy1,sz1;
727 Double_t x2,y2,z2,sx2,sy2,sz2;
728 AliITSRecPoint* p1=0;
729 AliITSRecPoint* p2=0;
730 Int_t index1=0,index2=0;
736 index1=clind[0][l0];mrk1=clmark[0][l0];
740 index1=clind[1][l1];mrk1=clmark[1][l1];
744 index1=clind[2][l2];mrk1=clmark[2][l2];
748 index1=clind[3][l3];mrk1=clmark[3][l3];
752 index1=clind[4][l4];mrk1=clmark[4][l4];
759 index2=clind[1][l1];mrk2=clmark[1][l1];
763 index2=clind[2][l2];mrk2=clmark[2][l2];
767 index2=clind[3][l3];mrk2=clmark[3][l3];
771 index2=clind[4][l4];mrk2=clmark[4][l4];
775 index2=clind[5][l5];mrk2=clmark[5][l5];
779 Int_t module1 = p1->GetDetectorIndex()+firstmod[firstLay];
783 AliITSclusterTable* arr1 = (AliITSclusterTable*)GetClusterCoord(firstLay,cln1);
784 AliITSclusterTable* arr2 = (AliITSclusterTable*)GetClusterCoord(secondLay,cln2);
798 Int_t layer,ladder,detector;
799 AliITSgeomTGeo::GetModuleId(module1,layer,ladder,detector);
800 Float_t yclu1 = p1->GetY();
801 Float_t zclu1 = p1->GetZ();
802 Double_t cv=Curvature(primaryVertex[0],primaryVertex[1],x1,y1,x2,y2);
803 Double_t tgl2 = (z2-z1)/TMath::Sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
804 Double_t phi2 = TMath::ATan2((y2-y1),(x2-x1));
805 AliITStrackSA* trac = new AliITStrackSA(layer,ladder,detector,yclu1,zclu1,phi2,tgl2,cv,1);
809 trac->AddClusterV2(5,(clind[5][l5] & 0x0fffffff)>>0);
810 trac->AddClusterMark(5,clmark[5][l5]);
813 trac->AddClusterV2(4,(clind[4][l4] & 0x0fffffff)>>0);
814 trac->AddClusterMark(4,clmark[4][l4]);
817 trac->AddClusterV2(3,(clind[3][l3] & 0x0fffffff)>>0);
818 trac->AddClusterMark(3,clmark[3][l3]);
821 trac->AddClusterV2(2,(clind[2][l2] & 0x0fffffff)>>0);
822 trac->AddClusterMark(2,clmark[2][l2]);
825 trac->AddClusterV2(1,(clind[1][l1] & 0x0fffffff)>>0);
826 trac->AddClusterMark(1,clmark[1][l1]);
829 trac->AddClusterV2(0,(clind[0][l0] & 0x0fffffff)>>0);
830 trac->AddClusterMark(0,clmark[0][l0]);
833 //fit with Kalman filter using AliITStrackerMI::RefitAt()
834 AliITStrackMI* ot = new AliITStrackSA(*trac);
836 ot->ResetCovariance(10.);
839 if(RefitAt(AliITSRecoParam::GetrInsideITSscreen(),ot,trac)){ //fit from layer 1 to layer 6
840 AliITStrackMI *otrack2 = new AliITStrackMI(*ot);
841 otrack2->ResetCovariance(10.);
842 otrack2->ResetClusters();
843 //fit from layer 6 to layer 1
844 if(RefitAt(AliITSRecoParam::GetrInsideSPD1(),otrack2,ot)) {
845 fListOfTracks->AddLast(otrack2);
846 new (tri[nlist]) AliITStrackSA(*trac);
867 Int_t dim=fListOfTracks->GetEntries();
869 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
883 Int_t lowchi2 = FindTrackLowChiSquare(fListOfTracks,dim);
884 AliITStrackV2* otrack =(AliITStrackV2*)fListOfTracks->At(lowchi2);
885 AliITStrackSA* trsa = (AliITStrackSA*)listSA->At(lowchi2);
888 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
903 Int_t * indexc = new Int_t[AliITSgeomTGeo::GetNLayers()];
904 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) indexc[i]=0;
905 for(Int_t nind=0;nind<otrack->GetNumberOfClusters();nind++){
906 indexc[nind] = otrack->GetClusterIndex(nind);
909 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
910 if(i<otrack->GetNumberOfClusters()) {
911 AliITSRecPoint* cl = (AliITSRecPoint*)GetCluster(indexc[i]);
912 labl[i][0]=cl->GetLabel(0);
913 labl[i][1]=cl->GetLabel(1);
914 labl[i][2]=cl->GetLabel(2);
923 CookLabel(otrack,0.); //MI change - to see fake ratio
925 Int_t label=FindLabel(labl[0][0],labl[1][0],labl[2][0],labl[3][0],labl[4][0],labl[5][0]);
927 for(Int_t i=0;i<otrack->GetNumberOfClusters();i++)
928 if(labl[i][0]==label || labl[i][1]==label || labl[i][2]==label) lflag++;
930 if(lflag<otrack->GetNumberOfClusters()) label = -label;
931 otrack->SetLabel(label);
933 //remove clusters of found track
934 for(Int_t nlay=0;nlay<AliITSgeomTGeo::GetNLayers();nlay++){
935 for(Int_t cln=0;cln<trsa->GetNumberOfMarked(nlay);cln++){
936 Int_t index = trsa->GetClusterMark(nlay,cln);
937 fCluLayer[nlay]->RemoveAt(index);
938 RemoveClusterCoord(nlay,index);
939 fCluLayer[nlay]->Compress();
945 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
960 //_______________________________________________________
961 Int_t AliITStrackerSA::SearchClusters(Int_t layer,Double_t phiwindow,Double_t lambdawindow, AliITStrackSA* trs,Double_t /*zvertex*/,Int_t pflag){
962 //function used to to find the clusters associated to the track
964 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(layer)) return 0;
967 AliITSlayer &lay = fgLayers[layer];
968 Double_t r=lay.GetR();
970 Float_t cx1,cx2,cy1,cy2;
971 FindEquation(fPoint1[0],fPoint1[1],fPoint2[0],fPoint2[1],fPoint3[0],fPoint3[1],fCoef1,fCoef2,fCoef3);
972 if (FindIntersection(fCoef1,fCoef2,fCoef3,-r*r,cx1,cy1,cx2,cy2)==0)
974 Double_t fi1=TMath::ATan2(cy1-fPoint1[1],cx1-fPoint1[0]);
975 Double_t fi2=TMath::ATan2(cy2-fPoint1[1],cx2-fPoint1[0]);
976 fPhiEstimate=ChoosePoint(fi1,fi2,fPhic);
980 Int_t ncl = fCluLayer[layer]->GetEntries();
981 for (Int_t index=0; index<ncl; index++) {
982 AliITSRecPoint *c = (AliITSRecPoint*)fCluLayer[layer]->At(index);
984 if (c->GetQ()<=0) continue;
986 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(layer,index);
987 Double_t phi = arr->GetPhi();
988 if (TMath::Abs(phi-fPhiEstimate)>phiwindow) continue;
990 Double_t lambda = arr->GetLambda();
991 if (TMath::Abs(lambda-fLambdac)>lambdawindow) continue;
993 if(trs->GetNumberOfClustersSA()==trs->GetMaxNumberOfClusters()) return 0;
994 if(trs->GetNumberOfMarked(layer)==trs->GetMaxNMarkedPerLayer()) return 0;
995 Int_t orind = arr->GetOrInd();
996 trs->AddClusterSA(layer,orind);
997 trs->AddClusterMark(layer,index);
1003 fPointc[0]=arr->GetX();
1004 fPointc[1]=arr->GetY();
1010 //________________________________________________________________
1011 void AliITStrackerSA::UpdatePoints(){
1012 //update of points for the estimation of the curvature
1014 fPoint2[0]=fPoint3[0];
1015 fPoint2[1]=fPoint3[1];
1016 fPoint3[0]=fPointc[0];
1017 fPoint3[1]=fPointc[1];
1022 //___________________________________________________________________
1023 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){
1025 //given (x,y) of three recpoints (in global coordinates)
1026 //returns the parameters a,b,c of circonference x*x + y*y +a*x + b*y +c
1028 Float_t den = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1);
1029 if(den==0) return 0;
1030 a = ((y3-y1)*(x2*x2+y2*y2-x1*x1-y1*y1)-(y2-y1)*(x3*x3+y3*y3-x1*x1-y1*y1))/den;
1031 b = -(x2*x2-x1*x1+y2*y2-y1*y1+a*(x2-x1))/(y2-y1);
1032 c = -x1*x1-y1*y1-a*x1-b*y1;
1035 //__________________________________________________________________________
1036 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){
1038 //Finds the intersection between the circonference of the track and the circonference centered in (0,0) represented by one layer
1039 //c2 is -rlayer*rlayer
1043 Double_t aA = (b1*b1)/(a1*a1)+1;
1044 Double_t bB = (-2*m*b1/(a1*a1));
1045 Double_t cC = c2+(m*m)/(a1*a1);
1046 Double_t dD = bB*bB-4*aA*cC;
1049 y1 = (-bB+TMath::Sqrt(dD))/(2*aA);
1050 y2 = (-bB-TMath::Sqrt(dD))/(2*aA);
1051 x1 = (c2-c1-b1*y1)/a1;
1052 x2 = (c2-c1-b1*y2)/a1;
1056 //____________________________________________________________________
1057 Double_t AliITStrackerSA::Curvature(Double_t x1,Double_t y1,Double_t
1058 x2,Double_t y2,Double_t x3,Double_t y3){
1060 //calculates the curvature of track
1061 Double_t den = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1);
1062 if(den==0) return 0;
1063 Double_t a = ((y3-y1)*(x2*x2+y2*y2-x1*x1-y1*y1)-(y2-y1)*(x3*x3+y3*y3-x1*x1-y1*y1))/den;
1064 Double_t b = -(x2*x2-x1*x1+y2*y2-y1*y1+a*(x2-x1))/(y2-y1);
1065 Double_t c = -x1*x1-y1*y1-a*x1-b*y1;
1068 if((a*a+b*b-4*c)<0) return 0;
1069 Double_t rad = TMath::Sqrt(a*a+b*b-4*c)/2.;
1070 if(rad==0) return 0;
1072 if((x1>0 && y1>0 && x1<xc)) rad*=-1;
1073 if((x1<0 && y1>0 && x1<xc)) rad*=-1;
1074 // if((x1<0 && y1<0 && x1<xc)) rad*=-1;
1075 // if((x1>0 && y1<0 && x1<xc)) rad*=-1;
1082 //____________________________________________________________________
1083 Double_t AliITStrackerSA::ChoosePoint(Double_t p1, Double_t p2, Double_t pp){
1085 //Returns the point closest to pp
1087 Double_t diff1 = p1-pp;
1088 Double_t diff2 = p2-pp;
1090 if(TMath::Abs(diff1)<TMath::Abs(diff2)) fPhiEstimate=p1;
1091 else fPhiEstimate=p2;
1092 return fPhiEstimate;
1097 //_________________________________________________________________
1098 Int_t AliITStrackerSA::FindTrackLowChiSquare(TObjArray* tracklist, Int_t dim) const {
1099 // returns track with lowers chi square
1101 //AliITStrackV2* trk = (AliITStrackV2*)tracklist->At(0);
1105 if(dim==0) return 0;
1106 Double_t * chi2 = new Double_t[dim];
1107 Int_t * index = new Int_t[dim];
1108 for(Int_t i=0;i<dim;i++){
1109 AliITStrackV2* trk = (AliITStrackV2*)tracklist->At(i);
1110 chi2[i]=trk->GetChi2();
1114 Int_t w=0;Double_t value;
1117 for(Int_t j=w+1;j<dim;j++){
1118 if(chi2[w]<chi2[j]){
1129 Int_t tmp = index[dim-1];
1135 //__________________________________________________________
1136 Int_t AliITStrackerSA::FindLabel(Int_t l0, Int_t l1, Int_t l2, Int_t l3, Int_t l4, Int_t l5){
1138 //function used to determine the track label
1140 Int_t lb[6] = {l0,l1,l2,l3,l4,l5};
1141 Int_t aa[6]={1,1,1,1,1,1};
1144 Int_t k=0;Int_t w=0;Int_t num=6;
1145 for(Int_t i=5;i>=0;i--) if(lb[i]==-1) num=i;
1149 for(Int_t i=k+1;i<num;i++){
1151 if(lb[k]==lb[i] && aa[k]!=0){
1162 for(Int_t j=0;j<6;j++){
1175 if(num<1) return -1;
1179 //_____________________________________________________________________________
1180 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,
1181 Int_t gl12, Int_t gl13, Int_t gl14,Int_t gl15, Int_t gl16, Int_t gl17, Int_t gl18, Int_t minNPoints){
1184 //function used to assign label to the found track. If track is fake, the label is negative
1186 Int_t lb0[6] = {gl1,gl2,gl3,gl4,gl5,gl6};
1187 Int_t lb1[6] = {gl7,gl8,gl9,gl10,gl11,gl12};
1188 Int_t lb2[6] = {gl13,gl14,gl15,gl16,gl17,gl18};
1189 Int_t ll=FindLabel(lb0[0],lb0[1],lb0[2],lb0[3],lb0[4],lb0[5]);
1190 Int_t lflag=0;Int_t num=6;
1191 if(lb0[5]==-1 && lb1[5]==-1 && lb2[5]==-1) num=5;
1193 for(Int_t i=0;i<num;i++){
1194 if(lb0[i]==ll || lb1[i]==ll || lb2[i]==ll) lflag+=1;
1197 if(lflag>=minNPoints) return ll;
1203 //_____________________________________________________________________________
1204 void AliITStrackerSA::SetWindowSizes(Int_t n, Double_t *phi, Double_t *lam){
1205 // Set sizes of the phi and lambda windows used for track finding
1207 if(phi){ // user defined values
1208 fPhiWin = new Double_t[fNloop];
1209 fLambdaWin = new Double_t[fNloop];
1210 for(Int_t k=0;k<fNloop;k++){
1212 fLambdaWin[k]=lam[k];
1215 else { // default values
1217 Double_t phid[33] = {0.002,0.003,0.004,0.0045,0.0047,
1218 0.005,0.0053,0.0055,
1219 0.006,0.0063,0.0065,0.007,0.0073,0.0075,0.0077,
1220 0.008,0.0083,0.0085,0.0087,0.009,0.0095,0.0097,
1221 0.01,0.0105,0.011,0.0115,0.012,0.0125,0.013,0.0135,0.0140,0.0145};
1222 Double_t lambdad[33] = {0.003,0.004,0.005,0.005,0.005,
1224 0.006,0.006,0.006,0.007,0.007,0.007,0.007,
1225 0.007,0.007,0.007,0.007,0.007,0.007,0.007,
1226 0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008};
1233 fPhiWin = new Double_t[fNloop];
1234 fLambdaWin = new Double_t[fNloop];
1236 Double_t factor=AliITSReconstructor::GetRecoParam()->GetFactorSAWindowSizes(); // possibility to enlarge windows for cosmics reco with large misalignments (A.Dainese)
1238 for(Int_t k=0;k<fNloop;k++){
1239 fPhiWin[k]=phid[k]*factor;
1240 fLambdaWin[k]=lambdad[k]*factor;
1246 //_______________________________________________________________________
1247 void AliITStrackerSA::GetCoorAngles(AliITSRecPoint* cl,Double_t &phi,Double_t &lambda, Float_t &x, Float_t &y,Float_t &z,Double_t* vertex){
1248 //Returns values of phi (azimuthal) and lambda angles for a given cluster
1250 Double_t rot[9]; fGeom->GetRotMatrix(module,rot);
1251 Int_t lay,lad,det; fGeom->GetModuleId(module,lay,lad,det);
1252 Float_t tx,ty,tz; fGeom->GetTrans(lay,lad,det,tx,ty,tz);
1254 Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
1255 Double_t phi1=TMath::Pi()/2+alpha;
1256 if (lay==1) phi1+=TMath::Pi();
1258 Float_t cp=TMath::Cos(phi1), sp=TMath::Sin(phi1);
1259 Float_t r=tx*cp+ty*sp;
1261 xyz= r*cp - cl->GetY()*sp;
1262 y= r*sp + cl->GetY()*cp;
1266 cl->GetGlobalXYZ(xyz);
1271 phi=TMath::ATan2(y-vertex[1],x-vertex[0]);
1272 lambda=TMath::ATan2(z-vertex[2],TMath::Sqrt((x-vertex[0])*(x-vertex[0])+(y-vertex[1])*(y-vertex[1])));
1275 //________________________________________________________________________
1276 void AliITStrackerSA::GetCoorErrors(AliITSRecPoint* cl,Float_t &sx,Float_t &sy, Float_t &sz){
1278 //returns sigmax, y, z of cluster in global coordinates
1280 Double_t rot[9]; fGeom->GetRotMatrix(module,rot);
1282 AliITSgeomTGeo::GetModuleId(module,lay,lad,det);
1284 Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
1285 Double_t phi=TMath::Pi()/2+alpha;
1286 if (lay==1) phi+=TMath::Pi();
1288 Float_t cp=TMath::Cos(phi), sp=TMath::Sin(phi);
1291 cl->GetGlobalCov(covm);
1292 sx=TMath::Sqrt(covm[0]);
1293 sy=TMath::Sqrt(covm[3]);
1294 sz=TMath::Sqrt(covm[5]);
1296 sx = TMath::Sqrt(sp*sp*cl->GetSigmaY2());
1297 sy = TMath::Sqrt(cp*cp*cl->GetSigmaY2());
1298 sz = TMath::Sqrt(cl->GetSigmaZ2());