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();
318 if(AliITSReconstructor::GetRecoParam()->GetSAUseAllClusters()==kFALSE) {
320 AliESDtrack *track=event->GetTrack(nentr);
321 if (track->GetStatus()&AliESDtrack::kITSin==AliESDtrack::kITSin){
323 Int_t ncl = track->GetITSclusters(idx);
324 for(Int_t k=0;k<ncl;k++){
325 AliITSRecPoint* cll = (AliITSRecPoint*)GetCluster(idx[k]);
326 cll->SetBit(kSAflag);
332 Double_t primaryVertex[3];
333 event->GetVertex()->GetXYZ(primaryVertex);
334 //Creates TClonesArray with clusters for each layer. The clusters already used
335 //by AliITStrackerMI are not considered
336 Int_t nclusters[6]={0,0,0,0,0,0};
337 Int_t dmar[6]={0,0,0,0,0,0};
338 if (fCluLayer == 0) {
339 fCluLayer = new TClonesArray*[AliITSgeomTGeo::GetNLayers()];
340 fCluCoord = new TClonesArray*[AliITSgeomTGeo::GetNLayers()];
341 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
346 Int_t * firstmod = new Int_t[AliITSgeomTGeo::GetNLayers()];
347 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
348 firstmod[i]=AliITSgeomTGeo::GetModuleIndex(i+1,1,1);
349 AliITSlayer &layer=fgLayers[i];
350 if (!AliITSReconstructor::GetRecoParam()->GetLayersToSkip(i)) {
351 for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
352 AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
353 if(cls->TestBit(kSAflag)==kTRUE) continue; //clusters used by TPC prol.
354 if(cls->GetQ()==0) continue; //fake clusters dead zones
360 fCluLayer[i] = new TClonesArray("AliITSRecPoint",nclusters[i]);
362 fCluCoord[i] = new TClonesArray("AliITSclusterTable",nclusters[i]);
365 for(Int_t ilay=0;ilay<AliITSgeomTGeo::GetNLayers();ilay++){
366 TClonesArray &clulay = *fCluLayer[ilay];
367 TClonesArray &clucoo = *fCluCoord[ilay];
368 AliITSlayer &layer=fgLayers[ilay];
369 if (!AliITSReconstructor::GetRecoParam()->GetLayersToSkip(ilay)) {
370 for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
371 AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
372 if(cls->TestBit(kSAflag)==kTRUE) continue;
373 if(cls->GetQ()==0) continue;
374 Double_t phi=0;Double_t lambda=0;
375 Float_t x=0;Float_t y=0;Float_t z=0;
376 Float_t sx=0;Float_t sy=0;Float_t sz=0;
377 GetCoorAngles(cls,phi,lambda,x,y,z,primaryVertex);
378 GetCoorErrors(cls,sx,sy,sz);
379 new (clulay[dmar[ilay]]) AliITSRecPoint(*cls);
380 new (clucoo[dmar[ilay]]) AliITSclusterTable(x,y,z,sx,sy,sz,phi,lambda,cli);
386 Int_t minNPoints = (fSixPoints ? AliITSgeomTGeo::GetNLayers() : AliITSgeomTGeo::GetNLayers()-1);
387 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
388 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(i)) {
395 //loop on the different windows
396 Int_t * nn = new Int_t[AliITSgeomTGeo::GetNLayers()];//counter for clusters on each layer
397 for(Int_t nloop=0;nloop<fNloop;nloop++){
398 for(Int_t ncl=0;ncl<fCluLayer[0]->GetEntries();ncl++){ //loop starting from layer 0
403 AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[0]->At(ncl);
406 if (cl->GetQ()<=0) continue;
408 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(0,ncl);
409 fPhic = arr->GetPhi();
410 fLambdac = arr->GetLambda();
411 if (TMath::Abs(fLambdac)>0.26*TMath::Pi()) continue;
412 fPhiEstimate = fPhic;
413 AliITStrackSA* trs = new AliITStrackSA();
414 fPoint1[0]=primaryVertex[0];
415 fPoint1[1]=primaryVertex[1];
418 fPoint2[0]=arr->GetX();
419 fPoint2[1]=arr->GetY();
420 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){ nn[i]=0;}
421 nn[0] = SearchClusters(0,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
422 nn[1] = SearchClusters(1,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
425 fPoint3[0] = fPointc[0];
426 fPoint3[1] = fPointc[1];
428 nn[2] = SearchClusters(2,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
429 if(nn[1]==0 && nn[2]==0) pflag=0;
430 if(nn[2]!=0 && nn[1]!=0){ pflag=1; UpdatePoints();}
431 if(nn[2]!=0 && nn[1]==0){
433 fPoint3[0]=fPointc[0];
434 fPoint3[1]=fPointc[1];
437 nn[3] = SearchClusters(3,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
439 if(nn[3]!=0) UpdatePoints();
440 nn[4] = SearchClusters(4,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
442 if(nn[4]!=0) UpdatePoints();
443 nn[5] = SearchClusters(5,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
447 //check of the candidate track
448 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers();nnp++) {
449 if(nn[nnp]!=0) layOK+=1;
452 if(layOK>=minNPoints) {
453 AliITStrackV2* tr2 = 0;
454 tr2 = FitTrack(trs,primaryVertex);
457 AliESDtrack outtrack;
458 outtrack.UpdateTrackParams(tr2,AliESDtrack::kITSin);
459 event->AddTrack(&outtrack);
463 }//end loop on clusters of layer1
472 //if 5/6 points are required, second loop starting
473 //from second layer (SPD2), to find tracks with point of
476 //printf("looking from SPD2\n");
477 // counter for clusters on each layer
478 Int_t * nn = new Int_t[AliITSgeomTGeo::GetNLayers()-1];
479 for(Int_t nloop=0;nloop<fNloop;nloop++){
480 Int_t ncl2=fCluLayer[1]->GetEntries();
481 while(ncl2--){ //loop starting from layer 2
484 AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[1]->At(ncl2);
487 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(1,ncl2);
488 fPhic = arr->GetPhi();
489 fLambdac = arr->GetLambda();
490 fPhiEstimate = fPhic;
492 AliITStrackSA* trs = new AliITStrackSA();
493 fPoint1[0]=primaryVertex[0];
494 fPoint1[1]=primaryVertex[1];
496 fPoint2[0]=arr->GetX();
497 fPoint2[1]=arr->GetY();
498 for(Int_t kk=0;kk<AliITSgeomTGeo::GetNLayers()-1;kk++)nn[kk] = 0;
499 nn[0] = SearchClusters(1,fPhiWin[nloop],fLambdaWin[nloop],
500 trs,primaryVertex[2],pflag);
501 nn[1] = SearchClusters(2,fPhiWin[nloop],fLambdaWin[nloop],
502 trs,primaryVertex[2],pflag);
505 fPoint3[0]=fPointc[0];
506 fPoint3[1]=fPointc[1];
508 nn[2]= SearchClusters(3,fPhiWin[nloop],fLambdaWin[nloop],
509 trs,primaryVertex[2],pflag);
514 nn[3]= SearchClusters(4,fPhiWin[nloop],fLambdaWin[nloop],
515 trs,primaryVertex[2],pflag);
520 nn[4]=SearchClusters(5,fPhiWin[nloop],fLambdaWin[nloop],
521 trs,primaryVertex[2],pflag);
524 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-1;nnp++){
525 if(nn[nnp]!=0) layOK+=1;
527 if(layOK>=minNPoints){ // 5/6
528 AliITStrackV2* tr2 = 0;
529 tr2 = FitTrack(trs,primaryVertex);
532 AliESDtrack outtrack;
533 outtrack.UpdateTrackParams(tr2,AliESDtrack::kITSin);
534 event->AddTrack(&outtrack);
540 }//end loop on clusters of layer2
546 // search for tracks starting from SPD2, SDD1, SDD2, SSD2
547 // for cosmics (A. Dainese 31.07.07)
548 if(fOuterStartLayer>0) {
549 for(Int_t innLay=1; innLay<=fOuterStartLayer; innLay++) {
550 //printf("Searching from layer %d outward\n",innLay);
551 minNPoints=AliITSgeomTGeo::GetNLayers()-innLay;
552 for(Int_t i=innLay;i<AliITSgeomTGeo::GetNLayers();i++)
553 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(i))
555 // counter for clusters on each layer
556 Int_t * nn = new Int_t[AliITSgeomTGeo::GetNLayers()-innLay];
557 for(Int_t nloop=0;nloop<fNloop;nloop++){
558 Int_t nclInnLay=fCluLayer[innLay]->GetEntries();
559 while(nclInnLay--){ //loop starting from layer innLay
562 AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[innLay]->At(nclInnLay);
565 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(innLay,nclInnLay);
566 fPhic = arr->GetPhi();
567 fLambdac = arr->GetLambda();
568 fPhiEstimate = fPhic;
570 AliITStrackSA* trs = new AliITStrackSA();
571 fPoint1[0]=primaryVertex[0];
572 fPoint1[1]=primaryVertex[1];
573 fPoint2[0]=arr->GetX();
574 fPoint2[1]=arr->GetY();
577 for(kk=0;kk<AliITSgeomTGeo::GetNLayers()-innLay;kk++) nn[kk] = 0;
580 nn[kk] = SearchClusters(innLay,fPhiWin[nloop],fLambdaWin[nloop],
581 trs,primaryVertex[2],pflag);
582 for(Int_t nextLay=innLay+1; nextLay<AliITSgeomTGeo::GetNLayers(); nextLay++) {
584 nn[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
585 trs,primaryVertex[2],pflag);
589 fPoint3[0]=fPointc[0];
590 fPoint3[1]=fPointc[1];
598 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-innLay;nnp++){
599 if(nn[nnp]!=0) layOK+=1;
601 if(layOK>=minNPoints){
602 AliITStrackV2* tr2 = 0;
603 tr2 = FitTrack(trs,primaryVertex);
607 AliESDtrack outtrack;
608 outtrack.UpdateTrackParams(tr2,AliESDtrack::kITSin);
609 event->AddTrack(&outtrack);
615 }//end loop on clusters of innLay
616 } //end loop on window sizes
619 } //end loop on innLay
620 } //end if(fOuterStartLayer>0)
623 // search for 1-point tracks, only for cosmics
624 // (A.Dainese 21.03.08)
625 if(AliITSReconstructor::GetRecoParam()->GetSAOnePointTracks() &&
626 TMath::Abs(event->GetMagneticField())<0.01) {
627 for(Int_t innLay=0; innLay<=fOuterStartLayer; innLay++) {
628 // counter for clusters on each layer
629 Int_t * nn = new Int_t[AliITSgeomTGeo::GetNLayers()-innLay];
630 for(Int_t nloop=0;nloop<fNloop;nloop++){
631 Int_t nclInnLay=fCluLayer[innLay]->GetEntries();
632 while(nclInnLay--){ //loop starting from layer innLay
635 AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[innLay]->At(nclInnLay);
638 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(innLay,nclInnLay);
639 fPhic = arr->GetPhi();
640 fLambdac = arr->GetLambda();
641 fPhiEstimate = fPhic;
643 AliITStrackSA* trs = new AliITStrackSA();
644 fPoint1[0]=primaryVertex[0];
645 fPoint1[1]=primaryVertex[1];
646 fPoint2[0]=arr->GetX();
647 fPoint2[1]=arr->GetY();
650 for(kk=0;kk<AliITSgeomTGeo::GetNLayers()-innLay;kk++) nn[kk] = 0;
653 nn[kk] = SearchClusters(innLay,fPhiWin[nloop],fLambdaWin[nloop],
654 trs,primaryVertex[2],pflag);
655 for(Int_t nextLay=innLay+1; nextLay<AliITSgeomTGeo::GetNLayers(); nextLay++) {
657 nn[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
658 trs,primaryVertex[2],pflag);
662 fPoint3[0]=fPointc[0];
663 fPoint3[1]=fPointc[1];
671 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-innLay;nnp++){
672 if(nn[nnp]!=0) layOK+=1;
675 AliITStrackV2* tr2 = 0;
676 Bool_t onePoint = kTRUE;
677 tr2 = FitTrack(trs,primaryVertex,onePoint);
680 AliESDtrack outtrack;
681 outtrack.UpdateTrackParams(tr2,AliESDtrack::kITSin);
682 event->AddTrack(&outtrack);
688 }//end loop on clusters of innLay
689 } //end loop on window sizes
692 } //end loop on innLay
693 } // end search 1-point tracks
696 Info("FindTracks","Number of found tracks: %d",event->GetNumberOfTracks());
701 //________________________________________________________________________
703 AliITStrackV2* AliITStrackerSA::FitTrack(AliITStrackSA* tr,Double_t *primaryVertex,Bool_t onePoint) {
704 //fit of the found track (most general case, also <6 points, layers missing)
705 // A.Dainese 16.11.07
708 Int_t * firstmod = new Int_t[AliITSgeomTGeo::GetNLayers()];
709 TObjArray** listlayer = new TObjArray*[AliITSgeomTGeo::GetNLayers()];
710 Int_t ** clind=new Int_t*[AliITSgeomTGeo::GetNLayers()];
711 Int_t ** clmark=new Int_t*[AliITSgeomTGeo::GetNLayers()];
712 Int_t * nnn = new Int_t[AliITSgeomTGeo::GetNLayers()];
713 Int_t * kkk = new Int_t[AliITSgeomTGeo::GetNLayers()];
715 const Int_t maxclu=AliITStrackSA::GetMaxNumberOfClusters();
717 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
718 firstmod[i]=AliITSgeomTGeo::GetModuleIndex(i+1,1,1);
719 listlayer[i] = new TObjArray(0,0);
722 clind[i]=new Int_t[maxclu];
723 clmark[i]=new Int_t[maxclu];
724 for(Int_t j=0;j<maxclu; j++){
731 Int_t nclusters = tr->GetNumberOfClustersSA();
732 for(Int_t ncl=0;ncl<nclusters;ncl++){
733 Int_t index = tr->GetClusterIndexSA(ncl);
734 AliITSRecPoint* cl = (AliITSRecPoint*)GetCluster(index);
735 if(cl->TestBit(kSAflag)==kTRUE) cl->ResetBit(kSAflag);
736 Int_t lay = (index & 0xf0000000) >> 28;
737 listlayer[lay]->AddLast(cl);
739 clind[lay][ind]=index;
743 for(Int_t nlay=0;nlay<AliITSgeomTGeo::GetNLayers();nlay++){
744 for(Int_t ncl=0;ncl<tr->GetNumberOfMarked(nlay);ncl++){
745 Int_t mark = tr->GetClusterMark(nlay,ncl);
747 clmark[nlay][ind]=mark;
753 Int_t firstLay=-1,secondLay=-1;
754 Int_t * end = new Int_t[AliITSgeomTGeo::GetNLayers()];
755 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
756 if(listlayer[i]->GetEntries()==0) {
759 end[i]=listlayer[i]->GetEntries();
762 } else if(secondLay==-1) {
768 if(firstLay==-1 || (secondLay==-1 && !onePoint)) {
769 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
782 TClonesArray* listSA = new TClonesArray("AliITStrackSA");
783 TClonesArray &tri = *listSA;
786 for(Int_t l0=0;l0<end[0];l0++){ //loop on layer 1
787 AliITSRecPoint* cl0 = (AliITSRecPoint*)listlayer[0]->At(l0);
788 for(Int_t l1=0;l1<end[1];l1++){ //loop on layer 2
789 AliITSRecPoint* cl1 = (AliITSRecPoint*)listlayer[1]->At(l1);
790 for(Int_t l2=0;l2<end[2];l2++){ //loop on layer 3
791 AliITSRecPoint* cl2 = (AliITSRecPoint*)listlayer[2]->At(l2);
792 for(Int_t l3=0;l3<end[3];l3++){ //loop on layer 4
793 AliITSRecPoint* cl3 = (AliITSRecPoint*)listlayer[3]->At(l3);
794 for(Int_t l4=0;l4<end[4];l4++){ //loop on layer 5
795 AliITSRecPoint* cl4 = (AliITSRecPoint*)listlayer[4]->At(l4);
796 for(Int_t l5=0;l5<end[5];l5++){ //loop on layer 6
797 AliITSRecPoint* cl5 = (AliITSRecPoint*)listlayer[5]->At(l5);
800 Double_t x1,y1,z1,sx1,sy1,sz1;
801 Double_t x2,y2,z2,sx2,sy2,sz2;
802 AliITSRecPoint* p1=0;
803 AliITSRecPoint* p2=0;
804 Int_t index1=0,index2=0;
810 index1=clind[0][l0];mrk1=clmark[0][l0];
814 index1=clind[1][l1];mrk1=clmark[1][l1];
818 index1=clind[2][l2];mrk1=clmark[2][l2];
822 index1=clind[3][l3];mrk1=clmark[3][l3];
826 index1=clind[4][l4];mrk1=clmark[4][l4];
833 index2=clind[1][l1];mrk2=clmark[1][l1];
837 index2=clind[2][l2];mrk2=clmark[2][l2];
841 index2=clind[3][l3];mrk2=clmark[3][l3];
845 index2=clind[4][l4];mrk2=clmark[4][l4];
849 index2=clind[5][l5];mrk2=clmark[5][l5];
857 Int_t module1 = p1->GetDetectorIndex()+firstmod[firstLay];
858 Int_t layer,ladder,detector;
859 AliITSgeomTGeo::GetModuleId(module1,layer,ladder,detector);
860 Float_t yclu1 = p1->GetY();
861 Float_t zclu1 = p1->GetZ();
862 Double_t cv=0,tgl2=0,phi2=0;
865 AliITSclusterTable* arr1 = (AliITSclusterTable*)GetClusterCoord(firstLay,cln1);
875 AliITSclusterTable* arr2 = (AliITSclusterTable*)GetClusterCoord(secondLay,cln2);
882 cv = Curvature(primaryVertex[0],primaryVertex[1],x1,y1,x2,y2);
883 tgl2 = (z2-z1)/TMath::Sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
884 phi2 = TMath::ATan2((y2-y1),(x2-x1));
885 } else { // special case of 1-point tracks, only for cosmics (B=0)
886 x2 = primaryVertex[0];
887 y2 = primaryVertex[1];
888 z2 = primaryVertex[2];
890 tgl2 = (z1-z2)/TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
891 phi2 = TMath::ATan2((y1-y2),(x1-x2));
895 AliITStrackSA* trac = new AliITStrackSA(layer,ladder,detector,yclu1,zclu1,phi2,tgl2,cv,1);
899 trac->AddClusterV2(5,(clind[5][l5] & 0x0fffffff)>>0);
900 trac->AddClusterMark(5,clmark[5][l5]);
903 trac->AddClusterV2(4,(clind[4][l4] & 0x0fffffff)>>0);
904 trac->AddClusterMark(4,clmark[4][l4]);
907 trac->AddClusterV2(3,(clind[3][l3] & 0x0fffffff)>>0);
908 trac->AddClusterMark(3,clmark[3][l3]);
911 trac->AddClusterV2(2,(clind[2][l2] & 0x0fffffff)>>0);
912 trac->AddClusterMark(2,clmark[2][l2]);
915 trac->AddClusterV2(1,(clind[1][l1] & 0x0fffffff)>>0);
916 trac->AddClusterMark(1,clmark[1][l1]);
919 trac->AddClusterV2(0,(clind[0][l0] & 0x0fffffff)>>0);
920 trac->AddClusterMark(0,clmark[0][l0]);
923 //fit with Kalman filter using AliITStrackerMI::RefitAt()
924 AliITStrackMI* ot = new AliITStrackSA(*trac);
926 ot->ResetCovariance(10.);
929 if(RefitAt(AliITSRecoParam::GetrInsideITSscreen(),ot,trac)){ //fit from layer 1 to layer 6
930 AliITStrackMI *otrack2 = new AliITStrackMI(*ot);
931 otrack2->ResetCovariance(10.);
932 otrack2->ResetClusters();
933 //fit from layer 6 to layer 1
934 if(RefitAt(AliITSRecoParam::GetrInsideSPD1(),otrack2,ot)) {
935 fListOfTracks->AddLast(otrack2);
936 new (tri[nlist]) AliITStrackSA(*trac);
957 Int_t dim=fListOfTracks->GetEntries();
959 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
973 Int_t lowchi2 = FindTrackLowChiSquare(fListOfTracks,dim);
974 AliITStrackV2* otrack =(AliITStrackV2*)fListOfTracks->At(lowchi2);
975 AliITStrackSA* trsa = (AliITStrackSA*)listSA->At(lowchi2);
978 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
993 Int_t * indexc = new Int_t[AliITSgeomTGeo::GetNLayers()];
994 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) indexc[i]=0;
995 for(Int_t nind=0;nind<otrack->GetNumberOfClusters();nind++){
996 indexc[nind] = otrack->GetClusterIndex(nind);
999 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
1000 if(i<otrack->GetNumberOfClusters()) {
1001 AliITSRecPoint* cl = (AliITSRecPoint*)GetCluster(indexc[i]);
1002 labl[i][0]=cl->GetLabel(0);
1003 labl[i][1]=cl->GetLabel(1);
1004 labl[i][2]=cl->GetLabel(2);
1013 CookLabel(otrack,0.); //MI change - to see fake ratio
1015 Int_t label=FindLabel(labl[0][0],labl[1][0],labl[2][0],labl[3][0],labl[4][0],labl[5][0]);
1017 for(Int_t i=0;i<otrack->GetNumberOfClusters();i++)
1018 if(labl[i][0]==label || labl[i][1]==label || labl[i][2]==label) lflag++;
1020 if(lflag<otrack->GetNumberOfClusters()) label = -label;
1021 otrack->SetLabel(label);
1023 //remove clusters of found track
1024 for(Int_t nlay=0;nlay<AliITSgeomTGeo::GetNLayers();nlay++){
1025 for(Int_t cln=0;cln<trsa->GetNumberOfMarked(nlay);cln++){
1026 Int_t index = trsa->GetClusterMark(nlay,cln);
1027 fCluLayer[nlay]->RemoveAt(index);
1028 RemoveClusterCoord(nlay,index);
1029 fCluLayer[nlay]->Compress();
1035 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
1036 delete listlayer[i];
1040 delete [] listlayer;
1050 //_______________________________________________________
1051 Int_t AliITStrackerSA::SearchClusters(Int_t layer,Double_t phiwindow,Double_t lambdawindow, AliITStrackSA* trs,Double_t /*zvertex*/,Int_t pflag){
1052 //function used to to find the clusters associated to the track
1054 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(layer)) return 0;
1057 AliITSlayer &lay = fgLayers[layer];
1058 Double_t r=lay.GetR();
1060 Float_t cx1,cx2,cy1,cy2;
1061 FindEquation(fPoint1[0],fPoint1[1],fPoint2[0],fPoint2[1],fPoint3[0],fPoint3[1],fCoef1,fCoef2,fCoef3);
1062 if (FindIntersection(fCoef1,fCoef2,fCoef3,-r*r,cx1,cy1,cx2,cy2)==0)
1064 Double_t fi1=TMath::ATan2(cy1-fPoint1[1],cx1-fPoint1[0]);
1065 Double_t fi2=TMath::ATan2(cy2-fPoint1[1],cx2-fPoint1[0]);
1066 fPhiEstimate=ChoosePoint(fi1,fi2,fPhic);
1070 Int_t ncl = fCluLayer[layer]->GetEntries();
1071 for (Int_t index=0; index<ncl; index++) {
1072 AliITSRecPoint *c = (AliITSRecPoint*)fCluLayer[layer]->At(index);
1074 if (c->GetQ()<=0) continue;
1076 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(layer,index);
1077 Double_t phi = arr->GetPhi();
1078 if (TMath::Abs(phi-fPhiEstimate)>phiwindow) continue;
1080 Double_t lambda = arr->GetLambda();
1081 if (TMath::Abs(lambda-fLambdac)>lambdawindow) continue;
1083 if(trs->GetNumberOfClustersSA()==trs->GetMaxNumberOfClusters()) return 0;
1084 if(trs->GetNumberOfMarked(layer)==trs->GetMaxNMarkedPerLayer()) return 0;
1085 Int_t orind = arr->GetOrInd();
1086 trs->AddClusterSA(layer,orind);
1087 trs->AddClusterMark(layer,index);
1093 fPointc[0]=arr->GetX();
1094 fPointc[1]=arr->GetY();
1100 //________________________________________________________________
1101 void AliITStrackerSA::UpdatePoints(){
1102 //update of points for the estimation of the curvature
1104 fPoint2[0]=fPoint3[0];
1105 fPoint2[1]=fPoint3[1];
1106 fPoint3[0]=fPointc[0];
1107 fPoint3[1]=fPointc[1];
1112 //___________________________________________________________________
1113 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){
1115 //given (x,y) of three recpoints (in global coordinates)
1116 //returns the parameters a,b,c of circonference x*x + y*y +a*x + b*y +c
1118 Float_t den = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1);
1119 if(den==0) return 0;
1120 a = ((y3-y1)*(x2*x2+y2*y2-x1*x1-y1*y1)-(y2-y1)*(x3*x3+y3*y3-x1*x1-y1*y1))/den;
1121 b = -(x2*x2-x1*x1+y2*y2-y1*y1+a*(x2-x1))/(y2-y1);
1122 c = -x1*x1-y1*y1-a*x1-b*y1;
1125 //__________________________________________________________________________
1126 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){
1128 //Finds the intersection between the circonference of the track and the circonference centered in (0,0) represented by one layer
1129 //c2 is -rlayer*rlayer
1133 Double_t aA = (b1*b1)/(a1*a1)+1;
1134 Double_t bB = (-2*m*b1/(a1*a1));
1135 Double_t cC = c2+(m*m)/(a1*a1);
1136 Double_t dD = bB*bB-4*aA*cC;
1139 y1 = (-bB+TMath::Sqrt(dD))/(2*aA);
1140 y2 = (-bB-TMath::Sqrt(dD))/(2*aA);
1141 x1 = (c2-c1-b1*y1)/a1;
1142 x2 = (c2-c1-b1*y2)/a1;
1146 //____________________________________________________________________
1147 Double_t AliITStrackerSA::Curvature(Double_t x1,Double_t y1,Double_t
1148 x2,Double_t y2,Double_t x3,Double_t y3){
1150 //calculates the curvature of track
1151 Double_t den = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1);
1152 if(den==0) return 0;
1153 Double_t a = ((y3-y1)*(x2*x2+y2*y2-x1*x1-y1*y1)-(y2-y1)*(x3*x3+y3*y3-x1*x1-y1*y1))/den;
1154 Double_t b = -(x2*x2-x1*x1+y2*y2-y1*y1+a*(x2-x1))/(y2-y1);
1155 Double_t c = -x1*x1-y1*y1-a*x1-b*y1;
1158 if((a*a+b*b-4*c)<0) return 0;
1159 Double_t rad = TMath::Sqrt(a*a+b*b-4*c)/2.;
1160 if(rad==0) return 0;
1162 if((x1>0 && y1>0 && x1<xc)) rad*=-1;
1163 if((x1<0 && y1>0 && x1<xc)) rad*=-1;
1164 // if((x1<0 && y1<0 && x1<xc)) rad*=-1;
1165 // if((x1>0 && y1<0 && x1<xc)) rad*=-1;
1172 //____________________________________________________________________
1173 Double_t AliITStrackerSA::ChoosePoint(Double_t p1, Double_t p2, Double_t pp){
1175 //Returns the point closest to pp
1177 Double_t diff1 = p1-pp;
1178 Double_t diff2 = p2-pp;
1180 if(TMath::Abs(diff1)<TMath::Abs(diff2)) fPhiEstimate=p1;
1181 else fPhiEstimate=p2;
1182 return fPhiEstimate;
1187 //_________________________________________________________________
1188 Int_t AliITStrackerSA::FindTrackLowChiSquare(TObjArray* tracklist, Int_t dim) const {
1189 // returns track with lowers chi square
1191 //AliITStrackV2* trk = (AliITStrackV2*)tracklist->At(0);
1195 if(dim==0) return 0;
1196 Double_t * chi2 = new Double_t[dim];
1197 Int_t * index = new Int_t[dim];
1198 for(Int_t i=0;i<dim;i++){
1199 AliITStrackV2* trk = (AliITStrackV2*)tracklist->At(i);
1200 chi2[i]=trk->GetChi2();
1204 Int_t w=0;Double_t value;
1207 for(Int_t j=w+1;j<dim;j++){
1208 if(chi2[w]<chi2[j]){
1219 Int_t tmp = index[dim-1];
1225 //__________________________________________________________
1226 Int_t AliITStrackerSA::FindLabel(Int_t l0, Int_t l1, Int_t l2, Int_t l3, Int_t l4, Int_t l5){
1228 //function used to determine the track label
1230 Int_t lb[6] = {l0,l1,l2,l3,l4,l5};
1231 Int_t aa[6]={1,1,1,1,1,1};
1234 Int_t k=0;Int_t w=0;Int_t num=6;
1235 for(Int_t i=5;i>=0;i--) if(lb[i]==-1) num=i;
1239 for(Int_t i=k+1;i<num;i++){
1241 if(lb[k]==lb[i] && aa[k]!=0){
1252 for(Int_t j=0;j<6;j++){
1265 if(num<1) return -1;
1269 //_____________________________________________________________________________
1270 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,
1271 Int_t gl12, Int_t gl13, Int_t gl14,Int_t gl15, Int_t gl16, Int_t gl17, Int_t gl18, Int_t minNPoints){
1274 //function used to assign label to the found track. If track is fake, the label is negative
1276 Int_t lb0[6] = {gl1,gl2,gl3,gl4,gl5,gl6};
1277 Int_t lb1[6] = {gl7,gl8,gl9,gl10,gl11,gl12};
1278 Int_t lb2[6] = {gl13,gl14,gl15,gl16,gl17,gl18};
1279 Int_t ll=FindLabel(lb0[0],lb0[1],lb0[2],lb0[3],lb0[4],lb0[5]);
1280 Int_t lflag=0;Int_t num=6;
1281 if(lb0[5]==-1 && lb1[5]==-1 && lb2[5]==-1) num=5;
1283 for(Int_t i=0;i<num;i++){
1284 if(lb0[i]==ll || lb1[i]==ll || lb2[i]==ll) lflag+=1;
1287 if(lflag>=minNPoints) return ll;
1293 //_____________________________________________________________________________
1294 void AliITStrackerSA::SetWindowSizes(Int_t n, Double_t *phi, Double_t *lam){
1295 // Set sizes of the phi and lambda windows used for track finding
1297 if(phi){ // user defined values
1298 fPhiWin = new Double_t[fNloop];
1299 fLambdaWin = new Double_t[fNloop];
1300 for(Int_t k=0;k<fNloop;k++){
1302 fLambdaWin[k]=lam[k];
1305 else { // default values
1307 Double_t phid[33] = {0.002,0.003,0.004,0.0045,0.0047,
1308 0.005,0.0053,0.0055,
1309 0.006,0.0063,0.0065,0.007,0.0073,0.0075,0.0077,
1310 0.008,0.0083,0.0085,0.0087,0.009,0.0095,0.0097,
1311 0.01,0.0105,0.011,0.0115,0.012,0.0125,0.013,0.0135,0.0140,0.0145};
1312 Double_t lambdad[33] = {0.003,0.004,0.005,0.005,0.005,
1314 0.006,0.006,0.006,0.007,0.007,0.007,0.007,
1315 0.007,0.007,0.007,0.007,0.007,0.007,0.007,
1316 0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008};
1323 fPhiWin = new Double_t[fNloop];
1324 fLambdaWin = new Double_t[fNloop];
1326 Double_t factor=AliITSReconstructor::GetRecoParam()->GetFactorSAWindowSizes(); // possibility to enlarge windows for cosmics reco with large misalignments (A.Dainese)
1328 for(Int_t k=0;k<fNloop;k++){
1329 fPhiWin[k]=phid[k]*factor;
1330 fLambdaWin[k]=lambdad[k]*factor;
1336 //_______________________________________________________________________
1337 void AliITStrackerSA::GetCoorAngles(AliITSRecPoint* cl,Double_t &phi,Double_t &lambda, Float_t &x, Float_t &y,Float_t &z,Double_t* vertex){
1338 //Returns values of phi (azimuthal) and lambda angles for a given cluster
1340 Double_t rot[9]; fGeom->GetRotMatrix(module,rot);
1341 Int_t lay,lad,det; fGeom->GetModuleId(module,lay,lad,det);
1342 Float_t tx,ty,tz; fGeom->GetTrans(lay,lad,det,tx,ty,tz);
1344 Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
1345 Double_t phi1=TMath::Pi()/2+alpha;
1346 if (lay==1) phi1+=TMath::Pi();
1348 Float_t cp=TMath::Cos(phi1), sp=TMath::Sin(phi1);
1349 Float_t r=tx*cp+ty*sp;
1351 xyz= r*cp - cl->GetY()*sp;
1352 y= r*sp + cl->GetY()*cp;
1356 cl->GetGlobalXYZ(xyz);
1361 phi=TMath::ATan2(y-vertex[1],x-vertex[0]);
1362 lambda=TMath::ATan2(z-vertex[2],TMath::Sqrt((x-vertex[0])*(x-vertex[0])+(y-vertex[1])*(y-vertex[1])));
1365 //________________________________________________________________________
1366 void AliITStrackerSA::GetCoorErrors(AliITSRecPoint* cl,Float_t &sx,Float_t &sy, Float_t &sz){
1368 //returns sigmax, y, z of cluster in global coordinates
1370 Double_t rot[9]; fGeom->GetRotMatrix(module,rot);
1372 AliITSgeomTGeo::GetModuleId(module,lay,lad,det);
1374 Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
1375 Double_t phi=TMath::Pi()/2+alpha;
1376 if (lay==1) phi+=TMath::Pi();
1378 Float_t cp=TMath::Cos(phi), sp=TMath::Sin(phi);
1381 cl->GetGlobalCov(covm);
1382 sx=TMath::Sqrt(covm[0]);
1383 sy=TMath::Sqrt(covm[3]);
1384 sz=TMath::Sqrt(covm[5]);
1386 sx = TMath::Sqrt(sp*sp*cl->GetSigmaY2());
1387 sy = TMath::Sqrt(cp*cp*cl->GetSigmaY2());
1388 sz = TMath::Sqrt(cl->GetSigmaZ2());