CMS 3D CMS Logo

MuonResidualsAngleFitter.cc
Go to the documentation of this file.
2 
4 
6 
7 void MuonResidualsAngleFitter_FCN(int &npar, double *gin, double &fval, double *par, int iflag) {
10  MuonResidualsFitter *fitter = fitinfo->fitter();
11 
12  fval = 0.;
13  for (std::vector<double *>::const_iterator resiter = fitter->residuals_begin(); resiter != fitter->residuals_end();
14  ++resiter) {
15  const double residual = (*resiter)[MuonResidualsAngleFitter::kResidual];
16  const double xangle = (*resiter)[MuonResidualsAngleFitter::kXAngle];
17  const double yangle = (*resiter)[MuonResidualsAngleFitter::kYAngle];
18 
19  double center = 0.;
20  center += par[MuonResidualsAngleFitter::kAngle];
21  center += par[MuonResidualsAngleFitter::kXControl] * xangle;
22  center += par[MuonResidualsAngleFitter::kYControl] * yangle;
23 
26  } else if (fitter->residualsModel() == MuonResidualsFitter::kPowerLawTails) {
29  } else if (fitter->residualsModel() == MuonResidualsFitter::kROOTVoigt) {
32  } else if (fitter->residualsModel() == MuonResidualsFitter::kGaussPowerTails) {
34  } else {
35  assert(false);
36  }
37  }
38 }
39 
41  initialize_table(); // if not already initialized
42 
43  double sum_x = 0.;
44  double sum_xx = 0.;
45  int N = 0;
46 
47  for (std::vector<double *>::const_iterator resiter = residuals_begin(); resiter != residuals_end(); ++resiter) {
48  const double residual = (*resiter)[kResidual];
49  // const double xangle = (*resiter)[kXAngle];
50  // const double yangle = (*resiter)[kYAngle];
51 
52  if (fabs(residual) < 0.1) { // truncate at 100 mrad
53  sum_x += residual;
54  sum_xx += residual * residual;
55  N++;
56  }
57  }
58 
59  if (N < m_minHits)
60  return false;
61 
62  // truncated mean and stdev to seed the fit
63  double mean = sum_x / double(N);
64  double stdev = sqrt(sum_xx / double(N) - pow(sum_x / double(N), 2));
65 
66  // refine the standard deviation calculation
67  sum_x = 0.;
68  sum_xx = 0.;
69  N = 0;
70  for (std::vector<double *>::const_iterator resiter = residuals_begin(); resiter != residuals_end(); ++resiter) {
71  const double residual = (*resiter)[kResidual];
72  if (mean - 1.5 * stdev < residual && residual < mean + 1.5 * stdev) {
73  sum_x += residual;
74  sum_xx += residual * residual;
75  N++;
76  }
77  }
78  mean = sum_x / double(N);
79  stdev = sqrt(sum_xx / double(N) - pow(sum_x / double(N), 2));
80 
81  sum_x = 0.;
82  sum_xx = 0.;
83  N = 0;
84  for (std::vector<double *>::const_iterator resiter = residuals_begin(); resiter != residuals_end(); ++resiter) {
85  const double residual = (*resiter)[kResidual];
86  if (mean - 1.5 * stdev < residual && residual < mean + 1.5 * stdev) {
87  sum_x += residual;
88  sum_xx += residual * residual;
89  N++;
90  }
91  }
92  mean = sum_x / double(N);
93  stdev = sqrt(sum_xx / double(N) - pow(sum_x / double(N), 2));
94 
95  std::vector<int> parNum;
96  std::vector<std::string> parName;
97  std::vector<double> start;
98  std::vector<double> step;
99  std::vector<double> low;
100  std::vector<double> high;
101 
102  parNum.push_back(kAngle);
103  parName.push_back(std::string("angle"));
104  start.push_back(mean);
105  step.push_back(0.1);
106  low.push_back(0.);
107  high.push_back(0.);
108  parNum.push_back(kXControl);
109  parName.push_back(std::string("xcontrol"));
110  start.push_back(0.);
111  step.push_back(0.1);
112  low.push_back(0.);
113  high.push_back(0.);
114  parNum.push_back(kYControl);
115  parName.push_back(std::string("ycontrol"));
116  start.push_back(0.);
117  step.push_back(0.1);
118  low.push_back(0.);
119  high.push_back(0.);
120  parNum.push_back(kSigma);
121  parName.push_back(std::string("sigma"));
122  start.push_back(stdev);
123  step.push_back(0.1 * stdev);
124  low.push_back(0.);
125  high.push_back(0.);
127  parNum.push_back(kGamma);
128  parName.push_back(std::string("gamma"));
129  start.push_back(stdev);
130  step.push_back(0.1 * stdev);
131  low.push_back(0.);
132  high.push_back(0.);
133  }
134 
135  return dofit(&MuonResidualsAngleFitter_FCN, parNum, parName, start, step, low, high);
136 }
137 
139  std::stringstream raw_name, narrowed_name, xcontrol_name, ycontrol_name;
140  raw_name << name << "_raw";
141  narrowed_name << name << "_narrowed";
142  xcontrol_name << name << "_xcontrol";
143  ycontrol_name << name << "_ycontrol";
144 
145  TH1F *raw_hist =
146  dir->make<TH1F>(raw_name.str().c_str(), (raw_name.str() + std::string(" (mrad)")).c_str(), 100, -100., 100.);
147  TH1F *narrowed_hist = dir->make<TH1F>(
148  narrowed_name.str().c_str(), (narrowed_name.str() + std::string(" (mrad)")).c_str(), 100, -100., 100.);
149  TProfile *xcontrol_hist = dir->make<TProfile>(
150  xcontrol_name.str().c_str(), (xcontrol_name.str() + std::string(" (mrad)")).c_str(), 100, -1., 1.);
151  TProfile *ycontrol_hist = dir->make<TProfile>(
152  ycontrol_name.str().c_str(), (ycontrol_name.str() + std::string(" (mrad)")).c_str(), 100, -1., 1.);
153 
154  narrowed_name << "fit";
155  xcontrol_name << "fit";
156  ycontrol_name << "fit";
157 
158  double scale_factor = double(numResiduals()) * (100. - -100.) / 100; // (max - min)/nbins
159 
160  TF1 *narrowed_fit = nullptr;
161  if (residualsModel() == kPureGaussian) {
162  narrowed_fit = new TF1(narrowed_name.str().c_str(), MuonResidualsFitter_pureGaussian_TF1, -100., 100., 3);
163  narrowed_fit->SetParameters(scale_factor, value(kAngle) * 1000., value(kSigma) * 1000.);
164  narrowed_fit->Write();
165  } else if (residualsModel() == kPowerLawTails) {
166  narrowed_fit = new TF1(narrowed_name.str().c_str(), MuonResidualsFitter_powerLawTails_TF1, -100., 100., 4);
167  narrowed_fit->SetParameters(scale_factor, value(kAngle) * 1000., value(kSigma) * 1000., value(kGamma) * 1000.);
168  narrowed_fit->Write();
169  } else if (residualsModel() == kROOTVoigt) {
170  narrowed_fit = new TF1(narrowed_name.str().c_str(), MuonResidualsFitter_ROOTVoigt_TF1, -100., 100., 4);
171  narrowed_fit->SetParameters(scale_factor, value(kAngle) * 1000., value(kSigma) * 1000., value(kGamma) * 1000.);
172  narrowed_fit->Write();
173  } else if (residualsModel() == kGaussPowerTails) {
174  narrowed_fit = new TF1(narrowed_name.str().c_str(), MuonResidualsFitter_GaussPowerTails_TF1, -100., 100., 3);
175  narrowed_fit->SetParameters(scale_factor, value(kAngle) * 1000., value(kSigma) * 1000.);
176  narrowed_fit->Write();
177  }
178 
179  TF1 *xcontrol_fit = new TF1(xcontrol_name.str().c_str(), "[0]+x*[1]", -1., 1.);
180  xcontrol_fit->SetParameters(value(kAngle) * 1000., value(kXControl) * 1000.);
181  xcontrol_fit->Write();
182 
183  TF1 *ycontrol_fit = new TF1(ycontrol_name.str().c_str(), "[0]+x*[1]", -1., 1.);
184  ycontrol_fit->SetParameters(value(kAngle) * 1000., value(kYControl) * 1000.);
185  ycontrol_fit->Write();
186 
187  for (std::vector<double *>::const_iterator resiter = residuals_begin(); resiter != residuals_end(); ++resiter) {
188  const double raw_residual = (*resiter)[kResidual];
189  const double xangle = (*resiter)[kXAngle];
190  const double yangle = (*resiter)[kYAngle];
191 
192  double xangle_correction = value(kXControl) * xangle;
193  double yangle_correction = value(kYControl) * yangle;
194  double corrected_residual = raw_residual - xangle_correction - yangle_correction;
195 
196  raw_hist->Fill(raw_residual * 1000.);
197  narrowed_hist->Fill(corrected_residual * 1000.);
198 
199  xcontrol_hist->Fill(xangle, (raw_residual - yangle_correction) * 1000.);
200  ycontrol_hist->Fill(yangle, (raw_residual - xangle_correction) * 1000.);
201  }
202 
203  return 0.;
204 }
double MuonResidualsFitter_logGaussPowerTails(double residual, double center, double sigma)
std::vector< double * >::const_iterator residuals_begin() const
Double_t MuonResidualsFitter_powerLawTails_TF1(Double_t *xvec, Double_t *par)
MuonResidualsFitter * fitter()
double value(int parNum)
double plot(std::string name, TFileDirectory *dir, Alignable *ali) override
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)
bool fit(Alignable *ali) override
T sqrt(T t)
Definition: SSEVec.h:19
double MuonResidualsFitter_logPowerLawTails(double residual, double center, double sigma, double gamma)
Double_t MuonResidualsFitter_GaussPowerTails_TF1(Double_t *xvec, Double_t *par)
T * make(const Args &...args) const
make new ROOT object
Double_t MuonResidualsFitter_pureGaussian_TF1(Double_t *xvec, Double_t *par)
#define N
Definition: blowfish.cc:9
std::vector< double * >::const_iterator residuals_end() const
void MuonResidualsAngleFitter_FCN(int &npar, double *gin, double &fval, double *par, int iflag)
void inform(TMinuit *tMinuit) override
def stdev(xlist)
Definition: plotscripts.py:69
step
Definition: StallMonitor.cc:94
Double_t MuonResidualsFitter_ROOTVoigt_TF1(Double_t *xvec, Double_t *par)
static TMinuit * MuonResidualsAngleFitter_TMinuit
double MuonResidualsFitter_logPureGaussian(double residual, double center, double sigma)
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:30