Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:10:10

0001 // @(#)root/mathcore:$Id$
0002 // Authors: W. Brown, M. Fischler, L. Moneta    2005
0003 
0004  /**********************************************************************
0005   *                                                                    *
0006   * Copyright (c) 2005 , LCG ROOT MathLib Team and                     *
0007   *                      FNAL LCG ROOT MathLib Team                    *
0008   *                                                                    *
0009   *                                                                    *
0010   **********************************************************************/
0011 
0012 // Header source file for class DisplacementVector3D
0013 //
0014 // Created by: Lorenzo Moneta  at Mon May 30 12:21:43 2005
0015 // Major rewrite: M. FIschler  at Wed Jun  8  2005
0016 //
0017 // Last update: $Id$
0018 //
0019 
0020 #ifndef ROOT_Math_GenVector_DisplacementVector3D
0021 #define ROOT_Math_GenVector_DisplacementVector3D  1
0022 
0023 #include "Math/GenVector/Cartesian3D.h"
0024 
0025 #include "Math/GenVector/PositionVector3Dfwd.h"
0026 
0027 #include "Math/GenVector/GenVectorIO.h"
0028 
0029 #include "Math/GenVector/BitReproducible.h"
0030 
0031 #include "Math/GenVector/CoordinateSystemTags.h"
0032 
0033 #include <cassert>
0034 
0035 
0036 namespace ROOT {
0037 
0038   namespace Math {
0039 
0040 
0041 //__________________________________________________________________________________________
0042     /**
0043      Class describing a generic displacement vector in 3 dimensions.
0044      This class is templated on the type of Coordinate system.
0045      One example is the XYZVector which is a vector based on
0046      double precision x,y,z data members by using the
0047      ROOT::Math::Cartesian3D<double> Coordinate system.
0048      The class is having also an extra template parameter, the coordinate system tag,
0049      to be able to identify (tag) vector described in different reference coordinate system,
0050      like global or local coordinate systems.
0051 
0052      @ingroup GenVector
0053 
0054      @sa Overview of the @ref GenVector "physics vector library"
0055     */
0056 
0057     template <class CoordSystem, class Tag = DefaultCoordinateSystemTag >
0058     class DisplacementVector3D {
0059 
0060     public:
0061 
0062       typedef typename CoordSystem::Scalar Scalar;
0063       typedef CoordSystem CoordinateType;
0064       typedef Tag  CoordinateSystemTag;
0065 
0066       // ------ ctors ------
0067 
0068       /**
0069           Default constructor. Construct an empty object with zero values
0070       */
0071       constexpr DisplacementVector3D ( ) :   fCoordinates()  { }
0072 
0073 
0074       /**
0075          Construct from three values of type <em>Scalar</em>.
0076          In the case of a XYZVector the values are x,y,z
0077          In the case of  a polar vector they are r,theta, phi
0078       */
0079       constexpr DisplacementVector3D(Scalar a, Scalar b, Scalar c) :
0080         fCoordinates ( a , b,  c )  { }
0081 
0082      /**
0083           Construct from a displacement vector expressed in different
0084           coordinates, or using a different Scalar type, but with same coordinate system tag
0085       */
0086       template <class OtherCoords>
0087       explicit constexpr DisplacementVector3D( const DisplacementVector3D<OtherCoords, Tag> & v) :
0088         fCoordinates ( v.Coordinates() ) { }
0089 
0090 
0091       /**
0092          Construct from a position vector expressed in different coordinates
0093          but with the same coordinate system tag
0094       */
0095       template <class OtherCoords>
0096       explicit constexpr DisplacementVector3D( const PositionVector3D<OtherCoords,Tag> & p) :
0097         fCoordinates ( p.Coordinates() ) { }
0098 
0099 
0100       /**
0101           Construct from a foreign 3D vector type, for example, Hep3Vector
0102           Precondition: v must implement methods x(), y() and z()
0103       */
0104       template <class ForeignVector>
0105       explicit constexpr DisplacementVector3D( const ForeignVector & v) :
0106         fCoordinates ( Cartesian3D<Scalar>( v.x(), v.y(), v.z() ) ) { }
0107 
0108 
0109 #ifdef LATER
0110       /**
0111          construct from a generic linear algebra  vector of at least size 3
0112          implementing operator [].
0113          \par v  LAVector
0114          \par index0   index where coordinates starts (typically zero)
0115          It works for all Coordinates types,
0116          ( x= v[index0] for Cartesian and r=v[index0] for Polar )
0117       */
0118       template <class LAVector>
0119       constexpr DisplacementVector3D(const LAVector & v, size_t index0 ) {
0120         fCoordinates = CoordSystem ( v[index0], v[index0+1], v[index0+2] );
0121       }
0122 #endif
0123 
0124       // compiler-generated copy ctor and dtor are fine.
0125 
0126       // ------ assignment ------
0127 
0128       /**
0129           Assignment operator from a displacement vector of arbitrary type
0130       */
0131       template <class OtherCoords>
0132       DisplacementVector3D & operator=
0133                         ( const DisplacementVector3D<OtherCoords, Tag> & v) {
0134         fCoordinates = v.Coordinates();
0135         return *this;
0136       }
0137 
0138       /**
0139          Assignment operator from a position vector
0140          (not necessarily efficient unless one or the other is Cartesian)
0141       */
0142       template <class OtherCoords>
0143       DisplacementVector3D & operator=
0144                         ( const PositionVector3D<OtherCoords,Tag> & rhs) {
0145          SetXYZ(rhs.x(), rhs.y(), rhs.z());
0146          return *this;
0147       }
0148 
0149 
0150       /**
0151           Assignment from a foreign 3D vector type, for example, Hep3Vector
0152           Precondition: v must implement methods x(), y() and z()
0153       */
0154       template <class ForeignVector>
0155       DisplacementVector3D & operator= ( const ForeignVector & v) {
0156         SetXYZ( v.x(),  v.y(), v.z() );
0157         return *this;
0158       }
0159 
0160 
0161 #ifdef LATER
0162       /**
0163          assign from a generic linear algebra  vector of at least size 3
0164          implementing operator []. This could be also a C array
0165          \par v  LAVector
0166          \par index0   index where coordinates starts (typically zero)
0167          It works for all Coordinates types,
0168          ( x= v[index0] for Cartesian and r=v[index0] for Polar )
0169       */
0170       template <class LAVector>
0171       DisplacementVector3D & assignFrom(const LAVector & v, size_t index0 = 0) {
0172         fCoordinates = CoordSystem  ( v[index0], v[index0+1], v[index0+2] );
0173         return *this;
0174       }
0175 #endif
0176 
0177       // ------ Set, Get, and access coordinate data ------
0178 
0179       /**
0180           Retrieve a copy of the coordinates object
0181       */
0182       CoordSystem Coordinates() const {
0183         return fCoordinates;
0184       }
0185 
0186       /**
0187          Set internal data based on a C-style array of 3 Scalar numbers
0188        */
0189       DisplacementVector3D<CoordSystem, Tag>& SetCoordinates( const Scalar src[] )
0190        { fCoordinates.SetCoordinates(src); return *this; }
0191 
0192       /**
0193          Set internal data based on 3 Scalar numbers
0194        */
0195       DisplacementVector3D<CoordSystem, Tag>& SetCoordinates( Scalar a, Scalar b, Scalar c )
0196        { fCoordinates.SetCoordinates(a, b, c); return *this; }
0197 
0198       /**
0199          Set internal data based on 3 Scalars at *begin to *end
0200        */
0201       template <class IT>
0202       DisplacementVector3D<CoordSystem, Tag>& SetCoordinates( IT begin, IT end  )
0203       { IT a = begin; IT b = ++begin; IT c = ++begin;
0204         (void)end;
0205         assert (++begin==end);
0206         SetCoordinates (*a,*b,*c);
0207         return *this;
0208       }
0209 
0210       /**
0211          get internal data into 3 Scalar numbers
0212        */
0213       void GetCoordinates( Scalar& a, Scalar& b, Scalar& c ) const
0214                             { fCoordinates.GetCoordinates(a, b, c);  }
0215 
0216       /**
0217          get internal data into a C-style array of 3 Scalar numbers
0218        */
0219       void GetCoordinates( Scalar dest[] ) const
0220                             { fCoordinates.GetCoordinates(dest);  }
0221 
0222       /**
0223          get internal data into 3 Scalars at *begin to *end (3 past begin)
0224        */
0225       template <class IT>
0226       void GetCoordinates( IT begin, IT end ) const
0227       { IT a = begin; IT b = ++begin; IT c = ++begin;
0228         (void)end;
0229         assert (++begin==end);
0230         GetCoordinates (*a,*b,*c);
0231       }
0232       /**
0233          get internal data into 3 Scalars starting at *begin
0234        */
0235       template <class IT>
0236       void GetCoordinates( IT begin) const {
0237          Scalar a = Scalar(0);
0238          Scalar b = Scalar(0);
0239          Scalar c = Scalar(0);
0240          GetCoordinates(a, b, c);
0241          *begin++ = a;
0242          *begin++ = b;
0243          *begin   = c;
0244       }
0245 
0246       /**
0247          set the values of the vector from the cartesian components (x,y,z)
0248          (if the vector is held in polar or cylindrical eta coordinates,
0249          then (x, y, z) are converted to that form)
0250        */
0251       DisplacementVector3D<CoordSystem, Tag>& SetXYZ (Scalar a, Scalar b, Scalar c) {
0252          fCoordinates.SetXYZ(a, b, c);
0253          return *this;
0254       }
0255 
0256       // ------------------- Equality -----------------
0257 
0258       /**
0259         Exact equality
0260        */
0261       bool operator==(const DisplacementVector3D & rhs) const {
0262         return fCoordinates==rhs.fCoordinates;
0263       }
0264       bool operator!= (const DisplacementVector3D & rhs) const {
0265         return !(operator==(rhs));
0266       }
0267 
0268       // ------ Individual element access, in various coordinate systems ------
0269 
0270       /**
0271           Dimension
0272       */
0273       unsigned int Dimension() const
0274       {
0275          return fDimension;
0276       };
0277 
0278       /**
0279           Cartesian X, converting if necessary from internal coordinate system.
0280       */
0281       Scalar X() const { return fCoordinates.X(); }
0282 
0283       /**
0284           Cartesian Y, converting if necessary from internal coordinate system.
0285       */
0286       Scalar Y() const { return fCoordinates.Y(); }
0287 
0288       /**
0289           Cartesian Z, converting if necessary from internal coordinate system.
0290       */
0291       Scalar Z() const { return fCoordinates.Z(); }
0292 
0293       /**
0294           Polar R, converting if necessary from internal coordinate system.
0295       */
0296       Scalar R() const { return fCoordinates.R(); }
0297 
0298       /**
0299           Polar theta, converting if necessary from internal coordinate system.
0300       */
0301       Scalar Theta() const { return fCoordinates.Theta(); }
0302 
0303       /**
0304           Polar phi, converting if necessary from internal coordinate system.
0305       */
0306       Scalar Phi() const { return fCoordinates.Phi(); }
0307 
0308       /**
0309           Polar eta, converting if necessary from internal coordinate system.
0310       */
0311       Scalar Eta() const { return fCoordinates.Eta(); }
0312 
0313       /**
0314           Cylindrical transverse component rho
0315       */
0316       Scalar Rho() const { return fCoordinates.Rho(); }
0317 
0318       // ----- Other fundamental properties -----
0319 
0320       /**
0321           Magnitute squared ( r^2 in spherical coordinate)
0322       */
0323       Scalar Mag2() const { return fCoordinates.Mag2();}
0324 
0325       /**
0326          Transverse component squared (rho^2 in cylindrical coordinates.
0327       */
0328       Scalar Perp2() const { return fCoordinates.Perp2();}
0329 
0330       /**
0331          return unit vector parallel to this (scalar)
0332       */
0333       template <typename SCALAR = Scalar, typename std::enable_if<std::is_arithmetic<SCALAR>::value>::type * = nullptr>
0334       DisplacementVector3D Unit() const
0335       {
0336          const auto tot = R();
0337          return tot == 0 ? *this : DisplacementVector3D(*this) / tot;
0338       }
0339 
0340       /**
0341          return unit vector parallel to this (vector)
0342       */
0343       template <typename SCALAR = Scalar, typename std::enable_if<!std::is_arithmetic<SCALAR>::value>::type * = nullptr>
0344       DisplacementVector3D Unit() const
0345       {
0346          SCALAR tot            = R();
0347          tot(tot == SCALAR(0)) = SCALAR(1);
0348          return DisplacementVector3D(*this) / tot;
0349       }
0350 
0351       // ------ Setting of individual elements present in coordinate system ------
0352 
0353       /**
0354          Change X - Cartesian3D coordinates only
0355       */
0356        DisplacementVector3D<CoordSystem, Tag>& SetX (Scalar xx) { fCoordinates.SetX(xx); return *this;}
0357 
0358       /**
0359          Change Y - Cartesian3D coordinates only
0360       */
0361        DisplacementVector3D<CoordSystem, Tag>& SetY (Scalar yy) { fCoordinates.SetY(yy); return *this;}
0362 
0363       /**
0364          Change Z - Cartesian3D coordinates only
0365       */
0366        DisplacementVector3D<CoordSystem, Tag>& SetZ (Scalar zz) { fCoordinates.SetZ(zz); return *this;}
0367 
0368       /**
0369          Change R - Polar3D coordinates only
0370       */
0371        DisplacementVector3D<CoordSystem, Tag>& SetR (Scalar rr) { fCoordinates.SetR(rr); return *this;}
0372 
0373       /**
0374          Change Theta - Polar3D coordinates only
0375       */
0376        DisplacementVector3D<CoordSystem, Tag>& SetTheta (Scalar ang) { fCoordinates.SetTheta(ang); return *this;}
0377 
0378       /**
0379          Change Phi - Polar3D or CylindricalEta3D coordinates
0380       */
0381        DisplacementVector3D<CoordSystem, Tag>& SetPhi (Scalar ang) { fCoordinates.SetPhi(ang); return *this;}
0382 
0383       /**
0384          Change Rho - CylindricalEta3D coordinates only
0385       */
0386        DisplacementVector3D<CoordSystem, Tag>& SetRho (Scalar rr) { fCoordinates.SetRho(rr); return *this;}
0387 
0388       /**
0389          Change Eta - CylindricalEta3D coordinates only
0390       */
0391        DisplacementVector3D<CoordSystem, Tag>& SetEta (Scalar etaval) { fCoordinates.SetEta(etaval); return *this;}
0392 
0393 
0394       // ------ Operations combining two vectors ------
0395       // -- need to have the specialized version in order to avoid
0396 
0397       /**
0398        Return the scalar (dot) product of two displacement vectors.
0399        It is possible to perform the product for any type of vector coordinates,
0400        but they must have the same coordinate system tag
0401       */
0402       template< class OtherCoords >
0403       Scalar Dot( const  DisplacementVector3D<OtherCoords,Tag>  & v) const {
0404         return X()*v.X() + Y()*v.Y() + Z()*v.Z();
0405       }
0406       /**
0407           Return the scalar (dot) product of two vectors.
0408           It is possible to perform the product for any classes
0409           implementing x(), y() and z() member functions
0410       */
0411       template< class OtherVector >
0412       Scalar Dot( const  OtherVector & v) const {
0413         return X()*v.x() + Y()*v.y() + Z()*v.z();
0414       }
0415 
0416       /**
0417        Return vector (cross) product of two displacement vectors,
0418        as a vector in the coordinate system of this class.
0419        It is possible to perform the product for any type of vector coordinates,
0420        but they must have the same coordinate system tag
0421       */
0422       template <class OtherCoords>
0423       DisplacementVector3D Cross( const DisplacementVector3D<OtherCoords,Tag>  & v) const {
0424         DisplacementVector3D  result;
0425         result.SetXYZ (  Y()*v.Z() - v.Y()*Z(),
0426                          Z()*v.X() - v.Z()*X(),
0427                          X()*v.Y() - v.X()*Y() );
0428         return result;
0429       }
0430       /**
0431          Return vector (cross) product of two  vectors,
0432          as a vector in the coordinate system of this class.
0433           It is possible to perform the product for any classes
0434           implementing X(), Y() and Z() member functions
0435       */
0436       template <class OtherVector>
0437       DisplacementVector3D Cross( const OtherVector & v) const {
0438         DisplacementVector3D  result;
0439         result.SetXYZ (  Y()*v.z() - v.y()*Z(),
0440                          Z()*v.x() - v.z()*X(),
0441                          X()*v.y() - v.x()*Y() );
0442         return result;
0443       }
0444 
0445 
0446 
0447       /**
0448           Self Addition with a displacement vector.
0449       */
0450       template <class OtherCoords>
0451       DisplacementVector3D & operator+=
0452                         (const  DisplacementVector3D<OtherCoords,Tag> & v) {
0453         SetXYZ(  X() + v.X(), Y() + v.Y(), Z() + v.Z() );
0454         return *this;
0455       }
0456 
0457       /**
0458           Self Difference with a displacement vector.
0459       */
0460       template <class OtherCoords>
0461       DisplacementVector3D & operator-=
0462                         (const  DisplacementVector3D<OtherCoords,Tag> & v) {
0463         SetXYZ(  x() - v.x(), y() - v.y(), z() - v.z() );
0464         return *this;
0465       }
0466 
0467 
0468       /**
0469          multiply this vector by a scalar quantity
0470       */
0471       DisplacementVector3D & operator*= (Scalar a) {
0472         fCoordinates.Scale(a);
0473         return *this;
0474       }
0475 
0476       /**
0477          divide this vector by a scalar quantity
0478       */
0479       DisplacementVector3D & operator/= (Scalar a) {
0480         fCoordinates.Scale(1/a);
0481         return *this;
0482       }
0483 
0484       // The following methods (v*a and v/a) could instead be free functions.
0485       // They were moved into the class to solve a problem on AIX.
0486 
0487       /**
0488         Multiply a vector by a real number
0489       */
0490       DisplacementVector3D operator * ( Scalar a ) const {
0491         DisplacementVector3D tmp(*this);
0492         tmp *= a;
0493         return tmp;
0494       }
0495 
0496       /**
0497          Negative of the vector
0498        */
0499       DisplacementVector3D operator - ( ) const {
0500         return operator*( Scalar(-1) );
0501       }
0502 
0503       /**
0504          Positive of the vector, return itself
0505        */
0506       DisplacementVector3D operator + ( ) const {return *this;}
0507 
0508       /**
0509          Division of a vector with a real number
0510        */
0511       DisplacementVector3D operator/ (Scalar a) const {
0512         DisplacementVector3D tmp(*this);
0513         tmp /= a;
0514         return tmp;
0515       }
0516 
0517 
0518       // Methods providing limited backward name compatibility with CLHEP
0519 
0520       Scalar x()     const { return fCoordinates.X();     }
0521       Scalar y()     const { return fCoordinates.Y();     }
0522       Scalar z()     const { return fCoordinates.Z();     }
0523       Scalar r()     const { return fCoordinates.R();     }
0524       Scalar theta() const { return fCoordinates.Theta(); }
0525       Scalar phi()   const { return fCoordinates.Phi();   }
0526       Scalar eta()   const { return fCoordinates.Eta();   }
0527       Scalar rho()   const { return fCoordinates.Rho();   }
0528       Scalar mag2()  const { return fCoordinates.Mag2();  }
0529       Scalar perp2() const { return fCoordinates.Perp2(); }
0530       DisplacementVector3D unit() const {return Unit();}
0531 
0532 
0533     private:
0534 
0535        CoordSystem fCoordinates;  // internal coordinate system
0536        static constexpr unsigned int fDimension = CoordinateType::Dimension;
0537 
0538 #ifdef NOT_SURE_THIS_SHOULD_BE_FORBIDDEN
0539       /**
0540          Cross product involving a position vector is inappropriate
0541       */
0542       template <class T2>
0543       DisplacementVector3D Cross( const PositionVector3D<T2> & ) const;
0544 #endif
0545 
0546       // the following methods should not compile
0547 
0548       // this should not compile (if from a vector or points with different tag
0549       template <class OtherCoords, class OtherTag>
0550       explicit constexpr DisplacementVector3D( const DisplacementVector3D<OtherCoords, OtherTag> & ) {}
0551 
0552       template <class OtherCoords, class OtherTag>
0553       explicit constexpr DisplacementVector3D( const PositionVector3D<OtherCoords, OtherTag> & ) {}
0554 
0555       template <class OtherCoords, class OtherTag>
0556       DisplacementVector3D & operator=( const DisplacementVector3D<OtherCoords, OtherTag> & );
0557 
0558 
0559       template <class OtherCoords, class OtherTag>
0560       DisplacementVector3D & operator=( const PositionVector3D<OtherCoords, OtherTag> & );
0561 
0562       template <class OtherCoords, class OtherTag>
0563       DisplacementVector3D & operator+=(const  DisplacementVector3D<OtherCoords, OtherTag> & );
0564 
0565       template <class OtherCoords, class OtherTag>
0566       DisplacementVector3D & operator-=(const  DisplacementVector3D<OtherCoords, OtherTag> & );
0567 
0568       template<class OtherCoords, class OtherTag >
0569       Scalar Dot( const  DisplacementVector3D<OtherCoords, OtherTag> &  ) const;
0570 
0571       template<class OtherCoords, class OtherTag >
0572       DisplacementVector3D Cross( const  DisplacementVector3D<OtherCoords, OtherTag> &  ) const;
0573 
0574 
0575     };
0576 
0577 // ---------- DisplacementVector3D class template ends here ------------
0578 // ---------------------------------------------------------------------
0579 
0580 
0581 
0582    /**
0583         Addition of DisplacementVector3D vectors.
0584         The (coordinate system) type of the returned vector is defined to
0585         be identical to that of the first vector, which is passed by value
0586     */
0587     template <class CoordSystem1, class CoordSystem2, class U>
0588     inline
0589     DisplacementVector3D<CoordSystem1,U>
0590     operator+(       DisplacementVector3D<CoordSystem1,U> v1,
0591                const DisplacementVector3D<CoordSystem2,U>  & v2) {
0592       return v1 += v2;
0593     }
0594 
0595     /**
0596         Difference between two DisplacementVector3D vectors.
0597         The (coordinate system) type of the returned vector is defined to
0598         be identical to that of the first vector.
0599     */
0600     template <class CoordSystem1, class CoordSystem2, class U>
0601     inline
0602     DisplacementVector3D<CoordSystem1,U>
0603     operator-( DisplacementVector3D<CoordSystem1,U> v1,
0604                DisplacementVector3D<CoordSystem2,U> const & v2) {
0605       return v1 -= v2;
0606     }
0607 
0608     /**
0609        Multiplication of a displacement vector by real number  a*v
0610     */
0611     template <class CoordSystem, class U>
0612     inline
0613     DisplacementVector3D<CoordSystem,U>
0614     operator * ( typename DisplacementVector3D<CoordSystem,U>::Scalar a,
0615                  DisplacementVector3D<CoordSystem,U> v) {
0616       return v *= a;
0617       // Note - passing v by value and using operator *= may save one
0618       // copy relative to passing v by const ref and creating a temporary.
0619     }
0620 
0621 
0622     // v1*v2 notation for Cross product of two vectors is omitted,
0623     // since it is always confusing as to whether dot product is meant.
0624 
0625 
0626 
0627     // ------------- I/O to/from streams -------------
0628 
0629     template <class char_t, class traits_t, class T, class U,
0630               typename std::enable_if<std::is_arithmetic<typename DisplacementVector3D<T, U>::Scalar>::value>::type * =
0631                  nullptr>
0632     std::basic_ostream<char_t, traits_t> &operator<<(std::basic_ostream<char_t, traits_t> &os,
0633                                                      DisplacementVector3D<T, U> const &v)
0634     {
0635        if (os) {
0636 
0637           typename T::Scalar a, b, c;
0638           v.GetCoordinates(a, b, c);
0639 
0640           if (detail::get_manip(os, detail::bitforbit)) {
0641              detail::set_manip(os, detail::bitforbit, '\00');
0642              typedef GenVector_detail::BitReproducible BR;
0643              BR::Output(os, a);
0644              BR::Output(os, b);
0645              BR::Output(os, c);
0646           } else {
0647              os << detail::get_manip(os, detail::open) << a << detail::get_manip(os, detail::sep) << b
0648                 << detail::get_manip(os, detail::sep) << c << detail::get_manip(os, detail::close);
0649           }
0650       }
0651       return os;
0652     }  // op<< <>()
0653 
0654     template <class char_t, class traits_t, class T, class U,
0655               typename std::enable_if<!std::is_arithmetic<typename DisplacementVector3D<T, U>::Scalar>::value>::type * =
0656                  nullptr>
0657     std::basic_ostream<char_t, traits_t> &operator<<(std::basic_ostream<char_t, traits_t> &os,
0658                                                      DisplacementVector3D<T, U> const &v)
0659     {
0660        if (os) {
0661           os << "{ ";
0662           for (std::size_t i = 0; i < PositionVector3D<T, U>::Scalar::Size; ++i) {
0663              os << "(" << v.x()[i] << "," << v.y()[i] << "," << v.z()[i] << ") ";
0664           }
0665           os << "}";
0666        }
0667        return os;
0668     } // op<< <>()
0669 
0670     template< class char_t, class traits_t, class T, class U >
0671       inline
0672       std::basic_istream<char_t,traits_t> &
0673       operator >> ( std::basic_istream<char_t,traits_t> & is
0674                   , DisplacementVector3D<T,U> & v
0675                   )
0676     {
0677       if( !is )  return is;
0678 
0679       typename T::Scalar a, b, c;
0680 
0681       if( detail::get_manip( is, detail::bitforbit ) )  {
0682         detail::set_manip( is, detail::bitforbit, '\00' );
0683         typedef GenVector_detail::BitReproducible BR;
0684         BR::Input(is, a);
0685         BR::Input(is, b);
0686         BR::Input(is, c);
0687       }
0688       else  {
0689         detail::require_delim( is, detail::open  );  is >> a;
0690         detail::require_delim( is, detail::sep   );  is >> b;
0691         detail::require_delim( is, detail::sep   );  is >> c;
0692         detail::require_delim( is, detail::close );
0693       }
0694 
0695       if( is )
0696         v.SetCoordinates(a, b, c);
0697       return is;
0698 
0699     }  // op>> <>()
0700 
0701 
0702 
0703   }  // namespace Math
0704 
0705 }  // namespace ROOT
0706 
0707 
0708 #endif /* ROOT_Math_GenVector_DisplacementVector3D  */
0709