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 for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
349 AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
350 if(cls->TestBit(kSAflag)==kTRUE) continue; //clusters used by TPC prol.
351 if(cls->GetQ()==0) continue; //fake clusters dead zones
356 fCluLayer[i] = new TClonesArray("AliITSRecPoint",nclusters[i]);
358 fCluCoord[i] = new TClonesArray("AliITSclusterTable",nclusters[i]);
361 for(Int_t ilay=0;ilay<AliITSgeomTGeo::GetNLayers();ilay++){
362 TClonesArray &clulay = *fCluLayer[ilay];
363 TClonesArray &clucoo = *fCluCoord[ilay];
364 AliITSlayer &layer=fgLayers[ilay];
365 for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
366 AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
367 if(cls->TestBit(kSAflag)==kTRUE) continue;
368 if(cls->GetQ()==0) continue;
369 Double_t phi=0;Double_t lambda=0;
370 Float_t x=0;Float_t y=0;Float_t z=0;
371 Float_t sx=0;Float_t sy=0;Float_t sz=0;
372 GetCoorAngles(cls,phi,lambda,x,y,z,primaryVertex);
373 GetCoorErrors(cls,sx,sy,sz);
374 new (clulay[dmar[ilay]]) AliITSRecPoint(*cls);
375 new (clucoo[dmar[ilay]]) AliITSclusterTable(x,y,z,sx,sy,sz,phi,lambda,cli);
380 Int_t minNPoints = (fSixPoints ? AliITSgeomTGeo::GetNLayers() : AliITSgeomTGeo::GetNLayers()-1);
381 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
382 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(i)) {
389 //loop on the different windows
390 Int_t * nn = new Int_t[AliITSgeomTGeo::GetNLayers()];//counter for clusters on each layer
391 for(Int_t nloop=0;nloop<fNloop;nloop++){
392 for(Int_t ncl=0;ncl<fCluLayer[0]->GetEntries();ncl++){ //loop starting from layer 0
397 AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[0]->At(ncl);
400 if (cl->GetQ()<=0) continue;
402 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(0,ncl);
403 fPhic = arr->GetPhi();
404 fLambdac = arr->GetLambda();
405 if (TMath::Abs(fLambdac)>0.26*TMath::Pi()) continue;
406 fPhiEstimate = fPhic;
407 AliITStrackSA* trs = new AliITStrackSA();
408 fPoint1[0]=primaryVertex[0];
409 fPoint1[1]=primaryVertex[1];
412 fPoint2[0]=arr->GetX();
413 fPoint2[1]=arr->GetY();
414 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){ nn[i]=0;}
415 nn[0] = SearchClusters(0,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
416 nn[1] = SearchClusters(1,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
419 fPoint3[0] = fPointc[0];
420 fPoint3[1] = fPointc[1];
422 nn[2] = SearchClusters(2,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
423 if(nn[1]==0 && nn[2]==0) pflag=0;
424 if(nn[2]!=0 && nn[1]!=0){ pflag=1; UpdatePoints();}
425 if(nn[2]!=0 && nn[1]==0){
427 fPoint3[0]=fPointc[0];
428 fPoint3[1]=fPointc[1];
431 nn[3] = SearchClusters(3,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
433 if(nn[3]!=0) UpdatePoints();
434 nn[4] = SearchClusters(4,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
436 if(nn[4]!=0) UpdatePoints();
437 nn[5] = SearchClusters(5,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
441 //check of the candidate track
442 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers();nnp++) {
443 if(nn[nnp]!=0) layOK+=1;
446 if(layOK>=minNPoints){
447 AliITStrackV2* tr2 = 0;
448 tr2 = FitTrack(trs,primaryVertex);
451 AliESDtrack outtrack;
452 outtrack.UpdateTrackParams(tr2,AliESDtrack::kITSin);
453 event->AddTrack(&outtrack);
457 }//end loop on clusters of layer1
466 //if 5/6 points are required, second loop starting
467 //from second layer (SPD2), to find tracks with point of
470 //printf("looking from SPD2\n");
471 // counter for clusters on each layer
472 Int_t * nn = new Int_t[AliITSgeomTGeo::GetNLayers()-1];
473 for(Int_t nloop=0;nloop<fNloop;nloop++){
474 Int_t ncl2=fCluLayer[1]->GetEntries();
475 while(ncl2--){ //loop starting from layer 2
478 AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[1]->At(ncl2);
481 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(1,ncl2);
482 fPhic = arr->GetPhi();
483 fLambdac = arr->GetLambda();
484 fPhiEstimate = fPhic;
486 AliITStrackSA* trs = new AliITStrackSA();
487 fPoint1[0]=primaryVertex[0];
488 fPoint1[1]=primaryVertex[1];
490 fPoint2[0]=arr->GetX();
491 fPoint2[1]=arr->GetY();
492 for(Int_t kk=0;kk<AliITSgeomTGeo::GetNLayers()-1;kk++)nn[kk] = 0;
493 nn[0] = SearchClusters(1,fPhiWin[nloop],fLambdaWin[nloop],
494 trs,primaryVertex[2],pflag);
495 nn[1] = SearchClusters(2,fPhiWin[nloop],fLambdaWin[nloop],
496 trs,primaryVertex[2],pflag);
499 fPoint3[0]=fPointc[0];
500 fPoint3[1]=fPointc[1];
502 nn[2]= SearchClusters(3,fPhiWin[nloop],fLambdaWin[nloop],
503 trs,primaryVertex[2],pflag);
508 nn[3]= SearchClusters(4,fPhiWin[nloop],fLambdaWin[nloop],
509 trs,primaryVertex[2],pflag);
514 nn[4]=SearchClusters(5,fPhiWin[nloop],fLambdaWin[nloop],
515 trs,primaryVertex[2],pflag);
518 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-1;nnp++){
519 if(nn[nnp]!=0) fl+=1;
521 if(fl>=minNPoints){ // 5/6
522 AliITStrackV2* tr2 = 0;
523 tr2 = FitTrack(trs,primaryVertex);
526 AliESDtrack outtrack;
527 outtrack.UpdateTrackParams(tr2,AliESDtrack::kITSin);
528 event->AddTrack(&outtrack);
534 }//end loop on clusters of layer2
540 // search for tracks starting from SPD2, SDD1, SDD2, SSD2
541 // for cosmics (A. Dainese 31.07.07)
542 if(fOuterStartLayer>0) {
543 for(Int_t innLay=1; innLay<=fOuterStartLayer; innLay++) {
544 //printf("Searching from layer %d outward\n",innLay);
545 minNPoints=AliITSgeomTGeo::GetNLayers()-innLay;
546 for(Int_t i=innLay;i<AliITSgeomTGeo::GetNLayers();i++)
547 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(i))
549 // counter for clusters on each layer
550 Int_t * nn = new Int_t[AliITSgeomTGeo::GetNLayers()-innLay];
551 for(Int_t nloop=0;nloop<fNloop;nloop++){
552 Int_t nclInnLay=fCluLayer[innLay]->GetEntries();
553 while(nclInnLay--){ //loop starting from layer innLay
556 AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[innLay]->At(nclInnLay);
559 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(innLay,nclInnLay);
560 fPhic = arr->GetPhi();
561 fLambdac = arr->GetLambda();
562 fPhiEstimate = fPhic;
564 AliITStrackSA* trs = new AliITStrackSA();
565 fPoint1[0]=primaryVertex[0];
566 fPoint1[1]=primaryVertex[1];
567 fPoint2[0]=arr->GetX();
568 fPoint2[1]=arr->GetY();
571 for(kk=0;kk<AliITSgeomTGeo::GetNLayers()-innLay;kk++) nn[kk] = 0;
574 nn[kk] = SearchClusters(innLay,fPhiWin[nloop],fLambdaWin[nloop],
575 trs,primaryVertex[2],pflag);
576 for(Int_t nextLay=innLay+1; nextLay<AliITSgeomTGeo::GetNLayers(); nextLay++) {
578 nn[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
579 trs,primaryVertex[2],pflag);
583 fPoint3[0]=fPointc[0];
584 fPoint3[1]=fPointc[1];
592 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-innLay;nnp++){
593 if(nn[nnp]!=0) fl+=1;
596 AliITStrackV2* tr2 = 0;
597 tr2 = FitTrack(trs,primaryVertex);
601 AliESDtrack outtrack;
602 outtrack.UpdateTrackParams(tr2,AliESDtrack::kITSin);
603 event->AddTrack(&outtrack);
609 }//end loop on clusters of innLay
610 } //end loop on window sizes
613 } //end loop on innLay
614 } //end if(fOuterStartLayer>0)
618 Info("FindTracks","Number of found tracks: %d",event->GetNumberOfTracks());
623 //________________________________________________________________________
625 AliITStrackV2* AliITStrackerSA::FitTrack(AliITStrackSA* tr,Double_t *primaryVertex) {
626 //fit of the found track (most general case, also <6 points, layers missing)
627 // A.Dainese 16.11.07
630 Int_t * firstmod = new Int_t[AliITSgeomTGeo::GetNLayers()];
631 TObjArray** listlayer = new TObjArray*[AliITSgeomTGeo::GetNLayers()];
632 Int_t ** clind=new Int_t*[AliITSgeomTGeo::GetNLayers()];
633 Int_t ** clmark=new Int_t*[AliITSgeomTGeo::GetNLayers()];
634 Int_t * nnn = new Int_t[AliITSgeomTGeo::GetNLayers()];
635 Int_t * kkk = new Int_t[AliITSgeomTGeo::GetNLayers()];
637 const Int_t maxclu=AliITStrackSA::GetMaxNumberOfClusters();
639 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
640 firstmod[i]=AliITSgeomTGeo::GetModuleIndex(i+1,1,1);
641 listlayer[i] = new TObjArray(0,0);
644 clind[i]=new Int_t[maxclu];
645 clmark[i]=new Int_t[maxclu];
646 for(Int_t j=0;j<maxclu; j++){
653 Int_t nclusters = tr->GetNumberOfClustersSA();
654 for(Int_t ncl=0;ncl<nclusters;ncl++){
655 Int_t index = tr->GetClusterIndexSA(ncl);
656 AliITSRecPoint* cl = (AliITSRecPoint*)GetCluster(index);
657 if(cl->TestBit(kSAflag)==kTRUE) cl->ResetBit(kSAflag);
658 Int_t lay = (index & 0xf0000000) >> 28;
659 listlayer[lay]->AddLast(cl);
661 clind[lay][ind]=index;
665 for(Int_t nlay=0;nlay<AliITSgeomTGeo::GetNLayers();nlay++){
666 for(Int_t ncl=0;ncl<tr->GetNumberOfMarked(nlay);ncl++){
667 Int_t mark = tr->GetClusterMark(nlay,ncl);
669 clmark[nlay][ind]=mark;
675 Int_t firstLay=-1,secondLay=-1;
676 Int_t * end = new Int_t[AliITSgeomTGeo::GetNLayers()];
677 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
678 if(listlayer[i]->GetEntries()==0) {
681 end[i]=listlayer[i]->GetEntries();
684 } else if(secondLay==-1) {
690 TClonesArray* listSA = new TClonesArray("AliITStrackSA");
691 TClonesArray &tri = *listSA;
694 for(Int_t l0=0;l0<end[0];l0++){ //loop on layer 1
695 AliITSRecPoint* cl0 = (AliITSRecPoint*)listlayer[0]->At(l0);
696 for(Int_t l1=0;l1<end[1];l1++){ //loop on layer 2
697 AliITSRecPoint* cl1 = (AliITSRecPoint*)listlayer[1]->At(l1);
698 for(Int_t l2=0;l2<end[2];l2++){ //loop on layer 3
699 AliITSRecPoint* cl2 = (AliITSRecPoint*)listlayer[2]->At(l2);
700 for(Int_t l3=0;l3<end[3];l3++){ //loop on layer 4
701 AliITSRecPoint* cl3 = (AliITSRecPoint*)listlayer[3]->At(l3);
702 for(Int_t l4=0;l4<end[4];l4++){ //loop on layer 5
703 AliITSRecPoint* cl4 = (AliITSRecPoint*)listlayer[4]->At(l4);
704 for(Int_t l5=0;l5<end[5];l5++){ //loop on layer 6
705 AliITSRecPoint* cl5 = (AliITSRecPoint*)listlayer[5]->At(l5);
708 Double_t x1,y1,z1,sx1,sy1,sz1;
709 Double_t x2,y2,z2,sx2,sy2,sz2;
710 AliITSRecPoint* p1=0;
711 AliITSRecPoint* p2=0;
712 Int_t index1=0,index2=0;
718 index1=clind[0][l0];mrk1=clmark[0][l0];
722 index1=clind[1][l1];mrk1=clmark[1][l1];
726 index1=clind[2][l2];mrk1=clmark[2][l2];
730 index1=clind[3][l3];mrk1=clmark[3][l3];
734 index1=clind[4][l4];mrk1=clmark[4][l4];
741 index2=clind[1][l1];mrk2=clmark[1][l1];
745 index2=clind[2][l2];mrk2=clmark[2][l2];
749 index2=clind[3][l3];mrk2=clmark[3][l3];
753 index2=clind[4][l4];mrk2=clmark[4][l4];
757 index2=clind[5][l5];mrk2=clmark[5][l5];
761 Int_t module1 = p1->GetDetectorIndex()+firstmod[firstLay];
765 AliITSclusterTable* arr1 = (AliITSclusterTable*)GetClusterCoord(firstLay,cln1);
766 AliITSclusterTable* arr2 = (AliITSclusterTable*)GetClusterCoord(secondLay,cln2);
780 Int_t layer,ladder,detector;
781 AliITSgeomTGeo::GetModuleId(module1,layer,ladder,detector);
782 Float_t yclu1 = p1->GetY();
783 Float_t zclu1 = p1->GetZ();
784 Double_t cv=Curvature(primaryVertex[0],primaryVertex[1],x1,y1,x2,y2);
785 Double_t tgl2 = (z2-z1)/TMath::Sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
786 Double_t phi2 = TMath::ATan2((y2-y1),(x2-x1));
787 AliITStrackSA* trac = new AliITStrackSA(layer,ladder,detector,yclu1,zclu1,phi2,tgl2,cv,1);
790 trac->AddClusterV2(5,(clind[5][l5] & 0x0fffffff)>>0);
791 trac->AddClusterMark(5,clmark[5][l5]);
794 trac->AddClusterV2(4,(clind[4][l4] & 0x0fffffff)>>0);
795 trac->AddClusterMark(4,clmark[4][l4]);
798 trac->AddClusterV2(3,(clind[3][l3] & 0x0fffffff)>>0);
799 trac->AddClusterMark(3,clmark[3][l3]);
802 trac->AddClusterV2(2,(clind[2][l2] & 0x0fffffff)>>0);
803 trac->AddClusterMark(2,clmark[2][l2]);
806 trac->AddClusterV2(1,(clind[1][l1] & 0x0fffffff)>>0);
807 trac->AddClusterMark(1,clmark[1][l1]);
810 trac->AddClusterV2(0,(clind[0][l0] & 0x0fffffff)>>0);
811 trac->AddClusterMark(0,clmark[0][l0]);
815 //fit with Kalman filter using AliITStrackerMI::RefitAt()
816 AliITStrackMI* ot = new AliITStrackSA(*trac);
818 ot->ResetCovariance(10.);
821 if(RefitAt(AliITSRecoParam::GetrInsideITSscreen(),ot,trac)){ //fit from layer 1 to layer 6
822 AliITStrackMI *otrack2 = new AliITStrackMI(*ot);
823 otrack2->ResetCovariance(10.);
824 otrack2->ResetClusters();
825 //fit from layer 6 to layer 1
826 if(RefitAt(AliITSRecoParam::GetrInsideSPD1(),otrack2,ot)) {
827 fListOfTracks->AddLast(otrack2);
828 new (tri[nlist]) AliITStrackSA(*trac);
849 Int_t dim=fListOfTracks->GetEntries();
851 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
865 Int_t lowchi2 = FindTrackLowChiSquare(fListOfTracks,dim);
866 AliITStrackV2* otrack =(AliITStrackV2*)fListOfTracks->At(lowchi2);
867 AliITStrackSA* trsa = (AliITStrackSA*)listSA->At(lowchi2);
870 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
885 Int_t * indexc = new Int_t[AliITSgeomTGeo::GetNLayers()];
886 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) indexc[i]=0;
887 for(Int_t nind=0;nind<otrack->GetNumberOfClusters();nind++){
888 indexc[nind] = otrack->GetClusterIndex(nind);
891 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
892 if(i<otrack->GetNumberOfClusters()) {
893 AliITSRecPoint* cl = (AliITSRecPoint*)GetCluster(indexc[i]);
894 labl[i][0]=cl->GetLabel(0);
895 labl[i][1]=cl->GetLabel(1);
896 labl[i][2]=cl->GetLabel(2);
905 CookLabel(otrack,0.); //MI change - to see fake ratio
907 Int_t label=FindLabel(labl[0][0],labl[1][0],labl[2][0],labl[3][0],labl[4][0],labl[5][0]);
909 for(Int_t i=0;i<otrack->GetNumberOfClusters();i++)
910 if(labl[i][0]==label || labl[i][1]==label || labl[i][2]==label) lflag++;
912 if(lflag<otrack->GetNumberOfClusters()) label = -label;
913 otrack->SetLabel(label);
915 //remove clusters of found track
916 for(Int_t nlay=0;nlay<AliITSgeomTGeo::GetNLayers();nlay++){
917 for(Int_t cln=0;cln<trsa->GetNumberOfMarked(nlay);cln++){
918 Int_t index = trsa->GetClusterMark(nlay,cln);
919 fCluLayer[nlay]->RemoveAt(index);
920 RemoveClusterCoord(nlay,index);
921 fCluLayer[nlay]->Compress();
927 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
942 //_______________________________________________________
943 Int_t AliITStrackerSA::SearchClusters(Int_t layer,Double_t phiwindow,Double_t lambdawindow, AliITStrackSA* trs,Double_t /*zvertex*/,Int_t pflag){
944 //function used to to find the clusters associated to the track
946 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(layer)) return 0;
949 AliITSlayer &lay = fgLayers[layer];
950 Double_t r=lay.GetR();
952 Float_t cx1,cx2,cy1,cy2;
953 FindEquation(fPoint1[0],fPoint1[1],fPoint2[0],fPoint2[1],fPoint3[0],fPoint3[1],fCoef1,fCoef2,fCoef3);
954 if (FindIntersection(fCoef1,fCoef2,fCoef3,-r*r,cx1,cy1,cx2,cy2)==0)
956 Double_t fi1=TMath::ATan2(cy1-fPoint1[1],cx1-fPoint1[0]);
957 Double_t fi2=TMath::ATan2(cy2-fPoint1[1],cx2-fPoint1[0]);
958 fPhiEstimate=ChoosePoint(fi1,fi2,fPhic);
962 Int_t ncl = fCluLayer[layer]->GetEntries();
963 for (Int_t index=0; index<ncl; index++) {
964 AliITSRecPoint *c = (AliITSRecPoint*)fCluLayer[layer]->At(index);
966 if (c->GetQ()<=0) continue;
968 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(layer,index);
969 Double_t phi = arr->GetPhi();
970 if (TMath::Abs(phi-fPhiEstimate)>phiwindow) continue;
972 Double_t lambda = arr->GetLambda();
973 if (TMath::Abs(lambda-fLambdac)>lambdawindow) continue;
975 if(trs->GetNumberOfClustersSA()==trs->GetMaxNumberOfClusters()) return 0;
976 if(trs->GetNumberOfMarked(layer)==trs->GetMaxNMarkedPerLayer()) return 0;
977 Int_t orind = arr->GetOrInd();
978 trs->AddClusterSA(layer,orind);
979 trs->AddClusterMark(layer,index);
985 fPointc[0]=arr->GetX();
986 fPointc[1]=arr->GetY();
992 //________________________________________________________________
993 void AliITStrackerSA::UpdatePoints(){
994 //update of points for the estimation of the curvature
996 fPoint2[0]=fPoint3[0];
997 fPoint2[1]=fPoint3[1];
998 fPoint3[0]=fPointc[0];
999 fPoint3[1]=fPointc[1];
1004 //___________________________________________________________________
1005 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){
1007 //given (x,y) of three recpoints (in global coordinates)
1008 //returns the parameters a,b,c of circonference x*x + y*y +a*x + b*y +c
1010 Float_t den = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1);
1011 if(den==0) return 0;
1012 a = ((y3-y1)*(x2*x2+y2*y2-x1*x1-y1*y1)-(y2-y1)*(x3*x3+y3*y3-x1*x1-y1*y1))/den;
1013 b = -(x2*x2-x1*x1+y2*y2-y1*y1+a*(x2-x1))/(y2-y1);
1014 c = -x1*x1-y1*y1-a*x1-b*y1;
1017 //__________________________________________________________________________
1018 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){
1020 //Finds the intersection between the circonference of the track and the circonference centered in (0,0) represented by one layer
1021 //c2 is -rlayer*rlayer
1025 Double_t aA = (b1*b1)/(a1*a1)+1;
1026 Double_t bB = (-2*m*b1/(a1*a1));
1027 Double_t cC = c2+(m*m)/(a1*a1);
1028 Double_t dD = bB*bB-4*aA*cC;
1031 y1 = (-bB+TMath::Sqrt(dD))/(2*aA);
1032 y2 = (-bB-TMath::Sqrt(dD))/(2*aA);
1033 x1 = (c2-c1-b1*y1)/a1;
1034 x2 = (c2-c1-b1*y2)/a1;
1038 //____________________________________________________________________
1039 Double_t AliITStrackerSA::Curvature(Double_t x1,Double_t y1,Double_t
1040 x2,Double_t y2,Double_t x3,Double_t y3){
1042 //calculates the curvature of track
1043 Double_t den = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1);
1044 if(den==0) return 0;
1045 Double_t a = ((y3-y1)*(x2*x2+y2*y2-x1*x1-y1*y1)-(y2-y1)*(x3*x3+y3*y3-x1*x1-y1*y1))/den;
1046 Double_t b = -(x2*x2-x1*x1+y2*y2-y1*y1+a*(x2-x1))/(y2-y1);
1047 Double_t c = -x1*x1-y1*y1-a*x1-b*y1;
1050 if((a*a+b*b-4*c)<0) return 0;
1051 Double_t rad = TMath::Sqrt(a*a+b*b-4*c)/2.;
1052 if(rad==0) return 0;
1054 if((x1>0 && y1>0 && x1<xc)) rad*=-1;
1055 if((x1<0 && y1>0 && x1<xc)) rad*=-1;
1056 // if((x1<0 && y1<0 && x1<xc)) rad*=-1;
1057 // if((x1>0 && y1<0 && x1<xc)) rad*=-1;
1064 //____________________________________________________________________
1065 Double_t AliITStrackerSA::ChoosePoint(Double_t p1, Double_t p2, Double_t pp){
1067 //Returns the point closest to pp
1069 Double_t diff1 = p1-pp;
1070 Double_t diff2 = p2-pp;
1072 if(TMath::Abs(diff1)<TMath::Abs(diff2)) fPhiEstimate=p1;
1073 else fPhiEstimate=p2;
1074 return fPhiEstimate;
1079 //_________________________________________________________________
1080 Int_t AliITStrackerSA::FindTrackLowChiSquare(TObjArray* tracklist, Int_t dim) const {
1081 // returns track with lowers chi square
1083 //AliITStrackV2* trk = (AliITStrackV2*)tracklist->At(0);
1087 if(dim==0) return 0;
1088 Double_t * chi2 = new Double_t[dim];
1089 Int_t * index = new Int_t[dim];
1090 for(Int_t i=0;i<dim;i++){
1091 AliITStrackV2* trk = (AliITStrackV2*)tracklist->At(i);
1092 chi2[i]=trk->GetChi2();
1096 Int_t w=0;Double_t value;
1099 for(Int_t j=w+1;j<dim;j++){
1100 if(chi2[w]<chi2[j]){
1111 Int_t tmp = index[dim-1];
1117 //__________________________________________________________
1118 Int_t AliITStrackerSA::FindLabel(Int_t l0, Int_t l1, Int_t l2, Int_t l3, Int_t l4, Int_t l5){
1120 //function used to determine the track label
1122 Int_t lb[6] = {l0,l1,l2,l3,l4,l5};
1123 Int_t aa[6]={1,1,1,1,1,1};
1126 Int_t k=0;Int_t w=0;Int_t num=6;
1127 for(Int_t i=5;i>=0;i--) if(lb[i]==-1) num=i;
1131 for(Int_t i=k+1;i<num;i++){
1133 if(lb[k]==lb[i] && aa[k]!=0){
1144 for(Int_t j=0;j<6;j++){
1157 if(num<1) return -1;
1161 //_____________________________________________________________________________
1162 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,
1163 Int_t gl12, Int_t gl13, Int_t gl14,Int_t gl15, Int_t gl16, Int_t gl17, Int_t gl18, Int_t minNPoints){
1166 //function used to assign label to the found track. If track is fake, the label is negative
1168 Int_t lb0[6] = {gl1,gl2,gl3,gl4,gl5,gl6};
1169 Int_t lb1[6] = {gl7,gl8,gl9,gl10,gl11,gl12};
1170 Int_t lb2[6] = {gl13,gl14,gl15,gl16,gl17,gl18};
1171 Int_t ll=FindLabel(lb0[0],lb0[1],lb0[2],lb0[3],lb0[4],lb0[5]);
1172 Int_t lflag=0;Int_t num=6;
1173 if(lb0[5]==-1 && lb1[5]==-1 && lb2[5]==-1) num=5;
1175 for(Int_t i=0;i<num;i++){
1176 if(lb0[i]==ll || lb1[i]==ll || lb2[i]==ll) lflag+=1;
1179 if(lflag>=minNPoints) return ll;
1185 //_____________________________________________________________________________
1186 void AliITStrackerSA::SetWindowSizes(Int_t n, Double_t *phi, Double_t *lam){
1187 // Set sizes of the phi and lambda windows used for track finding
1189 if(phi){ // user defined values
1190 fPhiWin = new Double_t[fNloop];
1191 fLambdaWin = new Double_t[fNloop];
1192 for(Int_t k=0;k<fNloop;k++){
1194 fLambdaWin[k]=lam[k];
1197 else { // default values
1199 Double_t phid[33] = {0.002,0.003,0.004,0.0045,0.0047,
1200 0.005,0.0053,0.0055,
1201 0.006,0.0063,0.0065,0.007,0.0073,0.0075,0.0077,
1202 0.008,0.0083,0.0085,0.0087,0.009,0.0095,0.0097,
1203 0.01,0.0105,0.011,0.0115,0.012,0.0125,0.013,0.0135,0.0140,0.0145};
1204 Double_t lambdad[33] = {0.003,0.004,0.005,0.005,0.005,
1206 0.006,0.006,0.006,0.007,0.007,0.007,0.007,
1207 0.007,0.007,0.007,0.007,0.007,0.007,0.007,
1208 0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008};
1215 fPhiWin = new Double_t[fNloop];
1216 fLambdaWin = new Double_t[fNloop];
1218 Double_t factor=AliITSReconstructor::GetRecoParam()->GetFactorSAWindowSizes(); // possibility to enlarge windows for cosmics reco with large misalignments (A.Dainese)
1220 for(Int_t k=0;k<fNloop;k++){
1221 fPhiWin[k]=phid[k]*factor;
1222 fLambdaWin[k]=lambdad[k]*factor;
1228 //_______________________________________________________________________
1229 void AliITStrackerSA::GetCoorAngles(AliITSRecPoint* cl,Double_t &phi,Double_t &lambda, Float_t &x, Float_t &y,Float_t &z,Double_t* vertex){
1230 //Returns values of phi (azimuthal) and lambda angles for a given cluster
1232 Double_t rot[9]; fGeom->GetRotMatrix(module,rot);
1233 Int_t lay,lad,det; fGeom->GetModuleId(module,lay,lad,det);
1234 Float_t tx,ty,tz; fGeom->GetTrans(lay,lad,det,tx,ty,tz);
1236 Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
1237 Double_t phi1=TMath::Pi()/2+alpha;
1238 if (lay==1) phi1+=TMath::Pi();
1240 Float_t cp=TMath::Cos(phi1), sp=TMath::Sin(phi1);
1241 Float_t r=tx*cp+ty*sp;
1243 xyz= r*cp - cl->GetY()*sp;
1244 y= r*sp + cl->GetY()*cp;
1248 cl->GetGlobalXYZ(xyz);
1253 phi=TMath::ATan2(y-vertex[1],x-vertex[0]);
1254 lambda=TMath::ATan2(z-vertex[2],TMath::Sqrt((x-vertex[0])*(x-vertex[0])+(y-vertex[1])*(y-vertex[1])));
1257 //________________________________________________________________________
1258 void AliITStrackerSA::GetCoorErrors(AliITSRecPoint* cl,Float_t &sx,Float_t &sy, Float_t &sz){
1260 //returns sigmax, y, z of cluster in global coordinates
1262 Double_t rot[9]; fGeom->GetRotMatrix(module,rot);
1264 AliITSgeomTGeo::GetModuleId(module,lay,lad,det);
1266 Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
1267 Double_t phi=TMath::Pi()/2+alpha;
1268 if (lay==1) phi+=TMath::Pi();
1270 Float_t cp=TMath::Cos(phi), sp=TMath::Sin(phi);
1273 cl->GetGlobalCov(covm);
1274 sx=TMath::Sqrt(covm[0]);
1275 sy=TMath::Sqrt(covm[3]);
1276 sz=TMath::Sqrt(covm[5]);
1278 sx = TMath::Sqrt(sp*sp*cl->GetSigmaY2());
1279 sy = TMath::Sqrt(cp*cp*cl->GetSigmaY2());
1280 sz = TMath::Sqrt(cl->GetSigmaZ2());