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"
38 using namespace ROOT::Minuit2;
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())));
670 if (
std::abs(d_dprime) < DeltadCut && option == 2) {
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();
760 bool testing = fmin.IsValid();
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),
reco::BeamSpot Fit_d_likelihood(double *inipar)
math::Error< dimension >::type CovarianceMatrix
double z0() const
z coordinate
static std::vector< std::string > checklist log
constexpr bool isNotFinite(T x)
reco::BeamSpot Fit_z_likelihood(double *inipar)
Sin< T >::type sin(const T &t)
math::XYZPoint Point
point in the space
Exp< T >::type exp(const T &t)
double scanPDF(double *init_pars, int &tracksFailed, int option)
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
reco::BeamSpot Fit_dres_z_likelihood(double *inipar)
void setType(BeamType type)
set beam type
double dydz() const
dydz slope
Cos< T >::type cos(const T &t)
Abs< T >::type abs(const T &t)
double BeamWidthX() const
beam width X
double dxdz() const
dxdz slope
Log< level::Info, false > LogInfo
reco::BeamSpot Fit_ited0phi()
double sigmaZ() const
sigma z
reco::BeamSpot Fit_z_chi2(double *inipar)
void Setd0Cut_d0phi(double d0cut)
double covariance(int i, int j) const
(i,j)-th element of error matrix
double y0() const
y coordinate
void SetChi2Cut_d0phi(double chi2cut)
Log< level::Warning, false > LogWarning
reco::BeamSpot Fit_d0phi()
reco::BeamSpot Fit_d_z_likelihood(double *inipar, double *error_par)
Power< A, B >::type pow(const A &a, const B &b)
double x0() const
x coordinate