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 ITS tracker class //
20 // Origin: Elisabetta Crescio - crescio@to.infn.it //
21 // Updated: Francesco Prino - prino@to.infn.it //
22 ///////////////////////////////////////////////////////////
28 #include <TObjArray.h>
31 #include "AliESDEvent.h"
32 #include "AliESDVertex.h"
33 #include "AliESDtrack.h"
34 #include "AliITSVertexer.h"
35 #include "AliITSclusterTable.h"
36 #include "AliITSRecPoint.h"
37 #include "AliITSgeomTGeo.h"
38 #include "AliITStrackSA.h"
39 #include "AliITStrackerSA.h"
40 #include "AliITSReconstructor.h"
44 ClassImp(AliITStrackerSA)
46 //____________________________________________________________________________
47 AliITStrackerSA::AliITStrackerSA():AliITStrackerMI(),
70 // Default constructor
74 //____________________________________________________________________________
75 AliITStrackerSA::AliITStrackerSA(const Char_t *geom):AliITStrackerMI(0),
99 // Standard constructor (Vertex is known and passed to this obj.)
101 AliWarning("\"geom\" is actually a dummy argument !");
109 //____________________________________________________________________________
110 AliITStrackerSA::AliITStrackerSA(const Char_t *geom, AliESDVertex *vert):AliITStrackerMI(0),
134 // Standard constructor (Vertex is known and passed to this obj.)
136 AliWarning("\"geom\" is actually a dummy argument !");
142 //____________________________________________________________________________
143 AliITStrackerSA::AliITStrackerSA(const Char_t *geom, AliITSVertexer *vertexer):AliITStrackerMI(0),
167 // Standard constructor (Vertex is unknown - vertexer is passed to this obj)
169 AliWarning("\"geom\" is actually a dummy argument !");
172 fVertexer = vertexer;
176 //____________________________________________________________________________
177 AliITStrackerSA::AliITStrackerSA(const AliITStrackerSA& tracker):AliITStrackerMI(),
178 fPhiEstimate(tracker.fPhiEstimate),
179 fITSStandAlone(tracker.fITSStandAlone),
180 fLambdac(tracker.fLambdac),
181 fPhic(tracker.fPhic),
182 fCoef1(tracker.fCoef1),
183 fCoef2(tracker.fCoef2),
184 fCoef3(tracker.fCoef3),
185 fNloop(tracker.fNloop),
186 fPhiWin(tracker.fPhiWin),
187 fLambdaWin(tracker.fLambdaWin),
188 fVert(tracker.fVert),
189 fVertexer(tracker.fVertexer),
190 fListOfTracks(tracker.fListOfTracks),
191 fListOfSATracks(tracker.fListOfSATracks),
192 fITSclusters(tracker.fITSclusters),
193 fInwardFlag(tracker.fInwardFlag),
194 fOuterStartLayer(tracker.fOuterStartLayer),
195 fInnerStartLayer(tracker.fInnerStartLayer),
196 fMinNPoints(tracker.fMinNPoints),
197 fMinQ(tracker.fMinQ),
198 fCluLayer(tracker.fCluLayer),
199 fCluCoord(tracker.fCluCoord) {
201 for(Int_t i=0;i<2;i++){
202 fPoint1[i]=tracker.fPoint1[i];
203 fPoint2[i]=tracker.fPoint2[i];
204 fPoint3[i]=tracker.fPoint3[i];
205 fPointc[i]=tracker.fPointc[i];
207 if(tracker.fVertexer && tracker.fVert){
208 fVert = new AliESDVertex(*tracker.fVert);
211 fVert = tracker.fVert;
213 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
214 fCluLayer[i] = tracker.fCluLayer[i];
215 fCluCoord[i] = tracker.fCluCoord[i];
218 //______________________________________________________________________
219 AliITStrackerSA& AliITStrackerSA::operator=(const AliITStrackerSA& source){
220 // Assignment operator.
221 this->~AliITStrackerSA();
222 new(this) AliITStrackerSA(source);
227 //____________________________________________________________________________
228 AliITStrackerSA::~AliITStrackerSA(){
230 // if fVertexer is not null, the AliESDVertex obj. is owned by this class
231 // and is deleted here
233 if(fVert)delete fVert;
238 if(fPhiWin)delete []fPhiWin;
239 if(fLambdaWin)delete []fLambdaWin;
240 fListOfTracks->Delete();
241 delete fListOfTracks;
242 fListOfSATracks->Delete();
243 delete fListOfSATracks;
245 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
247 fCluLayer[i]->Delete();
254 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
256 fCluCoord[i]->Delete();
265 //____________________________________________________________________________
266 Int_t AliITStrackerSA::Clusters2Tracks(AliESDEvent *event){
267 // This method is used to find and fit the tracks. By default the corresponding
268 // method in the parent class is invoked. In this way a combined tracking
269 // TPC+ITS is performed. If the flag fITSStandAlone is true, the tracking
270 // is done in the ITS only. In the standard reconstruction chain this option
271 // can be set via AliReconstruction::SetOption("ITS","onlyITS")
274 rc=AliITStrackerMI::Clusters2Tracks(event);
277 AliDebug(1,"Stand Alone flag set: doing tracking in ITS alone\n");
280 rc=FindTracks(event,kFALSE);
281 if(AliITSReconstructor::GetRecoParam()->GetSAUseAllClusters()==kTRUE) {
282 rc=FindTracks(event,kTRUE);
289 //____________________________________________________________________________
290 void AliITStrackerSA::Init(){
291 // Reset all data members
293 for(Int_t i=0;i<3;i++){fPoint1[i]=0;fPoint2[i]=0;fPoint3[i]=0;}
303 Int_t nLoops=AliITSReconstructor::GetRecoParam()->GetNLoopsSA();
305 SetFixedWindowSizes();
307 Double_t phimin=AliITSReconstructor::GetRecoParam()->GetMinPhiSA();
308 Double_t phimax=AliITSReconstructor::GetRecoParam()->GetMaxPhiSA();
309 Double_t lambmin=AliITSReconstructor::GetRecoParam()->GetMinLambdaSA();
310 Double_t lambmax=AliITSReconstructor::GetRecoParam()->GetMaxLambdaSA();
311 SetCalculatedWindowSizes(nLoops,phimin,phimax,lambmin,lambmax);
313 fMinQ=AliITSReconstructor::GetRecoParam()->GetSAMinClusterCharge();
315 SetOuterStartLayer(1);
317 fListOfTracks=new TClonesArray("AliITStrackMI",100);
318 fListOfSATracks=new TClonesArray("AliITStrackSA",100);
323 //_______________________________________________________________________
324 void AliITStrackerSA::ResetForFinding(){
325 // Reset data members used in all loops during track finding
327 for(Int_t i=0;i<3;i++){fPoint1[i]=0;fPoint2[i]=0;fPoint3[i]=0;}
335 fListOfTracks->Clear();
336 fListOfSATracks->Clear();
341 //______________________________________________________________________
342 Int_t AliITStrackerSA::FindTracks(AliESDEvent* event, Bool_t useAllClusters){
344 // Track finder using the ESD object
346 AliDebug(2,Form(" field is %f",event->GetMagneticField()));
347 AliDebug(2,Form("SKIPPING %d %d %d %d %d %d",ForceSkippingOfLayer(0),ForceSkippingOfLayer(1),ForceSkippingOfLayer(2),ForceSkippingOfLayer(3),ForceSkippingOfLayer(4),ForceSkippingOfLayer(5)));
350 Fatal("FindTracks","ITS cluster tree is not accessed - Abort!!!\n Please use method SetClusterTree to pass the pointer to the tree\n");
353 //Reads event and mark clusters of traks already found, with flag kITSin
354 Int_t nentr=event->GetNumberOfTracks();
355 if(!useAllClusters) {
357 AliESDtrack *track=event->GetTrack(nentr);
358 if ((track->GetStatus()&AliESDtrack::kITSin) == AliESDtrack::kITSin){
360 Int_t ncl = track->GetITSclusters(idx);
361 for(Int_t k=0;k<ncl;k++){
362 AliITSRecPoint* cll = (AliITSRecPoint*)GetCluster(idx[k]);
363 cll->SetBit(kSAflag);
369 AliESDtrack *track=event->GetTrack(nentr);
370 if ((track->GetStatus()&AliESDtrack::kITSin) == AliESDtrack::kITSin){
372 Int_t ncl = track->GetITSclusters(idx);
373 for(Int_t k=0;k<ncl;k++){
374 AliITSRecPoint* cll = (AliITSRecPoint*)GetCluster(idx[k]);
375 cll->ResetBit(kSAflag);
381 Double_t primaryVertex[3];
382 event->GetVertex()->GetXYZ(primaryVertex);
383 //Creates TClonesArray with clusters for each layer. The clusters already used
384 //by AliITStrackerMI are not considered
385 Int_t nclusters[AliITSgeomTGeo::kNLayers]={0,0,0,0,0,0};
386 Int_t dmar[AliITSgeomTGeo::kNLayers]={0,0,0,0,0,0};
387 if (fCluLayer == 0) {
388 fCluLayer = new TClonesArray*[AliITSgeomTGeo::kNLayers];
389 fCluCoord = new TClonesArray*[AliITSgeomTGeo::kNLayers];
390 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
395 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
396 AliITSlayer &layer=fgLayers[i];
397 if (!ForceSkippingOfLayer(i)) {
398 for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
399 AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
400 if(cls->TestBit(kSAflag)==kTRUE) continue; //clusters used by TPC prol.
401 if(cls->GetQ()==0) continue; //fake clusters dead zones
402 if(i>1 && cls->GetQ()<=fMinQ) continue; // cut on SDD and SSD cluster charge
408 fCluLayer[i] = new TClonesArray("AliITSRecPoint",nclusters[i]);
410 fCluLayer[i]->Delete();
411 fCluLayer[i]->Expand(nclusters[i]);
414 fCluCoord[i] = new TClonesArray("AliITSclusterTable",nclusters[i]);
416 fCluCoord[i]->Delete();
417 fCluCoord[i]->Expand(nclusters[i]);
421 for(Int_t ilay=0;ilay<AliITSgeomTGeo::GetNLayers();ilay++){
422 TClonesArray &clulay = *fCluLayer[ilay];
423 TClonesArray &clucoo = *fCluCoord[ilay];
424 AliITSlayer &layer=fgLayers[ilay];
425 if (!ForceSkippingOfLayer(ilay)) {
426 for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
427 AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
428 if(cls->TestBit(kSAflag)==kTRUE) continue;
429 if(cls->GetQ()==0) continue;
430 if(ilay>1 && cls->GetQ()<=fMinQ) continue;
431 Double_t phi=0;Double_t lambda=0;
432 Float_t x=0;Float_t y=0;Float_t z=0;
433 Float_t sx=0;Float_t sy=0;Float_t sz=0;
434 GetCoorAngles(cls,phi,lambda,x,y,z,primaryVertex);
435 GetCoorErrors(cls,sx,sy,sz);
436 new (clulay[dmar[ilay]]) AliITSRecPoint(*cls);
437 new (clucoo[dmar[ilay]]) AliITSclusterTable(x,y,z,sx,sy,sz,phi,lambda,cli);
446 static Int_t nClusLay[AliITSgeomTGeo::kNLayers];//counter for clusters on each layer
447 Int_t startLayForSeed=0;
448 Int_t lastLayForSeed=fOuterStartLayer;
449 Int_t nSeedSteps=lastLayForSeed-startLayForSeed;
452 startLayForSeed=AliITSgeomTGeo::GetNLayers()-1;
453 lastLayForSeed=fInnerStartLayer;
454 nSeedSteps=startLayForSeed-lastLayForSeed;
458 // loop on minimum number of points
459 for(Int_t iMinNPoints=AliITSgeomTGeo::GetNLayers(); iMinNPoints>=fMinNPoints; iMinNPoints--) {
461 // loop on starting layer for track finding
462 for(Int_t iSeedLay=0; iSeedLay<=nSeedSteps; iSeedLay++) {
463 Int_t theLay=startLayForSeed+iSeedLay*seedStep;
464 if(ForceSkippingOfLayer(theLay)) continue;
465 Int_t minNPoints=iMinNPoints-theLay;
466 if(fInwardFlag) minNPoints=iMinNPoints-(AliITSgeomTGeo::GetNLayers()-1-theLay);
467 for(Int_t i=theLay+1;i<AliITSgeomTGeo::GetNLayers();i++)
468 if(ForceSkippingOfLayer(i))
470 if(minNPoints<fMinNPoints) continue;
472 // loop on phi and lambda window size
473 for(Int_t nloop=0;nloop<fNloop;nloop++){
474 Int_t nclTheLay=fCluLayer[theLay]->GetEntries();
477 Bool_t useRP=SetFirstPoint(theLay,nclTheLay,primaryVertex);
483 for(kk=0;kk<AliITSgeomTGeo::GetNLayers();kk++) nClusLay[kk] = 0;
486 nClusLay[kk] = SearchClusters(theLay,fPhiWin[nloop],fLambdaWin[nloop],
487 &trs,primaryVertex[2],pflag);
488 Int_t nextLay=theLay+seedStep;
492 nClusLay[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
493 &trs,primaryVertex[2],pflag);
497 fPoint3[0]=fPointc[0];
498 fPoint3[1]=fPointc[1];
504 if(nextLay<0 || nextLay==6) goon=kFALSE;
510 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-theLay;nnp++){
511 if(nClusLay[nnp]!=0) layOK+=1;
514 for(Int_t nnp=theLay; nnp>=0; nnp--){
515 if(nClusLay[nnp]!=0) layOK+=1;
518 if(layOK>=minNPoints){
519 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]));
520 AliITStrackV2* tr2 = 0;
521 tr2 = FitTrack(&trs,primaryVertex);
525 AliDebug(2,Form("---NPOINTS fit: %d\n",tr2->GetNumberOfClusters()));
527 StoreTrack(tr2,event,useAllClusters);
532 }//end loop on clusters of theLay
533 } //end loop on window sizes
534 } //end loop on theLay
535 }//end loop on min points
537 // search for 1-point tracks in SPD, only for cosmics
538 // (A.Dainese 21.03.08)
539 if(AliITSReconstructor::GetRecoParam()->GetSAOnePointTracks() &&
540 TMath::Abs(event->GetMagneticField())<0.01) {
541 Int_t outerLayer=1; // only SPD
542 for(Int_t innLay=0; innLay<=TMath::Min(1,fOuterStartLayer); innLay++) {
543 // counter for clusters on each layer
545 for(Int_t nloop=0;nloop<fNloop;nloop++){
546 Int_t nclInnLay=fCluLayer[innLay]->GetEntries();
547 while(nclInnLay--){ //loop starting from layer innLay
549 Bool_t useRP=SetFirstPoint(innLay,nclInnLay,primaryVertex);
555 for(kk=0;kk<AliITSgeomTGeo::GetNLayers();kk++) nClusLay[kk] = 0;
558 nClusLay[kk] = SearchClusters(innLay,fPhiWin[nloop],fLambdaWin[nloop],
559 &trs,primaryVertex[2],pflag);
560 for(Int_t nextLay=innLay+1; nextLay<=outerLayer; nextLay++) {
562 nClusLay[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
563 &trs,primaryVertex[2],pflag);
567 fPoint3[0]=fPointc[0];
568 fPoint3[1]=fPointc[1];
576 for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-innLay;nnp++){
577 if(nClusLay[nnp]!=0) layOK+=1;
580 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]));
581 AliITStrackV2* tr2 = 0;
582 Bool_t onePoint = kTRUE;
583 tr2 = FitTrack(&trs,primaryVertex,onePoint);
587 AliDebug(2,Form("----NPOINTS fit: %d\n",tr2->GetNumberOfClusters()));
589 StoreTrack(tr2,event,useAllClusters);
594 }//end loop on clusters of innLay
595 } //end loop on window sizes
597 } //end loop on innLay
598 } // end search 1-point tracks
600 if(!useAllClusters) AliInfo(Form("Number of found tracks: %d",event->GetNumberOfTracks()));
606 //________________________________________________________________________
608 AliITStrackV2* AliITStrackerSA::FitTrack(AliITStrackSA* tr,Double_t *primaryVertex,Bool_t onePoint) {
609 //fit of the found track (most general case, also <6 points, layers missing)
610 // A.Dainese 16.11.07
613 const Int_t kMaxClu=AliITStrackSA::kMaxNumberOfClusters;
615 static Int_t firstmod[AliITSgeomTGeo::kNLayers];
616 static Int_t clind[AliITSgeomTGeo::kNLayers][kMaxClu];
617 static Int_t clmark[AliITSgeomTGeo::kNLayers][kMaxClu];
618 static Int_t end[AliITSgeomTGeo::kNLayers];
619 static Int_t indices[AliITSgeomTGeo::kNLayers];
621 static AliITSRecPoint *listlayer[AliITSgeomTGeo::kNLayers][kMaxClu];
623 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
624 firstmod[i]=AliITSgeomTGeo::GetModuleIndex(i+1,1,1);
626 for(Int_t j=0;j<kMaxClu; j++){
634 Int_t nclusters = tr->GetNumberOfClustersSA();
635 for(Int_t ncl=0;ncl<nclusters;ncl++){
636 Int_t index = tr->GetClusterIndexSA(ncl);
637 AliITSRecPoint* cl = (AliITSRecPoint*)GetCluster(index);
638 Int_t lay = (index & 0xf0000000) >> 28;
639 Int_t nInLay=end[lay];
640 listlayer[lay][nInLay]=cl;
641 clind[lay][nInLay]=index;
645 for(Int_t nlay=0;nlay<AliITSgeomTGeo::GetNLayers();nlay++){
646 for(Int_t ncl=0;ncl<tr->GetNumberOfMarked(nlay);ncl++){
647 Int_t mark = tr->GetClusterMark(nlay,ncl);
648 clmark[nlay][ncl]=mark;
653 Int_t firstLay=-1,secondLay=-1;
654 for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
660 } else if(secondLay==-1) {
666 if(firstLay==-1 || (secondLay==-1 && !onePoint)) return 0;
667 TClonesArray &arrMI= *fListOfTracks;
668 TClonesArray &arrSA= *fListOfSATracks;
669 Int_t nFoundTracks=0;
672 for(Int_t l0=0;l0<end[0];l0++){ //loop on layer 1
674 for(Int_t l1=0;l1<end[1];l1++){ //loop on layer 2
676 for(Int_t l2=0;l2<end[2];l2++){ //loop on layer 3
678 for(Int_t l3=0;l3<end[3];l3++){ //loop on layer 4
680 for(Int_t l4=0;l4<end[4];l4++){ //loop on layer 5
682 for(Int_t l5=0;l5<end[5];l5++){ //loop on layer 6
685 // estimate curvature from 2 innermost points (or innermost point + vertex)
687 Int_t iFirstLay=indices[firstLay];
688 Int_t mrk1=clmark[firstLay][iFirstLay];
690 AliITSRecPoint* p1=(AliITSRecPoint*)listlayer[firstLay][iFirstLay];
691 Int_t module1 = p1->GetDetectorIndex()+firstmod[firstLay];
692 Int_t layer,ladder,detector;
693 AliITSgeomTGeo::GetModuleId(module1,layer,ladder,detector);
694 Float_t yclu1 = p1->GetY();
695 Float_t zclu1 = p1->GetZ();
699 Double_t cv=0,tgl2=0,phi2=0;
700 AliITSclusterTable* arr1 = (AliITSclusterTable*)GetClusterCoord(firstLay,mrk1);
706 Int_t iSecondLay=indices[secondLay];
707 Int_t mrk2=clmark[secondLay][iSecondLay];
708 AliITSclusterTable* arr2 = (AliITSclusterTable*)GetClusterCoord(secondLay,mrk2);
712 cv = Curvature(primaryVertex[0],primaryVertex[1],x1,y1,x2,y2);
713 tgl2 = (z2-z1)/TMath::Sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
714 phi2 = TMath::ATan2((y2-y1),(x2-x1));
715 } else { // special case of 1-point tracks, only for cosmics (B=0)
716 x2 = primaryVertex[0];
717 y2 = primaryVertex[1];
718 z2 = primaryVertex[2];
720 tgl2 = (z1-z2)/TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
721 phi2 = TMath::ATan2((y1-y2),(x1-x2));
724 // create track and attach it the RecPoints
725 AliITStrackSA trac(layer,ladder,detector,yclu1,zclu1,phi2,tgl2,cv,1);
726 for(Int_t iLay=5; iLay>=0; iLay--){
727 Int_t iInLay=indices[iLay];
728 AliITSRecPoint* cl=(AliITSRecPoint*)listlayer[iLay][iInLay];
730 trac.AddClusterV2(iLay,(clind[iLay][iInLay] & 0x0fffffff)>>0);
731 trac.AddClusterMark(iLay,clmark[iLay][iInLay]);
735 //fit with Kalman filter using AliITStrackerMI::RefitAt()
736 AliITStrackSA ot(trac);
738 ot.ResetCovariance(10.);
741 // Propagate inside the innermost layer with a cluster
742 if(ot.Propagate(ot.GetX()-0.1*ot.GetX())) {
744 if(RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&ot,&trac)){ //fit from layer 1 to layer 6
745 AliITStrackMI otrack2(ot);
746 otrack2.ResetCovariance(10.);
747 otrack2.ResetClusters();
748 //fit from layer 6 to layer 1
749 if(RefitAt(AliITSRecoParam::GetrInsideSPD1(),&otrack2,&ot)) {
750 new(arrMI[nFoundTracks]) AliITStrackMI(otrack2);
751 new(arrSA[nFoundTracks]) AliITStrackSA(trac);
767 if(fListOfTracks->GetEntries()==0) return 0;
769 Int_t lowchi2 = FindTrackLowChiSquare();
770 AliITStrackV2* otrack =(AliITStrackV2*)fListOfTracks->At(lowchi2);
771 AliITStrackSA* trsa = (AliITStrackSA*)fListOfSATracks->At(lowchi2);
773 if(otrack==0) return 0;
775 CookLabel(otrack,0.); //MI change - to see fake ratio
776 Int_t label=FindLabel(otrack);
777 otrack->SetLabel(label);
780 otrack->CookdEdx(low,up);
782 //remove clusters of found track
783 for(Int_t nlay=0;nlay<AliITSgeomTGeo::GetNLayers();nlay++){
784 for(Int_t cln=0;cln<trsa->GetNumberOfMarked(nlay);cln++){
785 Int_t index = trsa->GetClusterMark(nlay,cln);
786 fCluLayer[nlay]->RemoveAt(index);
787 RemoveClusterCoord(nlay,index);
788 fCluLayer[nlay]->Compress();
796 //_______________________________________________________
797 void AliITStrackerSA::StoreTrack(AliITStrackV2 *t,AliESDEvent *event, Bool_t pureSA) const
800 // Add new track to the ESD
802 AliESDtrack outtrack;
803 outtrack.UpdateTrackParams(t,AliESDtrack::kITSin);
804 if(pureSA) outtrack.SetStatus(AliESDtrack::kITSpureSA);
805 for(Int_t i=0;i<12;i++) {
806 outtrack.SetITSModuleIndex(i,t->GetModuleIndex(i));
808 Double_t sdedx[4]={0.,0.,0.,0.};
809 for(Int_t i=0; i<4; i++) sdedx[i]=t->GetSampledEdx(i);
810 outtrack.SetITSdEdxSamples(sdedx);
811 event->AddTrack(&outtrack);
817 //_______________________________________________________
818 Int_t AliITStrackerSA::SearchClusters(Int_t layer,Double_t phiwindow,Double_t lambdawindow, AliITStrackSA* trs,Double_t /*zvertex*/,Int_t pflag){
819 //function used to to find the clusters associated to the track
821 if(ForceSkippingOfLayer(layer)) return 0;
824 AliITSlayer &lay = fgLayers[layer];
825 Double_t r=lay.GetR();
827 Float_t cx1,cx2,cy1,cy2;
828 FindEquation(fPoint1[0],fPoint1[1],fPoint2[0],fPoint2[1],fPoint3[0],fPoint3[1],fCoef1,fCoef2,fCoef3);
829 if (FindIntersection(fCoef1,fCoef2,fCoef3,-r*r,cx1,cy1,cx2,cy2)==0)
831 Double_t fi1=TMath::ATan2(cy1-fPoint1[1],cx1-fPoint1[0]);
832 Double_t fi2=TMath::ATan2(cy2-fPoint1[1],cx2-fPoint1[0]);
833 fPhiEstimate=ChoosePoint(fi1,fi2,fPhic);
837 Int_t ncl = fCluLayer[layer]->GetEntries();
838 for (Int_t index=0; index<ncl; index++) {
839 AliITSRecPoint *c = (AliITSRecPoint*)fCluLayer[layer]->At(index);
841 if (c->GetQ()<=0) continue;
842 if(layer>1 && c->GetQ()<=fMinQ) continue;
844 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(layer,index);
845 Double_t phi = arr->GetPhi();
846 if (TMath::Abs(phi-fPhiEstimate)>phiwindow) continue;
848 Double_t lambda = arr->GetLambda();
849 if (TMath::Abs(lambda-fLambdac)>lambdawindow) continue;
851 if(trs->GetNumberOfClustersSA()==trs->GetMaxNumberOfClusters()) return 0;
852 if(trs->GetNumberOfMarked(layer)==trs->GetMaxNMarkedPerLayer()) return 0;
853 Int_t orind = arr->GetOrInd();
854 trs->AddClusterSA(layer,orind);
855 trs->AddClusterMark(layer,index);
860 fPointc[0]=arr->GetX();
861 fPointc[1]=arr->GetY();
867 //________________________________________________________________
868 Bool_t AliITStrackerSA::SetFirstPoint(Int_t lay, Int_t clu, Double_t* primaryVertex){
869 // Sets the first point (seed) for tracking
871 AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[lay]->At(clu);
872 if(!cl) return kFALSE;
873 if (cl->GetQ()<=0) return kFALSE;
874 if(lay>1 && cl->GetQ()<=fMinQ) return kFALSE;
876 AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(lay,clu);
877 fPhic = arr->GetPhi();
878 fLambdac = arr->GetLambda();
879 fPhiEstimate = fPhic;
880 fPoint1[0]=primaryVertex[0];
881 fPoint1[1]=primaryVertex[1];
882 fPoint2[0]=arr->GetX();
883 fPoint2[1]=arr->GetY();
887 //________________________________________________________________
888 void AliITStrackerSA::UpdatePoints(){
889 //update of points for the estimation of the curvature
891 fPoint2[0]=fPoint3[0];
892 fPoint2[1]=fPoint3[1];
893 fPoint3[0]=fPointc[0];
894 fPoint3[1]=fPointc[1];
899 //___________________________________________________________________
900 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){
902 //given (x,y) of three recpoints (in global coordinates)
903 //returns the parameters a,b,c of circonference x*x + y*y +a*x + b*y +c
905 Float_t den = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1);
907 a = ((y3-y1)*(x2*x2+y2*y2-x1*x1-y1*y1)-(y2-y1)*(x3*x3+y3*y3-x1*x1-y1*y1))/den;
908 b = -(x2*x2-x1*x1+y2*y2-y1*y1+a*(x2-x1))/(y2-y1);
909 c = -x1*x1-y1*y1-a*x1-b*y1;
912 //__________________________________________________________________________
913 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){
915 //Finds the intersection between the circonference of the track and the circonference centered in (0,0) represented by one layer
916 //c2 is -rlayer*rlayer
920 Double_t aA = (b1*b1)/(a1*a1)+1;
921 Double_t bB = (-2*m*b1/(a1*a1));
922 Double_t cC = c2+(m*m)/(a1*a1);
923 Double_t dD = bB*bB-4*aA*cC;
926 y1 = (-bB+TMath::Sqrt(dD))/(2*aA);
927 y2 = (-bB-TMath::Sqrt(dD))/(2*aA);
928 x1 = (c2-c1-b1*y1)/a1;
929 x2 = (c2-c1-b1*y2)/a1;
933 //____________________________________________________________________
934 Double_t AliITStrackerSA::Curvature(Double_t x1,Double_t y1,Double_t
935 x2,Double_t y2,Double_t x3,Double_t y3){
937 //calculates the curvature of track
938 Double_t den = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1);
940 Double_t a = ((y3-y1)*(x2*x2+y2*y2-x1*x1-y1*y1)-(y2-y1)*(x3*x3+y3*y3-x1*x1-y1*y1))/den;
941 Double_t b = -(x2*x2-x1*x1+y2*y2-y1*y1+a*(x2-x1))/(y2-y1);
942 Double_t c = -x1*x1-y1*y1-a*x1-b*y1;
945 if((a*a+b*b-4*c)<0) return 0;
946 Double_t rad = TMath::Sqrt(a*a+b*b-4*c)/2.;
949 if((x1>0 && y1>0 && x1<xc)) rad*=-1;
950 if((x1<0 && y1>0 && x1<xc)) rad*=-1;
951 // if((x1<0 && y1<0 && x1<xc)) rad*=-1;
952 // if((x1>0 && y1<0 && x1<xc)) rad*=-1;
959 //____________________________________________________________________
960 Double_t AliITStrackerSA::ChoosePoint(Double_t p1, Double_t p2, Double_t pp){
962 //Returns the point closest to pp
964 Double_t diff1 = p1-pp;
965 Double_t diff2 = p2-pp;
967 if(TMath::Abs(diff1)<TMath::Abs(diff2)) fPhiEstimate=p1;
968 else fPhiEstimate=p2;
974 //_________________________________________________________________
975 Int_t AliITStrackerSA::FindTrackLowChiSquare() const {
976 // returns track with lowest chi square
977 Int_t dim=fListOfTracks->GetEntries();
979 AliITStrackV2* trk = (AliITStrackV2*)fListOfTracks->At(0);
980 Double_t minChi2=trk->GetChi2();
982 for(Int_t i=1;i<dim;i++){
983 trk = (AliITStrackV2*)fListOfTracks->At(i);
984 Double_t chi2=trk->GetChi2();
993 //__________________________________________________________
994 Int_t AliITStrackerSA::FindLabel(AliITStrackV2* track){
997 Int_t labl[AliITSgeomTGeo::kNLayers][3];
998 Int_t cnts[AliITSgeomTGeo::kNLayers][3];
999 for(Int_t j=0;j<AliITSgeomTGeo::GetNLayers();j++){
1000 for(Int_t k=0;k<3;k++){
1006 for(Int_t i=0;i<track->GetNumberOfClusters(); i++) {
1007 Int_t indexc = track->GetClusterIndex(i);
1008 AliITSRecPoint* cl = (AliITSRecPoint*)GetCluster(indexc);
1009 Int_t iLayer=cl->GetLayer();
1010 for(Int_t k=0;k<3;k++){
1011 labl[iLayer][k]=cl->GetLabel(k);
1012 if(labl[iLayer][k]<0) iNotLabel++;
1015 if(iNotLabel==3*track->GetNumberOfClusters()) return -2;
1017 for(Int_t j1=0;j1<AliITSgeomTGeo::kNLayers; j1++) {
1018 for(Int_t j2=0; j2<j1; j2++){
1019 for(Int_t k1=0; k1<3; k1++){
1020 for(Int_t k2=0; k2<3; k2++){
1021 if(labl[j1][k1]>=0 && labl[j1][k1]==labl[j2][k2] && cnts[j2][k2]>0){
1033 for(Int_t j=0;j<AliITSgeomTGeo::kNLayers;j++){
1034 for(Int_t k=0;k<3;k++){
1035 if(cnts[j][k]>cntMax && labl[j][k]>=0){
1043 for(Int_t i=0;i<AliITSgeomTGeo::kNLayers;i++)
1044 if(labl[i][0]==label || labl[i][1]==label || labl[i][2]==label) lflag++;
1046 if(lflag<track->GetNumberOfClusters()) label = -label;
1049 //_____________________________________________________________________________
1050 void AliITStrackerSA::SetCalculatedWindowSizes(Int_t n, Float_t phimin, Float_t phimax, Float_t lambdamin, Float_t lambdamax){
1051 // Set sizes of the phi and lambda windows used for track finding
1053 if(fPhiWin) delete [] fPhiWin;
1054 if(fLambdaWin) delete [] fLambdaWin;
1055 fPhiWin = new Double_t[fNloop];
1056 fLambdaWin = new Double_t[fNloop];
1057 Float_t stepPhi=(phimax-phimin)/(Float_t)(fNloop-1);
1058 Float_t stepLambda=(lambdamax-lambdamin)/(Float_t)(fNloop-1);
1059 for(Int_t k=0;k<fNloop;k++){
1060 Float_t phi=phimin+k*stepPhi;
1061 Float_t lam=lambdamin+k*stepLambda;
1066 //_____________________________________________________________________________
1067 void AliITStrackerSA::SetFixedWindowSizes(Int_t n, Double_t *phi, Double_t *lam){
1068 // Set sizes of the phi and lambda windows used for track finding
1070 if(phi){ // user defined values
1071 fPhiWin = new Double_t[fNloop];
1072 fLambdaWin = new Double_t[fNloop];
1073 for(Int_t k=0;k<fNloop;k++){
1075 fLambdaWin[k]=lam[k];
1078 else { // default values
1080 Double_t phid[33] = {0.002,0.003,0.004,0.0045,0.0047,
1081 0.005,0.0053,0.0055,
1082 0.006,0.0063,0.0065,0.007,0.0073,0.0075,0.0077,
1083 0.008,0.0083,0.0085,0.0087,0.009,0.0095,0.0097,
1084 0.01,0.0105,0.011,0.0115,0.012,0.0125,0.013,0.0135,0.0140,0.0145};
1085 Double_t lambdad[33] = {0.003,0.004,0.005,0.005,0.005,
1087 0.006,0.006,0.006,0.007,0.007,0.007,0.007,
1088 0.007,0.007,0.007,0.007,0.007,0.007,0.007,
1089 0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008};
1096 fPhiWin = new Double_t[fNloop];
1097 fLambdaWin = new Double_t[fNloop];
1099 Double_t factor=AliITSReconstructor::GetRecoParam()->GetFactorSAWindowSizes(); // possibility to enlarge windows for cosmics reco with large misalignments (A.Dainese)
1101 for(Int_t k=0;k<fNloop;k++){
1102 fPhiWin[k]=phid[k]*factor;
1103 fLambdaWin[k]=lambdad[k]*factor;
1109 //_______________________________________________________________________
1110 void AliITStrackerSA::GetCoorAngles(AliITSRecPoint* cl,Double_t &phi,Double_t &lambda, Float_t &x, Float_t &y,Float_t &z,Double_t* vertex){
1111 //Returns values of phi (azimuthal) and lambda angles for a given cluster
1113 Double_t rot[9]; fGeom->GetRotMatrix(module,rot);
1114 Int_t lay,lad,det; fGeom->GetModuleId(module,lay,lad,det);
1115 Float_t tx,ty,tz; fGeom->GetTrans(lay,lad,det,tx,ty,tz);
1117 Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
1118 Double_t phi1=TMath::Pi()/2+alpha;
1119 if (lay==1) phi1+=TMath::Pi();
1121 Float_t cp=TMath::Cos(phi1), sp=TMath::Sin(phi1);
1122 Float_t r=tx*cp+ty*sp;
1124 xyz= r*cp - cl->GetY()*sp;
1125 y= r*sp + cl->GetY()*cp;
1129 cl->GetGlobalXYZ(xyz);
1134 phi=TMath::ATan2(y-vertex[1],x-vertex[0]);
1135 lambda=TMath::ATan2(z-vertex[2],TMath::Sqrt((x-vertex[0])*(x-vertex[0])+(y-vertex[1])*(y-vertex[1])));
1138 //________________________________________________________________________
1139 void AliITStrackerSA::GetCoorErrors(AliITSRecPoint* cl,Float_t &sx,Float_t &sy, Float_t &sz){
1141 //returns sigmax, y, z of cluster in global coordinates
1143 Double_t rot[9]; fGeom->GetRotMatrix(module,rot);
1145 AliITSgeomTGeo::GetModuleId(module,lay,lad,det);
1147 Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
1148 Double_t phi=TMath::Pi()/2+alpha;
1149 if (lay==1) phi+=TMath::Pi();
1151 Float_t cp=TMath::Cos(phi), sp=TMath::Sin(phi);
1154 cl->GetGlobalCov(covm);
1155 sx=TMath::Sqrt(covm[0]);
1156 sy=TMath::Sqrt(covm[3]);
1157 sz=TMath::Sqrt(covm[5]);
1159 sx = TMath::Sqrt(sp*sp*cl->GetSigmaY2());
1160 sy = TMath::Sqrt(cp*cp*cl->GetSigmaY2());
1161 sz = TMath::Sqrt(cl->GetSigmaZ2());