CMS 3D CMS Logo

MuonResidualsPositionFitter.cc
Go to the documentation of this file.
2 
4 
6 
7 void MuonResidualsPositionFitter_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)[MuonResidualsPositionFitter::kResidual];
16  const double angleerror = (*resiter)[MuonResidualsPositionFitter::kAngleError];
17  const double trackangle = (*resiter)[MuonResidualsPositionFitter::kTrackAngle];
18  const double trackposition = (*resiter)[MuonResidualsPositionFitter::kTrackPosition];
19 
20  double center = 0.;
22  center += par[MuonResidualsPositionFitter::kZpos] * trackangle;
23  center += par[MuonResidualsPositionFitter::kPhiz] * trackposition;
24  center += par[MuonResidualsPositionFitter::kScattering] * angleerror;
25 
28  } else if (fitter->residualsModel() == MuonResidualsFitter::kPowerLawTails) {
31  } else if (fitter->residualsModel() == MuonResidualsFitter::kROOTVoigt) {
34  } else if (fitter->residualsModel() == MuonResidualsFitter::kGaussPowerTails) {
36  } else {
37  assert(false);
38  }
39  }
40 }
41 
43  initialize_table(); // if not already initialized
44 
45  double sum_x = 0.;
46  double sum_xx = 0.;
47  int N = 0;
48 
49  for (std::vector<double *>::const_iterator resiter = residuals_begin(); resiter != residuals_end(); ++resiter) {
50  const double residual = (*resiter)[kResidual];
51  // const double angleerror = (*resiter)[kAngleError];
52  // const double trackangle = (*resiter)[kTrackAngle];
53  // const double trackposition = (*resiter)[kTrackPosition];
54 
55  if (fabs(residual) < 10.) { // truncate at 100 mm
56  sum_x += residual;
57  sum_xx += residual * residual;
58  N++;
59  }
60  }
61 
62  if (N < m_minHits)
63  return false;
64 
65  // truncated mean and stdev to seed the fit
66  double mean = sum_x / double(N);
67  double stdev = sqrt(sum_xx / double(N) - pow(sum_x / double(N), 2));
68 
69  // refine the standard deviation calculation
70  sum_x = 0.;
71  sum_xx = 0.;
72  N = 0;
73  for (std::vector<double *>::const_iterator resiter = residuals_begin(); resiter != residuals_end(); ++resiter) {
74  const double residual = (*resiter)[kResidual];
75  if (mean - 1.5 * stdev < residual && residual < mean + 1.5 * stdev) {
76  sum_x += residual;
77  sum_xx += residual * residual;
78  N++;
79  }
80  }
81  mean = sum_x / double(N);
82  stdev = sqrt(sum_xx / double(N) - pow(sum_x / double(N), 2));
83 
84  sum_x = 0.;
85  sum_xx = 0.;
86  N = 0;
87  for (std::vector<double *>::const_iterator resiter = residuals_begin(); resiter != residuals_end(); ++resiter) {
88  const double residual = (*resiter)[kResidual];
89  if (mean - 1.5 * stdev < residual && residual < mean + 1.5 * stdev) {
90  sum_x += residual;
91  sum_xx += residual * residual;
92  N++;
93  }
94  }
95  mean = sum_x / double(N);
96  stdev = sqrt(sum_xx / double(N) - pow(sum_x / double(N), 2));
97 
98  std::vector<int> parNum;
99  std::vector<std::string> parName;
100  std::vector<double> start;
101  std::vector<double> step;
102  std::vector<double> low;
103  std::vector<double> high;
104 
105  parNum.push_back(kPosition);
106  parName.push_back(std::string("position"));
107  start.push_back(mean);
108  step.push_back(0.1);
109  low.push_back(0.);
110  high.push_back(0.);
111  parNum.push_back(kZpos);
112  parName.push_back(std::string("zpos"));
113  start.push_back(0.);
114  step.push_back(0.1);
115  low.push_back(0.);
116  high.push_back(0.);
117  parNum.push_back(kPhiz);
118  parName.push_back(std::string("phiz"));
119  start.push_back(0.);
120  step.push_back(0.1);
121  low.push_back(0.);
122  high.push_back(0.);
123  parNum.push_back(kScattering);
124  parName.push_back(std::string("scattering"));
125  start.push_back(0.);
126  step.push_back(0.1 * 1000.);
127  low.push_back(0.);
128  high.push_back(0.);
129  parNum.push_back(kSigma);
130  parName.push_back(std::string("sigma"));
131  start.push_back(stdev);
132  step.push_back(0.1 * stdev);
133  low.push_back(0.);
134  high.push_back(0.);
136  parNum.push_back(kGamma);
137  parName.push_back(std::string("gamma"));
138  start.push_back(stdev);
139  step.push_back(0.1 * stdev);
140  low.push_back(0.);
141  high.push_back(0.);
142  }
143 
144  return dofit(&MuonResidualsPositionFitter_FCN, parNum, parName, start, step, low, high);
145 }
146 
148  std::stringstream raw_name, narrowed_name, angleerror_name, trackangle_name, trackposition_name;
149  raw_name << name << "_raw";
150  narrowed_name << name << "_narrowed";
151  angleerror_name << name << "_angleerror";
152  trackangle_name << name << "_trackangle";
153  trackposition_name << name << "_trackposition";
154 
155  TH1F *raw_hist =
156  dir->make<TH1F>(raw_name.str().c_str(), (raw_name.str() + std::string(" (mm)")).c_str(), 100, -100., 100.);
157  TH1F *narrowed_hist = dir->make<TH1F>(
158  narrowed_name.str().c_str(), (narrowed_name.str() + std::string(" (mm)")).c_str(), 100, -100., 100.);
159  TProfile *angleerror_hist = dir->make<TProfile>(
160  angleerror_name.str().c_str(), (angleerror_name.str() + std::string(" (mm)")).c_str(), 100, -30., 30.);
161  TProfile *trackangle_hist = dir->make<TProfile>(
162  trackangle_name.str().c_str(), (trackangle_name.str() + std::string(" (mm)")).c_str(), 100, -0.5, 0.5);
163  TProfile *trackposition_hist = dir->make<TProfile>(
164  trackposition_name.str().c_str(), (trackposition_name.str() + std::string(" (mm)")).c_str(), 100, -300., 300.);
165 
166  angleerror_hist->SetAxisRange(-100., 100., "Y");
167  trackangle_hist->SetAxisRange(-10., 10., "Y");
168  trackposition_hist->SetAxisRange(-10., 10., "Y");
169 
170  narrowed_name << "fit";
171  angleerror_name << "fit";
172  trackangle_name << "fit";
173  trackposition_name << "fit";
174 
175  double scale_factor = double(numResiduals()) * (100. - -100.) / 100; // (max - min)/nbins
176 
177  TF1 *narrowed_fit = nullptr;
178  if (residualsModel() == kPureGaussian) {
179  narrowed_fit = new TF1(narrowed_name.str().c_str(), MuonResidualsFitter_pureGaussian_TF1, -100., 100., 3);
180  narrowed_fit->SetParameters(scale_factor, value(kPosition) * 10., value(kSigma) * 10.);
181  narrowed_fit->Write();
182  } else if (residualsModel() == kPowerLawTails) {
183  narrowed_fit = new TF1(narrowed_name.str().c_str(), MuonResidualsFitter_powerLawTails_TF1, -100., 100., 4);
184  narrowed_fit->SetParameters(scale_factor, value(kPosition) * 10., value(kSigma) * 10., value(kGamma) * 10.);
185  narrowed_fit->Write();
186  } else if (residualsModel() == kROOTVoigt) {
187  narrowed_fit = new TF1(narrowed_name.str().c_str(), MuonResidualsFitter_ROOTVoigt_TF1, -100., 100., 4);
188  narrowed_fit->SetParameters(scale_factor, value(kPosition) * 10., value(kSigma) * 10., value(kGamma) * 10.);
189  narrowed_fit->Write();
190  } else if (residualsModel() == kGaussPowerTails) {
191  narrowed_fit = new TF1(narrowed_name.str().c_str(), MuonResidualsFitter_GaussPowerTails_TF1, -100., 100., 3);
192  narrowed_fit->SetParameters(scale_factor, value(kPosition) * 10., value(kSigma) * 10.);
193  narrowed_fit->Write();
194  }
195 
196  TF1 *angleerror_fit = new TF1(angleerror_name.str().c_str(), "[0]+x*[1]", -30., 30.);
197  angleerror_fit->SetParameters(value(kPosition) * 10., value(kScattering) * 10. / 1000.);
198  angleerror_fit->Write();
199 
200  TF1 *trackangle_fit = new TF1(trackangle_name.str().c_str(), "[0]+x*[1]", -0.5, 0.5);
201  trackangle_fit->SetParameters(value(kPosition) * 10., value(kZpos) * 10.);
202  trackangle_fit->Write();
203 
204  TF1 *trackposition_fit = new TF1(trackposition_name.str().c_str(), "[0]+x*[1]", -300., 300.);
205  trackposition_fit->SetParameters(value(kPosition) * 10., value(kPhiz) * 10.);
206  trackposition_fit->Write();
207 
208  for (std::vector<double *>::const_iterator resiter = residuals_begin(); resiter != residuals_end(); ++resiter) {
209  const double raw_residual = (*resiter)[kResidual];
210  const double angleerror = (*resiter)[kAngleError];
211  const double trackangle = (*resiter)[kTrackAngle];
212  const double trackposition = (*resiter)[kTrackPosition];
213 
214  double angleerror_correction = value(kScattering) * angleerror;
215  double trackangle_correction = value(kZpos) * trackangle;
216  double trackposition_correction = value(kPhiz) * trackposition;
217 
218  double corrected_residual = raw_residual - angleerror_correction - trackangle_correction - trackposition_correction;
219 
220  raw_hist->Fill(raw_residual * 10.);
221  narrowed_hist->Fill(corrected_residual * 10.);
222 
223  angleerror_hist->Fill(angleerror * 1000., (raw_residual - trackangle_correction - trackposition_correction) * 10.);
224  trackangle_hist->Fill(trackangle, (raw_residual - angleerror_correction - trackposition_correction) * 10.);
225  trackposition_hist->Fill(trackposition, (raw_residual - angleerror_correction - trackangle_correction) * 10.);
226  }
227 
228  return 0.;
229 }
Definition: start.py:1
double MuonResidualsFitter_logGaussPowerTails(double residual, double center, double sigma)
Double_t MuonResidualsFitter_powerLawTails_TF1(Double_t *xvec, Double_t *par)
void MuonResidualsPositionFitter_FCN(int &npar, double *gin, double &fval, double *par, int iflag)
std::vector< double * >::const_iterator residuals_begin() const
MuonResidualsFitter * fitter()
constexpr int pow(int x)
Definition: conifer.h:24
double value(int parNum)
static TMinuit * MuonResidualsPositionFitter_TMinuit
std::vector< double * >::const_iterator residuals_end() const
assert(be >=bs)
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)
double plot(std::string name, TFileDirectory *dir, 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)
Double_t MuonResidualsFitter_pureGaussian_TF1(Double_t *xvec, Double_t *par)
#define N
Definition: blowfish.cc:9
void inform(TMinuit *tMinuit) override
def stdev(xlist)
Definition: plotscripts.py:69
step
Definition: StallMonitor.cc:83
Double_t MuonResidualsFitter_ROOTVoigt_TF1(Double_t *xvec, Double_t *par)
bool fit(Alignable *ali) override
double MuonResidualsFitter_logPureGaussian(double residual, double center, double sigma)