3 // Author: Anders Vestbo <mailto:vestbo$fi.uib.no>
4 //*-- Copyright © ASV
6 #include "AliL3StandardIncludes.h"
8 #include "AliL3Logging.h"
9 #include "AliL3ModelTrack.h"
10 #include "AliL3Transform.h"
16 //_____________________________________________________________
21 ClassImp(AliL3ModelTrack)
23 AliL3ModelTrack::AliL3ModelTrack()
36 AliL3ModelTrack::~AliL3ModelTrack()
50 void AliL3ModelTrack::Init(Int_t slice,Int_t patch)
55 Int_t nrows = AliL3Transform::GetNRows(fPatch);
56 fClusters = new AliL3ClusterModel[nrows];
57 fPad = new Float_t[nrows];
58 fTime = new Float_t[nrows];
59 fTrackModel = new AliL3TrackModel;
60 fOverlap = new Int_t[nrows];
62 memset(fClusters,0,nrows*sizeof(AliL3ClusterModel));
63 memset(fPad,0,nrows*sizeof(Float_t));
64 memset(fTime,0,nrows*sizeof(Float_t));
65 memset(fTrackModel,0,sizeof(AliL3TrackModel));
66 for(Int_t i=0; i<nrows; i++)
69 for(Int_t i=0; i<nrows; i++)
70 fClusters[i].fTrackID[0]=fClusters[i].fTrackID[1]=fClusters[i].fTrackID[2]=-2;
75 fXYResidualQ = 0.01/AliL3Transform::GetPadPitchWidth(patch);
76 fZResidualQ = 0.01/AliL3Transform::GetPadPitchWidth(patch);
78 fXYWidthQ = 0.005/AliL3Transform::GetPadPitchWidth(patch);
79 fZWidthQ = 0.005/AliL3Transform::GetPadPitchWidth(patch);
83 void AliL3ModelTrack::SetCluster(Int_t row,Float_t fpad,Float_t ftime,Float_t charge,Float_t sigmaY2,Float_t sigmaZ2,Int_t npads)
85 Int_t index = row - AliL3Transform::GetFirstRow(fPatch);
86 if(index != fNClusters)
87 cout<<"AliL3ModelTrack::SetCluster() : Mismatch ; index: "<<index<<" nclusters "<<fNClusters<<endl;
89 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
91 cerr<<"AliL3ModelTrack::SetCluster() : Wrong index: "<<index<<" row "<<row<<endl;
94 AliL3ClusterModel *cl = GetClusterModel(row);
96 cl->fPresent = kFALSE;
100 cl->fDTime = (ftime - GetTimeHit(row))/fXYResidualQ;
101 cl->fDPad = (fpad - GetPadHit(row))/fZResidualQ;
102 cl->fDCharge = charge - fClusterCharge;
103 cl->fDSigmaY2 = (sigmaY2 - GetParSigmaY2(row))/fXYWidthQ;
104 cl->fDSigmaZ2 = (sigmaZ2 - GetParSigmaZ2(row))/fZWidthQ;
111 Int_t AliL3ModelTrack::CheckClustersQuality(UInt_t npads)
114 //Check the quality of clusters,- remove clusters with less than
116 //Returns the number of good clusters left.
120 for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
122 AliL3ClusterModel *cl = GetClusterModel(i);
123 if(cl->fNPads < npads)
124 cl->fPresent = kFALSE;
132 void AliL3ModelTrack::FillModel()
134 //Fill the track structure
138 cerr<<"AliL3ModelTrack::FillModel() : No trackmodel "<<endl;
141 fTrackModel->fKappa = GetKappa();
142 fTrackModel->fFirstPointX = GetFirstPointX();
143 fTrackModel->fFirstPointY = GetFirstPointY();
144 fTrackModel->fFirstPointZ = GetFirstPointZ();
145 fTrackModel->fTgl = GetTgl();
146 fTrackModel->fPsi = GetPsi();
147 fTrackModel->fLength = (Short_t)GetLength();
148 fTrackModel->fClusterCharge = fClusterCharge;
149 fTrackModel->fNClusters = fNClusters;
153 void AliL3ModelTrack::FillTrack()
155 //Fill the track parameters from the structure.
159 cerr<<"AliL3ModelTrack::FillTrack() : No data!!"<<endl;
162 SetKappa(fTrackModel->fKappa);
163 SetCharge((-1*(Int_t)copysign(1.,GetKappa())));
164 SetFirstPoint(fTrackModel->fFirstPointX,fTrackModel->fFirstPointY,fTrackModel->fFirstPointZ);
165 SetTgl(fTrackModel->fTgl);
166 SetPsi(fTrackModel->fPsi);
167 SetLength(fTrackModel->fLength);
168 fClusterCharge=fTrackModel->fClusterCharge;
169 fNClusters = fTrackModel->fNClusters;
170 SetPt((BFACT*AliL3Transform::GetBField())/fabs(GetKappa()));
176 for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
178 AliL3ClusterModel *cl = GetClusterModel(i);
180 GetCrossingPoint(i,hit);
181 AliL3Transform::Slice2Sector(fSlice,i,sector,row);
182 AliL3Transform::Local2Raw(hit,sector,row);
184 SetTimeHit(i,hit[2]);
189 void AliL3ModelTrack::SetTrackID(Int_t row,Int_t *trackID)
192 AliL3ClusterModel *cluster = GetClusterModel(row);
193 cluster->fTrackID[0] = trackID[0];
194 cluster->fTrackID[1] = trackID[1];
195 cluster->fTrackID[2] = trackID[2];
198 cerr<<"AliL3ModelTrack::SetTrackID : Compile with do_mc flag"<<endl;
202 void AliL3ModelTrack::SetPadHit(Int_t row,Float_t pad)
204 Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
205 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
207 cerr<<"AliL3ModelTrack::SetPadHit() : Wrong index: "<<index<<endl;
214 void AliL3ModelTrack::SetTimeHit(Int_t row,Float_t time)
216 Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
217 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
219 cerr<<"AliL3ModelTrack::SetTimeHit() : Wrong index: "<<index<<endl;
225 void AliL3ModelTrack::SetOverlap(Int_t row,Int_t id)
227 Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
228 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
230 cerr<<"AliL3ModelTrack::SetOverlap() : Wrong index: "<<index<<endl;
237 Int_t AliL3ModelTrack::GetTrackID(Int_t row,Int_t index)
241 AliL3ClusterModel *cl = GetClusterModel(row);
242 return cl->fTrackID[index];
244 cerr<<"AliL3ModelTrack::GetTrackID : Compile with do_mc flag"<<endl;
248 Int_t AliL3ModelTrack::GetNPads(Int_t row)
250 AliL3ClusterModel *cl = GetClusterModel(row);
254 Bool_t AliL3ModelTrack::GetPad(Int_t row,Float_t &pad)
256 //(ftime - GetTimeHit(fNClusters))/fXYResidualQ;
257 //(fpad - GetPadHit(fNClusters))/fZResidualQ;
259 AliL3ClusterModel *cl = GetClusterModel(row);
260 pad = cl->fDPad*fXYResidualQ + GetPadHit(row);
262 return (Bool_t)cl->fPresent;
265 Bool_t AliL3ModelTrack::GetTime(Int_t row,Float_t &time)
267 AliL3ClusterModel *cl = GetClusterModel(row);
268 time = cl->fDTime*fZResidualQ + GetTimeHit(row);
270 return (Bool_t)cl->fPresent;
273 Bool_t AliL3ModelTrack::GetClusterCharge(Int_t row,Int_t &charge)
275 AliL3ClusterModel *cl = GetClusterModel(row);
276 charge = (Int_t)cl->fDCharge + fClusterCharge;
278 return (Bool_t)cl->fPresent;
281 Bool_t AliL3ModelTrack::GetXYWidth(Int_t row,Float_t &width)
283 AliL3ClusterModel *cl = GetClusterModel(row);
284 width = cl->fDSigmaY2*fXYWidthQ + GetParSigmaY2(row);
286 return (Bool_t)cl->fPresent;
289 Bool_t AliL3ModelTrack::GetZWidth(Int_t row,Float_t &width)
291 AliL3ClusterModel *cl = GetClusterModel(row);
292 width = cl->fDSigmaZ2*fZWidthQ + GetParSigmaZ2(row);
294 return (Bool_t)cl->fPresent;
297 Bool_t AliL3ModelTrack::GetPadResidual(Int_t row,Float_t &res)
299 AliL3ClusterModel *cl = GetClusterModel(row);
304 Bool_t AliL3ModelTrack::GetTimeResidual(Int_t row,Float_t &res)
306 AliL3ClusterModel *cl = GetClusterModel(row);
311 Bool_t AliL3ModelTrack::GetXYWidthResidual(Int_t row,Float_t &res)
313 AliL3ClusterModel *cl = GetClusterModel(row);
318 Bool_t AliL3ModelTrack::GetZWidthResidual(Int_t row,Float_t &res)
320 AliL3ClusterModel *cl = GetClusterModel(row);
325 Float_t AliL3ModelTrack::GetPadHit(Int_t row)
327 Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
328 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
330 cerr<<"AliL3ModelTrack::GetPadHit() : Wrong index: "<<index<<" row "<<row<<endl;
336 Float_t AliL3ModelTrack::GetTimeHit(Int_t row)
338 Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
339 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
341 cerr<<"AliL3ModelTrack::GetTimeHit() : Wrong index: "<<index<<" row "<<row<<endl;
347 Int_t AliL3ModelTrack::GetOverlap(Int_t row)
349 Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
350 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
352 cerr<<"AliL3ModelTrack::GetOverlap() : Wrong index: "<<index<<endl;
355 return fOverlap[index];
358 AliL3ClusterModel *AliL3ModelTrack::GetClusterModel(Int_t row)
360 if(!fClusters) return 0;
361 Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
362 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
364 cerr<<"AliL3ModelTrack::GetClusterModel() : Wrong index: "<<index<<endl;
367 return &fClusters[index];
370 void AliL3ModelTrack::Print()
374 cout<<"----Slice "<<fSlice<<" Patch "<<fPatch<<"----"<<endl;
375 cout<<"First point "<<GetFirstPointX()<<" "<<GetFirstPointY()<<" "<<GetFirstPointZ()<<endl;
376 cout<<"Last point "<<GetLastPointX()<<" "<<GetLastPointY()<<" "<<GetLastPointZ()<<endl;
377 cout<<"Pt "<<GetPt()<<" kappa "<<GetKappa()<<" tgl "<<GetTgl()<<" psi "<<GetPsi()<<" charge "<<GetCharge()<<endl;
378 cout<<"Center "<<GetCenterX()<<" "<<GetCenterY()<<endl<<endl;
379 cout<<"NHits "<<GetNClusters()<<endl;
380 cout<<"Clusters:"<<endl;
382 for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
384 AliL3ClusterModel *cl = GetClusterModel(i);
387 cout<<i<<" Empty"<<" Padcrossing "<<GetPadHit(i)<<" Timecrossing "<<GetTimeHit(i)<<" ";
390 cout<<i<<" Dpad "<<cl->fDPad<<" Dtime "<<cl->fDTime<<" Dcharge "<<cl->fDCharge;
391 cout<<" DsigmaY2 "<<cl->fDSigmaY2<<" DsigmaZ2 "<<cl->fDSigmaZ2;
392 cout<<" Padcrossing "<<GetPadHit(i)<<" Timecrossing "<<GetTimeHit(i)<<" ";
393 cout<<"Number of pads "<<GetNPads(i)<<endl;
395 cout<<"Overlapping index "<<GetOverlap(i)<<endl;
399 Double_t AliL3ModelTrack::GetParSigmaY2(Int_t row)
401 //Calculate the expected cluster width, based on the track parameters and drift distance.
404 if(!GetTime(row,time) || !GetPad(row,pad))
409 AliL3Transform::Slice2Sector(fSlice,row,sector,padrow);
410 AliL3Transform::Raw2Local(xyz,sector,padrow,pad,time);
412 //Calculate the drift length:
415 drift = AliL3Transform::GetZLength() - xyz[2];
417 drift = AliL3Transform::GetZLength() + xyz[2];
419 Double_t prf = AliL3Transform::GetPRFSigma(fPatch);
420 Double_t diffT = AliL3Transform::GetDiffT();
421 Double_t padlength = AliL3Transform::GetPadLength(fPatch);
422 Double_t anode = AliL3Transform::GetAnodeWireSpacing();
423 Double_t beta = GetCrossingAngle(row);
425 Double_t sigmaY2 = prf*prf + diffT*diffT*drift + padlength*padlength*tan(beta)*tan(beta)/12 + anode*anode*pow( tan(beta)-0.15, 2)/12;
427 //Convert back to raw coordinates.
428 sigmaY2 = sigmaY2/pow(AliL3Transform::GetPadPitchWidth(fPatch),2);
432 Double_t AliL3ModelTrack::GetParSigmaZ2(Int_t row)
434 //Calculate the expected cluster width, based on the track parameters and drift distance.
437 if(!GetTime(row,time) || !GetPad(row,pad))
442 AliL3Transform::Slice2Sector(fSlice,row,sector,padrow);
443 AliL3Transform::Raw2Local(xyz,sector,padrow,pad,time);
445 //Calculate the drift length:
448 drift = AliL3Transform::GetZLength() - xyz[2];
450 drift = AliL3Transform::GetZLength() + xyz[2];
452 Double_t sigma0 = AliL3Transform::GetTimeSigma();
453 Double_t diffL = AliL3Transform::GetDiffL();
454 Double_t padlength = AliL3Transform::GetPadLength(fPatch);
455 Double_t tanl = GetTgl();
457 Double_t sigmaZ2 = sigma0*sigma0 + diffL*diffL*drift + padlength*padlength * tanl*tanl/12;
459 //Convert back to raw coodinates:
460 sigmaZ2 = sigmaZ2/pow(AliL3Transform::GetZWidth(),2);
465 void AliL3ModelTrack::AssignTrackID(Float_t wrong)
467 //Assign a track ID to the track, corresponding to the MC TParticle ID.
468 //Can only be done if you compiled with do_mc flag, of course.
469 //The function loops over the assigned clusters, and finds the label (ID)
470 //of each clusters, and assigns the ID with the most hits to the track.
471 //If there are more than wrong% clusters of a different ID, the track is
472 //considered to be fake, and label will be assigned as negative.
475 Int_t *lb = new Int_t[GetNClusters()];
476 Int_t *mx = new Int_t[GetNClusters()];
479 for(Int_t i=0; i<GetNClusters(); i++)
484 for(i=0; i<GetNClusters(); i++)
486 lab = abs(GetTrackID(i,0));
487 for (j=0; j<GetNClusters(); j++)
488 if (lb[j]==lab || mx[j]==0) break;
494 for (i=0; i<GetNClusters(); i++)
503 for (i=0; i<GetNClusters(); i++)
505 if(abs(GetTrackID(i,1)) == lab ||
506 abs(GetTrackID(i,2)) == lab)
510 if ((1.- Float_t(max)/GetNClusters()) > wrong) lab=-lab;
518 cerr<<"AliL3ModelTrack::AssignTrackID : Compile with do_mc flag"<<endl;