Jpp  18.0.0-rc.1
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JLine1ZEstimator.hh
Go to the documentation of this file.
1 #ifndef __JFIT__JLINE1ZESTIMATOR__
2 #define __JFIT__JLINE1ZESTIMATOR__
3 
4 #include "JPhysics/JConstants.hh"
5 #include "JMath/JMatrix3S.hh"
6 #include "JMath/JSVD3D.hh"
7 #include "JFit/JMatrixNZ.hh"
8 #include "JFit/JLine1Z.hh"
9 #include "JFit/JEstimator.hh"
10 
11 
12 
13 /**
14  * \file
15  * Linear fit of JFIT::JLine1Z.
16  * \author mdejong
17  */
18 namespace JFIT {}
19 namespace JPP { using namespace JFIT; }
20 
21 namespace JFIT {
22 
23  /**
24  * Linear fit of straight line parallel to z-axis to set of hits (objects with position and time).
25  *
26  \f{center}\setlength{\unitlength}{0.7cm}\begin{picture}(8,12)
27 
28  \put( 1.0, 0.5){\vector(0,1){9}}
29  \put( 1.0,10.0){\makebox(0,0){$z$}}
30  \put( 1.0, 0.0){\makebox(0,0){muon}}
31 
32  \put( 1.0, 8.0){\line(1,0){6}}
33  \put( 4.0, 8.5){\makebox(0,0)[c]{$R$}}
34 
35  \multiput( 1.0, 2.0)(0.5, 0.5){12}{\qbezier(0.0,0.0)(-0.1,0.35)(0.25,0.25)\qbezier(0.25,0.25)(0.6,0.15)(0.5,0.5)}
36  \put( 4.5, 4.5){\makebox(0,0)[l]{photon}}
37 
38  \put( 1.0, 2.0){\circle*{0.2}}
39  \put( 0.5, 2.0){\makebox(0,0)[r]{$(x_{0},y_{0},z_{0},t_{0})$}}
40 
41  \put( 1.0, 8.0){\circle*{0.2}}
42  \put( 0.5, 8.0){\makebox(0,0)[r]{$(x_{0},y_{0},z_{j})$}}
43 
44  \put( 7.0, 8.0){\circle*{0.2}}
45  \put( 7.0, 9.0){\makebox(0,0)[c]{PMT}}
46  \put( 7.5, 8.0){\makebox(0,0)[l]{$(x_{j},y_{j},z_{j},t_{j})$}}
47 
48  \put( 1.1, 2.1){
49  \put(0.0,1.00){\vector(-1,0){0.1}}
50  \qbezier(0.0,1.0)(0.25,1.0)(0.5,0.75)
51  \put(0.5,0.75){\vector(1,-1){0.1}}
52  \put(0.4,1.5){\makebox(0,0){$\theta_{c}$}}
53  }
54 
55  \end{picture}
56  \f}
57 
58  \f[
59  ct_j = ct_0 + (z_j - z_0) + \tan(\theta_{c}) \sqrt((x_j - x_0)^2 + (y_j - y_0)^2)
60  \f]
61  *
62  * where:
63  *
64  \f{eqnarray*}{
65  x_0 & = & \textrm{x position of track (fit parameter)} \\
66  y_0 & = & \textrm{y position of track (fit parameter)} \\
67  z_0 & = & \textrm{z position of track} \\
68  t_0 & = & \textrm{time of track at } z = z_0 \textrm{ (fit parameter)} \\
69  \\
70  c & = & \textrm{speed of light in vacuum} \\
71  \theta_{c} & = & \textrm{Cherenkov angle} \\
72  \f}
73  *
74  * Defining:
75  *
76  \f{eqnarray*}{
77  t_j' & \equiv & ct_j / \tan(\theta_{c}) - (z_j - z_0)/\tan(\theta_{c}) \\
78  t_0' & \equiv & ct_0 / \tan(\theta_{c}) \\
79  \f}
80  *
81  \f[
82  \Rightarrow (t_j' - t_0')^2 = (x_j - x_0)^2 + (y_j - y_0)^2
83  \f]
84  *
85  * The parameters \f$ \{x_0, y_0, t_0\} \f$ are estimated in the constructor of this class based on
86  * consecutive pairs of equations by which the quadratic terms in \f$ x_0 \f$, \f$ y_0 \f$ and \f$ t_0 \f$ are eliminated.
87  */
88  template<>
89  class JEstimator<JLine1Z> :
90  public JLine1Z
91  {
92  public:
93  /**
94  * Default constructor.
95  */
97  JLine1Z()
98  {}
99 
100 
101  /**
102  * Constructor.
103  *
104  * \param __begin begin of data
105  * \param __end end of data
106  */
107  template<class T>
108  JEstimator(T __begin, T __end) :
109  JLine1Z()
110  {
111  (*this)(__begin, __end);
112  }
113 
114 
115  /**
116  * Fit.
117  *
118  * The template argument <tt>T</tt> refers to an iterator of a data structure which should have the following member methods:
119  * - double %getX(); // [m]
120  * - double %getY(); // [m]
121  * - double %getZ(); // [m]
122  * - double %getT(); // [ns]
123  *
124  * \param __begin begin of data
125  * \param __end end of data
126  */
127  template<class T>
128  const JEstimator<JLine1Z>& operator()(T __begin, T __end)
129  {
130  using namespace std;
131  using namespace JPP;
132 
133  const int N = distance(__begin, __end);
134 
135  if (N >= NUMBER_OF_PARAMETERS) {
136 
137  __x = 0.0;
138  __y = 0.0;
139  __z = 0.0;
140  __t = 0.0;
141 
142  double t0 = 0.0;
143 
144  for (T i = __begin; i != __end; ++i) {
145  __x += i->getX();
146  __y += i->getY();
147  __z += i->getZ();
148  t0 += i->getT();
149  }
150 
151  const double W = 1.0/N;
152 
153  __x *= W;
154  __y *= W;
155  __z *= W;
156  t0 *= W;
157 
158  V.reset();
159 
160  t0 *= getSpeedOfLight();
161 
162  double y0 = 0.0;
163  double y1 = 0.0;
164  double y2 = 0.0;
165 
166  T j = __begin;
167 
168  double xi = j->getX() - getX();
169  double yi = j->getY() - getY();
170  double ti = (j->getT() * getSpeedOfLight() - t0 - j->getZ() + getZ()) / getKappaC();
171 
172  for (bool done = false; !done; ) {
173 
174  if ((done = (++j == __end))) {
175  j = __begin;
176  }
177 
178  double xj = j->getX() - getX();
179  double yj = j->getY() - getY();
180  double tj = (j->getT() * getSpeedOfLight() - t0 - j->getZ() + getZ()) / getKappaC();
181 
182  double dx = xj - xi;
183  double dy = yj - yi;
184  double dt = ti - tj; // opposite sign!
185 
186  const double y = ((xj + xi) * dx +
187  (yj + yi) * dy +
188  (tj + ti) * dt);
189 
190  dx *= 2;
191  dy *= 2;
192  dt *= 2;
193 
194  V.a00 += dx * dx;
195  V.a01 += dx * dy;
196  V.a02 += dx * dt;
197  V.a11 += dy * dy;
198  V.a12 += dy * dt;
199  V.a22 += dt * dt;
200 
201  y0 += dx * y;
202  y1 += dy * y;
203  y2 += dt * y;
204 
205  xi = xj;
206  yi = yj;
207  ti = tj;
208  }
209 
210  t0 *= getInverseSpeedOfLight();
211 
212  V.a10 = V.a01;
213  V.a20 = V.a02;
214  V.a21 = V.a12;
215 
216  svd.decompose(V);
217 
218  if (fabs(svd.S.a11) < MINIMAL_SVD_WEIGHT * fabs(svd.S.a00)) {
219  THROW(JValueOutOfRange, "JEstimator<JLine1Z>::JEstimator(): singular value " << svd.S.a11 << ' ' << svd.S.a00);
220  }
221 
222  V = svd.invert(MINIMAL_SVD_WEIGHT);
223 
224  __x += V.a00 * y0 + V.a01 * y1 + V.a02 * y2;
225  __y += V.a10 * y0 + V.a11 * y1 + V.a12 * y2;
226  __t = V.a20 * y0 + V.a21 * y1 + V.a22 * y2;
227 
228  __t *= getKappaC() * getInverseSpeedOfLight();
229  __t += t0;
230 
231  } else {
232  throw JValueOutOfRange("JEstimator<JLine1Z>::JEstimator(): Not enough data points.");
233  }
234 
235  return *this;
236  }
237 
238 
239  /**
240  * Update track parameters using updated co-variance matrix (e.g.\ matrix with one hit switched off).
241  *
242  * In this, it is assumed that the changes in x and y positions are small
243  * compared to the actual distances between the track and the hits.
244  *
245  * The template argument <tt>T</tt> refers to an iterator of a data structure which should have the following member methods:
246  * - double %getX(); // [m]
247  * - double %getY(); // [m]
248  * - double %getZ(); // [m]
249  * - double %getT(); // [ns]
250  *
251  * \param __begin begin of data
252  * \param __end end of data
253  * \param A co-variance matrix of hits
254  */
255  template<class T>
256  void update(T __begin, T __end, const JMatrixNZ& A)
257  {
258  using namespace std;
259  using namespace JPP;
260 
261  const int N = distance(__begin, __end);
262 
263  if (N != (int) A.size()) {
264  THROW(JValueOutOfRange, "JEstimator<JLine1Z>::update(): Wrong number of points " << N << " != " << A.size());
265  }
266 
267  if (N >= NUMBER_OF_PARAMETERS) {
268 
269  double x1 = 0.0;
270  double y1 = 0.0;
271  double t1 = 0.0;
272 
273  V.reset();
274 
275  T i = __begin;
276 
277  for (size_t row = 0; row != A.size(); ++row, ++i) {
278 
279  const double dx = i->getX() - getX();
280  const double dy = i->getY() - getY();
281 
282  const double rt = sqrt(dx*dx + dy*dy);
283 
284  double xr = getKappaC() * getInverseSpeedOfLight();
285  double yr = getKappaC() * getInverseSpeedOfLight();
286  double tr = 1.0;
287 
288  if (rt != 0.0) {
289  xr *= -dx / rt;
290  yr *= -dy / rt;
291  }
292 
293  T j = __begin;
294 
295  for (size_t col = 0; col != A.size(); ++col, ++j) {
296 
297  const double dx = j->getX() - getX();
298  const double dy = j->getY() - getY();
299  const double dz = j->getZ() - getZ();
300 
301  const double rt = sqrt(dx*dx + dy*dy);
302 
303  double xc = getKappaC() * getInverseSpeedOfLight();
304  double yc = getKappaC() * getInverseSpeedOfLight();
305  double tc = 1.0;
306 
307  if (rt != 0.0) {
308  xc *= -dx / rt;
309  yc *= -dy / rt;
310  }
311 
312  const double ts = j->getT() - (dz + rt * getKappaC()) * getInverseSpeedOfLight();
313 
314  const double vs = A(row,col);
315 
316  x1 += xr * vs * ts;
317  y1 += yr * vs * ts;
318  t1 += tr * vs * ts;
319 
320  V.a00 += xr * vs * xc;
321  V.a01 += xr * vs * yc;
322  V.a02 += xr * vs * tc;
323  V.a11 += yr * vs * yc;
324  V.a12 += yr * vs * tc;
325  V.a22 += tr * vs * tc;
326  }
327  }
328 
329  V.a10 = V.a01;
330  V.a20 = V.a02;
331  V.a21 = V.a12;
332 
333  svd.decompose(V);
334 
335  if (fabs(svd.S.a11) < MINIMAL_SVD_WEIGHT * fabs(svd.S.a00)) {
336  THROW(JValueOutOfRange, "JEstimator<JLine1Z>::update(): singular value " << svd.S.a11 << ' ' << svd.S.a00);
337  }
338 
339  V = svd.invert(MINIMAL_SVD_WEIGHT);
340 
341  __x += V.a00 * x1 + V.a01 * y1 + V.a02 * t1;
342  __y += V.a10 * x1 + V.a11 * y1 + V.a12 * t1;
343  __t = V.a20 * x1 + V.a21 * y1 + V.a22 * t1;
344 
345  } else {
346  THROW(JValueOutOfRange, "JEstimator<JLine1Z>::update(): Not enough data points " << N);
347  }
348  }
349 
350 
351  static const int NUMBER_OF_PARAMETERS = 3; //!< number of parameters of fit
352  JMATH::JMatrix3S V; //!< co-variance matrix of fit parameters
354  static double MINIMAL_SVD_WEIGHT; //!< minimal SVD weight.
355  };
356 
357  /**
358  * Set default minimal SVD weight.
359  */
361 }
362 
363 #endif
Linear fit methods.
Linear fit of straight line parallel to z-axis to set of hits (objects with position and time)...
double getKappaC()
Get average R-dependence of arrival time of Cherenkov light (a.k.a.
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:696
JEstimator()
Default constructor.
Template definition of linear fit.
Definition: JEstimator.hh:25
V(JDAQEvent-JTriggerReprocessor)*1.0/(JDAQEvent+1.0e-10)
JEstimator(T __begin, T __end)
Constructor.
3 x 3 symmetric matrix
Definition: JMatrix3S.hh:29
std::vector< double > vs
Determination of the co-variance matrix of hits for a track along z-axis (JFIT::JLine1Z).
Definition: JMatrixNZ.hh:28
void update(T __begin, T __end, const JMatrixNZ &A)
Update track parameters using updated co-variance matrix (e.g. matrix with one hit switched off)...
do set_variable OUTPUT_DIRECTORY $WORKDIR T
const JEstimator< JLine1Z > & operator()(T __begin, T __end)
Fit.
Singular value decomposition.
Definition: JSVD3D.hh:27
Physics constants.
JMATH::JMatrix3S V
co-variance matrix of fit parameters
size_t size() const
Get dimension of matrix.
Definition: JMatrixND.hh:177
then usage $script< input file >[option[primary[working directory]]] nWhere option can be N
Definition: JMuonPostfit.sh:36
const double getSpeedOfLight()
Get speed of light.
const double getInverseSpeedOfLight()
Get inverse speed of light.
Data structure for fit of straight line paralel to z-axis.
Definition: JLine1Z.hh:27
int j
Definition: JPolint.hh:703
Exception for accessing a value in a collection that is outside of its range.
Definition: JException.hh:162
source $JPP_DIR setenv csh $JPP_DIR &dev null eval JShellParser o a A
static double MINIMAL_SVD_WEIGHT
minimal SVD weight.
esac done
Definition: JAddHDE.sh:21