]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - HLT/hough/AliL3HoughMaxFinder.cxx
Added missing files and defines, compilation should now work again.
[u/mrichter/AliRoot.git] / HLT / hough / AliL3HoughMaxFinder.cxx
... / ...
CommitLineData
1// @(#) $Id$
2
3// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
4//*-- Copyright &copy ALICE HLT Group
5
6#include <strings.h>
7#include "AliL3StandardIncludes.h"
8
9#ifndef no_root
10#include <TNtuple.h>
11#include <TFile.h>
12#endif
13
14#include "AliL3Logging.h"
15#include "AliL3HoughMaxFinder.h"
16#include "AliL3Histogram.h"
17#include "AliL3TrackArray.h"
18#include "AliL3HoughTrack.h"
19
20#if __GNUC__ == 3
21using namespace std;
22#endif
23
24/** \class AliL3HoughMaxFinder
25<pre>
26//_____________________________________________________________
27// AliL3HoughMaxFinder
28//
29// Maximum finder
30//
31</pre>
32*/
33
34ClassImp(AliL3HoughMaxFinder)
35
36
37AliL3HoughMaxFinder::AliL3HoughMaxFinder()
38{
39 //Default constructor
40 fThreshold = 0;
41 fHistoType=0;
42 fXPeaks=0;
43 fYPeaks=0;
44 fNPeaks=0;
45 fNMax=0;
46 fGradX=1;
47 fGradY=1;
48#ifndef no_root
49 fNtuppel = 0;
50#endif
51}
52
53AliL3HoughMaxFinder::AliL3HoughMaxFinder(Char_t *histotype,Int_t nmax,AliL3Histogram *hist)
54{
55 //Constructor
56
57 //fTracks = new AliL3TrackArray("AliL3HoughTrack");
58 if(strcmp(histotype,"KappaPhi")==0) fHistoType='c';
59 if(strcmp(histotype,"DPsi")==0) fHistoType='l';
60
61 if(hist)
62 fCurrentHisto = hist;
63
64 fGradX=1;
65 fGradY=1;
66 fNMax=nmax;
67 fXPeaks = new Float_t[fNMax];
68 fYPeaks = new Float_t[fNMax];
69 fWeight = new Int_t[fNMax];
70#ifndef no_root
71 fNtuppel = 0;
72#endif
73 fThreshold=0;
74}
75
76AliL3HoughMaxFinder::~AliL3HoughMaxFinder()
77{
78 //Destructor
79 if(fXPeaks)
80 delete [] fXPeaks;
81 if(fYPeaks)
82 delete [] fYPeaks;
83 if(fWeight)
84 delete [] fWeight;
85#ifndef no_root
86 if(fNtuppel)
87 delete fNtuppel;
88#endif
89}
90
91void AliL3HoughMaxFinder::Reset()
92{
93 for(Int_t i=0; i<fNMax; i++)
94 {
95 fXPeaks[i]=0;
96 fYPeaks[i]=0;
97 fWeight[i]=0;
98 }
99 fNPeaks=0;
100}
101
102void AliL3HoughMaxFinder::CreateNtuppel()
103{
104#ifndef no_root
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);
108#endif
109}
110
111void AliL3HoughMaxFinder::WriteNtuppel(Char_t *filename)
112{
113#ifndef no_root
114 TFile *file = TFile::Open(filename,"RECREATE");
115 if(!file)
116 {
117 cerr<<"AliL3HoughMaxFinder::WriteNtuppel : Error opening file "<<filename<<endl;
118 return;
119 }
120 fNtuppel->Write();
121 file->Close();
122#endif
123}
124
125void AliL3HoughMaxFinder::FindAbsMaxima()
126{
127
128 if(!fCurrentHisto)
129 {
130 cerr<<"AliL3HoughMaxFinder::FindAbsMaxima : No histogram"<<endl;
131 return;
132 }
133 AliL3Histogram *hist = fCurrentHisto;
134
135 if(hist->GetNEntries() == 0)
136 return;
137
138 Int_t xmin = hist->GetFirstXbin();
139 Int_t xmax = hist->GetLastXbin();
140 Int_t ymin = hist->GetFirstYbin();
141 Int_t ymax = hist->GetLastYbin();
142 Int_t bin;
143 Double_t value,max_value=0;
144
145 Int_t max_xbin=0,max_ybin=0;
146 for(Int_t xbin=xmin; xbin<=xmax; xbin++)
147 {
148 for(Int_t ybin=ymin; ybin<=ymax; ybin++)
149 {
150 bin = hist->GetBin(xbin,ybin);
151 value = hist->GetBinContent(bin);
152 if(value>max_value)
153 {
154 max_value = value;
155 max_xbin = xbin;
156 max_ybin = ybin;
157 }
158 }
159 }
160
161 if(max_value == 0)
162 return;
163
164 if(fNPeaks > fNMax)
165 {
166 cerr<<"AliL3HoughMaxFinder::FindAbsMaxima : Array out of range : "<<fNPeaks<<endl;
167 return;
168 }
169
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;
175
176 fNPeaks++;
177#ifndef no_root
178 if(fNtuppel)
179 {
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);
184
185 fNtuppel->Fill(max_x,max_y,max_value,hist->GetBinContent(bin3),hist->GetBinContent(bin5),hist->GetBinContent(bin1),hist->GetBinContent(bin7));
186 }
187#endif
188}
189
190void AliL3HoughMaxFinder::FindBigMaxima()
191{
192
193 AliL3Histogram *hist = fCurrentHisto;
194
195 if(hist->GetNEntries() == 0)
196 return;
197
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;
203 Double_t value[25];
204
205 for(Int_t xbin=xmin+2; xbin<xmax-3; xbin++)
206 {
207 for(Int_t ybin=ymin+2; ybin<ymax-3; ybin++)
208 {
209 bin_index=0;
210 for(Int_t xb=xbin-2; xb<=xbin+2; xb++)
211 {
212 for(Int_t yb=ybin-2; yb<=ybin+2; yb++)
213 {
214 bin[bin_index]=hist->GetBin(xb,yb);
215 value[bin_index]=hist->GetBinContent(bin[bin_index]);
216 bin_index++;
217 }
218 }
219 if(value[12]==0) continue;
220 Int_t b=0;
221 while(1)
222 {
223 if(value[b] > value[12] || b==bin_index) break;
224 b++;
225 //printf("b %d\n",b);
226 }
227 if(b == bin_index)
228 {
229 //Found maxima
230 if(fNPeaks > fNMax)
231 {
232 cerr<<"AliL3HoughMaxFinder::FindBigMaxima : Array out of range "<<fNPeaks<<endl;
233 return;
234 }
235
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;
240 fNPeaks++;
241 }
242 }
243 }
244}
245
246void AliL3HoughMaxFinder::FindMaxima(Int_t threshold)
247{
248 //Locate all the maxima in input histogram.
249 //Maxima is defined as bins with more entries than the
250 //immediately neighbouring bins.
251
252 if(fCurrentHisto->GetNEntries() == 0)
253 return;
254
255 Int_t xmin = fCurrentHisto->GetFirstXbin();
256 Int_t xmax = fCurrentHisto->GetLastXbin();
257 Int_t ymin = fCurrentHisto->GetFirstYbin();
258 Int_t ymax = fCurrentHisto->GetLastYbin();
259 Int_t bin[9];
260 Double_t value[9];
261
262 //Float_t max_kappa = 0.001;
263 //Float_t max_phi0 = 0.08;
264
265 for(Int_t xbin=xmin+1; xbin<=xmax-1; xbin++)
266 {
267 for(Int_t ybin=ymin+1; ybin<=ymax-1; ybin++)
268 {
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]);
287
288
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])
292 {
293 //Found a local maxima
294 Float_t max_x = fCurrentHisto->GetBinCenterX(xbin);
295 Float_t max_y = fCurrentHisto->GetBinCenterY(ybin);
296
297 if((Int_t)value[4] <= threshold) continue;//central bin below threshold
298 if(fNPeaks >= fNMax)
299 {
300 cout<<"AliL3HoughMaxFinder::FindMaxima : Array out of range "<<fNPeaks<<endl;
301 return;
302 }
303
304 //Check the gradient:
305 if(value[3]/value[4] > fGradX && value[5]/value[4] > fGradX)
306 continue;
307
308 if(value[1]/value[4] > fGradY && value[7]/value[4] > fGradY)
309 continue;
310
311 fXPeaks[fNPeaks] = max_x;
312 fYPeaks[fNPeaks] = max_y;
313 fWeight[fNPeaks] = (Int_t)value[4];
314 fNPeaks++;
315
316 /*
317 //Check if the peak is overlapping with a previous:
318 Bool_t bigger = kFALSE;
319 for(Int_t p=0; p<fNPeaks; p++)
320 {
321 if(fabs(max_x - fXPeaks[p]) < max_kappa && fabs(max_y - fYPeaks[p]) < max_phi0)
322 {
323 bigger = kTRUE;
324 if(value[4] > fWeight[p]) //this peak is bigger.
325 {
326 fXPeaks[p] = max_x;
327 fYPeaks[p] = max_y;
328 fWeight[p] = (Int_t)value[4];
329 }
330 else
331 continue; //previous peak is bigger.
332 }
333 }
334 if(!bigger) //there were no overlapping peaks.
335 {
336 fXPeaks[fNPeaks] = max_x;
337 fYPeaks[fNPeaks] = max_y;
338 fWeight[fNPeaks] = (Int_t)value[4];
339 fNPeaks++;
340 }
341 */
342 }
343 }
344 }
345
346}
347
348struct Window
349{
350 Int_t start;
351 Int_t sum;
352};
353
354void AliL3HoughMaxFinder::FindAdaptedPeaks(Int_t kappawindow,Float_t cut_ratio)
355{
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.)
363
364
365 AliL3Histogram *hist = fCurrentHisto;
366
367 if(!hist)
368 {
369 cerr<<"AliL3HoughMaxFinder : No histogram!"<<endl;
370 return;
371 }
372
373 if(hist->GetNEntries() == 0)
374 return;
375
376 Int_t xmin = hist->GetFirstXbin();
377 Int_t xmax = hist->GetLastXbin();
378 Int_t ymin = hist->GetFirstYbin();
379 Int_t ymax = hist->GetLastYbin();
380
381
382 //Start by looking for pre-peaks:
383
384 Window **local_maxima = new Window*[hist->GetNbinsY()];
385
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++)
390 {
391 local_maxima[ybin-ymin] = new Window[hist->GetNbinsX()];
392 nmaxs[ybin-ymin] = 0;
393 sum_was_rising=0;
394 last_sum=0;
395 n=0;
396 for(Int_t xbin=xmin; xbin<=xmax-kappawindow; xbin++)
397 {
398 sum=0;
399 for(Int_t lbin=xbin; lbin<xbin+kappawindow; lbin++)
400 sum += hist->GetBinContent(hist->GetBin(lbin,ybin));
401
402 if(sum < last_sum)
403 {
404 if(sum > fThreshold)
405 if(sum_was_rising)//Previous sum was a local maxima
406 {
407 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].start = xbin-1;
408 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].sum = last_sum;
409 nmaxs[ybin-ymin]++;
410 }
411
412 sum_was_rising=0;
413 }
414 else if(sum > 0)
415 sum_was_rising=1;
416 last_sum=sum;
417 }
418 }
419
420 Int_t match=0;
421 Int_t *starts = new Int_t[hist->GetNbinsY()+1];
422 Int_t *maxs = new Int_t[hist->GetNbinsY()+1];
423
424 for(Int_t ybin=ymax; ybin >= ymin+1; ybin--)
425 {
426 for(Int_t i=0; i<nmaxs[ybin-ymin]; i++)
427 {
428 Int_t lw = local_maxima[ybin-ymin][i].sum;
429
430 if(lw<0)
431 continue; //already used
432
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)
436 {
437 maxvalue = hist->GetBinContent(hist->GetBin(k,ybin));
438 maxybin = ybin;
439 maxxbin = k;
440 }
441
442 //start expanding in the psi-direction:
443
444 Int_t lb = local_maxima[ybin-ymin][i].start;
445 //Int_t ystart=ybin;
446 starts[ybin] = local_maxima[ybin-ymin][i].start;
447 maxs[ybin] = maxxbin;
448 Int_t yl=ybin-1,nybins=1;
449
450 //cout<<"Starting search at ybin "<<ybin<<" start "<<lb<<" with sum "<<local_maxima[ybin-ymin][i].sum<<endl;
451 while(yl >= ymin)
452 {
453 Bool_t found=0;
454 for(Int_t j=0; j<nmaxs[yl-ymin]; j++)
455 {
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)
459 {
460
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;
462
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++)
465 {
466 if(hist->GetBinContent(hist->GetBin(k,yl)) > maxvalue)
467 {
468 maxvalue = hist->GetBinContent(hist->GetBin(k,yl));
469 maxxbin = k;
470 maxybin = yl;
471 maxwindow = j;
472 }
473 if(hist->GetBinContent(hist->GetBin(k,yl)) > lmaxvalue)//local maxima value
474 {
475 lmaxvalue=hist->GetBinContent(hist->GetBin(k,yl));
476 lmaxxbin=k;
477 }
478 }
479 nybins++;
480 starts[yl] = local_maxima[yl-ymin][j].start;
481 maxs[yl] = lmaxxbin;
482 local_maxima[yl-ymin][j].sum=-1; //Mark as used
483 found=1;
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.
486 }
487 }
488 if(!found || yl == ymin)//no more local maximas to be matched, so write the final peak and break the expansion:
489 {
490 if(nybins > 4)
491 {
492 //cout<<"ystart "<<ystart<<" and nybins "<<nybins<<endl;
493
494 Bool_t truepeak=kTRUE;
495
496 //cout<<"Maxima found at xbin "<<maxxbin<<" ybin "<<maxybin<<" value "<<maxvalue<<endl;
497 //cout<<"Starting to sum at xbin "<<starts[maxybin-ymin]<<endl;
498
499
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++)
503 {
504 for(Int_t r=maxybin+1; r<=maxybin+3; r++)
505 {
506 right += (Float_t)hist->GetBinContent(hist->GetBin(w,r));
507 }
508 }
509
510 for(Int_t w=maxxbin-1; w>=maxxbin-3; w--)
511 {
512 for(Int_t r=maxybin+1; r<=maxybin+3; r++)
513 {
514 left += (Float_t)hist->GetBinContent(hist->GetBin(w,r));
515 }
516 }
517
518 //cout<<"ratio "<<right/left<<endl;
519
520 Float_t upper_ratio=1,lower_ratio=1;
521 if(left)
522 upper_ratio = right/left;
523
524 right=left=0;
525 for(Int_t w=maxxbin+1; w<=maxxbin+3; w++)
526 {
527 for(Int_t r=maxybin-1; r>=maxybin-3; r--)
528 {
529 right += (Float_t)hist->GetBinContent(hist->GetBin(w,r));
530 }
531 }
532
533 for(Int_t w=maxxbin-1; w>=maxxbin-3; w--)
534 {
535 for(Int_t r=maxybin-1; r>=maxybin-3; r--)
536 {
537 left += (Float_t)hist->GetBinContent(hist->GetBin(w,r));
538 }
539 }
540
541 //cout<<"ratio "<<left/right<<endl;
542
543 if(right)
544 lower_ratio = left/right;
545
546 if(upper_ratio > cut_ratio || lower_ratio > cut_ratio)
547 truepeak=kFALSE;
548
549 if(truepeak)
550 {
551
552 fXPeaks[fNPeaks] = hist->GetBinCenterX(maxxbin);
553 fYPeaks[fNPeaks] = hist->GetBinCenterY(maxybin);
554 fWeight[fNPeaks] = maxvalue;
555 fNPeaks++;
556
557 /*
558 //Calculate the peak using weigthed means:
559 Float_t sum=0;
560 fYPeaks[fNPeaks]=0;
561 for(Int_t k=maxybin-1; k<=maxybin+1; k++)
562 {
563 Float_t lsum = 0;
564 for(Int_t l=starts[k]; l<starts[k]+kappawindow; l++)
565 {
566 lsum += (Float_t)hist->GetBinContent(hist->GetBin(l,k));
567 sum += (Float_t)hist->GetBinContent(hist->GetBin(l,k));
568 }
569 fYPeaks[fNPeaks] += lsum*hist->GetBinCenterY(k);
570 }
571 fYPeaks[fNPeaks] /= sum;
572 Int_t ybin1,ybin2;
573 if(fYPeaks[fNPeaks] < hist->GetBinCenterY(hist->FindYbin(fYPeaks[fNPeaks])))
574 {
575 ybin1 = hist->FindYbin(fYPeaks[fNPeaks])-1;
576 ybin2 = ybin1+1;
577 }
578 else
579 {
580 ybin1 = hist->FindYbin(fYPeaks[fNPeaks]);
581 ybin2 = ybin1+1;
582 }
583
584 Float_t kappa1=0,kappa2=0;
585 sum=0;
586 for(Int_t k=starts[ybin1]; k<starts[ybin1] + kappawindow; k++)
587 {
588 kappa1 += hist->GetBinCenterX(k)*hist->GetBinContent(hist->GetBin(k,ybin1));
589 sum += (Float_t)hist->GetBinContent(hist->GetBin(k,ybin1));
590 }
591 kappa1 /= sum;
592 sum=0;
593 for(Int_t k=starts[ybin2]; k<starts[ybin2] + kappawindow; k++)
594 {
595 kappa2 += hist->GetBinCenterX(k)*hist->GetBinContent(hist->GetBin(k,ybin2));
596 sum += (Float_t)hist->GetBinContent(hist->GetBin(k,ybin2));
597 }
598 kappa2 /= sum;
599
600 fXPeaks[fNPeaks] = ( kappa1*( hist->GetBinCenterY(ybin2) - fYPeaks[fNPeaks] ) +
601 kappa2*( fYPeaks[fNPeaks] - hist->GetBinCenterY(ybin1) ) ) /
602 (hist->GetBinCenterY(ybin2) - hist->GetBinCenterY(ybin1));
603
604 fNPeaks++;
605 */
606 }
607 }
608 break;
609 }
610 else
611 yl--;//Search continues...
612 }
613 }
614 }
615
616 for(Int_t i=0; i<hist->GetNbinsY(); i++)
617 delete local_maxima[i];
618
619 delete [] local_maxima;
620 delete [] nmaxs;
621 delete [] starts;
622 delete [] maxs;
623}
624
625struct PreYPeak
626{
627 Int_t start_position;
628 Int_t end_position;
629 Int_t value;
630 Int_t prev_value;
631};
632
633struct Pre2DPeak
634{
635 Int_t start_x_position;
636 Int_t end_x_position;
637 Int_t start_y_position;
638 Int_t end_y_position;
639 Int_t value;
640};
641
642void AliL3HoughMaxFinder::FindAdaptedRowPeaks(Int_t kappawindow,Int_t /*xsize*/,Int_t ysize)
643{
644
645 AliL3Histogram *hist = fCurrentHisto;
646
647 if(!hist)
648 {
649 cerr<<"AliL3HoughMaxFinder : No histogram!"<<endl;
650 return;
651 }
652
653 if(hist->GetNEntries() == 0)
654 return;
655
656 Int_t xmin = hist->GetFirstXbin();
657 Int_t xmax = hist->GetLastXbin();
658 Int_t ymin = hist->GetFirstYbin();
659 Int_t ymax = hist->GetLastYbin();
660
661 //Start by looking for pre-peaks:
662
663 PreYPeak **local_maxima = new PreYPeak*[hist->GetNbinsY()];
664
665 Short_t *nmaxs = new Short_t[hist->GetNbinsY()];
666 Int_t n2dmax = 0;
667 Int_t last_value,value;
668 for(Int_t ybin=ymin; ybin<=ymax; ybin++)
669 {
670 local_maxima[ybin-ymin] = new PreYPeak[hist->GetNbinsX()];
671 nmaxs[ybin-ymin] = 0;
672 last_value = 0;
673 Bool_t found = 0;
674 for(Int_t xbin=xmin; xbin<=xmax; xbin++)
675 {
676 value = hist->GetBinContent(hist->GetBin(xbin,ybin));
677 if(value >= fThreshold)
678 {
679 if(value > last_value)
680 // if(value > (last_value + 1))
681 {
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;
686 found = 1;
687 }
688 if(value == last_value)
689 // if(abs(value - last_value) <= 1)
690 if(found)
691 local_maxima[ybin-ymin][nmaxs[ybin-ymin]].end_position = xbin;
692 }
693
694 if((value < fThreshold) || (value < last_value))
695 // if((value < fThreshold) || (value < (last_value - 1)))
696 {
697 if(found)
698 {
699 nmaxs[ybin-ymin]++;
700 found = 0;
701 }
702 }
703 last_value = value;
704
705 }
706 n2dmax += nmaxs[ybin-ymin];
707 }
708
709 // Pre2DPeak *maxima = new Pre2DPeak[n2dmax];
710 for(Int_t ybin=ymax; ybin >= ymin; ybin--)
711 {
712 for(Int_t i=0; i<nmaxs[ybin-ymin]; i++)
713 {
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;
717
718 if(local_value<0)
719 continue; //already used
720
721 //start expanding in the psi-direction:
722
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;
727
728 Int_t local_y=ybin-1,nybins=1;
729
730 while(local_y >= ymin)
731 {
732 Bool_t found=0;
733 for(Int_t j=0; j<nmaxs[local_y-ymin]; j++)
734 {
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;
745 else
746 adapted_kappawindow = 0;
747 //temprorary here
748 // adapted_kappawindow = 0;
749
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))
751 {
752 if( local_maxima[local_y-ymin][j].value == local_value )
753 {
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;
758 found = 1;
759 nybins++;
760 break;
761 }
762 else
763 {
764 local_maxima[local_y-ymin][j].prev_value = local_value;
765 local_next_value = local_maxima[local_y-ymin][j].value;
766 }
767 }
768 }
769 if(!found || local_y == ymin)//no more local maximas to be matched, so write the final peak and break the expansion:
770 {
771 Int_t adapted_xsize;
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)))
778 adapted_xsize = 1;
779 else
780 adapted_xsize = 2;
781 //temprorary here
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))
784 {
785 fXPeaks[fNPeaks] = hist->GetPreciseBinCenterX(adapted_x);
786 fYPeaks[fNPeaks] = hist->GetPreciseBinCenterY(adapted_y);
787 fWeight[fNPeaks] = local_value;
788#ifdef do_mc
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;
790#endif
791 fNPeaks++;
792 }
793 break;
794 }
795 else
796 local_y--;//Search continues...
797 }
798 }
799 }
800
801 for(Int_t i=0; i<hist->GetNbinsY(); i++)
802 delete local_maxima[i];
803
804 delete [] local_maxima;
805 delete [] nmaxs;
806 //delete [] maxima;
807}
808
809void AliL3HoughMaxFinder::FindPeak1(Int_t y_window,Int_t x_bin_sides)
810{
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.
817
818 if(!fCurrentHisto)
819 {
820 printf("AliL3HoughMaxFinder::FindPeak1 : No input histogram\n");
821 return;
822 }
823 if(fCurrentHisto->GetNEntries()==0)
824 return;
825
826 //Int_t y_window=2;
827 //Int_t x_bin_sides=1;
828
829 //Float_t max_kappa = 0.001;
830 //Float_t max_phi0 = 0.08;
831
832 Int_t max_sum=0;
833
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;
839
840 AxisWindow **windowPt = new AxisWindow*[nbinsx];
841 AxisWindow **anotherPt = new AxisWindow*[nbinsx];
842
843 for(Int_t i=0; i<nbinsx; i++)
844 {
845 windowPt[i] = new AxisWindow;
846#if defined(__DECCXX)
847 bzero((char *)windowPt[i],sizeof(AxisWindow));
848#else
849 bzero((void*)windowPt[i],sizeof(AxisWindow));
850#endif
851 anotherPt[i] = windowPt[i];
852 }
853
854 for(Int_t xbin=xmin; xbin<=xmax; xbin++)
855 {
856 max_sum = 0;
857 for(Int_t ybin=ymin; ybin<=ymax-y_window; ybin++)
858 {
859 Int_t sum_in_window=0;
860 for(Int_t b=ybin; b<ybin+y_window; b++)
861 {
862 //inside window
863 Int_t bin = fCurrentHisto->GetBin(xbin,b);
864 sum_in_window += (Int_t)fCurrentHisto->GetBinContent(bin);
865 }
866
867 if(sum_in_window > max_sum)
868 {
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;
874 }
875 }
876 }
877
878 //Sort the windows according to the weight
879 SortPeaks(windowPt,0,nbinsx);
880
881 Float_t top,butt;
882 for(Int_t i=0; i<nbinsx; i++)
883 {
884 top=butt=0;
885 Int_t xbin = windowPt[i]->xbin;
886
887 if(xbin<xmin || xbin > xmax-1) continue;
888
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)
892 continue;
893
894 for(Int_t j=windowPt[i]->ymin; j<windowPt[i]->ymax; j++)
895 {
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);
900 }
901
902 if(butt < fThreshold)
903 continue;
904
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;
909 fNPeaks++;
910 if(fNPeaks==fNMax)
911 {
912 cerr<<"AliL3HoughMaxFinder::FindPeak1 : Peak array out of range!!!"<<endl;
913 break;
914 }
915 }
916
917
918 //Improve the peaks by including the region around in x.
919 Float_t ytop,ybutt;
920 Int_t prev;
921 Int_t w;
922 for(Int_t i=0; i<fNPeaks; i++)
923 {
924 Int_t xbin = fCurrentHisto->FindXbin(fXPeaks[i]);
925 if(xbin - x_bin_sides < xmin || xbin + x_bin_sides > xmax) continue;
926 top=butt=0;
927 ytop=0,ybutt=0;
928 w=0;
929 prev = xbin - x_bin_sides+1;
930 for(Int_t j=xbin-x_bin_sides; j<=xbin+x_bin_sides; j++)
931 {
932 /*
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;}
936 prev = j;
937 */
938
939 top += fCurrentHisto->GetBinCenterX(j)*anotherPt[j]->weight;
940 butt += anotherPt[j]->weight;
941
942 for(Int_t k=anotherPt[j]->ymin; k<anotherPt[j]->ymax; k++)
943 {
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);
948 }
949 }
950
951 fXPeaks[i] = top/butt;
952 fYPeaks[i] = ytop/ybutt;
953 fWeight[i] = w;
954 //cout<<"Setting weight "<<w<<" kappa "<<fXPeaks[i]<<" phi0 "<<fYPeaks[i]<<endl;
955
956 /*
957 //Check if this peak is overlapping with a previous:
958 for(Int_t p=0; p<i; p++)
959 {
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)
963 {
964 fWeight[i]=0;
965 //break;
966 }
967 }
968 */
969 }
970
971 for(Int_t i=0; i<nbinsx; i++)
972 delete windowPt[i];
973 delete [] windowPt;
974 delete [] anotherPt;
975}
976
977void AliL3HoughMaxFinder::SortPeaks(struct AxisWindow **a,Int_t first,Int_t last)
978{
979 //General sorting routine
980 //Sort according to PeakCompare()
981
982 static struct AxisWindow *tmp;
983 static int i; // "static" to save stack space
984 int j;
985
986 while (last - first > 1) {
987 i = first;
988 j = last;
989 for (;;) {
990 while (++i < last && PeakCompare(a[i], a[first]) < 0)
991 ;
992 while (--j > first && PeakCompare(a[j], a[first]) > 0)
993 ;
994 if (i >= j)
995 break;
996
997 tmp = a[i];
998 a[i] = a[j];
999 a[j] = tmp;
1000 }
1001 if (j == first) {
1002 ++first;
1003 continue;
1004 }
1005 tmp = a[first];
1006 a[first] = a[j];
1007 a[j] = tmp;
1008 if (j - first < last - (j + 1)) {
1009 SortPeaks(a, first, j);
1010 first = j + 1; // QSort(j + 1, last);
1011 } else {
1012 SortPeaks(a, j + 1, last);
1013 last = j; // QSort(first, j);
1014 }
1015 }
1016
1017}
1018
1019Int_t AliL3HoughMaxFinder::PeakCompare(struct AxisWindow *a,struct AxisWindow *b)
1020{
1021 if(a->weight < b->weight) return 1;
1022 if(a->weight > b->weight) return -1;
1023 return 0;
1024}
1025
1026void AliL3HoughMaxFinder::FindPeak(Int_t t1,Double_t t2,Int_t t3)
1027{
1028 //Attempt of a more sophisticated peak finder.
1029 //Finds the best peak in the histogram, and returns the corresponding
1030 //track object.
1031
1032 if(!fCurrentHisto)
1033 {
1034 printf("AliL3HoughMaxFinder::FindPeak : No histogram!!\n");
1035 return;
1036 }
1037 AliL3Histogram *hist = fCurrentHisto;
1038 if(hist->GetNEntries()==0)
1039 return;
1040
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;
1046
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];
1050
1051
1052 recompute: //this is a goto.
1053
1054 for(Int_t i=0; i<nbinsx; i++)
1055 {
1056 m[i]=0;
1057 m_low[i]=0;
1058 m_up[i]=0;
1059 }
1060
1061 Int_t max_x=0,sum=0,max_xbin=0,bin=0;
1062
1063 for(Int_t xbin=xmin; xbin<=xmax; xbin++)
1064 {
1065 for(Int_t ybin=ymin; ybin <= ymax - t1; ybin++)
1066 {
1067 sum = 0;
1068 for(Int_t y=ybin; y <= ybin+t1; y++)
1069 {
1070 if(y>ymax) break;
1071 //Inside window
1072 bin = hist->GetBin(xbin,y);
1073 sum += (Int_t)hist->GetBinContent(bin);
1074
1075 }
1076 if(sum > m[xbin]) //Max value locally in this xbin
1077 {
1078 m[xbin]=sum;
1079 m_low[xbin]=ybin;
1080 m_up[xbin]=ybin + t1;
1081 }
1082
1083 }
1084
1085 if(m[xbin] > max_x) //Max value globally in x-direction
1086 {
1087 max_xbin = xbin;
1088 max_x = m[xbin];//sum;
1089 }
1090 }
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]));
1093
1094 //Determine a width in the x-direction
1095 Int_t x_low=0,x_up=0;
1096
1097 for(Int_t xbin=max_xbin-1; xbin >= xmin; xbin--)
1098 {
1099 if(m[xbin] < max_x*t2)
1100 {
1101 x_low = xbin+1;
1102 break;
1103 }
1104 }
1105 for(Int_t xbin = max_xbin+1; xbin <=xmax; xbin++)
1106 {
1107 if(m[xbin] < max_x*t2)
1108 {
1109 x_up = xbin-1;
1110 break;
1111 }
1112 }
1113
1114 Double_t top=0,butt=0,value,x_peak;
1115 if(x_up - x_low + 1 > t3)
1116 {
1117 t1 -= 1;
1118 printf("\nxrange out if limit x_up %d x_low %d t1 %d\n\n",x_low,x_up,t1);
1119 if(t1 > 1)
1120 goto recompute;
1121 else
1122 {
1123 x_peak = hist->GetBinCenterX(max_xbin);
1124 goto moveon;
1125 }
1126 }
1127
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);
1130
1131 //Now, calculate the center of mass in x-direction
1132 for(Int_t xbin=x_low; xbin <= x_up; xbin++)
1133 {
1134 value = hist->GetBinCenterX(xbin);
1135 top += value*m[xbin];
1136 butt += m[xbin];
1137 }
1138 x_peak = top/butt;
1139
1140 moveon:
1141
1142 //Find the peak in y direction:
1143 Int_t x_l = hist->FindXbin(x_peak);
1144 if(hist->GetBinCenterX(x_l) > x_peak)
1145 x_l--;
1146
1147 Int_t x_u = x_l + 1;
1148
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));
1151
1152 //printf("\nxlow %f xup %f\n",hist->GetBinCenterX(x_l),hist->GetBinCenterX(x_u));
1153
1154 value=top=butt=0;
1155
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]));
1158
1159 for(Int_t ybin=m_low[x_l]; ybin <= m_up[x_l]; ybin++)
1160 {
1161 value = hist->GetBinCenterY(ybin);
1162 bin = hist->GetBin(x_l,ybin);
1163 top += value*hist->GetBinContent(bin);
1164 butt += hist->GetBinContent(bin);
1165 }
1166 Double_t y_peak_low = top/butt;
1167
1168 //printf("y_peak_low %f\n",y_peak_low);
1169
1170 value=top=butt=0;
1171 for(Int_t ybin=m_low[x_u]; ybin <= m_up[x_u]; ybin++)
1172 {
1173 value = hist->GetBinCenterY(ybin);
1174 bin = hist->GetBin(x_u,ybin);
1175 top += value*hist->GetBinContent(bin);
1176 butt += hist->GetBinContent(bin);
1177 }
1178 Double_t y_peak_up = top/butt;
1179
1180 //printf("y_peak_up %f\n",y_peak_up);
1181
1182 Double_t x_value_up = hist->GetBinCenterX(x_u);
1183 Double_t x_value_low = hist->GetBinCenterX(x_l);
1184
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);
1186
1187
1188 //Find the weight:
1189 //bin = hist->FindBin(x_peak,y_peak);
1190 //Int_t weight = (Int_t)hist->GetBinContent(bin);
1191
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);
1197 fNPeaks++;
1198
1199 delete [] m;
1200 delete [] m_low;
1201 delete [] m_up;
1202
1203 //return track;
1204}
1205