1 /**************************************************************************
2 * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 ////////////////////////////////////////////////////
19 // Stand alone tracker class //
20 // Origin: Elisabetta Crescio //
21 // e-mail: crescio@to.infn.it //
22 // tracks are saved as AliITStrackV2 objects //
23 ////////////////////////////////////////////////////
29 #include <TObjArray.h>
32 #include "AliESDEvent.h"
33 #include "AliESDVertex.h"
34 #include "AliESDtrack.h"
35 #include "AliITSVertexer.h"
36 #include "AliITSclusterTable.h"
37 #include "AliITSRecPoint.h"
38 #include "AliITSgeomTGeo.h"
39 #include "AliITStrackSA.h"
40 #include "AliITStrackerSA.h"
41 #include "AliITSReconstructor.h"
45 ClassImp(AliITStrackerSA)
47 //____________________________________________________________________________
48 AliITStrackerSA::AliITStrackerSA():AliITStrackerMI(),
71 // Default constructor
75 //____________________________________________________________________________
76 AliITStrackerSA::AliITStrackerSA(const Char_t *geom):AliITStrackerMI(0),
100 // Standard constructor (Vertex is known and passed to this obj.)
102 AliWarning("\"geom\" is actually a dummy argument !");
110 //____________________________________________________________________________
111 AliITStrackerSA::AliITStrackerSA(const Char_t *geom, AliESDVertex *vert):AliITStrackerMI(0),
135 // Standard constructor (Vertex is known and passed to this obj.)
137 AliWarning("\"geom\" is actually a dummy argument !");
143 //____________________________________________________________________________
144 AliITStrackerSA::AliITStrackerSA(const Char_t *geom, AliITSVertexer *vertexer):AliITStrackerMI(0),
168 // Standard constructor (Vertex is unknown - vertexer is passed to this obj)
170 AliWarning("\"geom\" is actually a dummy argument !");
173 fVertexer = vertexer;
177 //____________________________________________________________________________
178 AliITStrackerSA::AliITStrackerSA(const AliITStrackerSA& tracker):AliITStrackerMI(),
179 fPhiEstimate(tracker.fPhiEstimate),
180 fITSStandAlone(tracker.fITSStandAlone),
181 fLambdac(tracker.fLambdac),
182 fPhic(tracker.fPhic),
183 fCoef1(tracker.fCoef1),
184 fCoef2(tracker.fCoef2),
185 fCoef3(tracker.fCoef3),
186 fNloop(tracker.fNloop),
187 fPhiWin(tracker.fPhiWin),
188 fLambdaWin(tracker.fLambdaWin),
189 fVert(tracker.fVert),
190 fVertexer(tracker.fVertexer),
191 fListOfTracks(tracker.fListOfTracks),
192 fListOfSATracks(tracker.fListOfSATracks),
193 fITSclusters(tracker.fITSclusters),
194 fInwardFlag(tracker.fInwardFlag),
195 fOuterStartLayer(tracker.fOuterStartLayer),
196 fInnerStartLayer(tracker.fInnerStartLayer),
197 fMinNPoints(tracker.fMinNPoints),
198 fMinQ(tracker.fMinQ),
199 fCluLayer(tracker.fCluLayer),
200 fCluCoord(tracker.fCluCoord) {
202 for(Int_t i=0;i<2;i++){
203 fPoint1[i]=tracker.fPoint1[i];
204 fPoint2[i]=tracker.fPoint2[i];
205 fPoint3[i]=tracker.fPoint3[i];
206 fPointc[i]=tracker.fPointc[i];
208 if(tracker.fVertexer && tracker.fVert){
209 fVert = new AliESDVertex(*tracker.fVert);
212 fVert = tracker.fVert;
214 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
215 fCluLayer[i] = tracker.fCluLayer[i];
216 fCluCoord[i] = tracker.fCluCoord[i];
219 //______________________________________________________________________
220 AliITStrackerSA& AliITStrackerSA::operator=(const AliITStrackerSA& source){
221 // Assignment operator.
222 this->~AliITStrackerSA();
223 new(this) AliITStrackerSA(source);
228 //____________________________________________________________________________
229 AliITStrackerSA::~AliITStrackerSA(){
231 // if fVertexer is not null, the AliESDVertex obj. is owned by this class
232 // and is deleted here
234 if(fVert)delete fVert;
239 if(fPhiWin)delete []fPhiWin;
240 if(fLambdaWin)delete []fLambdaWin;
241 fListOfTracks->Delete();
242 delete fListOfTracks;
243 fListOfSATracks->Delete();
244 delete fListOfSATracks;
246 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
248 fCluLayer[i]->Delete();
255 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
257 fCluCoord[i]->Delete();
266 //____________________________________________________________________________
267 Int_t AliITStrackerSA::Clusters2Tracks(AliESDEvent *event){
268 // This method is used to find and fit the tracks. By default the corresponding
269 // method in the parent class is invoked. In this way a combined tracking
270 // TPC+ITS is performed. If the flag fITSStandAlone is true, the tracking
271 // is done in the ITS only. In the standard reconstruction chain this option
272 // can be set via AliReconstruction::SetOption("ITS","onlyITS")
275 rc=AliITStrackerMI::Clusters2Tracks(event);
278 AliDebug(1,"Stand Alone flag set: doing tracking in ITS alone\n");
281 rc=FindTracks(event,kFALSE);
282 if(AliITSReconstructor::GetRecoParam()->GetSAUseAllClusters()==kTRUE) {
283 rc=FindTracks(event,kTRUE);
290 //____________________________________________________________________________
291 void AliITStrackerSA::Init(){
292 // Reset all data members
294 for(Int_t i=0;i<3;i++){fPoint1[i]=0;fPoint2[i]=0;fPoint3[i]=0;}
304 Int_t nLoops=AliITSReconstructor::GetRecoParam()->GetNLoopsSA();
306 SetFixedWindowSizes();
308 Double_t phimin=AliITSReconstructor::GetRecoParam()->GetMinPhiSA();
309 Double_t phimax=AliITSReconstructor::GetRecoParam()->GetMaxPhiSA();
310 Double_t lambmin=AliITSReconstructor::GetRecoParam()->GetMinLambdaSA();
311 Double_t lambmax=AliITSReconstructor::GetRecoParam()->GetMaxLambdaSA();
312 SetCalculatedWindowSizes(nLoops,phimin,phimax,lambmin,lambmax);
314 fMinQ=AliITSReconstructor::GetRecoParam()->GetSAMinClusterCharge();
316 SetOuterStartLayer(1);
318 fListOfTracks=new TObjArray(0,0);
319 fListOfSATracks=new TObjArray(0,0);
324 //_______________________________________________________________________
325 void AliITStrackerSA::ResetForFinding(){
326 // Reset data members used in all loops during track finding
328 for(Int_t i=0;i<3;i++){fPoint1[i]=0;fPoint2[i]=0;fPoint3[i]=0;}
336 fListOfTracks->Delete();
337 fListOfSATracks->Delete();
342 //______________________________________________________________________
343 Int_t AliITStrackerSA::FindTracks(AliESDEvent* event, Bool_t useAllClusters){
345 // Track finder using the ESD object
347 AliDebug(2,Form(" field is %f",event->GetMagneticField()));
348 AliDebug(2,Form("SKIPPING %d %d %d %d %d %d",ForceSkippingOfLayer(0),ForceSkippingOfLayer(1),ForceSkippingOfLayer(2),ForceSkippingOfLayer(3),ForceSkippingOfLayer(4),ForceSkippingOfLayer(5)));
351 Fatal("FindTracks","ITS cluster tree is not accessed - Abort!!!\n Please use method SetClusterTree to pass the pointer to the tree\n");
354 //Reads event and mark clusters of traks already found, with flag kITSin
355 Int_t nentr=event->GetNumberOfTracks();
356 if(!useAllClusters) {
358 AliESDtrack *track=event->GetTrack(nentr);
359 if ((track->GetStatus()&AliESDtrack::kITSin) == AliESDtrack::kITSin){
361 Int_t ncl = track->GetITSclusters(idx);
362 for(Int_t k=0;k<ncl;k++){
363 AliITSRecPoint* cll = (AliITSRecPoint*)GetCluster(idx[k]);
364 cll->SetBit(kSAflag);
370 Double_t primaryVertex[3];
371 event->GetVertex()->GetXYZ(primaryVertex);
372 //Creates TClonesArray with clusters for each layer. The clusters already used
373 //by AliITStrackerMI are not considered
374 Int_t nclusters[AliITSgeomTGeo::kNLayers]={0,0,0,0,0,0};
375 Int_t dmar[AliITSgeomTGeo::kNLayers]={0,0,0,0,0,0};
376 if (fCluLayer == 0) {
377 fCluLayer = new TClonesArray*[AliITSgeomTGeo::kNLayers];
378 fCluCoord = new TClonesArray*[AliITSgeomTGeo::kNLayers];
379 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
384 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
385 AliITSlayer &layer=fgLayers[i];
386 if (!ForceSkippingOfLayer(i)) {
387 for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
388 AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
389 if(cls->TestBit(kSAflag)==kTRUE) continue; //clusters used by TPC prol.
390 if(cls->GetQ()==0) continue; //fake clusters dead zones
391 if(i>1 && cls->GetQ()<=fMinQ) continue; // cut on SDD and SSD cluster charge
397 fCluLayer[i] = new TClonesArray("AliITSRecPoint",nclusters[i]);
399 fCluLayer[i]->Delete();
400 fCluLayer[i]->Expand(nclusters[i]);
403 fCluCoord[i] = new TClonesArray("AliITSclusterTable",nclusters[i]);
405 fCluCoord[i]->Delete();
406 fCluCoord[i]->Expand(nclusters[i]);
410 for(Int_t ilay=0;ilay<AliITSgeomTGeo::GetNLayers();ilay++){
411 TClonesArray &clulay = *fCluLayer[ilay];
412 TClonesArray &clucoo = *fCluCoord[ilay];
413 AliITSlayer &layer=fgLayers[ilay];
414 if (!ForceSkippingOfLayer(ilay)) {
415 for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
416 AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
417 if(cls->TestBit(kSAflag)==kTRUE) continue;
418 if(cls->GetQ()==0) continue;
419 if(ilay>1 && cls->GetQ()<=fMinQ) continue;
420 Double_t phi=0;Double_t lambda=0;
421 Float_t x=0;Float_t y=0;Float_t z=0;
422 Float_t sx=0;Float_t sy=0;Float_t sz=0;
423 GetCoorAngles(cls,phi,lambda,x,y,z,primaryVertex);
424 GetCoorErrors(cls,sx,sy,sz);
425 new (clulay[dmar[ilay]]) AliITSRecPoint(*cls);
426 new (clucoo[dmar[ilay]]) AliITSclusterTable(x,y,z,sx,sy,sz,phi,lambda,cli);
435 static Int_t nClusLay[AliITSgeomTGeo::kNLayers];//counter for clusters on each layer
437 // loop on minimum number of points
438 for(Int_t iMinNPoints=AliITSgeomTGeo::GetNLayers(); iMinNPoints>=fMinNPoints; iMinNPoints--) {
440 if(!fInwardFlag){ // Tracking outwards from the inner layers
441 // loop on starting layer for track finding
442 for(Int_t innLay=0; innLay<=fOuterStartLayer; innLay++) {
443 if(ForceSkippingOfLayer(innLay)) continue;
444 Int_t minNPoints=iMinNPoints-innLay;
445 for(Int_t i=innLay+1;i<AliITSgeomTGeo::GetNLayers();i++)
446 if(ForceSkippingOfLayer(i))
448 if(minNPoints<fMinNPoints) continue;
450 // loop on phi and lambda window size
451 for(Int_t nloop=0;nloop<fNloop;nloop++){
452 Int_t nclInnLay=fCluLayer[innLay]->GetEntries();
455 Bool_t useRP=SetFirstPoint(innLay,nclInnLay,primaryVertex);
457 AliITStrackSA* trs = new AliITStrackSA();
461 for(kk=0;kk<AliITSgeomTGeo::GetNLayers();kk++) nClusLay[kk] = 0;
464 nClusLay[kk] = SearchClusters(innLay,fPhiWin[nloop],fLambdaWin[nloop],
465 trs,primaryVertex[2],pflag);
466 for(Int_t nextLay=innLay+1; nextLay<AliITSgeomTGeo::GetNLayers(); nextLay++) {
468 nClusLay[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
469 trs,primaryVertex[2],pflag);
473 fPoint3[0]=fPointc[0];
474 fPoint3[1]=fPointc[1];
482 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-innLay;nnp++){
483 if(nClusLay[nnp]!=0) layOK+=1;
485 if(layOK>=minNPoints){
486 AliDebug(2,Form("---NPOINTS: %d; MAP: %d %d %d %d %d %d\n",layOK,nClusLay[0],nClusLay[1],nClusLay[2],nClusLay[3],nClusLay[4],nClusLay[5]));
487 AliITStrackV2* tr2 = 0;
488 tr2 = FitTrack(trs,primaryVertex);
493 AliDebug(2,Form("---NPOINTS fit: %d\n",tr2->GetNumberOfClusters()));
495 StoreTrack(tr2,event,useAllClusters);
501 }//end loop on clusters of innLay
502 } //end loop on window sizes
503 } //end loop on innLay
504 }else{// Tracking inwards from the outer layers
505 // loop on starting layer for track finding
506 for(Int_t outLay=AliITSgeomTGeo::GetNLayers()-1; outLay>=fInnerStartLayer; outLay--) {
508 if(ForceSkippingOfLayer(outLay)) continue;
509 Int_t minNPoints=iMinNPoints-(AliITSgeomTGeo::GetNLayers()-1-outLay);
510 for(Int_t i=0;i<outLay-1;i++)
511 if(ForceSkippingOfLayer(i))
513 if(minNPoints<fMinNPoints) continue;
515 // loop on phi and lambda window size
516 for(Int_t nloop=0;nloop<fNloop;nloop++){
517 Int_t nclOutLay=fCluLayer[outLay]->GetEntries();
520 Bool_t useRP=SetFirstPoint(outLay,nclOutLay,primaryVertex);
522 AliITStrackSA* trs = new AliITStrackSA();
526 for(kk=0;kk<AliITSgeomTGeo::GetNLayers();kk++) nClusLay[kk] = 0;
529 nClusLay[kk] = SearchClusters(outLay,fPhiWin[nloop],fLambdaWin[nloop],
530 trs,primaryVertex[2],pflag);
531 for(Int_t nextLay=outLay-1; nextLay>=0; nextLay--) {
533 nClusLay[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
534 trs,primaryVertex[2],pflag);
538 fPoint3[0]=fPointc[0];
539 fPoint3[1]=fPointc[1];
547 for(Int_t nnp=outLay; nnp>=0; nnp--){
548 if(nClusLay[nnp]!=0) layOK+=1;
550 if(layOK>=minNPoints){
551 AliDebug(2,Form("---NPOINTS: %d; MAP: %d %d %d %d %d %d\n",layOK,nClusLay[0],nClusLay[1],nClusLay[2],nClusLay[3],nClusLay[4],nClusLay[5]));
552 AliITStrackV2* tr2 = 0;
553 tr2 = FitTrack(trs,primaryVertex);
558 AliDebug(2,Form("---NPOINTS fit: %d\n",tr2->GetNumberOfClusters()));
560 StoreTrack(tr2,event,useAllClusters);
566 }//end loop on clusters of innLay
567 } //end loop on window sizes
568 } //end loop on innLay
569 } // end if (fInwardFlag)
570 }//end loop on min points
572 // search for 1-point tracks in SPD, only for cosmics
573 // (A.Dainese 21.03.08)
574 if(AliITSReconstructor::GetRecoParam()->GetSAOnePointTracks() &&
575 TMath::Abs(event->GetMagneticField())<0.01) {
576 Int_t outerLayer=1; // only SPD
577 for(Int_t innLay=0; innLay<=TMath::Min(1,fOuterStartLayer); innLay++) {
578 // counter for clusters on each layer
580 for(Int_t nloop=0;nloop<fNloop;nloop++){
581 Int_t nclInnLay=fCluLayer[innLay]->GetEntries();
582 while(nclInnLay--){ //loop starting from layer innLay
584 Bool_t useRP=SetFirstPoint(innLay,nclInnLay,primaryVertex);
586 AliITStrackSA* trs = new AliITStrackSA();
590 for(kk=0;kk<AliITSgeomTGeo::GetNLayers();kk++) nClusLay[kk] = 0;
593 nClusLay[kk] = SearchClusters(innLay,fPhiWin[nloop],fLambdaWin[nloop],
594 trs,primaryVertex[2],pflag);
595 for(Int_t nextLay=innLay+1; nextLay<=outerLayer; nextLay++) {
597 nClusLay[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
598 trs,primaryVertex[2],pflag);
602 fPoint3[0]=fPointc[0];
603 fPoint3[1]=fPointc[1];
611 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-innLay;nnp++){
612 if(nClusLay[nnp]!=0) layOK+=1;
615 AliDebug(2,Form("----NPOINTS: %d; MAP: %d %d %d %d %d %d\n",layOK,nClusLay[0],nClusLay[1],nClusLay[2],nClusLay[3],nClusLay[4],nClusLay[5]));
616 AliITStrackV2* tr2 = 0;
617 Bool_t onePoint = kTRUE;
618 tr2 = FitTrack(trs,primaryVertex,onePoint);
623 AliDebug(2,Form("----NPOINTS fit: %d\n",tr2->GetNumberOfClusters()));
625 StoreTrack(tr2,event,useAllClusters);
631 }//end loop on clusters of innLay
632 } //end loop on window sizes
634 } //end loop on innLay
635 } // end search 1-point tracks
637 if(!useAllClusters) AliInfo(Form("Number of found tracks: %d",event->GetNumberOfTracks()));
643 //________________________________________________________________________
645 AliITStrackV2* AliITStrackerSA::FitTrack(AliITStrackSA* tr,Double_t *primaryVertex,Bool_t onePoint) {
646 //fit of the found track (most general case, also <6 points, layers missing)
647 // A.Dainese 16.11.07
650 const Int_t kMaxClu=AliITStrackSA::kMaxNumberOfClusters;
652 static Int_t firstmod[AliITSgeomTGeo::kNLayers];
654 static Int_t clind[AliITSgeomTGeo::kNLayers][kMaxClu];
655 static Int_t clmark[AliITSgeomTGeo::kNLayers][kMaxClu];
656 static Int_t end[AliITSgeomTGeo::kNLayers];
657 static AliITSRecPoint *listlayer[AliITSgeomTGeo::kNLayers][kMaxClu];
659 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
660 firstmod[i]=AliITSgeomTGeo::GetModuleIndex(i+1,1,1);
662 for(Int_t j=0;j<kMaxClu; j++){
670 Int_t nclusters = tr->GetNumberOfClustersSA();
671 for(Int_t ncl=0;ncl<nclusters;ncl++){
672 Int_t index = tr->GetClusterIndexSA(ncl);
673 AliITSRecPoint* cl = (AliITSRecPoint*)GetCluster(index);
674 if(cl->TestBit(kSAflag)==kTRUE) cl->ResetBit(kSAflag);
675 Int_t lay = (index & 0xf0000000) >> 28;
676 Int_t nInLay=end[lay];
677 listlayer[lay][nInLay]=cl;
678 clind[lay][nInLay]=index;
682 for(Int_t nlay=0;nlay<AliITSgeomTGeo::GetNLayers();nlay++){
683 for(Int_t ncl=0;ncl<tr->GetNumberOfMarked(nlay);ncl++){
684 Int_t mark = tr->GetClusterMark(nlay,ncl);
685 clmark[nlay][ncl]=mark;
690 Int_t firstLay=-1,secondLay=-1;
691 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
697 } else if(secondLay==-1) {
703 if(firstLay==-1 || (secondLay==-1 && !onePoint)) return 0;
705 for(Int_t l0=0;l0<end[0];l0++){ //loop on layer 1
706 AliITSRecPoint* cl0 = (AliITSRecPoint*)listlayer[0][l0];
707 for(Int_t l1=0;l1<end[1];l1++){ //loop on layer 2
708 AliITSRecPoint* cl1 = (AliITSRecPoint*)listlayer[1][l1];
709 for(Int_t l2=0;l2<end[2];l2++){ //loop on layer 3
710 AliITSRecPoint* cl2 = (AliITSRecPoint*)listlayer[2][l2];
711 for(Int_t l3=0;l3<end[3];l3++){ //loop on layer 4
712 AliITSRecPoint* cl3 = (AliITSRecPoint*)listlayer[3][l3];
713 for(Int_t l4=0;l4<end[4];l4++){ //loop on layer 5
714 AliITSRecPoint* cl4 = (AliITSRecPoint*)listlayer[4][l4];
715 for(Int_t l5=0;l5<end[5];l5++){ //loop on layer 6
716 AliITSRecPoint* cl5 = (AliITSRecPoint*)listlayer[5][l5];
719 Double_t x1,y1,z1,sx1,sy1,sz1;
720 Double_t x2,y2,z2,sx2,sy2,sz2;
721 AliITSRecPoint* p1=0;
722 AliITSRecPoint* p2=0;
723 Int_t index1=0,index2=0;
729 index1=clind[0][l0];mrk1=clmark[0][l0];
733 index1=clind[1][l1];mrk1=clmark[1][l1];
737 index1=clind[2][l2];mrk1=clmark[2][l2];
741 index1=clind[3][l3];mrk1=clmark[3][l3];
745 index1=clind[4][l4];mrk1=clmark[4][l4];
752 index2=clind[1][l1];mrk2=clmark[1][l1];
756 index2=clind[2][l2];mrk2=clmark[2][l2];
760 index2=clind[3][l3];mrk2=clmark[3][l3];
764 index2=clind[4][l4];mrk2=clmark[4][l4];
768 index2=clind[5][l5];mrk2=clmark[5][l5];
776 Int_t module1 = p1->GetDetectorIndex()+firstmod[firstLay];
777 Int_t layer,ladder,detector;
778 AliITSgeomTGeo::GetModuleId(module1,layer,ladder,detector);
779 Float_t yclu1 = p1->GetY();
780 Float_t zclu1 = p1->GetZ();
781 Double_t cv=0,tgl2=0,phi2=0;
784 AliITSclusterTable* arr1 = (AliITSclusterTable*)GetClusterCoord(firstLay,cln1);
794 AliITSclusterTable* arr2 = (AliITSclusterTable*)GetClusterCoord(secondLay,cln2);
801 cv = Curvature(primaryVertex[0],primaryVertex[1],x1,y1,x2,y2);
802 tgl2 = (z2-z1)/TMath::Sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
803 phi2 = TMath::ATan2((y2-y1),(x2-x1));
804 } else { // special case of 1-point tracks, only for cosmics (B=0)
805 x2 = primaryVertex[0];
806 y2 = primaryVertex[1];
807 z2 = primaryVertex[2];
809 tgl2 = (z1-z2)/TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
810 phi2 = TMath::ATan2((y1-y2),(x1-x2));
814 AliITStrackSA* trac = new AliITStrackSA(layer,ladder,detector,yclu1,zclu1,phi2,tgl2,cv,1);
818 trac->AddClusterV2(5,(clind[5][l5] & 0x0fffffff)>>0);
819 trac->AddClusterMark(5,clmark[5][l5]);
822 trac->AddClusterV2(4,(clind[4][l4] & 0x0fffffff)>>0);
823 trac->AddClusterMark(4,clmark[4][l4]);
826 trac->AddClusterV2(3,(clind[3][l3] & 0x0fffffff)>>0);
827 trac->AddClusterMark(3,clmark[3][l3]);
830 trac->AddClusterV2(2,(clind[2][l2] & 0x0fffffff)>>0);
831 trac->AddClusterMark(2,clmark[2][l2]);
834 trac->AddClusterV2(1,(clind[1][l1] & 0x0fffffff)>>0);
835 trac->AddClusterMark(1,clmark[1][l1]);
838 trac->AddClusterV2(0,(clind[0][l0] & 0x0fffffff)>>0);
839 trac->AddClusterMark(0,clmark[0][l0]);
842 //fit with Kalman filter using AliITStrackerMI::RefitAt()
843 AliITStrackMI* ot = new AliITStrackSA(*trac);
845 ot->ResetCovariance(10.);
848 // Propagate inside the innermost layer with a cluster
849 if(ot->Propagate(ot->GetX()-0.1*ot->GetX())) {
851 if(RefitAt(AliITSRecoParam::GetrInsideITSscreen(),ot,trac)){ //fit from layer 1 to layer 6
852 AliITStrackMI *otrack2 = new AliITStrackMI(*ot);
853 otrack2->ResetCovariance(10.);
854 otrack2->ResetClusters();
855 //fit from layer 6 to layer 1
856 if(RefitAt(AliITSRecoParam::GetrInsideSPD1(),otrack2,ot)) {
857 fListOfTracks->AddLast(otrack2);
858 fListOfSATracks->AddLast(trac);
877 if(fListOfTracks->GetEntries()==0) return 0;
879 Int_t lowchi2 = FindTrackLowChiSquare();
880 AliITStrackV2* otrack =(AliITStrackV2*)fListOfTracks->At(lowchi2);
881 AliITStrackSA* trsa = (AliITStrackSA*)fListOfSATracks->At(lowchi2);
883 if(otrack==0) return 0;
885 Int_t indexc[AliITSgeomTGeo::kNLayers];
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);
904 CookLabel(otrack,0.); //MI change - to see fake ratio
906 Int_t label=FindLabel(labl[0][0],labl[1][0],labl[2][0],labl[3][0],labl[4][0],labl[5][0]);
908 for(Int_t i=0;i<otrack->GetNumberOfClusters();i++)
909 if(labl[i][0]==label || labl[i][1]==label || labl[i][2]==label) lflag++;
911 if(lflag<otrack->GetNumberOfClusters()) label = -label;
912 otrack->SetLabel(label);
914 //remove clusters of found track
915 for(Int_t nlay=0;nlay<AliITSgeomTGeo::GetNLayers();nlay++){
916 for(Int_t cln=0;cln<trsa->GetNumberOfMarked(nlay);cln++){
917 Int_t index = trsa->GetClusterMark(nlay,cln);
918 fCluLayer[nlay]->RemoveAt(index);
919 RemoveClusterCoord(nlay,index);
920 fCluLayer[nlay]->Compress();
928 //_______________________________________________________
929 void AliITStrackerSA::StoreTrack(AliITStrackV2 *t,AliESDEvent *event, Bool_t pureSA) const
932 // Add new track to the ESD
934 AliESDtrack outtrack;
935 outtrack.UpdateTrackParams(t,AliESDtrack::kITSin);
936 if(pureSA) outtrack.SetStatus(AliESDtrack::kITSpureSA);
937 for(Int_t i=0;i<12;i++) {
938 outtrack.SetITSModuleIndex(i,t->GetModuleIndex(i));
940 Double_t sdedx[4]={0.,0.,0.,0.};
941 for(Int_t i=0; i<4; i++) sdedx[i]=t->GetSampledEdx(i);
942 outtrack.SetITSdEdxSamples(sdedx);
943 event->AddTrack(&outtrack);
949 //_______________________________________________________
950 Int_t AliITStrackerSA::SearchClusters(Int_t layer,Double_t phiwindow,Double_t lambdawindow, AliITStrackSA* trs,Double_t /*zvertex*/,Int_t pflag){
951 //function used to to find the clusters associated to the track
953 if(ForceSkippingOfLayer(layer)) return 0;
956 AliITSlayer &lay = fgLayers[layer];
957 Double_t r=lay.GetR();
959 Float_t cx1,cx2,cy1,cy2;
960 FindEquation(fPoint1[0],fPoint1[1],fPoint2[0],fPoint2[1],fPoint3[0],fPoint3[1],fCoef1,fCoef2,fCoef3);
961 if (FindIntersection(fCoef1,fCoef2,fCoef3,-r*r,cx1,cy1,cx2,cy2)==0)
963 Double_t fi1=TMath::ATan2(cy1-fPoint1[1],cx1-fPoint1[0]);
964 Double_t fi2=TMath::ATan2(cy2-fPoint1[1],cx2-fPoint1[0]);
965 fPhiEstimate=ChoosePoint(fi1,fi2,fPhic);
969 Int_t ncl = fCluLayer[layer]->GetEntries();
970 for (Int_t index=0; index<ncl; index++) {
971 AliITSRecPoint *c = (AliITSRecPoint*)fCluLayer[layer]->At(index);
973 if (c->GetQ()<=0) continue;
974 if(layer>1 && c->GetQ()<=fMinQ) continue;
976 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(layer,index);
977 Double_t phi = arr->GetPhi();
978 if (TMath::Abs(phi-fPhiEstimate)>phiwindow) continue;
980 Double_t lambda = arr->GetLambda();
981 if (TMath::Abs(lambda-fLambdac)>lambdawindow) continue;
983 if(trs->GetNumberOfClustersSA()==trs->GetMaxNumberOfClusters()) return 0;
984 if(trs->GetNumberOfMarked(layer)==trs->GetMaxNMarkedPerLayer()) return 0;
985 Int_t orind = arr->GetOrInd();
986 trs->AddClusterSA(layer,orind);
987 trs->AddClusterMark(layer,index);
993 fPointc[0]=arr->GetX();
994 fPointc[1]=arr->GetY();
1000 //________________________________________________________________
1001 Bool_t AliITStrackerSA::SetFirstPoint(Int_t lay, Int_t clu, Double_t* primaryVertex){
1002 // Sets the first point (seed) for tracking
1004 AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[lay]->At(clu);
1005 if(!cl) return kFALSE;
1006 if (cl->GetQ()<=0) return kFALSE;
1007 if(lay>1 && cl->GetQ()<=fMinQ) return kFALSE;
1009 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(lay,clu);
1010 fPhic = arr->GetPhi();
1011 fLambdac = arr->GetLambda();
1012 fPhiEstimate = fPhic;
1013 fPoint1[0]=primaryVertex[0];
1014 fPoint1[1]=primaryVertex[1];
1015 fPoint2[0]=arr->GetX();
1016 fPoint2[1]=arr->GetY();
1020 //________________________________________________________________
1021 void AliITStrackerSA::UpdatePoints(){
1022 //update of points for the estimation of the curvature
1024 fPoint2[0]=fPoint3[0];
1025 fPoint2[1]=fPoint3[1];
1026 fPoint3[0]=fPointc[0];
1027 fPoint3[1]=fPointc[1];
1032 //___________________________________________________________________
1033 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){
1035 //given (x,y) of three recpoints (in global coordinates)
1036 //returns the parameters a,b,c of circonference x*x + y*y +a*x + b*y +c
1038 Float_t den = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1);
1039 if(den==0) return 0;
1040 a = ((y3-y1)*(x2*x2+y2*y2-x1*x1-y1*y1)-(y2-y1)*(x3*x3+y3*y3-x1*x1-y1*y1))/den;
1041 b = -(x2*x2-x1*x1+y2*y2-y1*y1+a*(x2-x1))/(y2-y1);
1042 c = -x1*x1-y1*y1-a*x1-b*y1;
1045 //__________________________________________________________________________
1046 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){
1048 //Finds the intersection between the circonference of the track and the circonference centered in (0,0) represented by one layer
1049 //c2 is -rlayer*rlayer
1053 Double_t aA = (b1*b1)/(a1*a1)+1;
1054 Double_t bB = (-2*m*b1/(a1*a1));
1055 Double_t cC = c2+(m*m)/(a1*a1);
1056 Double_t dD = bB*bB-4*aA*cC;
1059 y1 = (-bB+TMath::Sqrt(dD))/(2*aA);
1060 y2 = (-bB-TMath::Sqrt(dD))/(2*aA);
1061 x1 = (c2-c1-b1*y1)/a1;
1062 x2 = (c2-c1-b1*y2)/a1;
1066 //____________________________________________________________________
1067 Double_t AliITStrackerSA::Curvature(Double_t x1,Double_t y1,Double_t
1068 x2,Double_t y2,Double_t x3,Double_t y3){
1070 //calculates the curvature of track
1071 Double_t den = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1);
1072 if(den==0) return 0;
1073 Double_t a = ((y3-y1)*(x2*x2+y2*y2-x1*x1-y1*y1)-(y2-y1)*(x3*x3+y3*y3-x1*x1-y1*y1))/den;
1074 Double_t b = -(x2*x2-x1*x1+y2*y2-y1*y1+a*(x2-x1))/(y2-y1);
1075 Double_t c = -x1*x1-y1*y1-a*x1-b*y1;
1078 if((a*a+b*b-4*c)<0) return 0;
1079 Double_t rad = TMath::Sqrt(a*a+b*b-4*c)/2.;
1080 if(rad==0) return 0;
1082 if((x1>0 && y1>0 && x1<xc)) rad*=-1;
1083 if((x1<0 && y1>0 && x1<xc)) rad*=-1;
1084 // if((x1<0 && y1<0 && x1<xc)) rad*=-1;
1085 // if((x1>0 && y1<0 && x1<xc)) rad*=-1;
1092 //____________________________________________________________________
1093 Double_t AliITStrackerSA::ChoosePoint(Double_t p1, Double_t p2, Double_t pp){
1095 //Returns the point closest to pp
1097 Double_t diff1 = p1-pp;
1098 Double_t diff2 = p2-pp;
1100 if(TMath::Abs(diff1)<TMath::Abs(diff2)) fPhiEstimate=p1;
1101 else fPhiEstimate=p2;
1102 return fPhiEstimate;
1107 //_________________________________________________________________
1108 Int_t AliITStrackerSA::FindTrackLowChiSquare() const {
1109 // returns track with lowest chi square
1110 Int_t dim=fListOfTracks->GetEntries();
1111 if(dim<=1) return 0;
1112 AliITStrackV2* trk = (AliITStrackV2*)fListOfTracks->At(0);
1113 Double_t minChi2=trk->GetChi2();
1115 for(Int_t i=1;i<dim;i++){
1116 trk = (AliITStrackV2*)fListOfTracks->At(i);
1117 Double_t chi2=trk->GetChi2();
1126 //__________________________________________________________
1127 Int_t AliITStrackerSA::FindLabel(Int_t l0, Int_t l1, Int_t l2, Int_t l3, Int_t l4, Int_t l5){
1129 //function used to determine the track label
1131 Int_t lb[6] = {l0,l1,l2,l3,l4,l5};
1132 Int_t aa[6]={1,1,1,1,1,1};
1135 Int_t k=0;Int_t w=0;Int_t num=6;
1136 for(Int_t i=5;i>=0;i--) if(lb[i]==-1) num=i;
1140 for(Int_t i=k+1;i<num;i++){
1142 if(lb[k]==lb[i] && aa[k]!=0){
1153 for(Int_t j=0;j<6;j++){
1166 if(num<1) return -1;
1170 //_____________________________________________________________________________
1171 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,
1172 Int_t gl12, Int_t gl13, Int_t gl14,Int_t gl15, Int_t gl16, Int_t gl17, Int_t gl18, Int_t minNPoints){
1175 //function used to assign label to the found track. If track is fake, the label is negative
1177 Int_t lb0[6] = {gl1,gl2,gl3,gl4,gl5,gl6};
1178 Int_t lb1[6] = {gl7,gl8,gl9,gl10,gl11,gl12};
1179 Int_t lb2[6] = {gl13,gl14,gl15,gl16,gl17,gl18};
1180 Int_t ll=FindLabel(lb0[0],lb0[1],lb0[2],lb0[3],lb0[4],lb0[5]);
1181 Int_t lflag=0;Int_t num=6;
1182 if(lb0[5]==-1 && lb1[5]==-1 && lb2[5]==-1) num=5;
1184 for(Int_t i=0;i<num;i++){
1185 if(lb0[i]==ll || lb1[i]==ll || lb2[i]==ll) lflag+=1;
1188 if(lflag>=minNPoints) return ll;
1193 //_____________________________________________________________________________
1194 void AliITStrackerSA::SetCalculatedWindowSizes(Int_t n, Float_t phimin, Float_t phimax, Float_t lambdamin, Float_t lambdamax){
1195 // Set sizes of the phi and lambda windows used for track finding
1197 if(fPhiWin) delete [] fPhiWin;
1198 if(fLambdaWin) delete [] fLambdaWin;
1199 fPhiWin = new Double_t[fNloop];
1200 fLambdaWin = new Double_t[fNloop];
1201 Float_t stepPhi=(phimax-phimin)/(Float_t)(fNloop-1);
1202 Float_t stepLambda=(lambdamax-lambdamin)/(Float_t)(fNloop-1);
1203 for(Int_t k=0;k<fNloop;k++){
1204 Float_t phi=phimin+k*stepPhi;
1205 Float_t lam=lambdamin+k*stepLambda;
1210 //_____________________________________________________________________________
1211 void AliITStrackerSA::SetFixedWindowSizes(Int_t n, Double_t *phi, Double_t *lam){
1212 // Set sizes of the phi and lambda windows used for track finding
1214 if(phi){ // user defined values
1215 fPhiWin = new Double_t[fNloop];
1216 fLambdaWin = new Double_t[fNloop];
1217 for(Int_t k=0;k<fNloop;k++){
1219 fLambdaWin[k]=lam[k];
1222 else { // default values
1224 Double_t phid[33] = {0.002,0.003,0.004,0.0045,0.0047,
1225 0.005,0.0053,0.0055,
1226 0.006,0.0063,0.0065,0.007,0.0073,0.0075,0.0077,
1227 0.008,0.0083,0.0085,0.0087,0.009,0.0095,0.0097,
1228 0.01,0.0105,0.011,0.0115,0.012,0.0125,0.013,0.0135,0.0140,0.0145};
1229 Double_t lambdad[33] = {0.003,0.004,0.005,0.005,0.005,
1231 0.006,0.006,0.006,0.007,0.007,0.007,0.007,
1232 0.007,0.007,0.007,0.007,0.007,0.007,0.007,
1233 0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008};
1240 fPhiWin = new Double_t[fNloop];
1241 fLambdaWin = new Double_t[fNloop];
1243 Double_t factor=AliITSReconstructor::GetRecoParam()->GetFactorSAWindowSizes(); // possibility to enlarge windows for cosmics reco with large misalignments (A.Dainese)
1245 for(Int_t k=0;k<fNloop;k++){
1246 fPhiWin[k]=phid[k]*factor;
1247 fLambdaWin[k]=lambdad[k]*factor;
1253 //_______________________________________________________________________
1254 void AliITStrackerSA::GetCoorAngles(AliITSRecPoint* cl,Double_t &phi,Double_t &lambda, Float_t &x, Float_t &y,Float_t &z,Double_t* vertex){
1255 //Returns values of phi (azimuthal) and lambda angles for a given cluster
1257 Double_t rot[9]; fGeom->GetRotMatrix(module,rot);
1258 Int_t lay,lad,det; fGeom->GetModuleId(module,lay,lad,det);
1259 Float_t tx,ty,tz; fGeom->GetTrans(lay,lad,det,tx,ty,tz);
1261 Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
1262 Double_t phi1=TMath::Pi()/2+alpha;
1263 if (lay==1) phi1+=TMath::Pi();
1265 Float_t cp=TMath::Cos(phi1), sp=TMath::Sin(phi1);
1266 Float_t r=tx*cp+ty*sp;
1268 xyz= r*cp - cl->GetY()*sp;
1269 y= r*sp + cl->GetY()*cp;
1273 cl->GetGlobalXYZ(xyz);
1278 phi=TMath::ATan2(y-vertex[1],x-vertex[0]);
1279 lambda=TMath::ATan2(z-vertex[2],TMath::Sqrt((x-vertex[0])*(x-vertex[0])+(y-vertex[1])*(y-vertex[1])));
1282 //________________________________________________________________________
1283 void AliITStrackerSA::GetCoorErrors(AliITSRecPoint* cl,Float_t &sx,Float_t &sy, Float_t &sz){
1285 //returns sigmax, y, z of cluster in global coordinates
1287 Double_t rot[9]; fGeom->GetRotMatrix(module,rot);
1289 AliITSgeomTGeo::GetModuleId(module,lay,lad,det);
1291 Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
1292 Double_t phi=TMath::Pi()/2+alpha;
1293 if (lay==1) phi+=TMath::Pi();
1295 Float_t cp=TMath::Cos(phi), sp=TMath::Sin(phi);
1298 cl->GetGlobalCov(covm);
1299 sx=TMath::Sqrt(covm[0]);
1300 sy=TMath::Sqrt(covm[3]);
1301 sz=TMath::Sqrt(covm[5]);
1303 sx = TMath::Sqrt(sp*sp*cl->GetSigmaY2());
1304 sy = TMath::Sqrt(cp*cp*cl->GetSigmaY2());
1305 sz = TMath::Sqrt(cl->GetSigmaZ2());