3 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
4 //*-- Copyright © ALICE HLT Group
7 #include "AliL3StandardIncludes.h"
14 #include "AliL3Logging.h"
15 #include "AliL3HoughMaxFinder.h"
16 #include "AliL3Histogram.h"
17 #include "AliL3TrackArray.h"
18 #include "AliL3HoughTrack.h"
19 #include "AliL3Transform.h"
20 #include "AliL3HoughTransformerRow.h"
26 /** \class AliL3HoughMaxFinder
28 //_____________________________________________________________
29 // AliL3HoughMaxFinder
36 ClassImp(AliL3HoughMaxFinder)
39 AliL3HoughMaxFinder::AliL3HoughMaxFinder()
43 fCurrentEtaSlice = -1;
49 fN1PeaksPrevEtaSlice=0;
50 fN2PeaksPrevEtaSlice=0;
65 AliL3HoughMaxFinder::AliL3HoughMaxFinder(Char_t *histotype,Int_t nmax,AliL3Histogram *hist)
69 //fTracks = new AliL3TrackArray("AliL3HoughTrack");
70 if(strcmp(histotype,"KappaPhi")==0) fHistoType='c';
71 if(strcmp(histotype,"DPsi")==0) fHistoType='l';
73 fCurrentEtaSlice = -1;
81 fXPeaks = new Float_t[fNMax];
82 fYPeaks = new Float_t[fNMax];
83 fWeight = new Int_t[fNMax];
84 fSTARTXPeaks = new Int_t[fNMax];
85 fSTARTYPeaks = new Int_t[fNMax];
86 fENDXPeaks = new Int_t[fNMax];
87 fENDYPeaks = new Int_t[fNMax];
88 fSTARTETAPeaks = new Int_t[fNMax];
89 fENDETAPeaks = new Int_t[fNMax];
96 AliL3HoughMaxFinder::~AliL3HoughMaxFinder()
106 delete [] fSTARTXPeaks;
108 delete [] fSTARTYPeaks;
110 delete [] fENDXPeaks;
112 delete [] fENDYPeaks;
114 delete [] fSTARTETAPeaks;
116 delete [] fENDETAPeaks;
123 void AliL3HoughMaxFinder::Reset()
125 for(Int_t i=0; i<fNMax; i++)
138 fN1PeaksPrevEtaSlice=0;
139 fN2PeaksPrevEtaSlice=0;
142 void AliL3HoughMaxFinder::CreateNtuppel()
145 //content#; neighbouring bins of the peak.
146 fNtuppel = new TNtuple("ntuppel","Peak charateristics","kappa:phi0:weigth:content3:content5:content1:content7");
147 fNtuppel->SetDirectory(0);
151 void AliL3HoughMaxFinder::WriteNtuppel(Char_t *filename)
154 TFile *file = TFile::Open(filename,"RECREATE");
157 cerr<<"AliL3HoughMaxFinder::WriteNtuppel : Error opening file "<<filename<<endl;
165 void AliL3HoughMaxFinder::FindAbsMaxima()
170 cerr<<"AliL3HoughMaxFinder::FindAbsMaxima : No histogram"<<endl;
173 AliL3Histogram *hist = fCurrentHisto;
175 if(hist->GetNEntries() == 0)
178 Int_t xmin = hist->GetFirstXbin();
179 Int_t xmax = hist->GetLastXbin();
180 Int_t ymin = hist->GetFirstYbin();
181 Int_t ymax = hist->GetLastYbin();
183 Double_t value,max_value=0;
185 Int_t max_xbin=0,max_ybin=0;
186 for(Int_t xbin=xmin; xbin<=xmax; xbin++)
188 for(Int_t ybin=ymin; ybin<=ymax; ybin++)
190 bin = hist->GetBin(xbin,ybin);
191 value = hist->GetBinContent(bin);
206 cerr<<"AliL3HoughMaxFinder::FindAbsMaxima : Array out of range : "<<fNPeaks<<endl;
210 Double_t max_x = hist->GetBinCenterX(max_xbin);
211 Double_t max_y = hist->GetBinCenterY(max_ybin);
212 fXPeaks[fNPeaks] = max_x;
213 fYPeaks[fNPeaks] = max_y;
214 fWeight[fNPeaks] = (Int_t)max_value;
220 Int_t bin3 = hist->GetBin(max_xbin-1,max_ybin);
221 Int_t bin5 = hist->GetBin(max_xbin+1,max_ybin);
222 Int_t bin1 = hist->GetBin(max_xbin,max_ybin-1);
223 Int_t bin7 = hist->GetBin(max_xbin,max_ybin+1);
225 fNtuppel->Fill(max_x,max_y,max_value,hist->GetBinContent(bin3),hist->GetBinContent(bin5),hist->GetBinContent(bin1),hist->GetBinContent(bin7));
230 void AliL3HoughMaxFinder::FindBigMaxima()
233 AliL3Histogram *hist = fCurrentHisto;
235 if(hist->GetNEntries() == 0)
238 Int_t xmin = hist->GetFirstXbin();
239 Int_t xmax = hist->GetLastXbin();
240 Int_t ymin = hist->GetFirstYbin();
241 Int_t ymax = hist->GetLastYbin();
242 Int_t bin[25],bin_index;
245 for(Int_t xbin=xmin+2; xbin<xmax-3; xbin++)
247 for(Int_t ybin=ymin+2; ybin<ymax-3; ybin++)
250 for(Int_t xb=xbin-2; xb<=xbin+2; xb++)
252 for(Int_t yb=ybin-2; yb<=ybin+2; yb++)
254 bin[bin_index]=hist->GetBin(xb,yb);
255 value[bin_index]=hist->GetBinContent(bin[bin_index]);
259 if(value[12]==0) continue;
263 if(value[b] > value[12] || b==bin_index) break;
265 //printf("b %d\n",b);
272 cerr<<"AliL3HoughMaxFinder::FindBigMaxima : Array out of range "<<fNPeaks<<endl;
276 Double_t max_x = hist->GetBinCenterX(xbin);
277 Double_t max_y = hist->GetBinCenterY(ybin);
278 fXPeaks[fNPeaks] = max_x;
279 fYPeaks[fNPeaks] = max_y;
286 void AliL3HoughMaxFinder::FindMaxima(Int_t threshold)
288 //Locate all the maxima in input histogram.
289 //Maxima is defined as bins with more entries than the
290 //immediately neighbouring bins.
292 if(fCurrentHisto->GetNEntries() == 0)
295 Int_t xmin = fCurrentHisto->GetFirstXbin();
296 Int_t xmax = fCurrentHisto->GetLastXbin();
297 Int_t ymin = fCurrentHisto->GetFirstYbin();
298 Int_t ymax = fCurrentHisto->GetLastYbin();
302 //Float_t max_kappa = 0.001;
303 //Float_t max_phi0 = 0.08;
305 for(Int_t xbin=xmin+1; xbin<=xmax-1; xbin++)
307 for(Int_t ybin=ymin+1; ybin<=ymax-1; ybin++)
309 bin[0] = fCurrentHisto->GetBin(xbin-1,ybin-1);
310 bin[1] = fCurrentHisto->GetBin(xbin,ybin-1);
311 bin[2] = fCurrentHisto->GetBin(xbin+1,ybin-1);
312 bin[3] = fCurrentHisto->GetBin(xbin-1,ybin);
313 bin[4] = fCurrentHisto->GetBin(xbin,ybin);
314 bin[5] = fCurrentHisto->GetBin(xbin+1,ybin);
315 bin[6] = fCurrentHisto->GetBin(xbin-1,ybin+1);
316 bin[7] = fCurrentHisto->GetBin(xbin,ybin+1);
317 bin[8] = fCurrentHisto->GetBin(xbin+1,ybin+1);
318 value[0] = fCurrentHisto->GetBinContent(bin[0]);
319 value[1] = fCurrentHisto->GetBinContent(bin[1]);
320 value[2] = fCurrentHisto->GetBinContent(bin[2]);
321 value[3] = fCurrentHisto->GetBinContent(bin[3]);
322 value[4] = fCurrentHisto->GetBinContent(bin[4]);
323 value[5] = fCurrentHisto->GetBinContent(bin[5]);
324 value[6] = fCurrentHisto->GetBinContent(bin[6]);
325 value[7] = fCurrentHisto->GetBinContent(bin[7]);
326 value[8] = fCurrentHisto->GetBinContent(bin[8]);
329 if(value[4]>value[0] && value[4]>value[1] && value[4]>value[2]
330 && value[4]>value[3] && value[4]>value[5] && value[4]>value[6]
331 && value[4]>value[7] && value[4]>value[8])
333 //Found a local maxima
334 Float_t max_x = fCurrentHisto->GetBinCenterX(xbin);
335 Float_t max_y = fCurrentHisto->GetBinCenterY(ybin);
337 if((Int_t)value[4] <= threshold) continue;//central bin below threshold
340 cout<<"AliL3HoughMaxFinder::FindMaxima : Array out of range "<<fNPeaks<<endl;
344 //Check the gradient:
345 if(value[3]/value[4] > fGradX && value[5]/value[4] > fGradX)
348 if(value[1]/value[4] > fGradY && value[7]/value[4] > fGradY)
351 fXPeaks[fNPeaks] = max_x;
352 fYPeaks[fNPeaks] = max_y;
353 fWeight[fNPeaks] = (Int_t)value[4];
357 //Check if the peak is overlapping with a previous:
358 Bool_t bigger = kFALSE;
359 for(Int_t p=0; p<fNPeaks; p++)
361 if(fabs(max_x - fXPeaks[p]) < max_kappa && fabs(max_y - fYPeaks[p]) < max_phi0)
364 if(value[4] > fWeight[p]) //this peak is bigger.
368 fWeight[p] = (Int_t)value[4];
371 continue; //previous peak is bigger.
374 if(!bigger) //there were no overlapping peaks.
376 fXPeaks[fNPeaks] = max_x;
377 fYPeaks[fNPeaks] = max_y;
378 fWeight[fNPeaks] = (Int_t)value[4];
394 void AliL3HoughMaxFinder::FindAdaptedPeaks(Int_t kappawindow,Float_t cut_ratio)
396 //Peak finder which looks for peaks with a certain shape.
397 //The first step involves a pre-peak finder, which looks for peaks
398 //in windows (size controlled by kappawindow) summing over each psi-bin.
399 //These pre-preaks are then matched between neighbouring kappa-bins to
400 //look for real 2D peaks exhbiting the typical cross-shape in the Hough circle transform.
401 //The maximum bin within this region is marked as the peak itself, and
402 //a few checks is performed to avoid the clear fake peaks (asymmetry check etc.)
405 AliL3Histogram *hist = fCurrentHisto;
409 cerr<<"AliL3HoughMaxFinder : No histogram!"<<endl;
413 if(hist->GetNEntries() == 0)
416 Int_t xmin = hist->GetFirstXbin();
417 Int_t xmax = hist->GetLastXbin();
418 Int_t ymin = hist->GetFirstYbin();
419 Int_t ymax = hist->GetLastYbin();
422 //Start by looking for pre-peaks:
424 Window **local_maxima = new Window*[hist->GetNbinsY()];
426 Short_t *nmaxs = new Short_t[hist->GetNbinsY()];
427 Int_t n,last_sum,sum;
428 Bool_t sum_was_rising;
429 for(Int_t ybin=ymin; ybin<=ymax; ybin++)
431 local_maxima[ybin-ymin] = new Window[hist->GetNbinsX()];
432 nmaxs[ybin-ymin] = 0;
436 for(Int_t xbin=xmin; xbin<=xmax-kappawindow; xbin++)
439 for(Int_t lbin=xbin; lbin<xbin+kappawindow; lbin++)
440 sum += hist->GetBinContent(hist->GetBin(lbin,ybin));
445 if(sum_was_rising)//Previous sum was a local maxima
447 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].start = xbin-1;
448 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].sum = last_sum;
461 Int_t *starts = new Int_t[hist->GetNbinsY()+1];
462 Int_t *maxs = new Int_t[hist->GetNbinsY()+1];
464 for(Int_t ybin=ymax; ybin >= ymin+1; ybin--)
466 for(Int_t i=0; i<nmaxs[ybin-ymin]; i++)
468 Int_t lw = local_maxima[ybin-ymin][i].sum;
471 continue; //already used
473 Int_t maxvalue=0,maxybin=0,maxxbin=0,maxwindow=0;
474 for(Int_t k=local_maxima[ybin-ymin][i].start; k<local_maxima[ybin-ymin][i].start + kappawindow; k++)
475 if(hist->GetBinContent(hist->GetBin(k,ybin)) > maxvalue)
477 maxvalue = hist->GetBinContent(hist->GetBin(k,ybin));
482 //start expanding in the psi-direction:
484 Int_t lb = local_maxima[ybin-ymin][i].start;
486 starts[ybin] = local_maxima[ybin-ymin][i].start;
487 maxs[ybin] = maxxbin;
488 Int_t yl=ybin-1,nybins=1;
490 //cout<<"Starting search at ybin "<<ybin<<" start "<<lb<<" with sum "<<local_maxima[ybin-ymin][i].sum<<endl;
494 for(Int_t j=0; j<nmaxs[yl-ymin]; j++)
496 if( local_maxima[yl-ymin][j].start - lb < 0) continue;
497 if( local_maxima[yl-ymin][j].start < lb + kappawindow + match &&
498 local_maxima[yl-ymin][j].start >= lb && local_maxima[yl-ymin][j].sum > 0)
501 //cout<<"match at ybin "<<yl<<" yvalue "<<hist->GetBinCenterY(yl)<<" start "<<local_maxima[yl-ymin][j].start<<" sum "<<local_maxima[yl-ymin][j].sum<<endl;
503 Int_t lmaxvalue=0,lmaxxbin=0;
504 for(Int_t k=local_maxima[yl-ymin][j].start; k<local_maxima[yl-ymin][j].start + kappawindow; k++)
506 if(hist->GetBinContent(hist->GetBin(k,yl)) > maxvalue)
508 maxvalue = hist->GetBinContent(hist->GetBin(k,yl));
513 if(hist->GetBinContent(hist->GetBin(k,yl)) > lmaxvalue)//local maxima value
515 lmaxvalue=hist->GetBinContent(hist->GetBin(k,yl));
520 starts[yl] = local_maxima[yl-ymin][j].start;
522 local_maxima[yl-ymin][j].sum=-1; //Mark as used
524 lb = local_maxima[yl-ymin][j].start;
525 break;//Since we found a match in this bin, we dont have to search it anymore, goto next bin.
528 if(!found || yl == ymin)//no more local maximas to be matched, so write the final peak and break the expansion:
532 //cout<<"ystart "<<ystart<<" and nybins "<<nybins<<endl;
534 Bool_t truepeak=kTRUE;
536 //cout<<"Maxima found at xbin "<<maxxbin<<" ybin "<<maxybin<<" value "<<maxvalue<<endl;
537 //cout<<"Starting to sum at xbin "<<starts[maxybin-ymin]<<endl;
540 //Look in a window on both sides to probe the asymmetry
541 Float_t right=0,left=0;
542 for(Int_t w=maxxbin+1; w<=maxxbin+3; w++)
544 for(Int_t r=maxybin+1; r<=maxybin+3; r++)
546 right += (Float_t)hist->GetBinContent(hist->GetBin(w,r));
550 for(Int_t w=maxxbin-1; w>=maxxbin-3; w--)
552 for(Int_t r=maxybin+1; r<=maxybin+3; r++)
554 left += (Float_t)hist->GetBinContent(hist->GetBin(w,r));
558 //cout<<"ratio "<<right/left<<endl;
560 Float_t upper_ratio=1,lower_ratio=1;
562 upper_ratio = right/left;
565 for(Int_t w=maxxbin+1; w<=maxxbin+3; w++)
567 for(Int_t r=maxybin-1; r>=maxybin-3; r--)
569 right += (Float_t)hist->GetBinContent(hist->GetBin(w,r));
573 for(Int_t w=maxxbin-1; w>=maxxbin-3; w--)
575 for(Int_t r=maxybin-1; r>=maxybin-3; r--)
577 left += (Float_t)hist->GetBinContent(hist->GetBin(w,r));
581 //cout<<"ratio "<<left/right<<endl;
584 lower_ratio = left/right;
586 if(upper_ratio > cut_ratio || lower_ratio > cut_ratio)
592 fXPeaks[fNPeaks] = hist->GetBinCenterX(maxxbin);
593 fYPeaks[fNPeaks] = hist->GetBinCenterY(maxybin);
594 fWeight[fNPeaks] = maxvalue;
598 //Calculate the peak using weigthed means:
601 for(Int_t k=maxybin-1; k<=maxybin+1; k++)
604 for(Int_t l=starts[k]; l<starts[k]+kappawindow; l++)
606 lsum += (Float_t)hist->GetBinContent(hist->GetBin(l,k));
607 sum += (Float_t)hist->GetBinContent(hist->GetBin(l,k));
609 fYPeaks[fNPeaks] += lsum*hist->GetBinCenterY(k);
611 fYPeaks[fNPeaks] /= sum;
613 if(fYPeaks[fNPeaks] < hist->GetBinCenterY(hist->FindYbin(fYPeaks[fNPeaks])))
615 ybin1 = hist->FindYbin(fYPeaks[fNPeaks])-1;
620 ybin1 = hist->FindYbin(fYPeaks[fNPeaks]);
624 Float_t kappa1=0,kappa2=0;
626 for(Int_t k=starts[ybin1]; k<starts[ybin1] + kappawindow; k++)
628 kappa1 += hist->GetBinCenterX(k)*hist->GetBinContent(hist->GetBin(k,ybin1));
629 sum += (Float_t)hist->GetBinContent(hist->GetBin(k,ybin1));
633 for(Int_t k=starts[ybin2]; k<starts[ybin2] + kappawindow; k++)
635 kappa2 += hist->GetBinCenterX(k)*hist->GetBinContent(hist->GetBin(k,ybin2));
636 sum += (Float_t)hist->GetBinContent(hist->GetBin(k,ybin2));
640 fXPeaks[fNPeaks] = ( kappa1*( hist->GetBinCenterY(ybin2) - fYPeaks[fNPeaks] ) +
641 kappa2*( fYPeaks[fNPeaks] - hist->GetBinCenterY(ybin1) ) ) /
642 (hist->GetBinCenterY(ybin2) - hist->GetBinCenterY(ybin1));
651 yl--;//Search continues...
656 for(Int_t i=0; i<hist->GetNbinsY(); i++)
657 delete local_maxima[i];
659 delete [] local_maxima;
667 Int_t start_position;
689 void AliL3HoughMaxFinder::FindAdaptedRowPeaks(Int_t kappawindow,Int_t xsize,Int_t ysize)
692 AliL3Histogram *hist = fCurrentHisto;
696 cerr<<"AliL3HoughMaxFinder : No histogram!"<<endl;
700 if(hist->GetNEntries() == 0)
703 Int_t xmin = hist->GetFirstXbin();
704 Int_t xmax = hist->GetLastXbin();
705 Int_t ymin = hist->GetFirstYbin();
706 Int_t ymax = hist->GetLastYbin();
708 //Start by looking for pre-peaks:
710 PreYPeak **local_maxima = new PreYPeak*[hist->GetNbinsY()];
712 Short_t *nmaxs = new Short_t[hist->GetNbinsY()];
713 Int_t last_value=0,value=0;
714 for(Int_t ybin=ymin; ybin<=ymax; ybin++)
716 local_maxima[ybin-ymin] = new PreYPeak[hist->GetNbinsX()];
717 nmaxs[ybin-ymin] = 0;
720 for(Int_t xbin=xmin; xbin<=xmax; xbin++)
722 value = hist->GetBinContent(hist->GetBin(xbin,ybin));
725 if(abs(value - last_value) > 1)
728 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].right_value = value;
731 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].start_position = xbin;
732 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].end_position = xbin;
733 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].min_value = value;
734 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].max_value = value;
735 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].prev_value = 0;
736 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].left_value = last_value;
739 if(abs(value - last_value) <= 1)
741 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].end_position = xbin;
742 if(value>local_maxima[ybin-ymin][nmaxs[ybin-ymin]].max_value)
743 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].max_value = value;
744 if(value<local_maxima[ybin-ymin][nmaxs[ybin-ymin]].min_value)
745 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].min_value = value;
752 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].right_value = value;
757 Pre2DPeak maxima[500];
760 for(Int_t ybin=ymax; ybin >= ymin; ybin--)
762 for(Int_t i=0; i<nmaxs[ybin-ymin]; i++)
764 Int_t local_min_value = local_maxima[ybin-ymin][i].min_value;
765 Int_t local_max_value = local_maxima[ybin-ymin][i].max_value;
766 Int_t local_prev_value = local_maxima[ybin-ymin][i].prev_value;
767 Int_t local_next_value = 0;
768 Int_t local_left_value = local_maxima[ybin-ymin][i].left_value;
769 Int_t local_right_value = local_maxima[ybin-ymin][i].right_value;
771 if(local_min_value<0)
772 continue; //already used
774 //start expanding in the psi-direction:
776 Int_t local_x_start = local_maxima[ybin-ymin][i].start_position;
777 Int_t local_x_end = local_maxima[ybin-ymin][i].end_position;
778 Int_t temp_x_start = local_maxima[ybin-ymin][i].start_position;
779 Int_t temp_x_end = local_maxima[ybin-ymin][i].end_position;
781 Int_t local_y=ybin-1,nybins=1;
783 while(local_y >= ymin)
786 for(Int_t j=0; j<nmaxs[local_y-ymin]; j++)
788 if( (local_maxima[local_y-ymin][j].start_position <= (temp_x_end + kappawindow)) && (local_maxima[local_y-ymin][j].end_position >= (temp_x_start - kappawindow)))
790 if(((local_maxima[local_y-ymin][j].min_value <= local_max_value) && (local_maxima[local_y-ymin][j].min_value >= local_min_value)) ||
791 ((local_maxima[local_y-ymin][j].max_value >= local_min_value) && (local_maxima[local_y-ymin][j].max_value <= local_max_value)))
793 if(local_maxima[local_y-ymin][j].end_position > local_x_end)
794 local_x_end = local_maxima[local_y-ymin][j].end_position;
795 if(local_maxima[local_y-ymin][j].start_position < local_x_start)
796 local_x_start = local_maxima[local_y-ymin][j].start_position;
797 temp_x_start = local_maxima[local_y-ymin][j].start_position;
798 temp_x_end = local_maxima[local_y-ymin][j].end_position;
799 if(local_maxima[local_y-ymin][j].min_value < local_min_value)
800 local_min_value = local_maxima[local_y-ymin][j].min_value;
801 if(local_maxima[local_y-ymin][j].max_value > local_max_value)
802 local_max_value = local_maxima[local_y-ymin][j].max_value;
803 if(local_maxima[local_y-ymin][j].right_value > local_right_value)
804 local_right_value = local_maxima[local_y-ymin][j].right_value;
805 if(local_maxima[local_y-ymin][j].left_value > local_left_value)
806 local_left_value = local_maxima[local_y-ymin][j].left_value;
807 local_maxima[local_y-ymin][j].min_value = -1;
814 if(local_max_value > local_maxima[local_y-ymin][j].prev_value)
815 local_maxima[local_y-ymin][j].prev_value = local_max_value;
816 if(local_maxima[local_y-ymin][j].max_value > local_next_value)
817 local_next_value = local_maxima[local_y-ymin][j].max_value;
821 if(!found || local_y == ymin)//no more local maximas to be matched, so write the final peak and break the expansion:
823 if((nybins > ysize) && ((local_x_end-local_x_start+1) > xsize) && (local_max_value > local_prev_value) && (local_max_value > local_next_value) && (local_max_value > local_left_value) && (local_max_value > local_right_value))
824 // if((nybins > ysize) && ((local_x_end-local_x_start+1) > xsize))
826 maxima[nmaxima].x = ((Float_t)local_x_start+(Float_t)local_x_end)/2.0;
827 maxima[nmaxima].y = ((Float_t)ybin+(Float_t)(local_y+1))/2.0;
828 maxima[nmaxima].size_x = local_x_end-local_x_start+1;
829 maxima[nmaxima].size_y = nybins;
830 maxima[nmaxima].weight = (local_min_value+local_max_value)/2;
831 maxima[nmaxima].start_x = local_x_start;
832 maxima[nmaxima].end_x = local_x_end;
833 maxima[nmaxima].start_y = local_y +1;
834 maxima[nmaxima].end_y = ybin;
836 // cout<<"Peak found at: "<<((Float_t)local_x_start+(Float_t)local_x_end)/2.0<<" "<<((Float_t)ybin+(Float_t)(local_y+1))/2.0<<" "<<local_min_value<<" "<<local_max_value<<" "<<" with weight "<<(local_min_value+local_max_value)/2<<" and size "<<local_x_end-local_x_start+1<<" by "<<nybins<<endl;
843 local_y--;//Search continues...
849 Int_t nxbins = hist->GetNbinsX()+2;
851 for(Int_t i = 0; i < (nmaxima - 1); i++)
853 if(maxima[i].weight < 0) continue;
854 for(Int_t j = i + 1; j < nmaxima; j++)
856 if(maxima[j].weight < 0) continue;
857 Int_t xtrack1=0,xtrack2=0,ytrack1=0,ytrack2=0;
859 for(Int_t ix1 = maxima[i].start_x; ix1 <= maxima[i].end_x; ix1++) {
860 for(Int_t ix2 = maxima[j].start_x; ix2 <= maxima[j].end_x; ix2++) {
861 if(abs(ix1 - ix2) < deltax) {
862 deltax = abs(ix1 - ix2);
869 for(Int_t iy1 = maxima[i].start_y; iy1 <= maxima[i].end_y; iy1++) {
870 for(Int_t iy2 = maxima[j].start_y; iy2 <= maxima[j].end_y; iy2++) {
871 if(abs(iy1 - iy2) < deltay) {
872 deltay = abs(iy1 - iy2);
878 Int_t firstrow1 = AliL3HoughTransformerRow::GetTrackFirstRow()[xtrack1 + nxbins*ytrack1];
879 Int_t lastrow1 = AliL3HoughTransformerRow::GetTrackLastRow()[xtrack1 + nxbins*ytrack1];
880 Int_t firstrow2 = AliL3HoughTransformerRow::GetTrackFirstRow()[xtrack1 + nxbins*ytrack1];
881 Int_t lastrow2 = AliL3HoughTransformerRow::GetTrackLastRow()[xtrack1 + nxbins*ytrack1];
882 Int_t firstrow,lastrow;
883 if(firstrow1 < firstrow2)
884 firstrow = firstrow2;
886 firstrow = firstrow1;
888 if(lastrow1 > lastrow2)
893 AliL3HoughTrack track1;
894 Float_t x1 = hist->GetPreciseBinCenterX(xtrack1);
895 Float_t y1 = hist->GetPreciseBinCenterY(ytrack1);
896 Float_t psi1 = atan((x1-y1)/(AliL3HoughTransformerRow::GetBeta1()-AliL3HoughTransformerRow::GetBeta2()));
897 Float_t kappa1 = 2.0*(x1*cos(psi1)-AliL3HoughTransformerRow::GetBeta1()*sin(psi1));
898 track1.SetTrackParameters(kappa1,psi1,1);
899 Float_t firsthit1[3];
900 if(!track1.GetCrossingPoint(firstrow,firsthit1)) continue;
902 if(!track1.GetCrossingPoint(lastrow,lasthit1)) continue;
904 AliL3HoughTrack track2;
905 Float_t x2 = hist->GetPreciseBinCenterX(xtrack2);
906 Float_t y2 = hist->GetPreciseBinCenterY(ytrack2);
907 Float_t psi2 = atan((x2-y2)/(AliL3HoughTransformerRow::GetBeta1()-AliL3HoughTransformerRow::GetBeta2()));
908 Float_t kappa2 = 2.0*(x2*cos(psi2)-AliL3HoughTransformerRow::GetBeta1()*sin(psi2));
909 track2.SetTrackParameters(kappa2,psi2,1);
910 Float_t firsthit2[3];
911 if(!track2.GetCrossingPoint(firstrow,firsthit2)) continue;
913 if(!track2.GetCrossingPoint(lastrow,lasthit2)) continue;
915 Float_t padpitchlow = AliL3Transform::GetPadPitchWidth(AliL3Transform::GetPatch(firstrow));
916 Float_t padpitchup = AliL3Transform::GetPadPitchWidth(AliL3Transform::GetPatch(lastrow));
917 // check the distance between tracks at the edges
919 // cout<<"DEBUG Merge peaks "<<i<<" "<<j<<" "<<firsthit1[1]<<" "<<firsthit2[1]<<" "<<lasthit1[1]<<" "<<lasthit2[1]<<endl;
921 //cvetan please check!!! I added a cast to Int_t
922 if((fabs(firsthit1[1]-firsthit2[1]) < 3.0*padpitchlow) && (fabs(lasthit1[1]-lasthit2[1]) < 3.0*padpitchup)) {
923 if(maxima[i].size_x*maxima[i].size_y > maxima[j].size_x*maxima[j].size_y)
924 maxima[j].weight = -maxima[j].weight;
925 if(maxima[i].size_x*maxima[i].size_y < maxima[j].size_x*maxima[j].size_y)
926 maxima[i].weight = -maxima[i].weight;
928 // cout<<"Merge peaks "<<i<<" "<<j<<" "<<maxima[i].weight<<" "<<maxima[j].weight<<endl;
934 //merge tracks in neighbour eta slices
936 for(Int_t i = 0; i < nmaxima; i++) {
937 if(maxima[i].weight > 0) {
938 fXPeaks[fNPeaks] = hist->GetPreciseBinCenterX(maxima[i].x);
939 fYPeaks[fNPeaks] = hist->GetPreciseBinCenterY(maxima[i].y);
940 fWeight[fNPeaks] = (Int_t)maxima[i].weight;
942 cout<<"Final Peak found at: "<<maxima[i].x<<" "<<maxima[i].y<<" "<<" "<<fXPeaks[fNPeaks]<<" "<<fYPeaks[fNPeaks]<<" with weight "<<fWeight[fNPeaks]<<" and size "<<maxima[i].size_x<<" by "<<maxima[i].size_y<<endl;
949 Int_t currentnpeaks = fNPeaks;
950 for(Int_t i = 0; i < nmaxima; i++) {
951 if(maxima[i].weight < 0) continue;
952 Bool_t merged = kFALSE;
953 for(Int_t j = fN1PeaksPrevEtaSlice; j < fN2PeaksPrevEtaSlice; j++) {
954 if(fWeight[j] < 0) continue;
955 if((fENDETAPeaks[j]-fSTARTETAPeaks[j]) >= 1) continue;
956 if((maxima[i].start_x <= fENDXPeaks[j]+1) && (maxima[i].end_x >= fSTARTXPeaks[j]-1)) {
957 if((maxima[i].start_y <= fENDYPeaks[j]+1) && (maxima[i].end_y >= fSTARTYPeaks[j]-1)) {
960 fXPeaks[fNPeaks] = (hist->GetPreciseBinCenterX(maxima[i].x)+(fENDETAPeaks[j]-fSTARTETAPeaks[j]+1)*fXPeaks[j])/(fENDETAPeaks[j]-fSTARTETAPeaks[j]+2);
961 fYPeaks[fNPeaks] = (hist->GetPreciseBinCenterY(maxima[i].y)+(fENDETAPeaks[j]-fSTARTETAPeaks[j]+1)*fYPeaks[j])/(fENDETAPeaks[j]-fSTARTETAPeaks[j]+2);
962 fWeight[fNPeaks] = (Int_t)maxima[i].weight + fWeight[j];
963 fSTARTXPeaks[fNPeaks] = maxima[i].start_x;
964 fSTARTYPeaks[fNPeaks] = maxima[i].start_y;
965 fENDXPeaks[fNPeaks] = maxima[i].end_x;
966 fENDYPeaks[fNPeaks] = maxima[i].end_y;
967 fSTARTETAPeaks[fNPeaks] = fSTARTETAPeaks[j];
968 fENDETAPeaks[fNPeaks] = fCurrentEtaSlice;
970 fWeight[j] = -fWeight[j];
974 fXPeaks[fNPeaks] = hist->GetPreciseBinCenterX(maxima[i].x);
975 fYPeaks[fNPeaks] = hist->GetPreciseBinCenterY(maxima[i].y);
977 fWeight[fNPeaks] = (Int_t)maxima[i].weight;
979 fWeight[fNPeaks] = -(Int_t)maxima[i].weight;
980 fSTARTXPeaks[fNPeaks] = maxima[i].start_x;
981 fSTARTYPeaks[fNPeaks] = maxima[i].start_y;
982 fENDXPeaks[fNPeaks] = maxima[i].end_x;
983 fENDYPeaks[fNPeaks] = maxima[i].end_y;
984 fSTARTETAPeaks[fNPeaks] = fCurrentEtaSlice;
985 fENDETAPeaks[fNPeaks] = fCurrentEtaSlice;
988 fN1PeaksPrevEtaSlice = currentnpeaks;
989 fN2PeaksPrevEtaSlice = fNPeaks;
991 for(Int_t i=0; i<hist->GetNbinsY(); i++)
992 delete local_maxima[i];
994 delete [] local_maxima;
998 void AliL3HoughMaxFinder::FindPeak1(Int_t y_window,Int_t x_bin_sides)
1000 //Testing mutliple peakfinding.
1001 //The algorithm searches the histogram for prepreaks by looking in windows
1002 //for each bin on the xaxis. The size of these windows is controlled by y_window.
1003 //Then the prepreaks are sorted according to their weight (sum inside window),
1004 //and the peak positions are calculated by taking the weighted mean in both
1005 //x and y direction. The size of the peak in x-direction is controlled by x_bin_sides.
1009 printf("AliL3HoughMaxFinder::FindPeak1 : No input histogram\n");
1012 if(fCurrentHisto->GetNEntries()==0)
1016 //Int_t x_bin_sides=1;
1018 //Float_t max_kappa = 0.001;
1019 //Float_t max_phi0 = 0.08;
1023 Int_t xmin = fCurrentHisto->GetFirstXbin();
1024 Int_t xmax = fCurrentHisto->GetLastXbin();
1025 Int_t ymin = fCurrentHisto->GetFirstYbin();
1026 Int_t ymax = fCurrentHisto->GetLastYbin();
1027 Int_t nbinsx = fCurrentHisto->GetNbinsX()+1;
1029 AxisWindow **windowPt = new AxisWindow*[nbinsx];
1030 AxisWindow **anotherPt = new AxisWindow*[nbinsx];
1032 for(Int_t i=0; i<nbinsx; i++)
1034 windowPt[i] = new AxisWindow;
1035 #if defined(__DECCXX)
1036 bzero((char *)windowPt[i],sizeof(AxisWindow));
1038 bzero((void*)windowPt[i],sizeof(AxisWindow));
1040 anotherPt[i] = windowPt[i];
1043 for(Int_t xbin=xmin; xbin<=xmax; xbin++)
1046 for(Int_t ybin=ymin; ybin<=ymax-y_window; ybin++)
1048 Int_t sum_in_window=0;
1049 for(Int_t b=ybin; b<ybin+y_window; b++)
1052 Int_t bin = fCurrentHisto->GetBin(xbin,b);
1053 sum_in_window += (Int_t)fCurrentHisto->GetBinContent(bin);
1056 if(sum_in_window > max_sum)
1058 max_sum = sum_in_window;
1059 windowPt[xbin]->ymin = ybin;
1060 windowPt[xbin]->ymax = ybin + y_window;
1061 windowPt[xbin]->weight = sum_in_window;
1062 windowPt[xbin]->xbin = xbin;
1067 //Sort the windows according to the weight
1068 SortPeaks(windowPt,0,nbinsx);
1071 for(Int_t i=0; i<nbinsx; i++)
1074 Int_t xbin = windowPt[i]->xbin;
1076 if(xbin<xmin || xbin > xmax-1) continue;
1078 //Check if this is really a local maxima
1079 if(anotherPt[xbin-1]->weight > anotherPt[xbin]->weight ||
1080 anotherPt[xbin+1]->weight > anotherPt[xbin]->weight)
1083 for(Int_t j=windowPt[i]->ymin; j<windowPt[i]->ymax; j++)
1085 //Calculate the mean in y direction:
1086 Int_t bin = fCurrentHisto->GetBin(windowPt[i]->xbin,j);
1087 top += (fCurrentHisto->GetBinCenterY(j))*(fCurrentHisto->GetBinContent(bin));
1088 butt += fCurrentHisto->GetBinContent(bin);
1091 if(butt < fThreshold)
1094 fXPeaks[fNPeaks] = fCurrentHisto->GetBinCenterX(windowPt[i]->xbin);
1095 fYPeaks[fNPeaks] = top/butt;
1096 fWeight[fNPeaks] = (Int_t)butt;
1097 //cout<<"mean in y "<<ypeaks[n]<<" on x "<<windowPt[i]->xbin<<" content "<<butt<<endl;
1101 cerr<<"AliL3HoughMaxFinder::FindPeak1 : Peak array out of range!!!"<<endl;
1107 //Improve the peaks by including the region around in x.
1111 for(Int_t i=0; i<fNPeaks; i++)
1113 Int_t xbin = fCurrentHisto->FindXbin(fXPeaks[i]);
1114 if(xbin - x_bin_sides < xmin || xbin + x_bin_sides > xmax) continue;
1118 prev = xbin - x_bin_sides+1;
1119 for(Int_t j=xbin-x_bin_sides; j<=xbin+x_bin_sides; j++)
1122 //Check if the windows are overlapping:
1123 if(anotherPt[j]->ymin > anotherPt[prev]->ymax) {prev=j; continue;}
1124 if(anotherPt[j]->ymax < anotherPt[prev]->ymin) {prev=j; continue;}
1128 top += fCurrentHisto->GetBinCenterX(j)*anotherPt[j]->weight;
1129 butt += anotherPt[j]->weight;
1131 for(Int_t k=anotherPt[j]->ymin; k<anotherPt[j]->ymax; k++)
1133 Int_t bin = fCurrentHisto->GetBin(j,k);
1134 ytop += (fCurrentHisto->GetBinCenterY(k))*(fCurrentHisto->GetBinContent(bin));
1135 ybutt += fCurrentHisto->GetBinContent(bin);
1136 w+=(Int_t)fCurrentHisto->GetBinContent(bin);
1140 fXPeaks[i] = top/butt;
1141 fYPeaks[i] = ytop/ybutt;
1143 //cout<<"Setting weight "<<w<<" kappa "<<fXPeaks[i]<<" phi0 "<<fYPeaks[i]<<endl;
1146 //Check if this peak is overlapping with a previous:
1147 for(Int_t p=0; p<i; p++)
1149 //cout<<fabs(fXPeaks[p] - fXPeaks[i])<<" "<<fabs(fYPeaks[p] - fYPeaks[i])<<endl;
1150 if(fabs(fXPeaks[p] - fXPeaks[i]) < max_kappa &&
1151 fabs(fYPeaks[p] - fYPeaks[i]) < max_phi0)
1160 for(Int_t i=0; i<nbinsx; i++)
1163 delete [] anotherPt;
1166 void AliL3HoughMaxFinder::SortPeaks(struct AxisWindow **a,Int_t first,Int_t last)
1168 //General sorting routine
1169 //Sort according to PeakCompare()
1171 static struct AxisWindow *tmp;
1172 static int i; // "static" to save stack space
1175 while (last - first > 1) {
1179 while (++i < last && PeakCompare(a[i], a[first]) < 0)
1181 while (--j > first && PeakCompare(a[j], a[first]) > 0)
1197 if (j - first < last - (j + 1)) {
1198 SortPeaks(a, first, j);
1199 first = j + 1; // QSort(j + 1, last);
1201 SortPeaks(a, j + 1, last);
1202 last = j; // QSort(first, j);
1208 Int_t AliL3HoughMaxFinder::PeakCompare(struct AxisWindow *a,struct AxisWindow *b)
1210 if(a->weight < b->weight) return 1;
1211 if(a->weight > b->weight) return -1;
1215 void AliL3HoughMaxFinder::FindPeak(Int_t t1,Double_t t2,Int_t t3)
1217 //Attempt of a more sophisticated peak finder.
1218 //Finds the best peak in the histogram, and returns the corresponding
1223 printf("AliL3HoughMaxFinder::FindPeak : No histogram!!\n");
1226 AliL3Histogram *hist = fCurrentHisto;
1227 if(hist->GetNEntries()==0)
1230 Int_t xmin = hist->GetFirstXbin();
1231 Int_t xmax = hist->GetLastXbin();
1232 Int_t ymin = hist->GetFirstYbin();
1233 Int_t ymax = hist->GetLastYbin();
1234 Int_t nbinsx = hist->GetNbinsX()+1;
1236 Int_t *m = new Int_t[nbinsx];
1237 Int_t *m_low = new Int_t[nbinsx];
1238 Int_t *m_up = new Int_t[nbinsx];
1241 recompute: //this is a goto.
1243 for(Int_t i=0; i<nbinsx; i++)
1250 Int_t max_x=0,sum=0,max_xbin=0,bin=0;
1252 for(Int_t xbin=xmin; xbin<=xmax; xbin++)
1254 for(Int_t ybin=ymin; ybin <= ymax - t1; ybin++)
1257 for(Int_t y=ybin; y <= ybin+t1; y++)
1261 bin = hist->GetBin(xbin,y);
1262 sum += (Int_t)hist->GetBinContent(bin);
1265 if(sum > m[xbin]) //Max value locally in this xbin
1269 m_up[xbin]=ybin + t1;
1274 if(m[xbin] > max_x) //Max value globally in x-direction
1277 max_x = m[xbin];//sum;
1280 //printf("max_xbin %d max_x %d m_low %d m_up %d\n",max_xbin,max_x,m_low[max_xbin],m_up[max_xbin]);
1281 //printf("ylow %f yup %f\n",hist->GetBinCenterY(m_low[max_xbin]),hist->GetBinCenterY(m_up[max_xbin]));
1283 //Determine a width in the x-direction
1284 Int_t x_low=0,x_up=0;
1286 for(Int_t xbin=max_xbin-1; xbin >= xmin; xbin--)
1288 if(m[xbin] < max_x*t2)
1294 for(Int_t xbin = max_xbin+1; xbin <=xmax; xbin++)
1296 if(m[xbin] < max_x*t2)
1303 Double_t top=0,butt=0,value,x_peak;
1304 if(x_up - x_low + 1 > t3)
1307 printf("\nxrange out if limit x_up %d x_low %d t1 %d\n\n",x_low,x_up,t1);
1312 x_peak = hist->GetBinCenterX(max_xbin);
1317 //printf("xlow %f xup %f\n",hist->GetBinCenterX(x_low),hist->GetBinCenterX(x_up));
1318 //printf("Spread in x %d\n",x_up-x_low +1);
1320 //Now, calculate the center of mass in x-direction
1321 for(Int_t xbin=x_low; xbin <= x_up; xbin++)
1323 value = hist->GetBinCenterX(xbin);
1324 top += value*m[xbin];
1331 //Find the peak in y direction:
1332 Int_t x_l = hist->FindXbin(x_peak);
1333 if(hist->GetBinCenterX(x_l) > x_peak)
1336 Int_t x_u = x_l + 1;
1338 if(hist->GetBinCenterX(x_l) > x_peak || hist->GetBinCenterX(x_u) <= x_peak)
1339 printf("\nAliL3HoughMaxFinder::FindPeak : Wrong xrange %f %f %f\n\n",hist->GetBinCenterX(x_l),x_peak,hist->GetBinCenterX(x_u));
1341 //printf("\nxlow %f xup %f\n",hist->GetBinCenterX(x_l),hist->GetBinCenterX(x_u));
1345 //printf("ylow %f yup %f\n",hist->GetBinCenterY(m_low[x_l]),hist->GetBinCenterY(m_up[x_l]));
1346 //printf("ylow %f yup %f\n",hist->GetBinCenterY(m_low[x_u]),hist->GetBinCenterY(m_up[x_u]));
1348 for(Int_t ybin=m_low[x_l]; ybin <= m_up[x_l]; ybin++)
1350 value = hist->GetBinCenterY(ybin);
1351 bin = hist->GetBin(x_l,ybin);
1352 top += value*hist->GetBinContent(bin);
1353 butt += hist->GetBinContent(bin);
1355 Double_t y_peak_low = top/butt;
1357 //printf("y_peak_low %f\n",y_peak_low);
1360 for(Int_t ybin=m_low[x_u]; ybin <= m_up[x_u]; ybin++)
1362 value = hist->GetBinCenterY(ybin);
1363 bin = hist->GetBin(x_u,ybin);
1364 top += value*hist->GetBinContent(bin);
1365 butt += hist->GetBinContent(bin);
1367 Double_t y_peak_up = top/butt;
1369 //printf("y_peak_up %f\n",y_peak_up);
1371 Double_t x_value_up = hist->GetBinCenterX(x_u);
1372 Double_t x_value_low = hist->GetBinCenterX(x_l);
1374 Double_t y_peak = (y_peak_low*(x_value_up - x_peak) + y_peak_up*(x_peak - x_value_low))/(x_value_up - x_value_low);
1378 //bin = hist->FindBin(x_peak,y_peak);
1379 //Int_t weight = (Int_t)hist->GetBinContent(bin);
1381 //AliL3HoughTrack *track = new AliL3HoughTrack();
1382 //track->SetTrackParameters(x_peak,y_peak,weight);
1383 fXPeaks[fNPeaks]=x_peak;
1384 fYPeaks[fNPeaks]=y_peak;
1385 fWeight[fNPeaks]=(Int_t)hist->GetBinContent(bin);
1395 Float_t AliL3HoughMaxFinder::GetXPeakSize(Int_t i)
1399 STDCERR<<"AliL3HoughMaxFinder::GetXPeakSize : Invalid index "<<i<<STDENDL;
1402 Float_t BinWidth = fCurrentHisto->GetBinWidthX();
1403 return BinWidth*(fENDXPeaks[i]-fSTARTXPeaks[i]+1);
1406 Float_t AliL3HoughMaxFinder::GetYPeakSize(Int_t i)
1410 STDCERR<<"AliL3HoughMaxFinder::GetYPeak : Invalid index "<<i<<STDENDL;
1413 Float_t BinWidth = fCurrentHisto->GetBinWidthY();
1414 return BinWidth*(fENDYPeaks[i]-fSTARTYPeaks[i]+1);