1 #include "PeakFinder.h" 5 #include "Minuit2/Minuit2Minimizer.h" 6 #include "Math/Interpolator.h" 9 #ifdef UCORRELATOR_USE_EIGEN_FOR_PEAK_FINDER 10 #include <Eigen/Dense> 13 #include "TDecompSVD.h" 18 static bool isLocalMaxima(
const TH2D * hist,
int bin)
22 const double* I = hist->GetArray();
23 const int width = hist->GetNbinsX()+2;
28 if (I[bin-1] >= I[bin])
return false;
29 if (I[bin+1] > I[bin])
return false;
30 if (I[bin-width-1] >= I[bin])
return false;
31 if (I[bin-width] >= I[bin])
return false;
32 if (I[bin-width+1] >= I[bin])
return false;
33 if (I[bin+width+1] > I[bin])
return false;
34 if (I[bin+width] > I[bin])
return false;
35 if (I[bin+width+1] > I[bin])
return false;
41 static int findMaximum(
const TH2D* hist, std::vector<char> * notallowed)
43 const double * arr = hist->GetArray();
44 int width = hist->GetNbinsX() + 2;
45 int height = hist->GetNbinsY() + 2;
46 int N = width * height;
48 double max = -DBL_MAX;
50 for (
int i = 0; i < N; i++)
52 if (notallowed->at(i))
59 if (i % width == 0)
continue;
60 if (i % width == width-1)
continue;
61 if (i / width == 0)
continue;
62 if (i / width == height-1)
break;
64 if (arr[i] > max && isLocalMaxima(hist,i))
73 static void maskNearbyBins(
const TH2D * hist,
double distance,
int bin, std::vector<char> * used)
76 const int width = hist->GetNbinsX()+2;
77 const int height = hist->GetNbinsY()+2;
78 int int_dist = int(distance+0.5);
80 double dw = hist->GetXaxis()->GetBinWidth(1);
81 double dh = hist->GetYaxis()->GetBinWidth(1);
89 double dist2 = distance*distance;
91 for (
int jj = -int_dist; jj <= int_dist; jj++)
95 if (j >= height)
continue;
97 for (
int ii = -int_dist; ii <= int_dist; ii++)
100 if (i < 1) i += width;
101 if (i >= width) i-=width;
102 if (ii*ii*dw2 + j2*dh2 > dist2)
continue;
104 int bin2use = i+ j * width;
106 (*used)[bin2use] = 1;
113 double minPhi,
double maxPhi,
double minTheta,
double maxTheta,
bool exclude,
bool use_bin_center)
115 int width = hist->GetNbinsX()+2;
116 int height = hist->GetNbinsY()+2;
117 std::vector<char> used( width*height,
false);
121 std::vector<int> row_not_allowed(0);
122 std::vector<int> col_not_allowed(0);
128 if(minTheta != maxTheta)
130 for(
int ybin = 2; ybin < hist->GetNbinsY(); ybin++)
132 double yCenter = hist->GetYaxis()->GetBinCenter(ybin);
133 if(yCenter <= minTheta || yCenter >= maxTheta) row_not_allowed.push_back(ybin);
140 for(
int xbin = 1; xbin < hist->GetNbinsX()+1; xbin++)
142 double xCenter = hist->GetXaxis()->GetBinCenter(xbin);
143 if( (xCenter <= minPhi && xCenter >= maxPhi ))
146 col_not_allowed.push_back(xbin);
151 for (
unsigned i = 0; i < row_not_allowed.size(); i++)
153 memset(&used[(width)*row_not_allowed[i]], 1, width);
155 for (
unsigned i = 0; i < col_not_allowed.size(); i++)
157 for(
unsigned j = 0; j < (unsigned) height; j++) used[col_not_allowed[i] + (j*width)] = 1;
163 for(
unsigned i = 0; i < (unsigned)width*height; i++) used[i] = used[i] xor 1;
168 int rows_not_allowed[] = {1,hist->GetNbinsY()};
169 for(
unsigned i = 0; i <
sizeof(rows_not_allowed) /
sizeof(*rows_not_allowed); i++)
171 memset(&used[(width)*rows_not_allowed[i]], 1, width);
174 while (nfound < Nmaxima)
176 int bin = findMaximum(hist, &used);
179 maxima[nfound].bin = bin;
180 maxima[nfound].val = hist->GetArray()[bin];
181 int xbin = bin % (hist->GetNbinsX() + 2);
182 maxima[nfound].xbin = xbin;
183 maxima[nfound].x = use_bin_center ? hist->GetXaxis()->GetBinCenter(xbin) : hist->GetXaxis()->GetBinLowEdge(xbin);
184 int ybin = bin / (hist->GetNbinsX() + 2);
185 maxima[nfound].y = use_bin_center ? hist->GetYaxis()->GetBinCenter(ybin) : hist->GetYaxis()->GetBinLowEdge(ybin);
186 maskNearbyBins(hist, distance, bin, &used);
190 for (
int i = nfound; i < Nmaxima; i++)
193 maxima[i].val = -9999;
209 p->
rho = covar / (sigma_x * sigma_y);
214 const int X2COEFF = 0;
215 const int Y2COEFF = 1;
216 const int XYCOEFF = 2;
217 const int XCOEFF = 3;
218 const int YCOEFF = 4;
219 const int CCOEFF = 5;
223 #ifdef UCORRELATOR_USE_EIGEN_FOR_PEAK_FINDER 225 template <
unsigned N>
226 static const Eigen::Matrix<double,N*N,6> & getM()
229 static Eigen::Matrix<double, N*N,6> M;
230 for (
unsigned i = 0; i < N; i++)
232 for (
unsigned j = 0; j < N; j++)
236 M(i + j * N, X2COEFF) = x * x;
237 M(i + j * N, Y2COEFF) = y * y;
238 M(i + j * N, XYCOEFF) = x * y;
239 M(i + j * N, XCOEFF) = x;
240 M(i + j * N, YCOEFF) = y;
241 M(i + j * N, CCOEFF) = 1;
247 template <
unsigned N>
248 static const Eigen::JacobiSVD<Eigen::Matrix<double, N*N,6> > & getSVD()
250 static Eigen::JacobiSVD<Eigen::Matrix<double, N*N,6> > svd(getM<N>(),Eigen::ComputeFullU | Eigen::ComputeFullV);
255 template <
unsigned N>
256 static const TMatrixD & getM()
259 static TMatrixD M(N*N,6);
260 for (
unsigned i = 0; i < N; i++)
262 for (
unsigned j = 0; j < N; j++)
266 M(i + j * N, X2COEFF) = x * x;
267 M(i + j * N, Y2COEFF) = y * y;
268 M(i + j * N, XYCOEFF) = x * y;
269 M(i + j * N, XCOEFF) = x;
270 M(i + j * N, YCOEFF) = y;
271 M(i + j * N, CCOEFF) = 1;
278 template <
unsigned N>
279 static const TDecompSVD & getSVD()
281 static TDecompSVD svd(getM<N>());
291 template <
unsigned N>
294 int xmax, ymax, ignored;
295 hist->GetMaximumBin(xmax,ymax,ignored);
297 double dx = hist->GetXaxis()->GetBinWidth(1);
298 double dy = hist->GetYaxis()->GetBinWidth(1);
299 int nbinsx = hist->GetNbinsX();
300 int nbinsy = hist->GetNbinsY();
301 int width = nbinsx + 2;
304 #ifdef UCORRELATOR_USE_EIGEN_FOR_PEAK_FINDER 305 static const Eigen::JacobiSVD<Eigen::Matrix<double, N*N, 6> > & svd = getSVD<N>();
306 Eigen::Matrix<double,N*N,1> Z;
308 static const TDecompSVD & svd = getSVD<N>();
313 double xcenter = hist->GetXaxis()->GetBinCenter(xmax);
314 double ycenter = hist->GetYaxis()->GetBinCenter(ymax);
318 for (
unsigned i = 0; i < N; i++)
320 for (
unsigned j = 0; j < N; j++)
322 int ii = xmax + i - halfway;
323 int jj = ymax + j - halfway;
324 double z = ii < 1 || ii > nbinsx || jj < 1 || jj > nbinsy ? 0 : hist->GetArray()[ii + jj * width];
330 #ifdef UCORRELATOR_USE_EIGEN_FOR_PEAK_FINDER 331 Eigen::Matrix<double,6,1> B = svd.solve(Z);
334 TVectorD B = ((TDecompSVD & )svd).Solve(Z,ok);
337 fprintf(stderr,
"Warning in doQuadraticPeakFinding: SVD decomposition failed!\n");
343 double a = B(X2COEFF);
344 double b = B(Y2COEFF);
345 double c = B(XYCOEFF);
346 double d = B(XCOEFF);
347 double e = B(YCOEFF);
348 double f = B(CCOEFF);
353 double x0 = (2 * b * d / c - e) / (c - 4*a*b / c);
354 double y0 = ( -d - 2* a * x0)/ c;
356 peak->x = xcenter + x0*dx;
357 peak->y = ycenter + y0*dy;
361 peak->val = a*x0*x0 + b * y0*y0 + c * x0*y0 + d * x0 + e * y0 + f;
362 peak->sigma_x = sqrt(-2*b*peak->val / fabs(4*a*b - c*c))*dx;
363 peak->sigma_y = sqrt(-2*a*peak->val / fabs(4*a*b - c*c))*dy;
364 peak->covar = c*peak->val / fabs(4*a*b - c*c)*dx*dy;
365 #ifdef UCORRELATOR_USE_EIGEN_FOR_PEAK_FINDER 366 peak->chisq = (getM<N>() * B - Z).squaredNorm()/ (N*N);
368 peak->chisq = (getM<N>() * B - Z).Norm2Sqr()/ (N*N);
376 doQuadraticPeakFinding<3>(hist,peak);
379 void UCorrelator::peakfinder::doPeakFindingQuadratic16(
const TH2D * hist, FineMaximum * peak)
381 doQuadraticPeakFinding<4>(hist,peak);
384 void UCorrelator::peakfinder::doPeakFindingQuadratic25(
const TH2D * hist, FineMaximum * peak)
386 doQuadraticPeakFinding<5>(hist,peak);
389 void UCorrelator::peakfinder::doPeakFindingQuadratic36(
const TH2D * hist, FineMaximum * peak)
391 doQuadraticPeakFinding<6>(hist,peak);
394 void UCorrelator::peakfinder::doPeakFindingQuadratic49(
const TH2D * hist, FineMaximum * peak)
396 doQuadraticPeakFinding<7>(hist,peak);
407 int peakPhiBin, peakThetaBin, ignored;
408 int max_bin = hist->GetMaximumBin(peakPhiBin,peakThetaBin,ignored);
409 double peakVal = hist->GetArray()[max_bin];
411 int NUM_BINS_FINE_THETA = hist->GetNbinsY();
412 int NUM_BINS_FINE_PHI = hist->GetNbinsX();
413 double FINE_BIN_SIZE=hist->GetXaxis()->GetBinWidth(1);
415 int npointsTheta=NUM_BINS_FINE_THETA - 19;
416 int npointsPhi=NUM_BINS_FINE_THETA - 19;
418 double thetaArray[npointsTheta];
419 double phiArray[npointsPhi];
420 double thetaValArray[npointsTheta], phiValArray[npointsPhi];
422 for (
int i=0;i<npointsTheta;i++){
423 if (
int(peakThetaBin-npointsTheta/2.)>=0 &&
int(peakThetaBin+npointsTheta/2.)<NUM_BINS_FINE_THETA){
424 thetaValArray[i]=hist->GetBinContent(
int(peakThetaBin-npointsTheta/2+i),peakPhiBin);
425 thetaArray[i]=hist->GetYaxis()->GetBinCenter(
int(peakThetaBin-npointsTheta/2+i));
428 else if(
int(peakThetaBin-npointsTheta/2.)<0){
429 thetaValArray[i]=hist->GetBinContent(i,peakPhiBin);
430 thetaArray[i]=hist->GetYaxis()->GetBinCenter(i);
433 thetaValArray[i]=hist->GetBinContent(NUM_BINS_FINE_THETA-(npointsTheta-i),peakPhiBin);
434 thetaArray[i]=hist->GetYaxis()->GetBinCenter(NUM_BINS_FINE_THETA-(npointsTheta-i));
437 for (
int i=0;i<npointsPhi;i++){
438 if (
int(peakPhiBin-npointsPhi/2.)>=0 &&
int(peakPhiBin+npointsPhi/2.)<NUM_BINS_FINE_PHI){
439 phiValArray[i]=hist->GetBinContent(peakThetaBin,
int(peakPhiBin-npointsPhi/2+i));
440 phiArray[i]=hist->GetXaxis()->GetBinCenter(
int(peakPhiBin-npointsPhi/2+i));
443 else if (
int(peakPhiBin-npointsPhi/2.)<0){
444 phiValArray[i]=hist->GetBinContent(peakThetaBin,i);
445 phiArray[i]=hist->GetXaxis()->GetBinCenter(i);
448 phiValArray[i]=hist->GetBinContent(peakThetaBin,NUM_BINS_FINE_PHI-(npointsPhi-i));
449 phiArray[i]=hist->GetXaxis()->GetBinCenter(NUM_BINS_FINE_PHI-(npointsPhi-i));
456 std::vector<double> thetaVector(npointsTheta);
457 std::vector<double> thetaValVector(npointsTheta);
458 std::vector<double> phiVector(npointsPhi);
459 std::vector<double> phiValVector(npointsPhi);
460 for (
int i=0;i<npointsTheta;i++){
461 thetaVector[i]=thetaArray[i];
462 thetaValVector[i]=thetaValArray[i];
464 for (
int i=0;i<npointsPhi;i++){
465 phiVector[i]=phiArray[i];
466 phiValVector[i]=phiValArray[i];
469 ROOT::Math::Interpolator interpolatorTheta(thetaVector.size(), ROOT::Math::Interpolation::kAKIMA );
470 interpolatorTheta.SetData(thetaVector,thetaValVector);
471 ROOT::Math::Interpolator interpolatorPhi(phiVector.size(), ROOT::Math::Interpolation::kAKIMA );
472 interpolatorPhi.SetData(phiVector,phiValVector);
474 int upsampleFactor=100;
476 double interpThetaArray[npointsTheta*upsampleFactor], interpThetaValArray[npointsTheta*upsampleFactor];
477 double interpPhiArray[npointsPhi*upsampleFactor], interpPhiValArray[npointsPhi*upsampleFactor];
479 for (
double interp_theta=thetaArray[0];interp_theta<thetaArray[npointsTheta-1];
480 interp_theta+=FINE_BIN_SIZE/double(upsampleFactor)){
481 interpThetaArray[interpCtr]=interp_theta;
482 interpThetaValArray[interpCtr]=interpolatorTheta.Eval(interp_theta);
487 for (
double interp_phi=phiArray[0];interp_phi<phiArray[npointsPhi-1];interp_phi+=FINE_BIN_SIZE/double(upsampleFactor)){
488 interpPhiArray[interpCtr]=interp_phi;
489 interpPhiValArray[interpCtr]=interpolatorPhi.Eval(interp_phi);
495 TGraph *gInterpTheta=
new TGraph((npointsTheta-1)*upsampleFactor,interpThetaArray,interpThetaValArray);
496 TGraph *gInterpPhi=
new TGraph((npointsPhi-1)*upsampleFactor,interpPhiArray,interpPhiValArray);
517 Double_t peakValTheta;
519 gInterpTheta->GetPoint(peakBinTheta,peakTheta,peakValTheta);
523 gInterpPhi->GetPoint(peakBinPhi,peakPhi,peakValPhi);
529 if (peakValTheta<peakValPhi) peakVal=peakValTheta;
530 else peakVal=peakValPhi;
533 double halfPeakThetaLeft=0;
534 double halfPeakThetaRight=0;
536 for (
int i=0;i<(npointsTheta-1)*upsampleFactor;i++){
537 if (peakBinTheta-i>0){
538 if (interpThetaValArray[peakBinTheta-i]<peakValTheta/2.
539 && interpThetaValArray[peakBinTheta-(i-1)]>peakValTheta/2.){
540 halfPeakThetaLeft=(interpThetaArray[peakBinTheta-i]+interpThetaArray[peakBinTheta-(i-1)])/2.;
543 if (halfPeakThetaLeft!=0)
break;
547 for (
int i=0;i<(npointsTheta-1)*upsampleFactor;i++){
548 if (peakBinTheta+i<(npointsTheta-1)*upsampleFactor){
549 if (interpThetaValArray[peakBinTheta+i]<peakValTheta/2.
550 && interpThetaValArray[peakBinTheta+(i-1)]>peakValTheta/2.){
551 halfPeakThetaRight=(interpThetaArray[peakBinTheta+i]+interpThetaArray[peakBinTheta+(i-1)])/2.;
554 if (halfPeakThetaRight!=0)
break;
558 double halfPeakPhiLeft=0;
559 double halfPeakPhiRight=0;
560 for (
int i=0;i<(npointsPhi-1)*upsampleFactor;i++){
562 if (interpPhiValArray[peakBinPhi-i]<peakValPhi/2. && interpPhiValArray[peakBinPhi-(i-1)]>peakValPhi/2.){
563 halfPeakPhiLeft=(interpPhiArray[peakBinPhi-i]+interpPhiArray[peakBinPhi-(i-1)])/2.;
566 if (halfPeakPhiLeft!=0)
break;
570 for (
int i=0;i<(npointsPhi-1)*upsampleFactor;i++){
571 if (peakBinPhi+i<(npointsPhi-1)*upsampleFactor){
572 if (interpPhiValArray[peakBinPhi+i]<peakValPhi/2. && interpPhiValArray[peakBinPhi+(i-1)]>peakValPhi/2.){
573 halfPeakPhiRight=(interpPhiArray[peakBinPhi+i]+interpPhiArray[peakBinPhi+(i-1)])/2.;
576 if (halfPeakPhiRight!=0)
break;
580 Double_t FWHMTheta, FWHMPhi;
581 if (halfPeakThetaRight==0 || halfPeakThetaLeft==0) FWHMTheta=-1;
582 else FWHMTheta=halfPeakThetaRight-halfPeakThetaLeft;
583 if (halfPeakPhiRight==0 || halfPeakPhiLeft==0) FWHMPhi=-1;
584 else FWHMPhi=halfPeakPhiRight-halfPeakPhiLeft;
588 const double fwhm_conversion = 2 * sqrt(2 * log(2));
592 peak->sigma_x = FWHMPhi / fwhm_conversion;
593 peak->sigma_y = FWHMTheta / fwhm_conversion;
602 const int GAUS_A = 0;
603 const int GAUS_X0 = 1;
604 const int GAUS_Y0 = 2;
605 const int GAUS_SIGMA_X = 3;
606 const int GAUS_SIGMA_Y = 4;
607 const int GAUS_COVAR = 5;
608 const int GAUS_PEDESTAL = 6;
609 const int GAUS_NPAR = 7;
611 static double gaus2d(
double *xx,
double *ps)
614 double A = ps[GAUS_A];
615 double sx = ps[GAUS_SIGMA_X];
616 double sy = ps[GAUS_SIGMA_Y];
617 double x0 = ps[GAUS_X0];
618 double y0 = ps[GAUS_Y0];
619 double p = ps[GAUS_COVAR];
620 double z0 = ps[GAUS_PEDESTAL];
625 return z0 + A / (2 * M_PI * sx * sy * sqrt(1-p*p))
626 * exp( - (x-x0)*(x-x0) / (2 * sx * sx * (1-p*p))
627 - (y-y0)*(y-y0) / (2 * sy * sy * (1-p*p))
628 + p * (x-x0) * (y-y0) / ( (1-p*p) * sx * sy)
636 TF2 gaus2dfn(
"fitter", gaus2d, GAUS_NPAR,
637 zoomed->GetXaxis()->GetXmin(), zoomed->GetXaxis()->GetXmax(),
638 zoomed->GetYaxis()->GetXmin(), zoomed->GetYaxis()->GetXmax() );
640 int xmax, ymax, ignored;
641 int max_bin = zoomed->GetMaximumBin(xmax,ymax,ignored);
642 gaus2dfn.SetParameter(GAUS_A, zoomed->GetArray()[max_bin]);
643 gaus2dfn.SetParameter(GAUS_SIGMA_X, zoomed->GetRMS(1));
644 gaus2dfn.SetParameter(GAUS_SIGMA_Y, zoomed->GetRMS(2));
645 gaus2dfn.SetParameter(GAUS_X0, zoomed->GetXaxis()->GetBinCenter(xmax));
646 gaus2dfn.SetParameter(GAUS_Y0, zoomed->GetYaxis()->GetBinCenter(ymax));
647 gaus2dfn.SetParameter(GAUS_COVAR, 0);
648 gaus2dfn.SetParameter(GAUS_PEDESTAL, 0);
651 copy.Fit(&gaus2dfn,
"NQ");
653 peak->sigma_x = gaus2dfn.GetParameter(GAUS_SIGMA_X);
654 peak->sigma_y = gaus2dfn.GetParameter(GAUS_SIGMA_Y);
655 peak->covar = gaus2dfn.GetParameter(GAUS_COVAR) * peak->sigma_x * peak->sigma_y;
656 peak->x = gaus2dfn.GetParameter(GAUS_X0);
657 peak->y = gaus2dfn.GetParameter(GAUS_Y0);
658 peak->val = gaus2dfn.GetParameter(GAUS_A) / (2 * M_PI * peak->sigma_x * peak->sigma_y * sqrt(1-peak->covar *peak->covar));
659 peak->chisq = gaus2dfn.GetChisquare()/ gaus2dfn.GetNDF();
663 const double M1_elems[] = { 1,0,0,0,
668 const static TMatrixD M1(4,4, M1_elems);
669 const double M2_elems[] = { 1,0,-3,2,
674 const static TMatrixD M2(4,4, M2_elems);
686 virtual double DoEval(
const double * x)
const;
687 virtual double DoDerivative(
const double * x,
unsigned int coord)
const;
688 unsigned NDim()
const {
return 2; }
697 NegativeBicubicFunction::NegativeBicubicFunction (
const double m[4][4],
double xw,
double yw)
705 double f_00 = m[1][1];
706 double f_11 = m[2][2];
707 double f_01 = m[1][2];
708 double f_10 = m[2][1];
711 double fx_00 = (m[2][1] - m[0][1]) / (2*xw);
712 double fx_10 = (m[3][1] - m[1][1]) / (2*xw);
713 double fx_01 = (m[2][2] - m[0][2]) / (2*xw);
714 double fx_11 = (m[3][2] - m[1][2]) / (2*xw);
716 double fy_00 = (m[1][2] - m[1][0]) / (2*yw);
717 double fy_10 = (m[2][2] - m[2][0]) / (2*yw);
718 double fy_01 = (m[1][3] - m[1][1]) / (2*yw);
719 double fy_11 = (m[2][3] - m[2][1]) / (2*yw);
721 double fxy_00 = ( (m[2][2] - m[0][2]) -(m[2][0] - m[0][0])) / (4*xw*yw) ;
722 double fxy_01 = ( (m[2][3] - m[0][3]) -(m[2][1] - m[0][1])) / (4*xw*yw) ;
723 double fxy_10 = ( (m[3][2] - m[1][2]) -(m[3][0] - m[1][0])) / (4*xw*yw) ;
724 double fxy_11 = ( (m[3][3] - m[1][3]) -(m[3][1] - m[1][1])) / (4*xw*yw) ;
726 Mf(0,0) = f_00; Mf(0,1) = f_01; Mf(0,2) = fy_00; Mf(0,3) = fy_01;
727 Mf(1,0) = f_10; Mf(1,1) = f_11; Mf(1,2) = fy_10; Mf(1,3) = fy_11;
728 Mf(2,0) = fx_00; Mf(2,1) = fx_01; Mf(2,2) = fxy_00; Mf(2,3) = fxy_01;
729 Mf(3,0) = fx_10; Mf(3,1) = fx_11; Mf(3,2) = fxy_10; Mf(3,3) = fxy_11;
733 TMatrix Ma = M1 * Mf * M2;
734 for (
int i = 0; i < 4; i++)
736 for (
int j = 0; j < 4; j++)
744 double NegativeBicubicFunction::DoEval(
const double * p)
const 750 for (
int i = 1; i < 3; i++)
752 x[i] = p[0] * x[i-1];
753 y[i] = p[1] * y[i-1];
759 for (
int i = 0; i < 3; i++)
761 for (
int j = 0; j < 3; j++)
763 val += a[i][j] * x[i] * y[j];
770 double NegativeBicubicFunction::DoDerivative(
const double * p,
unsigned int coord)
const 776 for (
int i = 1; i < 3; i++)
778 x[i] = p[0] * x[i-1];
779 y[i] = p[1] * y[i-1];
788 for (
int i = 1; i < 3; i++)
790 for (
int j = 0; j < 3; j++)
792 val += a[i][j] * x[i-1] * y[j] * i;
798 for (
int i = 0; i < 3; i++)
800 for (
int j = 1; j < 3; j++)
802 val += a[i][j] * x[i] * y[j-1]*j;
811 static __thread ROOT::Minuit2::Minuit2Minimizer *min = 0;
817 double xwidth = zoomed->GetXaxis()->GetBinWidth(1);
818 double ywidth = zoomed->GetYaxis()->GetBinWidth(1);
821 if (!min) min =
new ROOT::Minuit2::Minuit2Minimizer;
823 double stupid_max = zoomed->GetMaximum();
827 for (
int i = 2; i < zoomed->GetNbinsX(); i++)
829 for (
int j = 2; j < zoomed->GetNbinsY(); j++)
833 for (
int ii = -1; ii < 3; ii++)
835 for (
int jj = -1; jj < 3; jj++)
837 double val = zoomed->GetBinContent(i+ii, j+ii);
838 if (val > stupid_max * min_to_consider) ok =
true;
840 m[ii+1][jj+1] = zoomed->GetBinContent(i+ii,j+jj);
850 min->SetLimitedVariable(0,
"x", 0.5, 0.1, 0,1);
851 min->SetLimitedVariable(1,
"y", 0.5, 0.1, 0,1);
855 int old_level = gErrorIgnoreLevel;
857 gErrorIgnoreLevel = old_level;
860 if (-min->MinValue() > peak->val)
862 peak->val = -min->MinValue();
863 peak->x = min->X()[0];
864 peak->y = min->X()[1];
865 peak->sigma_x = sqrt(min->CovMatrix(0,0));
866 peak->sigma_y = sqrt(min->CovMatrix(1,1));
867 peak->covar = min->CovMatrix(0,1);
878 int max_bin = hist->GetMaximumBin();
880 hist->GetBinXYZ(max_bin,bx,by,bz);
882 peak->val = hist->GetBinContent(bx,by);
883 peak->x = hist->GetXaxis()->GetBinCenter(bx);
884 peak->y = hist->GetYaxis()->GetBinCenter(by);
893 for (
int i = 1; i <= hist->GetNbinsX(); i++)
895 for (
int j = 1; j <= hist->GetNbinsY(); j++)
897 double val = hist->GetBinContent(i,j);
898 double x = hist->GetXaxis()->GetBinCenter(i);
899 double y = hist->GetYaxis()->GetBinCenter(j);
902 var_x += val * (x-peak->x) * (x-peak->x);
903 var_y += val * (y-peak->y) * (y-peak->y);
904 covar += val * (y-peak->y) * (x-peak->x);
909 peak->sigma_x = sqrt( var_x / (total-1));
910 peak->sigma_y = sqrt( var_y / (total-1));
911 peak->covar = covar / (total - 1);
Double_t sigma_phi
error on theta
int findIsolatedMaxima(const TH2D *hist, double distance, int Nmaxima, RoughMaximum *maxima, double minPhi=0., double maxPhi=0., double minTheta=0., double maxTheta=0., bool exclude=false, bool use_bin_center=true)
void doPeakFindingGaussian(const TH2D *hist, FineMaximum *peak)
Double_t sigma_theta
on continent, or -9999 if doesn't intersect
void copyToPointingHypothesis(AnitaEventSummary::PointingHypothesis *p)
void doPeakFindingHistogram(const TH2D *hist, FineMaximum *peak)
void doPeakFindingQuadratic9(const TH2D *hist, FineMaximum *peak)
Double_t chisq
correlation coefficient between theta and phi
void doInterpolationPeakFindingBicubic(const TH2D *hist, FineMaximum *peak, double min_to_consider=0.75)
Double_t theta
peak phi, degrees
void doInterpolationPeakFindingAbby(const TH2D *hist, FineMaximum *peak)
Double_t value
peak theta, degrees