Logo ROOT   6.08/07
Reference Guide
coordinates4D.cxx
Go to the documentation of this file.
1 // $Id $
2 //
3 // Tests that each form of 4-vector has all the properties that stem from
4 // owning and forwarding to a 4D coordinates instance
5 //
6 // 6/28/05 m fischler
7 // from contents of test_coordinates.h by L. Moneta.
8 //
9 // =================================================================
10 
11 
15 #include "Math/GenVector/Polar3D.h"
17 #include "Math/GenVector/etaMax.h"
18 
24 
25 #include "Math/Vector4Dfwd.h" // for typedefs definitions
26 
27 #include "CoordinateTraits.h"
28 
29 #include <iostream>
30 #include <limits>
31 #include <cmath>
32 #include <vector>
33 
34 //#define TRACE1
35 #define DEBUG
36 
37 using namespace ROOT::Math;
38 
39 
40 
41 template <typename T1, typename T2 >
42 struct Precision {
43  enum { result = std::numeric_limits<T1>::digits <= std::numeric_limits<T2>::digits };
44 };
45 
46 template <typename T1, typename T2, bool>
47 struct LessPreciseType {
48  typedef T1 type;
49 };
50 template <typename T1, typename T2>
51 struct LessPreciseType<T1, T2, false> {
52  typedef T2 type;
53 };
54 
55 
56 template <typename Scalar1, typename Scalar2>
57 int
58 closeEnough ( Scalar1 s1, Scalar2 s2, std::string const & coord, double ticks ) {
59  int ret = 0;
63  Scalar epsilon = (eps1 >= eps2) ? eps1 : eps2;
64  int pr = std::cout.precision(18);
65  Scalar ss1 (s1);
66  Scalar ss2 (s2);
67  Scalar diff = ss1 - ss2;
68  if (diff < 0) diff = -diff;
69  if (ss1 == 0 || ss2 == 0) { // TODO - the ss2==0 makes a big change??
70  if ( diff > ticks*epsilon ) {
71  ret=3;
72  std::cout << "\nAbsolute discrepancy in " << coord << "(): "
73  << ss1 << " != " << ss2 << "\n"
74  << " (Allowed discrepancy is " << ticks*epsilon
75  << ")\nDifference is " << diff/epsilon << " ticks\n";
76  }
77  std::cout.precision (pr);
78  return ret;
79  }
80  // infinity dicrepancy musy be checked with max precision
81  long double sd1(ss1);
82  long double sd2(ss2);
83  if ( (sd1 + sd2 == sd1) != (sd1 + sd2 == sd2) ) {
84  ret=5;
85  std::cout << "\nInfinity discrepancy in " << coord << "(): "
86  << sd1 << " != " << sd2 << "\n";
87  std::cout.precision (pr);
88  return ret;
89  }
90  Scalar denom = ss1 > 0 ? ss1 : -ss1;
91  if ((diff/denom > ticks*epsilon) && (diff > ticks*epsilon)) {
92  ret=9;
93  std::cout << "\nDiscrepancy in " << coord << "(): "
94  << ss1 << " != " << ss2 << "\n"
95  << " (Allowed discrepancy is " << ticks*epsilon*ss1
96  << ")\nDifference is " << (diff/denom)/epsilon << " ticks\n";
97  }
98  std::cout.precision (pr);
99  return ret;
100 }
101 
102 
103 template <class V1, class V2>
104 int compare4D (const V1 & v1, const V2 & v2, double ticks) {
105  int ret =0;
106  typedef typename V1::CoordinateType CoordType1;
107  typedef typename V2::CoordinateType CoordType2;
108 
109  ret |= closeEnough ( v1.x(), v2.x(), "x" ,ticks);
110  ret |= closeEnough ( v1.y(), v2.y(), "y" ,ticks);
111  ret |= closeEnough ( v1.z(), v2.z(), "z" ,ticks);
112  ret |= closeEnough ( v1.t(), v2.t(), "t" ,ticks);
113  ret |= closeEnough ( v1.rho(), v2.rho(), "rho" ,ticks);
114  ret |= closeEnough ( v1.phi(), v2.phi(), "phi" ,ticks);
115  ret |= closeEnough ( v1.P(), v2.P(), "p" ,ticks);
116  ret |= closeEnough ( v1.theta(), v2.theta(), "theta" ,ticks);
117  ret |= closeEnough ( v1.perp2(), v2.perp2(), "perp2" ,ticks);
118  ret |= closeEnough ( v1.M2(), v2.M2(), "m2" ,ticks);
119  ret |= closeEnough ( v1.M(), v2.M(), "m" ,ticks);
120  ret |= closeEnough ( v1.Mt(), v2.Mt(), "mt" ,ticks);
121  ret |= closeEnough ( v1.Et(), v2.Et(), "et" ,ticks);
122  if ( v1.rho() > 0 && v2.rho() > 0 ) { // eta can legitimately vary if rho == 0
123  ret |= closeEnough ( v1.eta(), v2.eta(), "eta" ,ticks);
124  }
125 
126  if (ret != 0) {
127  std::cout << "Discrepancy detected (see above) is between:\n "
128  << CoordinateTraits<CoordType1>::name() << " and\n "
130  << "with v = (" << v1.x() << ", " << v1.y() << ", "
131  << v1.z() << ", " << v1.t() << ")\n";
132  }
133  else {
134  std::cout << ".";
135  }
136 
137  return ret;
138 }
139 
140 
141 
142 
143 template <class C>
144 int test4D ( const LorentzVector<C> & v, double ticks ) {
145 
146 #ifdef DEBUG
147  std::cout <<"\n>>>>> Testing LorentzVector from " << XYZTVector(v) << " ticks = " << ticks << "\t: ";
148 #endif
149 
150  int ret = 0;
151  LorentzVector< PxPyPzE4D<double> > vxyzt_d (v.x(), v.y(), v.z(), v.t());
152 
153  //double m = std::sqrt ( v.t()*v.t() - v.x()*v.x() - v.y()*v.y() - v.z()*v.z());
154  //double r = std::sqrt (v.x()*v.x() + v.y()*v.y() + v.z()*v.z());
155  double rho = std::sqrt (v.x()*v.x() + v.y()*v.y());
156  double theta = std::atan2( rho, v.z() ); // better tahn using acos
157  //double theta = r>0 ? std::acos ( v.z()/r ) : 0;
158  double phi = rho>0 ? std::atan2 (v.y(), v.x()) : 0;
159 
160  double eta;
161  if (rho != 0) {
162  eta = -std::log(std::tan(theta/2));
163  #ifdef TRACE1
164  std::cout << ":::: rho != 0\n"
165  << ":::: theta = " << theta
166  <<"/n:::: tan(theta/2) = " << std::tan(theta/2)
167  <<"\n:::: eta = " << eta << "\n";
168  #endif
169  } else if (v.z() == 0) {
170  eta = 0;
171  #ifdef TRACE1
172  std::cout << ":::: v.z() == 0\n"
173  <<"\n:::: eta = " << eta << "\n";
174  #endif
175  } else if (v.z() > 0) {
176  eta = v.z() + etaMax<long double>();
177  #ifdef TRACE1
178  std::cout << ":::: v.z() > 0\n"
179  << ":::: etaMax = " << etaMax<long double>()
180  <<"\n:::: eta = " << eta << "\n";
181  #endif
182  } else {
183  eta = v.z() - etaMax<long double>();
184  #ifdef TRACE1
185  std::cout << ":::: v.z() < 0\n"
186  << ":::: etaMax = " << etaMax<long double>()
187  <<"\n:::: eta = " << eta << "\n";
188  #endif
189  }
190 
191 
192  LorentzVector< PtEtaPhiE4D<double> > vrep_d ( rho, eta, phi, v.t() );
193  ret |= compare4D( vxyzt_d, vrep_d, ticks);
194 
195  LorentzVector< PtEtaPhiM4D<double> > vrepm_d ( rho, eta, phi, v.M() );
196  ret |= compare4D( vxyzt_d, vrepm_d, ticks);
197 
198  LorentzVector< PxPyPzM4D <double> > vxyzm_d ( v.x(), v.y(), v.z(), v.M() );
199  ret |= compare4D( vrep_d, vxyzm_d, ticks);
200 
201  LorentzVector< PxPyPzE4D<float> > vxyzt_f (v.x(), v.y(), v.z(), v.t());
202  ret |= compare4D( vxyzt_d, vxyzt_f, ticks);
203 
204  LorentzVector< PtEtaPhiE4D<float> > vrep_f ( rho, eta, phi, v.t() );
205  ret |= compare4D( vxyzt_f, vrep_f, ticks);
206 
207  LorentzVector< PtEtaPhiM4D<float> > vrepm_f ( rho, eta, phi, v.M() );
208  ret |= compare4D( vxyzt_f, vrepm_f, ticks);
209 
210  LorentzVector< PxPyPzM4D<float> > vxyzm_f (v.x(), v.y(), v.z(), v.M());
211  ret |= compare4D( vrep_f, vxyzm_f, ticks);
212 
213  if (ret == 0) std::cout << "\t OK\n";
214  else {
215  std::cout << "\t FAIL\n";
216  std::cerr << "\n>>>>> Testing LorentzVector from " << XYZTVector(v) << " ticks = " << ticks
217  << "\t:\t FAILED\n";
218  }
219  return ret;
220 }
221 
222 
223 int coordinates4D (bool testAll = false) {
224  int ret = 0;
225 
226  ret |= test4D (XYZTVector ( 0.0, 0.0, 0.0, 0.0 ) , 1 );
227  ret |= test4D (XYZTVector ( 1.0, 2.0, 3.0, 4.0 ) ,10 );
228  ret |= test4D (XYZTVector ( -1.0, -2.0, 3.0, 4.0 ) ,10 );
229  // test for large eta values (which was giving inf before Jun 07)
230  ret |= test4D (XYZTVector ( 1.E-8, 1.E-8, 10.0, 100.0 ) ,10 );
231  // for z < 0 precision in eta is worse since theta is close to Pi
232  ret |= test4D (XYZTVector ( 1.E-8, 1.E-8, -10.0, 100.0 ) ,1000000000 );
233 
234  // test cases with zero mass
235 
236  // tick should be p /sqrt(eps) ~ 4 /sqrt(eps)
237  // take a factor 1.5 in ticks to be conservative
238  ret |= test4D (PxPyPzMVector ( 1., 2., 3., 0.) , 1.5 * 4./std::sqrt(std::numeric_limits<double>::epsilon()) );
239 
240  // this test fails in some machines (skip by default)
241  if (!testAll) return ret;
242 
243  // take a factor 1.5 in ticks to be conservative
244  ret |= test4D (PxPyPzMVector ( 1., 1., 100., 0.) , 150./std::sqrt(std::numeric_limits<double>::epsilon()) );
245  // need a larger a factor here
246  ret |= test4D (PxPyPzMVector ( 1.E8, 1.E8, 1.E8, 0.) , 1.E9/std::sqrt(std::numeric_limits<double>::epsilon()) );
247  // if use 1 here fails
248  ret |= test4D (PxPyPzMVector ( 1.E-8, 1.E-8, 1.E-8, 0.) , 2.E-8/std::sqrt(std::numeric_limits<double>::epsilon()) );
249 
250  return ret;
251 }
252 
253 int main() {
254  int ret = coordinates4D();
255  if (ret) std::cerr << "test FAILED !!! " << std::endl;
256  else std::cout << "test OK " << std::endl;
257  return ret;
258 }
Class describing a generic LorentzVector in the 4D space-time, using the specified coordinate system ...
Definition: LorentzVector.h:54
int main()
int compare4D(const V1 &v1, const V2 &v2, double ticks)
double sqrt(double)
LorentzVector< PxPyPzE4D< double > > XYZTVector
LorentzVector based on x,y,x,t (or px,py,pz,E) coordinates in double precision with metric (-...
Definition: Vector4Dfwd.h:33
static const std::string name()
int coordinates4D(bool testAll=false)
int test4D(const LorentzVector< C > &v, double ticks)
SVector< double, 2 > v
Definition: Dict.h:5
Double_t E()
Definition: TMath.h:54
REAL epsilon
Definition: triangle.c:617
int closeEnough(Scalar1 s1, Scalar2 s2, std::string const &coord, double ticks)
RooCmdArg Precision(Double_t prec)
double atan2(double, double)
int type
Definition: TGX11.cxx:120
Scalar M() const
return magnitude (mass) using the (-,-,-,+) metric.
#define T1
Definition: md5.inl:145
double tan(double)
double result[121]
Plane3D::Scalar Scalar
Definition: Plane3D.cxx:29
double log(double)