ATLAS Offline Software
MuonHoughMathUtils.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include <cfloat>
8 
9 #include <cassert>
10 #include <iostream>
11 #include <sstream>
12 
14 #include "CxxUtils/sincos.h"
15 #include "GaudiKernel/MsgStream.h"
18 
19 int MuonHoughMathUtils::sgn(double d) { return d >= 0 ? 1 : -1; }
20 
21 int MuonHoughMathUtils::step(double d, double x0) {
22  if (d == x0) {
23  MsgStream log(Athena::getMessageSvc(), "MuonHoughMathUtils::step");
24  if (log.level() <= MSG::WARNING) log << MSG::WARNING << "WARNING: Possible mistake in Step function" << endmsg;
25  }
26  if (d <= x0) { return 0; }
27  if (d > x0) { return 1; }
28  return -1;
29 }
30 
32  double x0, double y0, double r0,
33  double phi) // distance from (x0,y0) to the line (r0,phi) , phi in [-Pi,Pi] ,different phi than in calculateangle() (==angle(2))
34 {
35  CxxUtils::sincos scphi(phi);
36  double distance = scphi.apply(x0, -y0) - r0;
37  return distance;
38 }
39 
40 double MuonHoughMathUtils::distanceToLine(double x0, double y0, double r0, double phi) {
41  return std::abs(signedDistanceToLine(x0, y0, r0, phi));
42 }
43 
44 double MuonHoughMathUtils::incrementTillAbove0(double x, double inc, double zero) {
45  while (x > inc + zero) { x -= inc; }
46  while (x < zero) { x += inc; }
47  return x;
48 }
49 
51 
53 
55 
57 
59  std::string s;
60  std::stringstream ss;
61  ss << i;
62  ss >> s;
63 
64  return s;
65 }
66 
67 double MuonHoughMathUtils::distanceToLine2D(double x0, double y0, double r0, double phi)
68  // distance from (x0,y0) to line (r,phi) // from mathworld.wolfram.com/Point-LineDistance2-Dimensional.html // better to use
69  // distancetoline()
70 {
71  // need two points on line:
72 
73  CxxUtils::sincos scphi(phi);
74 
75  double x1 = -r0 * scphi.sn; // point closest to origin
76  double y1 = r0 * scphi.cs;
77 
78  Amg::Vector3D v{x1 - x0, y1 - y0, 0}; // (p1 - p0)
79 
80  Amg::Vector3D r{x1, y1, 0}; // vector perpendicular to line
81  double distance = r.dot(v) / r.mag();
82 
83  return distance;
84 }
85 
87  const Amg::Vector3D& point, const Amg::Vector3D& l_trans, double phi,
88  double theta) // from wolfram: http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
89 {
90  Amg::Vector3D x1 = l_trans - point; // x1-x0
91 
92  CxxUtils::sincos scphi(phi);
93  CxxUtils::sincos sctheta(theta);
94 
96  const Amg::Vector3D dir{scphi.cs * sctheta.sn, scphi.sn * sctheta.sn, sctheta.cs};
97 
98  // sqrt(x3^2) == 1; !
99 
100  double distance;
101  const Amg::Vector3D x4 = dir.cross(x1);
102 
103  distance = x4.mag();
104 
105  return distance;
106 }
107 
108 double MuonHoughMathUtils::distanceOfLineToOrigin2D(double a, double b) { return std::abs(b / (std::sqrt(a * a + 1))); }
109 
111  CxxUtils::sincos scphi(phi);
112  return scphi.apply(x, -y);
113 }
114 
116  const Amg::Vector3D& vec, double phi, double theta) // actually this is the 3d-point closest to origin in xy-plane
117 {
119 
120  CxxUtils::sincos scphi(phi);
121 
122  double x0 = r0 * scphi.sn;
123  double y0 = -r0 * scphi.cs;
124 
125  const double d_x = vec[Amg::x] - x0;
126  const double d_y = vec[Amg::y] - y0;
127  double radius = std::hypot(d_x, d_y);
128 
129  if (std::abs(d_y - scphi.sn * radius) > std::abs(d_y + scphi.cs * radius)) // also possible for x
130  {
131  radius = -radius;
132  }
133 
134  double z0 = vec[Amg::z] - radius / std::tan(theta);
135 
136  return {x0, y0, z0};
137 }
138 
140  const Amg::Vector3D& line_trans, double phi,
141  double theta) // from wolfram: http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
142 {
143  // origin:
144  static const Amg::Vector3D origin{0., 0., 0.};
145 
146  const Amg::Vector3D x1 = line_trans - origin;
147 
148  CxxUtils::sincos scphi(phi);
149  CxxUtils::sincos sctheta(theta);
150  const Amg::Vector3D dir{scphi.cs * sctheta.sn, scphi.sn * sctheta.sn, sctheta.cs};
151 
152  double time = 0;
153  double x5 = 0;
154  x5 = x1.dot(dir);
155  time = -x5;
156 
157  Amg::Vector3D short_point = x1 + time * dir;
158  return short_point;
159 }
160 
161 bool MuonHoughMathUtils::lineThroughCylinder(const Amg::Vector3D& line_trans, double phi, double theta, double r_cyl, double z_cyl) {
162  // if there is one, then track will be split
163  assert(r_cyl >= 0);
164 
165  CxxUtils::sincos scphi(phi);
166  CxxUtils::sincos sctheta(theta);
167 
168  // 1 -- check if there is an intersection at z0=+-c0
169  double p_1 = line_trans[Amg::z] - z_cyl;
170  double p_2 = line_trans[Amg::z] + z_cyl;
171  double tantheta = sctheta.sn / sctheta.cs;
172 
173  double x_1 = line_trans[Amg::x] - p_1 * scphi.cs * tantheta;
174  double y_1 = line_trans[Amg::y] - p_1 * scphi.sn * tantheta;
175  double r_1 = std::hypot(x_1, y_1);
176  if (r_1 < r_cyl) { return true; }
177 
178  double x_2 = line_trans[Amg::x] - p_2 * scphi.cs * tantheta;
179  double y_2 = line_trans[Amg::y] - p_2 * scphi.sn * tantheta;
180  double r_2 = std::hypot(x_2, y_2);
181  if (r_2 < r_cyl) { return true; }
182 
183  // 2 -- check if there is an intersection with the circle x^2 + y^2 = r_cyl^2 and the line y=px+q, p = tan(phi), q = y_0 - x_0 tan(phi)
184  // <--> r_cyl^2 = (px+q)^2 + x^2
185  double r_0 = scphi.apply(-line_trans[Amg::x], line_trans[Amg::y]);
186 
187  if (std::abs(r_0) > r_cyl) return false;
188 
189  // 3 -- check if the intersection is cylinder: for -z_cyl<z<z_cyl
190  double s_1 = -scphi.sn * r_0;
191  double s_2 = scphi.cs * std::sqrt(r_cyl * r_cyl - r_0 * r_0);
192 
193  x_1 = s_1 + s_2;
194 
195  double inv_angle = 1 / (scphi.cs * tantheta);
196 
197  double z_1 = line_trans[Amg::z] + (x_1 - line_trans[Amg::x]) * inv_angle;
198 
199  if (std::abs(z_1) < z_cyl) return true;
200 
201  x_2 = s_1 - s_2;
202  double z_2 = line_trans[Amg::z] + (x_2 - line_trans[Amg::x]) * inv_angle;
203 
204  return std::abs(z_2) < z_cyl;
205 }
206 
207 double MuonHoughMathUtils::signedDistanceCurvedToHit(double z0, double theta, double invcurvature, const Amg::Vector3D& hit) {
208  double hitr = hit.perp();
209 
210  CxxUtils::sincos sctheta(theta);
211 
212  double sdistance = FLT_MAX;
213  // if angle rotation larger than Pi/2 then return large distance (formulas don't work for flip in z!)
214  if (sctheta.apply(hitr, hit[Amg::z]) < 0) return sdistance; // hitr*sctheta.sn + hitz*sctheta.cs < 0
215 
216  const int sign = hit[Amg::z] < 0 ? -1 : 1;
217 
218  if (std::abs(hitr / hit[Amg::z]) > MuonHough::tan_barrel) {
219  // Barrel Extrapolation
220  if (std::abs(sctheta.sn) > 1e-7) {
221  double diffr = hitr - MuonHough::radius_cylinder;
222  double zext = z0 + (hitr * sctheta.cs + diffr * diffr * invcurvature) / sctheta.sn;
223  sdistance = (zext - hit[Amg::z]);
224  }
225 
226  } else {
227  if (std::abs(sctheta.sn) > 1e-7) {
228  double rext = 0.;
229  if (std::abs(hit[Amg::z]) < MuonHough::z_end) {
230  // Forward in Toroid
231  double diffz = hit[Amg::z] - sign * MuonHough::z_cylinder;
232  rext = ((hit[Amg::z] - z0) * sctheta.sn - diffz * diffz * invcurvature) / sctheta.cs;
233 
234  } else {
235  // Forward OutSide EC Toroid
236  rext = ((hit[Amg::z] - z0) * sctheta.sn +
238  sctheta.cs;
239  }
240  sdistance = (rext - hitr);
241  }
242  }
243  return sdistance;
244 }
245 
246 double MuonHoughMathUtils::thetaForCurvedHit(double invcurvature, MuonHoughHit* hit) {
247  double ratio = hit->getMagneticTrackRatio() * invcurvature;
248  if (std::abs(ratio) < 1.)
249  return hit->getTheta() + std::asin(ratio);
250  else
251  return -1;
252 }
253 
254 void MuonHoughMathUtils::thetasForCurvedHit(double ratio, MuonHoughHit* hit, double& theta1, double& theta2) {
257  if (std::abs(ratio) < 1.) {
258  double asin_ratio = std::asin(ratio);
259  theta1 = hit->getTheta() + asin_ratio;
260  theta2 = hit->getTheta() - asin_ratio;
261  }
262 }
263 
265  Amg::Vector3D& roadpose, Amg::Vector3D& roaddire) {
273  // m_log<< MSG::VERBOSE << "Extrapolate the road to the segment (hit)" <<endmsg;
274 
275  const double theta = roadmom.theta();
276  const double phi = roadmom.phi();
277 
278  CxxUtils::sincos scphi(phi);
279  CxxUtils::sincos sctheta(theta);
280 
281  double tantheta = sctheta.sn / sctheta.cs;
282 
283  double r0 = scphi.apply(roadpos.x(), -roadpos.y());
284  double charge = 1.;
285  if (r0 < 0) charge = -1.;
286  double invcurvature = charge / roadmom.mag();
287  // No momentum estimate
288  if (roadmom.mag() < 2) invcurvature = 0.;
289 
290  double posr = std::sqrt(pos.x() * pos.x() + pos.y() * pos.y());
291  double thetan = theta;
292 
293  int sign = 1;
294  if (pos.z() < 0) sign = -1;
295 
296  double xe = pos.x();
297  double ye = pos.y();
298  double ze = pos.z();
299  double rotationangle = 0.;
300 
301  if (std::abs(posr / pos.z()) > MuonHough::tan_barrel) {
302  // Barrel Extrapolation
303  if ((posr * posr - r0 * r0) > 0) {
304  double lenr = std::sqrt(posr * posr - r0 * r0);
305  double len = posr - fabs(r0);
306  double diffr = posr - MuonHough::radius_cylinder;
307  rotationangle = diffr * invcurvature / sctheta.sn;
308  xe = roadpos.x() + lenr * scphi.cs;
309  ye = roadpos.y() + lenr * scphi.sn;
310  ze = roadpos.z() + len / tantheta + diffr * rotationangle;
311  thetan = std::atan2(1., 1 / tantheta + 2 * rotationangle);
312  }
313  } else {
314  double lext = 0., rotationangle = 0.;
315  if (std::abs(pos.z()) < MuonHough::z_end) {
316  // Forward in Toroid
317  double diffz = pos.z() - sign * MuonHough::z_cylinder;
318  rotationangle = diffz * invcurvature / sctheta.cs;
319  lext = (pos.z() - roadpos.z()) * tantheta - diffz * rotationangle;
320  } else {
321  // Forward OutSide EC Toroid
322  double effcurv = invcurvature / sctheta.cs;
323  rotationangle = sign * (MuonHough::z_end - MuonHough::z_cylinder) * effcurv;
324  lext = (pos.z() - roadpos.z()) * tantheta +
326  }
327  xe = roadpos.x() + lext * scphi.cs;
328  ye = roadpos.y() + lext * scphi.sn;
329  double dx = tantheta - 2 * rotationangle;
330  if (dx != 0) thetan = std::atan2(1., 1 / dx);
331  }
332 
333  // In case direction theta is rotated for low momenta: flip direction vector
334  CxxUtils::sincos scthetan(thetan);
335  if (sctheta.cs * scthetan.cs + sctheta.sn * scthetan.sn < 0) {
336  roaddire = Amg::Vector3D(scthetan.sn * scphi.cs, scthetan.sn * scphi.sn, -scthetan.cs);
337  } else {
338  roaddire = Amg::Vector3D(scthetan.sn * scphi.cs, scthetan.sn * scphi.sn, scthetan.cs);
339  }
340  roadpose = Amg::Vector3D(xe, ye, ze);
341 }
CxxUtils::sincos::apply
double apply(double a, double b) const
Definition: sincos.h:97
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
beamspotman.r
def r
Definition: beamspotman.py:676
MuonHoughMathUtils::angleFrom0To180
static double angleFrom0To180(double angle)
computes angle in degrees between 0 and 180
Definition: MuonHoughMathUtils.cxx:52
MuonHoughHit::getMagneticTrackRatio
double getMagneticTrackRatio() const
ratio of the tracklength of the particle to which hit might belong would have traversed in magnetic f...
Definition: MuonHoughHit.h:173
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
MuonHoughMathUtils::signedDistanceToLine
static double signedDistanceToLine(double x0, double y0, double r0, double phi)
distance from (x0,y0) to the line (r0,phi), phi in rad
Definition: MuonHoughMathUtils.cxx:31
MuonHoughMathUtils::sgn
static int sgn(double d)
sign (-1 or 1) of a double
Definition: MuonHoughMathUtils.cxx:19
MuonHoughMathUtils::shortestPointOfLineToOrigin
static Amg::Vector3D shortestPointOfLineToOrigin(const Amg::Vector3D &vec, double phi, double theta)
calculates the 3d-point closest to origin
Definition: MuonHoughMathUtils.cxx:139
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:67
getMessageSvc.h
singleton-like access to IMessageSvc via open function and helper
hist_file_dump.d
d
Definition: hist_file_dump.py:137
theta
Scalar theta() const
theta method
Definition: AmgMatrixBasePlugin.h:75
MuonHoughMathUtils::step
static int step(double d, double x0=0)
step function at place x0
Definition: MuonHoughMathUtils.cxx:21
Amg::y
@ y
Definition: GeoPrimitives.h:35
M_PI
#define M_PI
Definition: ActiveFraction.h:11
sincos.h
Helper to simultaneously calculate sin and cos of the same angle.
MuonHough::z_cylinder
constexpr double z_cylinder
length of cylinder
Definition: MuonHoughMathUtils.h:26
MuonHoughMathUtils::distanceToLine3D
static double distanceToLine3D(const Amg::Vector3D &point, const Amg::Vector3D &l_trans, double phi, double theta)
distance from (x0,y0,z0) to line (x,y,z,phi,theta)
Definition: MuonHoughMathUtils.cxx:86
MuonHoughHit
Definition: MuonHoughHit.h:28
vec
std::vector< size_t > vec
Definition: CombinationsGeneratorTest.cxx:12
x
#define x
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
makeTRTBarrelCans.y1
tuple y1
Definition: makeTRTBarrelCans.py:15
Amg::z
@ z
Definition: GeoPrimitives.h:36
MuonHoughMathUtils::thetasForCurvedHit
static void thetasForCurvedHit(double ratio, MuonHoughHit *hit, double &theta1, double &theta2)
calculates theta at (x,y,z) for curved track model, for positive and negative curvature
Definition: MuonHoughMathUtils.cxx:254
CxxUtils::sincos::cs
double cs
Definition: sincos.h:94
lumiFormat.i
int i
Definition: lumiFormat.py:85
MuonHoughMathUtils::distanceToLine
static double distanceToLine(double x0, double y0, double r0, double phi)
distance from (x0,y0) to the line (r0,phi), phi in rad
Definition: MuonHoughMathUtils.cxx:40
MuonHoughMathUtils::angleFromMinusPiToPi
static double angleFromMinusPiToPi(double angle)
computes angle in rad between -Pi and Pi
Definition: MuonHoughMathUtils.cxx:56
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
MuonHoughMathUtils::signedDistanceOfLineToOrigin2D
static double signedDistanceOfLineToOrigin2D(double x, double y, double phi)
signed distance of line with point (x,y) and angle phi to origin
Definition: MuonHoughMathUtils.cxx:110
angle
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
Definition: TRTDetectorFactory_Full.cxx:73
Amg::x
@ x
Definition: GeoPrimitives.h:34
MuonHoughMathUtils::incrementTillAbove0
static double incrementTillAbove0(double x, double inc, double zero=0)
increments x with inc till above x
Definition: MuonHoughMathUtils.cxx:44
TRT_PAI_physicsConstants::r0
const double r0
electron radius{cm}
Definition: TRT_PAI_physicsConstants.h:20
sign
int sign(int a)
Definition: TRT_StrawNeighbourSvc.h:107
MuonHough::z_end
constexpr double z_end
z value whereafter no magnetic field / curvature
Definition: MuonHoughMathUtils.h:28
drawFromPickle.tan
tan
Definition: drawFromPickle.py:36
MuonHoughMathUtils::angleFrom0To360
static double angleFrom0To360(double angle)
computes angle in degrees between 0 and 360
Definition: MuonHoughMathUtils.cxx:50
TRT::Track::z0
@ z0
Definition: InnerDetector/InDetCalibEvent/TRT_CalibData/TRT_CalibData/TrackInfo.h:63
MuonHoughMathUtils::extrapolateCurvedRoad
static void extrapolateCurvedRoad(const Amg::Vector3D &roadpos, const Amg::Vector3D &roadmom, const Amg::Vector3D &pos, Amg::Vector3D &roadpose, Amg::Vector3D &roaddire)
extrapolates road to global position
Definition: MuonHoughMathUtils.cxx:264
MuonHoughMathUtils::MuonHoughMathUtils
MuonHoughMathUtils()
default constructor
beamspotman.dir
string dir
Definition: beamspotman.py:623
MuonHoughMathUtils::thetaForCurvedHit
static double thetaForCurvedHit(double invcurvature, MuonHoughHit *hit)
calculates theta at (x,y,z) for curved track model
Definition: MuonHoughMathUtils.cxx:246
MuonHoughMathUtils::shortestPointOfLineToOrigin3D
static Amg::Vector3D shortestPointOfLineToOrigin3D(const Amg::Vector3D &vec, double phi, double theta)
calculates the 3d-point closest to origin in xy-plane
Definition: MuonHoughMathUtils.cxx:115
MuonHoughMathUtils::angleFrom0ToPi
static double angleFrom0ToPi(double angle)
computes angle in rad between 0 and Pi
Definition: MuonHoughMathUtils.cxx:54
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
charge
double charge(const T &p)
Definition: AtlasPID.h:756
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
ParticleGun_SamplingFraction.radius
radius
Definition: ParticleGun_SamplingFraction.py:96
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
CxxUtils::sincos::sn
double sn
Definition: sincos.h:91
MuonHoughMathUtils::distanceToLine2D
static double distanceToLine2D(double x0, double y0, double r, double phi)
distance from (x0,y0) to line (r,phi)
Definition: MuonHoughMathUtils.cxx:67
python.PyAthena.v
v
Definition: PyAthena.py:154
a
TList * a
Definition: liststreamerinfos.cxx:10
y
#define y
python.compareTCTs.ratio
ratio
Definition: compareTCTs.py:295
CaloSwCorrections.time
def time(flags, cells_name, *args, **kw)
Definition: CaloSwCorrections.py:242
GeoPrimitivesHelpers.h
makeTRTBarrelCans.dx
tuple dx
Definition: makeTRTBarrelCans.py:20
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
MuonHoughHit::getTheta
double getTheta() const
returns theta
Definition: MuonHoughHit.h:168
CxxUtils::sincos
Helper to simultaneously calculate sin and cos of the same angle.
Definition: sincos.h:76
MuonHoughMathUtils::distanceOfLineToOrigin2D
static double distanceOfLineToOrigin2D(double a, double b)
distance of line y = ax + b to origin
Definition: MuonHoughMathUtils.cxx:108
MuonHough::radius_cylinder
constexpr double radius_cylinder
radius of cylinder
Definition: MuonHoughMathUtils.h:24
MuonHoughMathUtils::lineThroughCylinder
static bool lineThroughCylinder(const Amg::Vector3D &vec, double phi, double theta, double r_0, double z_0)
calculates if line (x,y,z,phi,theta) crosses cylinder (r_0,z_0) around origin
Definition: MuonHoughMathUtils.cxx:161
MuonHoughMathUtils.h
MuonHough::tan_barrel
constexpr double tan_barrel
relation for transition between endcap and barrel 11.43 m (r) / 14m (z)
Definition: MuonHoughMathUtils.h:22
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
MuonHoughMathUtils::intToString
static std::string intToString(int i)
converts integer to string
Definition: MuonHoughMathUtils.cxx:58
MuonHough::z_magnetic_range
constexpr double z_magnetic_range
range where hit is curved in endcap region
Definition: MuonHoughMathUtils.h:30
zero
void zero(TH2 *h)
zero the contents of a 2d histogram
Definition: comparitor.cxx:436
MuonHoughMathUtils::signedDistanceCurvedToHit
static double signedDistanceCurvedToHit(double z0, double theta, double invcurvature, const Amg::Vector3D &hit)
calculates distance of point (x,y,z) to curved track with z0, theta and invcurvature for curved track...
Definition: MuonHoughMathUtils.cxx:207
MuonHough::z_magnetic_range_squared
constexpr double z_magnetic_range_squared
range where hit is curved in endcap region ('squared')
Definition: MuonHoughMathUtils.h:32