CMS 3D CMS Logo

BSFitter.cc
Go to the documentation of this file.
1 
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"
18 //#include "CLHEP/config/CLHEP.h"
19 
20 // C++ standard
21 #include <vector>
22 #include <cmath>
23 
24 // CMS
29 
30 // ROOT
31 #include "TMatrixD.h"
32 #include "TMatrixDSym.h"
33 #include "TDecompBK.h"
34 #include "TH1.h"
35 #include "TF1.h"
36 #include "TMinuitMinimizer.h"
37 
38 using namespace ROOT::Minuit2;
39 
40 //_____________________________________________________________________
42  fbeamtype = reco::BeamSpot::Unknown;
43 
44  //In order to make fitting ROOT histograms thread safe
45  // one must call this undocumented function
46  TMinuitMinimizer::UseStaticMinuit(false);
47 }
48 
49 //_____________________________________________________________________
50 BSFitter::BSFitter(const std::vector<BSTrkParameters> &BSvector) {
51  //In order to make fitting ROOT histograms thread safe
52  // one must call this undocumented function
53  TMinuitMinimizer::UseStaticMinuit(false);
54 
55  ffit_type = "default";
56  ffit_variable = "default";
57 
58  fBSvector = BSvector;
59 
60  fsqrt2pi = sqrt(2. * TMath::Pi());
61 
62  fpar_name[0] = "z0 ";
63  fpar_name[1] = "SigmaZ0 ";
64  fpar_name[2] = "X0 ";
65  fpar_name[3] = "Y0 ";
66  fpar_name[4] = "dxdz ";
67  fpar_name[5] = "dydz ";
68  fpar_name[6] = "SigmaBeam ";
69 
70  //if (theGausszFcn == 0 ) {
71  thePDF = new BSpdfsFcn();
72 
73  //}
74  //if (theFitter == 0 ) {
75 
76  theFitter = new VariableMetricMinimizer();
77 
78  //}
79 
80  fapplyd0cut = false;
81  fapplychi2cut = false;
82  ftmprow = 0;
83  ftmp.ResizeTo(4, 1);
84  ftmp.Zero();
85  fnthite = 0;
86  fMaxZ = 50.; //cm
87  fconvergence = 0.5; // stop fit when 50% of the input collection has been removed.
88  fminNtrks = 100;
89  finputBeamWidth = -1; // no input
90 
91  h1z = new TH1F("h1z", "z distribution", 200, -fMaxZ, fMaxZ);
92 }
93 
94 //______________________________________________________________________
96  //delete fBSvector;
97  delete thePDF;
98  delete theFitter;
99 }
100 
101 //______________________________________________________________________
102 reco::BeamSpot BSFitter::Fit() { return this->Fit(nullptr); }
103 
104 //______________________________________________________________________
105 reco::BeamSpot BSFitter::Fit(double *inipar = nullptr) {
106  fbeamtype = reco::BeamSpot::Unknown;
107  if (ffit_variable == "z") {
108  if (ffit_type == "chi2") {
109  return Fit_z_chi2(inipar);
110 
111  } else if (ffit_type == "likelihood") {
112  return Fit_z_likelihood(inipar);
113 
114  } else if (ffit_type == "combined") {
115  reco::BeamSpot tmp_beamspot = Fit_z_chi2(inipar);
116  double tmp_par[2] = {tmp_beamspot.z0(), tmp_beamspot.sigmaZ()};
117  return Fit_z_likelihood(tmp_par);
118 
119  } else {
120  throw cms::Exception("LogicError")
121  << "Error in BeamSpotProducer/BSFitter: "
122  << "Illegal fit type, options are chi2,likelihood or combined(ie. first chi2 then likelihood)";
123  }
124  } else if (ffit_variable == "d") {
125  if (ffit_type == "d0phi") {
126  this->d0phi_Init();
127  return Fit_d0phi();
128 
129  } else if (ffit_type == "likelihood") {
130  return Fit_d_likelihood(inipar);
131 
132  } else if (ffit_type == "combined") {
133  this->d0phi_Init();
134  reco::BeamSpot tmp_beamspot = Fit_d0phi();
135  double tmp_par[4] = {tmp_beamspot.x0(), tmp_beamspot.y0(), tmp_beamspot.dxdz(), tmp_beamspot.dydz()};
136  return Fit_d_likelihood(tmp_par);
137 
138  } else {
139  throw cms::Exception("LogicError") << "Error in BeamSpotProducer/BSFitter: "
140  << "Illegal fit type, options are d0phi, likelihood or combined";
141  }
142  } else if (ffit_variable == "d*z" || ffit_variable == "default") {
143  if (ffit_type == "likelihood" || ffit_type == "default") {
145  // we are now fitting Z inside d0phi fitter
146  // first fit z distribution using a chi2 fit
147  //reco::BeamSpot tmp_z = Fit_z_chi2(inipar);
148  //for (int j = 2 ; j < 4 ; ++j) {
149  //for(int k = j ; k < 4 ; ++k) {
150  // matrix(j,k) = tmp_z.covariance()(j,k);
151  //}
152  //}
153 
154  // use d0-phi algorithm to extract transverse position
155  this->d0phi_Init();
156  //reco::BeamSpot tmp_d0phi= Fit_d0phi(); // change to iterative procedure:
157  this->Setd0Cut_d0phi(4.0);
158  reco::BeamSpot tmp_d0phi = Fit_ited0phi();
159 
160  //for (int j = 0 ; j < 2 ; ++j) {
161  // for(int k = j ; k < 2 ; ++k) {
162  // matrix(j,k) = tmp_d0phi.covariance()(j,k);
163  //}
164  //}
165  // slopes
166  //for (int j = 4 ; j < 6 ; ++j) {
167  // for(int k = j ; k < 6 ; ++k) {
168  // matrix(j,k) = tmp_d0phi.covariance()(j,k);
169  // }
170  //}
171 
172  // put everything into one object
173  reco::BeamSpot spot(reco::BeamSpot::Point(tmp_d0phi.x0(), tmp_d0phi.y0(), tmp_d0phi.z0()),
174  tmp_d0phi.sigmaZ(),
175  tmp_d0phi.dxdz(),
176  tmp_d0phi.dydz(),
177  0.,
178  tmp_d0phi.covariance(),
179  fbeamtype);
180 
181  //reco::BeamSpot tmp_z = Fit_z_chi2(inipar);
182 
183  //reco::BeamSpot tmp_d0phi = Fit_d0phi();
184 
185  // log-likelihood fit
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};
189 
190  double tmp_error_par[7];
191  for (int s = 0; s < 6; s++) {
192  tmp_error_par[s] = pow(tmp_d0phi.covariance()(s, s), 0.5);
193  }
194  tmp_error_par[6] = 0.0;
195 
196  reco::BeamSpot tmp_lh = Fit_d_z_likelihood(tmp_par, tmp_error_par);
197 
198  if (edm::isNotFinite(ff_minimum)) {
199  edm::LogWarning("BSFitter")
200  << "BSFitter: Result is non physical. Log-Likelihood fit to extract beam width did not converge."
201  << std::endl;
203  return tmp_lh;
204  }
205  return tmp_lh;
206 
207  } else {
208  edm::LogInfo("BSFitter") << "default track-based fit does not extract beam width." << std::endl;
209  return spot;
210  }
211 
212  } else if (ffit_type == "resolution") {
213  reco::BeamSpot tmp_z = Fit_z_chi2(inipar);
214  this->d0phi_Init();
215  reco::BeamSpot tmp_d0phi = Fit_d0phi();
216 
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);
222  }
223  tmp_error_par[6] = 0.0;
224 
225  reco::BeamSpot tmp_beam = Fit_d_z_likelihood(tmp_par, tmp_error_par);
226 
227  double tmp_par2[7] = {tmp_beam.x0(),
228  tmp_beam.y0(),
229  tmp_beam.z0(),
230  tmp_beam.sigmaZ(),
231  tmp_beam.dxdz(),
232  tmp_beam.dydz(),
233  tmp_beam.BeamWidthX()};
234 
235  reco::BeamSpot tmp_lh = Fit_dres_z_likelihood(tmp_par2);
236 
237  if (edm::isNotFinite(ff_minimum)) {
238  edm::LogWarning("BSFitter") << "Result is non physical. Log-Likelihood fit did not converge." << std::endl;
240  return tmp_lh;
241  }
242  return tmp_lh;
243 
244  } else {
245  throw cms::Exception("LogicError") << "Error in BeamSpotProducer/BSFitter: "
246  << "Illegal fit type, options are likelihood or resolution";
247  }
248  } else {
249  throw cms::Exception("LogicError") << "Error in BeamSpotProducer/BSFitter: "
250  << "Illegal variable type, options are \"z\", \"d\", or \"d*z\"";
251  }
252 }
253 
254 //______________________________________________________________________
256  //std::cout << "Fit_z(double *) called" << std::endl;
257  //std::cout << "inipar[0]= " << inipar[0] << std::endl;
258  //std::cout << "inipar[1]= " << inipar[1] << std::endl;
259 
260  std::vector<double> par(2, 0);
261  std::vector<double> err(2, 0);
262 
263  par.push_back(0.0);
264  par.push_back(7.0);
265  err.push_back(0.0001);
266  err.push_back(0.0001);
267  //par[0] = 0.0; err[0] = 0.0;
268  //par[1] = 7.0; err[1] = 0.0;
269 
270  thePDF->SetPDFs("PDFGauss_z");
271  thePDF->SetData(fBSvector);
272  //std::cout << "data loaded"<< std::endl;
273 
274  //FunctionMinimum fmin = theFitter->Minimize(*theGausszFcn, par, err, 1, 500, 0.1);
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);
280 
281  MnMigrad migrad(*thePDF, upar);
282 
283  FunctionMinimum fmin = migrad();
284  ff_minimum = fmin.Fval();
285  //std::cout << " eval= " << ff_minimum
286  // << "/n params[0]= " << fmin.Parameters().Vec()(0) << std::endl;
287 
288  /*
289  TMinuit *gmMinuit = new TMinuit(2);
290 
291  //gmMinuit->SetFCN(z_fcn);
292  gmMinuit->SetFCN(myFitz_fcn);
293 
294 
295  int ierflg = 0;
296  double step[2] = {0.001,0.001};
297 
298  for (int i = 0; i<2; i++) {
299  gmMinuit->mnparm(i,fpar_name[i].c_str(),inipar[i],step[i],0,0,ierflg);
300  }
301  gmMinuit->Migrad();
302  */
304 
305  for (int j = 2; j < 4; ++j) {
306  for (int k = j; k < 4; ++k) {
307  matrix(j, k) = fmin.Error().Matrix()(j, k);
308  }
309  }
310 
311  return reco::BeamSpot(reco::BeamSpot::Point(0., 0., fmin.Parameters().Vec()(2)),
312  fmin.Parameters().Vec()(3),
313  0.,
314  0.,
315  0.,
316  matrix,
317  fbeamtype);
318 }
319 
320 //______________________________________________________________________
322  // N.B. this fit is not performed anymore but now
323  // Z is fitted in the same track set used in the d0-phi fit after
324  // each iteration
325 
326  //std::cout << "Fit_z_chi2() called" << std::endl;
327  // FIXME: include whole tracker z length for the time being
328  // ==> add protection and z0 cut
329  h1z = new TH1F("h1z", "z distribution", 200, -fMaxZ, fMaxZ);
330 
331  std::vector<BSTrkParameters>::const_iterator iparam = fBSvector.begin();
332 
333  // HERE check size of track vector
334 
335  for (iparam = fBSvector.begin(); iparam != fBSvector.end(); ++iparam) {
336  h1z->Fill(iparam->z0());
337  //std::cout<<"z0="<<iparam->z0()<<"; sigZ0="<<iparam->sigz0()<<std::endl;
338  }
339 
340  //Use our own copy for thread safety
341  // also do not add to global list of functions
342  TF1 fgaus("fgaus", "gaus", 0., 1., TF1::EAddToList::kNo);
343  h1z->Fit(&fgaus, "QLMN0 SERIAL");
344  //std::cout << "fitted "<< std::endl;
345 
346  //std::cout << "got function" << std::endl;
347  double fpar[2] = {fgaus.GetParameter(1), fgaus.GetParameter(2)};
348  //std::cout<<"Debug fpar[2] = (" <<fpar[0]<<","<<fpar[1]<<")"<<std::endl;
350  // add matrix values.
351  matrix(2, 2) = fgaus.GetParError(1) * fgaus.GetParError(1);
352  matrix(3, 3) = fgaus.GetParError(2) * fgaus.GetParError(2);
353 
354  //delete h1z;
355 
356  return reco::BeamSpot(reco::BeamSpot::Point(0., 0., fpar[0]), fpar[1], 0., 0., 0., matrix, fbeamtype);
357 }
358 
359 //______________________________________________________________________
361  this->d0phi_Init();
362  edm::LogInfo("BSFitter") << "number of total input tracks: " << fBSvector.size() << std::endl;
363 
364  reco::BeamSpot theanswer;
365 
366  if ((int)fBSvector.size() <= fminNtrks) {
367  edm::LogWarning("BSFitter") << "need at least " << fminNtrks << " tracks to run beamline fitter." << std::endl;
368  fbeamtype = reco::BeamSpot::Fake;
369  theanswer.setType(fbeamtype);
370  return theanswer;
371  }
372 
373  theanswer = Fit_d0phi(); //get initial ftmp and ftmprow
374  if (goodfit)
375  fnthite++;
376  //std::cout << "Initial tempanswer (iteration 0): " << theanswer << std::endl;
377 
378  reco::BeamSpot preanswer = theanswer;
379 
380  while (goodfit && ftmprow > fconvergence * fBSvector.size() && ftmprow > fminNtrks) {
381  theanswer = Fit_d0phi();
382  fd0cut /= 1.5;
383  fchi2cut /= 1.5;
384  if (goodfit && ftmprow > fconvergence * fBSvector.size() && ftmprow > fminNtrks) {
385  preanswer = theanswer;
386  //std::cout << "Iteration " << fnthite << ": " << preanswer << std::endl;
387  fnthite++;
388  }
389  }
390  // FIXME: return fit results from previous iteration for both bad fit and for >50% tracks thrown away
391  //std::cout << "The last iteration, theanswer: " << theanswer << std::endl;
392  theanswer = preanswer;
393  //std::cout << "Use previous results from iteration #" << ( fnthite > 0 ? fnthite-1 : 0 ) << std::endl;
394  //if ( fnthite > 1 ) std::cout << theanswer << std::endl;
395 
396  edm::LogInfo("BSFitter") << "Total number of successful iterations = " << (goodfit ? (fnthite + 1) : fnthite)
397  << std::endl;
398  if (goodfit) {
399  fbeamtype = reco::BeamSpot::Tracker;
400  theanswer.setType(fbeamtype);
401  } else {
402  edm::LogWarning("BSFitter") << "Fit doesn't converge!!!" << std::endl;
403  fbeamtype = reco::BeamSpot::Unknown;
404  theanswer.setType(fbeamtype);
405  }
406  return theanswer;
407 }
408 
409 //______________________________________________________________________
411  //LogDebug ("BSFitter") << " we will use " << fBSvector.size() << " tracks.";
412  if (fnthite > 0)
413  edm::LogInfo("BSFitter") << " number of tracks used: " << ftmprow << std::endl;
414  //std::cout << " ftmp = matrix("<<ftmp.GetNrows()<<","<<ftmp.GetNcols()<<")"<<std::endl;
415  //std::cout << " ftmp(0,0)="<<ftmp(0,0)<<std::endl;
416  //std::cout << " ftmp(1,0)="<<ftmp(1,0)<<std::endl;
417  //std::cout << " ftmp(2,0)="<<ftmp(2,0)<<std::endl;
418  //std::cout << " ftmp(3,0)="<<ftmp(3,0)<<std::endl;
419 
420  h1z->Reset();
421 
422  TMatrixD x_result(4, 1);
423  TMatrixDSym V_result(4);
424 
425  TMatrixDSym Vint(4);
426  TMatrixD b(4, 1);
427 
428  //Double_t weightsum = 0;
429 
430  Vint.Zero();
431  b.Zero();
432 
433  TMatrixD g(4, 1);
434  TMatrixDSym temp(4);
435 
436  std::vector<BSTrkParameters>::iterator iparam = fBSvector.begin();
437  ftmprow = 0;
438 
439  //edm::LogInfo ("BSFitter") << " test";
440 
441  //std::cout << "BSFitter: fit" << std::endl;
442 
443  for (iparam = fBSvector.begin(); iparam != fBSvector.end(); ++iparam) {
444  //if(i->weight2 == 0) continue;
445 
446  //if (ftmprow==0) {
447  //std::cout << "d0=" << iparam->d0() << " sigd0=" << iparam->sigd0()
448  //<< " phi0="<< iparam->phi0() << " z0=" << iparam->z0() << std::endl;
449  //std::cout << "d0phi_d0=" << iparam->d0phi_d0() << " d0phi_chi2="<<iparam->d0phi_chi2() << std::endl;
450  //}
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);
455 
456  // average transverse beam width
457  double sigmabeam2 = 0.006 * 0.006;
458  if (finputBeamWidth > 0)
459  sigmabeam2 = finputBeamWidth * finputBeamWidth;
460  else {
461  //edm::LogWarning("BSFitter") << "using in fit beam width = " << sqrt(sigmabeam2) << std::endl;
462  }
463 
464  //double sigma2 = sigmabeam2 + (iparam->sigd0())* (iparam->sigd0()) / iparam->weight2;
465  // this should be 2*sigmabeam2?
466  double sigma2 = sigmabeam2 + (iparam->sigd0()) * (iparam->sigd0());
467 
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;
472  (*iparam) = BSTrkParameters(
473  iparam->z0(), iparam->sigz0(), iparam->d0(), iparam->sigd0(), iparam->phi0(), iparam->pt(), dcor(0, 0), chi2tmp);
474 
475  bool pass = true;
476  if (fapplyd0cut && fnthite > 0) {
477  if (std::abs(iparam->d0() - dcor(0, 0)) > fd0cut)
478  pass = false;
479  }
480  if (fapplychi2cut && fnthite > 0) {
481  if (chi2tmp > fchi2cut)
482  pass = false;
483  }
484 
485  if (pass) {
486  temp.Zero();
487  for (int j = 0; j < 4; ++j) {
488  for (int k = j; k < 4; ++k) {
489  temp(j, k) += g(j, 0) * g(k, 0);
490  }
491  }
492 
493  Vint += (temp * (1 / sigma2));
494  b += (iparam->d0() / sigma2 * g);
495  //weightsum += sqrt(i->weight2);
496  ftmprow++;
497  h1z->Fill(iparam->z0());
498  }
499  }
500  Double_t determinant;
501  TDecompBK bk(Vint);
502  bk.SetTol(1e-11); //FIXME: find a better way to solve x_result
503  if (!bk.Decompose()) {
504  goodfit = false;
505  edm::LogWarning("BSFitter") << "Decomposition failed, matrix singular ?" << std::endl
506  << "condition number = " << bk.Condition() << std::endl;
507  } else {
508  V_result = Vint.InvertFast(&determinant);
509  x_result = V_result * b;
510  }
511  // for(int j = 0 ; j < 4 ; ++j) {
512  // for(int k = 0 ; k < 4 ; ++k) {
513  // std::cout<<"V_result("<<j<<","<<k<<")="<<V_result(j,k)<<std::endl;
514  // }
515  // }
516  // for (int j=0;j<4;++j){
517  // std::cout<<"x_result("<<j<<",0)="<<x_result(j,0)<<std::endl;
518  // }
519  //LogDebug ("BSFitter") << " d0-phi fit done.";
520  //std::cout<< " d0-phi fit done." << std::endl;
521 
522  //Use our own copy for thread safety
523  // also do not add to global list of functions
524  TF1 fgaus("fgaus", "gaus", 0., 1., TF1::EAddToList::kNo);
525  //returns 0 if OK
526  //auto status = h1z->Fit(&fgaus,"QLM0","",h1z->GetMean() -2.*h1z->GetRMS(),h1z->GetMean() +2.*h1z->GetRMS());
527  auto status =
528  h1z->Fit(&fgaus, "QLN0 SERIAL", "", h1z->GetMean() - 2. * h1z->GetRMS(), h1z->GetMean() + 2. * h1z->GetRMS());
529 
530  //std::cout << "fitted "<< std::endl;
531 
532  //std::cout << "got function" << std::endl;
533  if (status) {
534  //edm::LogError("NoBeamSpotFit")<<"gaussian fit failed. no BS d0 fit";
535 
536  goodfit = false;
537  return reco::BeamSpot();
538  }
539  double fpar[2] = {fgaus.GetParameter(1), fgaus.GetParameter(2)};
540 
542  // first two parameters
543  for (int j = 0; j < 2; ++j) {
544  for (int k = j; k < 2; ++k) {
545  matrix(j, k) = V_result(j, k);
546  }
547  }
548  // slope parameters
549  for (int j = 4; j < 6; ++j) {
550  for (int k = j; k < 6; ++k) {
551  matrix(j, k) = V_result(j - 2, k - 2);
552  }
553  }
554 
555  // Z0 and sigmaZ
556  matrix(2, 2) = fgaus.GetParError(1) * fgaus.GetParError(1);
557  matrix(3, 3) = fgaus.GetParError(2) * fgaus.GetParError(2);
558 
559  ftmp = x_result;
560 
561  // x0 and y0 are *not* x,y at z=0, but actually at z=0
562  // to correct for this, we need to translate them to z=z0
563  // using the measured slopes
564  //
565  double x0tmp = x_result(0, 0);
566  double y0tmp = x_result(1, 0);
567 
568  x0tmp += x_result(2, 0) * fpar[0];
569  y0tmp += x_result(3, 0) * fpar[0];
570 
571  return reco::BeamSpot(
572  reco::BeamSpot::Point(x0tmp, y0tmp, fpar[0]), fpar[1], x_result(2, 0), x_result(3, 0), 0., matrix, fbeamtype);
573 }
574 
575 //______________________________________________________________________
576 void BSFitter::Setd0Cut_d0phi(double d0cut) {
577  fapplyd0cut = true;
578 
579  //fBSforCuts = BSfitted;
580  fd0cut = d0cut;
581 }
582 
583 //______________________________________________________________________
585  fapplychi2cut = true;
586 
587  //fBSforCuts = BSfitted;
588  fchi2cut = chi2cut;
589 }
590 
591 //______________________________________________________________________
593  thePDF->SetPDFs("PDFGauss_d");
594  thePDF->SetData(fBSvector);
595 
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);
603 
604  MnMigrad migrad(*thePDF, upar);
605 
606  FunctionMinimum fmin = migrad();
607  ff_minimum = fmin.Fval();
608 
610  for (int j = 0; j < 6; ++j) {
611  for (int k = j; k < 6; ++k) {
612  matrix(j, k) = fmin.Error().Matrix()(j, k);
613  }
614  }
615 
616  return reco::BeamSpot(reco::BeamSpot::Point(fmin.Parameters().Vec()(0), fmin.Parameters().Vec()(1), 0.),
617  0.,
618  fmin.Parameters().Vec()(4),
619  fmin.Parameters().Vec()(5),
620  0.,
621  matrix,
622  fbeamtype);
623 }
624 //______________________________________________________________________
625 double BSFitter::scanPDF(double *init_pars, int &tracksfixed, int option) {
626  if (option == 1)
627  init_pars[6] = 0.0005; //starting value for any given configuration
628 
629  //local vairables with initial values
630  double fsqrt2pi = 0.0;
631  double d_sig = 0.0;
632  double d_dprime = 0.0;
633  double d_result = 0.0;
634  double z_sig = 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;
640  int iters = 0;
641 
642  //used to remove tracks if far away from bs by this
643  double DeltadCut = 0.1000;
644  if (init_pars[6] < 0.0200) {
645  DeltadCut = 0.0900;
646  } //worked for high 2.36TeV
647  if (init_pars[6] < 0.0100) {
648  DeltadCut = 0.0700;
649  } //just a guesss for 7 TeV but one should scan for actual values
650 
651  std::vector<BSTrkParameters>::const_iterator iparam = fBSvector.begin();
652 
653  if (option == 1)
654  iters = 500;
655  if (option == 2)
656  iters = 1;
657 
658  for (int p = 0; p < iters; p++) {
659  if (iters == 500)
660  init_pars[6] += 0.0002;
661  tracksfixed = 0;
662 
663  for (iparam = fBSvector.begin(); iparam != fBSvector.end(); ++iparam) {
664  fsqrt2pi = sqrt(2. * TMath::Pi());
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())));
668 
669  //***Remove tracks before the fit which gives low pdf values to blow up the pdf
670  if (std::abs(d_dprime) < DeltadCut && option == 2) {
671  fBSvectorBW.push_back(*iparam);
672  }
673 
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))) /
677  (z_sig * fsqrt2pi);
678  tot_pdf = z_result * d_result;
679 
680  //for those trcks which gives problems due to very tiny pdf_d values.
681  //Update: This protection will NOT be used with the dprime cut above but still kept here to get
682  // the intial value of beam width reasonably
683  //A warning will appear if there were any tracks with < 10^-5 for pdf_d so that (d-dprime) cut can be lowered
684  if (d_result < 1.0e-05) {
685  tot_pdf = z_result * 1.0e-05;
686  //if(option==2)std::cout<<"last Iter d-d' = "<<(std::abs(d_dprime))<<std::endl;
687  tracksfixed++;
688  }
689 
690  function = function + log(tot_pdf);
691 
692  } //loop over tracks
693 
694  function = -2.0 * function;
695  if (function < last_minvalue) {
696  init_bw = init_pars[6];
697  last_minvalue = function;
698  }
699  function = 0.0;
700  } //loop over beam width
701 
702  if (init_bw > 0) {
703  init_bw = init_bw + (0.20 * init_bw); //start with 20 % more
704 
705  } else {
706  if (option == 1) {
707  edm::LogWarning("BSFitter")
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;
710  init_bw = 0.0200;
711  }
712  }
713 
714  return init_bw;
715 }
716 
717 //________________________________________________________________________________
718 reco::BeamSpot BSFitter::Fit_d_z_likelihood(double *inipar, double *error_par) {
719  int tracksFailed = 0;
720 
721  //estimate first guess of beam width and tame 20% extra of it to start
722  inipar[6] = scanPDF(inipar, tracksFailed, 1);
723  error_par[6] = (inipar[6]) * 0.20;
724 
725  //Here remove the tracks which give low pdf and fill into a new vector
726  //std::cout<<"Size of Old vector = "<<(fBSvector.size())<<std::endl;
727  /* double junk= */ scanPDF(inipar, tracksFailed, 2);
728  //std::cout<<"Size of New vector = "<<(fBSvectorBW.size())<<std::endl;
729 
730  //Refill the fBSVector again with new sets of tracks
731  fBSvector.clear();
732  std::vector<BSTrkParameters>::const_iterator iparamBW = fBSvectorBW.begin();
733  for (iparamBW = fBSvectorBW.begin(); iparamBW != fBSvectorBW.end(); ++iparamBW) {
734  fBSvector.push_back(*iparamBW);
735  }
736 
737  thePDF->SetPDFs("PDFGauss_d*PDFGauss_z");
738  thePDF->SetData(fBSvector);
739  MnUserParameters upar;
740 
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]);
748 
749  MnMigrad migrad(*thePDF, upar);
750 
751  FunctionMinimum fmin = migrad();
752 
753  // std::cout<<"-----how the fit evoves------"<<std::endl;
754  // std::cout<<fmin<<std::endl;
755 
756  ff_minimum = fmin.Fval();
757 
758  bool ff_nfcn = fmin.HasReachedCallLimit();
759  bool ff_cov = fmin.HasCovariance();
760  bool testing = fmin.IsValid();
761 
762  //Print WARNINGS if minimum did not converged
763  if (!testing) {
764  edm::LogWarning("BSFitter") << "===========>>>>>** WARNING: MINUIT DID NOT CONVERGES PROPERLY !!!!!!" << std::endl;
765  if (ff_nfcn)
766  edm::LogWarning("BSFitter") << "===========>>>>>** WARNING: No. of Calls Exhausted" << std::endl;
767  if (!ff_cov)
768  edm::LogWarning("BSFitter") << "===========>>>>>** WARNING: Covariance did not found" << std::endl;
769  }
770 
771  edm::LogInfo("BSFitter") << "The Total # Tracks used for beam width fit = " << (fBSvectorBW.size()) << std::endl;
772 
773  //Checks after fit is performed
774  double lastIter_pars[7];
775 
776  for (int ip = 0; ip < 7; ip++) {
777  lastIter_pars[ip] = fmin.Parameters().Vec()(ip);
778  }
779 
780  tracksFailed = 0;
781  /* double lastIter_scan= */ scanPDF(lastIter_pars, tracksFailed, 2);
782 
783  edm::LogWarning("BSFitter") << "WARNING: # of tracks which have very low pdf value (pdf_d < 1.0e-05) are = "
784  << tracksFailed << std::endl;
785 
786  //std::cout << " eval= " << ff_minimum
787  // << "/n params[0]= " << fmin.Parameters().Vec()(0) << std::endl;
788 
790 
791  for (int j = 0; j < 7; ++j) {
792  for (int k = j; k < 7; ++k) {
793  matrix(j, k) = fmin.Error().Matrix()(j, k);
794  }
795  }
796 
797  return reco::BeamSpot(
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),
803 
804  matrix,
805  fbeamtype);
806 }
807 
808 //______________________________________________________________________
810  thePDF->SetPDFs("PDFGauss_d_resolution*PDFGauss_z");
811  thePDF->SetData(fBSvector);
812 
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);
823 
824  // fix beam width
825  upar.Fix("BeamWidthX");
826  // number of parameters in fit are 9-1 = 8
827 
828  MnMigrad migrad(*thePDF, upar);
829 
830  FunctionMinimum fmin = migrad();
831  ff_minimum = fmin.Fval();
832 
834 
835  for (int j = 0; j < 6; ++j) {
836  for (int k = j; k < 6; ++k) {
837  matrix(j, k) = fmin.Error().Matrix()(j, k);
838  }
839  }
840 
841  //std::cout << " fill resolution values" << std::endl;
842  //std::cout << " matrix size= " << fmin.Error().Matrix().size() << std::endl;
843  //std::cout << " vec(6)="<< fmin.Parameters().Vec()(6) << std::endl;
844  //std::cout << " vec(7)="<< fmin.Parameters().Vec()(7) << std::endl;
845 
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));
850 
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);
854  }
855  }
856 
857  return reco::BeamSpot(
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),
862  inipar[6],
863  matrix,
864  fbeamtype);
865 }
reco::BeamSpot Fit_d_likelihood(double *inipar)
Definition: BSFitter.cc:592
const double Pi
math::Error< dimension >::type CovarianceMatrix
Definition: BeamSpot.h:29
double BeamWidthX() const
beam width X
Definition: BeamSpot.h:82
virtual ~BSFitter()
Definition: BSFitter.cc:95
bool testing
reco::BeamSpot Fit()
Definition: BSFitter.cc:102
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
reco::BeamSpot Fit_z_likelihood(double *inipar)
Definition: BSFitter.cc:255
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
math::XYZPoint Point
point in the space
Definition: BeamSpot.h:27
double dydz() const
dydz slope
Definition: BeamSpot.h:80
double scanPDF(double *init_pars, int &tracksFailed, int option)
Definition: BSFitter.cc:625
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
Definition: Activities.doc:4
reco::BeamSpot Fit_dres_z_likelihood(double *inipar)
Definition: BSFitter.cc:809
void setType(BeamType type)
set beam type
Definition: BeamSpot.h:124
double x0() const
x coordinate
Definition: BeamSpot.h:61
Definition: Fit.h:32
T sqrt(T t)
Definition: SSEVec.h:19
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
BSFitter()
Definition: BSFitter.cc:41
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double y0() const
y coordinate
Definition: BeamSpot.h:63
Log< level::Info, false > LogInfo
double sigmaZ() const
sigma z
Definition: BeamSpot.h:76
reco::BeamSpot Fit_ited0phi()
Definition: BSFitter.cc:360
double dxdz() const
dxdz slope
Definition: BeamSpot.h:78
double b
Definition: hdecay.h:120
reco::BeamSpot Fit_z_chi2(double *inipar)
Definition: BSFitter.cc:321
void Setd0Cut_d0phi(double d0cut)
Definition: BSFitter.cc:576
double covariance(int i, int j) const
(i,j)-th element of error matrix
Definition: BeamSpot.h:108
double z0() const
z coordinate
Definition: BeamSpot.h:65
void SetChi2Cut_d0phi(double chi2cut)
Definition: BSFitter.cc:584
Log< level::Warning, false > LogWarning
reco::BeamSpot Fit_d0phi()
Definition: BSFitter.cc:410
reco::BeamSpot Fit_d_z_likelihood(double *inipar, double *error_par)
Definition: BSFitter.cc:718
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29