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 AliESDtrack *track=event->GetTrack(nentr);
371 if ((track->GetStatus()&AliESDtrack::kITSin) == AliESDtrack::kITSin){
373 Int_t ncl = track->GetITSclusters(idx);
374 for(Int_t k=0;k<ncl;k++){
375 AliITSRecPoint* cll = (AliITSRecPoint*)GetCluster(idx[k]);
376 cll->ResetBit(kSAflag);
382 Double_t primaryVertex[3];
383 event->GetVertex()->GetXYZ(primaryVertex);
384 //Creates TClonesArray with clusters for each layer. The clusters already used
385 //by AliITStrackerMI are not considered
386 Int_t nclusters[AliITSgeomTGeo::kNLayers]={0,0,0,0,0,0};
387 Int_t dmar[AliITSgeomTGeo::kNLayers]={0,0,0,0,0,0};
388 if (fCluLayer == 0) {
389 fCluLayer = new TClonesArray*[AliITSgeomTGeo::kNLayers];
390 fCluCoord = new TClonesArray*[AliITSgeomTGeo::kNLayers];
391 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
396 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
397 AliITSlayer &layer=fgLayers[i];
398 if (!ForceSkippingOfLayer(i)) {
399 for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
400 AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
401 if(cls->TestBit(kSAflag)==kTRUE) continue; //clusters used by TPC prol.
402 if(cls->GetQ()==0) continue; //fake clusters dead zones
403 if(i>1 && cls->GetQ()<=fMinQ) continue; // cut on SDD and SSD cluster charge
409 fCluLayer[i] = new TClonesArray("AliITSRecPoint",nclusters[i]);
411 fCluLayer[i]->Delete();
412 fCluLayer[i]->Expand(nclusters[i]);
415 fCluCoord[i] = new TClonesArray("AliITSclusterTable",nclusters[i]);
417 fCluCoord[i]->Delete();
418 fCluCoord[i]->Expand(nclusters[i]);
422 for(Int_t ilay=0;ilay<AliITSgeomTGeo::GetNLayers();ilay++){
423 TClonesArray &clulay = *fCluLayer[ilay];
424 TClonesArray &clucoo = *fCluCoord[ilay];
425 AliITSlayer &layer=fgLayers[ilay];
426 if (!ForceSkippingOfLayer(ilay)) {
427 for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
428 AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
429 if(cls->TestBit(kSAflag)==kTRUE) continue;
430 if(cls->GetQ()==0) continue;
431 if(ilay>1 && cls->GetQ()<=fMinQ) continue;
432 Double_t phi=0;Double_t lambda=0;
433 Float_t x=0;Float_t y=0;Float_t z=0;
434 Float_t sx=0;Float_t sy=0;Float_t sz=0;
435 GetCoorAngles(cls,phi,lambda,x,y,z,primaryVertex);
436 GetCoorErrors(cls,sx,sy,sz);
437 new (clulay[dmar[ilay]]) AliITSRecPoint(*cls);
438 new (clucoo[dmar[ilay]]) AliITSclusterTable(x,y,z,sx,sy,sz,phi,lambda,cli);
447 static Int_t nClusLay[AliITSgeomTGeo::kNLayers];//counter for clusters on each layer
449 // loop on minimum number of points
450 for(Int_t iMinNPoints=AliITSgeomTGeo::GetNLayers(); iMinNPoints>=fMinNPoints; iMinNPoints--) {
452 if(!fInwardFlag){ // Tracking outwards from the inner layers
453 // loop on starting layer for track finding
454 for(Int_t innLay=0; innLay<=fOuterStartLayer; innLay++) {
455 if(ForceSkippingOfLayer(innLay)) continue;
456 Int_t minNPoints=iMinNPoints-innLay;
457 for(Int_t i=innLay+1;i<AliITSgeomTGeo::GetNLayers();i++)
458 if(ForceSkippingOfLayer(i))
460 if(minNPoints<fMinNPoints) continue;
462 // loop on phi and lambda window size
463 for(Int_t nloop=0;nloop<fNloop;nloop++){
464 Int_t nclInnLay=fCluLayer[innLay]->GetEntries();
467 Bool_t useRP=SetFirstPoint(innLay,nclInnLay,primaryVertex);
469 AliITStrackSA* trs = new AliITStrackSA();
473 for(kk=0;kk<AliITSgeomTGeo::GetNLayers();kk++) nClusLay[kk] = 0;
476 nClusLay[kk] = SearchClusters(innLay,fPhiWin[nloop],fLambdaWin[nloop],
477 trs,primaryVertex[2],pflag);
478 for(Int_t nextLay=innLay+1; nextLay<AliITSgeomTGeo::GetNLayers(); nextLay++) {
480 nClusLay[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
481 trs,primaryVertex[2],pflag);
485 fPoint3[0]=fPointc[0];
486 fPoint3[1]=fPointc[1];
494 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-innLay;nnp++){
495 if(nClusLay[nnp]!=0) layOK+=1;
497 if(layOK>=minNPoints){
498 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]));
499 AliITStrackV2* tr2 = 0;
500 tr2 = FitTrack(trs,primaryVertex);
505 AliDebug(2,Form("---NPOINTS fit: %d\n",tr2->GetNumberOfClusters()));
507 StoreTrack(tr2,event,useAllClusters);
513 }//end loop on clusters of innLay
514 } //end loop on window sizes
515 } //end loop on innLay
516 }else{// Tracking inwards from the outer layers
517 // loop on starting layer for track finding
518 for(Int_t outLay=AliITSgeomTGeo::GetNLayers()-1; outLay>=fInnerStartLayer; outLay--) {
520 if(ForceSkippingOfLayer(outLay)) continue;
521 Int_t minNPoints=iMinNPoints-(AliITSgeomTGeo::GetNLayers()-1-outLay);
522 for(Int_t i=0;i<outLay-1;i++)
523 if(ForceSkippingOfLayer(i))
525 if(minNPoints<fMinNPoints) continue;
527 // loop on phi and lambda window size
528 for(Int_t nloop=0;nloop<fNloop;nloop++){
529 Int_t nclOutLay=fCluLayer[outLay]->GetEntries();
532 Bool_t useRP=SetFirstPoint(outLay,nclOutLay,primaryVertex);
534 AliITStrackSA* trs = new AliITStrackSA();
538 for(kk=0;kk<AliITSgeomTGeo::GetNLayers();kk++) nClusLay[kk] = 0;
541 nClusLay[kk] = SearchClusters(outLay,fPhiWin[nloop],fLambdaWin[nloop],
542 trs,primaryVertex[2],pflag);
543 for(Int_t nextLay=outLay-1; nextLay>=0; nextLay--) {
545 nClusLay[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
546 trs,primaryVertex[2],pflag);
550 fPoint3[0]=fPointc[0];
551 fPoint3[1]=fPointc[1];
559 for(Int_t nnp=outLay; nnp>=0; nnp--){
560 if(nClusLay[nnp]!=0) layOK+=1;
562 if(layOK>=minNPoints){
563 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]));
564 AliITStrackV2* tr2 = 0;
565 tr2 = FitTrack(trs,primaryVertex);
570 AliDebug(2,Form("---NPOINTS fit: %d\n",tr2->GetNumberOfClusters()));
572 StoreTrack(tr2,event,useAllClusters);
578 }//end loop on clusters of innLay
579 } //end loop on window sizes
580 } //end loop on innLay
581 } // end if (fInwardFlag)
582 }//end loop on min points
584 // search for 1-point tracks in SPD, only for cosmics
585 // (A.Dainese 21.03.08)
586 if(AliITSReconstructor::GetRecoParam()->GetSAOnePointTracks() &&
587 TMath::Abs(event->GetMagneticField())<0.01) {
588 Int_t outerLayer=1; // only SPD
589 for(Int_t innLay=0; innLay<=TMath::Min(1,fOuterStartLayer); innLay++) {
590 // counter for clusters on each layer
592 for(Int_t nloop=0;nloop<fNloop;nloop++){
593 Int_t nclInnLay=fCluLayer[innLay]->GetEntries();
594 while(nclInnLay--){ //loop starting from layer innLay
596 Bool_t useRP=SetFirstPoint(innLay,nclInnLay,primaryVertex);
598 AliITStrackSA* trs = new AliITStrackSA();
602 for(kk=0;kk<AliITSgeomTGeo::GetNLayers();kk++) nClusLay[kk] = 0;
605 nClusLay[kk] = SearchClusters(innLay,fPhiWin[nloop],fLambdaWin[nloop],
606 trs,primaryVertex[2],pflag);
607 for(Int_t nextLay=innLay+1; nextLay<=outerLayer; nextLay++) {
609 nClusLay[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
610 trs,primaryVertex[2],pflag);
614 fPoint3[0]=fPointc[0];
615 fPoint3[1]=fPointc[1];
623 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-innLay;nnp++){
624 if(nClusLay[nnp]!=0) layOK+=1;
627 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]));
628 AliITStrackV2* tr2 = 0;
629 Bool_t onePoint = kTRUE;
630 tr2 = FitTrack(trs,primaryVertex,onePoint);
635 AliDebug(2,Form("----NPOINTS fit: %d\n",tr2->GetNumberOfClusters()));
637 StoreTrack(tr2,event,useAllClusters);
643 }//end loop on clusters of innLay
644 } //end loop on window sizes
646 } //end loop on innLay
647 } // end search 1-point tracks
649 if(!useAllClusters) AliInfo(Form("Number of found tracks: %d",event->GetNumberOfTracks()));
655 //________________________________________________________________________
657 AliITStrackV2* AliITStrackerSA::FitTrack(AliITStrackSA* tr,Double_t *primaryVertex,Bool_t onePoint) {
658 //fit of the found track (most general case, also <6 points, layers missing)
659 // A.Dainese 16.11.07
662 const Int_t kMaxClu=AliITStrackSA::kMaxNumberOfClusters;
664 static Int_t firstmod[AliITSgeomTGeo::kNLayers];
666 static Int_t clind[AliITSgeomTGeo::kNLayers][kMaxClu];
667 static Int_t clmark[AliITSgeomTGeo::kNLayers][kMaxClu];
668 static Int_t end[AliITSgeomTGeo::kNLayers];
669 static AliITSRecPoint *listlayer[AliITSgeomTGeo::kNLayers][kMaxClu];
671 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
672 firstmod[i]=AliITSgeomTGeo::GetModuleIndex(i+1,1,1);
674 for(Int_t j=0;j<kMaxClu; j++){
682 Int_t nclusters = tr->GetNumberOfClustersSA();
683 for(Int_t ncl=0;ncl<nclusters;ncl++){
684 Int_t index = tr->GetClusterIndexSA(ncl);
685 AliITSRecPoint* cl = (AliITSRecPoint*)GetCluster(index);
686 if(cl->TestBit(kSAflag)==kTRUE) cl->ResetBit(kSAflag);
687 Int_t lay = (index & 0xf0000000) >> 28;
688 Int_t nInLay=end[lay];
689 listlayer[lay][nInLay]=cl;
690 clind[lay][nInLay]=index;
694 for(Int_t nlay=0;nlay<AliITSgeomTGeo::GetNLayers();nlay++){
695 for(Int_t ncl=0;ncl<tr->GetNumberOfMarked(nlay);ncl++){
696 Int_t mark = tr->GetClusterMark(nlay,ncl);
697 clmark[nlay][ncl]=mark;
702 Int_t firstLay=-1,secondLay=-1;
703 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
709 } else if(secondLay==-1) {
715 if(firstLay==-1 || (secondLay==-1 && !onePoint)) return 0;
717 for(Int_t l0=0;l0<end[0];l0++){ //loop on layer 1
718 AliITSRecPoint* cl0 = (AliITSRecPoint*)listlayer[0][l0];
719 for(Int_t l1=0;l1<end[1];l1++){ //loop on layer 2
720 AliITSRecPoint* cl1 = (AliITSRecPoint*)listlayer[1][l1];
721 for(Int_t l2=0;l2<end[2];l2++){ //loop on layer 3
722 AliITSRecPoint* cl2 = (AliITSRecPoint*)listlayer[2][l2];
723 for(Int_t l3=0;l3<end[3];l3++){ //loop on layer 4
724 AliITSRecPoint* cl3 = (AliITSRecPoint*)listlayer[3][l3];
725 for(Int_t l4=0;l4<end[4];l4++){ //loop on layer 5
726 AliITSRecPoint* cl4 = (AliITSRecPoint*)listlayer[4][l4];
727 for(Int_t l5=0;l5<end[5];l5++){ //loop on layer 6
728 AliITSRecPoint* cl5 = (AliITSRecPoint*)listlayer[5][l5];
731 Double_t x1,y1,z1,sx1,sy1,sz1;
732 Double_t x2,y2,z2,sx2,sy2,sz2;
733 AliITSRecPoint* p1=0;
734 AliITSRecPoint* p2=0;
735 Int_t index1=0,index2=0;
741 index1=clind[0][l0];mrk1=clmark[0][l0];
745 index1=clind[1][l1];mrk1=clmark[1][l1];
749 index1=clind[2][l2];mrk1=clmark[2][l2];
753 index1=clind[3][l3];mrk1=clmark[3][l3];
757 index1=clind[4][l4];mrk1=clmark[4][l4];
764 index2=clind[1][l1];mrk2=clmark[1][l1];
768 index2=clind[2][l2];mrk2=clmark[2][l2];
772 index2=clind[3][l3];mrk2=clmark[3][l3];
776 index2=clind[4][l4];mrk2=clmark[4][l4];
780 index2=clind[5][l5];mrk2=clmark[5][l5];
788 Int_t module1 = p1->GetDetectorIndex()+firstmod[firstLay];
789 Int_t layer,ladder,detector;
790 AliITSgeomTGeo::GetModuleId(module1,layer,ladder,detector);
791 Float_t yclu1 = p1->GetY();
792 Float_t zclu1 = p1->GetZ();
793 Double_t cv=0,tgl2=0,phi2=0;
796 AliITSclusterTable* arr1 = (AliITSclusterTable*)GetClusterCoord(firstLay,cln1);
806 AliITSclusterTable* arr2 = (AliITSclusterTable*)GetClusterCoord(secondLay,cln2);
813 cv = Curvature(primaryVertex[0],primaryVertex[1],x1,y1,x2,y2);
814 tgl2 = (z2-z1)/TMath::Sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
815 phi2 = TMath::ATan2((y2-y1),(x2-x1));
816 } else { // special case of 1-point tracks, only for cosmics (B=0)
817 x2 = primaryVertex[0];
818 y2 = primaryVertex[1];
819 z2 = primaryVertex[2];
821 tgl2 = (z1-z2)/TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
822 phi2 = TMath::ATan2((y1-y2),(x1-x2));
826 AliITStrackSA* trac = new AliITStrackSA(layer,ladder,detector,yclu1,zclu1,phi2,tgl2,cv,1);
830 trac->AddClusterV2(5,(clind[5][l5] & 0x0fffffff)>>0);
831 trac->AddClusterMark(5,clmark[5][l5]);
834 trac->AddClusterV2(4,(clind[4][l4] & 0x0fffffff)>>0);
835 trac->AddClusterMark(4,clmark[4][l4]);
838 trac->AddClusterV2(3,(clind[3][l3] & 0x0fffffff)>>0);
839 trac->AddClusterMark(3,clmark[3][l3]);
842 trac->AddClusterV2(2,(clind[2][l2] & 0x0fffffff)>>0);
843 trac->AddClusterMark(2,clmark[2][l2]);
846 trac->AddClusterV2(1,(clind[1][l1] & 0x0fffffff)>>0);
847 trac->AddClusterMark(1,clmark[1][l1]);
850 trac->AddClusterV2(0,(clind[0][l0] & 0x0fffffff)>>0);
851 trac->AddClusterMark(0,clmark[0][l0]);
854 //fit with Kalman filter using AliITStrackerMI::RefitAt()
855 AliITStrackMI* ot = new AliITStrackSA(*trac);
857 ot->ResetCovariance(10.);
860 // Propagate inside the innermost layer with a cluster
861 if(ot->Propagate(ot->GetX()-0.1*ot->GetX())) {
863 if(RefitAt(AliITSRecoParam::GetrInsideITSscreen(),ot,trac)){ //fit from layer 1 to layer 6
864 AliITStrackMI *otrack2 = new AliITStrackMI(*ot);
865 otrack2->ResetCovariance(10.);
866 otrack2->ResetClusters();
867 //fit from layer 6 to layer 1
868 if(RefitAt(AliITSRecoParam::GetrInsideSPD1(),otrack2,ot)) {
869 fListOfTracks->AddLast(otrack2);
870 fListOfSATracks->AddLast(trac);
889 if(fListOfTracks->GetEntries()==0) return 0;
891 Int_t lowchi2 = FindTrackLowChiSquare();
892 AliITStrackV2* otrack =(AliITStrackV2*)fListOfTracks->At(lowchi2);
893 AliITStrackSA* trsa = (AliITStrackSA*)fListOfSATracks->At(lowchi2);
895 if(otrack==0) return 0;
897 Int_t indexc[AliITSgeomTGeo::kNLayers];
898 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) indexc[i]=0;
899 for(Int_t nind=0;nind<otrack->GetNumberOfClusters();nind++){
900 indexc[nind] = otrack->GetClusterIndex(nind);
903 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
904 if(i<otrack->GetNumberOfClusters()) {
905 AliITSRecPoint* cl = (AliITSRecPoint*)GetCluster(indexc[i]);
906 labl[i][0]=cl->GetLabel(0);
907 labl[i][1]=cl->GetLabel(1);
908 labl[i][2]=cl->GetLabel(2);
916 CookLabel(otrack,0.); //MI change - to see fake ratio
918 Int_t label=FindLabel(labl[0][0],labl[1][0],labl[2][0],labl[3][0],labl[4][0],labl[5][0]);
920 for(Int_t i=0;i<otrack->GetNumberOfClusters();i++)
921 if(labl[i][0]==label || labl[i][1]==label || labl[i][2]==label) lflag++;
923 if(lflag<otrack->GetNumberOfClusters()) label = -label;
924 otrack->SetLabel(label);
926 //remove clusters of found track
927 for(Int_t nlay=0;nlay<AliITSgeomTGeo::GetNLayers();nlay++){
928 for(Int_t cln=0;cln<trsa->GetNumberOfMarked(nlay);cln++){
929 Int_t index = trsa->GetClusterMark(nlay,cln);
930 fCluLayer[nlay]->RemoveAt(index);
931 RemoveClusterCoord(nlay,index);
932 fCluLayer[nlay]->Compress();
940 //_______________________________________________________
941 void AliITStrackerSA::StoreTrack(AliITStrackV2 *t,AliESDEvent *event, Bool_t pureSA) const
944 // Add new track to the ESD
946 AliESDtrack outtrack;
947 outtrack.UpdateTrackParams(t,AliESDtrack::kITSin);
948 if(pureSA) outtrack.SetStatus(AliESDtrack::kITSpureSA);
949 for(Int_t i=0;i<12;i++) {
950 outtrack.SetITSModuleIndex(i,t->GetModuleIndex(i));
952 Double_t sdedx[4]={0.,0.,0.,0.};
953 for(Int_t i=0; i<4; i++) sdedx[i]=t->GetSampledEdx(i);
954 outtrack.SetITSdEdxSamples(sdedx);
955 event->AddTrack(&outtrack);
961 //_______________________________________________________
962 Int_t AliITStrackerSA::SearchClusters(Int_t layer,Double_t phiwindow,Double_t lambdawindow, AliITStrackSA* trs,Double_t /*zvertex*/,Int_t pflag){
963 //function used to to find the clusters associated to the track
965 if(ForceSkippingOfLayer(layer)) return 0;
968 AliITSlayer &lay = fgLayers[layer];
969 Double_t r=lay.GetR();
971 Float_t cx1,cx2,cy1,cy2;
972 FindEquation(fPoint1[0],fPoint1[1],fPoint2[0],fPoint2[1],fPoint3[0],fPoint3[1],fCoef1,fCoef2,fCoef3);
973 if (FindIntersection(fCoef1,fCoef2,fCoef3,-r*r,cx1,cy1,cx2,cy2)==0)
975 Double_t fi1=TMath::ATan2(cy1-fPoint1[1],cx1-fPoint1[0]);
976 Double_t fi2=TMath::ATan2(cy2-fPoint1[1],cx2-fPoint1[0]);
977 fPhiEstimate=ChoosePoint(fi1,fi2,fPhic);
981 Int_t ncl = fCluLayer[layer]->GetEntries();
982 for (Int_t index=0; index<ncl; index++) {
983 AliITSRecPoint *c = (AliITSRecPoint*)fCluLayer[layer]->At(index);
985 if (c->GetQ()<=0) continue;
986 if(layer>1 && c->GetQ()<=fMinQ) continue;
988 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(layer,index);
989 Double_t phi = arr->GetPhi();
990 if (TMath::Abs(phi-fPhiEstimate)>phiwindow) continue;
992 Double_t lambda = arr->GetLambda();
993 if (TMath::Abs(lambda-fLambdac)>lambdawindow) continue;
995 if(trs->GetNumberOfClustersSA()==trs->GetMaxNumberOfClusters()) return 0;
996 if(trs->GetNumberOfMarked(layer)==trs->GetMaxNMarkedPerLayer()) return 0;
997 Int_t orind = arr->GetOrInd();
998 trs->AddClusterSA(layer,orind);
999 trs->AddClusterMark(layer,index);
1005 fPointc[0]=arr->GetX();
1006 fPointc[1]=arr->GetY();
1012 //________________________________________________________________
1013 Bool_t AliITStrackerSA::SetFirstPoint(Int_t lay, Int_t clu, Double_t* primaryVertex){
1014 // Sets the first point (seed) for tracking
1016 AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[lay]->At(clu);
1017 if(!cl) return kFALSE;
1018 if (cl->GetQ()<=0) return kFALSE;
1019 if(lay>1 && cl->GetQ()<=fMinQ) return kFALSE;
1021 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(lay,clu);
1022 fPhic = arr->GetPhi();
1023 fLambdac = arr->GetLambda();
1024 fPhiEstimate = fPhic;
1025 fPoint1[0]=primaryVertex[0];
1026 fPoint1[1]=primaryVertex[1];
1027 fPoint2[0]=arr->GetX();
1028 fPoint2[1]=arr->GetY();
1032 //________________________________________________________________
1033 void AliITStrackerSA::UpdatePoints(){
1034 //update of points for the estimation of the curvature
1036 fPoint2[0]=fPoint3[0];
1037 fPoint2[1]=fPoint3[1];
1038 fPoint3[0]=fPointc[0];
1039 fPoint3[1]=fPointc[1];
1044 //___________________________________________________________________
1045 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){
1047 //given (x,y) of three recpoints (in global coordinates)
1048 //returns the parameters a,b,c of circonference x*x + y*y +a*x + b*y +c
1050 Float_t den = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1);
1051 if(den==0) return 0;
1052 a = ((y3-y1)*(x2*x2+y2*y2-x1*x1-y1*y1)-(y2-y1)*(x3*x3+y3*y3-x1*x1-y1*y1))/den;
1053 b = -(x2*x2-x1*x1+y2*y2-y1*y1+a*(x2-x1))/(y2-y1);
1054 c = -x1*x1-y1*y1-a*x1-b*y1;
1057 //__________________________________________________________________________
1058 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){
1060 //Finds the intersection between the circonference of the track and the circonference centered in (0,0) represented by one layer
1061 //c2 is -rlayer*rlayer
1065 Double_t aA = (b1*b1)/(a1*a1)+1;
1066 Double_t bB = (-2*m*b1/(a1*a1));
1067 Double_t cC = c2+(m*m)/(a1*a1);
1068 Double_t dD = bB*bB-4*aA*cC;
1071 y1 = (-bB+TMath::Sqrt(dD))/(2*aA);
1072 y2 = (-bB-TMath::Sqrt(dD))/(2*aA);
1073 x1 = (c2-c1-b1*y1)/a1;
1074 x2 = (c2-c1-b1*y2)/a1;
1078 //____________________________________________________________________
1079 Double_t AliITStrackerSA::Curvature(Double_t x1,Double_t y1,Double_t
1080 x2,Double_t y2,Double_t x3,Double_t y3){
1082 //calculates the curvature of track
1083 Double_t den = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1);
1084 if(den==0) return 0;
1085 Double_t a = ((y3-y1)*(x2*x2+y2*y2-x1*x1-y1*y1)-(y2-y1)*(x3*x3+y3*y3-x1*x1-y1*y1))/den;
1086 Double_t b = -(x2*x2-x1*x1+y2*y2-y1*y1+a*(x2-x1))/(y2-y1);
1087 Double_t c = -x1*x1-y1*y1-a*x1-b*y1;
1090 if((a*a+b*b-4*c)<0) return 0;
1091 Double_t rad = TMath::Sqrt(a*a+b*b-4*c)/2.;
1092 if(rad==0) return 0;
1094 if((x1>0 && y1>0 && x1<xc)) rad*=-1;
1095 if((x1<0 && y1>0 && x1<xc)) rad*=-1;
1096 // if((x1<0 && y1<0 && x1<xc)) rad*=-1;
1097 // if((x1>0 && y1<0 && x1<xc)) rad*=-1;
1104 //____________________________________________________________________
1105 Double_t AliITStrackerSA::ChoosePoint(Double_t p1, Double_t p2, Double_t pp){
1107 //Returns the point closest to pp
1109 Double_t diff1 = p1-pp;
1110 Double_t diff2 = p2-pp;
1112 if(TMath::Abs(diff1)<TMath::Abs(diff2)) fPhiEstimate=p1;
1113 else fPhiEstimate=p2;
1114 return fPhiEstimate;
1119 //_________________________________________________________________
1120 Int_t AliITStrackerSA::FindTrackLowChiSquare() const {
1121 // returns track with lowest chi square
1122 Int_t dim=fListOfTracks->GetEntries();
1123 if(dim<=1) return 0;
1124 AliITStrackV2* trk = (AliITStrackV2*)fListOfTracks->At(0);
1125 Double_t minChi2=trk->GetChi2();
1127 for(Int_t i=1;i<dim;i++){
1128 trk = (AliITStrackV2*)fListOfTracks->At(i);
1129 Double_t chi2=trk->GetChi2();
1138 //__________________________________________________________
1139 Int_t AliITStrackerSA::FindLabel(Int_t l0, Int_t l1, Int_t l2, Int_t l3, Int_t l4, Int_t l5){
1141 //function used to determine the track label
1143 Int_t lb[6] = {l0,l1,l2,l3,l4,l5};
1144 Int_t aa[6]={1,1,1,1,1,1};
1147 Int_t k=0;Int_t w=0;Int_t num=6;
1148 for(Int_t i=5;i>=0;i--) if(lb[i]==-1) num=i;
1152 for(Int_t i=k+1;i<num;i++){
1154 if(lb[k]==lb[i] && aa[k]!=0){
1165 for(Int_t j=0;j<6;j++){
1178 if(num<1) return -1;
1182 //_____________________________________________________________________________
1183 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,
1184 Int_t gl12, Int_t gl13, Int_t gl14,Int_t gl15, Int_t gl16, Int_t gl17, Int_t gl18, Int_t minNPoints){
1187 //function used to assign label to the found track. If track is fake, the label is negative
1189 Int_t lb0[6] = {gl1,gl2,gl3,gl4,gl5,gl6};
1190 Int_t lb1[6] = {gl7,gl8,gl9,gl10,gl11,gl12};
1191 Int_t lb2[6] = {gl13,gl14,gl15,gl16,gl17,gl18};
1192 Int_t ll=FindLabel(lb0[0],lb0[1],lb0[2],lb0[3],lb0[4],lb0[5]);
1193 Int_t lflag=0;Int_t num=6;
1194 if(lb0[5]==-1 && lb1[5]==-1 && lb2[5]==-1) num=5;
1196 for(Int_t i=0;i<num;i++){
1197 if(lb0[i]==ll || lb1[i]==ll || lb2[i]==ll) lflag+=1;
1200 if(lflag>=minNPoints) return ll;
1205 //_____________________________________________________________________________
1206 void AliITStrackerSA::SetCalculatedWindowSizes(Int_t n, Float_t phimin, Float_t phimax, Float_t lambdamin, Float_t lambdamax){
1207 // Set sizes of the phi and lambda windows used for track finding
1209 if(fPhiWin) delete [] fPhiWin;
1210 if(fLambdaWin) delete [] fLambdaWin;
1211 fPhiWin = new Double_t[fNloop];
1212 fLambdaWin = new Double_t[fNloop];
1213 Float_t stepPhi=(phimax-phimin)/(Float_t)(fNloop-1);
1214 Float_t stepLambda=(lambdamax-lambdamin)/(Float_t)(fNloop-1);
1215 for(Int_t k=0;k<fNloop;k++){
1216 Float_t phi=phimin+k*stepPhi;
1217 Float_t lam=lambdamin+k*stepLambda;
1222 //_____________________________________________________________________________
1223 void AliITStrackerSA::SetFixedWindowSizes(Int_t n, Double_t *phi, Double_t *lam){
1224 // Set sizes of the phi and lambda windows used for track finding
1226 if(phi){ // user defined values
1227 fPhiWin = new Double_t[fNloop];
1228 fLambdaWin = new Double_t[fNloop];
1229 for(Int_t k=0;k<fNloop;k++){
1231 fLambdaWin[k]=lam[k];
1234 else { // default values
1236 Double_t phid[33] = {0.002,0.003,0.004,0.0045,0.0047,
1237 0.005,0.0053,0.0055,
1238 0.006,0.0063,0.0065,0.007,0.0073,0.0075,0.0077,
1239 0.008,0.0083,0.0085,0.0087,0.009,0.0095,0.0097,
1240 0.01,0.0105,0.011,0.0115,0.012,0.0125,0.013,0.0135,0.0140,0.0145};
1241 Double_t lambdad[33] = {0.003,0.004,0.005,0.005,0.005,
1243 0.006,0.006,0.006,0.007,0.007,0.007,0.007,
1244 0.007,0.007,0.007,0.007,0.007,0.007,0.007,
1245 0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008};
1252 fPhiWin = new Double_t[fNloop];
1253 fLambdaWin = new Double_t[fNloop];
1255 Double_t factor=AliITSReconstructor::GetRecoParam()->GetFactorSAWindowSizes(); // possibility to enlarge windows for cosmics reco with large misalignments (A.Dainese)
1257 for(Int_t k=0;k<fNloop;k++){
1258 fPhiWin[k]=phid[k]*factor;
1259 fLambdaWin[k]=lambdad[k]*factor;
1265 //_______________________________________________________________________
1266 void AliITStrackerSA::GetCoorAngles(AliITSRecPoint* cl,Double_t &phi,Double_t &lambda, Float_t &x, Float_t &y,Float_t &z,Double_t* vertex){
1267 //Returns values of phi (azimuthal) and lambda angles for a given cluster
1269 Double_t rot[9]; fGeom->GetRotMatrix(module,rot);
1270 Int_t lay,lad,det; fGeom->GetModuleId(module,lay,lad,det);
1271 Float_t tx,ty,tz; fGeom->GetTrans(lay,lad,det,tx,ty,tz);
1273 Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
1274 Double_t phi1=TMath::Pi()/2+alpha;
1275 if (lay==1) phi1+=TMath::Pi();
1277 Float_t cp=TMath::Cos(phi1), sp=TMath::Sin(phi1);
1278 Float_t r=tx*cp+ty*sp;
1280 xyz= r*cp - cl->GetY()*sp;
1281 y= r*sp + cl->GetY()*cp;
1285 cl->GetGlobalXYZ(xyz);
1290 phi=TMath::ATan2(y-vertex[1],x-vertex[0]);
1291 lambda=TMath::ATan2(z-vertex[2],TMath::Sqrt((x-vertex[0])*(x-vertex[0])+(y-vertex[1])*(y-vertex[1])));
1294 //________________________________________________________________________
1295 void AliITStrackerSA::GetCoorErrors(AliITSRecPoint* cl,Float_t &sx,Float_t &sy, Float_t &sz){
1297 //returns sigmax, y, z of cluster in global coordinates
1299 Double_t rot[9]; fGeom->GetRotMatrix(module,rot);
1301 AliITSgeomTGeo::GetModuleId(module,lay,lad,det);
1303 Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
1304 Double_t phi=TMath::Pi()/2+alpha;
1305 if (lay==1) phi+=TMath::Pi();
1307 Float_t cp=TMath::Cos(phi), sp=TMath::Sin(phi);
1310 cl->GetGlobalCov(covm);
1311 sx=TMath::Sqrt(covm[0]);
1312 sy=TMath::Sqrt(covm[3]);
1313 sz=TMath::Sqrt(covm[5]);
1315 sx = TMath::Sqrt(sp*sp*cl->GetSigmaY2());
1316 sy = TMath::Sqrt(cp*cp*cl->GetSigmaY2());
1317 sz = TMath::Sqrt(cl->GetSigmaZ2());