Belle II Software  release-08-01-10
ModuleAlignment.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <top/reconstruction_cpp/ModuleAlignment.h>
10 #include <Math/RotationX.h>
11 #include <Math/RotationY.h>
12 #include <Math/RotationZ.h>
13 #include <Math/Translation3D.h>
14 #include <Math/Transform3D.h>
15 #include <TDecompChol.h>
16 
17 
18 namespace Belle2 {
23  namespace TOP {
24 
26  {
27  m_parNames.push_back("x");
28  m_parNames.push_back("y");
29  m_parNames.push_back("z");
30  m_parNames.push_back("alpha");
31  m_parNames.push_back("beta");
32  m_parNames.push_back("gamma");
33  m_parNames.push_back("t0");
34  unsigned numPar = m_parNames.size();
35  m_parInit.resize(numPar, 0);
36  m_par = m_parInit;
37  m_steps.resize(numPar, 0);
38  m_fixed.resize(numPar, false);
39  m_COV.ResizeTo(numPar, numPar);
40  m_U.ResizeTo(numPar, numPar);
41  setSteps(1.0, 0.01, 0.05);
42  }
43 
44  void ModuleAlignment::setSteps(double position, double angle, double time)
45  {
46  m_steps[0] = position;
47  m_steps[1] = position;
48  m_steps[2] = position;
49  m_steps[3] = angle;
50  m_steps[4] = angle;
51  m_steps[5] = angle;
52  m_steps[6] = time;
54  }
55 
57  {
58  m_numPhotons = 0;
59  if (track.getModuleID() != m_moduleID) return -2;
60 
61  m_track = &track;
62  m_hypothesis = hypothesis;
63 
64  std::vector<double> first(m_par.size(), 0);
65  TMatrixDSym second(m_par.size());
66  if (not derivatives(first, second)) return -1;
67 
68  m_U -= second;
69  m_numTracks++;
70 
71  int ier = invertMatrixU();
72  if (ier != 0) return ier;
73 
74  std::vector<double> dpar(m_par.size(), 0);
75  for (size_t i = 0; i < dpar.size(); i++) {
76  for (size_t k = 0; k < dpar.size(); k++) {
77  dpar[i] += m_COV[i][k] * first[k];
78  }
79  if (fabs(dpar[i]) > m_maxDpar[i]) return ier;
80  }
81 
82  for (size_t i = 0; i < dpar.size(); i++) {
83  m_par[i] += dpar[i];
84  }
86  m_valid = true;
87 
88  return 0;
89  }
90 
92  {
93  m_par = m_parInit;
94  m_COV.Zero();
95  m_U.Zero();
96  m_numTracks = 0;
97  m_numUsedTracks = 0;
98  m_valid = false;
99  m_numPhotons = 0;
100  }
101 
102  std::vector<float> ModuleAlignment::getParameters() const
103  {
104  std::vector<float> pars;
105  for (auto par : m_par) pars.push_back(par);
106  return pars;
107  }
108 
109  std::vector<float> ModuleAlignment::getErrors() const
110  {
111  std::vector<float> errors;
112  int numPar = m_par.size();
113  for (int i = 0; i < numPar; i++) {
114  errors.push_back(sqrt(m_COV[i][i]));
115  }
116  return errors;
117  }
118 
119  double ModuleAlignment::getLogL(const std::vector<double>& par, bool& ok)
120  {
121  ROOT::Math::Translation3D t(par[0], par[1], par[2]);
122  ROOT::Math::RotationX Rx(par[3]);
123  ROOT::Math::RotationY Ry(par[4]);
124  ROOT::Math::RotationZ Rz(par[5]);
125  ROOT::Math::Transform3D T(Rz * Ry * Rx, t);
127  if (not ok) return 0;
128 
129  PDFConstructor pdfConstructor(*m_track, m_hypothesis, m_opt);
130  if (not pdfConstructor.isValid()) {
131  ok = false;
132  return 0;
133  }
134 
135  auto LL = pdfConstructor.getLogL(par[6]);
136  m_numPhotons = LL.numPhotons;
137 
138  return LL.logL;
139  }
140 
141  bool ModuleAlignment::derivatives(std::vector<double>& first, TMatrixDSym& second)
142  {
143  bool ok = false;
144  double f0 = getLogL(m_par, ok);
145  if (not ok) return false;
146 
147  auto par = m_par;
148  for (size_t k = 0; k < par.size(); k++) {
149  if (m_fixed[k]) continue;
150 
151  par[k] = m_par[k] + m_steps[k];
152  double fp = getLogL(par, ok);
153  if (not ok) return false;
154 
155  par[k] = m_par[k] - m_steps[k];
156  double fm = getLogL(par, ok);
157  if (not ok) return false;
158 
159  first[k] = (fp - fm) / 2 / m_steps[k];
160  second[k][k] = (fp - 2 * f0 + fm) / pow(m_steps[k], 2);
161 
162  par[k] = m_par[k];
163  }
164 
165  for (size_t k = 0; k < par.size(); k++) {
166  if (m_fixed[k]) continue;
167  for (size_t j = k + 1; j < par.size(); j++) {
168  if (m_fixed[j]) continue;
169 
170  par[k] = m_par[k] + m_steps[k];
171  par[j] = m_par[j] + m_steps[j];
172  double fpp = getLogL(par, ok);
173  if (not ok) return false;
174 
175  par[j] = m_par[j] - m_steps[j];
176  double fpm = getLogL(par, ok);
177  if (not ok) return false;
178 
179  par[k] = m_par[k] - m_steps[k];
180  par[j] = m_par[j] + m_steps[j];
181  double fmp = getLogL(par, ok);
182  if (not ok) return false;
183 
184  par[j] = m_par[j] - m_steps[j];
185  double fmm = getLogL(par, ok);
186  if (not ok) return false;
187 
188  second[j][k] = second[k][j] = (fpp - fmp - fpm + fmm) / 4 / m_steps[k] / m_steps[j];
189 
190  par[j] = m_par[j];
191  }
192  par[k] = m_par[k];
193  }
194 
195  return true;
196  }
197 
199  {
200  int n = 0;
201  for (auto fixed : m_fixed) {
202  if (not fixed) n++;
203  }
204 
205  TMatrixDSym A(n);
206  int ii = 0;
207  for (int i = 0; i < m_U.GetNrows(); i++) {
208  if (m_fixed[i]) continue;
209  int kk = 0;
210  for (int k = 0; k < m_U.GetNrows(); k++) {
211  if (m_fixed[k]) continue;
212  A[ii][kk] = m_U[i][k];
213  kk++;
214  }
215  ii++;
216  }
217 
218  TDecompChol chol(A);
219  if (not chol.Decompose()) return 1;
220  chol.Invert(A);
221 
222  ii = 0;
223  for (int i = 0; i < m_U.GetNrows(); i++) {
224  if (m_fixed[i]) continue;
225  int kk = 0;
226  for (int k = 0; k < m_U.GetNrows(); k++) {
227  if (m_fixed[k]) continue;
228  m_COV[i][k] = A[ii][kk];
229  kk++;
230  }
231  ii++;
232  }
233 
234  return 0;
235  }
236 
237  } // end top namespace
239 } // end Belle2 namespace
240 
241 
Provides a type-safe way to pass members of the chargedStableSet set.
Definition: Const.h:580
int m_numUsedTracks
number of tracks used
TMatrixDSym m_U
matrix (neg.
bool derivatives(std::vector< double > &first, TMatrixDSym &second)
Calculates numerically first and second derivatives of log likelihood against the parameters.
TMatrixDSym m_COV
covariance matrix
std::vector< double > m_steps
step sizes
int m_numPhotons
number of photons used for log likelihood calculation
std::vector< bool > m_fixed
true if parameter is fixed
std::vector< std::string > m_parNames
parameter names
std::vector< float > getParameters() const
Returns alignment parameters.
std::vector< double > m_par
current parameter values
double getLogL(const std::vector< double > &par, bool &ok)
Returns log likelihood for given parameters Note: it changes helix parameters of TOPTrack object (m_t...
Const::ChargedStable m_hypothesis
particle hypothesis
bool m_valid
validity of results
void setSteps(double position, double angle, double time)
Sets steps for numerical calculation of derivatives.
int iterate(TOPTrack &track, const Const::ChargedStable &hypothesis)
Run a single alignment iteration, on success update alignment parameters.
std::vector< double > m_parInit
initial parameter values
int invertMatrixU()
Inverts matrix m_U using Cholesky decomposition.
std::vector< double > m_maxDpar
maximal parameter changes in one iteration
std::vector< float > getErrors() const
Returns errors on alignment parameters.
void reset()
Reset the object.
ModuleAlignment(PDFConstructor::EPDFOption opt=PDFConstructor::c_Rough)
Constructor.
TOPTrack * m_track
track parameters at TOP
PDFConstructor::EPDFOption m_opt
PDF option.
PDF construction and log likelihood determination for a given track and particle hypothesis.
LogL getLogL() const
Returns extended log likelihood (using the default time window)
bool isValid() const
Checks the object status.
EPDFOption
Signal PDF construction options.
Reconstructed track at TOP.
Definition: TOPTrack.h:39
bool overrideTransformation(const ROOT::Math::Transform3D &transform)
Overrides transformation from local to nominal frame, which is by default obtained from DB.
Definition: TOPTrack.h:127
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.