3 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
4 //*-- Copyright © ASV
6 #include "AliL3StandardIncludes.h"
8 #include "AliL3Logging.h"
9 #include "AliL3HoughTransformer.h"
10 #include "AliL3MemHandler.h"
11 #include "AliL3Transform.h"
12 #include "AliL3DigitData.h"
13 #include "AliL3HistogramAdaptive.h"
19 //_____________________________________________________________
20 // AliL3HoughTransformer
22 // Hough transformation class
25 ClassImp(AliL3HoughTransformer)
27 AliL3HoughTransformer::AliL3HoughTransformer()
37 AliL3HoughTransformer::AliL3HoughTransformer(Int_t slice,Int_t patch,Int_t n_eta_segments,Bool_t DoMC) : AliL3HoughBaseTransformer(slice,patch,n_eta_segments)
53 AliL3HoughTransformer::~AliL3HoughTransformer()
59 for(Int_t i=0; i<GetNEtaSegments(); i++)
61 if(!fTrackID[i]) continue;
69 //void AliL3HoughTransformer::Init(Int_t slice=0,Int_t patch=0,Int_t n_eta_segments=100){}
71 void AliL3HoughTransformer::DeleteHistograms()
75 for(Int_t i=0; i<GetNEtaSegments(); i++)
77 if(!fParamSpace[i]) continue;
78 delete fParamSpace[i];
80 delete [] fParamSpace;
83 void AliL3HoughTransformer::CreateHistograms(Int_t nxbin,Double_t pt_min,
84 Int_t nybin,Double_t phimin,Double_t phimax)
86 //Create the histograms (parameter space).
87 //These are 2D histograms, span by kappa (curvature of track) and phi0 (emission angle with x-axis).
88 //The arguments give the range and binning;
89 //nxbin = #bins in kappa
90 //nybin = #bins in phi0
91 //pt_min = mimium Pt of track (corresponding to maximum kappa)
92 //phi_min = mimimum phi0 (degrees)
93 //phi_max = maximum phi0 (degrees)
95 Double_t x = AliL3Transform::GetBFact()*AliL3Transform::GetBField()/pt_min;
96 Double_t torad = AliL3Transform::Pi()/180;
97 CreateHistograms(nxbin,-1.*x,x,nybin,phimin*torad,phimax*torad);
100 void AliL3HoughTransformer::CreateHistograms(Int_t nxbin,Double_t xmin,Double_t xmax,
101 Int_t nybin,Double_t ymin,Double_t ymax)
104 fParamSpace = new AliL3Histogram*[GetNEtaSegments()];
106 Char_t histname[256];
107 for(Int_t i=0; i<GetNEtaSegments(); i++)
109 sprintf(histname,"paramspace_%d",i);
110 //fParamSpace[i] = new AliL3HistogramAdaptive(histname,0.1,2,0.02,nybin,ymin,ymax);
111 fParamSpace[i] = new AliL3Histogram(histname,"",nxbin,xmin,xmax,nybin,ymin,ymax);
117 AliL3Histogram *hist = fParamSpace[0];
118 Int_t ncells = (hist->GetNbinsX()+2)*(hist->GetNbinsY()+2);
119 cout<<"Allocating "<<GetNEtaSegments()*ncells*sizeof(TrackIndex)<<" bytes to fTrackID"<<endl;
120 fTrackID = new TrackIndex*[GetNEtaSegments()];
121 for(Int_t i=0; i<GetNEtaSegments(); i++)
122 fTrackID[i] = new TrackIndex[ncells];
127 void AliL3HoughTransformer::Reset()
129 //Reset all the histograms
133 LOG(AliL3Log::kWarning,"AliL3HoughTransformer::Reset","Histograms")
134 <<"No histograms to reset"<<ENDLOG;
138 for(Int_t i=0; i<GetNEtaSegments(); i++)
139 fParamSpace[i]->Reset();
143 AliL3Histogram *hist = fParamSpace[0];
144 Int_t ncells = (hist->GetNbinsX()+2)*(hist->GetNbinsY()+2);
145 for(Int_t i=0; i<GetNEtaSegments(); i++)
146 memset(fTrackID[i],0,ncells*sizeof(TrackIndex));
151 Int_t AliL3HoughTransformer::GetEtaIndex(Double_t eta)
153 //Return the histogram index of the corresponding eta.
155 Double_t etaslice = (GetEtaMax() - GetEtaMin())/GetNEtaSegments();
156 Double_t index = (eta-GetEtaMin())/etaslice;
160 inline AliL3Histogram *AliL3HoughTransformer::GetHistogram(Int_t eta_index)
162 if(!fParamSpace || eta_index >= GetNEtaSegments() || eta_index < 0)
164 if(!fParamSpace[eta_index])
166 return fParamSpace[eta_index];
169 Double_t AliL3HoughTransformer::GetEta(Int_t eta_index,Int_t slice)
171 Double_t eta_slice = (GetEtaMax()-GetEtaMin())/GetNEtaSegments();
172 Double_t eta=(Double_t)((eta_index+0.5)*eta_slice);
176 void AliL3HoughTransformer::TransformCircle()
178 //Transform the input data with a circle HT.
179 //The function loops over all the data, and transforms each pixel with the equations:
181 //kappa = 2/R*sin(phi - phi0)
183 //where R = sqrt(x*x +y*y), and phi = arctan(y/x)
185 //Each pixel then transforms into a curve in the (kappa,phi0)-space. In order to find
186 //which histogram in which the pixel should be transformed, the eta-value is calcluated
187 //and the proper histogram index is found by GetEtaIndex(eta).
190 AliL3DigitRowData *tempPt = GetDataPointer();
193 LOG(AliL3Log::kError,"AliL3HoughTransformer::TransformCircle","Data")
194 <<"No input data "<<ENDLOG;
198 //Loop over the padrows:
199 for(Int_t i=AliL3Transform::GetFirstRow(GetPatch()); i<=AliL3Transform::GetLastRow(GetPatch()); i++)
201 //Get the data on this padrow:
202 AliL3DigitData *digPt = tempPt->fDigitData;
203 if(i != (Int_t)tempPt->fRow)
205 cerr<<"AliL3HoughTransform::TransformCircle : Mismatching padrow numbering "<<i<<" "<<(Int_t)tempPt->fRow<<endl;
209 //Loop over the data on this padrow:
210 for(UInt_t j=0; j<tempPt->fNDigit; j++)
212 UShort_t charge = digPt[j].fCharge;
213 UChar_t pad = digPt[j].fPad;
214 UShort_t time = digPt[j].fTime;
215 if((Int_t)charge <= GetLowerThreshold() || (Int_t)charge > GetUpperThreshold())
221 //Transform data to local cartesian coordinates:
222 AliL3Transform::Slice2Sector(GetSlice(),i,sector,row);
223 AliL3Transform::Raw2Local(xyz,sector,row,(Int_t)pad,(Int_t)time);
226 Double_t eta = AliL3Transform::GetEta(xyz);
228 //Get the corresponding index, which determines which histogram to fill:
229 Int_t eta_index = GetEtaIndex(eta);
230 if(eta_index < 0 || eta_index >= GetNEtaSegments())
233 //Get the correct histogrampointer:
234 AliL3Histogram *hist = fParamSpace[eta_index];
237 printf("AliL3HoughTransformer::TransformCircle : Error getting histogram in index %d\n",eta_index);
241 //Do the transformation:
242 Float_t R = sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
243 Float_t phi = AliL3Transform::GetPhi(xyz);
245 //Fill the histogram along the phirange
246 for(Int_t b=hist->GetFirstYbin(); b<=hist->GetLastYbin(); b++)
248 Float_t phi0 = hist->GetBinCenterY(b);
249 Float_t kappa = 2*sin(phi - phi0)/R;
250 hist->Fill(kappa,phi0,1);//charge);
254 Int_t bin = hist->FindBin(kappa,phi0);
255 for(Int_t t=0; t<3; t++)
257 Int_t label = digPt[j].fTrackID[t];
260 for(c=0; c<MaxTrack; c++)
261 if(fTrackID[eta_index][bin].fLabel[c] == label || fTrackID[eta_index][bin].fNHits[c] == 0)
263 if(c == MaxTrack-1) cerr<<"AliL3HoughTransformer::TransformCircle : Array reached maximum!! "<<c<<endl;
264 fTrackID[eta_index][bin].fLabel[c] = label;
265 fTrackID[eta_index][bin].fNHits[c]++;
272 //Move the data pointer to the next padrow:
273 AliL3MemHandler::UpdateRowPointer(tempPt);
277 void AliL3HoughTransformer::TransformCircleC(Int_t row_range)
279 //Circle transform, using combinations of every 2 points lying
280 //on different padrows and within the same etaslice.
282 AliL3DigitRowData *tempPt = GetDataPointer();
284 LOG(AliL3Log::kError,"AliL3HoughTransformer::TransformCircleC","Data")
285 <<"No input data "<<ENDLOG;
288 for(Int_t i=AliL3Transform::GetFirstRow(GetPatch()); i<=AliL3Transform::GetLastRow(GetPatch()); i++)
290 counter += tempPt->fNDigit;
291 AliL3MemHandler::UpdateRowPointer(tempPt);
303 Digit *digits = new Digit[counter];
304 cout<<"Allocating "<<counter*sizeof(Digit)<<" bytes to digitsarray"<<endl;
306 Int_t total_digits=counter;
307 Int_t sector,row,tot_charge,pad,time,charge;
308 Double_t r1,r2,phi1,phi2,eta,kappa,phi_0;
312 tempPt = GetDataPointer();
314 for(Int_t i=AliL3Transform::GetFirstRow(GetPatch()); i<=AliL3Transform::GetLastRow(GetPatch()); i++)
316 AliL3DigitData *digPt = tempPt->fDigitData;
317 for(UInt_t di=0; di<tempPt->fNDigit; di++)
319 charge = digPt[di].fCharge;
320 pad = digPt[di].fPad;
321 time = digPt[di].fTime;
322 AliL3Transform::Slice2Sector(GetSlice(),i,sector,row);
323 AliL3Transform::Raw2Local(xyz,sector,row,(Int_t)pad,(Int_t)time);
324 eta = AliL3Transform::GetEta(xyz);
325 digits[counter].row = i;
326 digits[counter].r = sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
327 digits[counter].phi = atan2(xyz[1],xyz[0]);
328 digits[counter].eta_index = GetEtaIndex(eta);
329 digits[counter].charge = charge;
333 digits[counter].trackID[0] = digPt[di].fTrackID[0];
334 digits[counter].trackID[1] = digPt[di].fTrackID[1];
335 digits[counter].trackID[2] = digPt[di].fTrackID[2];
340 AliL3MemHandler::UpdateRowPointer(tempPt);
343 for(Int_t i=0; i<total_digits; i++)
345 if(digits[i].eta_index < 0 || digits[i].eta_index >= GetNEtaSegments()) continue;
346 Int_t ind = digits[i].eta_index;
348 for(Int_t j=i+1; j<total_digits; j++)
350 if(digits[i].row == digits[j].row) continue;
351 if(digits[i].eta_index != digits[j].eta_index) continue;
352 if(digits[i].row + row_range < digits[j].row) break;
354 //Get the correct histogrampointer:
355 AliL3Histogram *hist = fParamSpace[ind];
358 printf("AliL3HoughTransformer::TransformCircleC() : No histogram at index %d\n",ind);
363 phi1 = digits[i].phi;
365 phi2 = digits[j].phi;
366 phi_0 = atan( (r2*sin(phi1)-r1*sin(phi2))/(r2*cos(phi1)-r1*cos(phi2)) );
367 kappa = 2*sin(phi2-phi_0)/r2;
368 tot_charge = digits[i].charge + digits[j].charge;
369 hist->Fill(kappa,phi_0,1);//tot_charge);
373 Int_t bin = hist->FindBin(kappa,phi_0);
374 for(Int_t l=0; l<3; l++)
376 for(Int_t m=0; m<3; m++)
378 if(digits[i].trackID[l] == digits[j].trackID[m])
380 Int_t label = digits[i].trackID[l];
381 if(label < 0) continue;
383 for(c=0; c<MaxTrack; c++)
384 if(fTrackID[ind][bin].fLabel[c] == label || fTrackID[ind][bin].fNHits[c] == 0)
386 if(c == MaxTrack-1) cerr<<"AliL3HoughTransformer::TransformCircleC : Array reached maximum!! "<<c<<endl;
387 fTrackID[ind][bin].fLabel[c] = label;
388 fTrackID[ind][bin].fNHits[c]++;
399 void AliL3HoughTransformer::TransformLine()
401 //Do a line transform on the data.
404 AliL3DigitRowData *tempPt = GetDataPointer();
407 LOG(AliL3Log::kError,"AliL3HoughTransformer::TransformLine","Data")
408 <<"No input data "<<ENDLOG;
412 for(Int_t i=AliL3Transform::GetFirstRow(GetPatch()); i<=AliL3Transform::GetLastRow(GetPatch()); i++)
414 AliL3DigitData *digPt = tempPt->fDigitData;
415 if(i != (Int_t)tempPt->fRow)
417 printf("AliL3HoughTransform::TransformLine : Mismatching padrow numbering\n");
420 for(UInt_t j=0; j<tempPt->fNDigit; j++)
422 UShort_t charge = digPt[j].fCharge;
423 UChar_t pad = digPt[j].fPad;
424 UShort_t time = digPt[j].fTime;
425 if(charge < GetLowerThreshold())
429 AliL3Transform::Slice2Sector(GetSlice(),i,sector,row);
430 AliL3Transform::Raw2Local(xyz,sector,row,(Int_t)pad,(Int_t)time);
431 Float_t eta = AliL3Transform::GetEta(xyz);
432 Int_t eta_index = GetEtaIndex(eta);//(Int_t)(eta/etaslice);
433 if(eta_index < 0 || eta_index >= GetNEtaSegments())
436 //Get the correct histogram:
437 AliL3Histogram *hist = fParamSpace[eta_index];
440 printf("AliL3HoughTransformer::TransformLine : Error getting histogram in index %d\n",eta_index);
443 for(Int_t xbin=hist->GetFirstXbin(); xbin<hist->GetLastXbin(); xbin++)
445 Double_t theta = hist->GetBinCenterX(xbin);
446 Double_t rho = xyz[0]*cos(theta) + xyz[1]*sin(theta);
447 hist->Fill(theta,rho,charge);
450 AliL3MemHandler::UpdateRowPointer(tempPt);
455 Int_t AliL3HoughTransformer::GetTrackID(Int_t eta_index,Double_t kappa,Double_t psi)
459 cerr<<"AliL3HoughTransformer::GetTrackID : Flag switched off"<<endl;
464 if(eta_index < 0 || eta_index > GetNEtaSegments())
466 cerr<<"AliL3HoughTransformer::GetTrackID : Wrong etaindex "<<eta_index<<endl;
469 AliL3Histogram *hist = fParamSpace[eta_index];
470 Int_t bin = hist->FindBin(kappa,psi);
473 for(UInt_t i=0; i<MaxTrack; i++)
475 Int_t nhits=fTrackID[eta_index][bin].fNHits[i];
476 if(nhits == 0) break;
480 label = fTrackID[eta_index][bin].fLabel[i];
485 cout<<"AliL3HoughTransformer::GetTrackID : Compile with do_mc flag!"<<endl;