00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "Math/GenVector/DisplacementVector3D.h"
00013 #include "Math/GenVector/PositionVector3D.h"
00014 #include "Math/GenVector/Cartesian3D.h"
00015 #include "Math/GenVector/Polar3D.h"
00016 #include "Math/GenVector/CylindricalEta3D.h"
00017 #include "Math/GenVector/etaMax.h"
00018
00019 #include "Math/GenVector/PxPyPzE4D.h"
00020 #include "Math/GenVector/PxPyPzM4D.h"
00021 #include "Math/GenVector/PtEtaPhiE4D.h"
00022 #include "Math/GenVector/PtEtaPhiM4D.h"
00023 #include "Math/GenVector/LorentzVector.h"
00024
00025 #include "Math/Vector4Dfwd.h"
00026
00027 #include "CoordinateTraits.h"
00028
00029 #include <iostream>
00030 #include <limits>
00031 #include <cmath>
00032 #include <vector>
00033
00034
00035 #define DEBUG
00036
00037 using namespace ROOT::Math;
00038
00039
00040
00041 template <typename T1, typename T2 >
00042 struct Precision {
00043 enum { result = std::numeric_limits<T1>::digits <= std::numeric_limits<T2>::digits };
00044 };
00045
00046 template <typename T1, typename T2, bool>
00047 struct LessPreciseType {
00048 typedef T1 type;
00049 };
00050 template <typename T1, typename T2>
00051 struct LessPreciseType<T1, T2, false> {
00052 typedef T2 type;
00053 };
00054
00055
00056 template <typename Scalar1, typename Scalar2>
00057 int
00058 closeEnough ( Scalar1 s1, Scalar2 s2, std::string const & coord, double ticks ) {
00059 int ret = 0;
00060 Scalar1 eps1 = std::numeric_limits<Scalar1>::epsilon();
00061 Scalar2 eps2 = std::numeric_limits<Scalar2>::epsilon();
00062 typedef typename LessPreciseType<Scalar1, Scalar2,Precision<Scalar1,Scalar2>::result>::type Scalar;
00063 Scalar epsilon = (eps1 >= eps2) ? eps1 : eps2;
00064 int pr = std::cout.precision(18);
00065 Scalar ss1 (s1);
00066 Scalar ss2 (s2);
00067 Scalar diff = ss1 - ss2;
00068 if (diff < 0) diff = -diff;
00069 if (ss1 == 0 || ss2 == 0) {
00070 if ( diff > ticks*epsilon ) {
00071 ret=3;
00072 std::cout << "\nAbsolute discrepancy in " << coord << "(): "
00073 << ss1 << " != " << ss2 << "\n"
00074 << " (Allowed discrepancy is " << ticks*epsilon
00075 << ")\nDifference is " << diff/epsilon << " ticks\n";
00076 }
00077 std::cout.precision (pr);
00078 return ret;
00079 }
00080
00081 long double sd1(ss1);
00082 long double sd2(ss2);
00083 if ( (sd1 + sd2 == sd1) != (sd1 + sd2 == sd2) ) {
00084 ret=5;
00085 std::cout << "\nInfinity discrepancy in " << coord << "(): "
00086 << sd1 << " != " << sd2 << "\n";
00087 std::cout.precision (pr);
00088 return ret;
00089 }
00090 Scalar denom = ss1 > 0 ? ss1 : -ss1;
00091 if ((diff/denom > ticks*epsilon) && (diff > ticks*epsilon)) {
00092 ret=9;
00093 std::cout << "\nDiscrepancy in " << coord << "(): "
00094 << ss1 << " != " << ss2 << "\n"
00095 << " (Allowed discrepancy is " << ticks*epsilon*ss1
00096 << ")\nDifference is " << (diff/denom)/epsilon << " ticks\n";
00097 }
00098 std::cout.precision (pr);
00099 return ret;
00100 }
00101
00102
00103 template <class V1, class V2>
00104 int compare4D (const V1 & v1, const V2 & v2, double ticks) {
00105 int ret =0;
00106 typedef typename V1::CoordinateType CoordType1;
00107 typedef typename V2::CoordinateType CoordType2;
00108
00109 ret |= closeEnough ( v1.x(), v2.x(), "x" ,ticks);
00110 ret |= closeEnough ( v1.y(), v2.y(), "y" ,ticks);
00111 ret |= closeEnough ( v1.z(), v2.z(), "z" ,ticks);
00112 ret |= closeEnough ( v1.t(), v2.t(), "t" ,ticks);
00113 ret |= closeEnough ( v1.rho(), v2.rho(), "rho" ,ticks);
00114 ret |= closeEnough ( v1.phi(), v2.phi(), "phi" ,ticks);
00115 ret |= closeEnough ( v1.P(), v2.P(), "p" ,ticks);
00116 ret |= closeEnough ( v1.theta(), v2.theta(), "theta" ,ticks);
00117 ret |= closeEnough ( v1.perp2(), v2.perp2(), "perp2" ,ticks);
00118 ret |= closeEnough ( v1.M2(), v2.M2(), "m2" ,ticks);
00119 ret |= closeEnough ( v1.M(), v2.M(), "m" ,ticks);
00120 ret |= closeEnough ( v1.Mt(), v2.Mt(), "mt" ,ticks);
00121 ret |= closeEnough ( v1.Et(), v2.Et(), "et" ,ticks);
00122 if ( v1.rho() > 0 && v2.rho() > 0 ) {
00123 ret |= closeEnough ( v1.eta(), v2.eta(), "eta" ,ticks);
00124 }
00125
00126 if (ret != 0) {
00127 std::cout << "Discrepancy detected (see above) is between:\n "
00128 << CoordinateTraits<CoordType1>::name() << " and\n "
00129 << CoordinateTraits<CoordType2>::name() << "\n"
00130 << "with v = (" << v1.x() << ", " << v1.y() << ", "
00131 << v1.z() << ", " << v1.t() << ")\n";
00132 }
00133 else {
00134 std::cout << ".";
00135 }
00136
00137 return ret;
00138 }
00139
00140
00141
00142
00143 template <class C>
00144 int test4D ( const LorentzVector<C> & v, double ticks ) {
00145
00146 #ifdef DEBUG
00147 std::cout <<"\n>>>>> Testing LorentzVector from " << XYZTVector(v) << " ticks = " << ticks << "\t: ";
00148 #endif
00149
00150 int ret = 0;
00151 LorentzVector< PxPyPzE4D<double> > vxyzt_d (v.x(), v.y(), v.z(), v.t());
00152
00153
00154
00155 double rho = std::sqrt (v.x()*v.x() + v.y()*v.y());
00156 double theta = std::atan2( rho, v.z() );
00157
00158 double phi = rho>0 ? std::atan2 (v.y(), v.x()) : 0;
00159
00160 double eta;
00161 if (rho != 0) {
00162 eta = -std::log(std::tan(theta/2));
00163 #ifdef TRACE1
00164 std::cout << ":::: rho != 0\n"
00165 << ":::: theta = " << theta
00166 <<"/n:::: tan(theta/2) = " << std::tan(theta/2)
00167 <<"\n:::: eta = " << eta << "\n";
00168 #endif
00169 } else if (v.z() == 0) {
00170 eta = 0;
00171 #ifdef TRACE1
00172 std::cout << ":::: v.z() == 0\n"
00173 <<"\n:::: eta = " << eta << "\n";
00174 #endif
00175 } else if (v.z() > 0) {
00176 eta = v.z() + etaMax<long double>();
00177 #ifdef TRACE1
00178 std::cout << ":::: v.z() > 0\n"
00179 << ":::: etaMax = " << etaMax<long double>()
00180 <<"\n:::: eta = " << eta << "\n";
00181 #endif
00182 } else {
00183 eta = v.z() - etaMax<long double>();
00184 #ifdef TRACE1
00185 std::cout << ":::: v.z() < 0\n"
00186 << ":::: etaMax = " << etaMax<long double>()
00187 <<"\n:::: eta = " << eta << "\n";
00188 #endif
00189 }
00190
00191
00192 LorentzVector< PtEtaPhiE4D<double> > vrep_d ( rho, eta, phi, v.t() );
00193 ret |= compare4D( vxyzt_d, vrep_d, ticks);
00194
00195 LorentzVector< PtEtaPhiM4D<double> > vrepm_d ( rho, eta, phi, v.M() );
00196 ret |= compare4D( vxyzt_d, vrep_d, ticks);
00197
00198 LorentzVector< PxPyPzM4D <double> > vxyzm_d ( v.x(), v.y(), v.z(), v.M() );
00199 ret |= compare4D( vrep_d, vxyzm_d, ticks);
00200
00201 LorentzVector< PxPyPzE4D<float> > vxyzt_f (v.x(), v.y(), v.z(), v.t());
00202 ret |= compare4D( vxyzt_d, vxyzt_f, ticks);
00203
00204 LorentzVector< PtEtaPhiE4D<float> > vrep_f ( rho, eta, phi, v.t() );
00205 ret |= compare4D( vxyzt_f, vrep_f, ticks);
00206
00207 LorentzVector< PtEtaPhiM4D<float> > vrepm_f ( rho, eta, phi, v.M() );
00208 ret |= compare4D( vxyzt_f, vrepm_f, ticks);
00209
00210 LorentzVector< PxPyPzM4D<float> > vxyzm_f (v.x(), v.y(), v.z(), v.M());
00211 ret |= compare4D( vrep_f, vxyzm_f, ticks);
00212
00213 if (ret == 0) std::cout << "\t OK\n";
00214 else {
00215 std::cout << "\t FAIL\n";
00216 std::cerr << "\n>>>>> Testing LorentzVector from " << XYZTVector(v) << " ticks = " << ticks
00217 << "\t:\t FAILED\n";
00218 }
00219 return ret;
00220 }
00221
00222
00223 int coordinates4D (bool testAll = false) {
00224 int ret = 0;
00225
00226 ret |= test4D (XYZTVector ( 0.0, 0.0, 0.0, 0.0 ) , 1 );
00227 ret |= test4D (XYZTVector ( 1.0, 2.0, 3.0, 4.0 ) ,10 );
00228 ret |= test4D (XYZTVector ( -1.0, -2.0, 3.0, 4.0 ) ,10 );
00229
00230 ret |= test4D (XYZTVector ( 1.E-8, 1.E-8, 10.0, 100.0 ) ,10 );
00231
00232 ret |= test4D (XYZTVector ( 1.E-8, 1.E-8, -10.0, 100.0 ) ,1000000000 );
00233
00234
00235
00236
00237 ret |= test4D (PxPyPzMVector ( 1., 2., 3., 0.) , 4./std::sqrt(std::numeric_limits<double>::epsilon()) );
00238
00239
00240 if (!testAll) return ret;
00241
00242
00243 ret |= test4D (PxPyPzMVector ( 1., 1., 100., 0.) , 150./std::sqrt(std::numeric_limits<double>::epsilon()) );
00244
00245 ret |= test4D (PxPyPzMVector ( 1.E8, 1.E8, 1.E8, 0.) , 1.E9/std::sqrt(std::numeric_limits<double>::epsilon()) );
00246
00247 ret |= test4D (PxPyPzMVector ( 1.E-8, 1.E-8, 1.E-8, 0.) , 2.E-8/std::sqrt(std::numeric_limits<double>::epsilon()) );
00248
00249 return ret;
00250 }
00251
00252 int main() {
00253 int ret = coordinates4D();
00254 if (ret) std::cerr << "test FAILED !!! " << std::endl;
00255 else std::cout << "test OK " << std::endl;
00256 return ret;
00257 }