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 
28 using namespace std;
29 
50 namespace REST_Physics {
51 
58 TVector3 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 
71 Double_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 
81 TVector3 GetPlaneVectorIntersection(const TVector3& pos, const TVector3& dir, const TVector3& n,
82  const TVector3& a) {
83  return MoveToPlane(pos, dir, n, a);
84 }
85 
94 TVector3 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 
124 TVector3 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 
150 TMatrixD 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 
172 TVector3 GetVectorReflection(const TVector3& dir, const TVector3& n) { return dir - 2 * dir.Dot(n) * n; }
173 
177 Double_t GetVectorsAngle(const TVector3& v1, const TVector3& v2) { return TMath::ACos(v1.Dot(v2)); }
178 
189 TVector3 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 
208 TVector3 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 
223 TVector3 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 //
248 Double_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 
267 Double_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 
310 TVector3 MoveByDistance(const TVector3& pos, const TVector3& dir, Double_t d) { return pos + d * dir.Unit(); }
311 
316 TVector3 MoveByDistanceFast(const TVector3& pos, const TVector3& dir, Double_t d) { return pos + d * dir; }
317 
321 Double_t GetDistance(const TVector3& v1, const TVector3& v2) { return (v2 - v1).Mag(); }
322 
326 Double_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.