CMS 3D CMS Logo

MuonResiduals5DOFFitter.cc
Go to the documentation of this file.
1 // $Id:$
2 
3 #ifdef STANDALONE_FITTER
5 #else
7 #endif
8 
9 #include "TH2F.h"
10 #include "TMath.h"
11 #include "TTree.h"
12 #include "TFile.h"
13 
14 namespace {
15  TMinuit *minuit;
16 
17  double sum_of_weights;
18  double number_of_hits;
19  bool weight_alignment;
20 
21  double residual_x(double delta_x,
22  double delta_z,
23  double delta_phix,
24  double delta_phiy,
25  double delta_phiz,
26  double track_x,
27  double track_y,
28  double track_dxdz,
29  double track_dydz,
30  double alpha,
31  double resslope) {
32  return delta_x - track_dxdz * delta_z - track_y * track_dxdz * delta_phix + track_x * track_dxdz * delta_phiy -
33  track_y * delta_phiz + resslope * alpha;
34  }
35 
36  double residual_dxdz(double delta_x,
37  double delta_z,
38  double delta_phix,
39  double delta_phiy,
40  double delta_phiz,
41  double track_x,
42  double track_y,
43  double track_dxdz,
44  double track_dydz) {
45  return -track_dxdz * track_dydz * delta_phix + (1. + track_dxdz * track_dxdz) * delta_phiy -
46  track_dydz * delta_phiz;
47  }
48 
49  Double_t residual_x_trackx_TF1(Double_t *xx, Double_t *p) {
50  return 10. * residual_x(p[0], p[2], p[3], p[4], p[5], xx[0], p[7], p[8], p[9], p[10], p[11]);
51  }
52  Double_t residual_x_tracky_TF1(Double_t *xx, Double_t *p) {
53  return 10. * residual_x(p[0], p[2], p[3], p[4], p[5], p[6], xx[0], p[8], p[9], p[10], p[11]);
54  }
55  Double_t residual_x_trackdxdz_TF1(Double_t *xx, Double_t *p) {
56  return 10. * residual_x(p[0], p[2], p[3], p[4], p[5], p[6], p[7], xx[0], p[9], p[10], p[11]);
57  }
58  Double_t residual_x_trackdydz_TF1(Double_t *xx, Double_t *p) {
59  return 10. * residual_x(p[0], p[2], p[3], p[4], p[5], p[6], p[7], p[8], xx[0], p[10], p[11]);
60  }
61 
62  Double_t residual_dxdz_trackx_TF1(Double_t *xx, Double_t *p) {
63  return 1000. * residual_dxdz(p[0], p[2], p[3], p[4], p[5], xx[0], p[7], p[8], p[9]);
64  }
65  Double_t residual_dxdz_tracky_TF1(Double_t *xx, Double_t *p) {
66  return 1000. * residual_dxdz(p[0], p[2], p[3], p[4], p[5], p[6], xx[0], p[8], p[9]);
67  }
68  Double_t residual_dxdz_trackdxdz_TF1(Double_t *xx, Double_t *p) {
69  return 1000. * residual_dxdz(p[0], p[2], p[3], p[4], p[5], p[6], p[7], xx[0], p[9]);
70  }
71  Double_t residual_dxdz_trackdydz_TF1(Double_t *xx, Double_t *p) {
72  return 1000. * residual_dxdz(p[0], p[2], p[3], p[4], p[5], p[6], p[7], p[8], xx[0]);
73  }
74 } // namespace
75 
76 void MuonResiduals5DOFFitter_FCN(int &npar, double *gin, double &fval, double *par, int iflag) {
77  MuonResidualsFitterFitInfo *fitinfo = (MuonResidualsFitterFitInfo *)(minuit->GetObjectFit());
78  MuonResidualsFitter *fitter = fitinfo->fitter();
79 
80  fval = 0.;
81  for (std::vector<double *>::const_iterator resiter = fitter->residuals_begin(); resiter != fitter->residuals_end();
82  ++resiter) {
83  const double residual = (*resiter)[MuonResiduals5DOFFitter::kResid];
84  const double resslope = (*resiter)[MuonResiduals5DOFFitter::kResSlope];
85  const double positionX = (*resiter)[MuonResiduals5DOFFitter::kPositionX];
86  const double positionY = (*resiter)[MuonResiduals5DOFFitter::kPositionY];
87  const double angleX = (*resiter)[MuonResiduals5DOFFitter::kAngleX];
88  const double angleY = (*resiter)[MuonResiduals5DOFFitter::kAngleY];
89  const double redchi2 = (*resiter)[MuonResiduals5DOFFitter::kRedChi2];
90 
91  const double alignx = par[MuonResiduals5DOFFitter::kAlignX];
92  const double alignz = par[MuonResiduals5DOFFitter::kAlignZ];
93  const double alignphix = par[MuonResiduals5DOFFitter::kAlignPhiX];
94  const double alignphiy = par[MuonResiduals5DOFFitter::kAlignPhiY];
95  const double alignphiz = par[MuonResiduals5DOFFitter::kAlignPhiZ];
96  const double residsigma = par[MuonResiduals5DOFFitter::kResidSigma];
97  const double resslopesigma = par[MuonResiduals5DOFFitter::kResSlopeSigma];
98  const double alpha = par[MuonResiduals5DOFFitter::kAlpha];
99  const double residgamma = par[MuonResiduals5DOFFitter::kResidGamma];
100  const double resslopegamma = par[MuonResiduals5DOFFitter::kResSlopeGamma];
101 
102  double coeff = alpha;
105  coeff = 0.;
106  double residpeak = residual_x(
107  alignx, alignz, alignphix, alignphiy, alignphiz, positionX, positionY, angleX, angleY, coeff, resslope);
108  double resslopepeak =
109  residual_dxdz(alignx, alignz, alignphix, alignphiy, alignphiz, positionX, positionY, angleX, angleY);
110 
111  double weight = (1. / redchi2) * number_of_hits / sum_of_weights;
112  if (!weight_alignment)
113  weight = 1.;
114 
115  if (!weight_alignment || TMath::Prob(redchi2 * 8, 8) < 0.99) // no spikes allowed
116  {
118  if (fitter->useRes() == MuonResidualsFitter::k1111 || fitter->useRes() == MuonResidualsFitter::k1110 ||
119  fitter->useRes() == MuonResidualsFitter::k1010) {
120  fval += -weight * MuonResidualsFitter_logPureGaussian(residual, residpeak, residsigma);
121  fval += -weight * MuonResidualsFitter_logPureGaussian(resslope, resslopepeak, resslopesigma);
122  } else if (fitter->useRes() == MuonResidualsFitter::k1100) {
123  fval += -weight * MuonResidualsFitter_logPureGaussian(residual, residpeak, residsigma);
124  } else if (fitter->useRes() == MuonResidualsFitter::k0010) {
125  fval += -weight * MuonResidualsFitter_logPureGaussian(resslope, resslopepeak, resslopesigma);
126  }
127  } else if (fitter->residualsModel() == MuonResidualsFitter::kPureGaussian2D) {
128  if (fitter->useRes() == MuonResidualsFitter::k1111 || fitter->useRes() == MuonResidualsFitter::k1110 ||
129  fitter->useRes() == MuonResidualsFitter::k1010) {
131  residual, resslope, residpeak, resslopepeak, residsigma, resslopesigma, alpha);
132  } else if (fitter->useRes() == MuonResidualsFitter::k1100) {
133  fval += -weight * MuonResidualsFitter_logPureGaussian(residual, residpeak, residsigma);
134  } else if (fitter->useRes() == MuonResidualsFitter::k0010) {
135  fval += -weight * MuonResidualsFitter_logPureGaussian(resslope, resslopepeak, resslopesigma);
136  }
137  } else if (fitter->residualsModel() == MuonResidualsFitter::kPowerLawTails) {
138  fval += -weight * MuonResidualsFitter_logPowerLawTails(residual, residpeak, residsigma, residgamma);
139  fval += -weight * MuonResidualsFitter_logPowerLawTails(resslope, resslopepeak, resslopesigma, resslopegamma);
140  } else if (fitter->residualsModel() == MuonResidualsFitter::kROOTVoigt) {
141  fval += -weight * MuonResidualsFitter_logROOTVoigt(residual, residpeak, residsigma, residgamma);
142  fval += -weight * MuonResidualsFitter_logROOTVoigt(resslope, resslopepeak, resslopesigma, resslopegamma);
143  } else if (fitter->residualsModel() == MuonResidualsFitter::kGaussPowerTails) {
144  fval += -weight * MuonResidualsFitter_logGaussPowerTails(residual, residpeak, residsigma);
145  fval += -weight * MuonResidualsFitter_logGaussPowerTails(resslope, resslopepeak, resslopesigma);
146  } else {
147  assert(false);
148  }
149  }
150  }
151 }
152 
154 
155 void MuonResiduals5DOFFitter::inform(TMinuit *tMinuit) { minuit = tMinuit; }
156 
158  sum_of_weights = 0.;
159  number_of_hits = 0.;
160  weight_alignment = m_weightAlignment;
161  for (std::vector<double *>::const_iterator resiter = residuals_begin(); resiter != residuals_end(); ++resiter) {
162  if (m_weightAlignment) {
163  double redchi2 = (*resiter)[MuonResiduals5DOFFitter::kRedChi2];
164  if (TMath::Prob(redchi2 * 8, 8) < 0.99) {
165  sum_of_weights += 1. / redchi2;
166  number_of_hits += 1.;
167  }
168  } else {
169  sum_of_weights += 1.;
170  number_of_hits += 1.;
171  }
172  }
173  return sum_of_weights;
174 }
175 
177  initialize_table(); // if not already initialized
178  sumofweights();
179 
180  double res_std = 0.5;
181  double resslope_std = 0.005;
182 
183  int nums[10] = {kAlignX,
184  kAlignZ,
185  kAlignPhiX,
186  kAlignPhiY,
187  kAlignPhiZ,
188  kResidSigma,
190  kAlpha,
191  kResidGamma,
193  std::string names[10] = {"AlignX",
194  "AlignZ",
195  "AlignPhiX",
196  "AlignPhiY",
197  "AlignPhiZ",
198  "ResidSigma",
199  "ResSlopeSigma",
200  "Alpha",
201  "ResidGamma",
202  "ResSlopeGamma"};
203  double starts[10] = {0., 0., 0., 0., 0., res_std, resslope_std, 0., 0.1 * res_std, 0.1 * resslope_std};
204  double steps[10] = {
205  0.1, 0.1, 0.001, 0.001, 0.001, 0.001 * res_std, 0.001 * resslope_std, 0.001, 0.01 * res_std, 0.01 * resslope_std};
206  double lows[10] = {0., 0., 0., 0., 0., 0., 0., -1., 0., 0.};
207  double highs[10] = {0., 0., 0., 0., 0., 10., 0.1, 1., 0., 0.};
208 
209  std::vector<int> num(nums, nums + 5);
210  std::vector<std::string> name(names, names + 5);
211  std::vector<double> start(starts, starts + 5);
212  std::vector<double> step(steps, steps + 5);
213  std::vector<double> low(lows, lows + 5);
214  std::vector<double> high(highs, highs + 5);
215 
216  bool add_alpha = (residualsModel() == kPureGaussian2D);
217  bool add_gamma = (residualsModel() == kROOTVoigt || residualsModel() == kPowerLawTails);
218 
219  int idx[4], ni = 0;
220  if (useRes() == k1111 || useRes() == k1110 || useRes() == k1010) {
221  for (ni = 0; ni < 2; ni++)
222  idx[ni] = ni + 5;
223  if (add_alpha)
224  idx[ni++] = 7;
225  else if (add_gamma)
226  for (; ni < 4; ni++)
227  idx[ni] = ni + 6;
228  if (!add_alpha)
229  fix(kAlpha);
230  } else if (useRes() == k1100) {
231  idx[ni++] = 5;
232  if (add_gamma)
233  idx[ni++] = 8;
235  fix(kAlpha);
236  } else if (useRes() == k0010) {
237  idx[ni++] = 6;
238  if (add_gamma)
239  idx[ni++] = 9;
240  fix(kResidSigma);
241  fix(kAlpha);
242  }
243  for (int i = 0; i < ni; i++) {
244  num.push_back(nums[idx[i]]);
245  name.push_back(names[idx[i]]);
246  start.push_back(starts[idx[i]]);
247  step.push_back(steps[idx[i]]);
248  low.push_back(lows[idx[i]]);
249  high.push_back(highs[idx[i]]);
250  }
251 
253 }
254 
256  sumofweights();
257 
258  double mean_residual = 0., mean_resslope = 0.;
259  double mean_trackx = 0., mean_tracky = 0., mean_trackdxdz = 0., mean_trackdydz = 0.;
260  double sum_w = 0.;
261 
262  for (std::vector<double *>::const_iterator rit = residuals_begin(); rit != residuals_end(); ++rit) {
263  const double redchi2 = (*rit)[kRedChi2];
264  double weight = 1. / redchi2;
265  if (!m_weightAlignment)
266  weight = 1.;
267 
268  if (!m_weightAlignment || TMath::Prob(redchi2 * 6, 6) < 0.99) // no spikes allowed
269  {
270  double factor_w = 1. / (sum_w + weight);
271  mean_residual = factor_w * (sum_w * mean_residual + weight * (*rit)[kResid]);
272  mean_resslope = factor_w * (sum_w * mean_resslope + weight * (*rit)[kResSlope]);
273  mean_trackx = factor_w * (sum_w * mean_trackx + weight * (*rit)[kPositionX]);
274  mean_tracky = factor_w * (sum_w * mean_tracky + weight * (*rit)[kPositionY]);
275  mean_trackdxdz = factor_w * (sum_w * mean_trackdxdz + weight * (*rit)[kAngleX]);
276  mean_trackdydz = factor_w * (sum_w * mean_trackdydz + weight * (*rit)[kAngleY]);
277  sum_w += weight;
278  }
279  }
280 
281  std::string name_residual, name_resslope, name_residual_raw, name_resslope_raw, name_residual_cut, name_alpha;
282  std::string name_residual_trackx, name_resslope_trackx;
283  std::string name_residual_tracky, name_resslope_tracky;
284  std::string name_residual_trackdxdz, name_resslope_trackdxdz;
285  std::string name_residual_trackdydz, name_resslope_trackdydz;
286 
287  name_residual = name + "_residual";
288  name_resslope = name + "_resslope";
289  name_residual_raw = name + "_residual_raw";
290  name_resslope_raw = name + "_resslope_raw";
291  name_residual_cut = name + "_residual_cut";
292  name_alpha = name + "_alpha";
293  name_residual_trackx = name + "_residual_trackx";
294  name_resslope_trackx = name + "_resslope_trackx";
295  name_residual_tracky = name + "_residual_tracky";
296  name_resslope_tracky = name + "_resslope_tracky";
297  name_residual_trackdxdz = name + "_residual_trackdxdz";
298  name_resslope_trackdxdz = name + "_resslope_trackdxdz";
299  name_residual_trackdydz = name + "_residual_trackdydz";
300  name_resslope_trackdydz = name + "_resslope_trackdydz";
301 
302  double width = ali->surface().width();
303  double length = ali->surface().length();
304  int bins_residual = 150, bins_resslope = 100;
305  double min_residual = -75., max_residual = 75.;
306  double min_resslope = -50., max_resslope = 50.;
307  double min_trackx = -width / 2., max_trackx = width / 2.;
308  double min_tracky = -length / 2., max_tracky = length / 2.;
309  double min_trackdxdz = -1.5, max_trackdxdz = 1.5;
310  double min_trackdydz = -1.5, max_trackdydz = 1.5;
311 
312  TH1F *hist_residual = dir->make<TH1F>(name_residual.c_str(), "", bins_residual, min_residual, max_residual);
313  TH1F *hist_resslope = dir->make<TH1F>(name_resslope.c_str(), "", bins_resslope, min_resslope, max_resslope);
314  TH1F *hist_residual_raw = dir->make<TH1F>(name_residual_raw.c_str(), "", bins_residual, min_residual, max_residual);
315  TH1F *hist_resslope_raw = dir->make<TH1F>(name_resslope_raw.c_str(), "", bins_resslope, min_resslope, max_resslope);
316  TH1F *hist_residual_cut = dir->make<TH1F>(name_residual_cut.c_str(), "", bins_residual, min_residual, max_residual);
317  TH2F *hist_alpha = dir->make<TH2F>(name_alpha.c_str(), "", 50, min_resslope, max_resslope, 50, -50., 50.);
318 
319  TProfile *hist_residual_trackx =
320  dir->make<TProfile>(name_residual_trackx.c_str(), "", 50, min_trackx, max_trackx, min_residual, max_residual);
321  TProfile *hist_resslope_trackx =
322  dir->make<TProfile>(name_resslope_trackx.c_str(), "", 50, min_trackx, max_trackx, min_resslope, max_resslope);
323  TProfile *hist_residual_tracky =
324  dir->make<TProfile>(name_residual_tracky.c_str(), "", 50, min_tracky, max_tracky, min_residual, max_residual);
325  TProfile *hist_resslope_tracky =
326  dir->make<TProfile>(name_resslope_tracky.c_str(), "", 50, min_tracky, max_tracky, min_resslope, max_resslope);
327  TProfile *hist_residual_trackdxdz = dir->make<TProfile>(
328  name_residual_trackdxdz.c_str(), "", 250, min_trackdxdz, max_trackdxdz, min_residual, max_residual);
329  TProfile *hist_resslope_trackdxdz = dir->make<TProfile>(
330  name_resslope_trackdxdz.c_str(), "", 250, min_trackdxdz, max_trackdxdz, min_resslope, max_resslope);
331  TProfile *hist_residual_trackdydz = dir->make<TProfile>(
332  name_residual_trackdydz.c_str(), "", 250, min_trackdydz, max_trackdydz, min_residual, max_residual);
333  TProfile *hist_resslope_trackdydz = dir->make<TProfile>(
334  name_resslope_trackdydz.c_str(), "", 250, min_trackdydz, max_trackdydz, min_resslope, max_resslope);
335 
336  hist_residual_trackx->SetAxisRange(-10., 10., "Y");
337  hist_resslope_trackx->SetAxisRange(-10., 10., "Y");
338  hist_residual_tracky->SetAxisRange(-10., 10., "Y");
339  hist_resslope_tracky->SetAxisRange(-10., 10., "Y");
340  hist_residual_trackdxdz->SetAxisRange(-10., 10., "Y");
341  hist_resslope_trackdxdz->SetAxisRange(-10., 10., "Y");
342  hist_residual_trackdydz->SetAxisRange(-10., 10., "Y");
343  hist_resslope_trackdydz->SetAxisRange(-10., 10., "Y");
344 
345  name_residual += "_fit";
346  name_resslope += "_fit";
347  name_alpha += "_fit";
348  name_residual_trackx += "_fit";
349  name_resslope_trackx += "_fit";
350  name_residual_tracky += "_fit";
351  name_resslope_tracky += "_fit";
352  name_residual_trackdxdz += "_fit";
353  name_resslope_trackdxdz += "_fit";
354  name_residual_trackdydz += "_fit";
355  name_resslope_trackdydz += "_fit";
356 
357  TF1 *fit_residual = nullptr;
358  TF1 *fit_resslope = nullptr;
360  fit_residual = new TF1(name_residual.c_str(), MuonResidualsFitter_pureGaussian_TF1, min_residual, max_residual, 3);
361  fit_residual->SetParameters(
362  sum_of_weights * (max_residual - min_residual) / bins_residual, 10. * value(kAlignX), 10. * value(kResidSigma));
363  const double er_res[3] = {0., 10. * errorerror(kAlignX), 10. * errorerror(kResidSigma)};
364  fit_residual->SetParErrors(er_res);
365  fit_resslope = new TF1(name_resslope.c_str(), MuonResidualsFitter_pureGaussian_TF1, min_resslope, max_resslope, 3);
366  fit_resslope->SetParameters(sum_of_weights * (max_resslope - min_resslope) / bins_resslope,
367  1000. * value(kAlignPhiY),
368  1000. * value(kResSlopeSigma));
369  const double er_resslope[3] = {0., 1000. * errorerror(kAlignPhiY), 1000. * errorerror(kResSlopeSigma)};
370  fit_resslope->SetParErrors(er_resslope);
371  } else if (residualsModel() == kPowerLawTails) {
372  fit_residual = new TF1(name_residual.c_str(), MuonResidualsFitter_powerLawTails_TF1, min_residual, max_residual, 4);
373  fit_residual->SetParameters(sum_of_weights * (max_residual - min_residual) / bins_residual,
374  10. * value(kAlignX),
375  10. * value(kResidSigma),
376  10. * value(kResidGamma));
377  fit_resslope = new TF1(name_resslope.c_str(), MuonResidualsFitter_powerLawTails_TF1, min_resslope, max_resslope, 4);
378  fit_resslope->SetParameters(sum_of_weights * (max_resslope - min_resslope) / bins_resslope,
379  1000. * value(kAlignPhiY),
380  1000. * value(kResSlopeSigma),
381  1000. * value(kResSlopeGamma));
382  } else if (residualsModel() == kROOTVoigt) {
383  fit_residual = new TF1(name_residual.c_str(), MuonResidualsFitter_ROOTVoigt_TF1, min_residual, max_residual, 4);
384  fit_residual->SetParameters(sum_of_weights * (max_residual - min_residual) / bins_residual,
385  10. * value(kAlignX),
386  10. * value(kResidSigma),
387  10. * value(kResidGamma));
388  fit_resslope = new TF1(name_resslope.c_str(), MuonResidualsFitter_ROOTVoigt_TF1, min_resslope, max_resslope, 4);
389  fit_resslope->SetParameters(sum_of_weights * (max_resslope - min_resslope) / bins_resslope,
390  1000. * value(kAlignPhiY),
391  1000. * value(kResSlopeSigma),
392  1000. * value(kResSlopeGamma));
393  } else if (residualsModel() == kGaussPowerTails) {
394  fit_residual =
395  new TF1(name_residual.c_str(), MuonResidualsFitter_GaussPowerTails_TF1, min_residual, max_residual, 3);
396  fit_residual->SetParameters(
397  sum_of_weights * (max_residual - min_residual) / bins_residual, 10. * value(kAlignX), 10. * value(kResidSigma));
398  fit_resslope =
399  new TF1(name_resslope.c_str(), MuonResidualsFitter_GaussPowerTails_TF1, min_resslope, max_resslope, 3);
400  fit_resslope->SetParameters(sum_of_weights * (max_resslope - min_resslope) / bins_resslope,
401  1000. * value(kAlignPhiY),
402  1000. * value(kResSlopeSigma));
403  } else {
404  assert(false);
405  }
406 
407  fit_residual->SetLineColor(2);
408  fit_residual->SetLineWidth(2);
409  fit_residual->Write();
410  fit_resslope->SetLineColor(2);
411  fit_resslope->SetLineWidth(2);
412  fit_resslope->Write();
413 
414  TF1 *fit_alpha = new TF1(name_alpha.c_str(), "[0] + x*[1]", min_resslope, max_resslope);
415  double a = 10. * value(kAlignX), b = 10. * value(kAlpha) / 1000.;
416  if (residualsModel() == kPureGaussian2D) {
417  double sx = 10. * value(kResidSigma), sy = 1000. * value(kResSlopeSigma), r = value(kAlpha);
418  a = mean_residual;
419  b = 0.;
420  if (sx != 0.) {
421  b = 1. / (sy / sx * r);
422  a = -b * mean_resslope;
423  }
424  }
425  fit_alpha->SetParameters(a, b);
426  fit_alpha->SetLineColor(2);
427  fit_alpha->SetLineWidth(2);
428  fit_alpha->Write();
429 
430  TProfile *fit_residual_trackx = dir->make<TProfile>(name_residual_trackx.c_str(), "", 50, min_trackx, max_trackx);
431  TProfile *fit_resslope_trackx = dir->make<TProfile>(name_resslope_trackx.c_str(), "", 50, min_trackx, max_trackx);
432  TProfile *fit_residual_tracky = dir->make<TProfile>(name_residual_tracky.c_str(), "", 50, min_tracky, max_tracky);
433  TProfile *fit_resslope_tracky = dir->make<TProfile>(name_resslope_tracky.c_str(), "", 50, min_tracky, max_tracky);
434  TProfile *fit_residual_trackdxdz =
435  dir->make<TProfile>(name_residual_trackdxdz.c_str(), "", 250, min_trackdxdz, max_trackdxdz);
436  TProfile *fit_resslope_trackdxdz =
437  dir->make<TProfile>(name_resslope_trackdxdz.c_str(), "", 250, min_trackdxdz, max_trackdxdz);
438  TProfile *fit_residual_trackdydz =
439  dir->make<TProfile>(name_residual_trackdydz.c_str(), "", 250, min_trackdydz, max_trackdydz);
440  TProfile *fit_resslope_trackdydz =
441  dir->make<TProfile>(name_resslope_trackdydz.c_str(), "", 250, min_trackdydz, max_trackdydz);
442 
443  fit_residual_trackx->SetLineColor(2);
444  fit_residual_trackx->SetLineWidth(2);
445  fit_resslope_trackx->SetLineColor(2);
446  fit_resslope_trackx->SetLineWidth(2);
447  fit_residual_tracky->SetLineColor(2);
448  fit_residual_tracky->SetLineWidth(2);
449  fit_resslope_tracky->SetLineColor(2);
450  fit_resslope_tracky->SetLineWidth(2);
451  fit_residual_trackdxdz->SetLineColor(2);
452  fit_residual_trackdxdz->SetLineWidth(2);
453  fit_resslope_trackdxdz->SetLineColor(2);
454  fit_resslope_trackdxdz->SetLineWidth(2);
455  fit_residual_trackdydz->SetLineColor(2);
456  fit_residual_trackdydz->SetLineWidth(2);
457  fit_resslope_trackdydz->SetLineColor(2);
458  fit_resslope_trackdydz->SetLineWidth(2);
459 
460  name_residual_trackx += "line";
461  name_resslope_trackx += "line";
462  name_residual_tracky += "line";
463  name_resslope_tracky += "line";
464  name_residual_trackdxdz += "line";
465  name_resslope_trackdxdz += "line";
466  name_residual_trackdydz += "line";
467  name_resslope_trackdydz += "line";
468 
469  TF1 *fitline_residual_trackx =
470  new TF1(name_residual_trackx.c_str(), residual_x_trackx_TF1, min_trackx, max_trackx, 12);
471  TF1 *fitline_resslope_trackx =
472  new TF1(name_resslope_trackx.c_str(), residual_dxdz_trackx_TF1, min_trackx, max_trackx, 12);
473  TF1 *fitline_residual_tracky =
474  new TF1(name_residual_tracky.c_str(), residual_x_tracky_TF1, min_tracky, max_tracky, 12);
475  TF1 *fitline_resslope_tracky =
476  new TF1(name_resslope_tracky.c_str(), residual_dxdz_tracky_TF1, min_tracky, max_tracky, 12);
477  TF1 *fitline_residual_trackdxdz =
478  new TF1(name_residual_trackdxdz.c_str(), residual_x_trackdxdz_TF1, min_trackdxdz, max_trackdxdz, 12);
479  TF1 *fitline_resslope_trackdxdz =
480  new TF1(name_resslope_trackdxdz.c_str(), residual_dxdz_trackdxdz_TF1, min_trackdxdz, max_trackdxdz, 12);
481  TF1 *fitline_residual_trackdydz =
482  new TF1(name_residual_trackdydz.c_str(), residual_x_trackdydz_TF1, min_trackdydz, max_trackdydz, 12);
483  TF1 *fitline_resslope_trackdydz =
484  new TF1(name_resslope_trackdydz.c_str(), residual_dxdz_trackdydz_TF1, min_trackdydz, max_trackdydz, 12);
485 
486  std::vector<TF1 *> fitlines;
487  fitlines.push_back(fitline_residual_trackx);
488  fitlines.push_back(fitline_resslope_trackx);
489  fitlines.push_back(fitline_residual_tracky);
490  fitlines.push_back(fitline_resslope_tracky);
491  fitlines.push_back(fitline_residual_trackdxdz);
492  fitlines.push_back(fitline_resslope_trackdxdz);
493  fitlines.push_back(fitline_residual_trackdydz);
494  fitlines.push_back(fitline_resslope_trackdydz);
495 
496  double fitparameters[12] = {value(kAlignX),
497  0.,
498  value(kAlignZ),
499  value(kAlignPhiX),
500  value(kAlignPhiY),
501  value(kAlignPhiZ),
502  mean_trackx,
503  mean_tracky,
504  mean_trackdxdz,
505  mean_trackdydz,
506  value(kAlpha),
507  mean_resslope};
509  fitparameters[10] = 0.;
510 
511  for (std::vector<TF1 *>::const_iterator itr = fitlines.begin(); itr != fitlines.end(); itr++) {
512  (*itr)->SetParameters(fitparameters);
513  (*itr)->SetLineColor(2);
514  (*itr)->SetLineWidth(2);
515  (*itr)->Write();
516  }
517 
518  for (std::vector<double *>::const_iterator resiter = residuals_begin(); resiter != residuals_end(); ++resiter) {
519  const double resid = (*resiter)[kResid];
520  const double resslope = (*resiter)[kResSlope];
521  const double positionX = (*resiter)[kPositionX];
522  const double positionY = (*resiter)[kPositionY];
523  const double angleX = (*resiter)[kAngleX];
524  const double angleY = (*resiter)[kAngleY];
525  const double redchi2 = (*resiter)[kRedChi2];
526  double weight = 1. / redchi2;
527  if (!m_weightAlignment)
528  weight = 1.;
529 
530  if (!m_weightAlignment || TMath::Prob(redchi2 * 8, 8) < 0.99) { // no spikes allowed
531  hist_alpha->Fill(1000. * resslope, 10. * resid);
532 
533  double coeff = value(kAlpha);
535  coeff = 0.;
536  double geom_resid = residual_x(value(kAlignX),
537  value(kAlignZ),
538  value(kAlignPhiX),
539  value(kAlignPhiY),
540  value(kAlignPhiZ),
541  positionX,
542  positionY,
543  angleX,
544  angleY,
545  coeff,
546  resslope);
547  hist_residual->Fill(10. * (resid - geom_resid + value(kAlignX)), weight);
548  hist_residual_trackx->Fill(positionX, 10. * resid, weight);
549  hist_residual_tracky->Fill(positionY, 10. * resid, weight);
550  hist_residual_trackdxdz->Fill(angleX, 10. * resid, weight);
551  hist_residual_trackdydz->Fill(angleY, 10. * resid, weight);
552  fit_residual_trackx->Fill(positionX, 10. * geom_resid, weight);
553  fit_residual_tracky->Fill(positionY, 10. * geom_resid, weight);
554  fit_residual_trackdxdz->Fill(angleX, 10. * geom_resid, weight);
555  fit_residual_trackdydz->Fill(angleY, 10. * geom_resid, weight);
556 
557  double geom_resslope = residual_dxdz(value(kAlignX),
558  value(kAlignZ),
559  value(kAlignPhiX),
560  value(kAlignPhiY),
561  value(kAlignPhiZ),
562  positionX,
563  positionY,
564  angleX,
565  angleY);
566  hist_resslope->Fill(1000. * (resslope - geom_resslope + value(kAlignPhiY)), weight);
567  hist_resslope_trackx->Fill(positionX, 1000. * resslope, weight);
568  hist_resslope_tracky->Fill(positionY, 1000. * resslope, weight);
569  hist_resslope_trackdxdz->Fill(angleX, 1000. * resslope, weight);
570  hist_resslope_trackdydz->Fill(angleY, 1000. * resslope, weight);
571  fit_resslope_trackx->Fill(positionX, 1000. * geom_resslope, weight);
572  fit_resslope_tracky->Fill(positionY, 1000. * geom_resslope, weight);
573  fit_resslope_trackdxdz->Fill(angleX, 1000. * geom_resslope, weight);
574  fit_resslope_trackdydz->Fill(angleY, 1000. * geom_resslope, weight);
575  }
576 
577  hist_residual_raw->Fill(10. * resid);
578  hist_resslope_raw->Fill(1000. * resslope);
579  if (fabs(resslope) < 0.005)
580  hist_residual_cut->Fill(10. * resid);
581  }
582 
583  double chi2 = 0.;
584  double ndof = 0.;
585  for (int i = 1; i <= hist_residual->GetNbinsX(); i++) {
586  double xi = hist_residual->GetBinCenter(i);
587  double yi = hist_residual->GetBinContent(i);
588  double yerri = hist_residual->GetBinError(i);
589  double yth = fit_residual->Eval(xi);
590  if (yerri > 0.) {
591  chi2 += pow((yth - yi) / yerri, 2);
592  ndof += 1.;
593  }
594  }
595  for (int i = 1; i <= hist_resslope->GetNbinsX(); i++) {
596  double xi = hist_resslope->GetBinCenter(i);
597  double yi = hist_resslope->GetBinContent(i);
598  double yerri = hist_resslope->GetBinError(i);
599  double yth = fit_resslope->Eval(xi);
600  if (yerri > 0.) {
601  chi2 += pow((yth - yi) / yerri, 2);
602  ndof += 1.;
603  }
604  }
605  ndof -= npar();
606 
607  return (ndof > 0. ? chi2 / ndof : -1.);
608 }
609 
611  std::string fname, unsigned int wheel, unsigned int station, unsigned int sector, unsigned int preselected) {
612  TFile *f = new TFile(fname.c_str());
613  TTree *t = (TTree *)f->Get("mual_ttree");
614 
615  // Create new temporary file
616  TFile *tmpf = new TFile("small_tree_fit.root", "recreate");
617  assert(tmpf != nullptr);
618 
619  // filter the tree (temporarily lives in the new file)
620  TTree *tt = t->CopyTree(Form(
621  "is_dt && ring_wheel==%d && station==%d && sector==%d && select==%d", wheel, station, sector, (bool)preselected));
622 
624  tt->SetBranchAddress("res_x", &r.res_x);
625  tt->SetBranchAddress("res_slope_x", &r.res_slope_x);
626  tt->SetBranchAddress("pos_x", &r.pos_x);
627  tt->SetBranchAddress("pos_y", &r.pos_y);
628  tt->SetBranchAddress("angle_x", &r.angle_x);
629  tt->SetBranchAddress("angle_y", &r.angle_y);
630  tt->SetBranchAddress("pz", &r.pz);
631  tt->SetBranchAddress("pt", &r.pt);
632  tt->SetBranchAddress("q", &r.q);
633 
634  Long64_t nentries = tt->GetEntries();
635  for (Long64_t i = 0; i < nentries; i++) {
636  tt->GetEntry(i);
637  double *rdata = new double[MuonResiduals5DOFFitter::kNData];
638  rdata[kResid] = r.res_x;
639  rdata[kResSlope] = r.res_slope_x;
640  rdata[kPositionX] = r.pos_x;
641  rdata[kPositionY] = r.pos_y;
642  rdata[kAngleX] = r.angle_x;
643  rdata[kAngleY] = r.angle_y;
644  rdata[kRedChi2] = 0.1;
645  rdata[kPz] = r.pz;
646  rdata[kPt] = r.pt;
647  rdata[kCharge] = r.q;
648  fill(rdata);
649  }
650  delete f;
651  //delete tmpf;
652  return tt;
653 }
Definition: start.py:1
double MuonResidualsFitter_logGaussPowerTails(double residual, double center, double sigma)
Double_t MuonResidualsFitter_powerLawTails_TF1(Double_t *xvec, Double_t *par)
const AlignableSurface & surface() const
Return the Surface (global position and orientation) of the object.
Definition: Alignable.h:132
double MuonResidualsFitter_logPureGaussian2D(double x, double y, double x0, double y0, double sx, double sy, double r)
double plot(std::string name, TFileDirectory *dir, Alignable *ali) override
std::vector< double * >::const_iterator residuals_begin() const
void fill(double *residual)
align::Scalar width() const
MuonResidualsFitter * fitter()
Definition: weight.py:1
constexpr int pow(int x)
Definition: conifer.h:24
double value(int parNum)
TTree * readNtuple(std::string fname, unsigned int wheel, unsigned int station, unsigned int sector, unsigned int preselected=1)
std::vector< double * >::const_iterator residuals_end() const
assert(be >=bs)
const std::string names[nVars_]
bool dofit(void(*fcn)(int &, double *, double &, double *, int), std::vector< int > &parNum, std::vector< std::string > &parName, std::vector< double > &start, std::vector< double > &step, std::vector< double > &low, std::vector< double > &high)
double MuonResidualsFitter_logROOTVoigt(double residual, double center, double sigma, double gamma)
Definition: TTTypes.h:54
void MuonResiduals5DOFFitter_FCN(int &npar, double *gin, double &fval, double *par, int iflag)
double MuonResidualsFitter_logPowerLawTails(double residual, double center, double sigma, double gamma)
double f[11][100]
Double_t MuonResidualsFitter_GaussPowerTails_TF1(Double_t *xvec, Double_t *par)
void fix(int parNum, bool dofix=true)
virtual void correctBField()=0
Double_t MuonResidualsFitter_pureGaussian_TF1(Double_t *xvec, Double_t *par)
double errorerror(int parNum)
void inform(TMinuit *tMinuit) override
align::Scalar length() const
double b
Definition: hdecay.h:120
int useRes(int pattern=-1)
string fname
main script
double a
Definition: hdecay.h:121
step
Definition: StallMonitor.cc:83
Double_t MuonResidualsFitter_ROOTVoigt_TF1(Double_t *xvec, Double_t *par)
double MuonResidualsFitter_logPureGaussian(double residual, double center, double sigma)
bool fit(Alignable *ali) override