3 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>, Uli Frankenfeld <mailto:franken@fi.uib.no>
4 //*-- Copyright © ASV
7 #include "AliL3RootTypes.h"
8 #include "AliL3Logging.h"
9 #include "AliL3Vertex.h"
10 #include "AliL3ConfMapPoint.h"
11 #include "AliL3ConfMapFit.h"
12 #include "AliL3ConfMapTrack.h"
13 #include "AliL3Transform.h"
16 //_____________________________________________________________
19 // Track class for conformal mapper
21 ClassImp(AliL3ConfMapTrack)
24 AliL3ConfMapTrack::AliL3ConfMapTrack()
33 AliL3ConfMapTrack::~AliL3ConfMapTrack()
38 void AliL3ConfMapTrack::DeleteCandidate()
40 //Deletes this track by resetting all its parameters. Does not delete
43 AliL3ConfMapPoint *curHit = (AliL3ConfMapPoint*)firstHit;
44 AliL3ConfMapPoint *nextHit;
48 nextHit = (AliL3ConfMapPoint*)curHit->nextTrackHit;
49 curHit->nextTrackHit = 0;
53 UInt_t *hit_numbers = GetHitNumbers();
54 for(Int_t i=0; i<GetNHits(); i++)
64 ComesFromMainVertex(false);
73 void AliL3ConfMapTrack::SetProperties(Bool_t usage)
75 //Set the hits to this track to 'usage'
77 for(StartLoop(); LoopDone(); GetNextHit())
79 AliL3ConfMapPoint *p = (AliL3ConfMapPoint*)currentHit;
85 void AliL3ConfMapTrack::Reset()
87 //Resets the fit parameters of this track.
109 void AliL3ConfMapTrack::UpdateParam(AliL3ConfMapPoint *thisHit)
111 //Function to update fit parameters of track
112 //Also, it updates the hit pointers.
115 //Increment the number of hits assigned to this track:
118 Int_t nhits = GetNHits();
120 SetNHits(nhits); //SetNHits(nhits++);
122 //Set the hit pointers:
127 ((AliL3ConfMapPoint*)lastHit)->nextTrackHit = thisHit;
131 s11Xy = s11Xy + thisHit->GetXYWeight() ;
132 s12Xy = s12Xy + thisHit->GetXYWeight() * thisHit->GetXprime() ;
133 s22Xy = s22Xy + thisHit->GetXYWeight() * pow((thisHit->GetXprime()),2) ;
134 g1Xy = g1Xy + thisHit->GetXYWeight() * thisHit->GetYprime() ;
135 g2Xy = g2Xy + thisHit->GetXYWeight() * thisHit->GetXprime() * thisHit->GetYprime() ;
137 ddXy = s11Xy * s22Xy - pow((s12Xy),2) ;
140 a1Xy = ( g1Xy * s22Xy - g2Xy * s12Xy ) / ddXy ;
141 a2Xy = ( g2Xy * s11Xy - g1Xy * s12Xy ) / ddXy ;
144 // Now in the sz plane
145 s11Sz = s11Sz + thisHit->GetZWeight() ;
146 s12Sz = s12Sz + thisHit->GetZWeight() * thisHit->GetS() ;
147 s22Sz = s22Sz + thisHit->GetZWeight() * thisHit->GetS() * thisHit->GetS() ;
148 g1Sz = g1Sz + thisHit->GetZWeight() * thisHit->GetZ() ;
149 g2Sz = g2Sz + thisHit->GetZWeight() * thisHit->GetS() * thisHit->GetZ() ;
152 ddSz = s11Sz * s22Sz - s12Sz * s12Sz ;
154 a1Sz = ( g1Sz * s22Sz - g2Sz * s12Sz ) / ddSz ;
155 a2Sz = ( g2Sz * s11Sz - g1Sz * s12Sz ) / ddSz ;
161 void AliL3ConfMapTrack::Fill(AliL3Vertex *vertex,Double_t max_Dca)
163 //Fill track variables with or without fit.
165 //fRadius = sqrt(a2Xy*a2Xy+1)/(2*fabs(a1Xy));
166 Double_t radius = sqrt(a2Xy*a2Xy+1)/(2*fabs(a1Xy));
169 //fPt = (Double_t)(BFACT * AliL3Transform::GetBField() * fRadius);
170 Double_t pt = (Double_t)(BFACT * AliL3Transform::GetBField() * GetRadius());
173 if(GetPt() > max_Dca) //go for fit of helix in real space
175 AliL3ConfMapFit *fit = new AliL3ConfMapFit(this,vertex);
177 UpdateToFirstPoint();
181 else if(GetPt() == 0)
182 LOG(AliL3Log::kError,"AliL3ConfMapTrack::Fill","Tracks")<<AliL3Log::kDec<<
183 "Found track with Pt=0!!!"<<ENDLOG;
186 LOG(AliL3Log::kError,"AliL3ConfMapTrack::Fill","Tracks")<<AliL3Log::kDec<<
187 "Track with pt<max_Dca :"<<GetPt()<<ENDLOG;
192 void AliL3ConfMapTrack::UpdateToFirstPoint()
194 //Update track parameters to the innermost point on the track.
195 //Basically it justs calculates the intersection of the track, and a cylinder
196 //with radius = r(innermost point). Then the parameters are updated to this point.
197 //Should be called after the helixfit (in FillTracks).
199 //AliL3ConfMapPoint *lHit = (AliL3ConfMapPoint*)fPoints->Last();
200 AliL3ConfMapPoint *lHit = (AliL3ConfMapPoint*)lastHit;
201 Double_t radius = sqrt(lHit->GetX()*lHit->GetX()+lHit->GetY()*lHit->GetY());
203 //Get the track parameters
205 Double_t tPhi0 = GetPsi() + GetCharge() * 0.5 * pi / fabs(GetCharge()) ;
206 Double_t x0 = GetR0() * cos(GetPhi0()) ;
207 Double_t y0 = GetR0() * sin(GetPhi0()) ;
208 Double_t rc = fabs(GetPt()) / ( BFACT * AliL3Transform::GetBField() ) ;
209 Double_t xc = x0 - rc * cos(tPhi0) ;
210 Double_t yc = y0 - rc * sin(tPhi0) ;
212 //Check helix and cylinder intersect
214 Double_t fac1 = xc*xc + yc*yc ;
215 Double_t sfac = sqrt( fac1 ) ;
217 if ( fabs(sfac-rc) > radius || fabs(sfac+rc) < radius ) {
218 LOG(AliL3Log::kError,"AliL3ConfMapTrack::UpdateToLastPoint","Tracks")<<AliL3Log::kDec<<
219 "Track does not intersect"<<ENDLOG;
225 Double_t fac2 = ( radius*radius + fac1 - rc*rc) / (2.00 * radius * sfac ) ;
226 Double_t phi = atan2(yc,xc) + GetCharge()*acos(fac2) ;
227 Double_t td = atan2(radius*sin(phi) - yc,radius*cos(phi) - xc) ;
231 if ( td < 0 ) td = td + 2. * pi ;
232 Double_t deltat = fmod((-GetCharge()*td + GetCharge()*tPhi0),2*pi) ;
233 if ( deltat < 0. ) deltat += 2. * pi ;
234 if ( deltat > 2.*pi ) deltat -= 2. * pi ;
235 Double_t z = GetZ0() + rc * GetTgl() * deltat ;
238 Double_t xExtra = radius * cos(phi) ;
239 Double_t yExtra = radius * sin(phi) ;
241 Double_t tPhi = atan2(yExtra-yc,xExtra-xc);
243 //if ( tPhi < 0 ) tPhi += 2. * M_PI ;
245 Double_t tPsi = tPhi - GetCharge() * 0.5 * pi / fabs(GetCharge()) ;
246 if ( tPsi > 2. * pi ) tPsi -= 2. * pi ;
247 if ( tPsi < 0. ) tPsi += 2. * pi ;
249 //And finally, update the track parameters
259 Int_t AliL3ConfMapTrack::GetMCLabel()
261 //For evaluation study.
262 //Returns the MCtrackID of the belonging clusters.
263 //If MCLabel < 0, means that track is fake.
267 Int_t num_of_clusters = GetNumberOfPoints();
268 S *s=new S[num_of_clusters];
270 for (i=0; i<num_of_clusters; i++) s[i].lab=s[i].max=0;
273 for (i=0; i<num_of_clusters; i++) {
274 AliL3ConfMapPoint *c=(AliL3ConfMapPoint*)fPoints->UncheckedAt(i);
275 lab=fabs(c->fMCTrackID[0]);
277 for (j=0; j<num_of_clusters; j++)
278 if (s[j].lab==lab || s[j].max==0) break;
284 for (i=0; i<num_of_clusters; i++)
285 if (s[i].max>max) {max=s[i].max; lab=s[i].lab;}
289 for (i=0; i<num_of_clusters; i++) {
290 AliL3ConfMapPoint *c=(AliL3ConfMapPoint*)fPoints->UncheckedAt(i);
291 if (fabs(c->fMCTrackID[1]) == lab ||
292 fabs(c->fMCTrackID[2]) == lab ) max++;
295 //check if more than 10% of the clusters are incorrectly assigned (fake track):
297 if (1.-Float_t(max)/num_of_clusters > 0.10)
301 Int_t tail=Int_t(0.08*174);
302 if (num_of_clusters < tail) return lab;
305 for (i=1; i<=tail; i++) {
306 AliL3ConfMapPoint *c = (AliL3ConfMapPoint*)fPoints->UncheckedAt(num_of_clusters-i);
307 if (lab == fabs(c->fMCTrackID[0]) ||
308 lab == fabs(c->fMCTrackID[1]) ||
309 lab == fabs(c->fMCTrackID[2])) max++;
311 if (max < Int_t(0.5*tail))
313 //printf("Wrong innermost clusters\n");