00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "Math/GenVector/DisplacementVector3D.h"
00014 #include "Math/GenVector/PositionVector3D.h"
00015 #include "Math/GenVector/Cartesian3D.h"
00016 #include "Math/GenVector/Polar3D.h"
00017 #include "Math/GenVector/CylindricalEta3D.h"
00018 #include "Math/GenVector/Cylindrical3D.h"
00019 #include "Math/GenVector/etaMax.h"
00020
00021 #include "Math/Vector3Dfwd.h"
00022
00023 #include "CoordinateTraits.h"
00024
00025 #include <iostream>
00026 #include <limits>
00027 #include <cmath>
00028 #include <vector>
00029
00030
00031 #define DEBUG
00032
00033 using namespace ROOT::Math;
00034
00035
00036
00037
00038 template <typename T1, typename T2 >
00039 struct Precision {
00040 enum { result = std::numeric_limits<T1>::digits <= std::numeric_limits<T2>::digits };
00041 };
00042
00043 template <typename T1, typename T2, bool>
00044 struct LessPreciseType {
00045 typedef T1 type;
00046 };
00047 template <typename T1, typename T2>
00048 struct LessPreciseType<T1, T2, false> {
00049 typedef T2 type;
00050 };
00051
00052
00053 template <typename Scalar1, typename Scalar2>
00054 int
00055 closeEnough ( Scalar1 s1, Scalar2 s2, std::string const & coord, double ticks ) {
00056 int ret = 0;
00057 int pr = std::cout.precision(18);
00058 Scalar1 eps1 = std::numeric_limits<Scalar1>::epsilon();
00059 Scalar2 eps2 = std::numeric_limits<Scalar2>::epsilon();
00060 typedef typename LessPreciseType<Scalar1, Scalar2,Precision<Scalar1,Scalar2>::result>::type Scalar;
00061 Scalar epsilon = (eps1 >= eps2) ? eps1 : eps2;
00062 Scalar ss1 (s1);
00063 Scalar ss2 (s2);
00064 Scalar diff = ss1 - ss2;
00065 if (diff < 0) diff = -diff;
00066 if (ss1 == 0 || ss2 == 0) {
00067 if ( diff > ticks*epsilon ) {
00068 ret=3;
00069 std::cout << "\nAbsolute discrepancy in " << coord << "(): "
00070 << ss1 << " != " << ss2 << "\n"
00071 << " (Allowed discrepancy is " << ticks*epsilon
00072 << ")\nDifference is " << diff/epsilon << " ticks\n";
00073 }
00074 std::cout.precision (pr);
00075 return ret;
00076 }
00077
00078 long double sd1(ss1);
00079 long double sd2(ss2);
00080 if ( (sd1 + sd2 == sd1) != (sd1 + sd2 == sd2) ) {
00081 ret=5;
00082 std::cout << "\nInfinity discrepancy in " << coord << "(): "
00083 << sd1 << " != " << sd2 << "\n";
00084 std::cout.precision (pr);
00085 return ret;
00086 }
00087 Scalar denom = ss1 > 0 ? ss1 : -ss1;
00088 if ((diff/denom > ticks*epsilon) && (diff > ticks*epsilon)) {
00089 ret=9;
00090 std::cout << "\nDiscrepancy in " << coord << "(): "
00091 << ss1 << " != " << ss2 << "\n"
00092 << " (Allowed discrepancy is " << ticks*epsilon*ss1
00093 << ")\nDifference is " << (diff/denom)/epsilon << " ticks\n";
00094 }
00095 std::cout.precision (pr);
00096 return ret;
00097 }
00098
00099 template <class V1, class V2>
00100 int compare3D (const V1 & v1, const V2 & v2, double ticks) {
00101 int ret =0;
00102 typedef typename V1::CoordinateType CoordType1;
00103 typedef typename V2::CoordinateType CoordType2;
00104 ret |= closeEnough ( v1.x(), v2.x(), "x" ,ticks);
00105 ret |= closeEnough ( v1.y(), v2.y(), "y" ,ticks);
00106 ret |= closeEnough ( v1.z(), v2.z(), "z" ,ticks);
00107 ret |= closeEnough ( v1.rho(), v2.rho(), "rho" ,ticks);
00108
00109 typedef typename V2::Scalar Scalar;
00110 Scalar phi2 = v2.phi();
00111 if (std::abs(v1.phi()- phi2 ) > ROOT::Math::Pi() ) {
00112 if (phi2<0)
00113 phi2 += 2.*ROOT::Math::Pi();
00114 else
00115 phi2 -= 2*ROOT::Math::Pi();
00116 }
00117 ret |= closeEnough ( v1.phi(), phi2, "phi" ,ticks);
00118 ret |= closeEnough ( v1.r(), v2.r(), "r" ,ticks);
00119 ret |= closeEnough ( v1.theta(), v2.theta(), "theta" ,ticks);
00120 ret |= closeEnough ( v1.mag2(), v2.mag2(), "mag2" ,ticks);
00121 ret |= closeEnough ( v1.perp2(), v2.perp2(), "perp2" ,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 << "\nDiscrepancy detected (see above) is between:\n "
00128 << CoordinateTraits<CoordType1>::name() << " and\n "
00129 << CoordinateTraits<CoordType2>::name() << "\n"
00130 << "with v = (" << v1.x() << ", " << v1.y() << ", " << v1.z()
00131 << ")\n\n\n";
00132 }
00133 else {
00134 #ifdef DEBUG
00135 std::cout << ".";
00136 #endif
00137 }
00138
00139
00140 return ret;
00141 }
00142
00143 template <class C>
00144 int test3D ( const DisplacementVector3D<C> & v, double ticks ) {
00145
00146 #ifdef DEBUG
00147 std::cout <<"\n>>>>> Testing 3D from " << v << " ticks = " << ticks << std::endl;
00148 #endif
00149
00150 int ret = 0;
00151 DisplacementVector3D< Cartesian3D<double> > vxyz_d (v.x(), v.y(), v.z());
00152
00153 double r = std::sqrt (v.x()*v.x() + v.y()*v.y() + v.z()*v.z());
00154 double rho = std::sqrt (v.x()*v.x() + v.y()*v.y());
00155 double z = v.z();
00156
00157
00158 double theta = std::atan2( rho, z );
00159
00160 double phi = rho>0 ? std::atan2 (v.y(), v.x()) : 0;
00161 DisplacementVector3D< Polar3D<double> > vrtp_d ( r, theta, phi );
00162
00163 double eta;
00164 if (rho != 0) {
00165 eta = -std::log(std::tan(theta/2));
00166 #ifdef TRACE1
00167 std::cout << ":::: rho != 0\n"
00168 << ":::: theta = << " << theta
00169 <<"/n:::: tan(theta/2) = " << std::tan(theta/2)
00170 <<"\n:::: eta = " << eta << "\n";
00171 #endif
00172 } else if (v.z() == 0) {
00173 eta = 0;
00174 #ifdef TRACE1
00175 std::cout << ":::: v.z() == 0\n"
00176 <<"\n:::: eta = " << eta << "\n";
00177 #endif
00178 } else if (v.z() > 0) {
00179 eta = v.z() + etaMax<long double>();
00180 #ifdef TRACE1
00181 std::cout << ":::: v.z() > 0\n"
00182 << ":::: etaMax = " << etaMax<long double>()
00183 <<"\n:::: eta = " << eta << "\n";
00184 #endif
00185 } else {
00186 eta = v.z() - etaMax<long double>();
00187 #ifdef TRACE1
00188 std::cout << ":::: v.z() < 0\n"
00189 << ":::: etaMax = " << etaMax<long double>()
00190 <<"\n:::: eta = " << eta << "\n";
00191 #endif
00192 }
00193
00194 #ifdef DEBUG
00195 std::cout << " Testing DisplacementVector3D : ";
00196 #endif
00197
00198 DisplacementVector3D< CylindricalEta3D<double> > vrep_d ( rho, eta, phi );
00199
00200 ret |= compare3D( vxyz_d, vrtp_d, ticks);
00201 ret |= compare3D( vrtp_d, vxyz_d, ticks);
00202 ret |= compare3D( vxyz_d, vrep_d, ticks);
00203 ret |= compare3D( vrtp_d, vrep_d, ticks);
00204
00205 DisplacementVector3D< Cylindrical3D<double> > vrzp_d ( rho, z, phi );
00206
00207 ret |= compare3D( vxyz_d, vrzp_d, ticks);
00208 ret |= compare3D( vrtp_d, vrzp_d, ticks);
00209 ret |= compare3D( vrep_d, vrzp_d, ticks);
00210
00211 DisplacementVector3D< Cartesian3D<float> > vxyz_f (v.x(), v.y(), v.z());
00212 DisplacementVector3D< Polar3D<float> > vrtp_f ( r, theta, phi );
00213 DisplacementVector3D< CylindricalEta3D<float> > vrep_f ( rho, eta, phi );
00214
00215 ret |= compare3D( vxyz_d, vxyz_f, ticks);
00216 ret |= compare3D( vxyz_d, vrep_f, ticks);
00217 ret |= compare3D( vrtp_d, vrep_f, ticks);
00218
00219 ret |= compare3D( vxyz_f, vxyz_f, ticks);
00220 ret |= compare3D( vxyz_f, vrep_f, ticks);
00221 ret |= compare3D( vrtp_f, vrep_f, ticks);
00222
00223 #ifdef DEBUG
00224 if (ret == 0) std::cout << "\t OK\n";
00225 else {
00226 std::cout << "\t FAIL\n";
00227 std::cerr << "\n>>>>> Testing DisplacementVector3D from " << v << " ticks = " << ticks
00228 << "\t:\t FAILED\n";
00229 }
00230 std::cout << " Testing PositionVector3D : ";
00231 #endif
00232
00233
00234 PositionVector3D< Cartesian3D <double> > pxyz_d; pxyz_d = vxyz_d;
00235 PositionVector3D< Polar3D <double> > prtp_d; prtp_d = vrtp_d;
00236 PositionVector3D< CylindricalEta3D<double> > prep_d; prep_d = vrep_d;
00237 PositionVector3D< Cylindrical3D <double> > przp_d; przp_d = vrzp_d;
00238
00239 ret |= compare3D( pxyz_d, prtp_d, ticks);
00240 ret |= compare3D( vxyz_d, prep_d, ticks);
00241 ret |= compare3D( vrtp_d, prep_d, ticks);
00242 ret |= compare3D( vxyz_d, przp_d, ticks);
00243
00244 PositionVector3D< Cartesian3D<float> > pxyz_f (v.x(), v.y(), v.z());
00245 PositionVector3D< Polar3D<float> > prtp_f ( r, theta, phi );
00246 PositionVector3D< CylindricalEta3D<float> > prep_f ( rho, eta, phi );
00247
00248 ret |= compare3D( vxyz_d, pxyz_f, ticks);
00249 ret |= compare3D( vxyz_d, prep_f, ticks);
00250 ret |= compare3D( vrtp_d, prep_f, ticks);
00251
00252 ret |= compare3D( vxyz_f, pxyz_f, ticks);
00253 ret |= compare3D( vxyz_f, prep_f, ticks);
00254 ret |= compare3D( vrtp_f, prep_f, ticks);
00255
00256 #ifdef DEBUG
00257 if (ret == 0) std::cout << "\t\t OK\n";
00258 else {
00259 std::cout << "\t FAIL\n";
00260 std::cerr << "\n>>>>> Testing PositionVector3D from " << v << " ticks = " << ticks
00261 << "\t:\t FAILED\n";
00262 }
00263 #endif
00264 return ret;
00265 }
00266
00267
00268
00269 int coordinates3D () {
00270 int ret = 0;
00271
00272 ret |= test3D (XYZVector ( 0.0, 0.0, 0.0 ) ,2 );
00273 ret |= test3D (XYZVector ( 1.0, 2.0, 3.0 ) ,6 );
00274 ret |= test3D (XYZVector ( -1.0, 2.0, 3.0 ) ,6 );
00275 ret |= test3D (XYZVector ( 1.0, -2.0, 3.0 ) ,6 );
00276 ret |= test3D (XYZVector ( 1.0, 2.0, -3.0 ) ,6 );
00277 ret |= test3D (XYZVector ( -1.0, -2.0, 3.0 ) ,6 );
00278 ret |= test3D (XYZVector ( -1.0, 2.0, -3.0 ) ,6 );
00279 ret |= test3D (XYZVector ( 1.0, -2.0, -3.0 ) ,6 );
00280 ret |= test3D (XYZVector ( -1.0, -2.0, -3.0 ) ,6 );
00281 ret |= test3D (XYZVector ( 8.0, 0.0, 0.0 ) ,6 );
00282 ret |= test3D (XYZVector ( -8.0, 0.0, 0.0 ) ,12 );
00283 ret |= test3D (XYZVector ( 0.0, 9.0, 0.0 ) ,6 );
00284 ret |= test3D (XYZVector ( 0.0, -9.0, 0.0 ) ,6 );
00285
00286 ret |= test3D (XYZVector ( 0.0, 0.0, 7.0 ) ,8 );
00287 ret |= test3D (XYZVector ( 0.0, 0.0, -7.0 ) ,8 );
00288
00289 ret |= test3D (XYZVector ( 16.0, 0.02, .01 ) ,10 );
00290 ret |= test3D (XYZVector ( -16.0, 0.02, .01 ) ,10 );
00291 ret |= test3D (XYZVector ( -.01, 16.0, .01 ) ,2000 );
00292 ret |= test3D (XYZVector ( -.01, -16.0, .01 ) ,2000 );
00293 ret |= test3D (XYZVector ( 1.0, 2.0, 30.0 ) ,10 );
00294
00295
00296
00297
00298 ret |= test3D (XYZVector ( 0.0, 0.0, 15.0 ) ,30 );
00299 ret |= test3D (XYZVector ( 0.0, 0.0, -15.0 ) ,30 );
00300 ret |= test3D (XYZVector ( 0.0, 0.0, 35.0 ) ,30 );
00301 ret |= test3D (XYZVector ( 0.0, 0.0, -35.0 ) ,30 );
00302
00303 ret |= test3D (XYZVector ( 0.01, 0.02, 16.0 ) ,10 );
00304 ret |= test3D (XYZVector ( 0.01, 0.02, -16.0 ) ,40000 );
00305
00306 ret |= test3D (XYZVector ( 1.E-8, 1.E-8, 10.0 ) , 20 );
00307
00308
00309 ret |= test3D (XYZVector ( 1.E-8, 1.E-8, -10.0 ) ,2.E9 );
00310
00311
00312 ret |= test3D (XYZVector ( 10., 10., 1.E-8 ) ,1.0E6 );
00313 ret |= test3D (XYZVector ( 10., 10., -1.E-8 ) ,1.0E6 );
00314
00315
00316 return ret;
00317 }
00318
00319 int main() {
00320 int ret = coordinates3D();
00321 if (ret) std::cerr << "test FAILED !!! " << std::endl;
00322 else std::cout << "test OK " << std::endl;
00323 return ret;
00324 }