13 #include "Minuit2/VariableMetricMinimizer.h"
14 #include "Minuit2/FunctionMinimum.h"
15 #include "Minuit2/MnPrint.h"
16 #include "Minuit2/MnMigrad.h"
17 #include "Minuit2/MnUserParameterState.h"
32 #include "TMatrixDSym.h"
33 #include "TDecompBK.h"
36 #include "TMinuitMinimizer.h"
46 TMinuitMinimizer::UseStaticMinuit(
false);
53 TMinuitMinimizer::UseStaticMinuit(
false);
55 ffit_type =
"default";
56 ffit_variable =
"default";
63 fpar_name[1] =
"SigmaZ0 ";
66 fpar_name[4] =
"dxdz ";
67 fpar_name[5] =
"dydz ";
68 fpar_name[6] =
"SigmaBeam ";
76 theFitter =
new VariableMetricMinimizer();
81 fapplychi2cut =
false;
91 h1z =
new TH1F(
"h1z",
"z distribution", 200, -fMaxZ, fMaxZ);
107 if (ffit_variable ==
"z") {
108 if (ffit_type ==
"chi2") {
109 return Fit_z_chi2(inipar);
111 }
else if (ffit_type ==
"likelihood") {
112 return Fit_z_likelihood(inipar);
114 }
else if (ffit_type ==
"combined") {
116 double tmp_par[2] = {tmp_beamspot.
z0(), tmp_beamspot.
sigmaZ()};
117 return Fit_z_likelihood(tmp_par);
121 <<
"Error in BeamSpotProducer/BSFitter: "
122 <<
"Illegal fit type, options are chi2,likelihood or combined(ie. first chi2 then likelihood)";
124 }
else if (ffit_variable ==
"d") {
125 if (ffit_type ==
"d0phi") {
129 }
else if (ffit_type ==
"likelihood") {
130 return Fit_d_likelihood(inipar);
132 }
else if (ffit_type ==
"combined") {
135 double tmp_par[4] = {tmp_beamspot.
x0(), tmp_beamspot.
y0(), tmp_beamspot.
dxdz(), tmp_beamspot.
dydz()};
136 return Fit_d_likelihood(tmp_par);
139 throw cms::Exception(
"LogicError") <<
"Error in BeamSpotProducer/BSFitter: "
140 <<
"Illegal fit type, options are d0phi, likelihood or combined";
142 }
else if (ffit_variable ==
"d*z" || ffit_variable ==
"default") {
143 if (ffit_type ==
"likelihood" || ffit_type ==
"default") {
157 this->Setd0Cut_d0phi(4.0);
186 if (ffit_type ==
"likelihood") {
187 double tmp_par[7] = {
188 tmp_d0phi.
x0(), tmp_d0phi.
y0(), tmp_d0phi.
z0(), tmp_d0phi.
sigmaZ(), tmp_d0phi.
dxdz(), tmp_d0phi.
dydz(), 0.0};
190 double tmp_error_par[7];
191 for (
int s = 0;
s < 6;
s++) {
194 tmp_error_par[6] = 0.0;
196 reco::BeamSpot tmp_lh = Fit_d_z_likelihood(tmp_par, tmp_error_par);
200 <<
"BSFitter: Result is non physical. Log-Likelihood fit to extract beam width did not converge."
208 edm::LogInfo(
"BSFitter") <<
"default track-based fit does not extract beam width." << std::endl;
212 }
else if (ffit_type ==
"resolution") {
217 double tmp_par[7] = {
218 tmp_d0phi.
x0(), tmp_d0phi.
y0(), tmp_z.
z0(), tmp_z.
sigmaZ(), tmp_d0phi.
dxdz(), tmp_d0phi.
dydz(), 0.0};
219 double tmp_error_par[7];
220 for (
int s = 0;
s < 6;
s++) {
221 tmp_error_par[
s] =
pow(tmp_par[
s], 0.5);
223 tmp_error_par[6] = 0.0;
225 reco::BeamSpot tmp_beam = Fit_d_z_likelihood(tmp_par, tmp_error_par);
227 double tmp_par2[7] = {tmp_beam.
x0(),
238 edm::LogWarning(
"BSFitter") <<
"Result is non physical. Log-Likelihood fit did not converge." << std::endl;
245 throw cms::Exception(
"LogicError") <<
"Error in BeamSpotProducer/BSFitter: "
246 <<
"Illegal fit type, options are likelihood or resolution";
249 throw cms::Exception(
"LogicError") <<
"Error in BeamSpotProducer/BSFitter: "
250 <<
"Illegal variable type, options are \"z\", \"d\", or \"d*z\"";
260 std::vector<double> par(2, 0);
261 std::vector<double>
err(2, 0);
265 err.push_back(0.0001);
266 err.push_back(0.0001);
270 thePDF->SetPDFs(
"PDFGauss_z");
271 thePDF->SetData(fBSvector);
275 MnUserParameters upar;
276 upar.Add(
"X0", 0., 0.);
277 upar.Add(
"Y0", 0., 0.);
278 upar.Add(
"Z0", inipar[0], 0.001);
279 upar.Add(
"sigmaZ", inipar[1], 0.001);
281 MnMigrad migrad(*thePDF, upar);
283 FunctionMinimum fmin = migrad();
284 ff_minimum = fmin.Fval();
305 for (
int j = 2;
j < 4; ++
j) {
306 for (
int k =
j;
k < 4; ++
k) {
312 fmin.Parameters().Vec()(3),
329 h1z =
new TH1F(
"h1z",
"z distribution", 200, -fMaxZ, fMaxZ);
331 std::vector<BSTrkParameters>::const_iterator iparam = fBSvector.begin();
335 for (iparam = fBSvector.begin(); iparam != fBSvector.end(); ++iparam) {
336 h1z->Fill(iparam->z0());
342 TF1 fgaus(
"fgaus",
"gaus", 0., 1., TF1::EAddToList::kNo);
343 h1z->Fit(&fgaus,
"QLMN0 SERIAL");
347 double fpar[2] = {fgaus.GetParameter(1), fgaus.GetParameter(2)};
351 matrix(2, 2) = fgaus.GetParError(1) * fgaus.GetParError(1);
352 matrix(3, 3) = fgaus.GetParError(2) * fgaus.GetParError(2);
362 edm::LogInfo(
"BSFitter") <<
"number of total input tracks: " << fBSvector.size() << std::endl;
366 if ((
int)fBSvector.size() <= fminNtrks) {
367 edm::LogWarning(
"BSFitter") <<
"need at least " << fminNtrks <<
" tracks to run beamline fitter." << std::endl;
373 theanswer = Fit_d0phi();
380 while (goodfit && ftmprow > fconvergence * fBSvector.size() && ftmprow > fminNtrks) {
381 theanswer = Fit_d0phi();
384 if (goodfit && ftmprow > fconvergence * fBSvector.size() && ftmprow > fminNtrks) {
385 preanswer = theanswer;
392 theanswer = preanswer;
396 edm::LogInfo(
"BSFitter") <<
"Total number of successful iterations = " << (goodfit ? (fnthite + 1) : fnthite)
413 edm::LogInfo(
"BSFitter") <<
" number of tracks used: " << ftmprow << std::endl;
422 TMatrixD x_result(4, 1);
423 TMatrixDSym V_result(4);
436 std::vector<BSTrkParameters>::iterator iparam = fBSvector.begin();
443 for (iparam = fBSvector.begin(); iparam != fBSvector.end(); ++iparam) {
451 g(0, 0) =
sin(iparam->phi0());
452 g(1, 0) = -
cos(iparam->phi0());
453 g(2, 0) = iparam->z0() *
g(0, 0);
454 g(3, 0) = iparam->z0() *
g(1, 0);
457 double sigmabeam2 = 0.006 * 0.006;
458 if (finputBeamWidth > 0)
459 sigmabeam2 = finputBeamWidth * finputBeamWidth;
466 double sigma2 = sigmabeam2 + (iparam->sigd0()) * (iparam->sigd0());
468 TMatrixD ftmptrans(1, 4);
469 ftmptrans = ftmptrans.Transpose(ftmp);
470 TMatrixD dcor = ftmptrans *
g;
471 double chi2tmp = (iparam->d0() - dcor(0, 0)) * (iparam->d0() - dcor(0, 0)) / sigma2;
473 iparam->z0(), iparam->sigz0(), iparam->d0(), iparam->sigd0(), iparam->phi0(), iparam->pt(), dcor(0, 0), chi2tmp);
476 if (fapplyd0cut && fnthite > 0) {
477 if (
std::abs(iparam->d0() - dcor(0, 0)) > fd0cut)
480 if (fapplychi2cut && fnthite > 0) {
481 if (chi2tmp > fchi2cut)
487 for (
int j = 0;
j < 4; ++
j) {
488 for (
int k =
j;
k < 4; ++
k) {
493 Vint += (
temp * (1 / sigma2));
494 b += (iparam->d0() / sigma2 *
g);
497 h1z->Fill(iparam->z0());
500 Double_t determinant;
503 if (!
bk.Decompose()) {
505 edm::LogWarning(
"BSFitter") <<
"Decomposition failed, matrix singular ?" << std::endl
506 <<
"condition number = " <<
bk.Condition() << std::endl;
508 V_result = Vint.InvertFast(&determinant);
509 x_result = V_result *
b;
524 TF1 fgaus(
"fgaus",
"gaus", 0., 1., TF1::EAddToList::kNo);
528 h1z->Fit(&fgaus,
"QLN0 SERIAL",
"", h1z->GetMean() - 2. * h1z->GetRMS(), h1z->GetMean() + 2. * h1z->GetRMS());
539 double fpar[2] = {fgaus.GetParameter(1), fgaus.GetParameter(2)};
543 for (
int j = 0;
j < 2; ++
j) {
544 for (
int k =
j;
k < 2; ++
k) {
549 for (
int j = 4;
j < 6; ++
j) {
550 for (
int k =
j;
k < 6; ++
k) {
556 matrix(2, 2) = fgaus.GetParError(1) * fgaus.GetParError(1);
557 matrix(3, 3) = fgaus.GetParError(2) * fgaus.GetParError(2);
565 double x0tmp = x_result(0, 0);
566 double y0tmp = x_result(1, 0);
568 x0tmp += x_result(2, 0) * fpar[0];
569 y0tmp += x_result(3, 0) * fpar[0];
572 reco::BeamSpot::Point(x0tmp, y0tmp, fpar[0]), fpar[1], x_result(2, 0), x_result(3, 0), 0.,
matrix, fbeamtype);
585 fapplychi2cut =
true;
593 thePDF->SetPDFs(
"PDFGauss_d");
594 thePDF->SetData(fBSvector);
596 MnUserParameters upar;
597 upar.Add(
"X0", inipar[0], 0.001);
598 upar.Add(
"Y0", inipar[1], 0.001);
599 upar.Add(
"Z0", 0., 0.001);
600 upar.Add(
"sigmaZ", 0., 0.001);
601 upar.Add(
"dxdz", inipar[2], 0.001);
602 upar.Add(
"dydz", inipar[3], 0.001);
604 MnMigrad migrad(*thePDF, upar);
606 FunctionMinimum fmin = migrad();
607 ff_minimum = fmin.Fval();
610 for (
int j = 0;
j < 6; ++
j) {
611 for (
int k =
j;
k < 6; ++
k) {
618 fmin.Parameters().Vec()(4),
619 fmin.Parameters().Vec()(5),
627 init_pars[6] = 0.0005;
630 double fsqrt2pi = 0.0;
632 double d_dprime = 0.0;
633 double d_result = 0.0;
635 double z_result = 0.0;
636 double function = 0.0;
637 double tot_pdf = 0.0;
638 double last_minvalue = 1.0e+10;
639 double init_bw = -99.99;
643 double DeltadCut = 0.1000;
644 if (init_pars[6] < 0.0200) {
647 if (init_pars[6] < 0.0100) {
651 std::vector<BSTrkParameters>::const_iterator iparam = fBSvector.begin();
658 for (
int p = 0;
p < iters;
p++) {
660 init_pars[6] += 0.0002;
663 for (iparam = fBSvector.begin(); iparam != fBSvector.end(); ++iparam) {
665 d_sig =
sqrt(init_pars[6] * init_pars[6] + (iparam->sigd0()) * (iparam->sigd0()));
666 d_dprime = iparam->d0() - (((init_pars[0] + iparam->z0() * (init_pars[4])) *
sin(iparam->phi0())) -
667 ((init_pars[1] + iparam->z0() * (init_pars[5])) *
cos(iparam->phi0())));
671 fBSvectorBW.push_back(*iparam);
674 d_result = (
exp(-(d_dprime * d_dprime) / (2.0 * d_sig * d_sig))) / (d_sig * fsqrt2pi);
675 z_sig =
sqrt(iparam->sigz0() * iparam->sigz0() + init_pars[3] * init_pars[3]);
676 z_result = (
exp(-((iparam->z0() - init_pars[2]) * (iparam->z0() - init_pars[2])) / (2.0 * z_sig * z_sig))) /
678 tot_pdf = z_result * d_result;
684 if (d_result < 1.0
e-05) {
685 tot_pdf = z_result * 1.0e-05;
690 function =
function +
log(tot_pdf);
694 function = -2.0 *
function;
695 if (
function < last_minvalue) {
696 init_bw = init_pars[6];
697 last_minvalue =
function;
703 init_bw = init_bw + (0.20 * init_bw);
708 <<
"scanPDF:====>>>> WARNING***: The initial guess value of Beam width is negative!!!!!!" << std::endl
709 <<
"scanPDF:====>>>> Assigning beam width a starting value of " << init_bw <<
" cm" << std::endl;
719 int tracksFailed = 0;
722 inipar[6] = scanPDF(inipar, tracksFailed, 1);
723 error_par[6] = (inipar[6]) * 0.20;
727 scanPDF(inipar, tracksFailed, 2);
732 std::vector<BSTrkParameters>::const_iterator iparamBW = fBSvectorBW.begin();
733 for (iparamBW = fBSvectorBW.begin(); iparamBW != fBSvectorBW.end(); ++iparamBW) {
734 fBSvector.push_back(*iparamBW);
737 thePDF->SetPDFs(
"PDFGauss_d*PDFGauss_z");
738 thePDF->SetData(fBSvector);
739 MnUserParameters upar;
741 upar.Add(
"X0", inipar[0], error_par[0]);
742 upar.Add(
"Y0", inipar[1], error_par[1]);
743 upar.Add(
"Z0", inipar[2], error_par[2]);
744 upar.Add(
"sigmaZ", inipar[3], error_par[3]);
745 upar.Add(
"dxdz", inipar[4], error_par[4]);
746 upar.Add(
"dydz", inipar[5], error_par[5]);
747 upar.Add(
"BeamWidthX", inipar[6], error_par[6]);
749 MnMigrad migrad(*thePDF, upar);
751 FunctionMinimum fmin = migrad();
756 ff_minimum = fmin.Fval();
758 bool ff_nfcn = fmin.HasReachedCallLimit();
759 bool ff_cov = fmin.HasCovariance();
764 edm::LogWarning(
"BSFitter") <<
"===========>>>>>** WARNING: MINUIT DID NOT CONVERGES PROPERLY !!!!!!" << std::endl;
766 edm::LogWarning(
"BSFitter") <<
"===========>>>>>** WARNING: No. of Calls Exhausted" << std::endl;
768 edm::LogWarning(
"BSFitter") <<
"===========>>>>>** WARNING: Covariance did not found" << std::endl;
771 edm::LogInfo(
"BSFitter") <<
"The Total # Tracks used for beam width fit = " << (fBSvectorBW.size()) << std::endl;
774 double lastIter_pars[7];
776 for (
int ip = 0; ip < 7; ip++) {
777 lastIter_pars[ip] = fmin.Parameters().Vec()(ip);
781 scanPDF(lastIter_pars, tracksFailed, 2);
783 edm::LogWarning(
"BSFitter") <<
"WARNING: # of tracks which have very low pdf value (pdf_d < 1.0e-05) are = "
784 << tracksFailed << std::endl;
791 for (
int j = 0;
j < 7; ++
j) {
792 for (
int k =
j;
k < 7; ++
k) {
798 reco::BeamSpot::Point(fmin.Parameters().Vec()(0), fmin.Parameters().Vec()(1), fmin.Parameters().Vec()(2)),
799 fmin.Parameters().Vec()(3),
800 fmin.Parameters().Vec()(4),
801 fmin.Parameters().Vec()(5),
802 fmin.Parameters().Vec()(6),
810 thePDF->SetPDFs(
"PDFGauss_d_resolution*PDFGauss_z");
811 thePDF->SetData(fBSvector);
813 MnUserParameters upar;
814 upar.Add(
"X0", inipar[0], 0.001);
815 upar.Add(
"Y0", inipar[1], 0.001);
816 upar.Add(
"Z0", inipar[2], 0.001);
817 upar.Add(
"sigmaZ", inipar[3], 0.001);
818 upar.Add(
"dxdz", inipar[4], 0.001);
819 upar.Add(
"dydz", inipar[5], 0.001);
820 upar.Add(
"BeamWidthX", inipar[6], 0.0001);
821 upar.Add(
"c0", 0.0010, 0.0001);
822 upar.Add(
"c1", 0.0090, 0.0001);
825 upar.Fix(
"BeamWidthX");
828 MnMigrad migrad(*thePDF, upar);
830 FunctionMinimum fmin = migrad();
831 ff_minimum = fmin.Fval();
835 for (
int j = 0;
j < 6; ++
j) {
836 for (
int k =
j;
k < 6; ++
k) {
846 fresolution_c0 = fmin.Parameters().Vec()(6);
847 fresolution_c1 = fmin.Parameters().Vec()(7);
848 fres_c0_err =
sqrt(fmin.Error().Matrix()(6, 6));
849 fres_c1_err =
sqrt(fmin.Error().Matrix()(7, 7));
851 for (
int j = 6;
j < 8; ++
j) {
852 for (
int k = 6;
k < 8; ++
k) {
853 fres_matrix(
j - 6,
k - 6) = fmin.Error().Matrix()(
j,
k);
858 reco::BeamSpot::Point(fmin.Parameters().Vec()(0), fmin.Parameters().Vec()(1), fmin.Parameters().Vec()(2)),
859 fmin.Parameters().Vec()(3),
860 fmin.Parameters().Vec()(4),
861 fmin.Parameters().Vec()(5),