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, const Double_t lMirr) {
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 if (pos.Z() + root1 * dir.Z() > -lMirr and pos.Z() + root1 * dir.Z() < 0) {
105 return pos + root1 * dir;
106 } else if (pos.Z() + root2 * dir.Z() > -lMirr and pos.Z() + root2 * dir.Z() < 0) {
107 return pos + root2 * dir;
108 }
109 return pos;
110 }
111 return pos - c / b * dir;
112}
113
122TVector3 GetHyperbolicVectorIntersection(const TVector3& pos, const TVector3& dir, const Double_t alpha,
123 const Double_t R3, const Double_t lMirr, const Double_t focal) {
124 Double_t beta = 3 * alpha;
125 Double_t e = 2 * R3 * TMath::Tan(beta);
127 Double_t g = 2 * R3 * TMath::Tan(beta) / (focal + R3 / TMath::Tan(2 * alpha));
128 Double_t a = dir.X() * dir.X() + dir.Y() * dir.Y() - g * dir.Z() * dir.Z();
129 Double_t b = 2 * (pos.X() * dir.X() + pos.Y() * dir.Y() - g * dir.Z() * pos.Z()) + e * dir.Z();
130 Double_t half_b = b / 2;
131 Double_t c = pos.X() * pos.X() + pos.Y() * pos.Y() - R3 * R3 + e * pos.Z() - g * pos.Z() * pos.Z();
132 Double_t root1 = (-half_b - TMath::Sqrt(half_b * half_b - a * c)) / a;
133 Double_t root2 = (-half_b + TMath::Sqrt(half_b * half_b - a * c)) / a;
134 if (pos.Z() + root1 * dir.Z() > 0 and pos.Z() + root1 * dir.Z() < lMirr) {
135 return pos + root1 * dir;
136 } else if (pos.Z() + root2 * dir.Z() > 0 and pos.Z() + root2 * dir.Z() < lMirr) {
137 return pos + root2 * dir;
138 }
139
140 return pos;
141}
142
147TMatrixD GetConeMatrix(const TVector3& d, const Double_t cosTheta) {
148 double cAxis[3];
149 d.GetXYZ(cAxis);
150
151 TVectorD coneAxis(3, cAxis);
152
153 TMatrixD M(3, 3);
154 M.Rank1Update(coneAxis, coneAxis);
155
156 double cT2 = cosTheta * cosTheta;
157 TMatrixD gamma(3, 3);
158 gamma.UnitMatrix();
159 gamma *= cT2;
160
161 M -= gamma;
162 return M;
163}
164
169TVector3 GetVectorReflection(const TVector3& dir, const TVector3& n) { return dir - 2 * dir.Dot(n) * n; }
170
174Double_t GetVectorsAngle(const TVector3& v1, const TVector3& v2) { return TMath::ACos(v1.Dot(v2)); }
175
186TVector3 GetConeNormal(const TVector3& pos, const Double_t alpha, const Double_t R) {
187 Double_t r = 0;
188 if (R == 0)
189 r = TMath::Sqrt(pos.X() * pos.X() + pos.Y() * pos.Y());
190 else
191 r = R;
192
193 Double_t cosA = TMath::Cos(alpha);
194 Double_t sinA = TMath::Sin(alpha);
195
196 return -TVector3(cosA * pos.X() / r, cosA * pos.Y() / r, sinA);
197}
198
205TVector3 GetParabolicNormal(const TVector3& pos, const Double_t alpha, const Double_t R3) {
206 TVector3 normalVec = pos;
207 Double_t m =
208 1 / (R3 * TMath::Tan(alpha) / TMath::Sqrt(R3 * R3 + R3 * 2 * TMath::Tan(alpha) * (-pos.Z())));
209 Double_t n = TMath::Sqrt(pos.X() * pos.X() + pos.Y() * pos.Y()) - m * pos.Z();
210 normalVec.SetZ(pos.Z() - (-n / m));
211 return normalVec.Unit();
212}
213
220TVector3 GetHyperbolicNormal(const TVector3& pos, const Double_t alpha, const Double_t R3,
221 const Double_t focal) {
222 TVector3 normalVec = pos;
223 Double_t beta = 3 * alpha;
225 Double_t m = 1 / (R3 * TMath::Tan(beta) * (1 - 2 * pos.Z() / (focal + R3 / TMath::Tan(2 * alpha))) /
226 TMath::Sqrt(R3 * R3 - R3 * 2 * TMath::Tan(beta) * pos.Z() *
227 (1.0 - pos.Z() / (focal + R3 / TMath::Tan(2 * alpha)))));
228 Double_t n = TMath::Sqrt(pos.X() * pos.X() + pos.Y() * pos.Y()) - m * pos.Z();
229 normalVec.SetZ(pos.Z() - (-n / m));
230 return normalVec.Unit();
231}
232
241//
245Double_t GetConeVectorIntersection(const TVector3& pos, const TVector3& dir, const TVector3& d,
246 const TVector3& v, const Double_t cosTheta) {
247 TMatrixD M = GetConeMatrix(d, cosTheta);
248 return GetConeVectorIntersection(pos, dir, M, d, v);
249}
250
264Double_t GetConeVectorIntersection(const TVector3& pos, const TVector3& dir, const TMatrixD& M,
265 const TVector3& axis, const TVector3& v) {
266 double u[3];
267 dir.GetXYZ(u);
268 TMatrixD U(3, 1, u);
269 TMatrixD Ut(1, 3, u);
270
271 double delta[3];
272 TVector3 deltaV = pos - v;
273 deltaV.GetXYZ(delta);
274 TMatrixD D(3, 1, delta);
275 TMatrixD Dt(1, 3, delta);
276
277 TMatrixD C2 = Ut * M * U;
278 Double_t c2 = C2[0][0];
279
280 TMatrixD C1 = Ut * M * D;
281 Double_t c1 = C1[0][0];
282
283 TMatrixD C0 = Dt * M * D;
284 Double_t c0 = C0[0][0];
285
286 Double_t root = c1 * c1 - c0 * c2;
287 if (root < 0) return 0;
288
289 Double_t t1 = (-c1 + TMath::Sqrt(root)) / c2;
290 Double_t t2 = (-c1 - TMath::Sqrt(root)) / c2;
291
292 // The projections along the cone axis. If positive then the solution
293 // gives the cone intersection with the side defined by `axis`
294 // Double_t h1 = t1 * dir.Dot(axis) + axis.Dot(deltaV);
295 Double_t h2 = t2 * dir.Dot(axis) + axis.Dot(deltaV);
296
297 // We use it to select the root we are interested in
298 if (h2 > 0)
299 return t2;
300 else
301 return t1;
302}
303
307TVector3 MoveByDistance(const TVector3& pos, const TVector3& dir, Double_t d) { return pos + d * dir.Unit(); }
308
313TVector3 MoveByDistanceFast(const TVector3& pos, const TVector3& dir, Double_t d) { return pos + d * dir; }
314
318Double_t GetDistance(const TVector3& v1, const TVector3& v2) { return (v2 - v1).Mag(); }
319
323Double_t GetDistance2(const TVector3& v1, const TVector3& v2) { return (v2 - v1).Mag2(); }
324} // 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 alpha, const Double_t R3, const Double_t lMirr, 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 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...
TVector3 GetHyperbolicNormal(const TVector3 &pos, const Double_t alpha, 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...
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.
TVector3 GetParabolicVectorIntersection(const TVector3 &pos, const TVector3 &dir, const Double_t alpha, const Double_t R3, const Double_t lMirr)
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 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.