REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestPhysics.cxx
1/******************** REST disclaimer ***********************************
2 * This file is part of the REST software framework. *
3 * *
4 * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) *
5 * For more information see http://gifna.unizar.es/trex *
6 * *
7 * REST is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * REST is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have a copy of the GNU General Public License along with *
18 * REST in $REST_PATH/LICENSE. *
19 * If not, see http://www.gnu.org/licenses/. *
20 * For the list of contributors see $REST_PATH/CREDITS. *
21 *************************************************************************/
22
23#include "TRestPhysics.h"
24
25#include <iostream>
26#include <limits>
27
28using namespace std;
29
50namespace REST_Physics {
51
58TVector3 MoveToPlane(const TVector3& pos, const TVector3& dir, const TVector3& n, const TVector3& a) {
59 if (n * dir != 0) {
60 Double_t t = (n * a - n * pos) / (n * dir);
61
62 return pos + t * dir;
63 }
64 return pos;
65}
66
71Double_t DistanceToAxis(const TVector3& axisPoint, const TVector3& axisVector, const TVector3& point) {
72 TVector3 a = axisVector.Cross(axisPoint - point);
73 return a.Mag() / axisVector.Mag();
74}
75
81TVector3 GetPlaneVectorIntersection(const TVector3& pos, const TVector3& dir, const TVector3& n,
82 const TVector3& a) {
83 return MoveToPlane(pos, dir, n, a);
84}
85
94TVector3 GetParabolicVectorIntersection(const TVector3& pos, const TVector3& dir, const Double_t alpha,
95 const Double_t R3) {
96 Double_t e = 2 * R3 * TMath::Tan(alpha);
97 Double_t a = dir.X() * dir.X() + dir.Y() * dir.Y();
98 Double_t b = 2 * (pos.X() * dir.X() + pos.Y() * dir.Y()) + e * dir.Z();
99 Double_t half_b = b / 2;
100 Double_t c = pos.X() * pos.X() + pos.Y() * pos.Y() - R3 * R3 + e * pos.Z();
101 if (a != 0) {
102 Double_t root1 = (-half_b - TMath::Sqrt(half_b * half_b - a * c)) / a;
103 Double_t root2 = (-half_b + TMath::Sqrt(half_b * half_b - a * c)) / a;
104 Double_t int1 = pos.Z() + root1 * dir.Z();
105 Double_t int2 = pos.Z() + root2 * dir.Z();
106 if (int1 < 0 and int2 < 0 and int1 > int2) {
107 return pos + root1 * dir;
108 } else if (int1 < 0 and int2 < 0 and int1 < int2) {
109 return pos + root2 * dir;
110 }
111 return pos;
112 }
113 return pos - c / b * dir;
114}
115
124TVector3 GetHyperbolicVectorIntersection(const TVector3& pos, const TVector3& dir, const Double_t beta,
125 const Double_t R3, const Double_t focal) {
126 Double_t e = 2 * R3 * TMath::Tan(beta);
127 Double_t alpha = beta / 3;
129 Double_t g = 2 * R3 * TMath::Tan(beta) / (focal + R3 / TMath::Tan(2 * alpha));
130 Double_t a = dir.X() * dir.X() + dir.Y() * dir.Y() - g * dir.Z() * dir.Z();
131 Double_t b = 2 * (pos.X() * dir.X() + pos.Y() * dir.Y() - g * dir.Z() * pos.Z()) + e * dir.Z();
132 Double_t half_b = b / 2;
133 Double_t c = pos.X() * pos.X() + pos.Y() * pos.Y() - R3 * R3 + e * pos.Z() - g * pos.Z() * pos.Z();
134 Double_t root1 = (-half_b - TMath::Sqrt(half_b * half_b - a * c)) / a;
135 Double_t root2 = (-half_b + TMath::Sqrt(half_b * half_b - a * c)) / a;
136 Double_t int1 = pos.Z() + root1 * dir.Z();
137 Double_t int2 = pos.Z() + root2 * dir.Z();
138 if (int1 > 0 and int2 > 0 and int1 < int2) {
139 return pos + root1 * dir;
140 } else if (int1 > 0 and int2 > 0 and int1 > int2) {
141 return pos + root2 * dir;
142 }
143 return pos;
144}
145
150TMatrixD GetConeMatrix(const TVector3& d, const Double_t cosTheta) {
151 double cAxis[3];
152 d.GetXYZ(cAxis);
153
154 TVectorD coneAxis(3, cAxis);
155
156 TMatrixD M(3, 3);
157 M.Rank1Update(coneAxis, coneAxis);
158
159 double cT2 = cosTheta * cosTheta;
160 TMatrixD gamma(3, 3);
161 gamma.UnitMatrix();
162 gamma *= cT2;
163
164 M -= gamma;
165 return M;
166}
167
172TVector3 GetVectorReflection(const TVector3& dir, const TVector3& n) { return dir - 2 * dir.Dot(n) * n; }
173
177Double_t GetVectorsAngle(const TVector3& v1, const TVector3& v2) { return TMath::ACos(v1.Dot(v2)); }
178
189TVector3 GetConeNormal(const TVector3& pos, const Double_t alpha, const Double_t R) {
190 Double_t r = 0;
191 if (R == 0)
192 r = TMath::Sqrt(pos.X() * pos.X() + pos.Y() * pos.Y());
193 else
194 r = R;
195
196 Double_t cosA = TMath::Cos(alpha);
197 Double_t sinA = TMath::Sin(alpha);
198
199 return -TVector3(cosA * pos.X() / r, cosA * pos.Y() / r, sinA);
200}
201
208TVector3 GetParabolicNormal(const TVector3& pos, const Double_t alpha, const Double_t R3) {
209 TVector3 normalVec = pos;
210 Double_t m =
211 1 / (R3 * TMath::Tan(alpha) / TMath::Sqrt(R3 * R3 + R3 * 2 * TMath::Tan(alpha) * (-pos.Z())));
212 Double_t n = TMath::Sqrt(pos.X() * pos.X() + pos.Y() * pos.Y()) - m * pos.Z();
213 normalVec.SetZ(pos.Z() - (-n / m));
214 return normalVec.Unit();
215}
216
223TVector3 GetHyperbolicNormal(const TVector3& pos, const Double_t beta, const Double_t R3,
224 const Double_t focal) {
225 TVector3 normalVec = pos;
226 Double_t alpha = beta / 3;
228 Double_t m = 1 / (R3 * TMath::Tan(beta) * (1 - 2 * pos.Z() / (focal + R3 / TMath::Tan(2 * alpha))) /
229 TMath::Sqrt(R3 * R3 - R3 * 2 * TMath::Tan(beta) * pos.Z() *
230 (1.0 - pos.Z() / (focal + R3 / TMath::Tan(2 * alpha)))));
231 Double_t n = TMath::Sqrt(pos.X() * pos.X() + pos.Y() * pos.Y()) - m * pos.Z();
232 normalVec.SetZ(pos.Z() - (-n / m));
233 return normalVec.Unit();
234}
235
244//
248Double_t GetConeVectorIntersection(const TVector3& pos, const TVector3& dir, const TVector3& d,
249 const TVector3& v, const Double_t cosTheta) {
250 TMatrixD M = GetConeMatrix(d, cosTheta);
251 return GetConeVectorIntersection(pos, dir, M, d, v);
252}
253
267Double_t GetConeVectorIntersection(const TVector3& pos, const TVector3& dir, const TMatrixD& M,
268 const TVector3& axis, const TVector3& v) {
269 double u[3];
270 dir.GetXYZ(u);
271 TMatrixD U(3, 1, u);
272 TMatrixD Ut(1, 3, u);
273
274 double delta[3];
275 TVector3 deltaV = pos - v;
276 deltaV.GetXYZ(delta);
277 TMatrixD D(3, 1, delta);
278 TMatrixD Dt(1, 3, delta);
279
280 TMatrixD C2 = Ut * M * U;
281 Double_t c2 = C2[0][0];
282
283 TMatrixD C1 = Ut * M * D;
284 Double_t c1 = C1[0][0];
285
286 TMatrixD C0 = Dt * M * D;
287 Double_t c0 = C0[0][0];
288
289 Double_t root = c1 * c1 - c0 * c2;
290 if (root < 0) return 0;
291
292 Double_t t1 = (-c1 + TMath::Sqrt(root)) / c2;
293 Double_t t2 = (-c1 - TMath::Sqrt(root)) / c2;
294
295 // The projections along the cone axis. If positive then the solution
296 // gives the cone intersection with the side defined by `axis`
297 // Double_t h1 = t1 * dir.Dot(axis) + axis.Dot(deltaV);
298 Double_t h2 = t2 * dir.Dot(axis) + axis.Dot(deltaV);
299
300 // We use it to select the root we are interested in
301 if (h2 > 0)
302 return t2;
303 else
304 return t1;
305}
306
310TVector3 MoveByDistance(const TVector3& pos, const TVector3& dir, Double_t d) { return pos + d * dir.Unit(); }
311
316TVector3 MoveByDistanceFast(const TVector3& pos, const TVector3& dir, Double_t d) { return pos + d * dir; }
317
321Double_t GetDistance(const TVector3& v1, const TVector3& v2) { return (v2 - v1).Mag(); }
322
326Double_t GetDistance2(const TVector3& v1, const TVector3& v2) { return (v2 - v1).Mag2(); }
327} // namespace REST_Physics
This namespace serves to define physics constants and other basic physical operations.
Definition: TRestPhysics.h:34
TVector3 GetHyperbolicVectorIntersection(const TVector3 &pos, const TVector3 &dir, const Double_t beta, const Double_t R3, const Double_t focal)
TVector3 MoveByDistance(const TVector3 &pos, const TVector3 &dir, Double_t d)
This method transports a position pos by a distance d in the direction defined by dir.
TVector3 GetParabolicVectorIntersection(const TVector3 &pos, const TVector3 &dir, const Double_t alpha, const Double_t R3)
TVector3 GetParabolicNormal(const TVector3 &pos, const Double_t alpha, const Double_t R3)
This method returns the normal vector on a parabolic surface pointing towards the inside of the parab...
Double_t GetDistance(const TVector3 &v1, const TVector3 &v2)
This method returns the cartesian distance between vector v2 and v1.
TVector3 GetConeNormal(const TVector3 &pos, const Double_t alpha, const Double_t R=0)
This method will return a vector that is normal to the cone surface. The position pos should be at th...
Double_t GetConeVectorIntersection(const TVector3 &pos, const TVector3 &dir, const TVector3 &d, const TVector3 &v, const Double_t cosTheta)
This method will find the intersection of the trajectory defined by the vector starting at pos and mo...
TVector3 GetPlaneVectorIntersection(const TVector3 &pos, const TVector3 &dir, TVector3 const &n, TVector3 const &a)
This method will find the intersection of the trajectory defined by the vector starting at pos and mo...
Double_t DistanceToAxis(const TVector3 &axisPoint, const TVector3 &axisVector, const TVector3 &point)
This method will return the distance from point to the straight defined by axisPoint and axisVector.
TMatrixD GetConeMatrix(const TVector3 &d, const Double_t cosTheta)
It returns the cone matrix M = d^T x d - cosTheta^2 x I, extracted from the document by "David Eberly...
TVector3 MoveToPlane(const TVector3 &pos, const TVector3 &dir, const TVector3 &n, const TVector3 &a)
This method will translate the vector with direction dir starting at position pos to the plane define...
Double_t GetDistance2(const TVector3 &v1, const TVector3 &v2)
This method returns the squared cartesian distance between vector v2 and v1.
TVector3 MoveByDistanceFast(const TVector3 &pos, const TVector3 &dir, Double_t d)
This method transports a position pos by a distance d in the direction defined by dir....
TVector3 GetHyperbolicNormal(const TVector3 &pos, const Double_t beta, const Double_t R3, const Double_t focal)
This method returns the normal vector on a hyperbolic surface pointing towards the inside of the hype...
TVector3 GetVectorReflection(const TVector3 &dir, const TVector3 &n)
This method will return the reflected vector respect to a plane defined by its normal vector n....
Double_t GetVectorsAngle(const TVector3 &v1, const TVector3 &v2)
This method will return the angle in radians between 2 vectors.