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"
24 /** \class AliL3HoughMaxFinder
26 //_____________________________________________________________
27 // AliL3HoughMaxFinder
34 ClassImp(AliL3HoughMaxFinder)
37 AliL3HoughMaxFinder::AliL3HoughMaxFinder()
53 AliL3HoughMaxFinder::AliL3HoughMaxFinder(Char_t *histotype,Int_t nmax,AliL3Histogram *hist)
57 //fTracks = new AliL3TrackArray("AliL3HoughTrack");
58 if(strcmp(histotype,"KappaPhi")==0) fHistoType='c';
59 if(strcmp(histotype,"DPsi")==0) fHistoType='l';
67 fXPeaks = new Float_t[fNMax];
68 fYPeaks = new Float_t[fNMax];
69 fWeight = new Int_t[fNMax];
76 AliL3HoughMaxFinder::~AliL3HoughMaxFinder()
91 void AliL3HoughMaxFinder::Reset()
93 for(Int_t i=0; i<fNMax; i++)
102 void AliL3HoughMaxFinder::CreateNtuppel()
105 //content#; neighbouring bins of the peak.
106 fNtuppel = new TNtuple("ntuppel","Peak charateristics","kappa:phi0:weigth:content3:content5:content1:content7");
107 fNtuppel->SetDirectory(0);
111 void AliL3HoughMaxFinder::WriteNtuppel(Char_t *filename)
114 TFile *file = TFile::Open(filename,"RECREATE");
117 cerr<<"AliL3HoughMaxFinder::WriteNtuppel : Error opening file "<<filename<<endl;
125 void AliL3HoughMaxFinder::FindAbsMaxima()
130 cerr<<"AliL3HoughMaxFinder::FindAbsMaxima : No histogram"<<endl;
133 AliL3Histogram *hist = fCurrentHisto;
135 if(hist->GetNEntries() == 0)
138 Int_t xmin = hist->GetFirstXbin();
139 Int_t xmax = hist->GetLastXbin();
140 Int_t ymin = hist->GetFirstYbin();
141 Int_t ymax = hist->GetLastYbin();
143 Double_t value,max_value=0;
145 Int_t max_xbin=0,max_ybin=0;
146 for(Int_t xbin=xmin; xbin<=xmax; xbin++)
148 for(Int_t ybin=ymin; ybin<=ymax; ybin++)
150 bin = hist->GetBin(xbin,ybin);
151 value = hist->GetBinContent(bin);
166 cerr<<"AliL3HoughMaxFinder::FindAbsMaxima : Array out of range : "<<fNPeaks<<endl;
170 Double_t max_x = hist->GetBinCenterX(max_xbin);
171 Double_t max_y = hist->GetBinCenterY(max_ybin);
172 fXPeaks[fNPeaks] = max_x;
173 fYPeaks[fNPeaks] = max_y;
174 fWeight[fNPeaks] = (Int_t)max_value;
180 Int_t bin3 = hist->GetBin(max_xbin-1,max_ybin);
181 Int_t bin5 = hist->GetBin(max_xbin+1,max_ybin);
182 Int_t bin1 = hist->GetBin(max_xbin,max_ybin-1);
183 Int_t bin7 = hist->GetBin(max_xbin,max_ybin+1);
185 fNtuppel->Fill(max_x,max_y,max_value,hist->GetBinContent(bin3),hist->GetBinContent(bin5),hist->GetBinContent(bin1),hist->GetBinContent(bin7));
190 void AliL3HoughMaxFinder::FindBigMaxima()
193 AliL3Histogram *hist = fCurrentHisto;
195 if(hist->GetNEntries() == 0)
198 Int_t xmin = hist->GetFirstXbin();
199 Int_t xmax = hist->GetLastXbin();
200 Int_t ymin = hist->GetFirstYbin();
201 Int_t ymax = hist->GetLastYbin();
202 Int_t bin[25],bin_index;
205 for(Int_t xbin=xmin+2; xbin<xmax-3; xbin++)
207 for(Int_t ybin=ymin+2; ybin<ymax-3; ybin++)
210 for(Int_t xb=xbin-2; xb<=xbin+2; xb++)
212 for(Int_t yb=ybin-2; yb<=ybin+2; yb++)
214 bin[bin_index]=hist->GetBin(xb,yb);
215 value[bin_index]=hist->GetBinContent(bin[bin_index]);
219 if(value[12]==0) continue;
223 if(value[b] > value[12] || b==bin_index) break;
225 //printf("b %d\n",b);
232 cerr<<"AliL3HoughMaxFinder::FindBigMaxima : Array out of range "<<fNPeaks<<endl;
236 Double_t max_x = hist->GetBinCenterX(xbin);
237 Double_t max_y = hist->GetBinCenterY(ybin);
238 fXPeaks[fNPeaks] = max_x;
239 fYPeaks[fNPeaks] = max_y;
246 void AliL3HoughMaxFinder::FindMaxima(Int_t threshold)
248 //Locate all the maxima in input histogram.
249 //Maxima is defined as bins with more entries than the
250 //immediately neighbouring bins.
252 if(fCurrentHisto->GetNEntries() == 0)
255 Int_t xmin = fCurrentHisto->GetFirstXbin();
256 Int_t xmax = fCurrentHisto->GetLastXbin();
257 Int_t ymin = fCurrentHisto->GetFirstYbin();
258 Int_t ymax = fCurrentHisto->GetLastYbin();
262 //Float_t max_kappa = 0.001;
263 //Float_t max_phi0 = 0.08;
265 for(Int_t xbin=xmin+1; xbin<=xmax-1; xbin++)
267 for(Int_t ybin=ymin+1; ybin<=ymax-1; ybin++)
269 bin[0] = fCurrentHisto->GetBin(xbin-1,ybin-1);
270 bin[1] = fCurrentHisto->GetBin(xbin,ybin-1);
271 bin[2] = fCurrentHisto->GetBin(xbin+1,ybin-1);
272 bin[3] = fCurrentHisto->GetBin(xbin-1,ybin);
273 bin[4] = fCurrentHisto->GetBin(xbin,ybin);
274 bin[5] = fCurrentHisto->GetBin(xbin+1,ybin);
275 bin[6] = fCurrentHisto->GetBin(xbin-1,ybin+1);
276 bin[7] = fCurrentHisto->GetBin(xbin,ybin+1);
277 bin[8] = fCurrentHisto->GetBin(xbin+1,ybin+1);
278 value[0] = fCurrentHisto->GetBinContent(bin[0]);
279 value[1] = fCurrentHisto->GetBinContent(bin[1]);
280 value[2] = fCurrentHisto->GetBinContent(bin[2]);
281 value[3] = fCurrentHisto->GetBinContent(bin[3]);
282 value[4] = fCurrentHisto->GetBinContent(bin[4]);
283 value[5] = fCurrentHisto->GetBinContent(bin[5]);
284 value[6] = fCurrentHisto->GetBinContent(bin[6]);
285 value[7] = fCurrentHisto->GetBinContent(bin[7]);
286 value[8] = fCurrentHisto->GetBinContent(bin[8]);
289 if(value[4]>value[0] && value[4]>value[1] && value[4]>value[2]
290 && value[4]>value[3] && value[4]>value[5] && value[4]>value[6]
291 && value[4]>value[7] && value[4]>value[8])
293 //Found a local maxima
294 Float_t max_x = fCurrentHisto->GetBinCenterX(xbin);
295 Float_t max_y = fCurrentHisto->GetBinCenterY(ybin);
297 if((Int_t)value[4] <= threshold) continue;//central bin below threshold
300 cout<<"AliL3HoughMaxFinder::FindMaxima : Array out of range "<<fNPeaks<<endl;
304 //Check the gradient:
305 if(value[3]/value[4] > fGradX && value[5]/value[4] > fGradX)
308 if(value[1]/value[4] > fGradY && value[7]/value[4] > fGradY)
311 fXPeaks[fNPeaks] = max_x;
312 fYPeaks[fNPeaks] = max_y;
313 fWeight[fNPeaks] = (Int_t)value[4];
317 //Check if the peak is overlapping with a previous:
318 Bool_t bigger = kFALSE;
319 for(Int_t p=0; p<fNPeaks; p++)
321 if(fabs(max_x - fXPeaks[p]) < max_kappa && fabs(max_y - fYPeaks[p]) < max_phi0)
324 if(value[4] > fWeight[p]) //this peak is bigger.
328 fWeight[p] = (Int_t)value[4];
331 continue; //previous peak is bigger.
334 if(!bigger) //there were no overlapping peaks.
336 fXPeaks[fNPeaks] = max_x;
337 fYPeaks[fNPeaks] = max_y;
338 fWeight[fNPeaks] = (Int_t)value[4];
354 void AliL3HoughMaxFinder::FindAdaptedPeaks(Int_t kappawindow,Float_t cut_ratio)
356 //Peak finder which looks for peaks with a certain shape.
357 //The first step involves a pre-peak finder, which looks for peaks
358 //in windows (size controlled by kappawindow) summing over each psi-bin.
359 //These pre-preaks are then matched between neighbouring kappa-bins to
360 //look for real 2D peaks exhbiting the typical cross-shape in the Hough circle transform.
361 //The maximum bin within this region is marked as the peak itself, and
362 //a few checks is performed to avoid the clear fake peaks (asymmetry check etc.)
365 AliL3Histogram *hist = fCurrentHisto;
369 cerr<<"AliL3HoughMaxFinder : No histogram!"<<endl;
373 if(hist->GetNEntries() == 0)
376 Int_t xmin = hist->GetFirstXbin();
377 Int_t xmax = hist->GetLastXbin();
378 Int_t ymin = hist->GetFirstYbin();
379 Int_t ymax = hist->GetLastYbin();
382 //Start by looking for pre-peaks:
384 Window **local_maxima = new Window*[hist->GetNbinsY()];
386 Short_t *nmaxs = new Short_t[hist->GetNbinsY()];
387 Int_t n,last_sum,sum;
388 Bool_t sum_was_rising;
389 for(Int_t ybin=ymin; ybin<=ymax; ybin++)
391 local_maxima[ybin-ymin] = new Window[hist->GetNbinsX()];
392 nmaxs[ybin-ymin] = 0;
396 for(Int_t xbin=xmin; xbin<=xmax-kappawindow; xbin++)
399 for(Int_t lbin=xbin; lbin<xbin+kappawindow; lbin++)
400 sum += hist->GetBinContent(hist->GetBin(lbin,ybin));
405 if(sum_was_rising)//Previous sum was a local maxima
407 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].start = xbin-1;
408 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].sum = last_sum;
421 Int_t *starts = new Int_t[hist->GetNbinsY()+1];
422 Int_t *maxs = new Int_t[hist->GetNbinsY()+1];
424 for(Int_t ybin=ymax; ybin >= ymin+1; ybin--)
426 for(Int_t i=0; i<nmaxs[ybin-ymin]; i++)
428 Int_t lw = local_maxima[ybin-ymin][i].sum;
431 continue; //already used
433 Int_t maxvalue=0,maxybin=0,maxxbin=0,maxwindow=0;
434 for(Int_t k=local_maxima[ybin-ymin][i].start; k<local_maxima[ybin-ymin][i].start + kappawindow; k++)
435 if(hist->GetBinContent(hist->GetBin(k,ybin)) > maxvalue)
437 maxvalue = hist->GetBinContent(hist->GetBin(k,ybin));
442 //start expanding in the psi-direction:
444 Int_t lb = local_maxima[ybin-ymin][i].start;
446 starts[ybin] = local_maxima[ybin-ymin][i].start;
447 maxs[ybin] = maxxbin;
448 Int_t yl=ybin-1,nybins=1;
450 //cout<<"Starting search at ybin "<<ybin<<" start "<<lb<<" with sum "<<local_maxima[ybin-ymin][i].sum<<endl;
454 for(Int_t j=0; j<nmaxs[yl-ymin]; j++)
456 if( local_maxima[yl-ymin][j].start - lb < 0) continue;
457 if( local_maxima[yl-ymin][j].start < lb + kappawindow + match &&
458 local_maxima[yl-ymin][j].start >= lb && local_maxima[yl-ymin][j].sum > 0)
461 //cout<<"match at ybin "<<yl<<" yvalue "<<hist->GetBinCenterY(yl)<<" start "<<local_maxima[yl-ymin][j].start<<" sum "<<local_maxima[yl-ymin][j].sum<<endl;
463 Int_t lmaxvalue=0,lmaxxbin=0;
464 for(Int_t k=local_maxima[yl-ymin][j].start; k<local_maxima[yl-ymin][j].start + kappawindow; k++)
466 if(hist->GetBinContent(hist->GetBin(k,yl)) > maxvalue)
468 maxvalue = hist->GetBinContent(hist->GetBin(k,yl));
473 if(hist->GetBinContent(hist->GetBin(k,yl)) > lmaxvalue)//local maxima value
475 lmaxvalue=hist->GetBinContent(hist->GetBin(k,yl));
480 starts[yl] = local_maxima[yl-ymin][j].start;
482 local_maxima[yl-ymin][j].sum=-1; //Mark as used
484 lb = local_maxima[yl-ymin][j].start;
485 break;//Since we found a match in this bin, we dont have to search it anymore, goto next bin.
488 if(!found || yl == ymin)//no more local maximas to be matched, so write the final peak and break the expansion:
492 //cout<<"ystart "<<ystart<<" and nybins "<<nybins<<endl;
494 Bool_t truepeak=kTRUE;
496 //cout<<"Maxima found at xbin "<<maxxbin<<" ybin "<<maxybin<<" value "<<maxvalue<<endl;
497 //cout<<"Starting to sum at xbin "<<starts[maxybin-ymin]<<endl;
500 //Look in a window on both sides to probe the asymmetry
501 Float_t right=0,left=0;
502 for(Int_t w=maxxbin+1; w<=maxxbin+3; w++)
504 for(Int_t r=maxybin+1; r<=maxybin+3; r++)
506 right += (Float_t)hist->GetBinContent(hist->GetBin(w,r));
510 for(Int_t w=maxxbin-1; w>=maxxbin-3; w--)
512 for(Int_t r=maxybin+1; r<=maxybin+3; r++)
514 left += (Float_t)hist->GetBinContent(hist->GetBin(w,r));
518 //cout<<"ratio "<<right/left<<endl;
520 Float_t upper_ratio=1,lower_ratio=1;
522 upper_ratio = right/left;
525 for(Int_t w=maxxbin+1; w<=maxxbin+3; w++)
527 for(Int_t r=maxybin-1; r>=maxybin-3; r--)
529 right += (Float_t)hist->GetBinContent(hist->GetBin(w,r));
533 for(Int_t w=maxxbin-1; w>=maxxbin-3; w--)
535 for(Int_t r=maxybin-1; r>=maxybin-3; r--)
537 left += (Float_t)hist->GetBinContent(hist->GetBin(w,r));
541 //cout<<"ratio "<<left/right<<endl;
544 lower_ratio = left/right;
546 if(upper_ratio > cut_ratio || lower_ratio > cut_ratio)
552 fXPeaks[fNPeaks] = hist->GetBinCenterX(maxxbin);
553 fYPeaks[fNPeaks] = hist->GetBinCenterY(maxybin);
554 fWeight[fNPeaks] = maxvalue;
558 //Calculate the peak using weigthed means:
561 for(Int_t k=maxybin-1; k<=maxybin+1; k++)
564 for(Int_t l=starts[k]; l<starts[k]+kappawindow; l++)
566 lsum += (Float_t)hist->GetBinContent(hist->GetBin(l,k));
567 sum += (Float_t)hist->GetBinContent(hist->GetBin(l,k));
569 fYPeaks[fNPeaks] += lsum*hist->GetBinCenterY(k);
571 fYPeaks[fNPeaks] /= sum;
573 if(fYPeaks[fNPeaks] < hist->GetBinCenterY(hist->FindYbin(fYPeaks[fNPeaks])))
575 ybin1 = hist->FindYbin(fYPeaks[fNPeaks])-1;
580 ybin1 = hist->FindYbin(fYPeaks[fNPeaks]);
584 Float_t kappa1=0,kappa2=0;
586 for(Int_t k=starts[ybin1]; k<starts[ybin1] + kappawindow; k++)
588 kappa1 += hist->GetBinCenterX(k)*hist->GetBinContent(hist->GetBin(k,ybin1));
589 sum += (Float_t)hist->GetBinContent(hist->GetBin(k,ybin1));
593 for(Int_t k=starts[ybin2]; k<starts[ybin2] + kappawindow; k++)
595 kappa2 += hist->GetBinCenterX(k)*hist->GetBinContent(hist->GetBin(k,ybin2));
596 sum += (Float_t)hist->GetBinContent(hist->GetBin(k,ybin2));
600 fXPeaks[fNPeaks] = ( kappa1*( hist->GetBinCenterY(ybin2) - fYPeaks[fNPeaks] ) +
601 kappa2*( fYPeaks[fNPeaks] - hist->GetBinCenterY(ybin1) ) ) /
602 (hist->GetBinCenterY(ybin2) - hist->GetBinCenterY(ybin1));
611 yl--;//Search continues...
616 for(Int_t i=0; i<hist->GetNbinsY(); i++)
617 delete local_maxima[i];
619 delete [] local_maxima;
627 Int_t start_position;
635 Int_t start_x_position;
636 Int_t end_x_position;
637 Int_t start_y_position;
638 Int_t end_y_position;
642 void AliL3HoughMaxFinder::FindAdaptedRowPeaks(Int_t kappawindow,Int_t /*xsize*/,Int_t ysize)
645 AliL3Histogram *hist = fCurrentHisto;
649 cerr<<"AliL3HoughMaxFinder : No histogram!"<<endl;
653 if(hist->GetNEntries() == 0)
656 Int_t xmin = hist->GetFirstXbin();
657 Int_t xmax = hist->GetLastXbin();
658 Int_t ymin = hist->GetFirstYbin();
659 Int_t ymax = hist->GetLastYbin();
661 //Start by looking for pre-peaks:
663 PreYPeak **local_maxima = new PreYPeak*[hist->GetNbinsY()];
665 Short_t *nmaxs = new Short_t[hist->GetNbinsY()];
667 Int_t last_value,value;
668 for(Int_t ybin=ymin; ybin<=ymax; ybin++)
670 local_maxima[ybin-ymin] = new PreYPeak[hist->GetNbinsX()];
671 nmaxs[ybin-ymin] = 0;
674 for(Int_t xbin=xmin; xbin<=xmax; xbin++)
676 value = hist->GetBinContent(hist->GetBin(xbin,ybin));
677 if(value >= fThreshold)
679 if(value > last_value)
680 // if(value > (last_value + 1))
682 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].start_position = xbin;
683 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].end_position = xbin;
684 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].value = value;
685 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].prev_value = 0;
688 if(value == last_value)
689 // if(abs(value - last_value) <= 1)
691 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].end_position = xbin;
694 if((value < fThreshold) || (value < last_value))
695 // if((value < fThreshold) || (value < (last_value - 1)))
706 n2dmax += nmaxs[ybin-ymin];
709 // Pre2DPeak *maxima = new Pre2DPeak[n2dmax];
710 for(Int_t ybin=ymax; ybin >= ymin; ybin--)
712 for(Int_t i=0; i<nmaxs[ybin-ymin]; i++)
714 Int_t local_value = local_maxima[ybin-ymin][i].value;
715 Int_t local_prev_value = local_maxima[ybin-ymin][i].prev_value;
716 Int_t local_next_value = 0;
719 continue; //already used
721 //start expanding in the psi-direction:
723 Int_t local_x_start = local_maxima[ybin-ymin][i].start_position;
724 Int_t local_x_end = local_maxima[ybin-ymin][i].end_position;
725 Int_t temp_x_start = local_maxima[ybin-ymin][i].start_position;
726 Int_t temp_x_end = local_maxima[ybin-ymin][i].end_position;
728 Int_t local_y=ybin-1,nybins=1;
730 while(local_y >= ymin)
733 for(Int_t j=0; j<nmaxs[local_y-ymin]; j++)
735 Int_t adapted_kappawindow;
736 Float_t adapted_x,adapted_y;
737 adapted_x = ((Float_t)local_x_start+(Float_t)local_x_end)/2.0;
738 adapted_y = ((Float_t)ybin+(Float_t)(local_y+1))/2.0;
739 // if(adapted_y<(-0.46*adapted_x+86) && adapted_y>(-0.46*adapted_x+56) && adapted_y<(-0.215*adapted_x+68) && adapted_y>(-0.215*adapted_x+40))
740 // if(adapted_y<(-0.215*adapted_x+68) && adapted_y>(-0.215*adapted_x+40))
741 // if((adapted_y<(-0.46*adapted_x+86) && adapted_y>(-0.46*adapted_x+56)) && !(adapted_y<(-0.215*adapted_x+68) && adapted_y>(-0.215*adapted_x+40)))
742 if(((adapted_y<(-0.46*adapted_x+86) && adapted_y>(-0.46*adapted_x+56)) && !(adapted_y<(-0.215*adapted_x+68) && adapted_y>(-0.215*adapted_x+40))) ||
743 ((adapted_y<(-0.215*adapted_x+68) && adapted_y>(-0.215*adapted_x+40))&& !(adapted_y<(-0.46*adapted_x+86) && adapted_y>(-0.46*adapted_x+56))))
744 adapted_kappawindow = 1;
746 adapted_kappawindow = 0;
748 // adapted_kappawindow = 0;
750 if( (local_maxima[local_y-ymin][j].start_position <= (temp_x_end + kappawindow + adapted_kappawindow)) && (local_maxima[local_y-ymin][j].end_position >= temp_x_start))
752 if( local_maxima[local_y-ymin][j].value == local_value )
754 local_x_end = local_maxima[local_y-ymin][j].end_position;
755 temp_x_start = local_maxima[local_y-ymin][j].start_position;
756 temp_x_end = local_maxima[local_y-ymin][j].end_position;
757 local_maxima[local_y-ymin][j].value = -1;
764 local_maxima[local_y-ymin][j].prev_value = local_value;
765 local_next_value = local_maxima[local_y-ymin][j].value;
769 if(!found || local_y == ymin)//no more local maximas to be matched, so write the final peak and break the expansion:
772 Float_t adapted_x,adapted_y;
773 adapted_x = ((Float_t)local_x_start+(Float_t)local_x_end)/2.0;
774 adapted_y = ((Float_t)ybin+(Float_t)(local_y+1))/2.0;
775 // if(adapted_y<(-0.46*adapted_x+86) && adapted_y>(-0.46*adapted_x+56) && adapted_y<(-0.215*adapted_x+68) && adapted_y>(-0.215*adapted_x+40))
776 // if(adapted_y<(-0.215*adapted_x+68) && adapted_y>(-0.215*adapted_x+40))
777 if((adapted_y<(-0.46*adapted_x+86) && adapted_y>(-0.46*adapted_x+56)) && !(adapted_y<(-0.215*adapted_x+68) && adapted_y>(-0.215*adapted_x+40)))
782 // adapted_xsize = 1;
783 if((nybins > ysize) && ((local_x_end-local_x_start+1) > adapted_xsize) && (local_value > local_prev_value) && (local_value > local_next_value))
785 fXPeaks[fNPeaks] = hist->GetPreciseBinCenterX(adapted_x);
786 fYPeaks[fNPeaks] = hist->GetPreciseBinCenterY(adapted_y);
787 fWeight[fNPeaks] = local_value;
789 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<<" "<<fXPeaks[fNPeaks]<<" "<<fYPeaks[fNPeaks]<<" with weight "<<fWeight[fNPeaks]<<" and size "<<local_x_end-local_x_start+1<<" by "<<nybins<<endl;
796 local_y--;//Search continues...
801 for(Int_t i=0; i<hist->GetNbinsY(); i++)
802 delete local_maxima[i];
804 delete [] local_maxima;
809 void AliL3HoughMaxFinder::FindPeak1(Int_t y_window,Int_t x_bin_sides)
811 //Testing mutliple peakfinding.
812 //The algorithm searches the histogram for prepreaks by looking in windows
813 //for each bin on the xaxis. The size of these windows is controlled by y_window.
814 //Then the prepreaks are sorted according to their weight (sum inside window),
815 //and the peak positions are calculated by taking the weighted mean in both
816 //x and y direction. The size of the peak in x-direction is controlled by x_bin_sides.
820 printf("AliL3HoughMaxFinder::FindPeak1 : No input histogram\n");
823 if(fCurrentHisto->GetNEntries()==0)
827 //Int_t x_bin_sides=1;
829 //Float_t max_kappa = 0.001;
830 //Float_t max_phi0 = 0.08;
834 Int_t xmin = fCurrentHisto->GetFirstXbin();
835 Int_t xmax = fCurrentHisto->GetLastXbin();
836 Int_t ymin = fCurrentHisto->GetFirstYbin();
837 Int_t ymax = fCurrentHisto->GetLastYbin();
838 Int_t nbinsx = fCurrentHisto->GetNbinsX()+1;
840 AxisWindow **windowPt = new AxisWindow*[nbinsx];
841 AxisWindow **anotherPt = new AxisWindow*[nbinsx];
843 for(Int_t i=0; i<nbinsx; i++)
845 windowPt[i] = new AxisWindow;
846 #if defined(__DECCXX)
847 bzero((char *)windowPt[i],sizeof(AxisWindow));
849 bzero((void*)windowPt[i],sizeof(AxisWindow));
851 anotherPt[i] = windowPt[i];
854 for(Int_t xbin=xmin; xbin<=xmax; xbin++)
857 for(Int_t ybin=ymin; ybin<=ymax-y_window; ybin++)
859 Int_t sum_in_window=0;
860 for(Int_t b=ybin; b<ybin+y_window; b++)
863 Int_t bin = fCurrentHisto->GetBin(xbin,b);
864 sum_in_window += (Int_t)fCurrentHisto->GetBinContent(bin);
867 if(sum_in_window > max_sum)
869 max_sum = sum_in_window;
870 windowPt[xbin]->ymin = ybin;
871 windowPt[xbin]->ymax = ybin + y_window;
872 windowPt[xbin]->weight = sum_in_window;
873 windowPt[xbin]->xbin = xbin;
878 //Sort the windows according to the weight
879 SortPeaks(windowPt,0,nbinsx);
882 for(Int_t i=0; i<nbinsx; i++)
885 Int_t xbin = windowPt[i]->xbin;
887 if(xbin<xmin || xbin > xmax-1) continue;
889 //Check if this is really a local maxima
890 if(anotherPt[xbin-1]->weight > anotherPt[xbin]->weight ||
891 anotherPt[xbin+1]->weight > anotherPt[xbin]->weight)
894 for(Int_t j=windowPt[i]->ymin; j<windowPt[i]->ymax; j++)
896 //Calculate the mean in y direction:
897 Int_t bin = fCurrentHisto->GetBin(windowPt[i]->xbin,j);
898 top += (fCurrentHisto->GetBinCenterY(j))*(fCurrentHisto->GetBinContent(bin));
899 butt += fCurrentHisto->GetBinContent(bin);
902 if(butt < fThreshold)
905 fXPeaks[fNPeaks] = fCurrentHisto->GetBinCenterX(windowPt[i]->xbin);
906 fYPeaks[fNPeaks] = top/butt;
907 fWeight[fNPeaks] = (Int_t)butt;
908 //cout<<"mean in y "<<ypeaks[n]<<" on x "<<windowPt[i]->xbin<<" content "<<butt<<endl;
912 cerr<<"AliL3HoughMaxFinder::FindPeak1 : Peak array out of range!!!"<<endl;
918 //Improve the peaks by including the region around in x.
922 for(Int_t i=0; i<fNPeaks; i++)
924 Int_t xbin = fCurrentHisto->FindXbin(fXPeaks[i]);
925 if(xbin - x_bin_sides < xmin || xbin + x_bin_sides > xmax) continue;
929 prev = xbin - x_bin_sides+1;
930 for(Int_t j=xbin-x_bin_sides; j<=xbin+x_bin_sides; j++)
933 //Check if the windows are overlapping:
934 if(anotherPt[j]->ymin > anotherPt[prev]->ymax) {prev=j; continue;}
935 if(anotherPt[j]->ymax < anotherPt[prev]->ymin) {prev=j; continue;}
939 top += fCurrentHisto->GetBinCenterX(j)*anotherPt[j]->weight;
940 butt += anotherPt[j]->weight;
942 for(Int_t k=anotherPt[j]->ymin; k<anotherPt[j]->ymax; k++)
944 Int_t bin = fCurrentHisto->GetBin(j,k);
945 ytop += (fCurrentHisto->GetBinCenterY(k))*(fCurrentHisto->GetBinContent(bin));
946 ybutt += fCurrentHisto->GetBinContent(bin);
947 w+=(Int_t)fCurrentHisto->GetBinContent(bin);
951 fXPeaks[i] = top/butt;
952 fYPeaks[i] = ytop/ybutt;
954 //cout<<"Setting weight "<<w<<" kappa "<<fXPeaks[i]<<" phi0 "<<fYPeaks[i]<<endl;
957 //Check if this peak is overlapping with a previous:
958 for(Int_t p=0; p<i; p++)
960 //cout<<fabs(fXPeaks[p] - fXPeaks[i])<<" "<<fabs(fYPeaks[p] - fYPeaks[i])<<endl;
961 if(fabs(fXPeaks[p] - fXPeaks[i]) < max_kappa &&
962 fabs(fYPeaks[p] - fYPeaks[i]) < max_phi0)
971 for(Int_t i=0; i<nbinsx; i++)
977 void AliL3HoughMaxFinder::SortPeaks(struct AxisWindow **a,Int_t first,Int_t last)
979 //General sorting routine
980 //Sort according to PeakCompare()
982 static struct AxisWindow *tmp;
983 static int i; // "static" to save stack space
986 while (last - first > 1) {
990 while (++i < last && PeakCompare(a[i], a[first]) < 0)
992 while (--j > first && PeakCompare(a[j], a[first]) > 0)
1008 if (j - first < last - (j + 1)) {
1009 SortPeaks(a, first, j);
1010 first = j + 1; // QSort(j + 1, last);
1012 SortPeaks(a, j + 1, last);
1013 last = j; // QSort(first, j);
1019 Int_t AliL3HoughMaxFinder::PeakCompare(struct AxisWindow *a,struct AxisWindow *b)
1021 if(a->weight < b->weight) return 1;
1022 if(a->weight > b->weight) return -1;
1026 void AliL3HoughMaxFinder::FindPeak(Int_t t1,Double_t t2,Int_t t3)
1028 //Attempt of a more sophisticated peak finder.
1029 //Finds the best peak in the histogram, and returns the corresponding
1034 printf("AliL3HoughMaxFinder::FindPeak : No histogram!!\n");
1037 AliL3Histogram *hist = fCurrentHisto;
1038 if(hist->GetNEntries()==0)
1041 Int_t xmin = hist->GetFirstXbin();
1042 Int_t xmax = hist->GetLastXbin();
1043 Int_t ymin = hist->GetFirstYbin();
1044 Int_t ymax = hist->GetLastYbin();
1045 Int_t nbinsx = hist->GetNbinsX()+1;
1047 Int_t *m = new Int_t[nbinsx];
1048 Int_t *m_low = new Int_t[nbinsx];
1049 Int_t *m_up = new Int_t[nbinsx];
1052 recompute: //this is a goto.
1054 for(Int_t i=0; i<nbinsx; i++)
1061 Int_t max_x=0,sum=0,max_xbin=0,bin=0;
1063 for(Int_t xbin=xmin; xbin<=xmax; xbin++)
1065 for(Int_t ybin=ymin; ybin <= ymax - t1; ybin++)
1068 for(Int_t y=ybin; y <= ybin+t1; y++)
1072 bin = hist->GetBin(xbin,y);
1073 sum += (Int_t)hist->GetBinContent(bin);
1076 if(sum > m[xbin]) //Max value locally in this xbin
1080 m_up[xbin]=ybin + t1;
1085 if(m[xbin] > max_x) //Max value globally in x-direction
1088 max_x = m[xbin];//sum;
1091 //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]);
1092 //printf("ylow %f yup %f\n",hist->GetBinCenterY(m_low[max_xbin]),hist->GetBinCenterY(m_up[max_xbin]));
1094 //Determine a width in the x-direction
1095 Int_t x_low=0,x_up=0;
1097 for(Int_t xbin=max_xbin-1; xbin >= xmin; xbin--)
1099 if(m[xbin] < max_x*t2)
1105 for(Int_t xbin = max_xbin+1; xbin <=xmax; xbin++)
1107 if(m[xbin] < max_x*t2)
1114 Double_t top=0,butt=0,value,x_peak;
1115 if(x_up - x_low + 1 > t3)
1118 printf("\nxrange out if limit x_up %d x_low %d t1 %d\n\n",x_low,x_up,t1);
1123 x_peak = hist->GetBinCenterX(max_xbin);
1128 //printf("xlow %f xup %f\n",hist->GetBinCenterX(x_low),hist->GetBinCenterX(x_up));
1129 //printf("Spread in x %d\n",x_up-x_low +1);
1131 //Now, calculate the center of mass in x-direction
1132 for(Int_t xbin=x_low; xbin <= x_up; xbin++)
1134 value = hist->GetBinCenterX(xbin);
1135 top += value*m[xbin];
1142 //Find the peak in y direction:
1143 Int_t x_l = hist->FindXbin(x_peak);
1144 if(hist->GetBinCenterX(x_l) > x_peak)
1147 Int_t x_u = x_l + 1;
1149 if(hist->GetBinCenterX(x_l) > x_peak || hist->GetBinCenterX(x_u) <= x_peak)
1150 printf("\nAliL3HoughMaxFinder::FindPeak : Wrong xrange %f %f %f\n\n",hist->GetBinCenterX(x_l),x_peak,hist->GetBinCenterX(x_u));
1152 //printf("\nxlow %f xup %f\n",hist->GetBinCenterX(x_l),hist->GetBinCenterX(x_u));
1156 //printf("ylow %f yup %f\n",hist->GetBinCenterY(m_low[x_l]),hist->GetBinCenterY(m_up[x_l]));
1157 //printf("ylow %f yup %f\n",hist->GetBinCenterY(m_low[x_u]),hist->GetBinCenterY(m_up[x_u]));
1159 for(Int_t ybin=m_low[x_l]; ybin <= m_up[x_l]; ybin++)
1161 value = hist->GetBinCenterY(ybin);
1162 bin = hist->GetBin(x_l,ybin);
1163 top += value*hist->GetBinContent(bin);
1164 butt += hist->GetBinContent(bin);
1166 Double_t y_peak_low = top/butt;
1168 //printf("y_peak_low %f\n",y_peak_low);
1171 for(Int_t ybin=m_low[x_u]; ybin <= m_up[x_u]; ybin++)
1173 value = hist->GetBinCenterY(ybin);
1174 bin = hist->GetBin(x_u,ybin);
1175 top += value*hist->GetBinContent(bin);
1176 butt += hist->GetBinContent(bin);
1178 Double_t y_peak_up = top/butt;
1180 //printf("y_peak_up %f\n",y_peak_up);
1182 Double_t x_value_up = hist->GetBinCenterX(x_u);
1183 Double_t x_value_low = hist->GetBinCenterX(x_l);
1185 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);
1189 //bin = hist->FindBin(x_peak,y_peak);
1190 //Int_t weight = (Int_t)hist->GetBinContent(bin);
1192 //AliL3HoughTrack *track = new AliL3HoughTrack();
1193 //track->SetTrackParameters(x_peak,y_peak,weight);
1194 fXPeaks[fNPeaks]=x_peak;
1195 fYPeaks[fNPeaks]=y_peak;
1196 fWeight[fNPeaks]=(Int_t)hist->GetBinContent(bin);