3 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
4 //*-- Copyright © ALICE HLT Group
6 #include "AliHLTStandardIncludes.h"
8 #include "AliHLTLogging.h"
9 #include "AliHLTHoughTransformerGlobal.h"
10 #include "AliHLTFileHandler.h"
11 #include "AliHLTTransform.h"
12 #include "AliHLTDigitData.h"
13 #include "AliHLTTrack.h"
14 #include "AliHLTHistogram.h"
15 #include "AliHLTTrackArray.h"
16 #include "AliHLTHoughMaxFinder.h"
17 #include "AliHLTHoughTrack.h"
18 #include "AliHLTSpacePointData.h"
26 //_____________________________________________________________
27 // AliHLTHoughTransformerGlobal
29 // Hough transformation class
32 ClassImp(AliHLTHoughTransformerGlobal)
34 AliHLTHoughTransformerGlobal::AliHLTHoughTransformerGlobal()
49 AliHLTHoughTransformerGlobal::AliHLTHoughTransformerGlobal(Char_t *path,Int_t event)
60 fTracks = new AliHLTTrackArray("AliHLTHoughTrack");
61 fPeakFinder = new AliHLTHoughMaxFinder("KappaPhi",1000);
64 AliHLTHoughTransformerGlobal::~AliHLTHoughTransformerGlobal()
79 void AliHLTHoughTransformerGlobal::CreateHistograms(Float_t /*ptmin*/,Int_t nxbin,Int_t nybin)
81 //create histograms for HT
84 cerr<<"AliHLTHoughTransformerGlobal::CreateHistograms : Call DefineRegion first"<<endl;
87 AliHLTHoughTransformer::CreateHistograms(nxbin,fPtMin,nybin,-fPsi,fPsi);
88 //AliHLTHoughTransformer::CreateHistograms(fPtMin,ptmax,ptres,nybin,fPsi);
91 void AliHLTHoughTransformerGlobal::TransformCircleC()
94 AliHLTSeed *clusters = new AliHLTSeed[1000];
95 Int_t nclusters = LoadClusterSeeds(clusters);
97 Int_t i=0,sector,row,slice;
99 Float_t xyz[3],rpe[3],kappa,psi;
101 for(Int_t sl=GetSlice()-fNActiveSlice; sl<=GetSlice()+fNActiveSlice; sl++)
103 if(sl < 0 || sl < 18 && GetSlice() >= 18)
105 else if(sl > 35 || sl > 17 && GetSlice() <= 17)
109 cout<<"Transforming in slice "<<slice<<endl;
111 AliHLTDigitRowData *rowPt = (AliHLTDigitRowData*)fMemHandler[i++]->GetDataPointer(dummy);
113 for(Int_t padrow=0; padrow<AliHLTTransform::GetNRows(); padrow++)
115 if(padrow == fSeedPadRow) continue;
116 AliHLTDigitData *digits = (AliHLTDigitData*)rowPt->fDigitData;
118 for(UInt_t j=0; j<rowPt->fNDigit; j++)
120 Int_t pad = digits[j].fPad;
122 if(i==1 && pad < fPadMin[padrow])
124 if(i==fNActiveSlice*2+1 && pad>fPadMax[padrow])
127 Int_t time = digits[j].fTime;
128 Int_t charge = digits[j].fCharge;
130 if(charge > GetUpperThreshold() || charge < GetLowerThreshold())
133 AliHLTTransform::Slice2Sector(slice,padrow,sector,row);
134 AliHLTTransform::Raw2Local(xyz,sector,row,pad,time);
136 Rotate(xyz,i-1-fNActiveSlice);
138 AliHLTTransform::XYZtoRPhiEta(rpe,xyz);
139 rpe[0] = sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
141 Int_t etaindex = GetEtaIndex(rpe[2]);
143 AliHLTHistogram *hist = GetHistogram(etaindex);
145 for(Int_t l=0; l<nclusters; l++)
147 if(clusters[l].fIndex != etaindex) continue;
148 psi = atan( (clusters[l].fRadius*sin(rpe[1])-rpe[0]*sin(clusters[l].fPhi))/
149 (clusters[l].fRadius*cos(rpe[1])-rpe[0]*cos(clusters[l].fPhi)) );
150 kappa = 2*sin(clusters[l].fPhi-psi)/clusters[l].fRadius;
151 if(fabs(kappa) < 1e-33)
153 //hist->Fill(kappa,psi,(int)rint(log((Float_t)charge)));
154 hist->Fill(kappa,psi,charge);
157 AliHLTMemHandler::UpdateRowPointer(rowPt);
163 void AliHLTHoughTransformerGlobal::TransformCircle()
166 Int_t i=0,sector,row,slice;
168 Float_t xyz[3],rpe[3],kappa,psi;
170 for(Int_t sl=GetSlice()-fNActiveSlice; sl<=GetSlice()+fNActiveSlice; sl++)
172 if(sl < 0 || sl < 18 && GetSlice() >= 18)
174 else if(sl > 35 || sl > 17 && GetSlice() <= 17)
178 cout<<"Transforming in slice "<<slice<<endl;
180 AliHLTDigitRowData *rowPt = (AliHLTDigitRowData*)fMemHandler[i++]->GetDataPointer(dummy);
182 for(Int_t padrow=0; padrow<AliHLTTransform::GetNRows(); padrow++)
185 AliHLTDigitData *digits = (AliHLTDigitData*)rowPt->fDigitData;
187 for(UInt_t j=0; j<rowPt->fNDigit; j++)
189 Int_t pad = digits[j].fPad;
191 if(i==1 && pad < fPadMin[padrow])
193 if(i==fNActiveSlice*2+1 && pad>fPadMax[padrow])
196 Int_t time = digits[j].fTime;
197 Int_t charge = digits[j].fCharge;
199 if(charge > GetUpperThreshold() || charge < GetLowerThreshold())
202 AliHLTTransform::Slice2Sector(slice,padrow,sector,row);
203 AliHLTTransform::Raw2Local(xyz,sector,row,pad,time);
205 Rotate(xyz,i-1-fNActiveSlice);
207 AliHLTTransform::XYZtoRPhiEta(rpe,xyz);
208 rpe[0] = sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
210 Int_t etaindex = GetEtaIndex(rpe[2]);
212 AliHLTHistogram *hist = GetHistogram(etaindex);
214 for(Int_t b=hist->GetFirstYbin(); b<=hist->GetLastYbin(); b++)
216 psi = hist->GetBinCenterY(b);
217 kappa = 2*sin(rpe[1] - psi)/rpe[0];
219 if(fabs(kappa) < 1e-33)
222 hist->Fill(kappa,psi,charge);
223 //hist->Fill(kappa,psi,(int)rint(log((Float_t)charge)));
226 AliHLTMemHandler::UpdateRowPointer(rowPt);
231 void AliHLTHoughTransformerGlobal::VerifyTracks(AliHLTTrackArray *tracks,Int_t &index)
233 //remove tracks which do not cross the seed padrow
234 for(int i=index; i<tracks->GetNTracks(); i++)
236 AliHLTHoughTrack *tr = (AliHLTHoughTrack*)tracks->GetCheckedTrack(i);
240 AliHLTTransform::Local2GlobalAngle(&angle,GetSlice());
241 if(!tr->CalculateReferencePoint(angle,AliHLTTransform::Row2X(fSeedPadRow)))
247 AliHLTTransform::Slice2Sector(GetSlice(),fSeedPadRow,sector,row);
248 float xyz[3] = {tr->GetPointX(),tr->GetPointY(),tr->GetPointZ()};
249 AliHLTTransform::Global2Raw(xyz,sector,row);
250 if(xyz[1]<0 || xyz[1]>=AliHLTTransform::GetNPads(fSeedPadRow) ||
251 xyz[2]<0 || xyz[2]>=AliHLTTransform::GetNTimeBins())
255 index = tracks->GetNTracks();
258 void AliHLTHoughTransformerGlobal::FindPeaks(AliHLTHistogram *hist,Float_t eta)
261 fPeakFinder->Reset();
262 fPeakFinder->SetHistogram(hist);
263 fPeakFinder->FindAbsMaxima();
264 if(fPeakFinder->GetWeight(0) < 1000)
267 AliHLTHoughTrack *track = (AliHLTHoughTrack*)fTracks->NextTrack();
268 track->SetTrackParameters(fPeakFinder->GetXPeak(0),fPeakFinder->GetYPeak(0),fPeakFinder->GetWeight(0));
270 track->SetRowRange(AliHLTTransform::GetFirstRow(0),AliHLTTransform::GetLastRow(5));
273 void AliHLTHoughTransformerGlobal::Rotate(Float_t *xyz,Int_t relslice)
275 //Rotate coordinates from one slice to the slice relative to it;
279 Float_t angle = (Float_t)relslice*AliHLTTransform::Deg2Rad(20);
280 Float_t x=xyz[0],y=xyz[1];
281 xyz[0] = x*cos(angle) - y*sin(angle);
282 xyz[1] = x*sin(angle) + y*cos(angle);
286 void AliHLTHoughTransformerGlobal::DefineRegion(Float_t minpt,Float_t /*linephi*/,Int_t seedpadrow)
288 //Setup the region to be included in the transform
289 //This function should be called only once, since it is the same for all slices.
291 fSeedPadRow=seedpadrow;
294 fPadMin = new Int_t[AliHLTTransform::GetNRows()];
295 fPadMax = new Int_t[AliHLTTransform::GetNRows()];
297 //Phirange of data which should be included in the transform
298 //Here we assume a min pt to define it; fPtMin
299 //Based on pt (kappa) and the two points; origo and middle point, we can get psi angle
301 //Calculate the upper point, the lower point is symmetrical around the x-axis
302 //The track in this calculation has a positive charge, and the kappa sign is the opposite:
304 Float_t xyz[3],phi,phi2;
306 phi = CalculateBorder(xyz,-1); //upward bending track
307 phi2 = CalculateBorder(xyz,1); //downward bending track
311 cout<<"Phiangle "<<phi*180/AliHLTTransform::Pi()<<" psi "<<fPsi*180/AliHLTTransform::Pi()<<" nslices "<<fNActiveSlice<<endl;
313 Float_t rotangle = fNActiveSlice*20;
315 //Calculate the LUT for min/max pad for every padrow, and check which slices we need.
316 Int_t pad,sector,row;
317 for(Int_t i=0; i<AliHLTTransform::GetNRows(); i++)
319 AliHLTTransform::Slice2Sector(0,i,sector,row);
322 pad = AliHLTTransform::GetNPads(i)-1;
325 AliHLTTransform::Raw2Local(xyz,sector,row,pad,0);
326 if(AliHLTTransform::GetPhi(xyz) > -1.*phi + AliHLTTransform::Deg2Rad(rotangle))
335 while(pad < AliHLTTransform::GetNPads(i))
337 AliHLTTransform::Raw2Local(xyz,sector,row,pad,0);
338 if(AliHLTTransform::GetPhi(xyz) < phi - AliHLTTransform::Deg2Rad(rotangle))
346 cout<<"Padmax "<<fPadMax[155]<<endl;
350 Float_t AliHLTHoughTransformerGlobal::CalculateBorder(Float_t *xyz,Int_t charge)
352 //Define Hough space borders
353 Double_t lineradius = sqrt(pow(AliHLTTransform::Row2X(fSeedPadRow),2) + pow(AliHLTTransform::GetMaxY(fSeedPadRow),2));
355 Double_t kappa = -charge*AliHLTTransform::GetBField()*AliHLTTransform::GetBFact()/fPtMin;
357 //Calculate the psi angle of the track = emission angle with x-axis in origo
358 if( fabs(lineradius*kappa/2) > 1)
360 cerr<<"AliHLTTransformerGlobal::DefineRegion : Angle too big"<<endl;
365 Float_t psi = AliHLTTransform::Deg2Rad(10) - asin(lineradius*kappa/2);
369 cout<<"Calculated psi-angle "<<fPsi<<endl;
372 track.SetFirstPoint(0,0,0);
375 track.SetCharge(charge);
376 track.CalculateHelix();
380 crossingrow = AliHLTTransform::GetNRows()-1;
386 rotangle = nslices*20;
388 if(nslices==0)//here we are in local slice, so we use the appropriate function. a mess of course...
390 while(!track.GetCrossingPoint(crossingrow,xyz))
394 cerr<<"AliHLTHoughTransformerGlobal::DefineRegion : Error calculating point1 on row "<<crossingrow<<endl;
402 while(!track.CalculateReferencePoint(AliHLTTransform::Deg2Rad(rotangle),AliHLTTransform::Row2X(crossingrow)))
406 cerr<<"AliHLTHoughTransformerGlobal::DefineRegion : Error calculating point2 on row "<<crossingrow<<endl;
412 xyz[0] = track.GetPointX();
413 xyz[1] = track.GetPointY();
414 xyz[2] = track.GetPointZ();
417 Float_t phi = atan2(xyz[1],xyz[0]);
419 //Rotate coordinates back to local coordinates:
420 Rotate(xyz,-1*nslices);
423 AliHLTTransform::Slice2Sector(0,crossingrow,sector,row);
424 AliHLTTransform::Local2Raw(xyz,sector,row);
429 cerr<<"AliHLTHoughTransformerGlobal::DefineRegion : Wrong pad, probably a deadzone... "<<xyz[1]<<endl;
433 return 0;//here you only want the crossing point with the outer padrow
435 if(xyz[1] >= AliHLTTransform::GetNPads(crossingrow)) //Here the range is even one more slice away
437 cerr<<"One more slice with pad "<<xyz[1]<<endl;
440 crossingrow = AliHLTTransform::GetNRows()-1;
444 if(nslices > fNActiveSlice)
445 fNActiveSlice = nslices;
447 cout<<"Calculated phi "<<phi<<" and pad "<<xyz[1]<<" on row "<<crossingrow<<endl;
451 void AliHLTHoughTransformerGlobal::LoadActiveSlices(Bool_t binary)
455 UnloadActiveSlices();
456 fMemHandler = new AliHLTMemHandler*[(fNActiveSlice*2 + 1)];
457 Char_t filename[1024];
460 for(Int_t sl=GetSlice()-fNActiveSlice; sl<=GetSlice()+fNActiveSlice; sl++)
462 if(sl < 0 || sl < 18 && GetSlice() >= 18)
464 else if(sl > 35 || sl > 17 && GetSlice() <= 17)
468 cout<<"Loading slice "<<slice<<endl;
469 fMemHandler[i] = new AliHLTFileHandler();
470 fMemHandler[i]->Init(slice,-1);
473 sprintf(filename,"%s/binaries/digits_%d_%d_%d.raw",fPath,fEvent,slice,-1);
474 fMemHandler[i]->SetBinaryInput(filename);
475 fMemHandler[i]->CompBinary2Memory(dummy);
476 fMemHandler[i++]->CloseBinaryInput();
480 sprintf(filename,"%s/digitfile.root",fPath);
481 fMemHandler[i]->SetAliInput(filename);
482 fMemHandler[i]->AliAltroDigits2Memory(dummy,fEvent);
483 fMemHandler[i++]->CloseAliInput();
489 void AliHLTHoughTransformerGlobal::UnloadActiveSlices()
491 //Unload active slices
494 for(Int_t i=0; i<=fNActiveSlice*2; i++)
496 if(!fMemHandler[i]) continue;
497 delete fMemHandler[i];
499 delete [] fMemHandler;
503 Int_t AliHLTHoughTransformerGlobal::LoadClusterSeeds(AliHLTSeed *seeds)
506 Char_t filename[1024];
508 sprintf(filename,"%s/hough/points_%d_%d_%d.raw",fPath,fEvent,GetSlice(),-1);
509 //sprintf(filename,"../tracker/points_%d_%d_%d.raw",fEvent,GetSlice(),-1);
510 AliHLTMemHandler mem;
511 if(!mem.SetBinaryInput(filename))
513 cerr<<"AliHLTHoughTransformerGlobal::LoadClusterSeeds : Cannot open file "<<filename<<endl;
516 AliHLTSpacePointData *points = (AliHLTSpacePointData*)mem.Allocate();
517 mem.Binary2Memory(npoints,points);
518 mem.CloseBinaryInput();
521 for(UInt_t i=0; i<npoints; i++)
523 Int_t lrow = (Int_t)points[i].fPadRow;
524 if(lrow < fSeedPadRow) continue;
525 if(lrow > fSeedPadRow) break;
526 if(fabs(points[i].fY) > AliHLTTransform::GetMaxY(lrow))
528 cerr<<"AliHLTHoughTransformerGlobal::LoadClusterSeeds : Seeds seems not to be in local coordinates: "
529 <<points[i].fY<<endl;
532 Float_t xyz[3] = {AliHLTTransform::Row2X(lrow),points[i].fY,points[i].fZ};
533 Double_t eta = AliHLTTransform::GetEta(xyz);
534 seeds[counter].fPhi = atan2(xyz[1],xyz[0]);
535 seeds[counter].fRadius = sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
536 seeds[counter].fIndex = GetEtaIndex(eta);
537 seeds[counter++].fEta = eta;
539 cout<<"Loaded "<<counter<<" cluster seeds on slice "<<GetSlice()<<" padrow "<<fSeedPadRow<<endl;
544 void AliHLTHoughTransformerGlobal::DisplayActiveRegion(TH2F *hist,Int_t etaindex)
546 //Fill the active region in a histogram
548 Int_t i=0,sector,row,slice;
551 for(Int_t sl=GetSlice()-fNActiveSlice; sl<=GetSlice()+fNActiveSlice; sl++)
553 if(sl < 0 || sl < 18 && GetSlice() >= 18)
555 else if(sl > 35 || sl > 17 && GetSlice() <= 17)
559 cout<<"Displaying slice "<<slice<<endl;
560 AliHLTDigitRowData *rowPt = (AliHLTDigitRowData*)fMemHandler[i++]->GetDataPointer(dummy);
561 for(Int_t padrow=0; padrow<AliHLTTransform::GetNRows(); padrow++)
563 AliHLTDigitData *digits = (AliHLTDigitData*)rowPt->fDigitData;
564 for(UInt_t j=0; j<rowPt->fNDigit; j++)
566 Int_t pad = digits[j].fPad;
567 if(i==1 && pad < fPadMin[padrow])
569 if(i==fNActiveSlice*2+1 && pad>fPadMax[padrow])
571 Int_t time = digits[j].fTime;
572 AliHLTTransform::Slice2Sector(slice,padrow,sector,row);
573 AliHLTTransform::Raw2Local(xyz,sector,row,pad,time);
575 Rotate(xyz,i-1-fNActiveSlice);
577 Double_t eta = AliHLTTransform::GetEta(xyz);
578 if(GetEtaIndex(eta) == etaindex)
579 hist->Fill(xyz[0],xyz[1]);
581 AliHLTMemHandler::UpdateRowPointer(rowPt);