3 // Author: Constantin Loizides <mailto:loizides@ikf.uni-frankfurt.de>
4 //*-- Copyright & copy CL
6 #include "AliL3StandardIncludes.h"
8 #include "AliL3Logging.h"
9 #include "AliL3HoughTransformerLUT.h"
10 #include "AliL3Transform.h"
11 #include "AliL3MemHandler.h"
12 #include "AliL3DigitData.h"
13 #include "AliL3Histogram.h"
19 //_____________________________________________________________
20 // AliL3HoughTransformerLUT
22 // Hough transformation class using Look-UP-Tables
25 ClassImp(AliL3HoughTransformerLUT)
27 AliL3HoughTransformerLUT::AliL3HoughTransformerLUT() : AliL3HoughBaseTransformer()
56 AliL3HoughTransformerLUT::AliL3HoughTransformerLUT(Int_t slice,Int_t patch,Int_t n_eta_segments) : AliL3HoughBaseTransformer(slice,patch,n_eta_segments)
83 Init(slice,patch,n_eta_segments);
86 AliL3HoughTransformerLUT::~AliL3HoughTransformerLUT()
93 for(Int_t i=0; i<fNEtas; i++)
95 if(!fTrackID[i]) continue;
114 void AliL3HoughTransformerLUT::DeleteHistograms()
117 delete[] fLUT2sinphi0;
118 delete[] fLUT2cosphi0;
129 for(Int_t i=0; i<fNEtas; i++)
131 if(!fParamSpace[i]) continue;
132 delete fParamSpace[i];
134 delete [] fParamSpace;
138 void AliL3HoughTransformerLUT::Init(Int_t slice,Int_t patch,Int_t n_eta_segments)
140 AliL3HoughBaseTransformer::Init(slice,patch,n_eta_segments);
142 //delete old LUT tables
154 fMinRow=AliL3Transform::GetFirstRow(patch);;
155 fMaxRow=AliL3Transform::GetLastRow(patch);;
156 fNRows=AliL3Transform::GetNRows(patch);;
157 fNEtas=n_eta_segments;
158 if(fNEtas!=GetNEtaSegments()) {
159 cerr << "AliL3HoughTransformerLUT::Init -> Error: Number of Etas must be equal!" << endl;
163 AliL3Transform::Slice2Sector(slice,fMinRow,fSector,fSectorRow);
164 fZSign = slice < 18 ? 1:-1;
166 fZLengthPlusOff=AliL3Transform::GetZLength()+AliL3Transform::GetZOffset();
167 fTimeWidth=AliL3Transform::GetZWidth();
170 if(fSector<AliL3Transform::GetNSectorLow())
171 fPadPitch=AliL3Transform::GetPadPitchWidthLow();
173 fPadPitch=AliL3Transform::GetPadPitchWidthUp();
175 Float_t etamax_=GetEtaMax();
176 Float_t etamin_=GetEtaMin();
177 fEtaSlice=(etamax_-etamin_)/n_eta_segments;
179 //lookup tables for X and Y
180 fLUTX=new Float_t[fNRows];
181 fLUTY=new Float_t[fNRows];
182 for(Int_t rr=0;rr<fNRows;rr++){
183 fLUTX[rr]=Float_t(AliL3Transform::Row2X(rr+fMinRow));
184 fLUTY[rr]=Float_t(0.5*(AliL3Transform::GetNPads(rr+fMinRow)-1)*fPadPitch);
185 //cout << rr << ": " << (Float_t)fLUTX[rr] << " " << (Float_t)fLUTY[rr] << endl;
188 //lookup tables for rz2s <=> etas
189 fLUTEta=new Float_t[fNEtas];
190 for(Int_t rr=0;rr<fNEtas;rr++){
191 Float_t eta=etamin_+(rr+1)*fEtaSlice;
192 fLUTEta[rr]=CalcRoverZ2(eta);
193 //cout << rr << ": " << eta << " " << fLUTEta[rr] << " " << GetEta(rr,fSlice) << endl;
197 void AliL3HoughTransformerLUT::CreateHistograms(Int_t nxbin,Double_t pt_min,Int_t nybin,Double_t phimin,Double_t phimax)
199 //Create the histograms (parameter space).
200 //These are 2D histograms, span by kappa (curvature of track) and phi0 (emission angle with x-axis).
201 //The arguments give the range and binning;
202 //nxbin = #bins in kappa
203 //nybin = #bins in phi0
204 //pt_min = mimium Pt of track (corresponding to maximum kappa)
205 //phi_min = mimimum phi0 (degrees)
206 //phi_max = maximum phi0 (degrees)
208 Double_t x = AliL3Transform::GetBFact()*AliL3Transform::GetBField()/pt_min;
209 Double_t torad = AliL3Transform::Pi()/180;
210 CreateHistograms(nxbin,-1.*x,x,nybin,phimin*torad,phimax*torad);
213 void AliL3HoughTransformerLUT::CreateHistograms(Int_t nxbin,Double_t xmin,Double_t xmax,Int_t nybin,Double_t ymin,Double_t ymax)
215 fParamSpace = new AliL3Histogram*[fNEtas];
217 Char_t histname[256];
218 for(Int_t i=0; i<fNEtas; i++)
220 sprintf(histname,"paramspace_%d",i);
221 fParamSpace[i] = new AliL3Histogram(histname,"",nxbin,xmin,xmax,nybin,ymin,ymax);
227 AliL3Histogram *hist = fParamSpace[0];
228 Int_t ncells = (hist->GetNbinsX()+2)*(hist->GetNbinsY()+2);
229 cout<<"Allocating "<<fNEtas*ncells*sizeof(TrackIndex)<<" bytes to fTrackID"<<endl;
230 fTrackID = new TrackIndex*[fNEtas];
231 for(Int_t i=0; i<fNEtas; i++)
232 fTrackID[i] = new TrackIndex[ncells];
236 //create lookup table for sin and cos
239 fLUTphi0=new Float_t[fNPhi0];
240 fLUT2sinphi0=new Float_t[fNPhi0];
241 fLUT2cosphi0=new Float_t[fNPhi0];
242 fLUTKappa=new Float_t[fNPhi0];
243 Float_t diff=(ymax-ymin)/nybin;
244 Float_t phi0=ymin-0.5*diff;
245 for(Int_t i=0; i<fNPhi0; i++){
248 fLUT2sinphi0[i]=2.*sin(phi0);
249 fLUT2cosphi0[i]=2.*cos(phi0);
251 //cout << i << ": " << fLUTphi0[i] << " " << fLUT2sinphi0[i] << " " << fLUT2cosphi0[i] << endl;
255 void AliL3HoughTransformerLUT::Reset()
257 //Reset all the histograms
261 LOG(AliL3Log::kWarning,"AliL3HoughTransformer::Reset","Histograms")
262 <<"No histograms to reset"<<ENDLOG;
266 for(Int_t i=0; i<fNEtas; i++)
267 fParamSpace[i]->Reset();
271 AliL3Histogram *hist = fParamSpace[0];
272 Int_t ncells = (hist->GetNbinsX()+2)*(hist->GetNbinsY()+2);
273 for(Int_t i=0; i<fNEtas; i++)
274 memset(fTrackID[i],0,ncells*sizeof(TrackIndex));
279 Int_t AliL3HoughTransformerLUT::GetEtaIndex(Double_t eta)
281 //Return the histogram index of the corresponding eta.
283 Float_t rz2=CalcRoverZ2(eta);
284 return FindIndex(rz2);
287 Int_t AliL3HoughTransformerLUT::FindIndex(Float_t rz2, Int_t start)
289 //could improve search through devide and conquere strategy
294 while((index<fNEtas)&&(rz2<=fLUTEta[index])){
298 while((index>=0)&&(rz2>fLUTEta[index])){
302 //cout << start << " - " << index << ": " << rz2 << " " << fLUTEta[index] << endl;
306 inline AliL3Histogram *AliL3HoughTransformerLUT::GetHistogram(Int_t eta_index)
308 if(!fParamSpace || eta_index >= fNEtas || eta_index < 0)
310 if(!fParamSpace[eta_index])
312 return fParamSpace[eta_index];
315 Float_t AliL3HoughTransformerLUT::CalcRoverZ2(Float_t eta)
317 Float_t e=exp(2*eta);
318 Float_t ret=(e+1)/(e-1);
323 Float_t AliL3HoughTransformerLUT::CalcEta(Float_t roverz2)
325 Float_t rz=sqrt(roverz2);
327 Float_t ret=(1+rz)/(rz-1);
332 Float_t AliL3HoughTransformerLUT::CalcX(Int_t row)
337 Float_t AliL3HoughTransformerLUT::CalcY(Int_t pad,Int_t row)
339 return pad*fPadPitch-fLUTY[row];
342 Float_t AliL3HoughTransformerLUT::CalcZ(Int_t time)
344 Float_t ret=time*fTimeWidth;
345 if(fZSign>0) ret=fZLengthPlusOff-ret;
346 else ret=ret-fZLengthPlusOff;
350 Double_t AliL3HoughTransformerLUT::GetEta(Int_t eta_index,Int_t slice)
352 if(eta_index >= fNEtas || eta_index < 0){
353 //LOG(AliL3Log::kWarning,"AliL3HoughTransformerLUT::GetEta","Index") << "Index out of range."<<ENDLOG;
357 //LOG(AliL3Log::kWarning,"AliL3HoughTransformerLUT::GetEta","Index") << "Given slice does not match internal slice."<<ENDLOG;
361 return (CalcEta(fLUTEta[eta_index])-0.5*fEtaSlice);
364 void AliL3HoughTransformerLUT::TransformCircle()
366 //Transform the input data with a circle HT.
367 //The function loops over all the data, and transforms each pixel with the equation:
369 //kappa = 2/R^2 * (y*cos(phi0) - x*sin(phi0) )
371 //where R^2 = x^2 + y^2
373 //Each pixel then transforms into a curve in the (kappa,phi0)-space. In order to find
374 //which histogram in which the pixel should be transformed, the eta-value is calcluated
375 //and the proper histogram index is found by GetEtaIndex(eta).
377 AliL3DigitRowData *tempPt = GetDataPointer();
380 LOG(AliL3Log::kError,"AliL3HoughTransformerLUT::TransformCircle","Data")
381 <<"No input data "<<ENDLOG;
385 //Loop over the padrows:
386 for(Int_t i=fMinRow, row=0; i<=fMaxRow; i++, row++)
388 //Get the data on this padrow:
389 AliL3DigitData *digPt = tempPt->fDigitData;
390 if(i != (Int_t)tempPt->fRow)
392 LOG(AliL3Log::kError,"AliL3HoughTransformerLUT::TransformCircle","Data")
393 <<"AliL3HoughTransformerLUT::TransformCircle : Mismatching padrow numbering "<<i<<" != "<<(Int_t)tempPt->fRow<<ENDLOG;
397 Float_t x = CalcX(row);
404 //Loop over the data on this padrow:
405 for(UInt_t j=0; j<tempPt->fNDigit; j++)
407 UShort_t charge = digPt[j].fCharge;
410 if((Int_t)charge <= GetLowerThreshold() || (Int_t)charge > GetUpperThreshold())
413 UChar_t pad = digPt[j].fPad;
414 UShort_t time = digPt[j].fTime;
416 if(fLastPad!=pad){ //only update if necessary
422 for(Int_t b=0; b<fNPhi0; b++)
423 fLUTKappa[b]=R2*(y*fLUT2cosphi0[b]-x*fLUT2sinphi0[b]);
428 Float_t z = CalcZ(time);
431 Float_t rz2 = 1 + r2/(z*z);
432 Int_t eta_index = FindIndex(rz2,fLastIndex);
433 //cout << row << " " << (int)pad << " " << (int)time << " " << eta_index <<" " <<fLastIndex<< endl;
434 fLastIndex=eta_index;
435 if(eta_index < 0 || eta_index >= fNEtas){
436 //LOG(AliL3Log::kWarning,"AliL3HoughTransformerLUT::TransformCircle","Histograms")<<"No histograms corresponding to eta index value of "<<eta_index<<"."<<ENDLOG;
440 //Get the correct histogrampointer:
441 AliL3Histogram *hist = fParamSpace[eta_index];
443 //LOG(AliL3Log::kWarning,"AliL3HoughTransformerLUT::TransformCircle","Histograms")<<"Error getting histogram in index "<<eta_index<<"."<<ENDLOG;
447 //Fill the histogram along the phirange
449 for(Int_t b=0; b<fNPhi0; b++){
450 //Float_t kappa=R2*(y*fLUT2cosphi0[b]-x*fLUT2sinphi0[b]);
451 Float_t kappa=fLUTKappa[b];
452 hist->Fill(kappa,fLUTphi0[b],charge);
453 //cout << kappa << " " << fLUTphi0[b] << " " << charge << endl;
458 Int_t bin = hist->FindBin(kappa,phi0);
459 for(Int_t t=0; t<3; t++)
461 Int_t label = digPt[j].fTrackID[t];
464 for(c=0; c<MaxTrack; c++)
465 if(fTrackID[eta_index][bin].fLabel[c] == label || fTrackID[eta_index][bin].fNHits[c] == 0)
467 if(c == MaxTrack-1) LOG(AliL3Log::kError,"AliL3HoughTransformerLUT::TransformCircle","MCData") <<"Array reached maximum!! "<<c<<endl;
468 fTrackID[eta_index][bin].fLabel[c] = label;
469 fTrackID[eta_index][bin].fNHits[c]++;
475 //Move the data pointer to the next padrow:
476 AliL3MemHandler::UpdateRowPointer(tempPt);
480 Int_t AliL3HoughTransformerLUT::GetTrackID(Int_t eta_index,Double_t kappa,Double_t psi)
484 cerr<<"AliL3HoughTransformer::GetTrackID : Flag switched off"<<endl;
489 if(eta_index < 0 || eta_index > fNEtas)
491 cerr<<"AliL3HoughTransformer::GetTrackID : Wrong etaindex "<<eta_index<<endl;
494 AliL3Histogram *hist = fParamSpace[eta_index];
495 Int_t bin = hist->FindBin(kappa,psi);
498 for(UInt_t i=0; i<MaxTrack; i++)
500 Int_t nhits=fTrackID[eta_index][bin].fNHits[i];
501 if(nhits == 0) break;
505 label = fTrackID[eta_index][bin].fLabel[i];
510 cout<<"AliL3HoughTransformer::GetTrackID : Compile with do_mc flag!"<<endl;
514 void AliL3HoughTransformerLUT::Print()
516 cout << "fSlice: " << GetSlice() << endl;
517 cout << "fPatch: " << GetPatch() << endl;
518 cout << "fSector: " << fSector << endl;
519 cout << "fSectorRow: " << fSectorRow << endl;
520 cout << "fMinRow: " << fMinRow << endl;
521 cout << "fMaxRow: " << fMaxRow << endl;
522 cout << "fNRows: " << fNRows << endl;
523 cout << "fNEtas: " << fNEtas << endl;
524 cout << "fNPhi0: " << fNPhi0 << endl;
525 cout << "fZSign: " << fZSign << endl;
526 cout << "fZLengthPlusOff: " << fZLengthPlusOff << endl;
527 cout << "fPadPitch: " << fPadPitch << endl;
528 cout << "fTimeWidth: " << fTimeWidth << endl;
531 cout << "fLUTX " << fNRows << endl;
532 for(Int_t i=0;i<fNRows;i++) cout << "fLUTX[" << i << "]=" << (Float_t)fLUTX[i] << endl;
533 cout << "fLUTY " << fNRows << endl;
534 for(Int_t i=0;i<fNRows;i++) cout << "fLUTY[" << i << "]=" << fLUTY[i] << endl;
536 cout << "fLUTEta " << fNEtas << endl;
537 for(Int_t i=0;i<fNEtas;i++) cout << "fLUTEta[" << i << "]=" << fLUTEta[i] << endl;
539 cout << "fLUTphi0 " << fNPhi0 << endl;
540 for(Int_t i=0;i<fNPhi0;i++) cout << "fLUTPhi0[" << i << "]=" << fLUTphi0[i] << endl;
541 cout << "fLUT2sinphi0 " << fNPhi0 << endl;
542 for(Int_t i=0;i<fNPhi0;i++) cout << "fLUT2sinphi0[" << i << "]=" << fLUT2sinphi0[i] << endl;
543 cout << "fLUT2cosphi0 " << fNPhi0 << endl;
544 for(Int_t i=0;i<fNPhi0;i++) cout << "fLUT2cosphi0[" << i << "]=" << fLUT2cosphi0[i] << endl;