3 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
4 //*-- Copyright © ALICE HLT Group
6 #include "AliL3StandardIncludes.h"
8 #include "AliL3Logging.h"
9 #include "AliL3HoughTransformerGlobal.h"
10 #include "AliL3FileHandler.h"
11 #include "AliL3Transform.h"
12 #include "AliL3DigitData.h"
13 #include "AliL3Track.h"
14 #include "AliL3Histogram.h"
15 #include "AliL3TrackArray.h"
16 #include "AliL3HoughMaxFinder.h"
17 #include "AliL3HoughTrack.h"
18 #include "AliL3SpacePointData.h"
26 //_____________________________________________________________
27 // AliL3HoughTransformerGlobal
29 // Hough transformation class
32 ClassImp(AliL3HoughTransformerGlobal)
34 AliL3HoughTransformerGlobal::AliL3HoughTransformerGlobal()
48 AliL3HoughTransformerGlobal::AliL3HoughTransformerGlobal(Char_t *path,Int_t event)
58 fTracks = new AliL3TrackArray("AliL3HoughTrack");
59 fPeakFinder = new AliL3HoughMaxFinder("KappaPhi",1000);
62 AliL3HoughTransformerGlobal::~AliL3HoughTransformerGlobal()
76 void AliL3HoughTransformerGlobal::CreateHistograms(Float_t ptmin,Int_t nxbin,Int_t nybin)
80 cerr<<"AliL3HoughTransformerGlobal::CreateHistograms : Call DefineRegion first"<<endl;
83 AliL3HoughTransformer::CreateHistograms(nxbin,fPtMin,nybin,-fPsi,fPsi);
84 //AliL3HoughTransformer::CreateHistograms(fPtMin,ptmax,ptres,nybin,fPsi);
87 void AliL3HoughTransformerGlobal::TransformCircleC()
90 Seed *clusters = new Seed[1000];
91 Int_t nclusters = LoadClusterSeeds(clusters);
93 Int_t i=0,sector,row,slice;
95 Float_t xyz[3],rpe[3],kappa,psi;
97 for(Int_t sl=GetSlice()-fNActiveSlice; sl<=GetSlice()+fNActiveSlice; sl++)
99 if(sl < 0 || sl < 18 && GetSlice() >= 18)
101 else if(sl > 35 || sl > 17 && GetSlice() <= 17)
105 cout<<"Transforming in slice "<<slice<<endl;
107 AliL3DigitRowData *rowPt = (AliL3DigitRowData*)fMemHandler[i++]->GetDataPointer(dummy);
109 for(Int_t padrow=0; padrow<AliL3Transform::GetNRows(); padrow++)
111 if(padrow == fSeedPadRow) continue;
112 AliL3DigitData *digits = (AliL3DigitData*)rowPt->fDigitData;
114 for(UInt_t j=0; j<rowPt->fNDigit; j++)
116 Int_t pad = digits[j].fPad;
118 if(i==1 && pad < fPadMin[padrow])
120 if(i==fNActiveSlice*2+1 && pad>fPadMax[padrow])
123 Int_t time = digits[j].fTime;
124 Int_t charge = digits[j].fCharge;
126 if(charge > GetUpperThreshold() || charge < GetLowerThreshold())
129 AliL3Transform::Slice2Sector(slice,padrow,sector,row);
130 AliL3Transform::Raw2Local(xyz,sector,row,pad,time);
132 Rotate(xyz,i-1-fNActiveSlice);
134 AliL3Transform::XYZtoRPhiEta(rpe,xyz);
135 rpe[0] = sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
137 Int_t eta_index = GetEtaIndex(rpe[2]);
139 AliL3Histogram *hist = GetHistogram(eta_index);
141 for(Int_t l=0; l<nclusters; l++)
143 if(clusters[l].fIndex != eta_index) continue;
144 psi = atan( (clusters[l].fRadius*sin(rpe[1])-rpe[0]*sin(clusters[l].fPhi))/
145 (clusters[l].fRadius*cos(rpe[1])-rpe[0]*cos(clusters[l].fPhi)) );
146 kappa = 2*sin(clusters[l].fPhi-psi)/clusters[l].fRadius;
147 if(fabs(kappa) < 1e-33)
149 //hist->Fill(kappa,psi,(int)rint(log((Float_t)charge)));
150 hist->Fill(kappa,psi,charge);
153 AliL3MemHandler::UpdateRowPointer(rowPt);
159 void AliL3HoughTransformerGlobal::TransformCircle()
162 Int_t i=0,sector,row,slice;
164 Float_t xyz[3],rpe[3],kappa,psi;
166 for(Int_t sl=GetSlice()-fNActiveSlice; sl<=GetSlice()+fNActiveSlice; sl++)
168 if(sl < 0 || sl < 18 && GetSlice() >= 18)
170 else if(sl > 35 || sl > 17 && GetSlice() <= 17)
174 cout<<"Transforming in slice "<<slice<<endl;
176 AliL3DigitRowData *rowPt = (AliL3DigitRowData*)fMemHandler[i++]->GetDataPointer(dummy);
178 for(Int_t padrow=0; padrow<AliL3Transform::GetNRows(); padrow++)
181 AliL3DigitData *digits = (AliL3DigitData*)rowPt->fDigitData;
183 for(UInt_t j=0; j<rowPt->fNDigit; j++)
185 Int_t pad = digits[j].fPad;
187 if(i==1 && pad < fPadMin[padrow])
189 if(i==fNActiveSlice*2+1 && pad>fPadMax[padrow])
192 Int_t time = digits[j].fTime;
193 Int_t charge = digits[j].fCharge;
195 if(charge > GetUpperThreshold() || charge < GetLowerThreshold())
198 AliL3Transform::Slice2Sector(slice,padrow,sector,row);
199 AliL3Transform::Raw2Local(xyz,sector,row,pad,time);
201 Rotate(xyz,i-1-fNActiveSlice);
203 AliL3Transform::XYZtoRPhiEta(rpe,xyz);
204 rpe[0] = sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
206 Int_t eta_index = GetEtaIndex(rpe[2]);
208 AliL3Histogram *hist = GetHistogram(eta_index);
210 for(Int_t b=hist->GetFirstYbin(); b<=hist->GetLastYbin(); b++)
212 psi = hist->GetBinCenterY(b);
213 kappa = 2*sin(rpe[1] - psi)/rpe[0];
215 if(fabs(kappa) < 1e-33)
218 hist->Fill(kappa,psi,charge);
219 //hist->Fill(kappa,psi,(int)rint(log((Float_t)charge)));
222 AliL3MemHandler::UpdateRowPointer(rowPt);
227 void AliL3HoughTransformerGlobal::VerifyTracks(AliL3TrackArray *tracks,Int_t &index)
229 for(int i=index; i<tracks->GetNTracks(); i++)
231 AliL3HoughTrack *tr = (AliL3HoughTrack*)tracks->GetCheckedTrack(i);
235 AliL3Transform::Local2GlobalAngle(&angle,GetSlice());
236 if(!tr->CalculateReferencePoint(angle,AliL3Transform::Row2X(fSeedPadRow)))
242 AliL3Transform::Slice2Sector(GetSlice(),fSeedPadRow,sector,row);
243 float xyz[3] = {tr->GetPointX(),tr->GetPointY(),tr->GetPointZ()};
244 AliL3Transform::Global2Raw(xyz,sector,row);
245 if(xyz[1]<0 || xyz[1]>=AliL3Transform::GetNPads(fSeedPadRow) ||
246 xyz[2]<0 || xyz[2]>=AliL3Transform::GetNTimeBins())
250 index = tracks->GetNTracks();
253 void AliL3HoughTransformerGlobal::FindPeaks(AliL3Histogram *hist,Float_t eta)
256 fPeakFinder->Reset();
257 fPeakFinder->SetHistogram(hist);
258 fPeakFinder->FindAbsMaxima();
259 if(fPeakFinder->GetWeight(0) < 1000)
262 AliL3HoughTrack *track = (AliL3HoughTrack*)fTracks->NextTrack();
263 track->SetTrackParameters(fPeakFinder->GetXPeak(0),fPeakFinder->GetYPeak(0),fPeakFinder->GetWeight(0));
265 track->SetRowRange(AliL3Transform::GetFirstRow(0),AliL3Transform::GetLastRow(5));
268 void AliL3HoughTransformerGlobal::Rotate(Float_t *xyz,Int_t rel_slice)
270 //Rotate coordinates from one slice to the slice relative to it;
274 Float_t angle = (Float_t)rel_slice*AliL3Transform::Deg2Rad(20);
275 Float_t x=xyz[0],y=xyz[1];
276 xyz[0] = x*cos(angle) - y*sin(angle);
277 xyz[1] = x*sin(angle) + y*cos(angle);
281 void AliL3HoughTransformerGlobal::DefineRegion(Float_t minpt,Float_t linephi,Int_t seedpadrow)
283 //Setup the region to be included in the transform
284 //This function should be called only once, since it is the same for all slices.
286 fSeedPadRow=seedpadrow;
289 fPadMin = new Int_t[AliL3Transform::GetNRows()];
290 fPadMax = new Int_t[AliL3Transform::GetNRows()];
292 //Phirange of data which should be included in the transform
293 //Here we assume a min pt to define it; fPtMin
294 //Based on pt (kappa) and the two points; origo and middle point, we can get psi angle
296 //Calculate the upper point, the lower point is symmetrical around the x-axis
297 //The track in this calculation has a positive charge, and the kappa sign is the opposite:
299 Float_t xyz[3],phi,phi2;
301 phi = CalculateBorder(xyz,-1); //upward bending track
302 phi2 = CalculateBorder(xyz,1); //downward bending track
306 cout<<"Phiangle "<<phi*180/AliL3Transform::Pi()<<" psi "<<fPsi*180/AliL3Transform::Pi()<<" nslices "<<fNActiveSlice<<endl;
308 Float_t rotangle = fNActiveSlice*20;
310 //Calculate the LUT for min/max pad for every padrow, and check which slices we need.
311 Int_t pad,sector,row;
312 for(Int_t i=0; i<AliL3Transform::GetNRows(); i++)
314 AliL3Transform::Slice2Sector(0,i,sector,row);
317 pad = AliL3Transform::GetNPads(i)-1;
320 AliL3Transform::Raw2Local(xyz,sector,row,pad,0);
321 if(AliL3Transform::GetPhi(xyz) > -1.*phi + AliL3Transform::Deg2Rad(rotangle))
330 while(pad < AliL3Transform::GetNPads(i))
332 AliL3Transform::Raw2Local(xyz,sector,row,pad,0);
333 if(AliL3Transform::GetPhi(xyz) < phi - AliL3Transform::Deg2Rad(rotangle))
341 cout<<"Padmax "<<fPadMax[155]<<endl;
345 Float_t AliL3HoughTransformerGlobal::CalculateBorder(Float_t *xyz,Int_t charge)
347 Double_t lineradius = sqrt(pow(AliL3Transform::Row2X(fSeedPadRow),2) + pow(AliL3Transform::GetMaxY(fSeedPadRow),2));
349 Double_t kappa = -charge*AliL3Transform::GetBField()*AliL3Transform::GetBFact()/fPtMin;
351 //Calculate the psi angle of the track = emission angle with x-axis in origo
352 if( fabs(lineradius*kappa/2) > 1)
354 cerr<<"AliL3TransformerGlobal::DefineRegion : Angle too big"<<endl;
359 Float_t psi = AliL3Transform::Deg2Rad(10) - asin(lineradius*kappa/2);
363 cout<<"Calculated psi-angle "<<fPsi<<endl;
366 track.SetFirstPoint(0,0,0);
369 track.SetCharge(charge);
370 track.CalculateHelix();
374 crossingrow = AliL3Transform::GetNRows()-1;
380 rotangle = nslices*20;
382 if(nslices==0)//here we are in local slice, so we use the appropriate function. a mess of course...
384 while(!track.GetCrossingPoint(crossingrow,xyz))
388 cerr<<"AliL3HoughTransformerGlobal::DefineRegion : Error calculating point1 on row "<<crossingrow<<endl;
396 while(!track.CalculateReferencePoint(AliL3Transform::Deg2Rad(rotangle),AliL3Transform::Row2X(crossingrow)))
400 cerr<<"AliL3HoughTransformerGlobal::DefineRegion : Error calculating point2 on row "<<crossingrow<<endl;
406 xyz[0] = track.GetPointX();
407 xyz[1] = track.GetPointY();
408 xyz[2] = track.GetPointZ();
411 Float_t phi = atan2(xyz[1],xyz[0]);
413 //Rotate coordinates back to local coordinates:
414 Rotate(xyz,-1*nslices);
417 AliL3Transform::Slice2Sector(0,crossingrow,sector,row);
418 AliL3Transform::Local2Raw(xyz,sector,row);
423 cerr<<"AliL3HoughTransformerGlobal::DefineRegion : Wrong pad, probably a deadzone... "<<xyz[1]<<endl;
427 return 0;//here you only want the crossing point with the outer padrow
429 if(xyz[1] >= AliL3Transform::GetNPads(crossingrow)) //Here the range is even one more slice away
431 cerr<<"One more slice with pad "<<xyz[1]<<endl;
434 crossingrow = AliL3Transform::GetNRows()-1;
438 if(nslices > fNActiveSlice)
439 fNActiveSlice = nslices;
441 cout<<"Calculated phi "<<phi<<" and pad "<<xyz[1]<<" on row "<<crossingrow<<endl;
445 void AliL3HoughTransformerGlobal::LoadActiveSlices(Bool_t binary)
448 UnloadActiveSlices();
449 fMemHandler = new AliL3MemHandler*[(fNActiveSlice*2 + 1)];
450 Char_t filename[1024];
453 for(Int_t sl=GetSlice()-fNActiveSlice; sl<=GetSlice()+fNActiveSlice; sl++)
455 if(sl < 0 || sl < 18 && GetSlice() >= 18)
457 else if(sl > 35 || sl > 17 && GetSlice() <= 17)
461 cout<<"Loading slice "<<slice<<endl;
462 fMemHandler[i] = new AliL3FileHandler();
463 fMemHandler[i]->Init(slice,-1);
466 sprintf(filename,"%s/binaries/digits_%d_%d_%d.raw",fPath,fEvent,slice,-1);
467 fMemHandler[i]->SetBinaryInput(filename);
468 fMemHandler[i]->CompBinary2Memory(dummy);
469 fMemHandler[i++]->CloseBinaryInput();
473 sprintf(filename,"%s/digitfile.root",fPath);
474 fMemHandler[i]->SetAliInput(filename);
475 fMemHandler[i]->AliAltroDigits2Memory(dummy,fEvent);
476 fMemHandler[i++]->CloseAliInput();
482 void AliL3HoughTransformerGlobal::UnloadActiveSlices()
486 for(Int_t i=0; i<=fNActiveSlice*2; i++)
488 if(!fMemHandler[i]) continue;
489 delete fMemHandler[i];
491 delete [] fMemHandler;
495 Int_t AliL3HoughTransformerGlobal::LoadClusterSeeds(Seed *seeds)
497 Char_t filename[1024];
499 sprintf(filename,"%s/hough/points_%d_%d_%d.raw",fPath,fEvent,GetSlice(),-1);
500 //sprintf(filename,"../tracker/points_%d_%d_%d.raw",fEvent,GetSlice(),-1);
502 if(!mem.SetBinaryInput(filename))
504 cerr<<"AliL3HoughTransformerGlobal::LoadClusterSeeds : Cannot open file "<<filename<<endl;
507 AliL3SpacePointData *points = (AliL3SpacePointData*)mem.Allocate();
508 mem.Binary2Memory(npoints,points);
509 mem.CloseBinaryInput();
512 for(UInt_t i=0; i<npoints; i++)
514 Int_t lrow = (Int_t)points[i].fPadRow;
515 if(lrow < fSeedPadRow) continue;
516 if(lrow > fSeedPadRow) break;
517 if(fabs(points[i].fY) > AliL3Transform::GetMaxY(lrow))
519 cerr<<"AliL3HoughTransformerGlobal::LoadClusterSeeds : Seeds seems not to be in local coordinates: "
520 <<points[i].fY<<endl;
523 Float_t xyz[3] = {AliL3Transform::Row2X(lrow),points[i].fY,points[i].fZ};
524 Double_t eta = AliL3Transform::GetEta(xyz);
525 seeds[counter].fPhi = atan2(xyz[1],xyz[0]);
526 seeds[counter].fRadius = sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
527 seeds[counter].fIndex = GetEtaIndex(eta);
528 seeds[counter++].fEta = eta;
530 cout<<"Loaded "<<counter<<" cluster seeds on slice "<<GetSlice()<<" padrow "<<fSeedPadRow<<endl;
535 void AliL3HoughTransformerGlobal::DisplayActiveRegion(TH2F *hist,Int_t eta_index)
537 //Fill the active region in a histogram
539 Int_t i=0,sector,row,slice;
542 for(Int_t sl=GetSlice()-fNActiveSlice; sl<=GetSlice()+fNActiveSlice; sl++)
544 if(sl < 0 || sl < 18 && GetSlice() >= 18)
546 else if(sl > 35 || sl > 17 && GetSlice() <= 17)
550 cout<<"Displaying slice "<<slice<<endl;
551 AliL3DigitRowData *rowPt = (AliL3DigitRowData*)fMemHandler[i++]->GetDataPointer(dummy);
552 for(Int_t padrow=0; padrow<AliL3Transform::GetNRows(); padrow++)
554 AliL3DigitData *digits = (AliL3DigitData*)rowPt->fDigitData;
555 for(UInt_t j=0; j<rowPt->fNDigit; j++)
557 Int_t pad = digits[j].fPad;
558 if(i==1 && pad < fPadMin[padrow])
560 if(i==fNActiveSlice*2+1 && pad>fPadMax[padrow])
562 Int_t time = digits[j].fTime;
563 AliL3Transform::Slice2Sector(slice,padrow,sector,row);
564 AliL3Transform::Raw2Local(xyz,sector,row,pad,time);
566 Rotate(xyz,i-1-fNActiveSlice);
568 Double_t eta = AliL3Transform::GetEta(xyz);
569 if(GetEtaIndex(eta) == eta_index)
570 hist->Fill(xyz[0],xyz[1]);
572 AliL3MemHandler::UpdateRowPointer(rowPt);