3 // Author: Anders Vestbo <mailto:vestbo$fi.uib.no>
4 //*-- Copyright © ALICE HLT Group
6 #include "AliL3StandardIncludes.h"
8 #include "AliL3Logging.h"
9 #include "AliL3Transform.h"
10 #include "AliL3Vertex.h"
11 #include "AliL3DataCompressorHelper.h"
13 #include "AliL3ModelTrack.h"
19 //_____________________________________________________________
24 ClassImp(AliL3ModelTrack)
26 AliL3ModelTrack::AliL3ModelTrack()
39 fArraysCreated=kFALSE;
43 AliL3ModelTrack::~AliL3ModelTrack()
48 void AliL3ModelTrack::DeleteArrays()
57 delete [] fCrossingAngle;
59 delete [] fParSigmaY2;
61 delete [] fParSigmaZ2;
68 for(Int_t i=0; i<AliL3Transform::GetNRows(fPatch); i++)
69 delete [] fOverlap[i];
72 fArraysCreated=kFALSE;
75 void AliL3ModelTrack::Init(Int_t /*slice*/,Int_t patch)
81 fNClusters=AliL3Transform::GetNRows(patch);
83 Int_t nrows = AliL3Transform::GetNRows(fPatch);
84 fClusters = new AliL3ClusterModel[nrows];
85 fPad = new Float_t[nrows];
86 fTime = new Float_t[nrows];
87 fCrossingAngle = new Float_t[nrows];
88 fParSigmaY2 = new Float_t[nrows];
89 fParSigmaZ2 = new Float_t[nrows];
90 fTrackModel = new AliL3TrackModel;
92 fOverlap = new Int_t*[nrows];
93 fNoverlaps = new Int_t[nrows];
96 memset(fNoverlaps,0,nrows*sizeof(Int_t));
97 memset(fClusters,0,nrows*sizeof(AliL3ClusterModel));
98 memset(fPad,0,nrows*sizeof(Float_t));
99 memset(fTime,0,nrows*sizeof(Float_t));
100 memset(fCrossingAngle,0,nrows*sizeof(Float_t));
101 memset(fParSigmaY2,0,nrows*sizeof(Float_t));
102 memset(fParSigmaZ2,0,nrows*sizeof(Float_t));
103 memset(fTrackModel,0,sizeof(AliL3TrackModel));
104 for(Int_t i=0; i<nrows; i++)
106 fOverlap[i] = new Int_t[fMaxOverlaps];
107 for(Int_t j=0; j<fMaxOverlaps; j++)
109 fClusters[i].fSlice = -1;
111 fArraysCreated=kTRUE;
116 void AliL3ModelTrack::CalculateClusterWidths(Int_t row,Bool_t parametrize)
122 Int_t index = row - AliL3Transform::GetFirstRow(fPatch);
123 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
125 cerr<<"AliL3ModelTrack::CalculcateClusterWidths : Wrond index "<<index<<" row "<<row<<endl;
128 Int_t patch = AliL3Transform::GetPatch(row);
129 AliL3Transform::Slice2Sector(0,row,sr,lr);
130 AliL3Transform::Raw2Local(xyz,sr,lr,GetPadHit(row),GetTimeHit(row));
131 fParSigmaY2[index] = AliL3Transform::GetParSigmaY2(row,xyz[2],GetCrossingAngleLUT(row));
132 fParSigmaZ2[index] = AliL3Transform::GetParSigmaZ2(row,xyz[2],GetTgl());
136 fParSigmaY2[index] = (fParSigmaY2[index] + (1./12)*pow(AliL3Transform::GetPadPitchWidth(patch),2) );
137 fParSigmaY2[index] *= 0.108;
139 fParSigmaY2[index] *= 2.07;
141 fParSigmaZ2[index] = (fParSigmaZ2[index] + (1./12)*pow(AliL3Transform::GetZWidth(),2) );
142 fParSigmaZ2[index] *= 0.169;
144 fParSigmaZ2[index] *= 1.77;
147 //convert to raw coordinates:
148 fParSigmaY2[index] /= pow(AliL3Transform::GetPadPitchWidth(patch),2);
149 fParSigmaZ2[index] /= pow(AliL3Transform::GetZWidth(),2);
152 void AliL3ModelTrack::SetCluster(Int_t row,Float_t fpad,Float_t ftime,Float_t charge,
153 Float_t sigmaY2,Float_t sigmaZ2,Int_t npads)
155 AliL3ClusterModel *cl = GetClusterModel(row);
157 //First bit: Cluster is present or not
158 //Second bit: Cluster was set, meaning an fit attempt was done (if true)
160 cl->fPresent |= 0x2; //set second bit to true, because a fit attempt has been made
162 Int_t patch = AliL3Transform::GetPatch(row);
163 if(!charge || npads == 1)
165 cl->fPresent &= ~0x1; //set first bit to false
169 cl->fPresent|=0x1;//set first bit to true
170 cl->fDPad = (fpad - GetPadHit(row))/(AliL3DataCompressorHelper::GetXYResidualStep(row)/AliL3Transform::GetPadPitchWidth(patch));
171 cl->fDTime = (ftime - GetTimeHit(row))/(AliL3DataCompressorHelper::GetZResidualStep(row)/AliL3Transform::GetZWidth());
172 cl->fDCharge = charge;
173 if(sigmaY2==0 && sigmaZ2==0)
175 cl->fDSigmaY=0;//if width is zero, shape is not supposed to be written
180 //cl->fDSigmaY2 = (sigmaY2 - GetParSigmaY2(row))/(pow(AliL3DataCompressorHelper::GetXYWidthStep(),2)/pow(AliL3Transform::GetPadPitchWidth(patch),2));
181 //cl->fDSigmaZ2 = (sigmaZ2 - GetParSigmaZ2(row))/(pow(AliL3DataCompressorHelper::GetZWidthStep(),2)/pow(AliL3Transform::GetZWidth(),2));
182 cl->fDSigmaY = (sqrt(sigmaY2) - sqrt(GetParSigmaY2(row)))/(AliL3DataCompressorHelper::GetXYWidthStep()/AliL3Transform::GetPadPitchWidth(patch));
183 cl->fDSigmaZ = (sqrt(sigmaZ2) - sqrt(GetParSigmaZ2(row)))/(AliL3DataCompressorHelper::GetZWidthStep()/AliL3Transform::GetZWidth());
190 void AliL3ModelTrack::Set(AliL3Track *tpt)
192 AliL3ModelTrack *tr = (AliL3ModelTrack*)tpt;
193 SetRowRange(tr->GetFirstRow(),tr->GetLastRow());
194 SetPhi0(tr->GetPhi0());
195 SetKappa(tr->GetKappa());
196 SetFirstPoint(tr->GetFirstPointX(),tr->GetFirstPointY(),tr->GetFirstPointZ());
197 SetLastPoint(tr->GetLastPointX(),tr->GetLastPointY(),tr->GetLastPointZ());
199 SetPsi(tr->GetPsi());
200 SetTgl(tr->GetTgl());
201 SetCharge(tr->GetCharge());
205 cerr<<"AliL3ModelTrack::Set : Init has already been called for this object!"<<endl;
209 //Init(tr->fSlice,tr->fPatch);
211 memcpy(fClusters,tr->fClusters,AliL3Transform::GetNRows(fPatch)*sizeof(AliL3ClusterModel));
212 memcpy(fPad,tr->fPad,AliL3Transform::GetNRows(fPatch)*sizeof(Float_t));
213 memcpy(fTime,tr->fTime,AliL3Transform::GetNRows(fPatch)*sizeof(Float_t));
214 memcpy(fParSigmaY2,tr->fParSigmaY2,AliL3Transform::GetNRows(fPatch)*sizeof(Float_t));
215 memcpy(fParSigmaZ2,tr->fParSigmaZ2,AliL3Transform::GetNRows(fPatch)*sizeof(Float_t));
216 memcpy(fCrossingAngle,tr->fCrossingAngle,AliL3Transform::GetNRows(fPatch)*sizeof(Float_t));
217 memcpy(fTrackModel,tr->fTrackModel,sizeof(AliL3TrackModel));
221 Int_t AliL3ModelTrack::GetNPresentClusters()
223 //Return the number of assigned clusters to the track.
224 //Differs from fNClusters, which should be equal to the
225 //number of padrows in the present patch.
229 for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
236 void AliL3ModelTrack::FillModel()
238 //Fill the track structure
240 if(fNClusters != AliL3Transform::GetNRows(fPatch))
242 cout<<"AliL3ModelTrack::FillModel : fNClusters != nrows; beware, this could be caused by a bug!!!"<<endl;
243 fNClusters = AliL3Transform::GetNRows(fPatch);
248 cerr<<"AliL3ModelTrack::FillModel() : No trackmodel "<<endl;
254 GetClosestPoint(&vertex,impact[0],impact[1],impact[2]);
255 fTrackModel->fKappa = GetKappa();
256 fTrackModel->fPhi = atan2(impact[1],impact[0]);
257 fTrackModel->fD = sqrt(impact[0]*impact[0] + impact[1]*impact[1]);
258 fTrackModel->fZ0 = impact[2];
259 fTrackModel->fTgl = GetTgl();
261 //We have to check on which of the vertex the track fit is lying
262 //This we need to encode the azimuthal angle coordinate of the center of curvature.
263 if(GetRadius() < sqrt(GetCenterX()*GetCenterX()+GetCenterY()*GetCenterY()))
264 fTrackModel->fD *=-1;
268 void AliL3ModelTrack::FillTrack()
270 //Fill the track parameters from the structure.
274 cerr<<"AliL3ModelTrack::FillTrack() : No data!!"<<endl;
277 SetKappa(fTrackModel->fKappa);
278 Double_t impact[3],psi;
279 Float_t trackPhi0 = fTrackModel->fPhi;
280 if(fTrackModel->fD < 0)
281 trackPhi0 += AliL3Transform::Pi();
282 Int_t charge = -1*(Int_t)copysign(1.,GetKappa());
283 impact[0] = fabs(fTrackModel->fD)*cos(fTrackModel->fPhi);
284 impact[1] = fabs(fTrackModel->fD)*sin(fTrackModel->fPhi);
285 impact[2] = fTrackModel->fZ0;
287 psi = trackPhi0 - charge*0.5*AliL3Transform::Pi();
289 psi += 2*AliL3Transform::Pi();
292 SetFirstPoint(impact[0],impact[1],impact[2]);
294 SetTgl(fTrackModel->fTgl);
295 SetPt((AliL3Transform::GetBFact()*AliL3Transform::GetBField())/fabs(GetKappa()));
296 fNClusters = AliL3Transform::GetNRows(fPatch);
299 for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
301 AliL3ClusterModel *cl = GetClusterModel(i);
310 if(cl->fSlice < 0 || cl->fSlice > 35)
312 cerr<<"AliL3ModelTrack::FillTrack : Slice out of range "<<cl->fSlice<<" on row "<<i<<endl;
318 AliL3Transform::Local2GlobalAngle(&angle,cl->fSlice);
319 if(!CalculateReferencePoint(angle,AliL3Transform::Row2X(i)))
323 cerr<<"AliL3ModelTrack::FillTrack : Track does not cross slice "<<cl->fSlice<<" row "<<i<<" Points "
324 <<GetPointX()<<" "<<GetPointY()<<" "<<GetPointZ()<<endl;
332 Float_t hit[3] = {GetPointX(),GetPointY(),GetPointZ()};
334 AliL3Transform::Slice2Sector(cl->fSlice,i,sector,row);
335 AliL3Transform::Global2Raw(hit,sector,row);
338 SetTimeHit(i,hit[2]);
340 Float_t crossingangle = GetCrossingAngle(i,cl->fSlice);
342 SetCrossingAngleLUT(i,crossingangle);
343 CalculateClusterWidths(i,kTRUE);
348 void AliL3ModelTrack::SetPadHit(Int_t row,Float_t pad)
350 Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
351 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
353 cerr<<"AliL3ModelTrack::SetPadHit() : Wrong index: "<<index<<endl;
359 void AliL3ModelTrack::SetTimeHit(Int_t row,Float_t time)
361 Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
362 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
364 cerr<<"AliL3ModelTrack::SetTimeHit() : Wrong index: "<<index<<endl;
370 void AliL3ModelTrack::SetCrossingAngleLUT(Int_t row,Float_t angle)
372 Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
373 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
375 cerr<<"AliL3ModelTrack::SetCrossingAngle() : Wrong index: "<<index<<endl;
378 fCrossingAngle[index]=angle;
381 void AliL3ModelTrack::SetOverlap(Int_t row,Int_t id)
384 Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
385 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
387 cerr<<"AliL3ModelTrack::SetOverlap() : Wrong index: "<<index<<endl;
390 if(fNoverlaps[index] >= fMaxOverlaps) return;
391 fOverlap[index][fNoverlaps[index]++] = id;
394 Bool_t AliL3ModelTrack::IsPresent(Int_t row)
396 AliL3ClusterModel *cl = GetClusterModel(row);
397 return (Bool_t)(cl->fPresent & 0x1);
400 Bool_t AliL3ModelTrack::IsSet(Int_t row)
402 AliL3ClusterModel *cl = GetClusterModel(row);
403 return (Bool_t)(cl->fPresent & 0x2);
406 Int_t AliL3ModelTrack::GetNPads(Int_t row)
408 AliL3ClusterModel *cl = GetClusterModel(row);
412 Bool_t AliL3ModelTrack::GetPad(Int_t row,Float_t &pad)
414 //(fpad - GetPadHit(row))/(AliL3DataCompressorHelper::GetXYResidualStep(row)/AliL3Transform::GetPadPitchWidth(patch));
415 AliL3ClusterModel *cl = GetClusterModel(row);
416 Int_t patch = AliL3Transform::GetPatch(row);
417 pad = cl->fDPad*(AliL3DataCompressorHelper::GetXYResidualStep(row)/AliL3Transform::GetPadPitchWidth(patch)) + GetPadHit(row);
418 return IsPresent(row);
421 Bool_t AliL3ModelTrack::GetTime(Int_t row,Float_t &time)
423 AliL3ClusterModel *cl = GetClusterModel(row);
424 time = cl->fDTime*(AliL3DataCompressorHelper::GetZResidualStep(row)/AliL3Transform::GetZWidth()) + GetTimeHit(row);
425 return IsPresent(row);
428 Bool_t AliL3ModelTrack::GetClusterCharge(Int_t row,Int_t &charge)
430 AliL3ClusterModel *cl = GetClusterModel(row);
431 charge = (Int_t)cl->fDCharge;// + AliL3DataCompressorHelperHelper::GetClusterCharge();
432 return IsPresent(row);
435 Bool_t AliL3ModelTrack::GetSigmaY2(Int_t row,Float_t &sigma2)
437 //cl->fDSigmaY = (sqrt(sigmaY2) - sqrt(GetParSigmaY2(row)))/(AliL3DataCompressorHelper::GetXYWidthStep()/AliL3Transform::GetPadPitchWidth(patch));
438 AliL3ClusterModel *cl = GetClusterModel(row);
439 Int_t patch = AliL3Transform::GetPatch(row);
440 Float_t sigma = cl->fDSigmaY*(AliL3DataCompressorHelper::GetXYWidthStep()/AliL3Transform::GetPadPitchWidth(patch)) + sqrt(GetParSigmaY2(row));
441 sigma2 = sigma*sigma;
442 return IsPresent(row);
445 Bool_t AliL3ModelTrack::GetSigmaZ2(Int_t row,Float_t &sigma2)
447 //cl->fDSigmaZ = (sqrt(sigmaZ2) - sqrt(GetParSigmaZ2(row)))/(AliL3DataCompressorHelper::GetZWidthStep()/AliL3Transform::GetZWidth());
448 AliL3ClusterModel *cl = GetClusterModel(row);
449 Float_t sigma = cl->fDSigmaZ*(AliL3DataCompressorHelper::GetZWidthStep()/AliL3Transform::GetZWidth()) + sqrt(GetParSigmaZ2(row));
450 sigma2 = sigma*sigma;
451 return IsPresent(row);
454 Bool_t AliL3ModelTrack::GetPadResidual(Int_t row,Float_t &res)
456 AliL3ClusterModel *cl = GetClusterModel(row);
457 Int_t patch = AliL3Transform::GetPatch(row);
458 res = cl->fDPad*(AliL3DataCompressorHelper::GetXYResidualStep(row)/AliL3Transform::GetPadPitchWidth(patch));
459 return IsPresent(row);
462 Bool_t AliL3ModelTrack::GetTimeResidual(Int_t row,Float_t &res)
464 AliL3ClusterModel *cl = GetClusterModel(row);
465 res = cl->fDTime*(AliL3DataCompressorHelper::GetZResidualStep(row)/AliL3Transform::GetZWidth());
466 return IsPresent(row);
469 Bool_t AliL3ModelTrack::GetSigmaYResidual(Int_t row,Float_t &res)
471 AliL3ClusterModel *cl = GetClusterModel(row);
472 Int_t patch = AliL3Transform::GetPatch(row);
473 res = cl->fDSigmaY*(AliL3DataCompressorHelper::GetXYWidthStep()/AliL3Transform::GetPadPitchWidth(patch));
474 return IsPresent(row);
477 Bool_t AliL3ModelTrack::GetSigmaZResidual(Int_t row,Float_t &res)
479 AliL3ClusterModel *cl = GetClusterModel(row);
480 res = cl->fDSigmaZ*(AliL3DataCompressorHelper::GetZWidthStep()/AliL3Transform::GetZWidth());
481 return IsPresent(row);
484 Int_t AliL3ModelTrack::GetSlice(Int_t row)
486 AliL3ClusterModel *cl = GetClusterModel(row);
490 Float_t AliL3ModelTrack::GetPadHit(Int_t row)
492 Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
493 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
495 cerr<<"AliL3ModelTrack::GetPadHit() : Wrong index: "<<index<<" row "<<row<<endl;
501 Float_t AliL3ModelTrack::GetTimeHit(Int_t row)
503 Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
504 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
506 cerr<<"AliL3ModelTrack::GetTimeHit() : Wrong index: "<<index<<" row "<<row<<endl;
512 Float_t AliL3ModelTrack::GetCrossingAngleLUT(Int_t row)
514 Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
515 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
517 cerr<<"AliL3ModelTrack::GetCrossingAngleLUT() : Wrong index: "<<index<<" row "<<row<<endl;
520 return fCrossingAngle[index];
523 Float_t AliL3ModelTrack::GetParSigmaY2(Int_t row)
525 Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
526 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
528 cerr<<"AliL3ModelTrack::GetParSigmaY2() : Wrong index: "<<index<<" row "<<row<<endl;
531 return fParSigmaY2[index];
534 Float_t AliL3ModelTrack::GetParSigmaZ2(Int_t row)
536 Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
537 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
539 cerr<<"AliL3ModelTrack::GetParSigmaZ2() : Wrong index: "<<index<<" row "<<row<<endl;
542 return fParSigmaZ2[index];
545 Int_t AliL3ModelTrack::GetNOverlaps(Int_t row)
547 Int_t index = row - AliL3Transform::GetFirstRow(fPatch);
548 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
550 cerr<<"AliL3ModelTrack::GetOverlap() : Wrong index: "<<index<<endl;
553 return fNoverlaps[index];
556 Int_t *AliL3ModelTrack::GetOverlaps(Int_t row)
558 Int_t index = row - AliL3Transform::GetFirstRow(fPatch);
559 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
561 cerr<<"AliL3ModelTrack::GetOverlap() : Wrong index: "<<index<<endl;
564 return fOverlap[index];
567 AliL3ClusterModel *AliL3ModelTrack::GetClusterModel(Int_t row)
569 if(!fClusters) return 0;
570 Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
571 if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
573 cerr<<"AliL3ModelTrack::GetClusterModel() : Wrong index: "<<index<<endl;
576 return &fClusters[index];
579 void AliL3ModelTrack::Print(Bool_t everything)
583 cout<<"First point "<<GetFirstPointX()<<" "<<GetFirstPointY()<<" "<<GetFirstPointZ()<<endl;
584 cout<<"Last point "<<GetLastPointX()<<" "<<GetLastPointY()<<" "<<GetLastPointZ()<<endl;
585 cout<<"Pt "<<GetPt()<<" kappa "<<GetKappa()<<" tgl "<<GetTgl()<<" psi "<<GetPsi()<<" charge "<<GetCharge()<<endl;
586 cout<<"Center "<<GetCenterX()<<" "<<GetCenterY()<<endl<<endl;
589 cout<<"NHits "<<GetNClusters()<<endl;
591 cout<<"Clusters:"<<endl;
592 Int_t origslice=-1,counter=0;
593 Float_t fpad,ftime,sigmaY2,sigmaZ2;
594 for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
596 AliL3ClusterModel *cl = GetClusterModel(i);
600 cout<<i<<" Empty"<<" Slice "<<cl->fSlice<<" Padcrossing "<<GetPadHit(i)<<" Timecrossing "<<GetTimeHit(i)<<" ";
601 //AliL3Transform::RawHLT2Global(xyz,cl->fSlice,i,GetPadHit(i),GetTimeHit(i));
602 //cout<<i<<" slice "<<cl->fSlice<<" x "<<xyz[0]<<" y "<<xyz[1]<<" z "<<xyz[2];
608 GetSigmaY2(i,sigmaY2);
609 GetSigmaZ2(i,sigmaZ2);
611 origslice=cl->fSlice;
612 else if(cl->fSlice != origslice)
613 cout<<"Change in slice "<<cl->fSlice<<" "<<origslice<<endl;
614 cout<<i<<" Slice "<<cl->fSlice<<" Dpad "<<cl->fDPad<<" Dtime "<<cl->fDTime<<" Dcharge "<<cl->fDCharge;
615 cout<<" sigmaY2 "<<sigmaY2<<" sigmaZ2 "<<sigmaZ2;
616 cout<<" parsigmaY2 "<<GetParSigmaY2(i)<<" parsigmaZ2 "<<GetParSigmaZ2(i);
617 cout<<" Pad "<<fpad<<" padhit "<<GetPadHit(i)<<" Time "<<ftime<<" timehit "<<GetTimeHit(i)<<" ";
624 void AliL3ModelTrack::SetClusterLabel(Int_t row,Int_t *trackID)
627 AliL3ClusterModel *cl = GetClusterModel(row);
628 cl->fTrackID[0] = trackID[0];
629 cl->fTrackID[1] = trackID[1];
630 cl->fTrackID[2] = trackID[2];
635 void AliL3ModelTrack::GetClusterLabel(Int_t row,Int_t *trackID)
638 AliL3ClusterModel *cl = GetClusterModel(row);
639 trackID[0] = cl->fTrackID[0];
640 trackID[1] = cl->fTrackID[1];
641 trackID[2] = cl->fTrackID[2];