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()
49 AliL3HoughTransformerGlobal::AliL3HoughTransformerGlobal(Char_t *path,Int_t event)
60 fTracks = new AliL3TrackArray("AliL3HoughTrack");
61 fPeakFinder = new AliL3HoughMaxFinder("KappaPhi",1000);
64 AliL3HoughTransformerGlobal::~AliL3HoughTransformerGlobal()
79 void AliL3HoughTransformerGlobal::CreateHistograms(Float_t /*ptmin*/,Int_t nxbin,Int_t nybin)
81 //create histograms for HT
84 cerr<<"AliL3HoughTransformerGlobal::CreateHistograms : Call DefineRegion first"<<endl;
87 AliL3HoughTransformer::CreateHistograms(nxbin,fPtMin,nybin,-fPsi,fPsi);
88 //AliL3HoughTransformer::CreateHistograms(fPtMin,ptmax,ptres,nybin,fPsi);
91 void AliL3HoughTransformerGlobal::TransformCircleC()
94 AliL3Seed *clusters = new AliL3Seed[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 AliL3DigitRowData *rowPt = (AliL3DigitRowData*)fMemHandler[i++]->GetDataPointer(dummy);
113 for(Int_t padrow=0; padrow<AliL3Transform::GetNRows(); padrow++)
115 if(padrow == fSeedPadRow) continue;
116 AliL3DigitData *digits = (AliL3DigitData*)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 AliL3Transform::Slice2Sector(slice,padrow,sector,row);
134 AliL3Transform::Raw2Local(xyz,sector,row,pad,time);
136 Rotate(xyz,i-1-fNActiveSlice);
138 AliL3Transform::XYZtoRPhiEta(rpe,xyz);
139 rpe[0] = sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
141 Int_t etaindex = GetEtaIndex(rpe[2]);
143 AliL3Histogram *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 AliL3MemHandler::UpdateRowPointer(rowPt);
163 void AliL3HoughTransformerGlobal::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 AliL3DigitRowData *rowPt = (AliL3DigitRowData*)fMemHandler[i++]->GetDataPointer(dummy);
182 for(Int_t padrow=0; padrow<AliL3Transform::GetNRows(); padrow++)
185 AliL3DigitData *digits = (AliL3DigitData*)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 AliL3Transform::Slice2Sector(slice,padrow,sector,row);
203 AliL3Transform::Raw2Local(xyz,sector,row,pad,time);
205 Rotate(xyz,i-1-fNActiveSlice);
207 AliL3Transform::XYZtoRPhiEta(rpe,xyz);
208 rpe[0] = sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
210 Int_t etaindex = GetEtaIndex(rpe[2]);
212 AliL3Histogram *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 AliL3MemHandler::UpdateRowPointer(rowPt);
231 void AliL3HoughTransformerGlobal::VerifyTracks(AliL3TrackArray *tracks,Int_t &index)
233 //remove tracks which do not cross the seed padrow
234 for(int i=index; i<tracks->GetNTracks(); i++)
236 AliL3HoughTrack *tr = (AliL3HoughTrack*)tracks->GetCheckedTrack(i);
240 AliL3Transform::Local2GlobalAngle(&angle,GetSlice());
241 if(!tr->CalculateReferencePoint(angle,AliL3Transform::Row2X(fSeedPadRow)))
247 AliL3Transform::Slice2Sector(GetSlice(),fSeedPadRow,sector,row);
248 float xyz[3] = {tr->GetPointX(),tr->GetPointY(),tr->GetPointZ()};
249 AliL3Transform::Global2Raw(xyz,sector,row);
250 if(xyz[1]<0 || xyz[1]>=AliL3Transform::GetNPads(fSeedPadRow) ||
251 xyz[2]<0 || xyz[2]>=AliL3Transform::GetNTimeBins())
255 index = tracks->GetNTracks();
258 void AliL3HoughTransformerGlobal::FindPeaks(AliL3Histogram *hist,Float_t eta)
261 fPeakFinder->Reset();
262 fPeakFinder->SetHistogram(hist);
263 fPeakFinder->FindAbsMaxima();
264 if(fPeakFinder->GetWeight(0) < 1000)
267 AliL3HoughTrack *track = (AliL3HoughTrack*)fTracks->NextTrack();
268 track->SetTrackParameters(fPeakFinder->GetXPeak(0),fPeakFinder->GetYPeak(0),fPeakFinder->GetWeight(0));
270 track->SetRowRange(AliL3Transform::GetFirstRow(0),AliL3Transform::GetLastRow(5));
273 void AliL3HoughTransformerGlobal::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*AliL3Transform::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 AliL3HoughTransformerGlobal::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[AliL3Transform::GetNRows()];
295 fPadMax = new Int_t[AliL3Transform::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/AliL3Transform::Pi()<<" psi "<<fPsi*180/AliL3Transform::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<AliL3Transform::GetNRows(); i++)
319 AliL3Transform::Slice2Sector(0,i,sector,row);
322 pad = AliL3Transform::GetNPads(i)-1;
325 AliL3Transform::Raw2Local(xyz,sector,row,pad,0);
326 if(AliL3Transform::GetPhi(xyz) > -1.*phi + AliL3Transform::Deg2Rad(rotangle))
335 while(pad < AliL3Transform::GetNPads(i))
337 AliL3Transform::Raw2Local(xyz,sector,row,pad,0);
338 if(AliL3Transform::GetPhi(xyz) < phi - AliL3Transform::Deg2Rad(rotangle))
346 cout<<"Padmax "<<fPadMax[155]<<endl;
350 Float_t AliL3HoughTransformerGlobal::CalculateBorder(Float_t *xyz,Int_t charge)
352 //Define Hough space borders
353 Double_t lineradius = sqrt(pow(AliL3Transform::Row2X(fSeedPadRow),2) + pow(AliL3Transform::GetMaxY(fSeedPadRow),2));
355 Double_t kappa = -charge*AliL3Transform::GetBField()*AliL3Transform::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<<"AliL3TransformerGlobal::DefineRegion : Angle too big"<<endl;
365 Float_t psi = AliL3Transform::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 = AliL3Transform::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<<"AliL3HoughTransformerGlobal::DefineRegion : Error calculating point1 on row "<<crossingrow<<endl;
402 while(!track.CalculateReferencePoint(AliL3Transform::Deg2Rad(rotangle),AliL3Transform::Row2X(crossingrow)))
406 cerr<<"AliL3HoughTransformerGlobal::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 AliL3Transform::Slice2Sector(0,crossingrow,sector,row);
424 AliL3Transform::Local2Raw(xyz,sector,row);
429 cerr<<"AliL3HoughTransformerGlobal::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] >= AliL3Transform::GetNPads(crossingrow)) //Here the range is even one more slice away
437 cerr<<"One more slice with pad "<<xyz[1]<<endl;
440 crossingrow = AliL3Transform::GetNRows()-1;
444 if(nslices > fNActiveSlice)
445 fNActiveSlice = nslices;
447 cout<<"Calculated phi "<<phi<<" and pad "<<xyz[1]<<" on row "<<crossingrow<<endl;
451 void AliL3HoughTransformerGlobal::LoadActiveSlices(Bool_t binary)
455 UnloadActiveSlices();
456 fMemHandler = new AliL3MemHandler*[(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 AliL3FileHandler();
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 AliL3HoughTransformerGlobal::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 AliL3HoughTransformerGlobal::LoadClusterSeeds(AliL3Seed *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);
511 if(!mem.SetBinaryInput(filename))
513 cerr<<"AliL3HoughTransformerGlobal::LoadClusterSeeds : Cannot open file "<<filename<<endl;
516 AliL3SpacePointData *points = (AliL3SpacePointData*)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) > AliL3Transform::GetMaxY(lrow))
528 cerr<<"AliL3HoughTransformerGlobal::LoadClusterSeeds : Seeds seems not to be in local coordinates: "
529 <<points[i].fY<<endl;
532 Float_t xyz[3] = {AliL3Transform::Row2X(lrow),points[i].fY,points[i].fZ};
533 Double_t eta = AliL3Transform::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 AliL3HoughTransformerGlobal::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 AliL3DigitRowData *rowPt = (AliL3DigitRowData*)fMemHandler[i++]->GetDataPointer(dummy);
561 for(Int_t padrow=0; padrow<AliL3Transform::GetNRows(); padrow++)
563 AliL3DigitData *digits = (AliL3DigitData*)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 AliL3Transform::Slice2Sector(slice,padrow,sector,row);
573 AliL3Transform::Raw2Local(xyz,sector,row,pad,time);
575 Rotate(xyz,i-1-fNActiveSlice);
577 Double_t eta = AliL3Transform::GetEta(xyz);
578 if(GetEtaIndex(eta) == etaindex)
579 hist->Fill(xyz[0],xyz[1]);
581 AliL3MemHandler::UpdateRowPointer(rowPt);