GeneralBrokenLines V03-00-01
using EIGEN
exampleUtil.cpp
Go to the documentation of this file.
1/*
2 * exampleUtil.cpp
3 *
4 * Created on: 6 Nov 2018
5 * Author: kleinwrt
6 */
7
30#include "exampleUtil.h"
31
32using namespace Eigen;
33
34namespace gbl {
35
36typedef Eigen::Matrix<double, 5, 5> Matrix5d;
37
39
44double gblMultipleScatteringError(double qbyp, double xbyx0) {
45 return 0.015 * fabs(qbyp) * sqrt(xbyx0);
46}
47
49
58Matrix5d gblSimpleJacobian(double ds, double cosl, double bfac) {
59 Matrix5d jac;
60 jac.setIdentity();
61 jac(1, 0) = -bfac * ds * cosl;
62 jac(3, 0) = -0.5 * bfac * ds * ds * cosl;
63 jac(3, 1) = ds;
64 jac(4, 2) = ds;
65 return jac;
66}
67
69double unrm() {
70 static double unrm2 = 0.0;
71 static bool cached = false;
72 if (!cached) {
73 double x, y, r;
74 do {
75 x = 2.0 * static_cast<double>(rand())
76 / static_cast<double>(RAND_MAX) - 1;
77 y = 2.0 * static_cast<double>(rand())
78 / static_cast<double>(RAND_MAX) - 1;
79 r = x * x + y * y;
80 } while (r == 0.0 || r > 1.0);
81 // (x,y) in unit circle
82 double d = sqrt(-2.0 * log(r) / r);
83 double unrm1 = x * d;
84 unrm2 = y * d;
85 cached = true;
86 return unrm1;
87 } else {
88 cached = false;
89 return unrm2;
90 }
91}
92
94double unif() {
95 return static_cast<double>(rand()) / static_cast<double>(RAND_MAX);
96}
97
99
108GblHelixPrediction::GblHelixPrediction(double sArc, const Vector2d& aPred,
109 const Vector3d& tDir, const Vector3d& uDir, const Vector3d& vDir,
110 const Vector3d& nDir, const Vector3d& aPos) :
111 sarc(sArc), pred(aPred), tdir(tDir), udir(uDir), vdir(vDir), ndir(nDir), pos(
112 aPos) {
113 global2meas << uDir.transpose(), vDir.transpose(), nDir.transpose();
114}
115
117}
118
121 return sarc;
122}
123
125const Vector2d& GblHelixPrediction::getMeasPred() const {
126 return pred;
127}
128
130const Vector3d& GblHelixPrediction::getPosition() const {
131 return pos;
132}
133
135const Vector3d& GblHelixPrediction::getDirection() const {
136 return tdir;
137}
138
141 return tdir.dot(ndir);
142}
143
145/*
146 * Curvilinear system: track direction T, U = Z x T / |Z x T|, V = T x U
147 */
148Eigen::Matrix<double, 2, 3> GblHelixPrediction::getCurvilinearDirs() const {
149 const double cosTheta = tdir[2];
150 const double sinTheta = sqrt(tdir[0] * tdir[0] + tdir[1] * tdir[1]);
151 const double cosPhi = tdir[0] / sinTheta;
152 const double sinPhi = tdir[1] / sinTheta;
153 Eigen::Matrix<double, 2, 3> uvDir;
154 uvDir << -sinPhi, cosPhi, 0., -cosPhi * cosTheta, -sinPhi * cosTheta, sinTheta;
155 return uvDir;
156}
157
159
166GblSimpleHelix::GblSimpleHelix(double aRinv, double aPhi0, double aDca,
167 double aDzds, double aZ0) :
168 rinv(aRinv), phi0(aPhi0), dca(aDca), dzds(aDzds), z0(aZ0), cosPhi0(
169 cos(phi0)), sinPhi0(sin(phi0)), xRelCenter(
170 -(1. - dca * rinv) * sinPhi0), yRelCenter(
171 (1. - dca * rinv) * cosPhi0) {
172}
173
175}
176
178
183double GblSimpleHelix::getPhi(double aRadius) const {
184 double arg = (0.5 * rinv * (aRadius * aRadius + dca * dca) - dca)
185 / (aRadius * (1.0 - rinv * dca));
186 return asin(arg) + phi0;
187}
188
190
195double GblSimpleHelix::getArcLengthR(double aRadius) const {
196 double arg = (0.5 * rinv * (aRadius * aRadius + dca * dca) - dca)
197 / (aRadius * (1.0 - rinv * dca));
198 if (fabs(arg) >= 1.) {
199 std::cout << " bad arc " << aRadius << " " << rinv << " " << dca
200 << std::endl;
201 return 0.;
202 }
203 // line
204 if (rinv == 0)
205 return sqrt(aRadius * aRadius - dca * dca);
206 // helix
207 double sxy = asin(aRadius * rinv * sqrt(1.0 - arg * arg)) / rinv;
208 if (0.5 * rinv * rinv * (aRadius * aRadius - dca * dca) - 1. + rinv * dca
209 > 0.)
210 sxy = M_PI / fabs(rinv) - sxy;
211 return sxy;
212}
213
215
219double GblSimpleHelix::getArcLengthXY(double xPos, double yPos) const {
220// line
221 if (rinv == 0)
222 return cosPhi0 * xPos + sinPhi0 * yPos;
223// helix
224 double dx = xPos * rinv - xRelCenter;
225 double dy = yPos * rinv - yRelCenter;
226 double dphi = atan2(dx, -dy) - phi0;
227 if (dphi > M_PI)
228 dphi -= 2.0 * M_PI;
229 else if (dphi < -M_PI)
230 dphi += 2.0 * M_PI;
231 return dphi / rinv;
232}
233
235
242void GblSimpleHelix::moveToXY(double xPos, double yPos, double& newPhi0,
243 double& newDca, double& newZ0) const {
244// start values
245 newPhi0 = phi0;
246 newDca = dca;
247 newZ0 = z0;
248// Based on V. Karimaki, NIM A305 (1991) 187-191, eqn (19)
249 const double u = 1. - rinv * dca;
250 const double dp = -xPos * sinPhi0 + yPos * cosPhi0 + dca;
251 const double dl = xPos * cosPhi0 + yPos * sinPhi0;
252 const double sa = 2. * dp - rinv * (dp * dp + dl * dl);
253 const double sb = rinv * xPos + u * sinPhi0;
254 const double sc = -rinv * yPos + u * cosPhi0;
255 const double sd = sqrt(1. - rinv * sa);
256// transformed parameters
257 double sArc;
258 if (rinv == 0.) {
259 newDca = dp;
260 sArc = dl;
261 } else {
262 newPhi0 = atan2(sb, sc);
263 newDca = sa / (1. + sd);
264 double dphi = newPhi0 - phi0;
265 if (dphi > M_PI)
266 dphi -= 2.0 * M_PI;
267 else if (dphi < -M_PI)
268 dphi += 2.0 * M_PI;
269 sArc = dphi / rinv;
270 }
271 newZ0 += sArc * dzds;
272}
273
275/*
276 * \param [in] refPos reference position on detector plane
277 * \param [in] uDir measurement direction 'u'
278 * \param [in] vDir measurement direction 'v'
279 */
281 const Eigen::Vector3d& uDir, const Eigen::Vector3d& vDir) const {
282// normal to (u,v) measurement plane
283 Vector3d nDir = uDir.cross(vDir).normalized();
284// ZS direction
285 const double cosLambda = 1. / sqrt(1. + dzds * dzds);
286 const double sinLambda = dzds * cosLambda;
287 double sArc2D;
288 Vector3d dist, pos, tDir;
289// line (or helix)
290 if (rinv == 0.) {
291 // track direction
292 tDir << cosLambda * cosPhi0, cosLambda * sinPhi0, sinLambda;
293 // distance (of point at dca to reference)
294 Vector3d pca(dca * sinPhi0, -dca * cosPhi0, z0);
295 dist = pca - refPos;
296 // arc-length
297 double sArc3D = -dist.dot(nDir) / tDir.dot(nDir);
298 sArc2D = sArc3D * cosLambda;
299 // position at prediction
300 pos = pca + sArc3D * tDir;
301 // distance (of point at sArc to reference)
302 dist = pos - refPos;
303 } else {
304 // initial guess of 2D arc-length
305 sArc2D = this->getArcLengthXY(refPos(0), refPos(1));
306 unsigned int nIter = 0;
307 while (nIter < 10) {
308 nIter += 1;
309 // track direction
310 const double dPhi = sArc2D * rinv;
311 const double cosPhi = cos(phi0 + dPhi);
312 const double sinPhi = sin(phi0 + dPhi);
313 tDir << cosLambda * cosPhi, cosLambda * sinPhi, sinLambda;
314 // position at prediction
315 pos << (xRelCenter + sinPhi) / rinv, (yRelCenter - cosPhi) / rinv, z0
316 + dzds * sArc2D;
317 // distance (of point at sArc to reference)
318 dist = pos - refPos;
319 // arc-length correction (linearizing helix at sArc)
320 const double sCorr3D = -dist.dot(nDir) / tDir.dot(nDir);
321 if (fabs(sCorr3D) > 0.00001) {
322 // iterate
323 sArc2D += sCorr3D * cosLambda;
324 } else {
325 // converged
326 break;
327 }
328 }
329 }
330// projections on measurement directions
331 Vector2d pred(dist.dot(uDir), dist.dot(vDir));
332 return GblHelixPrediction(sArc2D, pred, tDir, uDir, vDir, nDir, pos);
333}
334
336
349 const unsigned int aLayer, const int aDim, const double thickness,
350 Eigen::Vector3d& aCenter, Eigen::Vector2d& aResolution,
351 Eigen::Vector2d& aPrecision, Eigen::Matrix3d& measTrafo,
352 Eigen::Matrix3d& alignTrafo) :
353 name(aName), layer(aLayer), measDim(aDim), xbyx0(thickness), center(
354 aCenter), resolution(aResolution), precision(aPrecision), global2meas(
355 measTrafo), global2align(alignTrafo) {
356 udir = global2meas.row(0);
357 vdir = global2meas.row(1);
358 ndir = global2meas.row(2);
359}
360
362}
363
366 IOFormat CleanFmt(4, 0, ", ", "\n", "[", "]");
367 std::cout << " Layer " << name << " " << layer << " : " << measDim << "D, "
368 << xbyx0 << " X0, @ " << center.transpose().format(CleanFmt)
369 << ", res " << resolution.transpose().format(CleanFmt) << ", udir "
370 << udir.transpose().format(CleanFmt) << ", vdir "
371 << vdir.transpose().format(CleanFmt) << std::endl;
372}
373
375unsigned int GblDetectorLayer::getLayerID() const {
376 return layer;
377}
378
381 return xbyx0;
382}
383
385Eigen::Vector2d GblDetectorLayer::getResolution() const {
386 return resolution;
387}
388
390Eigen::Vector2d GblDetectorLayer::getPrecision() const {
391 return precision;
392}
393
395Eigen::Vector3d GblDetectorLayer::getCenter() const {
396 return center;
397}
398
400
403Eigen::Matrix3d GblDetectorLayer::getMeasSystemDirs() const {
404 return global2meas;;
405}
406
408
412 return global2align;;
413}
414
416
420 GblSimpleHelix hlx) const {
421 return hlx.getPrediction(center, udir, vdir);
422}
423
425
430 Eigen::Vector3d& position, Eigen::Vector3d& direction) const {
431// lever arms (for rotations)
432 Vector3d dist = position;
433// dr/dm (residual vs measurement, 1-tdir*ndir^t/tdir*ndir)
434 Matrix3d drdm = Matrix3d::Identity()
435 - (direction * ndir.transpose()) / (direction.transpose() * ndir);
436// dm/dg (measurement vs 6 rigid body parameters, global system)
437 Matrix<double, 3, 6> dmdg = Matrix<double, 3, 6>::Zero();
438 dmdg(0, 0) = 1.;
439 dmdg(0, 4) = -dist(2);
440 dmdg(0, 5) = dist(1);
441 dmdg(1, 1) = 1.;
442 dmdg(1, 3) = dist(2);
443 dmdg(1, 5) = -dist(0);
444 dmdg(2, 2) = 1.;
445 dmdg(2, 3) = -dist(1);
446 dmdg(2, 4) = dist(0);
447// drl/dg (local residuals vs rigid body parameters)
448 return global2meas * drdm * dmdg;
449}
450
452
465 Eigen::Vector3d& position, Eigen::Vector3d& direction) const {
466 // track direction in local system
467 Vector3d tLoc = global2align * direction;
468 // local slopes
469 const double uSlope = tLoc[0] / tLoc[2];
470 const double vSlope = tLoc[1] / tLoc[2];
471 // lever arms (for rotations)
472 Vector3d dist = global2align * (position - center);
473 const double uPos = dist[0];
474 const double vPos = dist[1];
475 // wPos = 0 (in detector plane)
476 // drl/dg (local residuals (du,dv) vs rigid body parameters)
477 Matrix<double, 2, 6> drldg;
478 drldg << 1.0, 0.0, -uSlope, vPos * uSlope, -uPos * uSlope, vPos, 0.0, 1.0, -vSlope, vPos
479 * vSlope, -uPos * vSlope, -uPos;
480 // local (alignment) to measurement system
481 Matrix3d local2meas = global2meas * global2align.transpose();
482 return local2meas.block<2, 2>(0, 0) * drldg;
483}
484
486
493 Eigen::Vector3d& offset, Eigen::Matrix3d& rotation) const {
494 // transformation global to local
495 Matrix<double, 6, 6> glo2loc = Matrix<double, 6, 6>::Zero();
496 Matrix3d leverArms;
497 leverArms << 0., offset[2], -offset[1], -offset[2], 0., offset[0], offset[1], -offset[0], 0.;
498 glo2loc.block<3, 3>(0, 0) = rotation;
499 glo2loc.block<3, 3>(0, 3) = -rotation * leverArms;
500 glo2loc.block<3, 3>(3, 3) = rotation;
501 return glo2loc;
502}
503
505
512 Eigen::Vector3d& offset, Eigen::Matrix3d& rotation) const {
513 // transformation local to global
514 Matrix<double, 6, 6> loc2glo = Matrix<double, 6, 6>::Zero();
515 Matrix3d leverArms;
516 leverArms << 0., offset[2], -offset[1], -offset[2], 0., offset[0], offset[1], -offset[0], 0.;
517 loc2glo.block<3, 3>(0, 0) = rotation.transpose();
518 loc2glo.block<3, 3>(0, 3) = leverArms * rotation.transpose();
519 loc2glo.block<3, 3>(3, 3) = rotation.transpose();
520 return loc2glo;
521}
522
523}
double xbyx0
normalized material thickness
Definition: exampleUtil.h:136
Eigen::Vector3d getCenter() const
Get center.
GblHelixPrediction intersectWithHelix(GblSimpleHelix hlx) const
Intersect with helix.
Eigen::Vector3d ndir
normal to measurement plane
Definition: exampleUtil.h:142
Eigen::Vector3d center
center
Definition: exampleUtil.h:137
double getRadiationLength() const
Get radiation length.
void print() const
Print GblDetectorLayer.
unsigned int measDim
measurement dimension (1 or 2)
Definition: exampleUtil.h:135
Eigen::Matrix< double, 2, 6 > getRigidBodyDerLocal(Eigen::Vector3d &position, Eigen::Vector3d &direction) const
Get rigid body derivatives in local (alignment) frame (rotated in measurement plane).
unsigned int getLayerID() const
Get layer ID.
Eigen::Matrix3d getMeasSystemDirs() const
Get directions of measurement system.
Eigen::Matrix< double, 6, 6 > getTrafoGlobalToLocal(Eigen::Vector3d &offset, Eigen::Matrix3d &rotation) const
Get transformation for rigid body derivatives from global to local (alignment) system.
Eigen::Matrix< double, 3, 6 > getRigidBodyDerGlobal(Eigen::Vector3d &position, Eigen::Vector3d &direction) const
Get rigid body derivatives in global frame.
Eigen::Matrix3d global2meas
transformation into measurement system
Definition: exampleUtil.h:143
unsigned int layer
layer ID
Definition: exampleUtil.h:134
GblDetectorLayer(const std::string aName, const unsigned int aLayer, const int aDim, const double thickness, Eigen::Vector3d &aCenter, Eigen::Vector2d &aResolution, Eigen::Vector2d &aPrecision, Eigen::Matrix3d &measTrafo, Eigen::Matrix3d &alignTrafo)
Create a detector layer.
Eigen::Matrix3d getAlignSystemDirs() const
Get directions of alignment system.
Eigen::Vector2d precision
measurements precision
Definition: exampleUtil.h:139
Eigen::Vector3d vdir
Definition: exampleUtil.h:141
Eigen::Vector2d getResolution() const
Get resolution.
Eigen::Vector3d udir
Definition: exampleUtil.h:140
Eigen::Matrix< double, 6, 6 > getTrafoLocalToGlobal(Eigen::Vector3d &offset, Eigen::Matrix3d &rotation) const
Get transformation for rigid body derivatives from local (alignment) to global system.
Eigen::Vector2d resolution
measurements resolution
Definition: exampleUtil.h:138
std::string name
name
Definition: exampleUtil.h:133
Eigen::Vector2d getPrecision() const
Get precision.
Eigen::Matrix3d global2align
transformation into (local) alignment system
Definition: exampleUtil.h:144
Prediction on helix.
Definition: exampleUtil.h:49
Eigen::Matrix< double, 2, 3 > getCurvilinearDirs() const
Get curvilinear directions (U,V)
const Eigen::Vector3d pos
position at prediction
Definition: exampleUtil.h:70
double getArcLength() const
Get arc-length.
const Eigen::Vector2d & getMeasPred() const
Get (measurement) prediction.
const double sarc
arc-length at prediction
Definition: exampleUtil.h:64
double getCosIncidence() const
Get cosine of incidence.
Eigen::Matrix3d global2meas
transformation into measurement system
Definition: exampleUtil.h:71
const Eigen::Vector3d & getPosition() const
Get position.
const Eigen::Vector2d pred
prediction for measurement (u,v)
Definition: exampleUtil.h:65
const Eigen::Vector3d tdir
track direction at prediction
Definition: exampleUtil.h:66
GblHelixPrediction(double sArc, const Eigen::Vector2d &aPred, const Eigen::Vector3d &tDir, const Eigen::Vector3d &uDir, const Eigen::Vector3d &vDir, const Eigen::Vector3d &nDir, const Eigen::Vector3d &aPos)
Create helix prediction.
const Eigen::Vector3d & getDirection() const
Get position.
const Eigen::Vector3d ndir
normal to measurement plane
Definition: exampleUtil.h:69
Simple helix.
Definition: exampleUtil.h:78
double getArcLengthR(double aRadius) const
Get (2D) arc length for given radius (to ref. point)
void moveToXY(double xPos, double yPos, double &newPhi0, double &newDca, double &newZ0) const
Move to new reference point (X,y)
virtual ~GblSimpleHelix()
GblHelixPrediction getPrediction(const Eigen::Vector3d &refPos, const Eigen::Vector3d &uDir, const Eigen::Vector3d &vDir) const
Get prediction.
GblSimpleHelix(double aRinv, double aPhi0, double aDca, double aDzds, double aZ0)
Create simple helix.
const double rinv
curvature (1/Radius)
Definition: exampleUtil.h:92
double getPhi(double aRadius) const
Get phi (of point on circle) for given radius (to ref. point)
const double sinPhi0
sin(phi0)
Definition: exampleUtil.h:98
double getArcLengthXY(double xPos, double yPos) const
Get (2D) arc length for given point.
const double dca
distance to origin in XY plane at PCA
Definition: exampleUtil.h:94
const double z0
offset in ZS plane
Definition: exampleUtil.h:96
const double cosPhi0
cos(phi0)
Definition: exampleUtil.h:97
const double xRelCenter
X position of circle center / R.
Definition: exampleUtil.h:99
const double dzds
slope in ZS plane (dZ/dS)
Definition: exampleUtil.h:95
const double phi0
azimuth at PCA (point of closest approach to origin in XY plane, defines arc-length S=0)
Definition: exampleUtil.h:93
const double yRelCenter
Y position of circle center / R.
Definition: exampleUtil.h:100
Definitions for exampleUtil(ities).
Namespace for the general broken lines package.
double unrm()
unit normal distribution, Box-Muller method, polar form
Definition: exampleUtil.cpp:69
double gblMultipleScatteringError(double qbyp, double xbyx0)
Multiple scattering error.
Definition: exampleUtil.cpp:44
double unif()
uniform distribution [0..1]
Definition: exampleUtil.cpp:94
Matrix5d gblSimpleJacobian(double ds, double cosl, double bfac)
Simple jacobian.
Definition: exampleUtil.cpp:58
Eigen::Matrix< double, 5, 5 > Matrix5d
Definition: exampleUtil.cpp:36